From 16d8e1a261f1fb9cd8f30ada30d5e35cc4205a58 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Thu, 14 Nov 2024 03:17:21 -0500 Subject: [PATCH 01/38] Added pagination ui --- .../src/pages/ApplicationV2/HomeLayout.tsx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx index e69792bbd..e65533451 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx @@ -35,6 +35,7 @@ import { isFetchingFolderElements } from "../../redux/selectors/folderSelector"; import { checkIsMobile } from "util/commonUtils"; import { default as Divider } from "antd/es/divider"; import { ApplicationCategoriesEnum } from "constants/applicationConstants"; +import { Pagination } from 'antd'; const Wrapper = styled.div` display: flex; @@ -199,6 +200,12 @@ const EmptyView = styled.div` } } `; +const PaginationLayout = styled.div` + display: flex; + justify-content: center; + margin-top: 40px; + margin-bottom: 20px; +` const LayoutSwitcher = styled.div` position: absolute; @@ -307,6 +314,8 @@ export function HomeLayout(props: HomeLayoutProps) { const { breadcrumb = [], elements = [], localMarketplaceApps = [], globalMarketplaceApps = [], mode } = props; + console.log("folder", elements); + const categoryOptions = [ { label: {trans("home.allCategories")}, value: 'All' }, ...Object.entries(ApplicationCategoriesEnum).map(([key, value]) => ({ @@ -325,6 +334,7 @@ export function HomeLayout(props: HomeLayoutProps) { const [typeFilter, setTypeFilter] = useState("All"); const [categoryFilter, setCategoryFilter] = useState("All"); const [searchValue, setSearchValue] = useState(""); + const [visibility, setVisibility] = useState(true); const [layout, setLayout] = useState( checkIsMobile(window.innerWidth) ? "card" : getHomeLayout() ); @@ -415,6 +425,8 @@ export function HomeLayout(props: HomeLayoutProps) { } ); + console.log(resList); + const getFilterMenuItem = (type: HomeResTypeEnum) => { const Icon = HomeResInfo[type].icon; return { @@ -603,7 +615,12 @@ export function HomeLayout(props: HomeLayoutProps) { )} - + {visibility ?
+ + + + +
: null} From b6d8a1b1846e5ad792625958423be21f884f3cc4 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Tue, 26 Nov 2024 14:54:10 -0500 Subject: [PATCH 02/38] Removed Your Folder Component --- .../ApplicationV2/RootFolderListView.tsx | 23 ------------------- .../src/pages/ApplicationV2/index.tsx | 14 +++++------ 2 files changed, 6 insertions(+), 31 deletions(-) delete mode 100644 client/packages/lowcoder/src/pages/ApplicationV2/RootFolderListView.tsx diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/RootFolderListView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/RootFolderListView.tsx deleted file mode 100644 index a2263017c..000000000 --- a/client/packages/lowcoder/src/pages/ApplicationV2/RootFolderListView.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { useSelector } from "react-redux"; -import { HomeLayout } from "./HomeLayout"; -import { getUser } from "../../redux/selectors/usersSelectors"; -import { FOLDERS_URL } from "../../constants/routesURL"; -import { trans } from "../../i18n"; -import { foldersSelector } from "../../redux/selectors/folderSelector"; - -export function RootFolderListView() { - const user = useSelector(getUser); - const allFolders = useSelector(foldersSelector); - - if (!user.currentOrgId) { - return null; - } - - return ( - - ); -} diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx index fc2f7536a..5a3a2f3fa 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx @@ -4,7 +4,6 @@ import { DATASOURCE_URL, FOLDER_URL, FOLDER_URL_PREFIX, - FOLDERS_URL, MARKETPLACE_URL, QUERY_LIBRARY_URL, SETTING_URL, @@ -53,7 +52,6 @@ import { FolderView } from "./FolderView"; import { TrashView } from "./TrashView"; import { MarketplaceView } from "./MarketplaceView"; // import { SideBarItemType } from "../../components/layout/SideBarSection"; -import { RootFolderListView } from "./RootFolderListView"; // import InviteDialog from "../common/inviteDialog"; import { fetchFolderElements, updateFolder } from "../../redux/reduxActions/folderActions"; // import { ModuleView } from "./ModuleView"; @@ -262,12 +260,12 @@ export default function ApplicationHome() { { items: [ - { - text: {trans("home.allFolders")}, - routePath: FOLDERS_URL, - routeComp: RootFolderListView, - icon: ({ selected, ...otherProps }) => selected ? : , - }, + // { + // text: {trans("home.allFolders")}, + // routePath: FOLDERS_URL, + // routeComp: RootFolderListView, + // icon: ({ selected, ...otherProps }) => selected ? : , + // }, { text: {trans("home.allApplications")}, routePath: ALL_APPLICATIONS_URL, From efa56c3f4d351f77cc3c9ca3632f17db08cf2ef3 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Tue, 26 Nov 2024 14:56:42 -0500 Subject: [PATCH 03/38] Added utilities for pagination. --- .../lowcoder/src/util/pagination/axios.ts | 19 +++++++++++++++++++ .../lowcoder/src/util/pagination/type.ts | 14 ++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 client/packages/lowcoder/src/util/pagination/axios.ts create mode 100644 client/packages/lowcoder/src/util/pagination/type.ts diff --git a/client/packages/lowcoder/src/util/pagination/axios.ts b/client/packages/lowcoder/src/util/pagination/axios.ts new file mode 100644 index 000000000..67e22a7f5 --- /dev/null +++ b/client/packages/lowcoder/src/util/pagination/axios.ts @@ -0,0 +1,19 @@ +import { FolderApi } from "@lowcoder-ee/api/folderApi"; +import { FetchFolderElementsPaginationPayload } from "@lowcoder-ee/redux/reduxActions/folderActions"; + +export const fetchFolderElements = async (request: FetchFolderElementsPaginationPayload) => { + try { + const response = await FolderApi.fetchFolderElementsPagination(request); + return { + success: true, + data: response.data.data, + total:response.data.total + }; + } catch (error) { + console.error('Failed to fetch data:', error); + return { + success: false, + error: error + }; + } +} diff --git a/client/packages/lowcoder/src/util/pagination/type.ts b/client/packages/lowcoder/src/util/pagination/type.ts new file mode 100644 index 000000000..f73ddf306 --- /dev/null +++ b/client/packages/lowcoder/src/util/pagination/type.ts @@ -0,0 +1,14 @@ +type ApplicationType = { + [key: number]: string; // This allows numeric indexing +}; + +// Define the const with explicit type +export const ApplicationPaginationType: ApplicationType = { + 0: "", + 1: "APPLICATION", + 2: "MODULE", + 3: "NAVLAYOUT", + 4: "FOLDER", + 6: "MOBILETABLAYOUT", + 7: "NAVIGATION", +}; \ No newline at end of file From a602426f85b3c89ed1ef571ceecbb3d5247090ae Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Tue, 26 Nov 2024 14:58:47 -0500 Subject: [PATCH 04/38] Implemented pagination in Your App. --- .../lowcoder-design/src/components/Search.tsx | 35 ++++--- .../packages/lowcoder/src/api/apiResponses.ts | 8 ++ client/packages/lowcoder/src/api/folderApi.ts | 9 +- .../src/pages/ApplicationV2/HomeLayout.tsx | 92 ++++++++++++------- .../src/pages/ApplicationV2/HomeView.tsx | 56 ++++++++++- .../src/redux/reduxActions/folderActions.ts | 7 ++ 6 files changed, 154 insertions(+), 53 deletions(-) diff --git a/client/packages/lowcoder-design/src/components/Search.tsx b/client/packages/lowcoder-design/src/components/Search.tsx index 11e5f2adc..dff0ebeeb 100644 --- a/client/packages/lowcoder-design/src/components/Search.tsx +++ b/client/packages/lowcoder-design/src/components/Search.tsx @@ -62,24 +62,35 @@ interface ISearch { placeholder: string; value: string; onChange: (value: React.ChangeEvent) => void; + onEnterPress?: (value: string) => void; // Added for capturing Enter key press disabled?: boolean; } export const Search = (props: ISearch & InputProps) => { - const { value, onChange, style, disabled, placeholder, ...others } = props; + const { value, onChange, style, disabled, placeholder, onEnterPress, ...others } = props; + const handleChange = (e: React.ChangeEvent) => { onChange && onChange(e); }; + + // Handling Enter key press + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter' && onEnterPress) { + onEnterPress(value); + } + }; + return ( - - } - {...others} - /> - + + } + {...others} + /> + ); -}; +}; \ No newline at end of file diff --git a/client/packages/lowcoder/src/api/apiResponses.ts b/client/packages/lowcoder/src/api/apiResponses.ts index 5999bfcca..0c702b1ab 100644 --- a/client/packages/lowcoder/src/api/apiResponses.ts +++ b/client/packages/lowcoder/src/api/apiResponses.ts @@ -12,6 +12,14 @@ export interface GenericApiResponse { data: T; } +export interface GenericApiPaginationResponse { + total: number; + success: boolean; + code: number; + message: string; + data: T; +} + export interface FetchGroupApiResponse extends GenericApiResponse { totalAdmins: number, totalAdminsAndDevelopers: number, diff --git a/client/packages/lowcoder/src/api/folderApi.ts b/client/packages/lowcoder/src/api/folderApi.ts index 0f2fd47e5..10c6fef20 100644 --- a/client/packages/lowcoder/src/api/folderApi.ts +++ b/client/packages/lowcoder/src/api/folderApi.ts @@ -1,9 +1,10 @@ import Api from "./api"; import { AxiosPromise } from "axios"; -import { GenericApiResponse } from "./apiResponses"; +import {GenericApiPaginationResponse, GenericApiResponse} from "./apiResponses"; import { CreateFolderPayload, DeleteFolderPayload, + FetchFolderElementsPaginationPayload, FetchFolderElementsPayload, MoveToFolderPayload, UpdateFolderPayload, @@ -40,4 +41,10 @@ export class FolderApi extends Api { ): AxiosPromise> { return Api.get(FolderApi.url + `/elements`, { id: request.folderId }); } + + static fetchFolderElementsPagination( + request: FetchFolderElementsPaginationPayload + ): AxiosPromise> { + return Api.get(FolderApi.url + `/elements`, { ...request }); + } } diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx index e65533451..8fe7c49b5 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx @@ -203,7 +203,7 @@ const EmptyView = styled.div` const PaginationLayout = styled.div` display: flex; justify-content: center; - margin-top: 40px; + margin-top: -20px; margin-bottom: 20px; ` @@ -308,13 +308,39 @@ export interface HomeLayoutProps { localMarketplaceApps?: Array; globalMarketplaceApps?: Array; mode: HomeLayoutMode; + setCurrentPage?: any; + setPageSize?: any; + currentPage?: number; + pageSize?: number; + total?: number; + setSearchValues?: any; + typeFilter?: number; + setTypeFilter?: any; } export function HomeLayout(props: HomeLayoutProps) { + const { breadcrumb = [], + elements = [], + localMarketplaceApps = [], + globalMarketplaceApps = [], + mode , + setCurrentPage, + setPageSize, + pageSize, + currentPage, + setSearchValues, + total, + typeFilter, + setTypeFilter, + } = props; + console.log("elements", elements, total); + const handlePageChange = (page: number) => { + setCurrentPage(page); + }; - const { breadcrumb = [], elements = [], localMarketplaceApps = [], globalMarketplaceApps = [], mode } = props; - - console.log("folder", elements); + const handlePageSizeChange = (current: number, size: number) => { + setPageSize(size); + }; const categoryOptions = [ { label: {trans("home.allCategories")}, value: 'All' }, @@ -331,10 +357,9 @@ export function HomeLayout(props: HomeLayoutProps) { const user = useSelector(getUser); const isFetching = useSelector(isFetchingFolderElements); const isSelfHost = window.location.host !== 'app.lowcoder.cloud'; - const [typeFilter, setTypeFilter] = useState("All"); const [categoryFilter, setCategoryFilter] = useState("All"); const [searchValue, setSearchValue] = useState(""); - const [visibility, setVisibility] = useState(true); + const [visibility, setVisibility] = useState(mode !== "marketplace"); const [layout, setLayout] = useState( checkIsMobile(window.innerWidth) ? "card" : getHomeLayout() ); @@ -352,7 +377,15 @@ export function HomeLayout(props: HomeLayoutProps) { return null; } - var displayElements = elements; + var displayElements = elements.sort((a, b) => { + if (a.folder && !b.folder) { + return -1; // a is a folder and should come first + } else if (!a.folder && b.folder) { + return 1; // b is a folder and should come first + } else { + return 0; // both are folders or both are not, keep original order + } + }); if (mode === "marketplace" && isSelfHost) { const markedLocalApps = localMarketplaceApps.map(app => ({ ...app, isLocalMarketplace: true })); @@ -364,27 +397,7 @@ export function HomeLayout(props: HomeLayoutProps) { const markedLocalApps = localMarketplaceApps.map(app => ({ ...app, isLocalMarketplace: true })); displayElements = [...markedLocalApps]; } - const resList: HomeRes[] = displayElements - .filter((e) => - searchValue - ? e.name?.toLocaleLowerCase().includes(searchValue?.toLocaleLowerCase()) || - e.createBy?.toLocaleLowerCase().includes(searchValue?.toLocaleLowerCase()) - : true - ) - .filter((e) => { - if (HomeResTypeEnum[typeFilter].valueOf() === HomeResTypeEnum.All) { - return true; - } - if (e.folder) { - return HomeResTypeEnum[typeFilter] === HomeResTypeEnum.Folder; - } else { - if (typeFilter === "Navigation") { - return NavigationTypes.map((t) => t.valueOf()).includes(e.applicationType); - } - return HomeResTypeEnum[typeFilter].valueOf() === e.applicationType; - } - }) .filter((e) => { // If "All" is selected, do not filter out any elements based on category if (categoryFilter === 'All' || !categoryFilter) { @@ -425,7 +438,6 @@ export function HomeLayout(props: HomeLayoutProps) { } ); - console.log(resList); const getFilterMenuItem = (type: HomeResTypeEnum) => { const Icon = HomeResInfo[type].icon; @@ -474,7 +486,7 @@ export function HomeLayout(props: HomeLayoutProps) { {showNewUserGuide(user) && } - +

{mode === "marketplace" && trans("home.appMarketplace")} @@ -491,8 +503,11 @@ export function HomeLayout(props: HomeLayoutProps) { {mode !== "folders" && mode !== "module" && ( setTypeFilter(value as HomeResKey)} + value={HomeResTypeEnum[typeFilter || 0]} + onChange={(value: any) => { + console.log(HomeResTypeEnum[value]) + setTypeFilter(HomeResTypeEnum[value])} + } options={[ getFilterMenuItem(HomeResTypeEnum.All), getFilterMenuItem(HomeResTypeEnum.Application), @@ -519,6 +534,7 @@ export function HomeLayout(props: HomeLayoutProps) { placeholder={trans("search")} value={searchValue} onChange={(e) => setSearchValue(e.target.value)} + onEnterPress={(value) => setSearchValues(value)} style={{ width: "192px", height: "32px", margin: "0" }} /> {mode !== "trash" && mode !== "marketplace" && user.orgDev && ( @@ -615,15 +631,21 @@ export function HomeLayout(props: HomeLayoutProps) { )} - {visibility ?
- + {visibility && resList.length ?
- +
: null} - + ); diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx index b4309e321..7fd27ae1c 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx @@ -1,12 +1,50 @@ import { useSelector } from "react-redux"; import { HomeLayout } from "./HomeLayout"; import { getUser } from "../../redux/selectors/usersSelectors"; -import { folderElementsSelector } from "../../redux/selectors/folderSelector"; import { Helmet } from "react-helmet"; import { trans } from "i18n"; +import {useState, useEffect } from "react"; +import {fetchFolderElements} from "@lowcoder-ee/util/pagination/axios"; +import {ApplicationMeta, FolderMeta} from "@lowcoder-ee/constants/applicationConstants"; +import {ApplicationPaginationType} from "@lowcoder-ee/util/pagination/type"; + +interface ElementsState { + elements: (ApplicationMeta | FolderMeta)[]; + total: number; +} export function HomeView() { - const elements = useSelector(folderElementsSelector)[""]; + const [elements, setElements] = useState({ elements: [], total: 1 }); + const [currentPage, setCurrentPage] = useState(1); + const [pageSize, setPageSize] = useState(10); + const [searchValues, setSearchValues] = useState(""); + const [typeFilter, setTypeFilter] = useState(0); + useEffect( () => { + try{ + + fetchFolderElements({ + pageNum:currentPage, + pageSize:pageSize, + applicationType: ApplicationPaginationType[typeFilter], + name: searchValues, + }).then( + data => { + console.log(data) + if (data.success) { + setElements({elements: data.data || [], total: data.total || 1}) + } + else + console.error("ERROR: fetchFolderElements", data.error) + } + ); + } catch (error) { + console.error('Failed to fetch data:', error); + } + }, [currentPage, pageSize, searchValues, typeFilter] + ); + + console.log(currentPage, pageSize); + const user = useSelector(getUser); if (!user.currentOrgId) { @@ -16,9 +54,17 @@ export function HomeView() { return ( <> {{trans("productName")} {trans("home.home")}} - ); diff --git a/client/packages/lowcoder/src/redux/reduxActions/folderActions.ts b/client/packages/lowcoder/src/redux/reduxActions/folderActions.ts index 5c00aafe6..a793ddee3 100644 --- a/client/packages/lowcoder/src/redux/reduxActions/folderActions.ts +++ b/client/packages/lowcoder/src/redux/reduxActions/folderActions.ts @@ -78,6 +78,13 @@ export interface FetchFolderElementsPayload { folderId?: string; } +export interface FetchFolderElementsPaginationPayload { + pageNum?: number; + pageSize?: number; + name?: string; + applicationType?: string; +} + export const fetchFolderElements = ( payload: FetchFolderElementsPayload ): ReduxAction => { From fd62105fce70a7179caa3f7cb511158737e00195 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Tue, 26 Nov 2024 23:38:05 -0500 Subject: [PATCH 05/38] Implemented pagination in trash. --- .../lowcoder/src/api/applicationApi.ts | 7 ++- .../src/pages/ApplicationV2/BackButton.tsx | 4 ++ .../src/pages/ApplicationV2/HomeLayout.tsx | 53 ++++++++++++++---- .../src/pages/ApplicationV2/HomeView.tsx | 5 +- .../src/pages/ApplicationV2/TrashView.tsx | 56 +++++++++++++++---- .../redux/reduxActions/applicationActions.ts | 7 +++ .../lowcoder/src/util/pagination/axios.ts | 22 ++++++++ 7 files changed, 127 insertions(+), 27 deletions(-) create mode 100644 client/packages/lowcoder/src/pages/ApplicationV2/BackButton.tsx diff --git a/client/packages/lowcoder/src/api/applicationApi.ts b/client/packages/lowcoder/src/api/applicationApi.ts index a0edb7424..7fbf45975 100644 --- a/client/packages/lowcoder/src/api/applicationApi.ts +++ b/client/packages/lowcoder/src/api/applicationApi.ts @@ -5,6 +5,7 @@ import { DeleteApplicationPayload, DeleteAppPermissionPayload, FetchAppInfoPayload, + FetchApplicationElementsPaginationPayload, HomeDataPayload, PublishApplicationPayload, RecycleApplicationPayload, @@ -12,7 +13,7 @@ import { SetAppEditingStatePayload, UpdateAppPermissionPayload, } from "redux/reduxActions/applicationActions"; -import { ApiResponse, GenericApiResponse } from "./apiResponses"; +import {ApiResponse, GenericApiPaginationResponse, GenericApiResponse} from "./apiResponses"; import { JSONObject, JSONValue } from "util/jsonTypes"; import { ApplicationDetail, @@ -108,6 +109,10 @@ class ApplicationApi extends Api { return Api.get(ApplicationApi.newURLPrefix + "/list", { ...request, withContainerSize: false }); } + static fetchAllApplicationsPagination(request: FetchApplicationElementsPaginationPayload): AxiosPromise> { + return Api.get(ApplicationApi.newURLPrefix + "/list", { ...request, withContainerSize: false, applicationStatus: "RECYCLED" }); + } + static fetchAllModules(request: HomeDataPayload): AxiosPromise { return Api.get(ApplicationApi.newURLPrefix + "/list", { applicationType: AppTypeEnum.Module, diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/BackButton.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/BackButton.tsx new file mode 100644 index 000000000..65952d07c --- /dev/null +++ b/client/packages/lowcoder/src/pages/ApplicationV2/BackButton.tsx @@ -0,0 +1,4 @@ +export const BackButton = () =>{ + return +
123
+} \ No newline at end of file diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx index 8fe7c49b5..6b57c31ce 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx @@ -313,9 +313,9 @@ export interface HomeLayoutProps { currentPage?: number; pageSize?: number; total?: number; + searchValues?: number; setSearchValues?: any; - typeFilter?: number; - setTypeFilter?: any; + setTypeFilterPagination?: any; } export function HomeLayout(props: HomeLayoutProps) { @@ -328,10 +328,11 @@ export function HomeLayout(props: HomeLayoutProps) { setPageSize, pageSize, currentPage, + searchValues, setSearchValues, total, - typeFilter, - setTypeFilter, + setTypeFilterPagination, + } = props; console.log("elements", elements, total); const handlePageChange = (page: number) => { @@ -357,9 +358,10 @@ export function HomeLayout(props: HomeLayoutProps) { const user = useSelector(getUser); const isFetching = useSelector(isFetchingFolderElements); const isSelfHost = window.location.host !== 'app.lowcoder.cloud'; + const [typeFilter, setTypeFilter] = useState("All"); const [categoryFilter, setCategoryFilter] = useState("All"); const [searchValue, setSearchValue] = useState(""); - const [visibility, setVisibility] = useState(mode !== "marketplace"); + const [visibility, setVisibility] = useState(mode === "view" || mode === "trash"); const [layout, setLayout] = useState( checkIsMobile(window.innerWidth) ? "card" : getHomeLayout() ); @@ -379,11 +381,11 @@ export function HomeLayout(props: HomeLayoutProps) { var displayElements = elements.sort((a, b) => { if (a.folder && !b.folder) { - return -1; // a is a folder and should come first + return -1; } else if (!a.folder && b.folder) { - return 1; // b is a folder and should come first + return 1; } else { - return 0; // both are folders or both are not, keep original order + return 0; } }); @@ -398,6 +400,33 @@ export function HomeLayout(props: HomeLayoutProps) { displayElements = [...markedLocalApps]; } const resList: HomeRes[] = displayElements + .filter((e) => { + if (!visibility) { + if (searchValue) { + const lowerCaseSearchValue = searchValue.toLocaleLowerCase(); + return e.name?.toLocaleLowerCase().includes(lowerCaseSearchValue) || + e.createBy?.toLocaleLowerCase().includes(lowerCaseSearchValue); + } + return true; + } + return true; + }) + .filter((e) => { + if(!visibility) { + if (HomeResTypeEnum[typeFilter].valueOf() === HomeResTypeEnum.All) { + return true; + } + if (e.folder) { + return HomeResTypeEnum[typeFilter] === HomeResTypeEnum.Folder; + } else { + if (typeFilter === "Navigation") { + return NavigationTypes.map((t) => t.valueOf()).includes(e.applicationType); + } + return HomeResTypeEnum[typeFilter].valueOf() === e.applicationType; + } + } + return true; + }) .filter((e) => { // If "All" is selected, do not filter out any elements based on category if (categoryFilter === 'All' || !categoryFilter) { @@ -503,10 +532,12 @@ export function HomeLayout(props: HomeLayoutProps) { {mode !== "folders" && mode !== "module" && ( { - console.log(HomeResTypeEnum[value]) - setTypeFilter(HomeResTypeEnum[value])} + setTypeFilter(value as HomeResKey); + if(visibility) + setTypeFilterPagination(HomeResTypeEnum[value]) + } } options={[ getFilterMenuItem(HomeResTypeEnum.All), diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx index 7fd27ae1c..f32ec8453 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx @@ -21,7 +21,6 @@ export function HomeView() { const [typeFilter, setTypeFilter] = useState(0); useEffect( () => { try{ - fetchFolderElements({ pageNum:currentPage, pageSize:pageSize, @@ -29,7 +28,6 @@ export function HomeView() { name: searchValues, }).then( data => { - console.log(data) if (data.success) { setElements({elements: data.data || [], total: data.total || 1}) } @@ -63,8 +61,7 @@ export function HomeView() { setPageSize={setPageSize} total={elements.total} setSearchValues={setSearchValues} - typeFilter={typeFilter} - setTypeFilter={setTypeFilter} + setTypeFilterPagination={setTypeFilter} /> ); diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx index d1b0586c2..972288350 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx @@ -1,27 +1,61 @@ import { HomeLayout } from "./HomeLayout"; -import { useDispatch, useSelector } from "react-redux"; -import { recycleListSelector } from "../../redux/selectors/applicationSelector"; import { TRASH_URL } from "../../constants/routesURL"; -import { useEffect } from "react"; -import { fetchApplicationRecycleList } from "../../redux/reduxActions/applicationActions"; +import {useEffect, useState} from "react"; import { trans } from "../../i18n"; import { Helmet } from "react-helmet"; +import {fetchApplicationElements} from "@lowcoder-ee/util/pagination/axios"; + +interface ElementsState { + elements: any; + total: number; +} export function TrashView() { - const dispatch = useDispatch(); - const recycleList = useSelector(recycleListSelector); + const [elements, setElements] = useState({ elements: [], total: 1 }); + const [currentPage, setCurrentPage] = useState(1); + const [pageSize, setPageSize] = useState(10); + const [searchValues, setSearchValues] = useState(""); + const [typeFilter, setTypeFilter] = useState(0); - useEffect(() => { - dispatch(fetchApplicationRecycleList()); - }, [dispatch]); + useEffect( () => { + if (typeFilter === 7) // Application of Navigation is 3 in API. + setTypeFilter(3); + try{ + fetchApplicationElements({ + pageNum:currentPage, + pageSize:pageSize, + applicationType: typeFilter, + name: searchValues, + }).then( + data => { + if (data.success) { + setElements({elements: data.data || [], total: data.total || 1}) + } + else + console.error("ERROR: fetchFolderElements", data.error) + } + ); + } catch (error) { + console.error('Failed to fetch data:', error); + } + }, [currentPage, pageSize, searchValues, typeFilter] + ); return ( <> {{trans("home.trash")}} + mode={"trash"} + currentPage ={currentPage} + setCurrentPage={setCurrentPage} + pageSize={pageSize} + setPageSize={setPageSize} + total={elements.total} + setSearchValues={setSearchValues} + setTypeFilterPagination={setTypeFilter} + /> ); } diff --git a/client/packages/lowcoder/src/redux/reduxActions/applicationActions.ts b/client/packages/lowcoder/src/redux/reduxActions/applicationActions.ts index 83be6cdbb..99d5b0581 100644 --- a/client/packages/lowcoder/src/redux/reduxActions/applicationActions.ts +++ b/client/packages/lowcoder/src/redux/reduxActions/applicationActions.ts @@ -140,6 +140,13 @@ export type SetAppEditingStatePayload = { editingFinished: boolean; }; +export interface FetchApplicationElementsPaginationPayload { + pageNum?: number; + pageSize?: number; + name?: string; + applicationType?: number; +} + export const fetchApplicationInfo = (payload: FetchAppInfoPayload) => ({ type: ReduxActionTypes.FETCH_APPLICATION_DETAIL, payload: payload, diff --git a/client/packages/lowcoder/src/util/pagination/axios.ts b/client/packages/lowcoder/src/util/pagination/axios.ts index 67e22a7f5..c8421afbd 100644 --- a/client/packages/lowcoder/src/util/pagination/axios.ts +++ b/client/packages/lowcoder/src/util/pagination/axios.ts @@ -1,5 +1,9 @@ import { FolderApi } from "@lowcoder-ee/api/folderApi"; import { FetchFolderElementsPaginationPayload } from "@lowcoder-ee/redux/reduxActions/folderActions"; +import { + FetchApplicationElementsPaginationPayload, +} from "@lowcoder-ee/redux/reduxActions/applicationActions"; +import ApplicationApi from "@lowcoder-ee/api/applicationApi"; export const fetchFolderElements = async (request: FetchFolderElementsPaginationPayload) => { try { @@ -17,3 +21,21 @@ export const fetchFolderElements = async (request: FetchFolderElementsPagination }; } } + + +export const fetchApplicationElements = async (request: FetchApplicationElementsPaginationPayload)=> { + try { + const response = await ApplicationApi.fetchAllApplicationsPagination(request); + return { + success: true, + data: response.data.data, + total: response.data.total + } + } catch (error: any) { + console.error('Failed to fetch data:', error); + return { + success: false, + error: error + }; + } +} \ No newline at end of file From 3d9f56da8b114bd81f09c15189101413cb045141 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Wed, 27 Nov 2024 01:25:03 -0500 Subject: [PATCH 06/38] Imported types from util/pagination --- client/packages/lowcoder/src/api/apiResponses.ts | 8 -------- client/packages/lowcoder/src/api/applicationApi.ts | 6 +++--- client/packages/lowcoder/src/api/folderApi.ts | 9 ++++++--- .../src/redux/reduxActions/applicationActions.ts | 7 ------- .../lowcoder/src/redux/reduxActions/folderActions.ts | 7 ------- 5 files changed, 9 insertions(+), 28 deletions(-) diff --git a/client/packages/lowcoder/src/api/apiResponses.ts b/client/packages/lowcoder/src/api/apiResponses.ts index 0c702b1ab..5999bfcca 100644 --- a/client/packages/lowcoder/src/api/apiResponses.ts +++ b/client/packages/lowcoder/src/api/apiResponses.ts @@ -12,14 +12,6 @@ export interface GenericApiResponse { data: T; } -export interface GenericApiPaginationResponse { - total: number; - success: boolean; - code: number; - message: string; - data: T; -} - export interface FetchGroupApiResponse extends GenericApiResponse { totalAdmins: number, totalAdminsAndDevelopers: number, diff --git a/client/packages/lowcoder/src/api/applicationApi.ts b/client/packages/lowcoder/src/api/applicationApi.ts index 7fbf45975..2411b50d8 100644 --- a/client/packages/lowcoder/src/api/applicationApi.ts +++ b/client/packages/lowcoder/src/api/applicationApi.ts @@ -5,7 +5,6 @@ import { DeleteApplicationPayload, DeleteAppPermissionPayload, FetchAppInfoPayload, - FetchApplicationElementsPaginationPayload, HomeDataPayload, PublishApplicationPayload, RecycleApplicationPayload, @@ -13,7 +12,7 @@ import { SetAppEditingStatePayload, UpdateAppPermissionPayload, } from "redux/reduxActions/applicationActions"; -import {ApiResponse, GenericApiPaginationResponse, GenericApiResponse} from "./apiResponses"; +import {ApiResponse, GenericApiResponse} from "./apiResponses"; import { JSONObject, JSONValue } from "util/jsonTypes"; import { ApplicationDetail, @@ -25,6 +24,7 @@ import { } from "constants/applicationConstants"; import { CommonSettingResponseData } from "./commonSettingApi"; import { ResourceType } from "@lowcoder-ee/constants/queryConstants"; +import {fetchAppRequestType, GenericApiPaginationResponse} from "@lowcoder-ee/util/pagination/type"; export interface HomeOrgMeta { id: string; @@ -109,7 +109,7 @@ class ApplicationApi extends Api { return Api.get(ApplicationApi.newURLPrefix + "/list", { ...request, withContainerSize: false }); } - static fetchAllApplicationsPagination(request: FetchApplicationElementsPaginationPayload): AxiosPromise> { + static fetchAllApplicationsPagination(request: fetchAppRequestType): AxiosPromise> { return Api.get(ApplicationApi.newURLPrefix + "/list", { ...request, withContainerSize: false, applicationStatus: "RECYCLED" }); } diff --git a/client/packages/lowcoder/src/api/folderApi.ts b/client/packages/lowcoder/src/api/folderApi.ts index 10c6fef20..30aef9251 100644 --- a/client/packages/lowcoder/src/api/folderApi.ts +++ b/client/packages/lowcoder/src/api/folderApi.ts @@ -1,15 +1,18 @@ import Api from "./api"; import { AxiosPromise } from "axios"; -import {GenericApiPaginationResponse, GenericApiResponse} from "./apiResponses"; +import { GenericApiResponse } from "./apiResponses"; import { CreateFolderPayload, DeleteFolderPayload, - FetchFolderElementsPaginationPayload, FetchFolderElementsPayload, MoveToFolderPayload, UpdateFolderPayload, } from "../redux/reduxActions/folderActions"; import { ApplicationMeta, FolderMeta } from "../constants/applicationConstants"; +import { + fetchFolderRequestType, + GenericApiPaginationResponse +} from "@lowcoder-ee/util/pagination/type"; export class FolderApi extends Api { static url = "/folders"; @@ -43,7 +46,7 @@ export class FolderApi extends Api { } static fetchFolderElementsPagination( - request: FetchFolderElementsPaginationPayload + request: fetchFolderRequestType ): AxiosPromise> { return Api.get(FolderApi.url + `/elements`, { ...request }); } diff --git a/client/packages/lowcoder/src/redux/reduxActions/applicationActions.ts b/client/packages/lowcoder/src/redux/reduxActions/applicationActions.ts index 99d5b0581..83be6cdbb 100644 --- a/client/packages/lowcoder/src/redux/reduxActions/applicationActions.ts +++ b/client/packages/lowcoder/src/redux/reduxActions/applicationActions.ts @@ -140,13 +140,6 @@ export type SetAppEditingStatePayload = { editingFinished: boolean; }; -export interface FetchApplicationElementsPaginationPayload { - pageNum?: number; - pageSize?: number; - name?: string; - applicationType?: number; -} - export const fetchApplicationInfo = (payload: FetchAppInfoPayload) => ({ type: ReduxActionTypes.FETCH_APPLICATION_DETAIL, payload: payload, diff --git a/client/packages/lowcoder/src/redux/reduxActions/folderActions.ts b/client/packages/lowcoder/src/redux/reduxActions/folderActions.ts index a793ddee3..5c00aafe6 100644 --- a/client/packages/lowcoder/src/redux/reduxActions/folderActions.ts +++ b/client/packages/lowcoder/src/redux/reduxActions/folderActions.ts @@ -78,13 +78,6 @@ export interface FetchFolderElementsPayload { folderId?: string; } -export interface FetchFolderElementsPaginationPayload { - pageNum?: number; - pageSize?: number; - name?: string; - applicationType?: string; -} - export const fetchFolderElements = ( payload: FetchFolderElementsPayload ): ReduxAction => { From fa580fb49508c22eb76041d9a4cf9869033f090f Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Wed, 27 Nov 2024 01:26:18 -0500 Subject: [PATCH 07/38] Added utilities for pagination. --- .../src/util/pagination/Pagination.tsx | 52 +++++++++++++++++++ .../lowcoder/src/util/pagination/axios.ts | 11 ++-- .../lowcoder/src/util/pagination/type.ts | 24 ++++++++- 3 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 client/packages/lowcoder/src/util/pagination/Pagination.tsx diff --git a/client/packages/lowcoder/src/util/pagination/Pagination.tsx b/client/packages/lowcoder/src/util/pagination/Pagination.tsx new file mode 100644 index 000000000..fe93dfc93 --- /dev/null +++ b/client/packages/lowcoder/src/util/pagination/Pagination.tsx @@ -0,0 +1,52 @@ +import styled from "styled-components"; +import { Pagination } from "antd"; + +const PaginationLayout = styled(Pagination)` + display: flex; + justify-content: center; + margin-top: 40px; + margin-bottom: 20px; +`; + +interface PaginationCompProps { + setCurrentPage: (page: number) => void; + setPageSize: (size: number) => void; + currentPage: number; + pageSize: number; + total: number; +} + +const PaginationComp = (props: PaginationCompProps) => { + const { + setCurrentPage, + setPageSize, + currentPage, + pageSize, + total, + } = props; + + const handlePageChange = (page: number, pageSize: number | undefined) => { + if (setCurrentPage) { + setCurrentPage(page); + } + }; + + const handlePageSizeChange = (current: number, size: number) => { + if (setPageSize) { + setPageSize(size); + } + }; + + return ( + + ); +}; + +export default PaginationComp; \ No newline at end of file diff --git a/client/packages/lowcoder/src/util/pagination/axios.ts b/client/packages/lowcoder/src/util/pagination/axios.ts index c8421afbd..430d64ea7 100644 --- a/client/packages/lowcoder/src/util/pagination/axios.ts +++ b/client/packages/lowcoder/src/util/pagination/axios.ts @@ -1,11 +1,10 @@ import { FolderApi } from "@lowcoder-ee/api/folderApi"; -import { FetchFolderElementsPaginationPayload } from "@lowcoder-ee/redux/reduxActions/folderActions"; -import { - FetchApplicationElementsPaginationPayload, -} from "@lowcoder-ee/redux/reduxActions/applicationActions"; import ApplicationApi from "@lowcoder-ee/api/applicationApi"; +import {fetchAppRequestType, fetchFolderRequestType} from "@lowcoder-ee/util/pagination/type"; -export const fetchFolderElements = async (request: FetchFolderElementsPaginationPayload) => { + + +export const fetchFolderElements = async (request: fetchFolderRequestType) => { try { const response = await FolderApi.fetchFolderElementsPagination(request); return { @@ -23,7 +22,7 @@ export const fetchFolderElements = async (request: FetchFolderElementsPagination } -export const fetchApplicationElements = async (request: FetchApplicationElementsPaginationPayload)=> { +export const fetchApplicationElements = async (request: fetchAppRequestType)=> { try { const response = await ApplicationApi.fetchAllApplicationsPagination(request); return { diff --git a/client/packages/lowcoder/src/util/pagination/type.ts b/client/packages/lowcoder/src/util/pagination/type.ts index f73ddf306..e69e53adb 100644 --- a/client/packages/lowcoder/src/util/pagination/type.ts +++ b/client/packages/lowcoder/src/util/pagination/type.ts @@ -11,4 +11,26 @@ export const ApplicationPaginationType: ApplicationType = { 4: "FOLDER", 6: "MOBILETABLAYOUT", 7: "NAVIGATION", -}; \ No newline at end of file +}; + +export interface fetchAppRequestType { + pageNum?: number; + pageSize?: number; + name?: string; + applicationType?: number; +} + +export interface fetchFolderRequestType { + pageNum?: number; + pageSize?: number; + name?: string; + applicationType?: string; +} + +export interface GenericApiPaginationResponse { + total: number; + success: boolean; + code: number; + message: string; + data: T; +} \ No newline at end of file From 7bc6eb6776e7423b0162e958de0506b7960364cf Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Wed, 27 Nov 2024 02:44:00 -0500 Subject: [PATCH 08/38] Implemented pagination in User Group List. --- client/packages/lowcoder/src/api/orgApi.ts | 5 ++ .../src/pages/ApplicationV2/HomeLayout.tsx | 1 - .../src/pages/ApplicationV2/TrashView.tsx | 20 +++---- .../setting/permission/permissionList.tsx | 58 ++++++++++++++----- .../lowcoder/src/util/pagination/axios.ts | 24 ++++++-- .../lowcoder/src/util/pagination/type.ts | 20 ++++--- 6 files changed, 90 insertions(+), 38 deletions(-) diff --git a/client/packages/lowcoder/src/api/orgApi.ts b/client/packages/lowcoder/src/api/orgApi.ts index 6e7c532e4..08865e3e0 100644 --- a/client/packages/lowcoder/src/api/orgApi.ts +++ b/client/packages/lowcoder/src/api/orgApi.ts @@ -10,6 +10,7 @@ import { UpdateUserOrgRolePayload, } from "redux/reduxActions/orgActions"; import { ApiResponse, GenericApiResponse } from "./apiResponses"; +import {GenericApiPaginationResponse, orgGroupRequestType} from "@lowcoder-ee/util/pagination/type"; export interface GroupUsersResponse extends ApiResponse { data: { @@ -66,6 +67,10 @@ export class OrgApi extends Api { return Api.get(OrgApi.fetchGroupURL); } + static fetchGroupPagination(request: orgGroupRequestType): AxiosPromise> { + return Api.get(OrgApi.fetchGroupURL, {...request}); + } + static deleteGroup(groupId: string): AxiosPromise { return Api.delete(OrgApi.deleteGroupURL(groupId)); } diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx index 6b57c31ce..c9d8dee64 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx @@ -334,7 +334,6 @@ export function HomeLayout(props: HomeLayoutProps) { setTypeFilterPagination, } = props; - console.log("elements", elements, total); const handlePageChange = (page: number) => { setCurrentPage(page); }; diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx index 972288350..a273f0cb3 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx @@ -45,16 +45,16 @@ export function TrashView() { <> {{trans("home.trash")}} ); diff --git a/client/packages/lowcoder/src/pages/setting/permission/permissionList.tsx b/client/packages/lowcoder/src/pages/setting/permission/permissionList.tsx index c72579a36..d8fc7759f 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/permissionList.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/permissionList.tsx @@ -21,7 +21,6 @@ import { } from "lowcoder-design"; import styled from "styled-components"; import { trans } from "i18n"; -import { getOrgGroups } from "redux/selectors/orgSelectors"; import { Table } from "components/Table"; import history from "util/history"; import { Level1SettingPageContentWithList, Level1SettingPageTitleWithBtn } from "../styled"; @@ -32,6 +31,8 @@ import { OrgGroup } from "constants/orgConstants"; import { messageInstance } from "lowcoder-design/src/components/GlobalInstances"; import InviteDialog from "pages/common/inviteDialog"; import { Flex } from "antd"; +import {fetchOrgGroups} from "@lowcoder-ee/util/pagination/axios"; +import PaginationComp from "@lowcoder-ee/util/pagination/Pagination"; const NEW_GROUP_PREFIX = trans("memberSettings.newGroupPrefix"); @@ -51,17 +52,48 @@ type DataItemInfo = { group?: OrgGroup; }; +interface ElementsState { + elements: OrgGroup[]; + total: number; +} + export default function PermissionSetting() { + let dataSource: DataItemInfo[] = []; const user = useSelector(getUser); const orgId = user.currentOrgId; - const orgGroups = useSelector(getOrgGroups); - const visibleOrgGroups = orgGroups.filter((g) => !g.allUsersGroup); - const allUsersGroup = orgGroups.find((g) => g.allUsersGroup); const dispatch = useDispatch(); const [needRenameId, setNeedRenameId] = useState(undefined); const { nameSuffixFunc, menuItemsFunc, menuExtraView } = usePermissionMenuItems(orgId); const [groupCreating, setGroupCreating] = useState(false); + const [elements, setElements] = useState({ elements: [], total: 0 }); + const [currentPage, setCurrentPage] = useState(1); + const [pageSize, setPageSize] = useState(10); + useEffect( () => { + fetchOrgGroups( + { + pageNum: currentPage, + pageSize: pageSize, + } + ).then(result => { + if (result.success){ + setElements({elements: result.data || [], total: result.total || 1}) + } + else + console.error("ERROR: fetchFolderElements", result.error) + }) + }, [currentPage, pageSize] + ) + const visibleOrgGroups = elements.elements.filter((g) => !g.allUsersGroup); + const allUsersGroup = elements.elements.find((g) => g.allUsersGroup); + dataSource = currentPage === 1 ? [{ + key: "users", + label: trans("memberSettings.allMembers"), + createTime: allUsersGroup?.createTime, + lock: true, + del: false, + rename: false, + }] : []; useEffect(() => { if (!orgId) { return; @@ -105,17 +137,6 @@ export default function PermissionSetting() { }); }; - const dataSource: DataItemInfo[] = [ - { - key: "users", - label: trans("memberSettings.allMembers"), - createTime: allUsersGroup?.createTime, - lock: true, - del: false, - rename: false, - }, - ]; - visibleOrgGroups.forEach((group) => { dataSource.push({ key: group.groupId, @@ -255,6 +276,13 @@ export default function PermissionSetting() { />
{menuExtraView} + ); } diff --git a/client/packages/lowcoder/src/util/pagination/axios.ts b/client/packages/lowcoder/src/util/pagination/axios.ts index 430d64ea7..a3300ef0b 100644 --- a/client/packages/lowcoder/src/util/pagination/axios.ts +++ b/client/packages/lowcoder/src/util/pagination/axios.ts @@ -1,8 +1,7 @@ import { FolderApi } from "@lowcoder-ee/api/folderApi"; import ApplicationApi from "@lowcoder-ee/api/applicationApi"; -import {fetchAppRequestType, fetchFolderRequestType} from "@lowcoder-ee/util/pagination/type"; - - +import {fetchAppRequestType, fetchFolderRequestType, orgGroupRequestType} from "@lowcoder-ee/util/pagination/type"; +import OrgApi from "@lowcoder-ee/api/orgApi"; export const fetchFolderElements = async (request: fetchFolderRequestType) => { try { @@ -21,7 +20,6 @@ export const fetchFolderElements = async (request: fetchFolderRequestType) => { } } - export const fetchApplicationElements = async (request: fetchAppRequestType)=> { try { const response = await ApplicationApi.fetchAllApplicationsPagination(request); @@ -37,4 +35,22 @@ export const fetchApplicationElements = async (request: fetchAppRequestType)=> { error: error }; } +} + +export const fetchOrgGroups = async (request: orgGroupRequestType) => { + try{ + const response = await OrgApi.fetchGroupPagination(request); + return { + success: true, + data:response.data.data, + total:response.data.total + } + } + catch (error: any) { + console.error('Failed to fetch data:', error); + return { + success: false, + error: error + }; + } } \ No newline at end of file diff --git a/client/packages/lowcoder/src/util/pagination/type.ts b/client/packages/lowcoder/src/util/pagination/type.ts index e69e53adb..4da66aeb6 100644 --- a/client/packages/lowcoder/src/util/pagination/type.ts +++ b/client/packages/lowcoder/src/util/pagination/type.ts @@ -2,7 +2,14 @@ type ApplicationType = { [key: number]: string; // This allows numeric indexing }; -// Define the const with explicit type +export interface GenericApiPaginationResponse { + total: number; + success: boolean; + code: number; + message: string; + data: T; +} + export const ApplicationPaginationType: ApplicationType = { 0: "", 1: "APPLICATION", @@ -27,10 +34,7 @@ export interface fetchFolderRequestType { applicationType?: string; } -export interface GenericApiPaginationResponse { - total: number; - success: boolean; - code: number; - message: string; - data: T; -} \ No newline at end of file +export interface orgGroupRequestType{ + pageNum?: number; + pageSize?: number; +} From 41927a30431bb44f272abeb9cd5f66a0e2865dec Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Wed, 27 Nov 2024 04:37:32 -0500 Subject: [PATCH 09/38] Implemented pagination in Data Sources. --- .../lowcoder/src/api/datasourceApi.ts | 6 ++ .../src/pages/datasource/datasourceList.tsx | 62 ++++++++++++++----- .../setting/permission/orgUsersPermission.tsx | 5 ++ .../lowcoder/src/util/pagination/axios.ts | 25 +++++++- .../lowcoder/src/util/pagination/type.ts | 8 +++ 5 files changed, 90 insertions(+), 16 deletions(-) diff --git a/client/packages/lowcoder/src/api/datasourceApi.ts b/client/packages/lowcoder/src/api/datasourceApi.ts index ea08bb934..d5973c0e9 100644 --- a/client/packages/lowcoder/src/api/datasourceApi.ts +++ b/client/packages/lowcoder/src/api/datasourceApi.ts @@ -8,6 +8,7 @@ import { JSONArray } from "util/jsonTypes"; import { AuthType, HttpOAuthGrantType } from "pages/datasource/form/httpDatasourceForm"; import { Datasource } from "@lowcoder-ee/constants/datasourceConstants"; import { DataSourcePluginMeta } from "lowcoder-sdk/dataSource"; +import {fetchDBRequestType, GenericApiPaginationResponse} from "@lowcoder-ee/util/pagination/type"; export interface PreparedStatementConfig { enableTurnOffPreparedStatement: boolean; @@ -172,6 +173,11 @@ export class DatasourceApi extends Api { return Api.get(DatasourceApi.url + `/listByOrg?orgId=${orgId}`); } + static fetchDatasourcePaginationByOrg(request: fetchDBRequestType): AxiosPromise> { + const {orgId, ...res} = request; + return Api.get(DatasourceApi.url + `/listByOrg?orgId=${orgId}`, {...res}); + } + static createDatasource( datasourceConfig: Partial ): AxiosPromise> { diff --git a/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx b/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx index 87fb7ec08..01c086163 100644 --- a/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx +++ b/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx @@ -1,6 +1,6 @@ import styled from "styled-components"; import { EditPopover, PointIcon, Search, TacoButton } from "lowcoder-design"; -import React, { useState } from "react"; +import React, {useEffect, useState} from "react"; import { useDispatch, useSelector } from "react-redux"; import { getDataSource, getDataSourceLoading, getDataSourceTypesMap } from "../../redux/selectors/datasourceSelectors"; import { deleteDatasource } from "../../redux/reduxActions/datasourceActions"; @@ -17,6 +17,10 @@ import { DatasourcePermissionDialog } from "../../components/PermissionDialog/Da import DataSourceIcon from "components/DataSourceIcon"; import { Helmet } from "react-helmet"; import LoadingOutlined from "@ant-design/icons/LoadingOutlined"; +import PaginationComp from "@lowcoder-ee/util/pagination/Pagination"; +import {DatasourceInfo} from "@lowcoder-ee/api/datasourceApi"; +import {fetchDatasourcePagination} from "@lowcoder-ee/util/pagination/axios"; +import {getUser} from "@lowcoder-ee/redux/selectors/usersSelectors"; const DatasourceWrapper = styled.div` display: flex; @@ -103,11 +107,41 @@ const StyledTable = styled(Table)` export const DatasourceList = () => { const dispatch = useDispatch(); const [searchValue, setSearchValue] = useState(""); + const [searchValues, setSearchValues] = useState(""); const [isCreateFormShow, showCreateForm] = useState(false); const [shareDatasourceId, setShareDatasourceId] = useState(undefined); const datasource = useSelector(getDataSource); + const currentUser = useSelector(getUser); + const orgId = currentUser.currentOrgId; const datasourceLoading = useSelector(getDataSourceLoading); const plugins = useSelector(getDataSourceTypesMap); + interface ElementsState { + elements: DatasourceInfo[]; + total: number; + } + console.log(datasource); + + const [elements, setElements] = useState({ elements: [], total: 0 }); + const [currentPage, setCurrentPage] = useState(1); + const [pageSize, setPageSize] = useState(10); + + useEffect( () => { + fetchDatasourcePagination( + { + orgId: orgId, + pageNum: currentPage, + pageSize: pageSize, + name: searchValues + } + ).then(result => { + if (result.success){ + setElements({elements: result.data || [], total: result.total || 1}) + } + else + console.error("ERROR: fetchFolderElements", result.error) + }) + }, [currentPage, pageSize, searchValues] + ) return ( <> @@ -140,6 +174,7 @@ export const DatasourceList = () => { placeholder={trans("search")} value={searchValue} onChange={(e) => setSearchValue(e.target.value)} + onEnterPress={(value) => setSearchValues(value)} style={{ width: "192px", height: "32px", margin: "0 12px 0 0" }} /> showCreateForm(true)}> {trans("home.newDatasource")} @@ -267,19 +302,7 @@ export const DatasourceList = () => { ), }, ]} - dataSource={datasource - .filter((info) => { - if (info.datasource.creationSource === 2) { - return false; - } - if (!isEmpty(searchValue)) { - return ( - info.datasource.name.toLowerCase().includes(searchValue.trim().toLowerCase()) || - info.datasource.type.toLowerCase().includes(searchValue.trim().toLowerCase()) - ); - } - return true; - }) + dataSource={elements.elements .map((info, i) => ({ key: i, id: info.datasource.id, @@ -296,6 +319,13 @@ export const DatasourceList = () => { creator: info.creatorName, edit: info.edit, }))} /> + {shareDatasourceId && ( { !visible && setShareDatasourceId(undefined); } } /> )} - + + + ); }; diff --git a/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx b/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx index 992e7e0f8..32481f5c6 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx @@ -300,6 +300,11 @@ function OrgUsersPermission(props: UsersPermissionProp) { } const mapStateToProps = (state: AppState) => { + console.log({ + orgUsersFetching: state.ui.org.orgUsersFetching, + orgUsers: state.ui.org.orgUsers, + currentUser: getUser(state), + }) return { orgUsersFetching: state.ui.org.orgUsersFetching, orgUsers: state.ui.org.orgUsers, diff --git a/client/packages/lowcoder/src/util/pagination/axios.ts b/client/packages/lowcoder/src/util/pagination/axios.ts index a3300ef0b..1b1d01c7e 100644 --- a/client/packages/lowcoder/src/util/pagination/axios.ts +++ b/client/packages/lowcoder/src/util/pagination/axios.ts @@ -1,7 +1,13 @@ import { FolderApi } from "@lowcoder-ee/api/folderApi"; import ApplicationApi from "@lowcoder-ee/api/applicationApi"; -import {fetchAppRequestType, fetchFolderRequestType, orgGroupRequestType} from "@lowcoder-ee/util/pagination/type"; +import { + fetchAppRequestType, + fetchDBRequestType, + fetchFolderRequestType, + orgGroupRequestType +} from "@lowcoder-ee/util/pagination/type"; import OrgApi from "@lowcoder-ee/api/orgApi"; +import { DatasourceApi } from "@lowcoder-ee/api/datasourceApi"; export const fetchFolderElements = async (request: fetchFolderRequestType) => { try { @@ -53,4 +59,21 @@ export const fetchOrgGroups = async (request: orgGroupRequestType) => { error: error }; } +} + +export const fetchDatasourcePagination = async (request: fetchDBRequestType)=> { + try { + const response = await DatasourceApi.fetchDatasourcePaginationByOrg(request); + return { + success: true, + data: response.data.data, + total: response.data.total + } + } catch (error: any) { + console.error('Failed to fetch data:', error); + return { + success: false, + error: error + }; + } } \ No newline at end of file diff --git a/client/packages/lowcoder/src/util/pagination/type.ts b/client/packages/lowcoder/src/util/pagination/type.ts index 4da66aeb6..b2c8872c5 100644 --- a/client/packages/lowcoder/src/util/pagination/type.ts +++ b/client/packages/lowcoder/src/util/pagination/type.ts @@ -34,6 +34,14 @@ export interface fetchFolderRequestType { applicationType?: string; } +export interface fetchDBRequestType { + orgId: string; + pageNum?: number; + pageSize?: number; + name?: string; + type?: string; +} + export interface orgGroupRequestType{ pageNum?: number; pageSize?: number; From f2140e4d42d774f4d333abf84a4393a210f56f75 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Wed, 27 Nov 2024 15:22:21 -0500 Subject: [PATCH 10/38] Implemented pagination in groupUsersPermission. --- client/packages/lowcoder/src/api/orgApi.ts | 12 +++- .../permission/groupUsersPermission.tsx | 15 +--- .../setting/permission/permissionDetail.tsx | 70 +++++++++++++++---- .../lowcoder/src/util/pagination/axios.ts | 18 +++++ .../lowcoder/src/util/pagination/type.ts | 15 ++++ 5 files changed, 102 insertions(+), 28 deletions(-) diff --git a/client/packages/lowcoder/src/api/orgApi.ts b/client/packages/lowcoder/src/api/orgApi.ts index 08865e3e0..019fba076 100644 --- a/client/packages/lowcoder/src/api/orgApi.ts +++ b/client/packages/lowcoder/src/api/orgApi.ts @@ -10,7 +10,12 @@ import { UpdateUserOrgRolePayload, } from "redux/reduxActions/orgActions"; import { ApiResponse, GenericApiResponse } from "./apiResponses"; -import {GenericApiPaginationResponse, orgGroupRequestType} from "@lowcoder-ee/util/pagination/type"; +import { + fetchOrgUserRequestType, + GenericApiPaginationResponse, + GroupUsersPaginationResponse, + orgGroupRequestType +} from "@lowcoder-ee/util/pagination/type"; export interface GroupUsersResponse extends ApiResponse { data: { @@ -97,6 +102,11 @@ export class OrgApi extends Api { return Api.get(OrgApi.fetchGroupUsersURL(groupId)); } + static fetchGroupUsersPagination(request: fetchOrgUserRequestType): AxiosPromise { + const {groupId, ...res} = request; + return Api.get(OrgApi.fetchGroupUsersURL(groupId), {...res}); + } + static deleteGroupUser(request: RemoveGroupUserPayload): AxiosPromise { return Api.delete(OrgApi.deleteGroupUserURL(request.groupId), { userId: request.userId, diff --git a/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx b/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx index c0f7c79d8..02c4a3c90 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx @@ -4,15 +4,13 @@ import { AddIcon, ArrowIcon, CustomSelect, PackUpIcon, SuperUserIcon } from "low import { trans } from "i18n"; import ProfileImage from "pages/common/profileImage"; import React, { useEffect, useMemo } from "react"; -import { connect, useDispatch } from "react-redux"; -import { AppState } from "redux/reducers"; +import { useDispatch } from "react-redux"; import { deleteGroupUserAction, fetchGroupUsersAction, quitGroupAction, updateUserGroupRoleAction, } from "redux/reduxActions/orgActions"; -import { getUser } from "redux/selectors/usersSelectors"; import styled from "styled-components"; import { formatTimestamp } from "util/dateTimeUtils"; import { currentOrgAdmin, isGroupAdmin } from "util/permissionUtils"; @@ -208,13 +206,4 @@ function GroupUsersPermission(props: GroupPermissionProp) { ); } -const mapStateToProps = (state: AppState) => { - return { - groupUsers: state.ui.org.groupUsers, - groupUsersFetching: state.ui.org.groupUsersFetching, - currentUser: getUser(state), - currentUserGroupRole: state.ui.org.currentUserGroupRole, - }; -}; - -export default connect(mapStateToProps)(GroupUsersPermission); +export default GroupUsersPermission; diff --git a/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx b/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx index 2e190121e..4e551b62f 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx @@ -1,4 +1,4 @@ -import { useEffect } from "react"; +import React, {useEffect, useState} from "react"; import { useDispatch, useSelector } from "react-redux"; import { fetchGroupsAction } from "redux/reduxActions/orgActions"; import { getUser } from "redux/selectors/usersSelectors"; @@ -6,7 +6,11 @@ import styled from "styled-components"; import GroupPermission from "./groupUsersPermission"; import UsersPermission from "./orgUsersPermission"; import { getOrgGroups } from "redux/selectors/orgSelectors"; -import { useParams } from "react-router"; +import { useParams } from "react-router-dom"; +import { AppState } from "redux/reducers"; +import {fetchGroupUsrPagination} from "@lowcoder-ee/util/pagination/axios"; +import {OrgGroup} from "@lowcoder-ee/constants/orgConstants"; +import PaginationComp from "@lowcoder-ee/util/pagination/Pagination"; const PermissionContent = styled.div` display: flex; @@ -20,10 +24,18 @@ const PermissionContent = styled.div` const All_Users = "users"; -export default function PermissionSetting() { - const user = useSelector(getUser); +export default function PermissionSetting() { const user = useSelector(getUser); + + const [elements, setElements] = useState({ elements: [], total: 0 }); + const [currentPage, setCurrentPage] = useState(1); + const [pageSize, setPageSize] = useState(10); + const orgId = user.currentOrgId; const orgGroups = useSelector(getOrgGroups); + const groupUsers = useSelector((state: AppState) => state.ui.org.groupUsers); + const groupUsersFetching = useSelector((state: AppState) => state.ui.org.groupUsersFetching); + const currentUserGroupRole = useSelector((state: AppState) => state.ui.org.currentUserGroupRole); + const currentUser = useSelector(getUser); const groupIdMap = new Map(orgGroups.map((group) => [group.groupId, group])); const dispatch = useDispatch(); const selectKey = useParams<{ groupId: string }>().groupId; @@ -33,19 +45,49 @@ export default function PermissionSetting() { } dispatch(fetchGroupsAction(orgId)); }, [orgId]); + + useEffect( () => { + if (selectKey !== "users") + fetchGroupUsrPagination( + { + groupId: groupIdMap.get(selectKey)!.groupId, + pageNum: currentPage, + pageSize: pageSize, + } + ).then(result => { + if (result.success){ + setElements({elements: result.data || [], total: result.total || 1}) + } + else + console.error("ERROR: fetchFolderElements", result.error) + }) + }, [currentPage, pageSize] + ) + if (!orgId) { return null; } return ( - - {selectKey === All_Users ? ( - - ) : ( - groupIdMap.has(selectKey) && ( - - ) - )} - + + {selectKey === All_Users ? ( + + ) : ( + groupIdMap.has(selectKey) && ( + <> + + + + + ) + )} + ); -} +} \ No newline at end of file diff --git a/client/packages/lowcoder/src/util/pagination/axios.ts b/client/packages/lowcoder/src/util/pagination/axios.ts index 1b1d01c7e..c980b060a 100644 --- a/client/packages/lowcoder/src/util/pagination/axios.ts +++ b/client/packages/lowcoder/src/util/pagination/axios.ts @@ -4,6 +4,7 @@ import { fetchAppRequestType, fetchDBRequestType, fetchFolderRequestType, + fetchOrgUserRequestType, orgGroupRequestType } from "@lowcoder-ee/util/pagination/type"; import OrgApi from "@lowcoder-ee/api/orgApi"; @@ -76,4 +77,21 @@ export const fetchDatasourcePagination = async (request: fetchDBRequestType)=> { error: error }; } +} + +export const fetchGroupUsrPagination = async (request: fetchOrgUserRequestType)=> { + try { + const response = await OrgApi.fetchGroupUsersPagination(request); + return { + success: true, + data: response.data.data, + total: response.data.total + } + } catch (error: any) { + console.error('Failed to fetch data:', error); + return { + success: false, + error: error + }; + } } \ No newline at end of file diff --git a/client/packages/lowcoder/src/util/pagination/type.ts b/client/packages/lowcoder/src/util/pagination/type.ts index b2c8872c5..e5e1c466b 100644 --- a/client/packages/lowcoder/src/util/pagination/type.ts +++ b/client/packages/lowcoder/src/util/pagination/type.ts @@ -1,3 +1,5 @@ +import {GroupUser} from "@lowcoder-ee/constants/orgConstants"; + type ApplicationType = { [key: number]: string; // This allows numeric indexing }; @@ -9,6 +11,14 @@ export interface GenericApiPaginationResponse { message: string; data: T; } +export interface GroupUsersPaginationResponse { + total: number; + success: boolean; + data: { + members: GroupUser[]; + visitorRole: string; + }; +} export const ApplicationPaginationType: ApplicationType = { 0: "", @@ -46,3 +56,8 @@ export interface orgGroupRequestType{ pageNum?: number; pageSize?: number; } +export interface fetchOrgUserRequestType { + groupId: string; + pageNum?: number; + pageSize?: number; +} From 8c82fd1fced3475320aa3cd93b8a15483b4d40ed Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Thu, 28 Nov 2024 00:59:50 -0500 Subject: [PATCH 11/38] Implemented pagination in organizations's member. --- client/packages/lowcoder/src/api/orgApi.ts | 10 ++++- .../setting/permission/orgUsersPermission.tsx | 19 +-------- .../setting/permission/permissionDetail.tsx | 41 +++++++++++++++---- .../lowcoder/src/util/pagination/axios.ts | 26 ++++++++++-- .../lowcoder/src/util/pagination/type.ts | 19 ++++++++- 5 files changed, 83 insertions(+), 32 deletions(-) diff --git a/client/packages/lowcoder/src/api/orgApi.ts b/client/packages/lowcoder/src/api/orgApi.ts index 019fba076..5e650417d 100644 --- a/client/packages/lowcoder/src/api/orgApi.ts +++ b/client/packages/lowcoder/src/api/orgApi.ts @@ -11,10 +11,11 @@ import { } from "redux/reduxActions/orgActions"; import { ApiResponse, GenericApiResponse } from "./apiResponses"; import { + fetchGroupUserRequestType, fetchOrgUserRequestType, GenericApiPaginationResponse, GroupUsersPaginationResponse, - orgGroupRequestType + orgGroupRequestType, OrgUsersPaginationResponse } from "@lowcoder-ee/util/pagination/type"; export interface GroupUsersResponse extends ApiResponse { @@ -98,11 +99,16 @@ export class OrgApi extends Api { return Api.get(OrgApi.fetchOrgUsersURL(orgId)); } + static fetchOrgUsersPagination(request:fetchOrgUserRequestType): AxiosPromise { + const {orgId, ...res} = request; + return Api.get(OrgApi.fetchOrgUsersURL(orgId), {...res}); + } + static fetchGroupUsers(groupId: string): AxiosPromise { return Api.get(OrgApi.fetchGroupUsersURL(groupId)); } - static fetchGroupUsersPagination(request: fetchOrgUserRequestType): AxiosPromise { + static fetchGroupUsersPagination(request: fetchGroupUserRequestType): AxiosPromise { const {groupId, ...res} = request; return Api.get(OrgApi.fetchGroupUsersURL(groupId), {...res}); } diff --git a/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx b/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx index 32481f5c6..0e42134d8 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx @@ -15,15 +15,13 @@ import { trans, transToNode } from "i18n"; import InviteDialog from "pages/common/inviteDialog"; import ProfileImage from "pages/common/profileImage"; import React, { useEffect, useMemo } from "react"; -import { connect, useDispatch, useSelector } from "react-redux"; -import { AppState } from "redux/reducers"; +import { useDispatch, useSelector } from "react-redux"; import { deleteOrgUserAction, fetchOrgUsersAction, quitOrgAction, updateUserOrgRoleAction, } from "redux/reduxActions/orgActions"; -import { getUser } from "redux/selectors/usersSelectors"; import styled from "styled-components"; import { formatTimestamp } from "util/dateTimeUtils"; import { currentOrgAdmin } from "util/permissionUtils"; @@ -299,17 +297,4 @@ function OrgUsersPermission(props: UsersPermissionProp) { ); } -const mapStateToProps = (state: AppState) => { - console.log({ - orgUsersFetching: state.ui.org.orgUsersFetching, - orgUsers: state.ui.org.orgUsers, - currentUser: getUser(state), - }) - return { - orgUsersFetching: state.ui.org.orgUsersFetching, - orgUsers: state.ui.org.orgUsers, - currentUser: getUser(state), - }; -}; - -export default connect(mapStateToProps)(OrgUsersPermission); +export default OrgUsersPermission; diff --git a/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx b/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx index 4e551b62f..1e71f216f 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx @@ -8,8 +8,7 @@ import UsersPermission from "./orgUsersPermission"; import { getOrgGroups } from "redux/selectors/orgSelectors"; import { useParams } from "react-router-dom"; import { AppState } from "redux/reducers"; -import {fetchGroupUsrPagination} from "@lowcoder-ee/util/pagination/axios"; -import {OrgGroup} from "@lowcoder-ee/constants/orgConstants"; +import {fetchGroupUsrPagination, fetchOrgUsrPagination} from "@lowcoder-ee/util/pagination/axios"; import PaginationComp from "@lowcoder-ee/util/pagination/Pagination"; const PermissionContent = styled.div` @@ -27,15 +26,17 @@ const All_Users = "users"; export default function PermissionSetting() { const user = useSelector(getUser); const [elements, setElements] = useState({ elements: [], total: 0 }); + const [orgMemberElements, setOrgMemberElements] = useState({ elements: [], total: 0 }) const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); const orgId = user.currentOrgId; const orgGroups = useSelector(getOrgGroups); - const groupUsers = useSelector((state: AppState) => state.ui.org.groupUsers); const groupUsersFetching = useSelector((state: AppState) => state.ui.org.groupUsersFetching); const currentUserGroupRole = useSelector((state: AppState) => state.ui.org.currentUserGroupRole); const currentUser = useSelector(getUser); + const orgUsersFetching = useSelector((state: AppState) => state.ui.org.orgUsersFetching); + const groupIdMap = new Map(orgGroups.map((group) => [group.groupId, group])); const dispatch = useDispatch(); const selectKey = useParams<{ groupId: string }>().groupId; @@ -60,8 +61,25 @@ export default function PermissionSetting() { const user = useSelector(getUser) } else console.error("ERROR: fetchFolderElements", result.error) - }) - }, [currentPage, pageSize] + } + ) + else + fetchOrgUsrPagination( + { + orgId: orgId, + pageNum: currentPage, + pageSize: pageSize, + } + ).then(result => { + if (result.success){ + setOrgMemberElements({elements: result.data || [], total: result.total || 1}) + } + else + console.error("ERROR: fetchFolderElements", result.error) + } + ) + }, + [currentPage, pageSize] ) if (!orgId) { @@ -71,14 +89,23 @@ export default function PermissionSetting() { const user = useSelector(getUser) return ( {selectKey === All_Users ? ( - + <> + + + ) : ( groupIdMap.has(selectKey) && ( <> { } } -export const fetchGroupUsrPagination = async (request: fetchOrgUserRequestType)=> { +export const fetchGroupUsrPagination = async (request: fetchGroupUserRequestType)=> { try { const response = await OrgApi.fetchGroupUsersPagination(request); return { success: true, - data: response.data.data, - total: response.data.total + data: response.data.data.members, + total: response.data.data.total + } + } catch (error: any) { + console.error('Failed to fetch data:', error); + return { + success: false, + error: error + }; + } +} + +export const fetchOrgUsrPagination = async (request: fetchOrgUserRequestType)=> { + try { + const response = await OrgApi.fetchOrgUsersPagination(request); + return { + success: true, + data: response.data.data.members, + total: response.data.data.total, } } catch (error: any) { console.error('Failed to fetch data:', error); @@ -94,4 +112,4 @@ export const fetchGroupUsrPagination = async (request: fetchOrgUserRequestType)= error: error }; } -} \ No newline at end of file +} diff --git a/client/packages/lowcoder/src/util/pagination/type.ts b/client/packages/lowcoder/src/util/pagination/type.ts index e5e1c466b..c3e7dde90 100644 --- a/client/packages/lowcoder/src/util/pagination/type.ts +++ b/client/packages/lowcoder/src/util/pagination/type.ts @@ -1,4 +1,4 @@ -import {GroupUser} from "@lowcoder-ee/constants/orgConstants"; +import {GroupUser, OrgUser} from "@lowcoder-ee/constants/orgConstants"; type ApplicationType = { [key: number]: string; // This allows numeric indexing @@ -12,11 +12,20 @@ export interface GenericApiPaginationResponse { data: T; } export interface GroupUsersPaginationResponse { - total: number; success: boolean; data: { members: GroupUser[]; visitorRole: string; + total: number; + }; +} + +export interface OrgUsersPaginationResponse { + success: boolean; + data: { + total: number; + members: OrgUser[]; + visitorRole: string; }; } @@ -57,6 +66,12 @@ export interface orgGroupRequestType{ pageSize?: number; } export interface fetchOrgUserRequestType { + orgId: string; + pageNum?: number; + pageSize?: number; +} + +export interface fetchGroupUserRequestType { groupId: string; pageNum?: number; pageSize?: number; From d65c2d57ddc4f1c7c11dc1533281ba6864d0fbf7 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Thu, 28 Nov 2024 11:10:15 -0500 Subject: [PATCH 12/38] Implemented pagination in Query Library and made fetchJsDatasourcePaginationByApp function. --- .../lowcoder/src/api/datasourceApi.ts | 11 +++- .../lowcoder/src/api/queryLibraryApi.ts | 5 ++ .../src/pages/ApplicationV2/HomeView.tsx | 2 - .../lowcoder/src/pages/editor/AppEditor.tsx | 23 +++++++- .../src/pages/queryLibrary/LeftNav.tsx | 20 ++++++- .../pages/queryLibrary/QueryLibraryEditor.tsx | 56 ++++++++++++++++--- .../src/util/pagination/Pagination.tsx | 56 +++++++++++++++---- .../lowcoder/src/util/pagination/axios.ts | 39 ++++++++++++- .../lowcoder/src/util/pagination/type.ts | 33 +++++++---- 9 files changed, 209 insertions(+), 36 deletions(-) diff --git a/client/packages/lowcoder/src/api/datasourceApi.ts b/client/packages/lowcoder/src/api/datasourceApi.ts index d5973c0e9..1be29e646 100644 --- a/client/packages/lowcoder/src/api/datasourceApi.ts +++ b/client/packages/lowcoder/src/api/datasourceApi.ts @@ -8,7 +8,11 @@ import { JSONArray } from "util/jsonTypes"; import { AuthType, HttpOAuthGrantType } from "pages/datasource/form/httpDatasourceForm"; import { Datasource } from "@lowcoder-ee/constants/datasourceConstants"; import { DataSourcePluginMeta } from "lowcoder-sdk/dataSource"; -import {fetchDBRequestType, GenericApiPaginationResponse} from "@lowcoder-ee/util/pagination/type"; +import { + fetchDataSourcePaginationRequestType, + fetchDBRequestType, + GenericApiPaginationResponse +} from "@lowcoder-ee/util/pagination/type"; export interface PreparedStatementConfig { enableTurnOffPreparedStatement: boolean; @@ -165,6 +169,11 @@ export class DatasourceApi extends Api { return Api.get(DatasourceApi.url + `/jsDatasourcePlugins?appId=${appId}`); } + static fetchJsDatasourcePaginationByApp( request: fetchDataSourcePaginationRequestType ): AxiosPromise> { + const {appId, ...res} = request + return Api.get(DatasourceApi.url + `/jsDatasourcePlugins?appId=${appId}` ,{...res}); + } + static fetchDatasourceByApp(appId: string): AxiosPromise> { return Api.get(DatasourceApi.url + `/listByApp?appId=${appId}`); } diff --git a/client/packages/lowcoder/src/api/queryLibraryApi.ts b/client/packages/lowcoder/src/api/queryLibraryApi.ts index 063cf6ecc..16e6a9dc0 100644 --- a/client/packages/lowcoder/src/api/queryLibraryApi.ts +++ b/client/packages/lowcoder/src/api/queryLibraryApi.ts @@ -2,6 +2,7 @@ import Api from "./api"; import { AxiosPromise } from "axios"; import { GenericApiResponse } from "./apiResponses"; import { DatasourceType } from "@lowcoder-ee/constants/queryConstants"; +import {fetchQueryLibraryPaginationRequestType, GenericApiPaginationResponse} from "@lowcoder-ee/util/pagination/type"; export interface LibraryQuery { id: string; @@ -49,6 +50,10 @@ export class QueryLibraryApi extends Api { return Api.get(QueryLibraryApi.url + `/listByOrg`); } + static fetchQueryLibraryPaginationByOrg(request: fetchQueryLibraryPaginationRequestType): AxiosPromise>> { + return Api.get(QueryLibraryApi.url + `/listByOrg`, {...request}); + } + static fetchQueryLibraryDropdown(): AxiosPromise< GenericApiResponse> > { diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx index f32ec8453..26bfb8384 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx @@ -41,8 +41,6 @@ export function HomeView() { }, [currentPage, pageSize, searchValues, typeFilter] ); - console.log(currentPage, pageSize); - const user = useSelector(getUser); if (!user.currentOrgId) { diff --git a/client/packages/lowcoder/src/pages/editor/AppEditor.tsx b/client/packages/lowcoder/src/pages/editor/AppEditor.tsx index 0af4823f1..512e2d8d1 100644 --- a/client/packages/lowcoder/src/pages/editor/AppEditor.tsx +++ b/client/packages/lowcoder/src/pages/editor/AppEditor.tsx @@ -37,6 +37,8 @@ import { currentApplication } from "@lowcoder-ee/redux/selectors/applicationSele import { notificationInstance } from "components/GlobalInstances"; import { AppState } from "@lowcoder-ee/redux/reducers"; import { resetIconDictionary } from "@lowcoder-ee/constants/iconConstants"; +import {fetchJsDSPaginationByApp} from "@lowcoder-ee/util/pagination/axios"; +import PaginationComp from "@lowcoder-ee/util/pagination/Pagination"; const AppSnapshot = lazy(() => { return import("pages/editor/appSnapshot") @@ -57,6 +59,9 @@ const AppEditor = React.memo(() => { const fetchOrgGroupsFinished = useSelector(getFetchOrgGroupsFinished); const isCommonSettingsFetching = useSelector(getIsCommonSettingFetching); const application = useSelector(currentApplication); + const [currentPage, setCurrentPage] = useState(1); + const [pageSize, setPageSize] = useState(10); + const [elements, setElements] = useState({ elements: [], total: 1 }) const isLowcoderCompLoading = useSelector((state: AppState) => state.npmPlugin.loading.lowcoderComps); const isUserViewMode = useMemo( @@ -140,8 +145,13 @@ const AppEditor = React.memo(() => { }, [dispatch, applicationId, paramViewMode]); const fetchJSDataSourceByApp = useCallback(() => { - DatasourceApi.fetchJsDatasourceByApp(applicationId).then((res) => { - res.data.data.forEach((i) => { + fetchJsDSPaginationByApp({ + appId: applicationId, + pageNum: currentPage, + pageSize: pageSize + }).then((res) => { + setElements({elements: [], total: res.total || 1}) + res.data!.forEach((i: any) => { registryDataSourcePlugin(i.type, i.id, i.pluginDefinition); }); setIsDataSourcePluginRegistered(true); @@ -153,6 +163,8 @@ const AppEditor = React.memo(() => { setIsDataSourcePluginRegistered, setShowAppSnapshot, dispatch, + currentPage, + pageSize ]); useEffect(() => { @@ -219,6 +231,13 @@ const AppEditor = React.memo(() => { return ( + {/**/} {showAppSnapshot ? ( }> ` display: flex; @@ -72,7 +73,7 @@ const CreateBtn = styled(TacoButton)<{ $readOnly?: boolean }>` `; const Body = styled.div` - height: calc(100% - 80px); + height: calc(100% - 120px); display: flex; flex-direction: column; `; @@ -158,7 +159,13 @@ export const LeftNav = (props: { addQuery: () => void; onSelect: (queryId: string) => void; readOnly?: boolean; + setCurrentPage: (page: number) => void; + setPageSize: (size: number) => void; + currentPage: number; + pageSize: number; + total: number; }) => { + const {currentPage, setCurrentPage, pageSize, setPageSize, total } = props const dispatch = useDispatch(); const [searchValue, setSearchValue] = useState(""); const datasourceTypes = useSelector(getDataSourceTypesMap); @@ -272,6 +279,17 @@ export const LeftNav = (props: { + ); diff --git a/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx b/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx index 9882c360a..19a0572f1 100644 --- a/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx +++ b/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx @@ -22,7 +22,7 @@ import { useCompInstance } from "../../comps/utils/useCompInstance"; import { QueryLibraryComp } from "../../comps/comps/queryLibrary/queryLibraryComp"; import { useSearchParam, useThrottle } from "react-use"; import { Comp } from "lowcoder-core"; -import { LibraryQuery } from "../../api/queryLibraryApi"; +import {LibraryQuery} from "../../api/queryLibraryApi"; import { NameGenerator } from "../../comps/utils"; import { QueryLibraryHistoryView } from "./QueryLibraryHistoryView"; import { default as Form } from "antd/es/form"; @@ -46,6 +46,7 @@ import { importQueryLibrary } from "./importQueryLibrary"; import { registryDataSourcePlugin } from "constants/queryConstants"; import { messageInstance } from "lowcoder-design/src/components/GlobalInstances"; import { Helmet } from "react-helmet"; +import {fetchQLPaginationByOrg} from "@lowcoder-ee/util/pagination/axios"; const Wrapper = styled.div` display: flex; @@ -59,9 +60,21 @@ const RightContent = styled.div` position: relative; `; +interface ElementsState { + elements: LibraryQuery[]; + total: number; +} + +function transformData(input: LibraryQuery[]) { + const output: any = {}; + input.forEach(item => { + output[item.id] = item; + }); + return output; +} + export const QueryLibraryEditor = () => { const dispatch = useDispatch(); - const queryLibrary = useSelector(getQueryLibrary); const queryLibraryRecords = useSelector(getQueryLibraryRecords); const originDatasourceInfo = useSelector(getDataSource); const currentUser = useSelector(getUser); @@ -74,6 +87,10 @@ export const QueryLibraryEditor = () => { const [publishModalVisible, setPublishModalVisible] = useState(false); const [showHistory, setShowHistory] = useState(false); const [isDataSourceReady, setIsDataSourceReady] = useState(false); + const [elements, setElements] = useState({ elements: [], total: 0 }); + const [queryLibrary, setQueryLibrary] = useState({}); + const [currentPage, setCurrentPage] = useState(1); + const [pageSize, setPageSize] = useState(10); const selectedRecords = queryLibraryRecords[selectedQuery] ?? {}; const libraryQuery = queryLibrary[selectedQuery]; @@ -98,6 +115,25 @@ export const QueryLibraryEditor = () => { const [comp, container] = useCompInstance(params); useSaveQueryLibrary(libraryQuery, comp); + useEffect(() => { + try { + fetchQLPaginationByOrg( + { + name: "", + pageNum: currentPage, + pageSize: pageSize, + } + ).then(result => { + if (result.success){ + setElements({elements: result.data || [], total: result.total || 1}) + setQueryLibrary(transformData(result.data || [])); + } + }); + } catch (error) { + console.error(error) + } + }, [currentPage, pageSize]) + useEffect(() => { if (orgId) { dispatch(fetchQueryLibrary()); @@ -125,7 +161,8 @@ export const QueryLibraryEditor = () => { useEffect(() => { if (!forwardQueryId && !queryLibrary[selectedQuery]) { - setSelectedQuery(Object.values(queryLibrary)?.[0]?.id); + // @ts-ignore + setSelectedQuery(Object.values(queryLibrary)?.[0]?.id); } }, [dispatch, Object.keys(queryLibrary).length]); @@ -145,13 +182,13 @@ export const QueryLibraryEditor = () => { }) .map((info) => info.datasource); - const recentlyUsed = Object.values(queryLibrary) - .map((i) => i.libraryQueryDSL?.query.datasourceId) + const recentlyUsed = Object.values(queryLibrary) + .map((i: any) => i.libraryQueryDSL?.query.datasourceId) .map((id) => datasource.find((d) => d.id === id)) .filter((i) => !!i) as Datasource[]; const nameGenerator = new NameGenerator(); - nameGenerator.init(Object.values(queryLibrary).map((t) => t.name)); + nameGenerator.init(Object.values(queryLibrary).map((t: any) => t.name)); const newName = nameGenerator.genItemName(trans("queryLibrary.unnamed")); const handleAdd = (type: BottomResTypeEnum, extraInfo?: any) => { @@ -189,7 +226,12 @@ export const QueryLibraryEditor = () => { setSelectedQuery(id); showCreatePanel(false); } } - readOnly={showHistory} /> + setCurrentPage={setCurrentPage} + setPageSize={setPageSize} + currentPage={currentPage} + pageSize={pageSize} + total={elements.total} + /> {!selectedQuery || !comp?.children.query.children.id.getView() ? ( EmptyQueryWithoutTab diff --git a/client/packages/lowcoder/src/util/pagination/Pagination.tsx b/client/packages/lowcoder/src/util/pagination/Pagination.tsx index fe93dfc93..19001dea8 100644 --- a/client/packages/lowcoder/src/util/pagination/Pagination.tsx +++ b/client/packages/lowcoder/src/util/pagination/Pagination.tsx @@ -1,11 +1,19 @@ import styled from "styled-components"; import { Pagination } from "antd"; -const PaginationLayout = styled(Pagination)` +interface PaginationLayoutProps { + height?: number; + marginTop?: number; + marginBottom?: number; +} + +const PaginationLayout = styled(Pagination)` display: flex; justify-content: center; - margin-top: 40px; - margin-bottom: 20px; + align-items: center; + margin-top: ${(props) => props.marginTop !== undefined ? props.marginTop : 40}px !important; + margin-bottom: ${(props) => props.marginBottom !== undefined ? props.marginBottom : 20}px !important; + height: ${(props) => props.height}px; `; interface PaginationCompProps { @@ -14,6 +22,10 @@ interface PaginationCompProps { currentPage: number; pageSize: number; total: number; + height?: number; + marginTop?: number; + marginBottom?: number; + simple?: boolean; } const PaginationComp = (props: PaginationCompProps) => { @@ -23,6 +35,10 @@ const PaginationComp = (props: PaginationCompProps) => { currentPage, pageSize, total, + height, + marginTop, + marginBottom, + simple, } = props; const handlePageChange = (page: number, pageSize: number | undefined) => { @@ -38,14 +54,32 @@ const PaginationComp = (props: PaginationCompProps) => { }; return ( - + <> + {simple ? + : + + } + ); }; diff --git a/client/packages/lowcoder/src/util/pagination/axios.ts b/client/packages/lowcoder/src/util/pagination/axios.ts index 0600e47d2..808634fac 100644 --- a/client/packages/lowcoder/src/util/pagination/axios.ts +++ b/client/packages/lowcoder/src/util/pagination/axios.ts @@ -1,15 +1,16 @@ import { FolderApi } from "@lowcoder-ee/api/folderApi"; import ApplicationApi from "@lowcoder-ee/api/applicationApi"; import { - fetchAppRequestType, + fetchAppRequestType, fetchDataSourcePaginationRequestType, fetchDBRequestType, fetchFolderRequestType, fetchGroupUserRequestType, - fetchOrgUserRequestType, + fetchOrgUserRequestType, fetchQueryLibraryPaginationRequestType, orgGroupRequestType } from "@lowcoder-ee/util/pagination/type"; import OrgApi from "@lowcoder-ee/api/orgApi"; import { DatasourceApi } from "@lowcoder-ee/api/datasourceApi"; +import {QueryLibraryApi} from "@lowcoder-ee/api/queryLibraryApi"; export const fetchFolderElements = async (request: fetchFolderRequestType) => { try { @@ -113,3 +114,37 @@ export const fetchOrgUsrPagination = async (request: fetchOrgUserRequestType)=> }; } } + +export const fetchQLPaginationByOrg = async (request: fetchQueryLibraryPaginationRequestType)=> { + try { + const response = await QueryLibraryApi.fetchQueryLibraryPaginationByOrg(request); + return { + success: true, + data: response.data.data, + total: response.data.total + } + } catch (error: any) { + console.error('Failed to fetch data:', error); + return { + success: false, + error: error + }; + } +} + +export const fetchJsDSPaginationByApp = async (request: fetchDataSourcePaginationRequestType)=> { + try { + const response = await DatasourceApi.fetchJsDatasourcePaginationByApp(request); + return { + success: true, + data: response.data.data, + total: response.data.total + } + } catch (error: any) { + console.error('Failed to fetch data:', error); + return { + success: false, + error: error + }; + } +} \ No newline at end of file diff --git a/client/packages/lowcoder/src/util/pagination/type.ts b/client/packages/lowcoder/src/util/pagination/type.ts index c3e7dde90..695550dcc 100644 --- a/client/packages/lowcoder/src/util/pagination/type.ts +++ b/client/packages/lowcoder/src/util/pagination/type.ts @@ -4,6 +4,16 @@ type ApplicationType = { [key: number]: string; // This allows numeric indexing }; +export const ApplicationPaginationType: ApplicationType = { + 0: "", + 1: "APPLICATION", + 2: "MODULE", + 3: "NAVLAYOUT", + 4: "FOLDER", + 6: "MOBILETABLAYOUT", + 7: "NAVIGATION", +}; + export interface GenericApiPaginationResponse { total: number; success: boolean; @@ -29,16 +39,6 @@ export interface OrgUsersPaginationResponse { }; } -export const ApplicationPaginationType: ApplicationType = { - 0: "", - 1: "APPLICATION", - 2: "MODULE", - 3: "NAVLAYOUT", - 4: "FOLDER", - 6: "MOBILETABLAYOUT", - 7: "NAVIGATION", -}; - export interface fetchAppRequestType { pageNum?: number; pageSize?: number; @@ -76,3 +76,16 @@ export interface fetchGroupUserRequestType { pageNum?: number; pageSize?: number; } + +export interface fetchQueryLibraryPaginationRequestType { + name?: string; + pageNum?: number; + pageSize?: number; +} + +export interface fetchDataSourcePaginationRequestType { + appId: string; + name?: string; + pageNum?: number; + pageSize?: number; +} \ No newline at end of file From cce98cd860a6fda4eedcffcec6c5eb4435121003 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Thu, 28 Nov 2024 13:23:53 -0500 Subject: [PATCH 13/38] Implemented pagination in login. --- client/packages/lowcoder/src/api/orgApi.ts | 7 +++++ .../src/pages/userAuth/formLoginSteps.tsx | 30 +++++++++++++++++++ .../lowcoder/src/util/pagination/axios.ts | 21 ++++++++++++- .../lowcoder/src/util/pagination/type.ts | 15 ++++++++++ 4 files changed, 72 insertions(+), 1 deletion(-) diff --git a/client/packages/lowcoder/src/api/orgApi.ts b/client/packages/lowcoder/src/api/orgApi.ts index 5e650417d..588a20df5 100644 --- a/client/packages/lowcoder/src/api/orgApi.ts +++ b/client/packages/lowcoder/src/api/orgApi.ts @@ -11,7 +11,9 @@ import { } from "redux/reduxActions/orgActions"; import { ApiResponse, GenericApiResponse } from "./apiResponses"; import { + ApiPaginationResponse, fetchGroupUserRequestType, + fetchOrgsByEmailRequestType, fetchOrgUserRequestType, GenericApiPaginationResponse, GroupUsersPaginationResponse, @@ -166,6 +168,11 @@ export class OrgApi extends Api { static fetchOrgsByEmail(email: string): AxiosPromise { return Api.get(OrgApi.fetchOrgsByEmailURL(email)); } + + static fetchOrgsPaginationByEmail(request: fetchOrgsByEmailRequestType): AxiosPromise { + const { email, ...rest } = request; + return Api.get(OrgApi.fetchOrgsByEmailURL(email), {...rest}); + } } export default OrgApi; diff --git a/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx b/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx index 958995e74..70c1aaa79 100644 --- a/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx +++ b/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx @@ -29,6 +29,8 @@ import { useDispatch, useSelector } from "react-redux"; import history from "util/history"; import ApplicationApi from "@lowcoder-ee/api/applicationApi"; import { getServerSettings } from "@lowcoder-ee/redux/selectors/applicationSelector"; +import {fetchOrgPaginationByEmail} from "@lowcoder-ee/util/pagination/axios"; +import PaginationComp from "@lowcoder-ee/util/pagination/Pagination"; const StyledCard = styled.div<{$selected: boolean}>` display: flex; @@ -91,6 +93,11 @@ type FormLoginProps = { organizationId?: string; } +interface ElementsState { + elements: any; + total: number; +} + export default function FormLoginSteps(props: FormLoginProps) { const dispatch = useDispatch(); const location = useLocation(); @@ -111,6 +118,21 @@ export default function FormLoginSteps(props: FormLoginProps) { const [skipWorkspaceStep, setSkipWorkspaceStep] = useState(false); const [signupEnabled, setSignupEnabled] = useState(true); const serverSettings = useSelector(getServerSettings); + const [elements, setElements] = useState({ elements: [], total: 0 }); + const [currentPage, setCurrentPage] = useState(1); + const [pageSize, setPageSize] = useState(2); + + useEffect(() => { + fetchOrgPaginationByEmail({ + email: account, + pageNum: currentPage, + pageSize: pageSize + }).then( result => { + setElements({elements: result.data || [], total: result.total || 1}) + setOrgList(result.data) + } + ) + }, [pageSize, currentPage]) useEffect(() => { const { LOWCODER_EMAIL_SIGNUP_ENABLED } = serverSettings; @@ -233,6 +255,14 @@ export default function FormLoginSteps(props: FormLoginProps) { {org.orgName} ))} + {orgList.length > 10 ? + : <>} ) diff --git a/client/packages/lowcoder/src/util/pagination/axios.ts b/client/packages/lowcoder/src/util/pagination/axios.ts index 808634fac..92b1b345f 100644 --- a/client/packages/lowcoder/src/util/pagination/axios.ts +++ b/client/packages/lowcoder/src/util/pagination/axios.ts @@ -4,7 +4,7 @@ import { fetchAppRequestType, fetchDataSourcePaginationRequestType, fetchDBRequestType, fetchFolderRequestType, - fetchGroupUserRequestType, + fetchGroupUserRequestType, fetchOrgsByEmailRequestType, fetchOrgUserRequestType, fetchQueryLibraryPaginationRequestType, orgGroupRequestType } from "@lowcoder-ee/util/pagination/type"; @@ -147,4 +147,23 @@ export const fetchJsDSPaginationByApp = async (request: fetchDataSourcePaginatio error: error }; } +} + + + +export const fetchOrgPaginationByEmail = async (request: fetchOrgsByEmailRequestType)=> { + try { + const response = await OrgApi.fetchOrgsPaginationByEmail(request); + return { + success: true, + data: response.data.data, + total: response.data.total + } + } catch (error: any) { + console.error('Failed to fetch data:', error); + return { + success: false, + error: error + }; + } } \ No newline at end of file diff --git a/client/packages/lowcoder/src/util/pagination/type.ts b/client/packages/lowcoder/src/util/pagination/type.ts index 695550dcc..6929628f2 100644 --- a/client/packages/lowcoder/src/util/pagination/type.ts +++ b/client/packages/lowcoder/src/util/pagination/type.ts @@ -39,6 +39,15 @@ export interface OrgUsersPaginationResponse { }; } +export type ApiPaginationResponse = { + total: number; + success: boolean; + code: number; + message: string; + data: any; +}; + + export interface fetchAppRequestType { pageNum?: number; pageSize?: number; @@ -88,4 +97,10 @@ export interface fetchDataSourcePaginationRequestType { name?: string; pageNum?: number; pageSize?: number; +} + +export interface fetchOrgsByEmailRequestType { + email: string; + pageNum?: number; + pageSize?: number; } \ No newline at end of file From e2c1efc3d1e4ec766df43c258a0f6086270244a9 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Thu, 28 Nov 2024 14:28:09 -0500 Subject: [PATCH 14/38] Implemented realtime processing of create new folder in HomeView. --- .../src/pages/ApplicationV2/CreateDropdown.tsx | 6 +++--- .../lowcoder/src/pages/ApplicationV2/HomeLayout.tsx | 8 ++++++-- .../lowcoder/src/pages/ApplicationV2/HomeView.tsx | 5 ++++- .../src/pages/ApplicationV2/useCreateFolder.tsx | 10 +++++++--- .../src/pages/ApplicationV2/useCreateHomeRes.tsx | 4 ++-- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/CreateDropdown.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/CreateDropdown.tsx index c2d93086d..787d3a243 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/CreateDropdown.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/CreateDropdown.tsx @@ -185,14 +185,14 @@ function NavLayoutPickModal(props: { ); } -export const CreateDropdown = (props: { defaultVisible?: boolean; mode: HomeLayoutMode }) => { - const { defaultVisible, mode } = props; +export const CreateDropdown = (props: { defaultVisible?: boolean; mode: HomeLayoutMode; setModify: any; modify: boolean }) => { + const { defaultVisible, mode, setModify, modify} = props; const [createDropdownVisible, setCreateDropdownVisible] = useState(false); const [layoutPickerVisible, setLayoutPickerVisible] = useState(false); const user = useSelector(getUser); - const [handleCreate, isCreating] = useCreateHomeRes(); + const [handleCreate, isCreating] = useCreateHomeRes(setModify, modify); const getCreateMenuItem = (type: HomeResTypeEnum, mode?: HomeLayoutMode): ItemType => { if ( diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx index c9d8dee64..d97cded47 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx @@ -316,6 +316,8 @@ export interface HomeLayoutProps { searchValues?: number; setSearchValues?: any; setTypeFilterPagination?: any; + setModify?: any; + modify?: boolean; } export function HomeLayout(props: HomeLayoutProps) { @@ -332,6 +334,8 @@ export function HomeLayout(props: HomeLayoutProps) { setSearchValues, total, setTypeFilterPagination, + setModify, + modify } = props; const handlePageChange = (page: number) => { @@ -568,7 +572,7 @@ export function HomeLayout(props: HomeLayoutProps) { style={{ width: "192px", height: "32px", margin: "0" }} /> {mode !== "trash" && mode !== "marketplace" && user.orgDev && ( - + )} @@ -655,7 +659,7 @@ export function HomeLayout(props: HomeLayoutProps) { ? trans("home.projectEmptyCanAdd") : trans("home.projectEmpty")} - {mode !== "trash" && mode !== "marketplace" && user.orgDev && } + {mode !== "trash" && mode !== "marketplace" && user.orgDev && } )} diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx index 26bfb8384..720ba909f 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx @@ -19,6 +19,7 @@ export function HomeView() { const [pageSize, setPageSize] = useState(10); const [searchValues, setSearchValues] = useState(""); const [typeFilter, setTypeFilter] = useState(0); + const [modify, setModify] = useState(true); useEffect( () => { try{ fetchFolderElements({ @@ -38,7 +39,7 @@ export function HomeView() { } catch (error) { console.error('Failed to fetch data:', error); } - }, [currentPage, pageSize, searchValues, typeFilter] + }, [currentPage, pageSize, searchValues, typeFilter, modify] ); const user = useSelector(getUser); @@ -60,6 +61,8 @@ export function HomeView() { total={elements.total} setSearchValues={setSearchValues} setTypeFilterPagination={setTypeFilter} + setModify={setModify} + modify={modify} /> ); diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/useCreateFolder.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/useCreateFolder.tsx index 4c1243949..04c50f22c 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/useCreateFolder.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/useCreateFolder.tsx @@ -17,7 +17,7 @@ const CreateFolderLabel = styled.div` margin-bottom: 8px; `; -export function useCreateFolder() { +export function useCreateFolder(setModify: any, modify: boolean) { const dispatch = useDispatch(); const user = useSelector(getUser); const allFolders = useSelector(foldersSelector); @@ -73,7 +73,7 @@ export function useCreateFolder() { ), - onConfirm: () => + onConfirm: () =>{ form.validateFields().then( () => new Promise((resolve, reject) => { @@ -82,7 +82,11 @@ export function useCreateFolder() { () => reject(false) ); }) - ), + ) + setTimeout(() => { + setModify(!modify); + }, 200); + }, okText: trans("create"), }); }, [user, allFolders, form, dispatch]); diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/useCreateHomeRes.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/useCreateHomeRes.tsx index 6198279b8..7c314ab11 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/useCreateHomeRes.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/useCreateHomeRes.tsx @@ -31,7 +31,7 @@ export const newAppPrefix = (userName: string, appType: AppTypeEnum = AppTypeEnu return trans("home.newApp", { userName: userName, name: toLower(HomeResInfo[appType].name) }); }; -export function useCreateHomeRes() { +export function useCreateHomeRes(setModify:any, modify: boolean) { const dispatch = useDispatch(); const user = useSelector(getUser); const allApplications = useSelector(normalAppListSelector); @@ -39,7 +39,7 @@ export function useCreateHomeRes() { const { folderId } = useParams<{ folderId: string }>(); - const handleFolderCreate = useCreateFolder(); + const handleFolderCreate = useCreateFolder(setModify, modify); const handleCreate = useCallback( (type: HomeResTypeEnum) => { From 3ce6469907134ec1ad2556cf5526e50228a439f0 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Thu, 28 Nov 2024 14:59:13 -0500 Subject: [PATCH 15/38] Change search method in query library. --- .../src/pages/ApplicationV2/FolderView.tsx | 5 +++-- .../src/pages/ApplicationV2/HomeLayout.tsx | 12 +++++------- .../src/pages/ApplicationV2/HomeView.tsx | 13 +++++++++++-- .../src/pages/ApplicationV2/TrashView.tsx | 14 ++++++++++++-- .../src/pages/queryLibrary/LeftNav.tsx | 19 +++++++++++-------- .../pages/queryLibrary/QueryLibraryEditor.tsx | 7 +++++-- 6 files changed, 47 insertions(+), 23 deletions(-) diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/FolderView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/FolderView.tsx index 1862533d8..b5e3ecab2 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/FolderView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/FolderView.tsx @@ -1,7 +1,7 @@ import { useDispatch, useSelector } from "react-redux"; import { useParams } from "react-router-dom"; import { HomeBreadcrumbType, HomeLayout } from "./HomeLayout"; -import { useEffect } from "react"; +import {useEffect, useState} from "react"; import { fetchFolderElements } from "../../redux/reduxActions/folderActions"; import { FolderMeta } from "../../constants/applicationConstants"; import { buildFolderUrl } from "../../constants/routesURL"; @@ -34,6 +34,7 @@ export function FolderView() { const { folderId } = useParams<{ folderId: string }>(); const dispatch = useDispatch(); + const [searchValue, setSearchValue] = useState("") const elements = useSelector(folderElementsSelector); const allFolders = useSelector(foldersSelector); @@ -55,7 +56,7 @@ export function FolderView() { return ( <> {{trans("home.yourFolders")}} - + ); } diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx index d97cded47..96bc93e83 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx @@ -313,8 +313,8 @@ export interface HomeLayoutProps { currentPage?: number; pageSize?: number; total?: number; - searchValues?: number; - setSearchValues?: any; + searchValue?: string; + setSearchValue?: any; setTypeFilterPagination?: any; setModify?: any; modify?: boolean; @@ -330,8 +330,8 @@ export function HomeLayout(props: HomeLayoutProps) { setPageSize, pageSize, currentPage, - searchValues, - setSearchValues, + searchValue, + setSearchValue, total, setTypeFilterPagination, setModify, @@ -363,7 +363,6 @@ export function HomeLayout(props: HomeLayoutProps) { const isSelfHost = window.location.host !== 'app.lowcoder.cloud'; const [typeFilter, setTypeFilter] = useState("All"); const [categoryFilter, setCategoryFilter] = useState("All"); - const [searchValue, setSearchValue] = useState(""); const [visibility, setVisibility] = useState(mode === "view" || mode === "trash"); const [layout, setLayout] = useState( checkIsMobile(window.innerWidth) ? "card" : getHomeLayout() @@ -566,9 +565,8 @@ export function HomeLayout(props: HomeLayoutProps) { setSearchValue(e.target.value)} - onEnterPress={(value) => setSearchValues(value)} style={{ width: "192px", height: "32px", margin: "0" }} /> {mode !== "trash" && mode !== "marketplace" && user.orgDev && ( diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx index 720ba909f..6669d21b7 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx @@ -17,6 +17,7 @@ export function HomeView() { const [elements, setElements] = useState({ elements: [], total: 1 }); const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); + const [searchValue, setSearchValue] = useState(""); const [searchValues, setSearchValues] = useState(""); const [typeFilter, setTypeFilter] = useState(0); const [modify, setModify] = useState(true); @@ -26,7 +27,7 @@ export function HomeView() { pageNum:currentPage, pageSize:pageSize, applicationType: ApplicationPaginationType[typeFilter], - name: searchValues, + name: searchValue, }).then( data => { if (data.success) { @@ -42,6 +43,13 @@ export function HomeView() { }, [currentPage, pageSize, searchValues, typeFilter, modify] ); + useEffect(()=> { + setTimeout(() => { + if (searchValue.length > 2 || searchValue === "") + setSearchValues(searchValue) + }, 500); + }) + const user = useSelector(getUser); if (!user.currentOrgId) { @@ -59,7 +67,8 @@ export function HomeView() { pageSize={pageSize} setPageSize={setPageSize} total={elements.total} - setSearchValues={setSearchValues} + setSearchValue={setSearchValue} + searchValue={searchValue} setTypeFilterPagination={setTypeFilter} setModify={setModify} modify={modify} diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx index a273f0cb3..55a4733e2 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx @@ -15,9 +15,10 @@ export function TrashView() { const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); const [searchValues, setSearchValues] = useState(""); + const [searchValue, setSearchValue] = useState(""); const [typeFilter, setTypeFilter] = useState(0); - useEffect( () => { + useEffect( () => { if (typeFilter === 7) // Application of Navigation is 3 in API. setTypeFilter(3); try{ @@ -41,6 +42,13 @@ export function TrashView() { }, [currentPage, pageSize, searchValues, typeFilter] ); + useEffect(()=> { + setTimeout(() => { + if (searchValue.length > 2 || searchValue === "") + setSearchValues(searchValue) + }, 500); + }) + return ( <> {{trans("home.trash")}} @@ -53,9 +61,11 @@ export function TrashView() { pageSize={pageSize} setPageSize={setPageSize} total={elements.total} - setSearchValues={setSearchValues} + setSearchValue={setSearchValue} + searchValue={searchValue} setTypeFilterPagination={setTypeFilter} /> ); } + diff --git a/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx b/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx index 9eab70919..04447a0aa 100644 --- a/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx +++ b/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import {useEffect, useState} from "react"; import styled, { css } from "styled-components"; import { BluePlusIcon, @@ -164,12 +164,21 @@ export const LeftNav = (props: { currentPage: number; pageSize: number; total: number; + setSearchValues: any; + searchValues: string; }) => { - const {currentPage, setCurrentPage, pageSize, setPageSize, total } = props + const {currentPage, setCurrentPage, pageSize, setPageSize, total , setSearchValues, searchValues} = props const dispatch = useDispatch(); const [searchValue, setSearchValue] = useState(""); const datasourceTypes = useSelector(getDataSourceTypesMap); + useEffect(()=> { + setTimeout(() => { + if (searchValue.length > 2 || searchValue === "") + setSearchValues(searchValue) + }, 500); + }) + return ( @@ -196,12 +205,6 @@ export const LeftNav = (props: { let datasourceTypeName = datasourceTypes[q.libraryQueryDSL?.query?.compType as DatasourceType]?.name ?? ""; - if (searchValue) { - return ( - q.name.toLowerCase().includes(searchValue) || - datasourceTypeName.toLowerCase().includes(searchValue) - ); - } return true; }) .map((q) => ( diff --git a/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx b/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx index 19a0572f1..257d7f226 100644 --- a/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx +++ b/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx @@ -91,6 +91,7 @@ export const QueryLibraryEditor = () => { const [queryLibrary, setQueryLibrary] = useState({}); const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); + const [searchValues, setSearchValues] = useState("") const selectedRecords = queryLibraryRecords[selectedQuery] ?? {}; const libraryQuery = queryLibrary[selectedQuery]; @@ -119,7 +120,7 @@ export const QueryLibraryEditor = () => { try { fetchQLPaginationByOrg( { - name: "", + name: searchValues, pageNum: currentPage, pageSize: pageSize, } @@ -132,7 +133,7 @@ export const QueryLibraryEditor = () => { } catch (error) { console.error(error) } - }, [currentPage, pageSize]) + }, [currentPage, pageSize, searchValues, setSearchValues]) useEffect(() => { if (orgId) { @@ -231,6 +232,8 @@ export const QueryLibraryEditor = () => { currentPage={currentPage} pageSize={pageSize} total={elements.total} + setSearchValues={setSearchValues} + searchValues={searchValues} /> {!selectedQuery || !comp?.children.query.children.id.getView() ? ( From a0a6fa1058bcb7157172168809bebca4db755c49 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Thu, 28 Nov 2024 15:04:31 -0500 Subject: [PATCH 16/38] Changed search method in Data Sources. --- .../lowcoder/src/pages/datasource/datasourceList.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx b/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx index 01c086163..8f3b02db2 100644 --- a/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx +++ b/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx @@ -119,12 +119,18 @@ export const DatasourceList = () => { elements: DatasourceInfo[]; total: number; } - console.log(datasource); const [elements, setElements] = useState({ elements: [], total: 0 }); const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); + useEffect(()=> { + setTimeout(() => { + if (searchValue.length > 2 || searchValue === "") + setSearchValues(searchValue) + }, 500); + }) + useEffect( () => { fetchDatasourcePagination( { @@ -174,7 +180,6 @@ export const DatasourceList = () => { placeholder={trans("search")} value={searchValue} onChange={(e) => setSearchValue(e.target.value)} - onEnterPress={(value) => setSearchValues(value)} style={{ width: "192px", height: "32px", margin: "0 12px 0 0" }} /> showCreateForm(true)}> {trans("home.newDatasource")} From b27f13fdf819ea72de49feba8d8f9e68598eff43 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Thu, 28 Nov 2024 15:17:14 -0500 Subject: [PATCH 17/38] Changed search method in marketplace. --- .../lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx index 01b76fb78..185c2b18b 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/MarketplaceView.tsx @@ -13,6 +13,7 @@ import { Helmet } from "react-helmet"; export function MarketplaceView() { const [ marketplaceApps, setMarketplaceApps ] = useState>([]); const [ localMarketplaceApps, setLocalMarketplaceApps ] = useState>([]); + const [searchValue, setSearchValue] = useState(""); const fetchMarketplaceApps = async () => { try { @@ -60,7 +61,10 @@ export function MarketplaceView() { localMarketplaceApps={localMarketplaceApps} globalMarketplaceApps={marketplaceApps} breadcrumb={[{ text: trans("home.marketplace"), path: MARKETPLACE_URL }]} - mode={"marketplace"} /> + mode={"marketplace"} + searchValue={searchValue} + setSearchValue={setSearchValue} + /> ); }; \ No newline at end of file From f51f68185921b2b46a7493b6de1d9e0272f1937c Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Thu, 28 Nov 2024 22:53:48 -0500 Subject: [PATCH 18/38] Processed immediate activity in TrashView. --- .../src/pages/ApplicationV2/HomeLayout.tsx | 2 +- .../src/pages/ApplicationV2/HomeView.tsx | 6 ++-- .../pages/ApplicationV2/TrashTableView.tsx | 30 ++++++++++++------- .../src/pages/ApplicationV2/TrashView.tsx | 7 +++-- .../src/pages/datasource/datasourceList.tsx | 4 +-- .../src/pages/queryLibrary/LeftNav.tsx | 2 +- 6 files changed, 32 insertions(+), 19 deletions(-) diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx index 96bc93e83..c941d3827 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx @@ -586,7 +586,7 @@ export function HomeLayout(props: HomeLayoutProps) { {resList.length > 0 ? ( <> {mode === "trash" ? ( - + ) : ( <> setLayout(layout === "list" ? "card" : "list")}> diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx index 6669d21b7..4718ec764 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx @@ -27,9 +27,9 @@ export function HomeView() { pageNum:currentPage, pageSize:pageSize, applicationType: ApplicationPaginationType[typeFilter], - name: searchValue, + name: searchValues, }).then( - data => { + (data: any) => { if (data.success) { setElements({elements: data.data || [], total: data.total || 1}) } @@ -48,7 +48,7 @@ export function HomeView() { if (searchValue.length > 2 || searchValue === "") setSearchValues(searchValue) }, 500); - }) + }, [searchValue]) const user = useSelector(getUser); diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/TrashTableView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/TrashTableView.tsx index 0b600a472..424d67507 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/TrashTableView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/TrashTableView.tsx @@ -32,7 +32,8 @@ const EditBtn = styled(TacoButton)` height: 24px; `; -export const TrashTableView = (props: { resources: HomeRes[] }) => { +export const TrashTableView = (props: { resources: HomeRes[] , setModify: any, modify: boolean }) => { + const {resources, setModify, modify} = props; const dispatch = useDispatch(); return ( @@ -119,13 +120,17 @@ export const TrashTableView = (props: { resources: HomeRes[] }) => { 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={() =>{ + dispatch( + restoreApplication({ applicationId: item.id }, () => { + messageInstance.success(trans("home.recoverSuccessMsg")); + }) + ) + setTimeout(() => { + setModify(!modify); + }, 200); } + } > {trans("recover")} @@ -140,7 +145,7 @@ export const TrashTableView = (props: { resources: HomeRes[] }) => { type: HomeResInfo[item.type].name.toLowerCase(), name: {item.name}, }), - onConfirm: () => + onConfirm: () =>{ new Promise((resolve, reject) => { dispatch( deleteApplication( @@ -152,10 +157,15 @@ export const TrashTableView = (props: { resources: HomeRes[] }) => { () => reject() ) ); - }), + }) + setTimeout(() => { + setModify(!modify); + }, 200); + }, confirmBtnType: "delete", okText: trans("delete"), }) + } style={{ marginLeft: "12px", width: "76px" }} > @@ -166,7 +176,7 @@ export const TrashTableView = (props: { resources: HomeRes[] }) => { }, }, ]} - dataSource={props.resources} + dataSource={resources} /> ); }; diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx index 55a4733e2..940282984 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx @@ -17,6 +17,7 @@ export function TrashView() { const [searchValues, setSearchValues] = useState(""); const [searchValue, setSearchValue] = useState(""); const [typeFilter, setTypeFilter] = useState(0); + const [modify, setModify] = useState(false); useEffect( () => { if (typeFilter === 7) // Application of Navigation is 3 in API. @@ -39,7 +40,7 @@ export function TrashView() { } catch (error) { console.error('Failed to fetch data:', error); } - }, [currentPage, pageSize, searchValues, typeFilter] + }, [currentPage, pageSize, searchValues, typeFilter, modify] ); useEffect(()=> { @@ -47,7 +48,7 @@ export function TrashView() { if (searchValue.length > 2 || searchValue === "") setSearchValues(searchValue) }, 500); - }) + }, [searchValue]) return ( <> @@ -64,6 +65,8 @@ export function TrashView() { setSearchValue={setSearchValue} searchValue={searchValue} setTypeFilterPagination={setTypeFilter} + setModify={setModify} + modify={modify} /> ); diff --git a/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx b/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx index 8f3b02db2..0f7bba90c 100644 --- a/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx +++ b/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx @@ -129,7 +129,7 @@ export const DatasourceList = () => { if (searchValue.length > 2 || searchValue === "") setSearchValues(searchValue) }, 500); - }) + }, [searchValue]) useEffect( () => { fetchDatasourcePagination( @@ -139,7 +139,7 @@ export const DatasourceList = () => { pageSize: pageSize, name: searchValues } - ).then(result => { + ).then((result: any) => { if (result.success){ setElements({elements: result.data || [], total: result.total || 1}) } diff --git a/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx b/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx index 04447a0aa..4357970bb 100644 --- a/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx +++ b/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx @@ -177,7 +177,7 @@ export const LeftNav = (props: { if (searchValue.length > 2 || searchValue === "") setSearchValues(searchValue) }, 500); - }) + }, [searchValue]) return ( From cfe991defc5f761932bbf29024712ef8dbb5f2d9 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Fri, 29 Nov 2024 00:36:36 -0500 Subject: [PATCH 19/38] Processed immediate activity in Your Apps. --- .../src/pages/ApplicationV2/HomeCardView.tsx | 7 +-- .../src/pages/ApplicationV2/HomeLayout.tsx | 4 +- .../src/pages/ApplicationV2/HomeResCard.tsx | 12 ++++- .../pages/ApplicationV2/HomeResOptions.tsx | 53 +++++++++++-------- .../src/pages/ApplicationV2/HomeTableView.tsx | 15 ++++-- .../pages/ApplicationV2/MoveToFolderModal.tsx | 6 ++- 6 files changed, 65 insertions(+), 32 deletions(-) diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeCardView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeCardView.tsx index ac515b574..1bfa7e44c 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeCardView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeCardView.tsx @@ -19,7 +19,8 @@ const ApplicationCardsWrapper = styled.div` } `; -export function HomeCardView(props: { resources: HomeRes[] }) { +export function HomeCardView(props: { resources: HomeRes[], setModify?: any, modify?: boolean }) { + const {setModify, modify} = props; const [needMoveRes, setNeedMoveRes] = useState(undefined); return ( @@ -27,9 +28,9 @@ export function HomeCardView(props: { resources: HomeRes[] }) { {props.resources.map((res) => ( res.isMarketplace ? : - + ))} - setNeedMoveRes(undefined)} /> + setNeedMoveRes(undefined)} setModify={setModify} modify={modify!} /> ); } diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx index c941d3827..5989e1562 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx @@ -635,9 +635,9 @@ export function HomeLayout(props: HomeLayoutProps) { {mode !== "marketplace" && ( <> {layout === "list" ? ( - + ) : ( - + )} )} diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx index 846d59cbf..8abb3d69f 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx @@ -141,8 +141,8 @@ const OperationWrapper = styled.div` const MONTH_MILLIS = 30 * 24 * 60 * 60 * 1000; -export function HomeResCard(props: { res: HomeRes; onMove: (res: HomeRes) => void }) { - const { res, onMove } = props; +export function HomeResCard(props: { res: HomeRes; onMove: (res: HomeRes) => void; setModify:any; modify: boolean }) { + const { res, onMove, setModify, modify } = props; const [appNameEditing, setAppNameEditing] = useState(false); const dispatch = useDispatch(); @@ -214,10 +214,16 @@ export function HomeResCard(props: { res: HomeRes; onMove: (res: HomeRes) => voi } if (res.type === HomeResTypeEnum.Folder) { dispatch(updateFolder({ id: res.id, name: value })); + setTimeout(() => { + setModify(!modify); + }, 200); } else { dispatch( updateAppMetaAction({ applicationId: res.id, name: value, folderId: folderId }) ); + setTimeout(() => { + setModify(!modify); + }, 200); } setAppNameEditing(false); }} @@ -245,6 +251,8 @@ export function HomeResCard(props: { res: HomeRes; onMove: (res: HomeRes) => voi res={res} onRename={() => setAppNameEditing(true)} onMove={(res) => onMove(res)} + setModify={setModify} + modify={modify} /> diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResOptions.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResOptions.tsx index b712fe7e4..0049ff1b6 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResOptions.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResOptions.tsx @@ -38,8 +38,10 @@ export const HomeResOptions = (props: { onDuplicate?: (res: HomeRes | undefined) => void; onRename: (res: HomeRes) => void; onMove: (res: HomeRes) => void; + setModify: any; + modify: boolean; }) => { - const { res, onDuplicate, onRename, onMove } = props; + const { res, onDuplicate, onRename, onMove, setModify, modify } = props; const dispatch = useDispatch(); const [showCopyModal, setShowCopyModal] = useState(false); @@ -78,19 +80,24 @@ export const HomeResOptions = (props: { type: HomeResInfo[res.type].name, name: {res.name}, }), - onConfirm: () => + onConfirm: () =>{ new Promise((resolve, reject) => { dispatch( - recycleApplication( - { applicationId: res.id, folderId: folderId }, - () => { - messageInstance.success(trans("success")); - resolve(true); - }, - () => reject() - ) + recycleApplication( + { applicationId: res.id, folderId: folderId }, + () => { + messageInstance.success(trans("success")); + resolve(true); + }, + () => reject() + ) ); - }), + setTimeout(() => { + setModify(!modify); + }, 200); + }) + + }, confirmBtnType: "delete", okText: trans("home.moveToTrash"), }); @@ -115,19 +122,23 @@ export const HomeResOptions = (props: { type: HomeResInfo[res.type].name.toLowerCase(), name: {res.name}, }), - onConfirm: () => + onConfirm: () =>{ new Promise((resolve, reject) => { - dispatch( + dispatch( deleteFolder( - { folderId: res.id, parentFolderId: folderId }, - () => { - messageInstance.success(trans("home.deleteSuccessMsg")); - resolve(true); - }, - () => reject() + { folderId: res.id, parentFolderId: folderId }, + () => { + messageInstance.success(trans("home.deleteSuccessMsg")); + resolve(true); + }, + () => reject() ) - ); - }), + ); + }) + setTimeout(() => { + setModify(!modify); + }, 200); + }, confirmBtnType: "delete", okText: trans("delete"), }); diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeTableView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeTableView.tsx index 1eeb261e6..c0e700094 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeTableView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeTableView.tsx @@ -51,7 +51,8 @@ const TypographyText = styled(AntdTypographyText)` width: 100%; `; -export const HomeTableView = (props: { resources: HomeRes[] }) => { +export const HomeTableView = (props: { resources: HomeRes[], setModify?: any, modify?: boolean }) => { + const {setModify, modify, resources} = props const dispatch = useDispatch(); const { folderId } = useParams<{ folderId: string }>(); @@ -122,6 +123,9 @@ export const HomeTableView = (props: { resources: HomeRes[] }) => { } if (item.type === HomeResTypeEnum.Folder) { dispatch(updateFolder({ id: item.id, name: value })); + setTimeout(() => { + setModify(!modify); + }, 200); } else { dispatch( updateAppMetaAction({ @@ -130,6 +134,9 @@ export const HomeTableView = (props: { resources: HomeRes[] }) => { folderId: folderId, }) ); + setTimeout(() => { + setModify(!modify); + }, 200); } setNeedRenameRes(undefined); }, @@ -225,15 +232,17 @@ export const HomeTableView = (props: { resources: HomeRes[] }) => { onDuplicate={(res) => setNeedDuplicateRes(res)} onRename={(res) => setNeedRenameRes(res)} onMove={(res) => setNeedMoveRes(res)} + setModify={setModify} + modify={modify!} /> ); }, }, ]} - dataSource={props.resources} + dataSource={resources} /> - setNeedMoveRes(undefined)} /> + setNeedMoveRes(undefined)} setModify={setModify} modify={modify!} /> ); }; diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/MoveToFolderModal.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/MoveToFolderModal.tsx index 561020905..34bd6b9a1 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/MoveToFolderModal.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/MoveToFolderModal.tsx @@ -40,7 +40,8 @@ const MoveModalFooter = styled.div` gap: 8px; `; -export const MoveToFolderModal = (props: { source?: HomeRes; onClose: () => void }) => { +export const MoveToFolderModal = (props: { source?: HomeRes; onClose: () => void, setModify: any, modify: boolean }) => { + const {setModify, modify} = props; const [form] = Form.useForm(); const [loading, setLoading] = useState(false); @@ -83,6 +84,9 @@ export const MoveToFolderModal = (props: { source?: HomeRes; onClose: () => void () => setLoading(false) ) ); + setTimeout(() => { + setModify(!modify); + }, 200); }); }} > From add70834fa8e74104318925bacad30b254b9b121 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Fri, 29 Nov 2024 01:43:59 -0500 Subject: [PATCH 20/38] Processed immediate activity in Setting/UserGroup. --- .../setting/permission/addGroupUserDialog.tsx | 7 ++++++- .../setting/permission/groupUsersPermission.tsx | 15 ++++++++++++++- .../setting/permission/orgUsersPermission.tsx | 7 ++++++- .../pages/setting/permission/permissionDetail.tsx | 7 ++++++- .../pages/setting/permission/permissionList.tsx | 12 +++++++++++- 5 files changed, 43 insertions(+), 5 deletions(-) diff --git a/client/packages/lowcoder/src/pages/setting/permission/addGroupUserDialog.tsx b/client/packages/lowcoder/src/pages/setting/permission/addGroupUserDialog.tsx index b49d22199..726308be9 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/addGroupUserDialog.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/addGroupUserDialog.tsx @@ -31,8 +31,10 @@ function AddGroupUserDialog(props: { orgUsersFetching: boolean; groupUsers: GroupUser[]; style?: CSSProperties; + setModify?: any; + modify?: boolean }) { - const { orgId, orgUsers, orgUsersFetching, groupUsers, groupId } = props; + const { orgId, orgUsers, orgUsersFetching, groupUsers, groupId, setModify, modify } = props; const groupUserIdMap = new Map(groupUsers.map((gUser) => [gUser.userId, gUser])); const [dialogVisible, setDialogVisible] = useState(false); const addableUsers = orgUsers.filter((user) => !groupUserIdMap.has(user.userId)); @@ -83,6 +85,9 @@ function AddGroupUserDialog(props: { } } dispatch(fetchGroupUsersAction({ groupId })); + setTimeout(() => { + setModify(!modify); + }, 200); setDialogVisible(false); }} > diff --git a/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx b/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx index 02c4a3c90..4be4b2061 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx @@ -45,11 +45,13 @@ type GroupPermissionProp = { groupUsersFetching: boolean; currentUserGroupRole: string; currentUser: User; + setModify?: any; + modify?: boolean; }; function GroupUsersPermission(props: GroupPermissionProp) { const { Column } = TableStyled; - const { group, orgId, groupUsersFetching, groupUsers, currentUserGroupRole, currentUser } = props; + const { group, orgId, groupUsersFetching, groupUsers, currentUserGroupRole, currentUser , setModify, modify} = props; const adminCount = groupUsers.filter((user) => isGroupAdmin(user.role)).length; const sortedGroupUsers = useMemo(() => { return [...groupUsers].sort((a, b) => { @@ -83,6 +85,8 @@ function GroupUsersPermission(props: GroupPermissionProp) { groupUsers={groupUsers} orgId={orgId} groupId={group.groupId} + setModify={setModify} + modify={modify} trigger={ }> {trans("memberSettings.addMember")} @@ -145,6 +149,9 @@ function GroupUsersPermission(props: GroupPermissionProp) { groupId: group.groupId, }) ); + setTimeout(() => { + setModify(!modify); + }, 200); }} > {TacoRoles.map((role) => ( @@ -175,6 +182,9 @@ function GroupUsersPermission(props: GroupPermissionProp) { dispatch( quitGroupAction({ groupId: group.groupId, userId: currentUser.id }) ); + setTimeout(() => { + setModify(!modify); + }, 200); }} > {trans("memberSettings.exitGroup")} @@ -190,6 +200,9 @@ function GroupUsersPermission(props: GroupPermissionProp) { groupId: group.groupId, }) ); + setTimeout(() => { + setModify(!modify); + }, 200); }} > {trans("memberSettings.moveOutGroup")} diff --git a/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx b/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx index 0e42134d8..b9601a3c3 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx @@ -58,11 +58,13 @@ type UsersPermissionProp = { orgUsers: OrgUser[]; orgUsersFetching: boolean; currentUser: User; + setModify?: any; + modify?: boolean; }; function OrgUsersPermission(props: UsersPermissionProp) { const { Column } = TableStyled; - const { orgId, orgUsers, orgUsersFetching, currentUser } = props; + const { orgId, orgUsers, orgUsersFetching, currentUser , setModify, modify} = props; const adminCount = orgUsers.filter( (user) => user.role === ADMIN_ROLE || user.role === SUPER_ADMIN_ROLE, ).length; @@ -277,6 +279,9 @@ function OrgUsersPermission(props: UsersPermissionProp) { orgId: orgId, }) ); + setTimeout(() => { + setModify(!modify); + }, 200); }, confirmBtnType: "delete", okText: trans("memberSettings.moveOutOrg"), diff --git a/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx b/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx index 1e71f216f..ec7a91322 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx @@ -29,6 +29,7 @@ export default function PermissionSetting() { const user = useSelector(getUser) const [orgMemberElements, setOrgMemberElements] = useState({ elements: [], total: 0 }) const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); + const [modify, setModify] = useState(false); const orgId = user.currentOrgId; const orgGroups = useSelector(getOrgGroups); @@ -79,7 +80,7 @@ export default function PermissionSetting() { const user = useSelector(getUser) } ) }, - [currentPage, pageSize] + [currentPage, pageSize, modify] ) if (!orgId) { @@ -96,6 +97,8 @@ export default function PermissionSetting() { const user = useSelector(getUser) // orgUsers={!orgMemberElements.elements.members ? [] : orgMemberElements.elements.members} orgUsers={orgMemberElements.elements} currentUser={currentUser} + setModify={setModify} + modify={modify} /> @@ -109,6 +112,8 @@ export default function PermissionSetting() { const user = useSelector(getUser) groupUsersFetching={groupUsersFetching} currentUserGroupRole={currentUserGroupRole} currentUser={currentUser} + setModify={setModify} + modify={modify} /> diff --git a/client/packages/lowcoder/src/pages/setting/permission/permissionList.tsx b/client/packages/lowcoder/src/pages/setting/permission/permissionList.tsx index d8fc7759f..5b88705ab 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/permissionList.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/permissionList.tsx @@ -68,6 +68,7 @@ export default function PermissionSetting() { const [elements, setElements] = useState({ elements: [], total: 0 }); const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); + const [modify, setModify] = useState(false); useEffect( () => { fetchOrgGroups( @@ -82,7 +83,7 @@ export default function PermissionSetting() { else console.error("ERROR: fetchFolderElements", result.error) }) - }, [currentPage, pageSize] + }, [currentPage, pageSize, modify] ) const visibleOrgGroups = elements.elements.filter((g) => !g.allUsersGroup); const allUsersGroup = elements.elements.find((g) => g.allUsersGroup); @@ -116,6 +117,9 @@ export default function PermissionSetting() { setTimeout(() => { dispatch(fetchGroupsAction(orgId)); }, 200); + setTimeout(() => { + setModify(!modify); + }, 200); } }) .catch((e) => { @@ -130,6 +134,9 @@ export default function PermissionSetting() { .then((resp) => { if (validateResponse(resp)) { dispatch(fetchGroupsAction(orgId)); + setTimeout(() => { + setModify(!modify); + }, 200); } }) .catch((e) => { @@ -201,6 +208,9 @@ export default function PermissionSetting() { return; } dispatch(updateGroupAction(record.key, { groupName: value }, orgId)); + setTimeout(() => { + setModify(!modify); + }, 200); setNeedRenameId(undefined); }, }} From a65c737009e409eef16da8df8b3cd7b9afd132c4 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Fri, 29 Nov 2024 06:20:05 -0500 Subject: [PATCH 21/38] Added back button in your apps. --- .../src/components/TypographyText.tsx | 6 +-- .../src/pages/ApplicationV2/HomeCardView.tsx | 9 ++-- .../src/pages/ApplicationV2/HomeLayout.tsx | 4 +- .../src/pages/ApplicationV2/HomeResCard.tsx | 28 +++++++++++ .../src/pages/ApplicationV2/HomeTableView.tsx | 48 +++++++++++++------ .../lowcoder/src/util/homeResUtils.tsx | 9 +++- 6 files changed, 79 insertions(+), 25 deletions(-) diff --git a/client/packages/lowcoder/src/components/TypographyText.tsx b/client/packages/lowcoder/src/components/TypographyText.tsx index 7bf156859..81db5a69b 100644 --- a/client/packages/lowcoder/src/components/TypographyText.tsx +++ b/client/packages/lowcoder/src/components/TypographyText.tsx @@ -40,9 +40,9 @@ const StyledTypographyText = styled(AntdTypographyText)` `; export const TypographyText = (props: { - value: string; - editing: boolean; - onChange: (value: string) => void; + value?: string; + editing?: boolean; + onChange?: (value: string) => void; }) => ( (undefined); return ( + {props.resources.map((res) => ( res.isMarketplace ? : diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx index 5989e1562..df24ae701 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx @@ -635,9 +635,9 @@ export function HomeLayout(props: HomeLayoutProps) { {mode !== "marketplace" && ( <> {layout === "list" ? ( - + ) : ( - + )} )} diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx index 8abb3d69f..0ce784047 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeResCard.tsx @@ -8,6 +8,7 @@ import { HomeRes } from "./HomeLayout"; import { HomeResTypeEnum } from "../../types/homeRes"; import { updateFolder } from "../../redux/reduxActions/folderActions"; import { + backFolderViewClick, handleAppEditClick, handleAppViewClick, handleFolderViewClick, @@ -23,6 +24,7 @@ import { TypographyText } from "../../components/TypographyText"; import { useParams } from "react-router-dom"; import { messageInstance } from "lowcoder-design/src/components/GlobalInstances"; import { colorPickerEvent } from "@lowcoder-ee/comps/comps/mediaComp/colorPickerComp"; +import {FolderIcon} from "icons"; const EditButton = styled(TacoButton)` width: 52px; @@ -259,3 +261,29 @@ export function HomeResCard(props: { res: HomeRes; onMove: (res: HomeRes) => voi ); } + +export function Back(props: { mode: string }) { + const { mode } = props; + return mode === "folder" ? + + + + { + backFolderViewClick(); + }} + > + +

...

+ +
+
+
+ : <>; +} \ No newline at end of file diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeTableView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeTableView.tsx index c0e700094..e313b2ff6 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeTableView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeTableView.tsx @@ -4,6 +4,7 @@ import { TacoButton } from "lowcoder-design/src/components/button" import styled from "styled-components"; import { useDispatch } from "react-redux"; import { + backFolderViewClick, handleAppEditClick, handleAppViewClick, handleFolderViewClick, @@ -51,8 +52,8 @@ const TypographyText = styled(AntdTypographyText)` width: 100%; `; -export const HomeTableView = (props: { resources: HomeRes[], setModify?: any, modify?: boolean }) => { - const {setModify, modify, resources} = props +export const HomeTableView = (props: { resources: HomeRes[], setModify?: any, modify?: boolean, mode?: string }) => { + const {setModify, modify, resources, mode} = props const dispatch = useDispatch(); const { folderId } = useParams<{ folderId: string }>(); @@ -61,6 +62,20 @@ export const HomeTableView = (props: { resources: HomeRes[], setModify?: any, mo const [needDuplicateRes, setNeedDuplicateRes] = useState(undefined); const [needMoveRes, setNeedMoveRes] = useState(undefined); + const back: HomeRes = { + key: "", + id: "", + name: ". . .", + type: 4, + creator: "", + lastModifyTime: 0, + isManageable: false, + isDeletable: false + } + if (mode === "folder"){ + resources.unshift(back) + } + return ( <> ({ onClick: (e) => { - // console.log(e.target); - const item = record as HomeRes; - if (needRenameRes?.id === item.id || needDuplicateRes?.id === item.id) { - return; - } - if (item.type === HomeResTypeEnum.Folder) { - handleFolderViewClick(item.id); - } else if(item.isMarketplace) { - handleMarketplaceAppViewClick(item.id); - } else { - item.isEditable ? handleAppEditClick(e, item.id) : handleAppViewClick(item.id); + if (mode === "folder" && record.type === 4){ + backFolderViewClick() + } else{ + const item = record as HomeRes; + if (needRenameRes?.id === item.id || needDuplicateRes?.id === item.id) { + return; + } + if (item.type === HomeResTypeEnum.Folder) { + handleFolderViewClick(item.id); + } else if(item.isMarketplace) { + handleMarketplaceAppViewClick(item.id); + } else { + item.isEditable ? handleAppEditClick(e, item.id) : handleAppViewClick(item.id); + } } }, })} @@ -161,7 +179,7 @@ export const HomeTableView = (props: { resources: HomeRes[], setModify?: any, mo }, render: (_, record) => ( - {HomeResInfo[(record as any).type as HomeResTypeEnum].name} + { mode === "folder" && record.type === 4 ? "" : HomeResInfo[(record as any).type as HomeResTypeEnum].name } ), }, @@ -223,7 +241,7 @@ export const HomeTableView = (props: { resources: HomeRes[], setModify?: any, mo ? handleMarketplaceAppViewClick(item.id) : handleAppViewClick(item.id); }} - style={{ marginRight: "52px" }} + style={{ marginRight: "52px", display: mode === "folder" && record.type === 4 ? "none" : "block" }} > {trans("view")} diff --git a/client/packages/lowcoder/src/util/homeResUtils.tsx b/client/packages/lowcoder/src/util/homeResUtils.tsx index 1088ea01f..89c672634 100644 --- a/client/packages/lowcoder/src/util/homeResUtils.tsx +++ b/client/packages/lowcoder/src/util/homeResUtils.tsx @@ -7,7 +7,12 @@ import { NavDocIcon, } from "lowcoder-design"; import { HomeResTypeEnum } from "../types/homeRes"; -import { APPLICATION_VIEW_URL, APPLICATION_MARKETPLACE_VIEW_URL, buildFolderUrl } from "../constants/routesURL"; +import { + APPLICATION_VIEW_URL, + APPLICATION_MARKETPLACE_VIEW_URL, + buildFolderUrl, + ALL_APPLICATIONS_URL +} from "../constants/routesURL"; import history from "./history"; import { trans } from "../i18n"; import { FunctionComponent } from "react"; @@ -62,3 +67,5 @@ export const handleAppViewClick = (id: string) => window.open(APPLICATION_VIEW_U export const handleMarketplaceAppViewClick = (id: string, isLocalMarketplace?: boolean) => isLocalMarketplace == true ? window.open(APPLICATION_VIEW_URL(id, "view_marketplace"), '_blank') : window.open(APPLICATION_MARKETPLACE_VIEW_URL(id, "view_marketplace"), '_blank'); export const handleFolderViewClick = (id: string) => history.push(buildFolderUrl(id)); + +export const backFolderViewClick = () => history.push(ALL_APPLICATIONS_URL); \ No newline at end of file From 1d41e8000c8da47e02c1f1cb2f0aa98593da2847 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Fri, 29 Nov 2024 06:49:28 -0500 Subject: [PATCH 22/38] Processed immediate activity in Query Library. --- .../comps/queryLibrary/queryLibraryComp.tsx | 22 ++++++++++++------- .../src/pages/queryLibrary/LeftNav.tsx | 12 +++++++--- .../pages/queryLibrary/QueryLibraryEditor.tsx | 9 ++++++-- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/queryLibrary/queryLibraryComp.tsx b/client/packages/lowcoder/src/comps/comps/queryLibrary/queryLibraryComp.tsx index 7af0db937..392ffbcc5 100644 --- a/client/packages/lowcoder/src/comps/comps/queryLibrary/queryLibraryComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/queryLibrary/queryLibraryComp.tsx @@ -47,9 +47,9 @@ const children = { const QueryLibraryCompBase = simpleMultiComp(children); export const QueryLibraryComp = class extends QueryLibraryCompBase { - propertyView(params: { onPublish: () => void; onHistoryShow: () => void }) { + propertyView(params: { onPublish: () => void; onHistoryShow: () => void; setModify: any; modify: boolean }) { return ( - + ); } @@ -99,11 +99,13 @@ function getMetaData( } const PropertyView = (props: { - comp: QueryLibraryCompType; - onPublish: () => void; - onHistoryShow: () => void; + comp: QueryLibraryCompType, + onPublish: () => void, + onHistoryShow: () => void, + setModify?: any + modify?: boolean }) => { - const { comp, onPublish, onHistoryShow } = props; + const { comp, onPublish, onHistoryShow, setModify, modify } = props; const reduxDispatch = useDispatch(); @@ -157,12 +159,16 @@ const PropertyView = (props: { CustomModal.confirm({ title: trans("queryLibrary.deleteQueryLabel"), content: trans("queryLibrary.deleteQueryContent"), - onConfirm: () => + onConfirm: () =>{ reduxDispatch( deleteQueryLibrary({ queryLibraryId: comp.children.query.children.id.getView(), }) - ), + ) + setTimeout(() => { + setModify(!modify); + }, 500); + }, confirmBtnType: "delete", okText: trans("delete"), }) diff --git a/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx b/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx index 4357970bb..95b0288ee 100644 --- a/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx +++ b/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx @@ -166,8 +166,10 @@ export const LeftNav = (props: { total: number; setSearchValues: any; searchValues: string; + setModify?: any; + modify?: boolean; }) => { - const {currentPage, setCurrentPage, pageSize, setPageSize, total , setSearchValues, searchValues} = props + const {currentPage, setCurrentPage, pageSize, setPageSize, total , setSearchValues, searchValues, modify, setModify} = props const dispatch = useDispatch(); const [searchValue, setSearchValue] = useState(""); const datasourceTypes = useSelector(getDataSourceTypesMap); @@ -244,8 +246,12 @@ export const LeftNav = (props: { CustomModal.confirm({ title: trans("queryLibrary.deleteQueryTitle"), content: trans("queryLibrary.deleteQueryContent"), - onConfirm: () => - dispatch(deleteQueryLibrary({ queryLibraryId: q.id })), + onConfirm: () => { + dispatch(deleteQueryLibrary({ queryLibraryId: q.id })) + setTimeout(() => { + setModify(!modify); + }, 200); + }, confirmBtnType: "delete", okText: trans("delete"), }), diff --git a/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx b/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx index 257d7f226..d19a599ba 100644 --- a/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx +++ b/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx @@ -91,7 +91,8 @@ export const QueryLibraryEditor = () => { const [queryLibrary, setQueryLibrary] = useState({}); const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); - const [searchValues, setSearchValues] = useState("") + const [searchValues, setSearchValues] = useState(""); + const [modify, setModify] = useState(false); const selectedRecords = queryLibraryRecords[selectedQuery] ?? {}; const libraryQuery = queryLibrary[selectedQuery]; @@ -133,7 +134,7 @@ export const QueryLibraryEditor = () => { } catch (error) { console.error(error) } - }, [currentPage, pageSize, searchValues, setSearchValues]) + }, [currentPage, pageSize, searchValues, modify]) useEffect(() => { if (orgId) { @@ -234,6 +235,8 @@ export const QueryLibraryEditor = () => { total={elements.total} setSearchValues={setSearchValues} searchValues={searchValues} + setModify={setModify} + modify={modify} /> {!selectedQuery || !comp?.children.query.children.id.getView() ? ( @@ -247,6 +250,8 @@ export const QueryLibraryEditor = () => { comp.propertyView({ onPublish: () => setPublishModalVisible(true), onHistoryShow: () => setShowHistory(true), + setModify: setModify, + modify: modify }) )} From 4e1e0c0399524b0d502d71eee9e03aa32f847273 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Fri, 29 Nov 2024 07:36:50 -0500 Subject: [PATCH 23/38] Processed immediate activity in Data Sources. --- .../lowcoder/src/pages/datasource/datasourceList.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx b/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx index 0f7bba90c..40831fe97 100644 --- a/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx +++ b/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx @@ -110,6 +110,7 @@ export const DatasourceList = () => { const [searchValues, setSearchValues] = useState(""); const [isCreateFormShow, showCreateForm] = useState(false); const [shareDatasourceId, setShareDatasourceId] = useState(undefined); + const [modify, setModify] = useState(false); const datasource = useSelector(getDataSource); const currentUser = useSelector(getUser); const orgId = currentUser.currentOrgId; @@ -146,7 +147,7 @@ export const DatasourceList = () => { else console.error("ERROR: fetchFolderElements", result.error) }) - }, [currentPage, pageSize, searchValues] + }, [currentPage, pageSize, searchValues, modify] ) return ( @@ -294,6 +295,10 @@ export const DatasourceList = () => { text: trans("delete"), onClick: () => { dispatch(deleteDatasource({ datasourceId: record.id })); + setTimeout(() => { + setModify(!modify); + }, 500); + }, type: "delete", }, From 90648dca173921fa0ca6fc214e19fc5ed828d93a Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Fri, 29 Nov 2024 10:03:53 -0500 Subject: [PATCH 24/38] Removed unnessary APIs. --- .../lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx | 2 -- .../src/pages/setting/permission/groupUsersPermission.tsx | 4 ---- .../src/pages/setting/permission/orgUsersPermission.tsx | 6 +++--- .../src/pages/setting/permission/permissionDetail.tsx | 7 ------- .../src/pages/setting/permission/permissionList.tsx | 6 ------ 5 files changed, 3 insertions(+), 22 deletions(-) diff --git a/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx b/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx index d19a599ba..43663a455 100644 --- a/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx +++ b/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx @@ -138,8 +138,6 @@ export const QueryLibraryEditor = () => { useEffect(() => { if (orgId) { - dispatch(fetchQueryLibrary()); - dispatch(fetchDataSourceTypes({ organizationId: orgId })); dispatch( fetchDatasource({ organizationId: orgId, diff --git a/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx b/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx index 4be4b2061..67105aa2e 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx @@ -7,7 +7,6 @@ import React, { useEffect, useMemo } from "react"; import { useDispatch } from "react-redux"; import { deleteGroupUserAction, - fetchGroupUsersAction, quitGroupAction, updateUserGroupRoleAction, } from "redux/reduxActions/orgActions"; @@ -65,9 +64,6 @@ function GroupUsersPermission(props: GroupPermissionProp) { }); }, [groupUsers]); const dispatch = useDispatch(); - useEffect(() => { - dispatch(fetchGroupUsersAction({ groupId: group.groupId })); - }, []); return ( <> diff --git a/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx b/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx index b9601a3c3..2354782aa 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx @@ -82,9 +82,9 @@ function OrgUsersPermission(props: UsersPermissionProp) { }); }, [orgUsers]); - useEffect(() => { - dispatch(fetchOrgUsersAction(orgId)); - }, [dispatch, orgId]); + // useEffect(() => { + // dispatch(fetchOrgUsersAction(orgId)); + // }, [dispatch, orgId]); const onResetPass = (userId: string) => { return UserApi.resetPassword(userId) diff --git a/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx b/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx index ec7a91322..60ebf6f87 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx @@ -39,14 +39,7 @@ export default function PermissionSetting() { const user = useSelector(getUser) const orgUsersFetching = useSelector((state: AppState) => state.ui.org.orgUsersFetching); const groupIdMap = new Map(orgGroups.map((group) => [group.groupId, group])); - const dispatch = useDispatch(); const selectKey = useParams<{ groupId: string }>().groupId; - useEffect(() => { - if (!orgId) { - return; - } - dispatch(fetchGroupsAction(orgId)); - }, [orgId]); useEffect( () => { if (selectKey !== "users") diff --git a/client/packages/lowcoder/src/pages/setting/permission/permissionList.tsx b/client/packages/lowcoder/src/pages/setting/permission/permissionList.tsx index 5b88705ab..b6b1ab303 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/permissionList.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/permissionList.tsx @@ -95,12 +95,6 @@ export default function PermissionSetting() { del: false, rename: false, }] : []; - useEffect(() => { - if (!orgId) { - return; - } - dispatch(fetchGroupsAction(orgId)); - }, [orgId]); if (!orgId) { return null; } From b3329801f078f70d9f05e9d5a287a30ae1ced845 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Fri, 29 Nov 2024 11:12:31 -0500 Subject: [PATCH 25/38] Fixed Search functions. --- .../src/pages/ApplicationV2/HomeView.tsx | 19 +++++++++++++------ .../src/pages/ApplicationV2/TrashView.tsx | 9 ++++++++- .../src/pages/datasource/datasourceList.tsx | 9 ++++++++- .../src/pages/queryLibrary/LeftNav.tsx | 5 ++++- .../pages/queryLibrary/QueryLibraryEditor.tsx | 8 +++++++- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx index 4718ec764..8ae72d322 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeView.tsx @@ -43,12 +43,19 @@ export function HomeView() { }, [currentPage, pageSize, searchValues, typeFilter, modify] ); - useEffect(()=> { - setTimeout(() => { - if (searchValue.length > 2 || searchValue === "") - setSearchValues(searchValue) - }, 500); - }, [searchValue]) + useEffect( () => { + if (searchValues !== "") + setCurrentPage(1); + }, [searchValues] + ); + + useEffect(()=> { + const timer = setTimeout(() => { + if (searchValue.length > 2 || searchValue === "") + setSearchValues(searchValue) + }, 500); + return () => clearTimeout(timer); + }, [searchValue]) const user = useSelector(getUser); diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx index 940282984..3355c780a 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx @@ -42,12 +42,19 @@ export function TrashView() { } }, [currentPage, pageSize, searchValues, typeFilter, modify] ); + useEffect( () => { + if (searchValues !== "") + setCurrentPage(1); + }, [searchValues] + ); + //debouncing useEffect(()=> { - setTimeout(() => { + const timer = setTimeout(() => { if (searchValue.length > 2 || searchValue === "") setSearchValues(searchValue) }, 500); + return () => clearTimeout(timer); }, [searchValue]) return ( diff --git a/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx b/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx index 40831fe97..509d3201e 100644 --- a/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx +++ b/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx @@ -126,10 +126,11 @@ export const DatasourceList = () => { const [pageSize, setPageSize] = useState(10); useEffect(()=> { - setTimeout(() => { + const timer = setTimeout(() => { if (searchValue.length > 2 || searchValue === "") setSearchValues(searchValue) }, 500); + return () => clearTimeout(timer); }, [searchValue]) useEffect( () => { @@ -150,6 +151,12 @@ export const DatasourceList = () => { }, [currentPage, pageSize, searchValues, modify] ) + useEffect( () => { + if (searchValues !== "") + setCurrentPage(1); + }, [searchValues] + ); + return ( <> {{trans("home.datasource")}} diff --git a/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx b/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx index 95b0288ee..84bdade67 100644 --- a/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx +++ b/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx @@ -175,12 +175,15 @@ export const LeftNav = (props: { const datasourceTypes = useSelector(getDataSourceTypesMap); useEffect(()=> { - setTimeout(() => { + const timer = setTimeout(() => { if (searchValue.length > 2 || searchValue === "") setSearchValues(searchValue) }, 500); + return () => clearTimeout(timer); }, [searchValue]) + + return ( diff --git a/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx b/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx index 43663a455..5171b70cf 100644 --- a/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx +++ b/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx @@ -134,7 +134,13 @@ export const QueryLibraryEditor = () => { } catch (error) { console.error(error) } - }, [currentPage, pageSize, searchValues, modify]) + }, [currentPage, pageSize, searchValues, modify]) + + useEffect( () => { + if (searchValues !== "") + setCurrentPage(1); + }, [searchValues] + ); useEffect(() => { if (orgId) { From 34ce9898d57e114a0f362be8e683ec69356b5700 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Fri, 29 Nov 2024 12:13:38 -0500 Subject: [PATCH 26/38] Fixed pagination of folders and UI. --- client/packages/lowcoder/src/api/folderApi.ts | 3 +- .../src/pages/ApplicationV2/FolderView.tsx | 77 ++++++++++++++++--- .../src/pages/ApplicationV2/HomeLayout.tsx | 4 +- .../src/pages/ApplicationV2/HomeTableView.tsx | 2 +- .../lowcoder/src/util/pagination/type.ts | 1 + 5 files changed, 73 insertions(+), 14 deletions(-) diff --git a/client/packages/lowcoder/src/api/folderApi.ts b/client/packages/lowcoder/src/api/folderApi.ts index 30aef9251..113bab046 100644 --- a/client/packages/lowcoder/src/api/folderApi.ts +++ b/client/packages/lowcoder/src/api/folderApi.ts @@ -48,6 +48,7 @@ export class FolderApi extends Api { static fetchFolderElementsPagination( request: fetchFolderRequestType ): AxiosPromise> { - return Api.get(FolderApi.url + `/elements`, { ...request }); + const {id, ...res} = request + return request.id ? Api.get(FolderApi.url + `/elements`,{id: id, ...res}) : Api.get(FolderApi.url + `/elements`, { ...request }); } } diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/FolderView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/FolderView.tsx index b5e3ecab2..1d606bf84 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/FolderView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/FolderView.tsx @@ -2,12 +2,13 @@ import { useDispatch, useSelector } from "react-redux"; import { useParams } from "react-router-dom"; import { HomeBreadcrumbType, HomeLayout } from "./HomeLayout"; import {useEffect, useState} from "react"; -import { fetchFolderElements } from "../../redux/reduxActions/folderActions"; -import { FolderMeta } from "../../constants/applicationConstants"; +import {ApplicationMeta, FolderMeta} from "../../constants/applicationConstants"; import { buildFolderUrl } from "../../constants/routesURL"; import { folderElementsSelector, foldersSelector } from "../../redux/selectors/folderSelector"; 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"; function getBreadcrumbs( folder: FolderMeta, @@ -30,13 +31,25 @@ function getBreadcrumbs( return breadcrumb; } +interface ElementsState { + elements: ApplicationMeta[]; + total: number; +} + export function FolderView() { const { folderId } = useParams<{ folderId: string }>(); + const [elements, setElements] = useState({ elements: [], total: 0 }); + const [currentPage, setCurrentPage] = useState(1); + const [pageSize, setPageSize] = useState(10); + const [searchValues, setSearchValues] = useState(""); + const [typeFilter, setTypeFilter] = useState(0); + const [modify, setModify] = useState(true); + const [searchValue, setSearchValue] = useState(""); + const dispatch = useDispatch(); - const [searchValue, setSearchValue] = useState("") - const elements = useSelector(folderElementsSelector); + const element = useSelector(folderElementsSelector); const allFolders = useSelector(foldersSelector); const folder = allFolders.filter((f) => f.folderId === folderId)[0] || {}; @@ -47,16 +60,60 @@ export function FolderView() { }, ]); - useEffect(() => { - setTimeout(() => { - dispatch(fetchFolderElements({ folderId: folderId })); - }, 100); - }, [folderId]); + useEffect( () => { + try{ + fetchFolderElements({ + id: folderId, + pageNum:currentPage, + pageSize:pageSize, + applicationType: ApplicationPaginationType[typeFilter], + name: searchValues, + }).then( + (data: any) => { + if (data.success) { + setElements({elements: data.data || [], total: data.total || 1}) + } + else + console.error("ERROR: fetchFolderElements", data.error) + } + ); + } catch (error) { + console.error('Failed to fetch data:', error); + } + }, [currentPage, pageSize, searchValues, typeFilter, modify]); + + useEffect( () => { + if (searchValues !== "") + setCurrentPage(1); + }, [searchValues] + ); + + useEffect(()=> { + const timer = setTimeout(() => { + if (searchValue.length > 2 || searchValue === "") + setSearchValues(searchValue) + }, 500); + return () => clearTimeout(timer); + }, [searchValue]) return ( <> {{trans("home.yourFolders")}} - + ); } diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx index df24ae701..a042a10c4 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx @@ -203,7 +203,7 @@ const EmptyView = styled.div` const PaginationLayout = styled.div` display: flex; justify-content: center; - margin-top: -20px; + margin-top: 20px; margin-bottom: 20px; ` @@ -363,7 +363,7 @@ export function HomeLayout(props: HomeLayoutProps) { const isSelfHost = window.location.host !== 'app.lowcoder.cloud'; const [typeFilter, setTypeFilter] = useState("All"); const [categoryFilter, setCategoryFilter] = useState("All"); - const [visibility, setVisibility] = useState(mode === "view" || mode === "trash"); + const [visibility, setVisibility] = useState(mode === "view" || mode === "trash" || mode === "folder"); const [layout, setLayout] = useState( checkIsMobile(window.innerWidth) ? "card" : getHomeLayout() ); diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeTableView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeTableView.tsx index e313b2ff6..bd0cf6b82 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeTableView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeTableView.tsx @@ -79,7 +79,7 @@ export const HomeTableView = (props: { resources: HomeRes[], setModify?: any, mo return ( <>
Date: Fri, 29 Nov 2024 14:40:38 -0500 Subject: [PATCH 27/38] Fixed an issue that can not search Navigation. --- client/packages/lowcoder/src/util/pagination/type.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/packages/lowcoder/src/util/pagination/type.ts b/client/packages/lowcoder/src/util/pagination/type.ts index d443aeb0e..d7c1ae2e8 100644 --- a/client/packages/lowcoder/src/util/pagination/type.ts +++ b/client/packages/lowcoder/src/util/pagination/type.ts @@ -11,7 +11,7 @@ export const ApplicationPaginationType: ApplicationType = { 3: "NAVLAYOUT", 4: "FOLDER", 6: "MOBILETABLAYOUT", - 7: "NAVIGATION", + 7: "COMPOUND_APPLICATION", }; export interface GenericApiPaginationResponse { From 24469a31bdc13f5525f8f6a186d6b12ed4763b7a Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Sat, 30 Nov 2024 19:34:26 -0500 Subject: [PATCH 28/38] Fixed loading indicator in setting/permission. --- .../pages/setting/permission/groupUsersPermission.tsx | 2 +- .../pages/setting/permission/orgUsersPermission.tsx | 2 +- .../src/pages/setting/permission/permissionDetail.tsx | 11 +++++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx b/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx index 67105aa2e..3a576d99f 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx @@ -98,7 +98,7 @@ function GroupUsersPermission(props: GroupPermissionProp) { dataSource={sortedGroupUsers} rowKey="userId" pagination={false} - loading={groupUsersFetching} + loading={groupUsers.length === 0} > state.ui.org.orgUsersFetching); const groupIdMap = new Map(orgGroups.map((group) => [group.groupId, group])); + const dispatch = useDispatch(); const selectKey = useParams<{ groupId: string }>().groupId; + useEffect(() => { + if (!orgId) { + return; + } + dispatch(fetchGroupsAction(orgId)); + }, [orgId]); useEffect( () => { - if (selectKey !== "users") + if (selectKey !== "users" && !!groupIdMap.get(selectKey)) fetchGroupUsrPagination( { groupId: groupIdMap.get(selectKey)!.groupId, @@ -73,7 +80,7 @@ export default function PermissionSetting() { const user = useSelector(getUser) } ) }, - [currentPage, pageSize, modify] + [currentPage, pageSize, modify, groupIdMap.get(selectKey)] ) if (!orgId) { From 56ff238ffd22d20dd401660e49a57032056279c9 Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Mon, 2 Dec 2024 10:12:33 -0500 Subject: [PATCH 29/38] Fixed an issue that does not display 'Add member' button and 'Remove from Group' in group members table. --- .../permission/groupUsersPermission.tsx | 5 ++- .../setting/permission/orgUsersPermission.tsx | 6 ++-- .../setting/permission/permissionDetail.tsx | 35 ++++++++----------- .../lowcoder/src/util/pagination/axios.ts | 3 +- 4 files changed, 21 insertions(+), 28 deletions(-) diff --git a/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx b/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx index 3a576d99f..4ed3e0a3c 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/groupUsersPermission.tsx @@ -3,7 +3,7 @@ import { User } from "constants/userConstants"; import { AddIcon, ArrowIcon, CustomSelect, PackUpIcon, SuperUserIcon } from "lowcoder-design"; import { trans } from "i18n"; import ProfileImage from "pages/common/profileImage"; -import React, { useEffect, useMemo } from "react"; +import React, { useMemo } from "react"; import { useDispatch } from "react-redux"; import { deleteGroupUserAction, @@ -41,7 +41,6 @@ type GroupPermissionProp = { group: OrgGroup; orgId: string; groupUsers: GroupUser[]; - groupUsersFetching: boolean; currentUserGroupRole: string; currentUser: User; setModify?: any; @@ -50,7 +49,7 @@ type GroupPermissionProp = { function GroupUsersPermission(props: GroupPermissionProp) { const { Column } = TableStyled; - const { group, orgId, groupUsersFetching, groupUsers, currentUserGroupRole, currentUser , setModify, modify} = props; + const { group, orgId, groupUsers, currentUserGroupRole, currentUser , setModify, modify} = props; const adminCount = groupUsers.filter((user) => isGroupAdmin(user.role)).length; const sortedGroupUsers = useMemo(() => { return [...groupUsers].sort((a, b) => { diff --git a/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx b/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx index 009c14db6..e00d06e66 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/orgUsersPermission.tsx @@ -14,11 +14,10 @@ import { import { trans, transToNode } from "i18n"; import InviteDialog from "pages/common/inviteDialog"; import ProfileImage from "pages/common/profileImage"; -import React, { useEffect, useMemo } from "react"; +import React, { useMemo } from "react"; import { useDispatch, useSelector } from "react-redux"; import { deleteOrgUserAction, - fetchOrgUsersAction, quitOrgAction, updateUserOrgRoleAction, } from "redux/reduxActions/orgActions"; @@ -56,7 +55,6 @@ const StyledMembersIcon = styled(MembersIcon)` type UsersPermissionProp = { orgId: string; orgUsers: OrgUser[]; - orgUsersFetching: boolean; currentUser: User; setModify?: any; modify?: boolean; @@ -64,7 +62,7 @@ type UsersPermissionProp = { function OrgUsersPermission(props: UsersPermissionProp) { const { Column } = TableStyled; - const { orgId, orgUsers, orgUsersFetching, currentUser , setModify, modify} = props; + const { orgId, orgUsers, currentUser , setModify, modify} = props; const adminCount = orgUsers.filter( (user) => user.role === ADMIN_ROLE || user.role === SUPER_ADMIN_ROLE, ).length; diff --git a/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx b/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx index 67472483d..933522e3e 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx @@ -7,7 +7,6 @@ import GroupPermission from "./groupUsersPermission"; import UsersPermission from "./orgUsersPermission"; import { getOrgGroups } from "redux/selectors/orgSelectors"; import { useParams } from "react-router-dom"; -import { AppState } from "redux/reducers"; import {fetchGroupUsrPagination, fetchOrgUsrPagination} from "@lowcoder-ee/util/pagination/axios"; import PaginationComp from "@lowcoder-ee/util/pagination/Pagination"; @@ -25,7 +24,7 @@ const All_Users = "users"; export default function PermissionSetting() { const user = useSelector(getUser); - const [elements, setElements] = useState({ elements: [], total: 0 }); + const [elements, setElements] = useState({ elements: [], total: 0, role: "" }); const [orgMemberElements, setOrgMemberElements] = useState({ elements: [], total: 0 }) const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); @@ -33,10 +32,7 @@ export default function PermissionSetting() { const user = useSelector(getUser) const orgId = user.currentOrgId; const orgGroups = useSelector(getOrgGroups); - const groupUsersFetching = useSelector((state: AppState) => state.ui.org.groupUsersFetching); - const currentUserGroupRole = useSelector((state: AppState) => state.ui.org.currentUserGroupRole); const currentUser = useSelector(getUser); - const orgUsersFetching = useSelector((state: AppState) => state.ui.org.orgUsersFetching); const groupIdMap = new Map(orgGroups.map((group) => [group.groupId, group])); const dispatch = useDispatch(); @@ -47,7 +43,6 @@ export default function PermissionSetting() { const user = useSelector(getUser) } dispatch(fetchGroupsAction(orgId)); }, [orgId]); - useEffect( () => { if (selectKey !== "users" && !!groupIdMap.get(selectKey)) fetchGroupUsrPagination( @@ -58,27 +53,29 @@ export default function PermissionSetting() { const user = useSelector(getUser) } ).then(result => { if (result.success){ - setElements({elements: result.data || [], total: result.total || 1}) + setElements({elements: result.data || [], total: result.total || 1, role: result.visitorRole || ""}) } else console.error("ERROR: fetchFolderElements", result.error) } ) else + { fetchOrgUsrPagination( - { - orgId: orgId, - pageNum: currentPage, - pageSize: pageSize, - } + { + orgId: orgId, + pageNum: currentPage, + pageSize: pageSize, + } ).then(result => { - if (result.success){ - setOrgMemberElements({elements: result.data || [], total: result.total || 1}) - } - else - console.error("ERROR: fetchFolderElements", result.error) + if (result.success){ + setOrgMemberElements({elements: result.data || [], total: result.total || 1}) } + else + console.error("ERROR: fetchFolderElements", result.error) + } ) + } }, [currentPage, pageSize, modify, groupIdMap.get(selectKey)] ) @@ -93,7 +90,6 @@ export default function PermissionSetting() { const user = useSelector(getUser) <> Date: Mon, 2 Dec 2024 16:13:01 -0500 Subject: [PATCH 30/38] Optimized called APIs and in User groups. --- .../src/pages/setting/permission/index.tsx | 13 +++-- .../setting/permission/permissionDetail.tsx | 57 +++++++++++-------- .../setting/permission/permissionList.tsx | 37 +++++++----- 3 files changed, 63 insertions(+), 44 deletions(-) diff --git a/client/packages/lowcoder/src/pages/setting/permission/index.tsx b/client/packages/lowcoder/src/pages/setting/permission/index.tsx index 8c59eaa2e..6302d535a 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/index.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/index.tsx @@ -1,13 +1,16 @@ -import { Route, Switch } from "react-router"; +import React, {useState} from "react"; +import { Route, Switch } from "react-router-dom"; import PermissionList from "./permissionList"; import PermissionDetail from "./permissionDetail"; import { PERMISSION_SETTING, PERMISSION_SETTING_DETAIL, SETTING_URL } from "constants/routesURL"; -export default () => { +export default function PermissionRoutes() { + const [currentPage, setCurrentPage] = useState(1); + const [pageSize, setPageSize] = useState(10); return ( - - + } /> + } /> ); -}; +} \ No newline at end of file diff --git a/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx b/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx index 933522e3e..d144c4e47 100644 --- a/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx +++ b/client/packages/lowcoder/src/pages/setting/permission/permissionDetail.tsx @@ -1,14 +1,13 @@ import React, {useEffect, useState} from "react"; -import { useDispatch, useSelector } from "react-redux"; -import { fetchGroupsAction } from "redux/reduxActions/orgActions"; +import { useSelector } from "react-redux"; import { getUser } from "redux/selectors/usersSelectors"; import styled from "styled-components"; import GroupPermission from "./groupUsersPermission"; import UsersPermission from "./orgUsersPermission"; -import { getOrgGroups } from "redux/selectors/orgSelectors"; import { useParams } from "react-router-dom"; -import {fetchGroupUsrPagination, fetchOrgUsrPagination} from "@lowcoder-ee/util/pagination/axios"; +import {fetchGroupUsrPagination, fetchOrgGroups, fetchOrgUsrPagination} from "@lowcoder-ee/util/pagination/axios"; import PaginationComp from "@lowcoder-ee/util/pagination/Pagination"; +import {OrgGroup} from "@lowcoder-ee/constants/orgConstants"; const PermissionContent = styled.div` display: flex; @@ -20,34 +19,42 @@ const PermissionContent = styled.div` width: 100%; `; -const All_Users = "users"; +export default function PermissionSetting(props: {currentPageProp: number, pageSizeProp: number}) { -export default function PermissionSetting() { const user = useSelector(getUser); - - const [elements, setElements] = useState({ elements: [], total: 0, role: "" }); - const [orgMemberElements, setOrgMemberElements] = useState({ elements: [], total: 0 }) + const {currentPageProp, pageSizeProp} = props; + const user = useSelector(getUser); + const [elements, setElements] = useState({ elements: [], total: 1, role: "" }); + const [group, setGrouop] = useState(); + const [orgMemberElements, setOrgMemberElements] = useState({ elements: [], total: 1 }) const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); const [modify, setModify] = useState(false); const orgId = user.currentOrgId; - const orgGroups = useSelector(getOrgGroups); const currentUser = useSelector(getUser); - - const groupIdMap = new Map(orgGroups.map((group) => [group.groupId, group])); - const dispatch = useDispatch(); const selectKey = useParams<{ groupId: string }>().groupId; - useEffect(() => { - if (!orgId) { - return; - } - dispatch(fetchGroupsAction(orgId)); - }, [orgId]); + + useEffect( () => { + fetchOrgGroups( + { + pageNum: currentPageProp, + pageSize: pageSizeProp, + } + ).then(result => { + if (result.success && !!result.data){ + setGrouop(result.data.find(group => group.groupId === selectKey)) + } + else + console.error("ERROR: fetchFolderElements", result.error) + }) + }, [currentPageProp, pageSizeProp] + ) + useEffect( () => { - if (selectKey !== "users" && !!groupIdMap.get(selectKey)) + if (selectKey !== "users" && selectKey) fetchGroupUsrPagination( { - groupId: groupIdMap.get(selectKey)!.groupId, + groupId:selectKey, pageNum: currentPage, pageSize: pageSize, } @@ -77,7 +84,7 @@ export default function PermissionSetting() { const user = useSelector(getUser) ) } }, - [currentPage, pageSize, modify, groupIdMap.get(selectKey)] + [currentPage, pageSize, modify, selectKey] ) if (!orgId) { @@ -86,7 +93,7 @@ export default function PermissionSetting() { const user = useSelector(getUser) return ( - {selectKey === All_Users ? ( + {selectKey === "users" ? ( <> ) : ( - groupIdMap.has(selectKey) && ( + group && ( <> void; + pageSize: number; + setPageSize: (value: number) => void; +}; + interface ElementsState { elements: OrgGroup[]; total: number; } -export default function PermissionSetting() { +export default function PermissionSetting(props: PermissionSettingProps) { + + const {currentPage, setCurrentPage, pageSize, setPageSize} = props; let dataSource: DataItemInfo[] = []; const user = useSelector(getUser); const orgId = user.currentOrgId; @@ -66,27 +75,27 @@ export default function PermissionSetting() { const { nameSuffixFunc, menuItemsFunc, menuExtraView } = usePermissionMenuItems(orgId); const [groupCreating, setGroupCreating] = useState(false); const [elements, setElements] = useState({ elements: [], total: 0 }); - const [currentPage, setCurrentPage] = useState(1); - const [pageSize, setPageSize] = useState(10); const [modify, setModify] = useState(false); + const visibleOrgGroups = elements.elements.filter((g) => !g.allUsersGroup); + const allUsersGroup = elements.elements.find((g) => g.allUsersGroup); useEffect( () => { - fetchOrgGroups( + fetchOrgGroups( { pageNum: currentPage, pageSize: pageSize, } - ).then(result => { - if (result.success){ - setElements({elements: result.data || [], total: result.total || 1}) - } - else - console.error("ERROR: fetchFolderElements", result.error) - }) - }, [currentPage, pageSize, modify] + ).then(result => { + if (result.success){ + setElements({elements: result.data || [], total: result.total || 1}) + } + else + console.error("ERROR: fetchFolderElements", result.error) + }) + }, [currentPage, pageSize, modify] ) - const visibleOrgGroups = elements.elements.filter((g) => !g.allUsersGroup); - const allUsersGroup = elements.elements.find((g) => g.allUsersGroup); + + dataSource = currentPage === 1 ? [{ key: "users", label: trans("memberSettings.allMembers"), From 3d75c3ad7a29796ca2e427ccab70e8c8ad2b061a Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Tue, 3 Dec 2024 03:49:55 -0500 Subject: [PATCH 31/38] Fixed an issue that call double API in login. --- .../src/pages/userAuth/formLoginSteps.tsx | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx b/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx index 70c1aaa79..2504ca3f4 100644 --- a/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx +++ b/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx @@ -2,8 +2,6 @@ import { FormInput, messageInstance, PasswordInput } from "lowcoder-design"; import { AuthBottomView, ConfirmButton, - FormWrapperMobile, - LoginCardTitle, StyledRouteLink, } from "pages/userAuth/authComponents"; import React, { useContext, useEffect, useState } from "react"; @@ -15,7 +13,7 @@ import { UserConnectionSource } from "@lowcoder-ee/constants/userConstants"; import { trans } from "i18n"; import { AuthContext, useAuthSubmit } from "pages/userAuth/authUtils"; import { ThirdPartyAuth } from "pages/userAuth/thirdParty/thirdPartyAuth"; -import { AUTH_FORGOT_PASSWORD_URL, AUTH_REGISTER_URL, ORG_AUTH_FORGOT_PASSWORD_URL, ORG_AUTH_REGISTER_URL } from "constants/routesURL"; +import { AUTH_FORGOT_PASSWORD_URL, AUTH_REGISTER_URL } from "constants/routesURL"; import { Link, useLocation, useParams } from "react-router-dom"; import { Divider } from "antd"; import Flex from "antd/es/flex"; @@ -27,7 +25,6 @@ import LeftOutlined from "@ant-design/icons/LeftOutlined"; import { fetchConfigAction } from "@lowcoder-ee/redux/reduxActions/configActions"; import { useDispatch, useSelector } from "react-redux"; import history from "util/history"; -import ApplicationApi from "@lowcoder-ee/api/applicationApi"; import { getServerSettings } from "@lowcoder-ee/redux/selectors/applicationSelector"; import {fetchOrgPaginationByEmail} from "@lowcoder-ee/util/pagination/axios"; import PaginationComp from "@lowcoder-ee/util/pagination/Pagination"; @@ -120,9 +117,10 @@ export default function FormLoginSteps(props: FormLoginProps) { const serverSettings = useSelector(getServerSettings); const [elements, setElements] = useState({ elements: [], total: 0 }); const [currentPage, setCurrentPage] = useState(1); - const [pageSize, setPageSize] = useState(2); + const [pageSize, setPageSize] = useState(10); useEffect(() => { + if (account) fetchOrgPaginationByEmail({ email: account, pageNum: currentPage, @@ -169,20 +167,25 @@ export default function FormLoginSteps(props: FormLoginProps) { } setOrgLoading(true); - OrgApi.fetchOrgsByEmail(account) + fetchOrgPaginationByEmail({ + email: account, + pageNum: currentPage, + pageSize: pageSize + }) .then((resp) => { - if (validateResponse(resp)) { - setOrgList(resp.data.data); - if (!resp.data.data.length) { + if (resp.success) { + setElements({elements: resp.data || [], total: resp.total || 1}) + setOrgList(resp.data); + if (!resp.data.length) { history.push( AUTH_REGISTER_URL, {...location.state || {}, email: account}, ) return; } - if (resp.data.data.length === 1) { - setOrganizationId(resp.data.data[0].orgId); - dispatch(fetchConfigAction(resp.data.data[0].orgId)); + if (resp.data.length === 1) { + setOrganizationId(resp.data[0].orgId); + dispatch(fetchConfigAction(resp.data[0].orgId)); setCurrentStep(CurrentStepEnum.AUTH_PROVIDERS); return; } From ffd2889c05c320ce76570367cc2d79480e9e0dca Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Tue, 3 Dec 2024 09:33:47 -0500 Subject: [PATCH 32/38] Does not show Pagination when No data in Data Source. --- .../src/pages/datasource/datasourceList.tsx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx b/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx index 509d3201e..f85ab88ba 100644 --- a/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx +++ b/client/packages/lowcoder/src/pages/datasource/datasourceList.tsx @@ -111,7 +111,6 @@ export const DatasourceList = () => { const [isCreateFormShow, showCreateForm] = useState(false); const [shareDatasourceId, setShareDatasourceId] = useState(undefined); const [modify, setModify] = useState(false); - const datasource = useSelector(getDataSource); const currentUser = useSelector(getUser); const orgId = currentUser.currentOrgId; const datasourceLoading = useSelector(getDataSourceLoading); @@ -336,13 +335,13 @@ export const DatasourceList = () => { creator: info.creatorName, edit: info.edit, }))} /> - + { !!elements.elements.length ? : <>} {shareDatasourceId && ( Date: Tue, 3 Dec 2024 13:29:05 -0500 Subject: [PATCH 33/38] Implemented update-on-action when import file and create new Data Sources. --- .../src/pages/queryLibrary/QueryLibraryEditor.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx b/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx index 5171b70cf..d331b568a 100644 --- a/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx +++ b/client/packages/lowcoder/src/pages/queryLibrary/QueryLibraryEditor.tsx @@ -213,6 +213,11 @@ export const QueryLibraryEditor = () => { }, (resp) => { setSelectedQuery(resp.data.data.id); + setTimeout(() => { + setModify(!modify); + }, 200); + setCurrentPage(Math.ceil(elements.total / pageSize)); + }, () => {} ) @@ -273,6 +278,10 @@ export const QueryLibraryEditor = () => { onSuccess: (resp) => { setSelectedQuery(resp.data.data.id); showCreatePanel(false); + setTimeout(() => { + setModify(!modify); + }, 200); + setCurrentPage(Math.ceil(elements.total / pageSize)); }, })} /> )} From bed5f55fd0c6bdccb0e42b66c6a0126db13f736d Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Tue, 3 Dec 2024 15:57:07 -0500 Subject: [PATCH 34/38] Removed unnessary API calling (folders/elements) when first loading. --- client/packages/lowcoder/src/pages/ApplicationV2/index.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx index 5a3a2f3fa..79a7bfcdb 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx @@ -207,13 +207,6 @@ export default function ApplicationHome() { user.currentOrgId && dispatch(fetchAllApplications({})); }, [dispatch, allAppCount, user.currentOrgId]); - useEffect(() => { - if (allFoldersCount !== 0) { - return; - } - user.currentOrgId && dispatch(fetchFolderElements({})); - }, [dispatch, allFoldersCount, user.currentOrgId]); - if (fetchingUser || !isPreloadCompleted) { return ; } From 6f9b8215b3a1800811140891f5cca7bd28dcec74 Mon Sep 17 00:00:00 2001 From: FalkWolsky Date: Tue, 3 Dec 2024 22:19:46 +0100 Subject: [PATCH 35/38] Updating Yarn Lock --- server/node-service/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/node-service/yarn.lock b/server/node-service/yarn.lock index 03d63ef0f..d587e2cd0 100644 --- a/server/node-service/yarn.lock +++ b/server/node-service/yarn.lock @@ -8422,8 +8422,8 @@ __metadata: linkType: hard "node-gyp@npm:latest": - version: 10.2.0 - resolution: "node-gyp@npm:10.2.0" + version: 10.3.1 + resolution: "node-gyp@npm:10.3.1" dependencies: env-paths: ^2.2.0 exponential-backoff: ^3.1.1 @@ -8437,7 +8437,7 @@ __metadata: which: ^4.0.0 bin: node-gyp: bin/node-gyp.js - checksum: 0233759d8c19765f7fdc259a35eb046ad86c3d09e22f7384613ae2b89647dd27fcf833fdf5293d9335041e91f9b1c539494225959cdb312a5c8080b7534b926f + checksum: 91b0690ab504fe051ad66863226dc5ecac72b8471f85e8428e4d5ca3217d3a2adfffae48cd555e8d009a4164689fff558b88d2bc9bfd246452a3336ab308cf99 languageName: node linkType: hard From 326d27e31d49c830fec13340cbc24f154938079e Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Tue, 3 Dec 2024 17:34:31 -0500 Subject: [PATCH 36/38] Fixed an issue that app does not move to folder. --- client/packages/lowcoder/src/pages/ApplicationV2/index.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx index 79a7bfcdb..5a3a2f3fa 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/index.tsx @@ -207,6 +207,13 @@ export default function ApplicationHome() { user.currentOrgId && dispatch(fetchAllApplications({})); }, [dispatch, allAppCount, user.currentOrgId]); + useEffect(() => { + if (allFoldersCount !== 0) { + return; + } + user.currentOrgId && dispatch(fetchFolderElements({})); + }, [dispatch, allFoldersCount, user.currentOrgId]); + if (fetchingUser || !isPreloadCompleted) { return ; } From 9fcd924d1d0b5a5150fc7a1487f5521126ed964b Mon Sep 17 00:00:00 2001 From: Imiss-U1025 Date: Tue, 3 Dec 2024 18:57:10 -0500 Subject: [PATCH 37/38] Added categories dropdown button in Your apps. --- .../lowcoder/src/pages/ApplicationV2/HomeLayout.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx index a042a10c4..09cb1f9d0 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx @@ -551,6 +551,16 @@ export function HomeLayout(props: HomeLayoutProps) { getPopupContainer={(node: any) => node} suffixIcon={} /> )} + {mode === "view" && + setCategoryFilter(value as ApplicationCategoriesEnum)} + options={categoryOptions} + // getPopupContainer={(node) => node} + suffixIcon={} + />} {mode === "marketplace" && ( Date: Wed, 4 Dec 2024 02:25:26 -0500 Subject: [PATCH 38/38] Fixed an Navigation issue in Trash and Your Apps. --- .../packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx | 2 +- .../packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx index 09cb1f9d0..228fd0487 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/HomeLayout.tsx @@ -545,7 +545,7 @@ export function HomeLayout(props: HomeLayoutProps) { getFilterMenuItem(HomeResTypeEnum.All), getFilterMenuItem(HomeResTypeEnum.Application), getFilterMenuItem(HomeResTypeEnum.Module), - ...(mode !== "marketplace" ? [getFilterMenuItem(HomeResTypeEnum.Navigation)] : []), + ...(mode !== "marketplace" ? [getFilterMenuItem(HomeResTypeEnum.Navigation), getFilterMenuItem(HomeResTypeEnum.MobileTabLayout)] : []), ...(mode !== "trash" && mode !== "marketplace" ? [getFilterMenuItem(HomeResTypeEnum.Folder)] : []), ]} getPopupContainer={(node: any) => node} diff --git a/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx b/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx index 3355c780a..410a2632f 100644 --- a/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx +++ b/client/packages/lowcoder/src/pages/ApplicationV2/TrashView.tsx @@ -20,13 +20,11 @@ export function TrashView() { const [modify, setModify] = useState(false); useEffect( () => { - if (typeFilter === 7) // Application of Navigation is 3 in API. - setTypeFilter(3); try{ fetchApplicationElements({ pageNum:currentPage, pageSize:pageSize, - applicationType: typeFilter, + applicationType: typeFilter === 7 ? 3 : typeFilter, // // Application of Navigation is 3 in API. name: searchValues, }).then( data => {