Skip to content

Commit 5fb6c52

Browse files
committed
fix edit DS page and add loading states
1 parent c9e00c5 commit 5fb6c52

File tree

4 files changed

+74
-14
lines changed

4 files changed

+74
-14
lines changed

client/packages/lowcoder/src/api/datasourceApi.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ export class DatasourceApi extends Api {
187187
return Api.get(DatasourceApi.url + `/listByOrg?orgId=${orgId}`, {...res});
188188
}
189189

190+
static getDatasourceById(id: string): AxiosPromise<GenericApiResponse<Datasource>> {
191+
return Api.get(`${DatasourceApi.url}/${id}`);
192+
}
193+
190194
static createDatasource(
191195
datasourceConfig: Partial<Datasource>
192196
): AxiosPromise<GenericApiResponse<Datasource>> {

client/packages/lowcoder/src/pages/datasource/datasourceEditPage.tsx

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
import styled from "styled-components";
22
import history from "../../util/history";
33
import { default as Button } from "antd/es/button";
4-
import { useCallback, useMemo, useState } from "react";
4+
import { Spin } from "antd";
5+
import { useCallback, useEffect, useMemo, useState } from "react";
56
import { CopyTextButton, DocIcon, PackUpIcon, TacoButton } from "lowcoder-design";
67
import { useDatasourceForm } from "./form/useDatasourceForm";
78
import { useParams } from "react-router-dom";
89
import { DATASOURCE_URL } from "../../constants/routesURL";
910
import { useSelector } from "react-redux";
10-
import { getDataSource, getDataSourceTypes } from "../../redux/selectors/datasourceSelectors";
11+
import { getDataSourceTypes } from "../../redux/selectors/datasourceSelectors";
1112
import { trans } from "i18n";
1213
import { DatasourceType } from "@lowcoder-ee/constants/queryConstants";
1314
import { getDatasourceTutorial } from "@lowcoder-ee/util/tutorialUtils";
1415
import { getDataSourceFormManifest } from "./getDataSourceFormManifest";
1516
import DataSourceIcon from "components/DataSourceIcon";
1617
import { Helmet } from "react-helmet";
17-
18+
import { DatasourceApi } from "@lowcoder-ee/api/datasourceApi";
19+
import { DatasourceInfo } from "@lowcoder-ee/api/datasourceApi";
20+
import { GenericApiResponse } from "../../api/apiResponses";
21+
import { Datasource } from "@lowcoder-ee/constants/datasourceConstants";
22+
import { AxiosResponse } from "axios";
1823
const Wrapper = styled.div`
1924
display: flex;
2025
justify-content: center;
@@ -154,16 +159,44 @@ type DatasourcePathParams = {
154159

155160
export const DatasourceEditPage = () => {
156161
const { datasourceId, datasourceType } = useParams<DatasourcePathParams>();
157-
const datasourceList = useSelector(getDataSource);
158162
const datasourceTypes = useSelector(getDataSourceTypes);
159163
const [isReady, setIsReady] = useState(true);
160164

161-
const datasourceInfo = useMemo(() => {
165+
166+
const [datasourceInfo, setDatasourceInfo] = useState<DatasourceInfo | undefined>();
167+
const [loading, setLoading] = useState(false);
168+
169+
// Fetch individual datasource when editing
170+
useEffect(() => {
162171
if (!datasourceId) {
163-
return undefined;
172+
setDatasourceInfo(undefined);
173+
return;
164174
}
165-
return datasourceList.find((info) => info.datasource.id === datasourceId);
166-
}, [datasourceId, datasourceList]);
175+
176+
const fetchDatasource = async () => {
177+
setLoading(true);
178+
try {
179+
const response: AxiosResponse<GenericApiResponse<Datasource>> = await DatasourceApi.getDatasourceById(datasourceId);
180+
if (response.data.success) {
181+
// Transform to DatasourceInfo format
182+
setDatasourceInfo({
183+
datasource: response.data.data,
184+
edit: true, // Assume editable since user reached edit page
185+
});
186+
} else {
187+
console.error('API returned error:', response.data);
188+
setDatasourceInfo(undefined);
189+
}
190+
} catch (error: any) {
191+
console.error('Failed to fetch datasource:', error);
192+
setDatasourceInfo(undefined);
193+
} finally {
194+
setLoading(false);
195+
}
196+
};
197+
198+
fetchDatasource();
199+
}, [datasourceId]);
167200

168201
const dataSourceTypeInfo = useMemo(() => {
169202
if (datasourceId) {
@@ -181,6 +214,26 @@ export const DatasourceEditPage = () => {
181214
setIsReady(isReady);
182215
}, []);
183216

217+
// Show loading state while fetching datasource
218+
if (loading) {
219+
return (
220+
<Wrapper>
221+
<ContentWrapper>
222+
<div style={{
223+
display: 'flex',
224+
justifyContent: 'center',
225+
alignItems: 'center',
226+
height: '400px',
227+
flexDirection: 'column',
228+
gap: '16px'
229+
}}>
230+
<Spin size="large" />
231+
</div>
232+
</ContentWrapper>
233+
</Wrapper>
234+
);
235+
}
236+
184237
if (!finalDataSourceType) {
185238
return null;
186239
}

client/packages/lowcoder/src/pages/datasource/datasourceList.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import styled from "styled-components";
22
import { EditPopover, PointIcon, Search, TacoButton } from "lowcoder-design";
3-
import React, {useEffect, useState} from "react";
3+
import {useEffect, useState} from "react";
44
import { useDispatch, useSelector } from "react-redux";
5-
import { getDataSource, getDataSourceLoading, getDataSourceTypesMap } from "../../redux/selectors/datasourceSelectors";
5+
import { getDataSourceTypesMap } from "../../redux/selectors/datasourceSelectors";
66
import { deleteDatasource } from "../../redux/reduxActions/datasourceActions";
77
import { isEmpty } from "lodash";
88
import history from "../../util/history";
@@ -113,7 +113,6 @@ export const DatasourceList = () => {
113113
const [modify, setModify] = useState(false);
114114
const currentUser = useSelector(getUser);
115115
const orgId = currentUser.currentOrgId;
116-
const datasourceLoading = useSelector(getDataSourceLoading);
117116
const plugins = useSelector(getDataSourceTypesMap);
118117
interface ElementsState {
119118
elements: DatasourceInfo[];
@@ -123,6 +122,7 @@ export const DatasourceList = () => {
123122
const [elements, setElements] = useState<ElementsState>({ elements: [], total: 0 });
124123
const [currentPage, setCurrentPage] = useState(1);
125124
const [pageSize, setPageSize] = useState(10);
125+
const [paginationLoading, setPaginationLoading] = useState(false);
126126

127127
useEffect(()=> {
128128
const timer = setTimeout(() => {
@@ -133,6 +133,7 @@ export const DatasourceList = () => {
133133
}, [searchValue])
134134

135135
useEffect( () => {
136+
setPaginationLoading(true);
136137
fetchDatasourcePagination(
137138
{
138139
orgId: orgId,
@@ -146,6 +147,8 @@ export const DatasourceList = () => {
146147
}
147148
else
148149
console.error("ERROR: fetchFolderElements", result.error)
150+
}).finally(() => {
151+
setPaginationLoading(false);
149152
})
150153
}, [currentPage, pageSize, searchValues, modify]
151154
)
@@ -195,7 +198,7 @@ export const DatasourceList = () => {
195198
<BodyWrapper>
196199
<StyledTable
197200
loading={{
198-
spinning: datasourceLoading,
201+
spinning: paginationLoading,
199202
indicator: <LoadingOutlined spin style={{ fontSize: 30 }} />
200203
}}
201204
rowClassName={(record: any) => (!record.edit ? "datasource-can-not-edit" : "")}

client/packages/lowcoder/src/pages/datasource/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import {
88
} from "../../constants/routesURL";
99
import React, { useEffect } from "react";
1010
import { isEmpty } from "lodash";
11-
import { fetchDatasource, fetchDataSourceTypes } from "../../redux/reduxActions/datasourceActions";
11+
import { fetchDataSourceTypes } from "../../redux/reduxActions/datasourceActions";
1212
import { useDispatch, useSelector } from "react-redux";
1313
import { getUser } from "../../redux/selectors/usersSelectors";
14-
import { getDataSource, getDataSourceTypes } from "../../redux/selectors/datasourceSelectors";
14+
import { getDataSourceTypes } from "../../redux/selectors/datasourceSelectors";
1515

1616
export const DatasourceHome = () => {
1717
const dispatch = useDispatch();

0 commit comments

Comments
 (0)