Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[Fix]: #1848 remove unnecessary calls and optimization#1877

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
iamfaran wants to merge6 commits intolowcoder-org:dev
base:dev
Choose a base branch
Loading
fromiamfaran:fix/1848-optimization
Open
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletionsclient/packages/lowcoder/src/api/datasourceApi.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -187,6 +187,10 @@ export class DatasourceApi extends Api {
return Api.get(DatasourceApi.url + `/listByOrg?orgId=${orgId}`, {...res});
}

static getDatasourceById(id: string): AxiosPromise<GenericApiResponse<Datasource>> {
return Api.get(`${DatasourceApi.url}/${id}`);
}

static createDatasource(
datasourceConfig: Partial<Datasource>
): AxiosPromise<GenericApiResponse<Datasource>> {
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,6 +9,8 @@ import { Helmet } from "react-helmet";
import { trans } from "i18n";
import {ApplicationPaginationType} from "@lowcoder-ee/util/pagination/type";
import {fetchFolderElements} from "@lowcoder-ee/util/pagination/axios";
import { fetchFolderElements as fetchFolderElementsRedux } from "../../redux/reduxActions/folderActions";
import { getUser } from "../../redux/selectors/usersSelectors";

function getBreadcrumbs(
folder: FolderMeta,
Expand DownExpand Up@@ -52,6 +54,7 @@ export function FolderView() {

const element = useSelector(folderElementsSelector);
const allFolders = useSelector(foldersSelector);
const user = useSelector(getUser);

const folder = allFolders.filter((f) => f.folderId === folderId)[0] || {};
const breadcrumbs = getBreadcrumbs(folder, allFolders, [
Expand All@@ -61,6 +64,13 @@ export function FolderView() {
},
]);

// Fetch folder data for breadcrumbs if not available
useEffect(() => {
if (allFolders.length === 0 && user.currentOrgId) {
dispatch(fetchFolderElementsRedux({}));
}
}, [allFolders.length, user.currentOrgId, dispatch]);

useEffect( () => {
try{
fetchFolderElements({
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,8 +3,6 @@ import { HomeResTypeEnum } from "../../types/homeRes";
import { exportApplicationAsJSONFile } from "./components/AppImport";
import { CustomModal, EditPopover, EditPopoverItemType, PointIcon } from "lowcoder-design";
import { HomeResInfo } from "../../util/homeResUtils";
import { recycleApplication } from "../../redux/reduxActions/applicationActions";
import { deleteFolder } from "../../redux/reduxActions/folderActions";
import { useDispatch } from "react-redux";
import React, { useState } from "react";
import styled from "styled-components";
Expand All@@ -13,6 +11,9 @@ import { useParams } from "react-router-dom";
import { AppTypeEnum } from "constants/applicationConstants";
import { CopyModal } from "pages/common/copyModal";
import { messageInstance } from "lowcoder-design/src/components/GlobalInstances";
import ApplicationApi from "../../api/applicationApi";
import { FolderApi } from "../../api/folderApi";
import { ReduxActionTypes } from "constants/reduxActionConstants";

const PopoverIcon = styled(PointIcon)`
cursor: pointer;
Expand DownExpand Up@@ -80,23 +81,20 @@ export const HomeResOptions = (props: {
type: HomeResInfo[res.type].name,
name: <b>{res.name}</b>,
}),
onConfirm: () =>{
new Promise((resolve, reject) => {
dispatch(
recycleApplication(
{ applicationId: res.id, folderId: folderId },
() => {
messageInstance.success(trans("success"));
resolve(true);
},
() => reject()
)
);
onConfirm: async () => {
try {
await ApplicationApi.recycleApplication({
applicationId: res.id,
folderId: folderId || ""
});
messageInstance.success(trans("success"));
setTimeout(() => {
setModify(!modify);
}, 200);
})

} catch (error) {
console.error("Failed to recycle application:", error);
messageInstance.error("Failed to delete application");
}
},
confirmBtnType: "delete",
okText: trans("home.moveToTrash"),
Expand All@@ -122,22 +120,27 @@ export const HomeResOptions = (props: {
type: HomeResInfo[res.type].name.toLowerCase(),
name: <b>{res.name}</b>,
}),
onConfirm: () =>{
new Promise((resolve, reject) => {
dispatch(
deleteFolder(
{ folderId: res.id, parentFolderId: folderId },
() => {
messageInstance.success(trans("home.deleteSuccessMsg"));
resolve(true);
},
() => reject()
)
);
})
setTimeout(() => {
setModify(!modify);
}, 200);
onConfirm: async () => {
try {
await FolderApi.deleteFolder({
folderId: res.id,
parentFolderId: folderId || ""
});

// Update Redux state to remove deleted folder from dropdown
dispatch({
type: ReduxActionTypes.DELETE_FOLDER_SUCCESS,
payload: { folderId: res.id, parentFolderId: folderId || "" }
});

messageInstance.success(trans("home.deleteSuccessMsg"));
setTimeout(() => {
setModify(!modify);
}, 200);
} catch (error) {
console.error("Failed to delete folder:", error);
messageInstance.error("Failed to delete folder");
}
},
confirmBtnType: "delete",
okText: trans("delete"),
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,11 +5,11 @@ import styled from "styled-components";
import { useDispatch } from "react-redux";
import { HomeResInfo } from "../../util/homeResUtils";
import { HomeResTypeEnum } from "../../types/homeRes";
import { deleteApplication, restoreApplication } from "../../redux/reduxActions/applicationActions";
import { HomeRes } from "./HomeLayout";
import { trans, transToNode } from "../../i18n";
import { messageInstance } from "lowcoder-design/src/components/GlobalInstances";
import { BrandedIcon } from "@lowcoder-ee/components/BrandedIcon";
import ApplicationApi from "../../api/applicationApi";

const OperationWrapper = styled.div`
display: flex;
Expand DownExpand Up@@ -123,17 +123,18 @@ export const TrashTableView = (props: { resources: HomeRes[] , setModify: any, m
style={{ padding: "0 8px", width: "fit-content", minWidth: "52px" }}
buttonType={"blue"}
className={"home-datasource-edit-button"}
onClick={() =>{
dispatch(
restoreApplication({ applicationId: item.id }, () => {
messageInstance.success(trans("home.recoverSuccessMsg"));
})
)
onClick={async () => {
try {
await ApplicationApi.restoreApplication({ applicationId: item.id });
messageInstance.success(trans("home.recoverSuccessMsg"));
setTimeout(() => {
setModify(!modify);
setModify(!modify);
}, 200);
}
}
} catch (error) {
console.error("Failed to restore application:", error);
messageInstance.error("Failed to restore application");
}
}}
>
{trans("recover")}
</EditBtn>
Expand All@@ -148,27 +149,21 @@ export const TrashTableView = (props: { resources: HomeRes[] , setModify: any, m
type: HomeResInfo[item.type].name.toLowerCase(),
name: <b>{item.name}</b>,
}),
onConfirm: () =>{
new Promise((resolve, reject) => {
dispatch(
deleteApplication(
{ applicationId: item.id },
() => {
messageInstance.success(trans("home.deleteSuccessMsg"));
resolve(true);
},
() => reject()
)
);
})
onConfirm: async () => {
try {
await ApplicationApi.deleteApplication({ applicationId: item.id });
messageInstance.success(trans("home.deleteSuccessMsg"));
setTimeout(() => {
setModify(!modify);
setModify(!modify);
}, 200);
} catch (error) {
console.error("Failed to delete application:", error);
messageInstance.error("Failed to delete application permanently");
}
},
confirmBtnType: "delete",
okText: trans("delete"),
})

}
style={{ marginLeft: "12px", width: "76px" }}
>
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -124,15 +124,6 @@ export default function ApplicationHome() {
setIsPreloadCompleted(true);
}, [org, orgHomeId]);

useEffect(() => {
// Check if we need to fetch data (either no folders or no applications)
if (allFoldersCount !== 0 && allAppCount !== 0) {
return;
}

user.currentOrgId && dispatch(fetchFolderElements({}));
}, [dispatch, allFoldersCount, allAppCount, user.currentOrgId]);

if (fetchingUser || !isPreloadCompleted) {
return <ProductLoading />;
}
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
import styled from "styled-components";
import history from "../../util/history";
import { default as Button } from "antd/es/button";
import { useCallback, useMemo, useState } from "react";
import { Spin } from "antd";
import { useCallback, useEffect, useMemo, useState } from "react";
import { CopyTextButton, DocIcon, PackUpIcon, TacoButton } from "lowcoder-design";
import { useDatasourceForm } from "./form/useDatasourceForm";
import { useParams } from "react-router-dom";
import { DATASOURCE_URL } from "../../constants/routesURL";
import { useSelector } from "react-redux";
import {getDataSource,getDataSourceTypes } from "../../redux/selectors/datasourceSelectors";
import { getDataSourceTypes } from "../../redux/selectors/datasourceSelectors";
import { trans } from "i18n";
import { DatasourceType } from "@lowcoder-ee/constants/queryConstants";
import { getDatasourceTutorial } from "@lowcoder-ee/util/tutorialUtils";
import { getDataSourceFormManifest } from "./getDataSourceFormManifest";
import DataSourceIcon from "components/DataSourceIcon";
import { Helmet } from "react-helmet";

import { DatasourceApi } from "@lowcoder-ee/api/datasourceApi";
import { DatasourceInfo } from "@lowcoder-ee/api/datasourceApi";
import { GenericApiResponse } from "../../api/apiResponses";
import { Datasource } from "@lowcoder-ee/constants/datasourceConstants";
import { AxiosResponse } from "axios";
const Wrapper = styled.div`
display: flex;
justify-content: center;
Expand DownExpand Up@@ -154,16 +159,44 @@ type DatasourcePathParams = {

export const DatasourceEditPage = () => {
const { datasourceId, datasourceType } = useParams<DatasourcePathParams>();
const datasourceList = useSelector(getDataSource);
const datasourceTypes = useSelector(getDataSourceTypes);
const [isReady, setIsReady] = useState(true);

const datasourceInfo = useMemo(() => {

const [datasourceInfo, setDatasourceInfo] = useState<DatasourceInfo | undefined>();
const [loading, setLoading] = useState(false);

// Fetch individual datasource when editing
useEffect(() => {
if (!datasourceId) {
return undefined;
setDatasourceInfo(undefined);
return;
}
return datasourceList.find((info) => info.datasource.id === datasourceId);
}, [datasourceId, datasourceList]);

const fetchDatasource = async () => {
setLoading(true);
try {
const response: AxiosResponse<GenericApiResponse<Datasource>> = await DatasourceApi.getDatasourceById(datasourceId);
if (response.data.success) {
// Transform to DatasourceInfo format
setDatasourceInfo({
datasource: response.data.data,
edit: true, // Assume editable since user reached edit page
});
} else {
console.error('API returned error:', response.data);
setDatasourceInfo(undefined);
}
} catch (error: any) {
console.error('Failed to fetch datasource:', error);
setDatasourceInfo(undefined);
} finally {
setLoading(false);
}
};

fetchDatasource();
}, [datasourceId]);

const dataSourceTypeInfo = useMemo(() => {
if (datasourceId) {
Expand All@@ -181,6 +214,26 @@ export const DatasourceEditPage = () => {
setIsReady(isReady);
}, []);

// Show loading state while fetching datasource
if (loading) {
return (
<Wrapper>
<ContentWrapper>
<div style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '400px',
flexDirection: 'column',
gap: '16px'
}}>
<Spin size="large" />
</div>
</ContentWrapper>
</Wrapper>
);
}

if (!finalDataSourceType) {
return null;
}
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
import styled from "styled-components";
import { EditPopover, PointIcon, Search, TacoButton } from "lowcoder-design";
importReact,{useEffect, useState} from "react";
import {useEffect, useState} from "react";
import { useDispatch, useSelector } from "react-redux";
import {getDataSource, getDataSourceLoading,getDataSourceTypesMap } from "../../redux/selectors/datasourceSelectors";
import { getDataSourceTypesMap } from "../../redux/selectors/datasourceSelectors";
import { deleteDatasource } from "../../redux/reduxActions/datasourceActions";
import { isEmpty } from "lodash";
import history from "../../util/history";
Expand DownExpand Up@@ -113,7 +113,6 @@ export const DatasourceList = () => {
const [modify, setModify] = useState(false);
const currentUser = useSelector(getUser);
const orgId = currentUser.currentOrgId;
const datasourceLoading = useSelector(getDataSourceLoading);
const plugins = useSelector(getDataSourceTypesMap);
interface ElementsState {
elements: DatasourceInfo[];
Expand All@@ -123,6 +122,7 @@ export const DatasourceList = () => {
const [elements, setElements] = useState<ElementsState>({ elements: [], total: 0 });
const [currentPage, setCurrentPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const [paginationLoading, setPaginationLoading] = useState(false);

useEffect(()=> {
const timer = setTimeout(() => {
Expand All@@ -133,6 +133,7 @@ export const DatasourceList = () => {
}, [searchValue])

useEffect( () => {
setPaginationLoading(true);
fetchDatasourcePagination(
{
orgId: orgId,
Expand All@@ -146,6 +147,8 @@ export const DatasourceList = () => {
}
else
console.error("ERROR: fetchFolderElements", result.error)
}).finally(() => {
setPaginationLoading(false);
})
}, [currentPage, pageSize, searchValues, modify]
)
Expand DownExpand Up@@ -195,7 +198,7 @@ export const DatasourceList = () => {
<BodyWrapper>
<StyledTable
loading={{
spinning:datasourceLoading,
spinning:paginationLoading,
indicator: <LoadingOutlined spin style={{ fontSize: 30 }} />
}}
rowClassName={(record: any) => (!record.edit ? "datasource-can-not-edit" : "")}
Expand Down
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp