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

Commit19c99c7

Browse files
committed
add managed/unmanged workspaces
1 parentc96b993 commit19c99c7

File tree

3 files changed

+98
-33
lines changed

3 files changed

+98
-33
lines changed

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

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
importReactfrom"react";
1+
importReact,{useState}from"react";
22
import{useParams}from"react-router-dom";
33
import{
44
Spin,
@@ -13,6 +13,7 @@ import {
1313
Button,
1414
Statistic,
1515
Divider,
16+
message
1617
}from"antd";
1718
import{
1819
ReloadOutlined,
@@ -29,6 +30,8 @@ import { useEnvironmentWorkspaces } from "./hooks/useEnvironmentWorkspaces";
2930
import{useEnvironmentUserGroups}from"./hooks/useEnvironmentUserGroups";
3031
import{useManagedWorkspaces}from"./hooks/enterprise/useManagedWorkspaces";
3132
import{getMergedWorkspaces}from"./utils/getMergedWorkspaces";
33+
import{Workspace}from"./types/workspace.types";
34+
import{connectManagedWorkspace,unconnectManagedWorkspace}from"./services/enterprise.service";
3235

3336

3437
const{ Title, Text}=Typography;
@@ -38,6 +41,12 @@ const { TabPane } = Tabs;
3841
* Environment Detail Page Component
3942
* Shows detailed information about a specific environment
4043
*/
44+
45+
typeWorkspaceStats={
46+
total:number;
47+
managed:number;
48+
unmanaged:number;
49+
};
4150
constEnvironmentDetail:React.FC=()=>{
4251
// Get environment ID from URL params
4352
const{
@@ -72,6 +81,22 @@ const EnvironmentDetail: React.FC = () => {
7281

7382
// Use the custom hook to handle data fetching and state management
7483
// Use the custom hook to handle data fetching and state management
84+
85+
const[mergedWorkspaces,setMergedWorkspaces]=useState<Workspace[]>([]);
86+
const[workspaceStats,setWorkspaceStats]=useState<WorkspaceStats>({
87+
total:0,
88+
managed:0,
89+
unmanaged:0,
90+
});
91+
92+
93+
React.useEffect(()=>{
94+
if(workspaces&&managedWorkspaces){
95+
const{ merged, stats}=getMergedWorkspaces(workspaces,managedWorkspaces);
96+
setMergedWorkspaces(merged);
97+
setWorkspaceStats(stats);
98+
}
99+
},[workspaces,managedWorkspaces]);
75100

76101
// If loading, show spinner
77102
if(envLoading){
@@ -121,7 +146,39 @@ const EnvironmentDetail: React.FC = () => {
121146
);
122147
}
123148

124-
const{ merged,stats:workspaceStats}=getMergedWorkspaces(workspaces,managedWorkspaces);
149+
const{ merged,stats:initialStats}=getMergedWorkspaces(workspaces,managedWorkspaces);
150+
151+
152+
153+
consthandleToggleManaged=async(workspace:Workspace,checked:boolean)=>{
154+
try{
155+
console.log("WORKSPACE",workspace);
156+
if(checked){
157+
awaitconnectManagedWorkspace(environment.environmentId,workspace.name,workspace.gid!);
158+
}else{
159+
awaitunconnectManagedWorkspace(workspace.gid!);
160+
}
161+
162+
// Optimistically update the local state
163+
constupdatedList=mergedWorkspaces.map((w)=>
164+
w.id===workspace.id ?{ ...w,managed:checked} :w
165+
);
166+
167+
constupdatedManagedCount=updatedList.filter((w)=>w.managed).length;
168+
169+
setMergedWorkspaces(updatedList);
170+
setWorkspaceStats({
171+
total:updatedList.length,
172+
managed:updatedManagedCount,
173+
unmanaged:updatedList.length-updatedManagedCount,
174+
});
175+
176+
message.success(`${workspace.name} is now${checked ?'Managed' :'Unmanaged'}`);
177+
}catch(err){
178+
message.error(`Failed to toggle managed state for${workspace.name}`);
179+
}
180+
};
181+
125182

126183
return(
127184
<divclassName="environment-detail-container"style={{padding:"24px"}}>
@@ -297,10 +354,11 @@ const EnvironmentDetail: React.FC = () => {
297354

298355
{/* Workspaces List */}
299356
<WorkspacesList
300-
workspaces={merged}
357+
workspaces={mergedWorkspaces}// ⬅️ Use local state!
301358
loading={workspacesLoading&&!workspacesError}
302359
error={workspacesError}
303360
environmentId={environment.environmentId}
361+
onToggleManaged={handleToggleManaged}// ⬅️ Add this to enable toggles
304362
/>
305363
</Card>
306364
</TabPane>

‎client/packages/lowcoder/src/pages/setting/environments/components/WorkspacesList.tsx‎

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
importReactfrom'react';
2-
import{Table,Tag,Empty,Spin}from'antd';
2+
import{Table,Tag,Empty,Spin,Switch,Space}from'antd';
33
import{Workspace}from'../types/workspace.types';
44
importhistoryfrom'@lowcoder-ee/util/history';
55
import{buildEnvironmentWorkspaceId}from'@lowcoder-ee/constants/routesURL';
@@ -9,18 +9,18 @@ interface WorkspacesListProps {
99
loading:boolean;
1010
error?:string|null;
1111
environmentId:string;
12+
onToggleManaged?:(workspace:Workspace,checked:boolean)=>void;
13+
refreshing?:boolean;
1214
}
1315

14-
/**
15-
* Component to display a list of workspaces in a table
16-
*/
1716
constWorkspacesList:React.FC<WorkspacesListProps>=({
1817
workspaces,
1918
loading,
2019
error,
2120
environmentId,
21+
onToggleManaged,
22+
refreshing=false,
2223
})=>{
23-
// Format timestamp to date string
2424
constformatDate=(timestamp?:number):string=>{
2525
if(!timestamp)return'N/A';
2626
constdate=newDate(timestamp);
@@ -31,7 +31,6 @@ const WorkspacesList: React.FC<WorkspacesListProps> = ({
3131
history.push(`${buildEnvironmentWorkspaceId(environmentId,workspace.id)}`);
3232
};
3333

34-
// Table columns definition
3534
constcolumns=[
3635
{
3736
title:'Name',
@@ -48,9 +47,7 @@ const WorkspacesList: React.FC<WorkspacesListProps> = ({
4847
title:'Role',
4948
dataIndex:'role',
5049
key:'role',
51-
render:(role:string)=>(
52-
<span>{role}</span>
53-
),
50+
render:(role:string)=><span>{role}</span>,
5451
},
5552
{
5653
title:'Creation Date',
@@ -71,14 +68,27 @@ const WorkspacesList: React.FC<WorkspacesListProps> = ({
7168
title:'Managed',
7269
key:'managed',
7370
render:(record:Workspace)=>(
74-
<Tagcolor={record.managed ?'green' :'default'}>
75-
{record.managed ?'Managed' :'Unmanaged'}
76-
</Tag>
71+
<Space>
72+
<Tagcolor={record.managed ?'green' :'default'}>
73+
{record.managed ?'Managed' :'Unmanaged'}
74+
</Tag>
75+
{onToggleManaged&&(
76+
<Switch
77+
size="small"
78+
checked={record.managed}
79+
loading={refreshing}
80+
onClick={(checked,e)=>{
81+
e.stopPropagation();// ✅ THIS STOPS the row from being triggered
82+
onToggleManaged(record,checked);
83+
}}
84+
onChange={()=>{}}
85+
/>
86+
)}
87+
</Space>
7788
),
7889
},
7990
];
8091

81-
// If loading, show spinner
8292
if(loading){
8393
return(
8494
<divstyle={{display:'flex',justifyContent:'center',padding:'20px'}}>
@@ -87,7 +97,6 @@ const WorkspacesList: React.FC<WorkspacesListProps> = ({
8797
);
8898
}
8999

90-
// If no workspaces or error, show empty state
91100
if(!workspaces||workspaces.length===0||error){
92101
return(
93102
<Empty
@@ -106,7 +115,7 @@ const WorkspacesList: React.FC<WorkspacesListProps> = ({
106115
size="middle"
107116
onRow={(record)=>({
108117
onClick:()=>handleRowClick(record),
109-
style:{cursor:'pointer'},// Add pointer cursor to indicate clickable rows
118+
style:{cursor:'pointer'},
110119
})}
111120
/>
112121
);

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

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ export async function getManagedWorkspaces(
4141

4242
exportasyncfunctionconnectManagedWorkspace(
4343
environmentId:string,
44-
apiServiceUrl:string,
4544
orgName:string,
46-
orgTags:string[]=[]
45+
org_gid:string,// ✅ not optional
46+
orgTags:string[]=[],
4747
){
48-
if(!environmentId||!apiServiceUrl||!orgName){
48+
if(!environmentId||!orgName||!org_gid){
4949
thrownewError("Missing required params to connect org");
5050
}
5151

@@ -54,9 +54,10 @@ export async function connectManagedWorkspace(
5454
environment_id:environmentId,
5555
org_name:orgName,
5656
org_tags:orgTags,
57+
org_gid,
5758
};
5859

59-
constres=awaitaxios.post(`${apiServiceUrl}/api/plugins/enterprise/org`,payload);
60+
constres=awaitaxios.post(`/api/plugins/enterprise/org`,payload);
6061
returnres.data;
6162
}catch(err){
6263
consterrorMsg=errinstanceofError ?err.message :"Failed to connect org";
@@ -67,27 +68,24 @@ export async function connectManagedWorkspace(
6768

6869

6970

70-
71-
72-
7371
/**
7472
* Fetch workspaces for a specific environment
7573
*@param apiServiceUrl - API service URL for the environment
7674
*@param orgId - ID of the workspace
7775
*
7876
*/
79-
exportasyncfunctionunconnectManagedWorkspace(
80-
apiServiceUrl:string,
81-
orgId:string
82-
){
83-
if(!apiServiceUrl||!orgId){
84-
thrownewError("Missing apiServiceUrl or orgId");
77+
exportasyncfunctionunconnectManagedWorkspace(orgGid:string){
78+
if(!orgGid){
79+
thrownewError("Missing orgGid to unconnect workspace");
8580
}
8681

8782
try{
88-
awaitaxios.delete(`${apiServiceUrl}/api/plugins/enterprise/org/${orgId}`);
83+
awaitaxios.delete(`/api/plugins/enterprise/org`,{
84+
params:{ orgGid},// ✅ pass as query param
85+
});
8986
}catch(err){
90-
consterrorMsg=errinstanceofError ?err.message :"Failed to unconnect org";
87+
consterrorMsg=
88+
errinstanceofError ?err.message :"Failed to unconnect org";
9189
message.error(errorMsg);
9290
throwerr;
9391
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp