From d16e4751eeacb5c0aee847929c1a82db8c1fa46c Mon Sep 17 00:00:00 2001 From: Faran Javed Date: Fri, 1 Aug 2025 21:50:00 +0500 Subject: [PATCH] [Fix]: #1928 folder edit/create issues --- .../src/pages/ApplicationV2/HomeResCard.tsx | 15 +++++--- .../pages/ApplicationV2/HomeResOptions.tsx | 38 +++++++++---------- .../pages/ApplicationV2/MoveToFolderModal.tsx | 15 ++++++-- 3 files changed, 38 insertions(+), 30 deletions(-) diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx index db2758e73..627146ffc 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx @@ -143,7 +143,6 @@ export const StyledTypographyText = styled(AntdTypographyText)` &:hover { color: #315efb; } - } `; const MONTH_MILLIS = 30 * 24 * 60 * 60 * 1000; @@ -244,11 +243,15 @@ export function HomeResCard(props: { res: HomeRes; onMove: (res: HomeRes) => voi const Icon = resInfo.icon; const handleModalOk = (values: any) => { - res.type === HomeResTypeEnum.Folder && - dispatch(updateFolder({ id: res.id, name: values.appName || res.name })) - dispatch( - updateAppMetaAction({ applicationId: res.id, name: values.appName || res.name, folderId: folderId }) - ); + if (res.type === HomeResTypeEnum.Folder) { + // Update folder + dispatch(updateFolder({ id: res.id, name: values.appName || res.name })); + } else { + // Update application + dispatch( + updateAppMetaAction({ applicationId: res.id, name: values.appName || res.name, folderId: folderId }) + ); + } setDialogVisible(false); setTimeout(() => { diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResOptions.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResOptions.tsx index 38e4b6895..ce19949fb 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResOptions.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResOptions.tsx @@ -12,8 +12,7 @@ import { AppTypeEnum } from "constants/applicationConstants"; import { CopyModal } from "pages/common/copyModal"; import { messageInstance } from "lowcoder-design/src/components/GlobalInstances"; import ApplicationApi from "../../api/applicationApi"; -import { FolderApi } from "../../api/folderApi"; -import { ReduxActionTypes } from "constants/reduxActionConstants"; +import { deleteFolder } from "../../redux/reduxActions/folderActions"; const PopoverIcon = styled(PointIcon)` cursor: pointer; @@ -120,27 +119,24 @@ export const HomeResOptions = (props: { type: HomeResInfo[res.type].name.toLowerCase(), name: {res.name}, }), - onConfirm: async () => { - try { - await FolderApi.deleteFolder({ + onConfirm: () => { + dispatch(deleteFolder( + { folderId: res.id, parentFolderId: folderId || "" - }); - - // Update Redux state to remove deleted folder from dropdown - dispatch({ - type: ReduxActionTypes.DELETE_FOLDER_SUCCESS, - payload: { folderId: res.id, parentFolderId: folderId || "" } - }); - - messageInstance.success(trans("home.deleteSuccessMsg")); - setTimeout(() => { - setModify(!modify); - }, 200); - } catch (error) { - console.error("Failed to delete folder:", error); - messageInstance.error("Failed to delete folder"); - } + }, + () => { + // Success callback + messageInstance.success(trans("home.deleteSuccessMsg")); + setTimeout(() => { + setModify(!modify); + }, 200); + }, + () => { + // Error callback + messageInstance.error("Failed to delete folder"); + } + )); }, confirmBtnType: "delete", okText: trans("delete"), diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/MoveToFolderModal.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/MoveToFolderModal.tsx index 2e3d4888e..c97f48bd0 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/MoveToFolderModal.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/MoveToFolderModal.tsx @@ -1,6 +1,6 @@ import { HomeRes } from "./HomeLayout"; import { default as Form } from "antd/es/form"; -import React, { useState } from "react"; +import React, { useState, useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; import { useParams } from "react-router-dom"; import { @@ -11,10 +11,10 @@ import { FormSelectItem, TacoButton, } from "lowcoder-design"; -import { moveToFolder } from "../../redux/reduxActions/folderActions"; +import { moveToFolder, fetchFolderElements } from "../../redux/reduxActions/folderActions"; import styled from "styled-components"; import { trans } from "../../i18n"; -import { foldersSelector } from "../../redux/selectors/folderSelector"; +import { foldersSelector, isFetchingFolderElements } from "../../redux/selectors/folderSelector"; const MoveLabel = styled.div` font-size: 13px; @@ -47,11 +47,20 @@ export const MoveToFolderModal = (props: { source?: HomeRes; onClose: () => void const [loading, setLoading] = useState(false); const folders = useSelector(foldersSelector); + const isFetching = useSelector(isFetchingFolderElements); const dispatch = useDispatch(); const { folderId } = useParams<{ folderId: string }>(); + // Fetch folders when modal opens to populate Redux state (only if not already loaded or fetching) + useEffect(() => { + if (props.source && folders.length === 0 && !isFetching) { + // Dispatch the Redux action to fetch folders (empty folderId fetches all folders) + dispatch(fetchFolderElements({})); + } + }, [props.source, dispatch, folders.length, isFetching]); + return (