From 491c8bbed156866e7b19bfd703384774c8d2711a Mon Sep 17 00:00:00 2001
From: Faran Javed <faran1997@outlook.com>
Date: Thu, 17 Jul 2025 17:07:43 +0500
Subject: [PATCH 1/6] remove myorg call on initial load

---
 .../redux/reducers/uiReducers/usersReducer.ts  | 18 ++++++++++++++++--
 .../lowcoder/src/redux/sagas/userSagas.ts      |  3 +--
 .../lowcoder/src/util/useWorkspaceManager.ts   | 14 ++++++++++++--
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/client/packages/lowcoder/src/redux/reducers/uiReducers/usersReducer.ts b/client/packages/lowcoder/src/redux/reducers/uiReducers/usersReducer.ts
index 3142ca13d..f1a04ea2c 100644
--- a/client/packages/lowcoder/src/redux/reducers/uiReducers/usersReducer.ts
+++ b/client/packages/lowcoder/src/redux/reducers/uiReducers/usersReducer.ts
@@ -25,7 +25,9 @@ const initialState: UsersReduxState = {
   workspaces: {
     items: [],
     totalCount: 0,
-    currentOrg: null
+    currentOrg: null,
+    loading: false,
+    isFetched: false,
     
   }
 };
@@ -198,6 +200,14 @@ const usersReducer = createReducer(initialState, {
     apiKeys: action.payload,
   }),
 
+  [ReduxActionTypes.FETCH_WORKSPACES_INIT]: (state: UsersReduxState) => ({
+      ...state,
+      workspaces: {
+        ...state.workspaces,
+        loading: true,
+      },
+  }),
+
   
   [ReduxActionTypes.FETCH_WORKSPACES_SUCCESS]: (
     state: UsersReduxState,
@@ -208,7 +218,9 @@ const usersReducer = createReducer(initialState, {
       items: action.payload.isLoadMore 
         ? [...state.workspaces.items, ...action.payload.items] // Append for load more
         : action.payload.items, // Replace for new search/initial load
-      totalCount: action.payload.totalCount
+      totalCount: action.payload.totalCount,
+      isFetched: true,
+      loading: false,
     }
   }),
   
@@ -234,6 +246,8 @@ export interface UsersReduxState {
     items: Org[];           // Current page of workspaces
     totalCount: number;     // Total workspaces available
     currentOrg: Org | null;
+    loading: boolean;
+    isFetched: boolean;
   };
 }
 
diff --git a/client/packages/lowcoder/src/redux/sagas/userSagas.ts b/client/packages/lowcoder/src/redux/sagas/userSagas.ts
index d0dfdba06..b19e2b1a6 100644
--- a/client/packages/lowcoder/src/redux/sagas/userSagas.ts
+++ b/client/packages/lowcoder/src/redux/sagas/userSagas.ts
@@ -77,8 +77,7 @@ export function* getUserSaga() {
         type: ReduxActionTypes.FETCH_USER_DETAILS_SUCCESS,
         payload: user,
       });
