Skip to content

Commit 06b3822

Browse files
committed
add managed/unmaged for apps
1 parent 82ce3c3 commit 06b3822

File tree

6 files changed

+100
-10
lines changed

6 files changed

+100
-10
lines changed

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

+39-6
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import {
1313
Button,
1414
Statistic,
1515
Divider,
16-
Breadcrumb
16+
Breadcrumb,
17+
message
1718
} from "antd";
1819
import {
1920
AppstoreOutlined,
@@ -29,12 +30,16 @@ import { useEnvironmentContext } from "./context/EnvironmentContext";
2930
import { useWorkspace } from "./hooks/useWorkspace";
3031
import { useWorkspaceApps } from "./hooks/useWorkspaceApps";
3132
import { useWorkspaceDataSources } from "./hooks/useWorkspaceDataSources";
32-
33+
import { useManagedApps } from "./hooks/enterprise/useManagedApps";
34+
import { App } from "./types/app.types";
35+
import { getMergedApps } from "./utils/getMergedApps";
36+
import { connectManagedApp, unconnectManagedApp } from "./services/enterprise.service";
3337

3438
const { Title, Text } = Typography;
3539
const { TabPane } = Tabs;
3640

3741

42+
3843
const WorkspaceDetail: React.FC = () => {
3944

4045
// Get parameters from URL
@@ -72,8 +77,35 @@ const WorkspaceDetail: React.FC = () => {
7277
dataSourceStats,
7378
} = useWorkspaceDataSources(environment, workspaceId);
7479

75-
76-
80+
const { managedApps } = useManagedApps(environmentId);
81+
const [mergedApps, setMergedApps] = useState<App[]>([]);
82+
83+
useEffect(() => {
84+
setMergedApps(getMergedApps(apps, managedApps));
85+
}, [apps, managedApps]);
86+
87+
88+
89+
90+
const handleToggleManagedApp = async (app: App, checked: boolean) => {
91+
try {
92+
if (checked) {
93+
await connectManagedApp(environmentId, app.name, app.applicationGid!);
94+
} else {
95+
await unconnectManagedApp(app.applicationGid!);
96+
}
97+
98+
setMergedApps((currentApps) =>
99+
currentApps.map((a) =>
100+
a.applicationId === app.applicationId ? { ...a, managed: checked } : a
101+
)
102+
);
103+
104+
message.success(`${app.name} is now ${checked ? "Managed" : "Unmanaged"}`);
105+
} catch {
106+
message.error(`Failed to toggle ${app.name}`);
107+
}
108+
};
77109
if (envLoading || workspaceLoading) {
78110
return (
79111
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%', padding: '50px' }}>
@@ -187,10 +219,11 @@ const WorkspaceDetail: React.FC = () => {
187219
)}
188220

189221
{/* Apps List */}
190-
<AppsList
191-
apps={apps}
222+
<AppsList
223+
apps={mergedApps}
192224
loading={appsLoading}
193225
error={appsError}
226+
onToggleManaged={handleToggleManagedApp}
194227
/>
195228
</Card>
196229
</TabPane>

client/packages/lowcoder/src/pages/setting/environments/components/AppsList.tsx

+25-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { Table, Tag, Empty, Spin, Avatar, Tooltip } from 'antd';
2+
import { Table, Tag, Empty, Spin, Avatar, Tooltip, Switch, Space } from 'antd';
33
import {
44
AppstoreOutlined,
55
UserOutlined,
@@ -12,6 +12,8 @@ interface AppsListProps {
1212
apps: App[];
1313
loading: boolean;
1414
error?: string | null;
15+
onToggleManaged?: (app: App, checked: boolean) => void;
16+
1517
}
1618

1719
/**
@@ -21,6 +23,8 @@ const AppsList: React.FC<AppsListProps> = ({
2123
apps,
2224
loading,
2325
error,
26+
onToggleManaged
27+
2428
}) => {
2529
// Format timestamp to date string
2630
const formatDate = (timestamp?: number): string => {
@@ -89,7 +93,26 @@ const AppsList: React.FC<AppsListProps> = ({
8993
{status}
9094
</Tag>
9195
),
92-
}
96+
},
97+
{
98+
title: 'Managed',
99+
key: 'managed',
100+
render: (record: App) => (
101+
<Space>
102+
<Tag color={record.managed ? 'green' : 'default'}>
103+
{record.managed ? 'Managed' : 'Unmanaged'}
104+
</Tag>
105+
<Switch
106+
size="small"
107+
checked={record.managed}
108+
onClick={(checked, e) => {
109+
e.stopPropagation(); // Prevent navigation
110+
onToggleManaged?.(record, checked);
111+
}}
112+
/>
113+
</Space>
114+
),
115+
},
93116
];
94117

95118
// If loading, show spinner
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { useState, useEffect } from 'react';
2+
import { getManagedApps } from '../../services/enterprise.service';
3+
4+
export const useManagedApps = (environmentId: string) => {
5+
const [managedApps, setManagedApps] = useState<any[]>([]);
6+
const [loading, setLoading] = useState(false);
7+
const [error, setError] = useState<string | null>(null);
8+
9+
useEffect(() => {
10+
const fetchManagedApps = async () => {
11+
setLoading(true);
12+
try {
13+
const apps = await getManagedApps(environmentId);
14+
setManagedApps(apps);
15+
} catch (err: any) {
16+
setError(err.message || 'Failed to fetch managed apps');
17+
} finally {
18+
setLoading(false);
19+
}
20+
};
21+
22+
fetchManagedApps();
23+
}, [environmentId]);
24+
25+
return { managedApps, loading, error };
26+
};

client/packages/lowcoder/src/pages/setting/environments/services/enterprise.service.ts

-2
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,13 @@ export async function getManagedApps(environmentId: string) {
106106
export async function connectManagedApp(
107107
environmentId: string,
108108
app_name: string,
109-
app_version: string,
110109
app_gid: string,
111110
app_tags: string[] = []
112111
) {
113112
try {
114113
const payload = {
115114
environment_id: environmentId,
116115
app_name,
117-
app_version,
118116
app_gid,
119117
app_tags,
120118
};

client/packages/lowcoder/src/pages/setting/environments/types/app.types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ export interface App {
2222
icon: string;
2323
published: boolean;
2424
folder: boolean;
25+
managed?: boolean;
2526
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { App } from '../types/app.types';
2+
3+
4+
export const getMergedApps = (standardApps: App[], managedApps: any[]): App[] => {
5+
return standardApps.map((app) => ({
6+
...app,
7+
managed: managedApps.some((managedApp) => managedApp.appGid === app.applicationGid),
8+
}));
9+
};

0 commit comments

Comments
 (0)