1- import { TacoButton } from "lowcoder-design/src/components/button "
2- import { ReactNode , useState } from "react" ;
1+ import { TacoButton , CustomModal , Alert } from "lowcoder-design"
2+ import { useState , useEffect } from "react" ;
33import { useDispatch } from "react-redux" ;
44import { updateAppMetaAction } from "redux/reduxActions/applicationActions" ;
55import styled from "styled-components" ;
@@ -25,6 +25,11 @@ import { useParams } from "react-router-dom";
2525import { messageInstance } from "lowcoder-design/src/components/GlobalInstances" ;
2626import { FolderIcon } from "icons" ;
2727import { BrandedIcon } from "@lowcoder-ee/components/BrandedIcon" ;
28+ import { Typography } from "antd" ;
29+ import { default as Form } from "antd/es/form" ;
30+ import { default as Input } from "antd/es/input" ;
31+ import { MultiIconDisplay } from "@lowcoder-ee/comps/comps/multiIconDisplay" ;
32+ import { FormStyled } from "../setting/idSource/styledComponents" ;
2833
2934const ExecButton = styled ( TacoButton ) `
3035 width: 52px;
@@ -50,14 +55,16 @@ const ExecButton = styled(TacoButton)`
5055` ;
5156
5257const Wrapper = styled . div `
53- height: 67px;
5458 padding: 0 6px;
5559 border-radius: 8px;
56- margin-bottom: -1px;
57- margin-top: 1px;
58-
60+ margin-bottom: 2px;
61+ margin-top: 2px;
62+ padding-top: 10px;
63+ padding-bottom: 10px;
64+ background-color: #fcfcfc;
65+ min-height: 100px;
5966 &:hover {
60- background-color: #f5f7fa;
67+ background-color: #f5f5f6
6168 }
6269` ;
6370
@@ -98,7 +105,6 @@ const CardInfo = styled.div`
98105 height: 100%;
99106 flex-grow: 1;
100107 cursor: pointer;
101- overflow: hidden;
102108 padding-right: 12px;
103109
104110 &:hover {
@@ -124,6 +130,7 @@ const AppTimeOwnerInfoLabel = styled.div`
124130const OperationWrapper = styled . div `
125131 display: flex;
126132 align-items: center;
133+ padding-right: 10px;
127134 @media screen and (max-width: 500px) {
128135 > svg {
129136 display: none;
@@ -133,9 +140,75 @@ const OperationWrapper = styled.div`
133140
134141const MONTH_MILLIS = 30 * 24 * 60 * 60 * 1000 ;
135142
143+ interface UpdateAppModalProps {
144+ visible : boolean ;
145+ onCancel : ( ) => void ;
146+ onOk : ( values : any ) => void ;
147+ res : HomeRes ;
148+ folderId ?: string ;
149+ }
150+
151+ export function UpdateAppModal ( { visible, onCancel, onOk, res, folderId } : UpdateAppModalProps ) {
152+ const [ detailsForm ] = Form . useForm ( ) ;
153+
154+ // Reset form values when res changes
155+ useEffect ( ( ) => {
156+ if ( res && visible ) {
157+ detailsForm . setFieldsValue ( {
158+ appName : res . name ,
159+ title : res . title
160+ } ) ;
161+ }
162+ } , [ res , visible , detailsForm ] ) ;
163+
164+ return (
165+ < CustomModal
166+ title = { trans ( "home.updateAppName" ) }
167+ open = { visible }
168+ destroyOnHidden
169+ onCancel = { onCancel }
170+ showCancelButton = { false }
171+ showOkButton
172+ width = "440px"
173+ okText = { trans ( "finish" ) }
174+ onOk = { ( ) => {
175+ detailsForm . validateFields ( ) . then ( ( values ) => {
176+ onOk ( values ) ;
177+ } ) . catch ( ( errorInfo ) => {
178+ console . error ( 'Validation failed:' , errorInfo ) ;
179+ } ) ;
180+ } }
181+ >
182+ < FormStyled
183+ form = { detailsForm }
184+ name = "general"
185+ layout = "vertical"
186+ style = { { maxWidth : '100%' } }
187+ autoComplete = "off"
188+ >
189+ { res . title &&
190+ < Alert label = { trans ( "home.titleUpdateWarning" ) } type = "warning" /> }
191+ < br />
192+
193+ < Form . Item label = { trans ( "home.name" ) } name = "appName" >
194+ < Input />
195+ </ Form . Item >
196+
197+ { res . title && (
198+ < Form . Item label = { trans ( "title" ) } name = "title" >
199+ < Input disabled />
200+ </ Form . Item >
201+ ) }
202+
203+ </ FormStyled >
204+ </ CustomModal >
205+ ) ;
206+ }
207+
136208export function HomeResCard ( props : { res : HomeRes ; onMove : ( res : HomeRes ) => void ; setModify :any ; modify : boolean } ) {
137209 const { res, onMove, setModify, modify } = props ;
138210 const [ appNameEditing , setAppNameEditing ] = useState ( false ) ;
211+ const [ dialogVisible , setDialogVisible ] = useState ( false )
139212 const dispatch = useDispatch ( ) ;
140213
141214 const { folderId } = useParams < { folderId : string } > ( ) ;
@@ -161,96 +234,137 @@ export function HomeResCard(props: { res: HomeRes; onMove: (res: HomeRes) => voi
161234 else if ( res . type === HomeResTypeEnum . NavLayout || res . type === HomeResTypeEnum . MobileTabLayout ) {
162235 iconColor = "#af41ff" ;
163236 }
164-
165237 const Icon = resInfo . icon ;
166238
239+ const handleModalOk = ( values : any ) => {
240+ dispatch (
241+ updateAppMetaAction ( { applicationId : res . id , name : values . appName || res . name , folderId : folderId } )
242+ ) ;
243+
244+ setDialogVisible ( false ) ;
245+ setTimeout ( ( ) => {
246+ setModify ( ! modify ) ;
247+ } , 200 ) ;
248+ } ;
249+
167250 return (
168- < Wrapper >
169- < Card >
170- { Icon && (
171- < BrandedIcon >
172- < Icon width = { "42px" } height = { "42px" } style = {
173- {
174- color : iconColor ,
175- marginRight : "10px" ,
176- flexShrink : 0
177- }
178- } />
179- </ BrandedIcon >
180- ) }
181- < CardInfo
182- onClick = { ( e ) => {
183- if ( appNameEditing ) {
184- return ;
185- }
186- if ( res . type === HomeResTypeEnum . Folder ) {
187- handleFolderViewClick ( res . id ) ;
188- } else {
189- if ( checkIsMobile ( window . innerWidth ) ) {
190- history . push ( APPLICATION_VIEW_URL ( res . id , "view" ) ) ;
191- return ;
192- }
193- if ( res . isMarketplace ) {
194- handleMarketplaceAppViewClick ( res . id ) ;
195- return ;
196- }
197- res . isEditable ? handleAppEditClick ( e , res . id ) : handleAppViewClick ( res . id ) ;
198- }
199- } }
200- >
201- < TypographyText
202- value = { res . name }
203- editing = { appNameEditing }
204- onChange = { ( value ) => {
205- if ( ! value . trim ( ) ) {
206- messageInstance . warning ( trans ( "home.nameCheckMessage" ) ) ;
251+ < >
252+ < UpdateAppModal
253+ visible = { dialogVisible }
254+ onCancel = { ( ) => setDialogVisible ( false ) }
255+ onOk = { handleModalOk }
256+ res = { res }
257+ folderId = { folderId }
258+ />
259+
260+ < Wrapper >
261+ < Card >
262+ { res . icon ?
263+ < MultiIconDisplay
264+ identifier = { res . icon && typeof res . icon === 'string' ? res . icon : '/icon:antd/appstoreoutlined' }
265+ width = "30px"
266+ height = "30px"
267+ style = { {
268+ marginRight : "6px" ,
269+ flexShrink : 0 ,
270+ color : "#b766db"
271+ } }
272+ /> :
273+ Icon && (
274+ < BrandedIcon >
275+ < Icon width = { "42px" } height = { "42px" } style = {
276+ {
277+ color : iconColor ,
278+ marginRight : "10px" ,
279+ flexShrink : 0
280+ }
281+ } />
282+ </ BrandedIcon >
283+ )
284+ }
285+ < CardInfo
286+ onClick = { ( e ) => {
287+ if ( appNameEditing ) {
207288 return ;
208289 }
209290 if ( res . type === HomeResTypeEnum . Folder ) {
210- dispatch ( updateFolder ( { id : res . id , name : value } ) ) ;
211- setTimeout ( ( ) => {
212- setModify ( ! modify ) ;
213- } , 200 ) ;
291+ handleFolderViewClick ( res . id ) ;
214292 } else {
215- dispatch (
216- updateAppMetaAction ( { applicationId : res . id , name : value , folderId : folderId } )
217- ) ;
218- setTimeout ( ( ) => {
219- setModify ( ! modify ) ;
220- } , 200 ) ;
293+ if ( checkIsMobile ( window . innerWidth ) ) {
294+ history . push ( APPLICATION_VIEW_URL ( res . id , "view" ) ) ;
295+ return ;
296+ }
297+ if ( res . isMarketplace ) {
298+ handleMarketplaceAppViewClick ( res . id ) ;
299+ return ;
300+ }
301+ res . isEditable ? handleAppEditClick ( e , res . id ) : handleAppViewClick ( res . id ) ;
221302 }
222- setAppNameEditing ( false ) ;
223303 } }
224- />
225- < AppTimeOwnerInfoLabel title = { subTitle } > { subTitle } </ AppTimeOwnerInfoLabel >
226- </ CardInfo >
227- < OperationWrapper >
228- { /* {res.isEditable && (
229- <EditButton onClick={(e) => handleAppEditClick(e, res.id)} buttonType="primary">
230- {trans("edit")}
231- </EditButton>
232- )} */ }
233- < ExecButton
234- onClick = { ( ) =>
235- res . type === HomeResTypeEnum . Folder
236- ? handleFolderViewClick ( res . id )
237- : res . isMarketplace
238- ? handleMarketplaceAppViewClick ( res . id )
239- : handleAppViewClick ( res . id )
240- }
241304 >
242- { trans ( "view" ) }
243- </ ExecButton >
244- < HomeResOptions
245- res = { res }
246- onRename = { ( ) => setAppNameEditing ( true ) }
247- onMove = { ( res ) => onMove ( res ) }
248- setModify = { setModify }
249- modify = { modify }
250- />
251- </ OperationWrapper >
252- </ Card >
253- </ Wrapper >
305+ < TypographyText
306+ value = { res . title || res . name }
307+ editing = { false }
308+ onChange = { ( value ) => {
309+ if ( ! value . trim ( ) ) {
310+ messageInstance . warning ( trans ( "home.nameCheckMessage" ) ) ;
311+ return ;
312+ }
313+ if ( res . type === HomeResTypeEnum . Folder ) {
314+ dispatch ( updateFolder ( { id : res . id , name : value } ) ) ;
315+ setTimeout ( ( ) => {
316+ setModify ( ! modify ) ;
317+ } , 200 ) ;
318+ } else {
319+ dispatch (
320+ updateAppMetaAction ( { applicationId : res . id , name : value , folderId : folderId } )
321+ ) ;
322+ setTimeout ( ( ) => {
323+ setModify ( ! modify ) ;
324+ } , 200 ) ;
325+ }
326+ setAppNameEditing ( false ) ;
327+ } }
328+ />
329+
330+ { res ?. description
331+ && < Typography . Text
332+ type = "secondary"
333+ style = { { fontSize : 12 , textWrap : "wrap" } }
334+ >
335+ { res . description . length > 150 ? res . description . substring ( 0 , 150 ) + '...' : res . description }
336+ </ Typography . Text > }
337+
338+ < AppTimeOwnerInfoLabel title = { subTitle } > { subTitle } </ AppTimeOwnerInfoLabel >
339+ </ CardInfo >
340+ < OperationWrapper >
341+ { /* {res.isEditable && (
342+ <EditButton onClick={(e) => handleAppEditClick(e, res.id)} buttonType="primary">
343+ {trans("edit")}
344+ </EditButton>
345+ )} */ }
346+ < ExecButton
347+ onClick = { ( ) =>
348+ res . type === HomeResTypeEnum . Folder
349+ ? handleFolderViewClick ( res . id )
350+ : res . isMarketplace
351+ ? handleMarketplaceAppViewClick ( res . id )
352+ : handleAppViewClick ( res . id )
353+ }
354+ >
355+ { trans ( "view" ) }
356+ </ ExecButton >
357+ < HomeResOptions
358+ res = { res }
359+ onRename = { ( ) => setDialogVisible ( true ) }
360+ onMove = { ( res ) => onMove ( res ) }
361+ setModify = { setModify }
362+ modify = { modify }
363+ />
364+ </ OperationWrapper >
365+ </ Card >
366+ </ Wrapper >
367+ </ >
254368 ) ;
255369}
256370
0 commit comments