Skip to content

Commit 46911b0

Browse files
committed
Add Workspace and UserGroup hooks
1 parent d9f7dd5 commit 46911b0

File tree

3 files changed

+189
-18
lines changed

3 files changed

+189
-18
lines changed

client/packages/lowcoder/src/pages/setting/environments/EnvironmentDetail.tsx

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ import {
2525
import { useEnvironmentDetail } from "./hooks/useEnvironmentDetail";
2626
import WorkspacesList from "./components/WorkspacesList";
2727
import UserGroupsList from "./components/UserGroupsList";
28+
import { useEnvironmentContext } from "./context/EnvironmentContext";
29+
import { useEnvironmentWorkspaces } from "./hooks/useEnvironmentWorkspaces";
30+
import { useEnvironmentUserGroups } from "./hooks/useEnvironmentUserGroups";
2831

2932
const { Title, Text } = Typography;
3033
const { TabPane } = Tabs;
@@ -35,29 +38,35 @@ const { TabPane } = Tabs;
3538
*/
3639
const EnvironmentDetail: React.FC = () => {
3740
// Get environment ID from URL params
38-
const { environmentId: id } = useParams<{ environmentId: string }>();
39-
40-
// Use the custom hook to handle data fetching and state management
41-
// Use the custom hook to handle data fetching and state management
4241
const {
4342
environment,
44-
loading,
45-
error,
43+
loading: envLoading,
44+
error: envError,
4645
refresh,
46+
} = useEnvironmentContext();
47+
48+
49+
const {
4750
workspaces,
48-
workspacesLoading,
49-
workspacesError,
50-
refreshWorkspaces,
51+
loading: workspacesLoading,
52+
error: workspacesError,
53+
refresh: refreshWorkspaces,
5154
workspaceStats,
55+
} = useEnvironmentWorkspaces(environment);
56+
57+
const {
5258
userGroups,
53-
userGroupsLoading,
54-
userGroupsError,
55-
refreshUserGroups,
56-
userGroupStats
57-
58-
} = useEnvironmentDetail(id);
59+
loading: userGroupsLoading,
60+
error: userGroupsError,
61+
refresh: refreshUserGroups,
62+
userGroupStats,
63+
} = useEnvironmentUserGroups(environment);
64+
65+
// Use the custom hook to handle data fetching and state management
66+
// Use the custom hook to handle data fetching and state management
67+
5968
// If loading, show spinner
60-
if (loading) {
69+
if (envLoading) {
6170
return (
6271
<div
6372
style={{
@@ -74,11 +83,11 @@ const EnvironmentDetail: React.FC = () => {
7483
}
7584

7685
// If error, show error message
77-
if (error) {
86+
if (envError) {
7887
return (
7988
<Alert
8089
message="Error loading environment details"
81-
description={error}
90+
description={envError}
8291
type="error"
8392
showIcon
8493
style={{ margin: "24px" }}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { useState, useEffect, useCallback } from "react";
2+
import { getEnvironmentUserGroups } from "../services/environments.service";
3+
import { Environment } from "../types/environment.types";
4+
import { UserGroup } from "../types/userGroup.types";
5+
6+
interface UserGroupStats {
7+
total: number;
8+
totalUsers: number;
9+
adminUsers: number;
10+
apiKeyConfigured: boolean;
11+
apiServiceUrlConfigured: boolean;
12+
}
13+
14+
export const useEnvironmentUserGroups = (
15+
environment: Environment | null
16+
) => {
17+
const [userGroups, setUserGroups] = useState<UserGroup[]>([]);
18+
const [loading, setLoading] = useState(false);
19+
const [error, setError] = useState<string | null>(null);
20+
21+
const fetchUserGroups = useCallback(async () => {
22+
if (!environment) return;
23+
24+
setLoading(true);
25+
setError(null);
26+
27+
try {
28+
const { environmentId, environmentApikey, environmentApiServiceUrl } = environment;
29+
30+
if (!environmentApikey) {
31+
setError("No API key configured for this environment. User groups cannot be fetched.");
32+
setLoading(false);
33+
return;
34+
}
35+
36+
if (!environmentApiServiceUrl) {
37+
setError("No API service URL configured for this environment. User groups cannot be fetched.");
38+
setLoading(false);
39+
return;
40+
}
41+
42+
const data = await getEnvironmentUserGroups(
43+
environmentId,
44+
environmentApikey,
45+
environmentApiServiceUrl
46+
);
47+
48+
setUserGroups(data);
49+
} catch (err) {
50+
setError(
51+
err instanceof Error
52+
? err.message
53+
: "Failed to fetch user groups"
54+
);
55+
} finally {
56+
setLoading(false);
57+
}
58+
}, [environment]);
59+
60+
useEffect(() => {
61+
if (environment) {
62+
fetchUserGroups();
63+
}
64+
}, [environment, fetchUserGroups]);
65+
66+
const userGroupStats: UserGroupStats = {
67+
total: userGroups.length,
68+
totalUsers: userGroups.reduce((sum, group) => sum + (group.stats?.userCount ?? 0), 0),
69+
adminUsers: userGroups.reduce((sum, group) => sum + (group.stats?.adminUserCount ?? 0), 0),
70+
apiKeyConfigured: !!environment?.environmentApikey,
71+
apiServiceUrlConfigured: !!environment?.environmentApiServiceUrl,
72+
};
73+
74+
return {
75+
userGroups,
76+
loading,
77+
error,
78+
refresh: fetchUserGroups,
79+
userGroupStats,
80+
};
81+
};
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { useState, useEffect, useCallback } from "react";
2+
import { getEnvironmentWorkspaces } from "../services/environments.service";
3+
import { Environment } from "../types/environment.types";
4+
import { Workspace } from "../types/workspace.types";
5+
6+
interface WorkspaceStats {
7+
total: number;
8+
managed: number;
9+
unmanaged: number;
10+
apiKeyConfigured: boolean;
11+
apiServiceUrlConfigured: boolean;
12+
}
13+
14+
export const useEnvironmentWorkspaces = (
15+
environment: Environment | null
16+
) => {
17+
const [workspaces, setWorkspaces] = useState<Workspace[]>([]);
18+
const [loading, setLoading] = useState(false);
19+
const [error, setError] = useState<string | null>(null);
20+
21+
const fetchWorkspaces = useCallback(async () => {
22+
if (!environment) return;
23+
24+
setLoading(true);
25+
setError(null);
26+
27+
try {
28+
const { environmentId, environmentApikey, environmentApiServiceUrl } = environment;
29+
30+
if (!environmentApikey) {
31+
setError("No API key configured for this environment. Workspaces cannot be fetched.");
32+
setLoading(false);
33+
return;
34+
}
35+
36+
if (!environmentApiServiceUrl) {
37+
setError("No API service URL configured for this environment. Workspaces cannot be fetched.");
38+
setLoading(false);
39+
return;
40+
}
41+
42+
const data = await getEnvironmentWorkspaces(
43+
environmentId,
44+
environmentApikey,
45+
environmentApiServiceUrl
46+
);
47+
48+
setWorkspaces(data);
49+
} catch (err) {
50+
setError(
51+
err instanceof Error
52+
? err.message
53+
: "Failed to fetch workspaces"
54+
);
55+
} finally {
56+
setLoading(false);
57+
}
58+
}, [environment]);
59+
60+
useEffect(() => {
61+
if (environment) {
62+
fetchWorkspaces();
63+
}
64+
}, [environment, fetchWorkspaces]);
65+
66+
const workspaceStats: WorkspaceStats = {
67+
total: workspaces.length,
68+
managed: 0, // logic to be added later
69+
unmanaged: workspaces.length, // logic to be added later
70+
apiKeyConfigured: !!environment?.environmentApikey,
71+
apiServiceUrlConfigured: !!environment?.environmentApiServiceUrl,
72+
};
73+
74+
return {
75+
workspaces,
76+
loading,
77+
error,
78+
refresh: fetchWorkspaces,
79+
workspaceStats,
80+
};
81+
};

0 commit comments

Comments
 (0)