-      // fetch all workspaces and store in redux
-      yield put(fetchWorkspacesAction(1, 10));     
+       
     }
   } catch (error: any) {
     yield put({
diff --git a/client/packages/lowcoder/src/util/useWorkspaceManager.ts b/client/packages/lowcoder/src/util/useWorkspaceManager.ts
index 5c5cafee0..fe2379769 100644
--- a/client/packages/lowcoder/src/util/useWorkspaceManager.ts
+++ b/client/packages/lowcoder/src/util/useWorkspaceManager.ts
@@ -1,8 +1,9 @@
 import { useReducer, useEffect, useCallback, useMemo } from 'react';
-import { useSelector } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
 import { debounce } from 'lodash';
 import { Org } from 'constants/orgConstants';
 import { getWorkspaces } from 'redux/selectors/orgSelectors';
+import { fetchWorkspacesAction } from 'redux/reduxActions/orgActions';
 import UserApi from 'api/userApi';
 
 // State interface for the workspace manager
@@ -73,6 +74,7 @@ export function useWorkspaceManager({
 }: UseWorkspaceManagerOptions) {
   // Get workspaces from Redux
   const workspaces = useSelector(getWorkspaces);
+  const reduxDispatch = useDispatch();
   
   // Initialize reducer with Redux total count
   const [state, dispatch] = useReducer(workspaceReducer, {
@@ -81,6 +83,14 @@ export function useWorkspaceManager({
   });
 
 
+ 
+  /* ----- first-time fetch ------------------------------------------------ */
+  useEffect(() => {
+    if (!workspaces.isFetched && !workspaces.loading) {
+      reduxDispatch(fetchWorkspacesAction(1, pageSize));
+    }
+  }, [workspaces.isFetched, workspaces.loading, pageSize, reduxDispatch]);
+
   // API call to fetch workspaces (memoized for stable reference)
   const fetchWorkspacesPage = useCallback(
     async (page: number, search?: string) => {
@@ -177,7 +187,7 @@ export function useWorkspaceManager({
     // State
     searchTerm: state.searchTerm,
     currentPage: state.currentPage,
-    isLoading: state.isLoading,
+    isLoading: state.isLoading || workspaces.loading,
     displayWorkspaces,
     totalCount: currentTotalCount,
     

From c9e00c519d587af51e1cfc2cfdc91e53c6dbd7f9 Mon Sep 17 00:00:00 2001
From: Faran Javed <faran1997@outlook.com>
Date: Thu, 17 Jul 2025 17:41:11 +0500
Subject: [PATCH 2/6] remove api call from DS home page

---
 client/packages/lowcoder/src/pages/datasource/index.tsx | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/client/packages/lowcoder/src/pages/datasource/index.tsx b/client/packages/lowcoder/src/pages/datasource/index.tsx
index fe965aba6..3983a4069 100644
--- a/client/packages/lowcoder/src/pages/datasource/index.tsx
+++ b/client/packages/lowcoder/src/pages/datasource/index.tsx
@@ -16,18 +16,11 @@ import { getDataSource, getDataSourceTypes } from "../../redux/selectors/datasou
 export const DatasourceHome = () => {
   const dispatch = useDispatch();
 
-  const datasourceList = useSelector(getDataSource);
   const datasourceTypes = useSelector(getDataSourceTypes);
 
   const currentUser = useSelector(getUser);
   const orgId = currentUser.currentOrgId;
 
-  useEffect(() => {
-    if (isEmpty(orgId) || datasourceList.length !== 0) {
-      return;
-    }
-    dispatch(fetchDatasource({ organizationId: orgId }));
-  }, [dispatch, datasourceList.length, orgId]);
 
   useEffect(() => {
     if (isEmpty(orgId) || datasourceTypes.length !== 0) {

From 5fb6c52e05ff7169728b1d463b07a494f5377130 Mon Sep 17 00:00:00 2001
From: Faran Javed <faran1997@outlook.com>
Date: Thu, 17 Jul 2025 19:53:04 +0500
Subject: [PATCH 3/6] fix edit DS page and add loading states

---
 .../lowcoder/src/api/datasourceApi.ts         |  4 ++
 .../pages/datasource/datasourceEditPage.tsx   | 69 ++++++++++++++++---
 .../src/pages/datasource/datasourceList.tsx   | 11 +--
 .../lowcoder/src/pages/datasource/index.tsx   |  4 +-
 4 files changed, 74 insertions(+), 14 deletions(-)

diff --git a/client/packages/lowcoder/src/api/datasourceApi.ts b/client/packages/lowcoder/src/api/datasourceApi.ts
index 1be29e646..278015a12 100644
--- a/client/packages/lowcoder/src/api/datasourceApi.ts
+++ b/client/packages/lowcoder/src/api/datasourceApi.ts
@@ -187,6 +187,10 @@ export class DatasourceApi extends Api {
     return Api.get(DatasourceApi.url + `/listByOrg?orgId=${orgId}`, {...res});
   }
 
+  static getDatasourceById(id: string): AxiosPromise<GenericApiResponse<Datasource>> {
+    return Api.get(`${DatasourceApi.url}/${id}`);
+  }
+
   static createDatasource(
     datasourceConfig: Partial<Datasource>
   ): AxiosPromise<GenericApiResponse<Datasource>> {
diff --git a/client/packages/lowcoder/src/pages/datasource/datasourceEditPage.tsx b/client/packages/lowcoder/src/pages/datasource/datasourceEditPage.tsx
index 7e033cb7a..9f8de01aa 100644
--- a/client/packages/lowcoder/src/pages/datasource/datasourceEditPage.tsx
+++ b/client/packages/lowcoder/src/pages/datasource/datasourceEditPage.tsx
@@ -1,20 +1,25 @@
 import styled from "styled-components";
 import history from "../../util/history";
 import { default as Button } from "antd/es/button";
-import { useCallback, useMemo, useState } from "react";
+import { Spin } from "antd";
+import { useCallback, useEffect, useMemo, useState } from "react";
 import { CopyTextButton, DocIcon, PackUpIcon, TacoButton } from "lowcoder-design";
 import { useDatasourceForm } from "./form/useDatasourceForm";
 import { useParams } from "react-router-dom";
 import { DATASOURCE_URL } from "../../constants/routesURL";
 import { useSelector } from "react-redux";
-import { getDataSource, getDataSourceTypes } from "../../redux/selectors/datasourceSelectors";
+import { getDataSourceTypes } from "../../redux/selectors/datasourceSelectors";
 import { trans } from "i18n";
 import { DatasourceType } from "@lowcoder-ee/constants/queryConstants";
 import { getDatasourceTutorial } from "@lowcoder-ee/util/tutorialUtils";
 import { getDataSourceFormManifest } from "./getDataSourceFormManifest";
 import DataSourceIcon from "components/DataSourceIcon";
 import { Helmet } from "react-helmet";
-
+import { DatasourceApi } from "@lowcoder-ee/api/datasourceApi";
+import { DatasourceInfo } from "@lowcoder-ee/api/datasourceApi";
+import { GenericApiResponse } from "../../api/apiResponses";
+import { Datasource } from "@lowcoder-ee/constants/datasourceConstants";
+import { AxiosResponse } from "axios";
 const Wrapper = styled.div`
   display: flex;
   justify-content: center;
@@ -154,16 +159,44 @@ type DatasourcePathParams = {
 
 export const DatasourceEditPage = () => {
   const { datasourceId, datasourceType } = useParams<DatasourcePathParams>();
-  const datasourceList = useSelector(getDataSource);
   const datasourceTypes = useSelector(getDataSourceTypes);
   const [isReady, setIsReady] = useState(true);
 
-  const datasourceInfo = useMemo(() => {
+
+  const [datasourceInfo, setDatasourceInfo] = useState<DatasourceInfo | undefined>();
+  const [loading, setLoading] = useState(false);
+
+  // Fetch individual datasource when editing
+  useEffect(() => {
     if (!datasourceId) {
-      return undefined;
+      setDatasourceInfo(undefined);
+      return;
     }
-    return datasourceList.find((info) => info.datasource.id === datasourceId);
-  }, [datasourceId, datasourceList]);
+    
+    const fetchDatasource = async () => {
+      setLoading(true);
+      try {
+        const response: AxiosResponse<GenericApiResponse<Datasource>> = await DatasourceApi.getDatasourceById(datasourceId);
+        if (response.data.success) {
+          // Transform to DatasourceInfo format
+          setDatasourceInfo({
+            datasource: response.data.data,
+            edit: true, // Assume editable since user reached edit page
+          });
+        } else {
+          console.error('API returned error:', response.data);
+          setDatasourceInfo(undefined);
+        }
+      } catch (error: any) {
+        console.error('Failed to fetch datasource:', error);
+        setDatasourceInfo(undefined);
+      } finally {
+        setLoading(false);
+      }
+    };
+
+    fetchDatasource();
+  }, [datasourceId]);
 
   const dataSourceTypeInfo = useMemo(() => {
     if (datasourceId) {
@@ -181,6 +214,26 @@ export const DatasourceEditPage = () => {
     setIsReady(isReady);
   }, []);
 
+  // Show loading state while fetching datasource
+  if (loading) {
+    return (
+      <Wrapper>
+        <ContentWrapper>
+          <div style={{ 
+            display: 'flex', 
+            justifyContent: 'center', 
+            alignItems: 'center', 
+            height: '400px',
+            flexDirection: 'column',
+            gap: '16px'
+          }}>
+            <Spin size="large" />
+          </div>
+        </ContentWrapper>
+      </Wrapper>
+    );
+  }
+
   if (!finalDataSourceType) {
     return null;
   }
diff --git a/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx b/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx
index 2d7386fa0..61eb621b2 100644
--- a/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx
+++ b/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx
@@ -1,8 +1,8 @@
 import styled from "styled-components";
 import { EditPopover, PointIcon, Search, TacoButton } from "lowcoder-design";
-import React, {useEffect, useState} from "react";
+import {useEffect, useState} from "react";
 import { useDispatch, useSelector } from "react-redux";
-import { getDataSource, getDataSourceLoading, getDataSourceTypesMap } from "../../redux/selectors/datasourceSelectors";
+import { getDataSourceTypesMap } from "../../redux/selectors/datasourceSelectors";
 import { deleteDatasource } from "../../redux/reduxActions/datasourceActions";
 import { isEmpty } from "lodash";
 import history from "../../util/history";
@@ -113,7 +113,6 @@ export const DatasourceList = () => {
   const [modify, setModify] = useState(false);
   const currentUser = useSelector(getUser);
   const orgId = currentUser.currentOrgId;
-  const datasourceLoading = useSelector(getDataSourceLoading);
   const plugins = useSelector(getDataSourceTypesMap);
   interface ElementsState {
     elements: DatasourceInfo[];
@@ -123,6 +122,7 @@ export const DatasourceList = () => {
   const [elements, setElements] = useState<ElementsState>({ elements: [], total: 0 });
   const [currentPage, setCurrentPage] = useState(1);
   const [pageSize, setPageSize] = useState(10);
+  const [paginationLoading, setPaginationLoading] = useState(false);
 
   useEffect(()=> {
     const timer = setTimeout(() => {
@@ -133,6 +133,7 @@ export const DatasourceList = () => {
   }, [searchValue])
 
   useEffect( () => {
+    setPaginationLoading(true);
     fetchDatasourcePagination(
       {
         orgId: orgId,
@@ -146,6 +147,8 @@ export const DatasourceList = () => {
       }
       else
         console.error("ERROR: fetchFolderElements", result.error)
+    }).finally(() => {
+      setPaginationLoading(false);
     })
   }, [currentPage, pageSize, searchValues, modify]
   )
@@ -195,7 +198,7 @@ export const DatasourceList = () => {
         <BodyWrapper>
           <StyledTable
             loading={{
-              spinning: datasourceLoading,
+              spinning: paginationLoading,
               indicator: <LoadingOutlined spin style={{ fontSize: 30 }} />
             }}
             rowClassName={(record: any) => (!record.edit ? "datasource-can-not-edit" : "")}
diff --git a/client/packages/lowcoder/src/pages/datasource/index.tsx b/client/packages/lowcoder/src/pages/datasource/index.tsx
index 3983a4069..9364af391 100644
--- a/client/packages/lowcoder/src/pages/datasource/index.tsx
+++ b/client/packages/lowcoder/src/pages/datasource/index.tsx
@@ -8,10 +8,10 @@ import {
 } from "../../constants/routesURL";
 import React, { useEffect } from "react";
 import { isEmpty } from "lodash";
-import { fetchDatasource, fetchDataSourceTypes } from "../../redux/reduxActions/datasourceActions";
+import { fetchDataSourceTypes } from "../../redux/reduxActions/datasourceActions";
 import { useDispatch, useSelector } from "react-redux";
 import { getUser } from "../../redux/selectors/usersSelectors";
-import { getDataSource, getDataSourceTypes } from "../../redux/selectors/datasourceSelectors";
+import { getDataSourceTypes } from "../../redux/selectors/datasourceSelectors";
 
 export const DatasourceHome = () => {
   const dispatch = useDispatch();

From c8f9e3d22548cbef3d6f8bae25c38a9d53de5d75 Mon Sep 17 00:00:00 2001
From: Faran Javed <faran1997@outlook.com>
Date: Thu, 17 Jul 2025 23:59:10 +0500
Subject: [PATCH 4/6] #1848 remove duplicate environments call

---
 .../lowcoder/src/util/context/EnterpriseContext.tsx      | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/client/packages/lowcoder/src/util/context/EnterpriseContext.tsx b/client/packages/lowcoder/src/util/context/EnterpriseContext.tsx
index ba8e911c9..61b3097dc 100644
--- a/client/packages/lowcoder/src/util/context/EnterpriseContext.tsx
+++ b/client/packages/lowcoder/src/util/context/EnterpriseContext.tsx
@@ -26,13 +26,12 @@ export const EnterpriseProvider: React.FC<ProviderProps> = ({ children }) => {
         // Fetch the enterprise license only if we're in an EE environment
         dispatch(fetchEnterpriseLicense());
         dispatch(fetchEnvironments());
-        dispatch(fetchBrandingSetting({ orgId: user.currentOrgId, fallbackToGlobal: true }))
       } else {
         // Set the state to false for non-EE environments
         // setEEActiveState(false);
         setIsEnterpriseActive(false);
       }
-    }, [dispatch, user.currentOrgId]);
+    }, [dispatch]);
   
     useEffect(() => {
       if (isEEEnvironment()) {
@@ -41,6 +40,12 @@ export const EnterpriseProvider: React.FC<ProviderProps> = ({ children }) => {
         setIsEnterpriseActive(isEnterpriseActiveRedux);
       }
     }, [isEnterpriseActiveRedux]);
+
+    useEffect(() => {
+      if (isEEEnvironment()) {
+        dispatch(fetchBrandingSetting({ orgId: user.currentOrgId, fallbackToGlobal: true }))
+      }
+    }, [dispatch, user.currentOrgId]);
   
     return (
       <EnterpriseContext.Provider value={{ isEnterpriseActive }}>

From 9e10673be0da50d1bfc1d979a98898a52c1bb2ca Mon Sep 17 00:00:00 2001
From: Faran Javed <faran1997@outlook.com>
Date: Fri, 18 Jul 2025 18:26:08 +0500
Subject: [PATCH 5/6] [Fix]: #1848 remove duplicate folderelements request from
 Home

---
 .../lowcoder/src/pages/ApplicationV2/FolderView.tsx    | 10 ++++++++++
 .../lowcoder/src/pages/ApplicationV2/index.tsx         |  9 ---------
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/FolderView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/FolderView.tsx
index 695b932a9..887a74cc1 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/FolderView.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/FolderView.tsx
@@ -9,6 +9,8 @@ import { Helmet } from "react-helmet";
 import { trans } from "i18n";
 import {ApplicationPaginationType} from "@lowcoder-ee/util/pagination/type";
 import {fetchFolderElements} from "@lowcoder-ee/util/pagination/axios";
+import { fetchFolderElements as fetchFolderElementsRedux } from "../../redux/reduxActions/folderActions";
+import { getUser } from "../../redux/selectors/usersSelectors";
 
 function getBreadcrumbs(
   folder: FolderMeta,
@@ -52,6 +54,7 @@ export function FolderView() {
 
   const element = useSelector(folderElementsSelector);
   const allFolders = useSelector(foldersSelector);
+  const user = useSelector(getUser);
 
   const folder = allFolders.filter((f) => f.folderId === folderId)[0] || {};
   const breadcrumbs = getBreadcrumbs(folder, allFolders, [
@@ -61,6 +64,13 @@ export function FolderView() {
     },
   ]);
 
+  // Fetch folder data for breadcrumbs if not available
+  useEffect(() => {
+    if (allFolders.length === 0 && user.currentOrgId) {
+      dispatch(fetchFolderElementsRedux({}));
+    }
+  }, [allFolders.length, user.currentOrgId, dispatch]);
+
   useEffect( () => {
         try{
           fetchFolderElements({
diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
index 5987d097d..14bf9df2e 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx
@@ -124,15 +124,6 @@ export default function ApplicationHome() {
     setIsPreloadCompleted(true);
   }, [org, orgHomeId]);
 
-  useEffect(() => {
-    // Check if we need to fetch data (either no folders or no applications)
-    if (allFoldersCount !== 0 && allAppCount !== 0) {
-      return;
-    }
-    
-    user.currentOrgId && dispatch(fetchFolderElements({}));
-  }, [dispatch, allFoldersCount, allAppCount, user.currentOrgId]);
-
   if (fetchingUser || !isPreloadCompleted) {
     return <ProductLoading />;
   }

From 2df0a8fed3739498e14afd1edb6e99fb97440db7 Mon Sep 17 00:00:00 2001
From: Faran Javed <faran1997@outlook.com>
Date: Fri, 18 Jul 2025 23:08:33 +0500
Subject: [PATCH 6/6] [Fix]: #1848 delete/recycled and movetofolder

---
 .../pages/ApplicationV2/HomeResOptions.tsx    | 67 ++++++++++---------
 .../pages/ApplicationV2/TrashTableView.tsx    | 45 ++++++-------
 2 files changed, 55 insertions(+), 57 deletions(-)

diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResOptions.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResOptions.tsx
index 99244d7fc..38e4b6895 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResOptions.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResOptions.tsx
@@ -3,8 +3,6 @@ import { HomeResTypeEnum } from "../../types/homeRes";
 import { exportApplicationAsJSONFile } from "./components/AppImport";
 import { CustomModal, EditPopover, EditPopoverItemType, PointIcon } from "lowcoder-design";
 import { HomeResInfo } from "../../util/homeResUtils";
-import { recycleApplication } from "../../redux/reduxActions/applicationActions";
-import { deleteFolder } from "../../redux/reduxActions/folderActions";
 import { useDispatch } from "react-redux";
 import React, { useState } from "react";
 import styled from "styled-components";
@@ -13,6 +11,9 @@ import { useParams } from "react-router-dom";
 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";
 
 const PopoverIcon = styled(PointIcon)`
   cursor: pointer;
@@ -80,23 +81,20 @@ export const HomeResOptions = (props: {
                 type: HomeResInfo[res.type].name,
                 name: <b>{res.name}</b>,
               }),
-              onConfirm: () =>{
-                new Promise((resolve, reject) => {
-                  dispatch(
-                      recycleApplication(
-                          { applicationId: res.id, folderId: folderId },
-                          () => {
-                            messageInstance.success(trans("success"));
-                            resolve(true);
-                          },
-                          () => reject()
-                      )
-                  );
+              onConfirm: async () => {
+                try {
+                  await ApplicationApi.recycleApplication({ 
+                    applicationId: res.id, 
+                    folderId: folderId || "" 
+                  });
+                  messageInstance.success(trans("success"));
                   setTimeout(() => {
                     setModify(!modify);
                   }, 200);
-                })
-
+                } catch (error) {
+                  console.error("Failed to recycle application:", error);
+                  messageInstance.error("Failed to delete application");
+                }
               },
               confirmBtnType: "delete",
               okText: trans("home.moveToTrash"),
@@ -122,22 +120,27 @@ export const HomeResOptions = (props: {
                 type: HomeResInfo[res.type].name.toLowerCase(),
                 name: <b>{res.name}</b>,
               }),
-              onConfirm: () =>{
-                new Promise((resolve, reject) => {
-                dispatch(
-                    deleteFolder(
-                        { folderId: res.id, parentFolderId: folderId },
-                        () => {
-                          messageInstance.success(trans("home.deleteSuccessMsg"));
-                          resolve(true);
-                        },
-                        () => reject()
-                    )
-                );
-              })
-                setTimeout(() => {
-                  setModify(!modify);
-                }, 200);
+              onConfirm: async () => {
+                try {
+                  await FolderApi.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");
+                }
               },
               confirmBtnType: "delete",
               okText: trans("delete"),
diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/TrashTableView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/TrashTableView.tsx
index 11323e56d..54d93835d 100644
--- a/client/packages/lowcoder/src/pages/ApplicationV2/TrashTableView.tsx
+++ b/client/packages/lowcoder/src/pages/ApplicationV2/TrashTableView.tsx
@@ -5,11 +5,11 @@ import styled from "styled-components";
 import { useDispatch } from "react-redux";
 import { HomeResInfo } from "../../util/homeResUtils";
 import { HomeResTypeEnum } from "../../types/homeRes";
-import { deleteApplication, restoreApplication } from "../../redux/reduxActions/applicationActions";
 import { HomeRes } from "./HomeLayout";
 import { trans, transToNode } from "../../i18n";
 import { messageInstance } from "lowcoder-design/src/components/GlobalInstances";
 import { BrandedIcon } from "@lowcoder-ee/components/BrandedIcon";
+import ApplicationApi from "../../api/applicationApi";
 
 const OperationWrapper = styled.div`
   display: flex;
@@ -123,17 +123,18 @@ export const TrashTableView = (props: { resources: HomeRes[] , setModify: any, m
                     style={{ padding: "0 8px", width: "fit-content", minWidth: "52px" }}
                     buttonType={"blue"}
                     className={"home-datasource-edit-button"}
-                    onClick={() =>{
-                        dispatch(
-                            restoreApplication({ applicationId: item.id }, () => {
-                                messageInstance.success(trans("home.recoverSuccessMsg"));
-                            })
-                        )
+                    onClick={async () => {
+                      try {
+                        await ApplicationApi.restoreApplication({ applicationId: item.id });
+                        messageInstance.success(trans("home.recoverSuccessMsg"));
                         setTimeout(() => {
-                            setModify(!modify);
+                          setModify(!modify);
                         }, 200);
-                    }
-                  }
+                      } catch (error) {
+                        console.error("Failed to restore application:", error);
+                        messageInstance.error("Failed to restore application");
+                      }
+                    }}
                   >
                     {trans("recover")}
                   </EditBtn>
@@ -148,27 +149,21 @@ export const TrashTableView = (props: { resources: HomeRes[] , setModify: any, m
                         type: HomeResInfo[item.type].name.toLowerCase(),
                         name: <b>{item.name}</b>,
                       }),
-                      onConfirm: () =>{
-                        new Promise((resolve, reject) => {
-                          dispatch(
-                            deleteApplication(
-                              { applicationId: item.id },
-                              () => {
-                                messageInstance.success(trans("home.deleteSuccessMsg"));
-                                resolve(true);
-                              },
-                              () => reject()
-                            )
-                          );
-                        })
+                      onConfirm: async () => {
+                        try {
+                          await ApplicationApi.deleteApplication({ applicationId: item.id });
+                          messageInstance.success(trans("home.deleteSuccessMsg"));
                           setTimeout(() => {
-                              setModify(!modify);
+                            setModify(!modify);
                           }, 200);
+                        } catch (error) {
+                          console.error("Failed to delete application:", error);
+                          messageInstance.error("Failed to delete application permanently");
+                        }
                       },
                       confirmBtnType: "delete",
                       okText: trans("delete"),
                     })
-
                   }
                   style={{ marginLeft: "12px", width: "76px" }}
                 >
