Skip to content

Commit ce9b5ba

Browse files
committed
Move Workspace/User-Group tabs to the seperate component
1 parent a758d7e commit ce9b5ba

File tree

3 files changed

+293
-199
lines changed

3 files changed

+293
-199
lines changed

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

Lines changed: 5 additions & 199 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import { useManagedWorkspaces } from "./hooks/enterprise/useManagedWorkspaces";
3232
import { getMergedWorkspaces } from "./utils/getMergedWorkspaces";
3333
import { Workspace } from "./types/workspace.types";
3434
import { connectManagedWorkspace, unconnectManagedWorkspace } from "./services/enterprise.service";
35+
import WorkspacesTab from "./components/WorkspacesTab";
36+
import UserGroupsTab from "./components/UserGroupsTab";
3537

3638

3739
const { Title, Text } = Typography;
@@ -253,105 +255,7 @@ const EnvironmentDetail: React.FC = () => {
253255
}
254256
key="workspaces"
255257
>
256-
<Card>
257-
{/* Header with refresh button */}
258-
<div
259-
style={{
260-
display: "flex",
261-
justifyContent: "space-between",
262-
alignItems: "center",
263-
marginBottom: "16px",
264-
}}
265-
>
266-
<Title level={5}>Workspaces in this Environment</Title>
267-
<Button
268-
icon={<SyncOutlined />}
269-
onClick={refreshWorkspaces}
270-
size="small"
271-
loading={workspacesLoading}
272-
>
273-
Refresh Workspaces
274-
</Button>
275-
</div>
276-
277-
{/* Workspace Statistics */}
278-
<Row gutter={16} style={{ marginBottom: "24px" }}>
279-
<Col span={8}>
280-
<Statistic
281-
title="Total Workspaces"
282-
value={workspaceStats.total}
283-
prefix={<ClusterOutlined />}
284-
/>
285-
</Col>
286-
<Col span={8}>
287-
<Statistic
288-
title="Managed Workspaces"
289-
value={workspaceStats.managed}
290-
prefix={<ClusterOutlined />}
291-
/>
292-
</Col>
293-
<Col span={8}>
294-
<Statistic
295-
title="Unmanaged Workspaces"
296-
value={workspaceStats.unmanaged}
297-
prefix={<ClusterOutlined />}
298-
/>
299-
</Col>
300-
</Row>
301-
302-
<Divider style={{ margin: "16px 0" }} />
303-
304-
{/* Show error if workspace loading failed */}
305-
{workspacesError && (
306-
<Alert
307-
message="Error loading workspaces"
308-
description={workspacesError}
309-
type="error"
310-
showIcon
311-
style={{ marginBottom: "16px" }}
312-
action={
313-
workspacesError.includes("No API key configured") ? (
314-
<Button size="small" type="primary" disabled>
315-
API Key Required
316-
</Button>
317-
) : (
318-
<Button
319-
size="small"
320-
type="primary"
321-
onClick={refreshWorkspaces}
322-
>
323-
Try Again
324-
</Button>
325-
)
326-
}
327-
/>
328-
)}
329-
330-
{(!environment.environmentApikey ||
331-
!environment.environmentApiServiceUrl) &&
332-
!workspacesError && (
333-
<Alert
334-
message="Configuration Issue"
335-
description={
336-
!environment.environmentApikey
337-
? "An API key is required to fetch workspaces for this environment."
338-
: "An API service URL is required to fetch workspaces for this environment."
339-
}
340-
type="warning"
341-
showIcon
342-
style={{ marginBottom: "16px" }}
343-
/>
344-
)}
345-
346-
{/* Workspaces List */}
347-
<WorkspacesList
348-
workspaces={mergedWorkspaces} // ⬅️ Use local state!
349-
loading={workspacesLoading && !workspacesError}
350-
error={workspacesError}
351-
environmentId={environment.environmentId}
352-
onToggleManaged={handleToggleManaged} // ⬅️ Add this to enable toggles
353-
/>
354-
</Card>
258+
<WorkspacesTab environment={environment} />
355259
</TabPane>
356260
<TabPane
357261
tab={
@@ -360,106 +264,8 @@ const EnvironmentDetail: React.FC = () => {
360264
</span>
361265
}
362266
key="userGroups"
363-
>
364-
<Card>
365-
{/* Header with refresh button */}
366-
<div
367-
style={{
368-
display: "flex",
369-
justifyContent: "space-between",
370-
alignItems: "center",
371-
marginBottom: "16px",
372-
}}
373-
>
374-
<Title level={5}>User Groups in this Environment</Title>
375-
<Button
376-
icon={<SyncOutlined />}
377-
onClick={refreshUserGroups}
378-
size="small"
379-
loading={userGroupsLoading}
380-
>
381-
Refresh User Groups
382-
</Button>
383-
</div>
384-
385-
{/* User Group Statistics */}
386-
<Row gutter={16} style={{ marginBottom: "24px" }}>
387-
<Col span={8}>
388-
<Statistic
389-
title="Total User Groups"
390-
value={userGroupStats.total}
391-
prefix={<TeamOutlined />}
392-
/>
393-
</Col>
394-
<Col span={8}>
395-
<Statistic
396-
title="Total Users"
397-
value={userGroupStats.totalUsers}
398-
prefix={<UserOutlined />}
399-
/>
400-
</Col>
401-
<Col span={8}>
402-
<Statistic
403-
title="Admin Users"
404-
value={userGroupStats.adminUsers}
405-
prefix={<UserOutlined />}
406-
/>
407-
</Col>
408-
</Row>
409-
410-
<Divider style={{ margin: "16px 0" }} />
411-
412-
{/* Show error if user group loading failed */}
413-
{userGroupsError && (
414-
<Alert
415-
message="Error loading user groups"
416-
description={userGroupsError}
417-
type="error"
418-
showIcon
419-
style={{ marginBottom: "16px" }}
420-
action={
421-
userGroupsError.includes("No API key configured") ||
422-
userGroupsError.includes("No API service URL configured") ? (
423-
<Button size="small" type="primary" disabled>
424-
Configuration Required
425-
</Button>
426-
) : (
427-
<Button
428-
size="small"
429-
type="primary"
430-
onClick={refreshUserGroups}
431-
>
432-
Try Again
433-
</Button>
434-
)
435-
}
436-
/>
437-
)}
438-
439-
{/* Show warning if no API key or API service URL is configured */}
440-
{(!environment.environmentApikey ||
441-
!environment.environmentApiServiceUrl) &&
442-
!userGroupsError && (
443-
<Alert
444-
message="Configuration Issue"
445-
description={
446-
!environment.environmentApikey
447-
? "An API key is required to fetch user groups for this environment."
448-
: "An API service URL is required to fetch user groups for this environment."
449-
}
450-
type="warning"
451-
showIcon
452-
style={{ marginBottom: "16px" }}
453-
/>
454-
)}
455-
456-
{/* User Groups List */}
457-
<UserGroupsList
458-
userGroups={userGroups}
459-
loading={userGroupsLoading && !userGroupsError}
460-
error={userGroupsError}
461-
/>
462-
</Card>
267+
>
268+
<UserGroupsTab environment={environment} />
463269
</TabPane>
464270
</Tabs>
465271
</div>
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// components/UserGroupsTab.tsx
2+
import React from 'react';
3+
import { Card, Button, Row, Col, Statistic, Divider, Alert } from 'antd';
4+
import { TeamOutlined, UserOutlined, SyncOutlined } from '@ant-design/icons';
5+
import Title from 'antd/lib/typography/Title';
6+
import { Environment } from '../types/environment.types';
7+
import { useEnvironmentUserGroups } from '../hooks/useEnvironmentUserGroups';
8+
import UserGroupsList from './UserGroupsList';
9+
10+
interface UserGroupsTabProps {
11+
environment: Environment;
12+
}
13+
14+
const UserGroupsTab: React.FC<UserGroupsTabProps> = ({ environment }) => {
15+
const {
16+
userGroups,
17+
loading: userGroupsLoading,
18+
error: userGroupsError,
19+
refresh: refreshUserGroups,
20+
userGroupStats,
21+
} = useEnvironmentUserGroups(environment);
22+
23+
return (
24+
<Card>
25+
{/* Header with refresh button */}
26+
<div
27+
style={{
28+
display: "flex",
29+
justifyContent: "space-between",
30+
alignItems: "center",
31+
marginBottom: "16px",
32+
}}
33+
>
34+
<Title level={5}>User Groups in this Environment</Title>
35+
<Button
36+
icon={<SyncOutlined />}
37+
onClick={refreshUserGroups}
38+
size="small"
39+
loading={userGroupsLoading}
40+
>
41+
Refresh User Groups
42+
</Button>
43+
</div>
44+
45+
{/* User Group Statistics */}
46+
<Row gutter={16} style={{ marginBottom: "24px" }}>
47+
<Col span={8}>
48+
<Statistic
49+
title="Total User Groups"
50+
value={userGroupStats.total}
51+
prefix={<TeamOutlined />}
52+
/>
53+
</Col>
54+
<Col span={8}>
55+
<Statistic
56+
title="Total Users"
57+
value={userGroupStats.totalUsers}
58+
prefix={<UserOutlined />}
59+
/>
60+
</Col>
61+
<Col span={8}>
62+
<Statistic
63+
title="Admin Users"
64+
value={userGroupStats.adminUsers}
65+
prefix={<UserOutlined />}
66+
/>
67+
</Col>
68+
</Row>
69+
70+
<Divider style={{ margin: "16px 0" }} />
71+
72+
{/* Show error if user group loading failed */}
73+
{userGroupsError && (
74+
<Alert
75+
message="Error loading user groups"
76+
description={userGroupsError}
77+
type="error"
78+
showIcon
79+
style={{ marginBottom: "16px" }}
80+
action={
81+
userGroupsError.includes("No API key configured") ||
82+
userGroupsError.includes("No API service URL configured") ? (
83+
<Button size="small" type="primary" disabled>
84+
Configuration Required
85+
</Button>
86+
) : (
87+
<Button
88+
size="small"
89+
type="primary"
90+
onClick={refreshUserGroups}
91+
>
92+
Try Again
93+
</Button>
94+
)
95+
}
96+
/>
97+
)}
98+
99+
{/* Show warning if no API key or API service URL is configured */}
100+
{(!environment.environmentApikey ||
101+
!environment.environmentApiServiceUrl) &&
102+
!userGroupsError && (
103+
<Alert
104+
message="Configuration Issue"
105+
description={
106+
!environment.environmentApikey
107+
? "An API key is required to fetch user groups for this environment."
108+
: "An API service URL is required to fetch user groups for this environment."
109+
}
110+
type="warning"
111+
showIcon
112+
style={{ marginBottom: "16px" }}
113+
/>
114+
)}
115+
116+
{/* User Groups List */}
117+
<UserGroupsList
118+
userGroups={userGroups}
119+
loading={userGroupsLoading && !userGroupsError}
120+
error={userGroupsError}
121+
/>
122+
</Card>
123+
);
124+
};
125+
126+
export default UserGroupsTab;

0 commit comments

Comments
 (0)