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

Commit465dcef

Browse files
authored
Merge pull request#1716 from iamfaran/environments-selector
Add Environments in the Redux State
2 parents0650f85 +5df453d commit465dcef

File tree

10 files changed

+133
-49
lines changed

10 files changed

+133
-49
lines changed

‎client/packages/lowcoder/src/constants/reduxActionConstants.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ export const ReduxActionTypes = {
172172
/* Enterprise Edition */
173173
FETCH_ENTERPRISE_LICENSE :"FETCH_ENTERPRISE_LICENSE",
174174
SET_ENTERPRISE_LICENSE :"SET_ENTERPRISE_LICENSE",
175+
176+
/* Environments */
177+
FETCH_ENVIRONMENTS :"FETCH_ENVIRONMENTS",
178+
FETCH_ENVIRONMENTS_SUCCESS:"FETCH_ENVIRONMENTS_SUCCESS",
179+
FETCH_ENVIRONMENTS_FAILURE:"FETCH_ENVIRONMENTS_FAILURE",
175180

176181
/* Branding Setting */
177182
FETCH_BRANDING_SETTING :"FETCH_BRANDING_SETTING",

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

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,28 @@
11
// client/packages/lowcoder/src/pages/setting/environments/Environments.tsx
22
importReactfrom"react";
33
import{Switch,Route,useRouteMatch}from"react-router-dom";
4-
import{EnvironmentProvider}from"./context/EnvironmentContext";
54
importEnvironmentRoutesfrom"./routes/EnvironmentRoutes";
65
importEnvironmentsListfrom"./EnvironmentsList";
76

87
/**
98
* Top-level Environments component
10-
*Providesthe EnvironmentProviderat the top level
9+
*No longer needsthe EnvironmentProvidersince we use Redux
1110
*/
1211
constEnvironmentsSettings:React.FC=()=>{
1312
const{ path}=useRouteMatch();
1413

1514
return(
16-
<EnvironmentProvider>
17-
<Switch>
18-
{/* Environment list route */}
19-
<Routeexactpath={path}>
20-
<EnvironmentsList/>
21-
</Route>
22-
23-
{/* All routes that need a specific environment */}
24-
<Routepath={`${path}/:envId`}>
25-
<EnvironmentRoutes/>
26-
</Route>
27-
</Switch>
28-
</EnvironmentProvider>
15+
<Switch>
16+
{/* Environment list route */}
17+
<Routeexactpath={path}>
18+
<EnvironmentsList/>
19+
</Route>
20+
21+
{/* All routes that need a specific environment */}
22+
<Routepath={`${path}/:envId`}>
23+
<EnvironmentRoutes/>
24+
</Route>
25+
</Switch>
2926
);
3027
};
3128

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

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
importReact,{useState}from"react";
1+
importReact,{useState,useEffect,useRef}from"react";
22
import{Typography,Alert,Input,Button,Space,Empty,Card,Spin,Row,Col,Tooltip,Badge}from"antd";
33
import{SearchOutlined,CloudServerOutlined,SyncOutlined,PlusOutlined}from"@ant-design/icons";
44
import{useHistory}from"react-router-dom";
5-
import{useEnvironmentContext}from"./context/EnvironmentContext";
5+
import{useSelector,useDispatch}from"react-redux";
6+
import{selectEnvironments,selectEnvironmentsLoading,selectEnvironmentsError}from"redux/selectors/enterpriseSelectors";
7+
import{fetchEnvironments}from"redux/reduxActions/enterpriseActions";
68
import{Environment}from"./types/environment.types";
79
importEnvironmentsTablefrom"./components/EnvironmentsTable";
810
importCreateEnvironmentModalfrom"./components/CreateEnvironmentModal";
@@ -17,23 +19,23 @@ const { Title, Text } = Typography;
1719
* Displays a table of environments
1820
*/
1921
constEnvironmentsList:React.FC=()=>{
20-
// Use the shared context instead of a local hook
21-
const{
22-
environments,
23-
isLoading,
24-
error,
25-
refreshEnvironments
26-
}=useEnvironmentContext();
22+
// Use Redux state instead of context
23+
constdispatch=useDispatch();
24+
constenvironments=useSelector(selectEnvironments);
25+
constisLoading=useSelector(selectEnvironmentsLoading);
26+
consterror=useSelector(selectEnvironmentsError);
2727

2828
// State for search input
2929
const[searchText,setSearchText]=useState("");
30-
const[isRefreshing,setIsRefreshing]=useState(false);
3130
const[isCreateModalVisible,setIsCreateModalVisible]=useState(false);
3231
const[isCreating,setIsCreating]=useState(false);
32+
33+
3334

3435
// Hook for navigation
3536
consthistory=useHistory();
3637

38+
3739
// Filter environments based on search text
3840
constfilteredEnvironments=environments.filter((env)=>{
3941
constsearchLower=searchText.toLowerCase();
@@ -62,18 +64,16 @@ const EnvironmentsList: React.FC = () => {
6264
};
6365

6466
// Handle refresh
65-
consthandleRefresh=async()=>{
66-
setIsRefreshing(true);
67-
awaitrefreshEnvironments();
68-
setIsRefreshing(false);
67+
consthandleRefresh=()=>{
68+
dispatch(fetchEnvironments());
6969
};
7070

7171
// Handle create environment
7272
consthandleCreateEnvironment=async(environmentData:Partial<Environment>)=>{
7373
setIsCreating(true);
7474
try{
7575
awaitcreateEnvironment(environmentData);
76-
awaitrefreshEnvironments();// Refresh the list after creation
76+
dispatch(fetchEnvironments());// Refresh the list after creation
7777
}catch(error){
7878
console.error("Failed to create environment:",error);
7979
throwerror;// Re-throw to let the modal handle the error display
@@ -153,7 +153,7 @@ const EnvironmentsList: React.FC = () => {
153153
Create Environment
154154
</Button>
155155
<Button
156-
icon={<SyncOutlinedspin={isRefreshing}/>}
156+
icon={<SyncOutlinedspin={isLoading}/>}
157157
onClick={handleRefresh}
158158
loading={isLoading}
159159
type="default"

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
importReact,{useState,useEffect}from'react';
33
import{Modal,Form,Select,Checkbox,Button,Spin,Input,Tag,Space,Alert}from'antd';
44
import{messageInstance}from'lowcoder-design/src/components/GlobalInstances';
5+
import{useSelector}from'react-redux';
6+
import{selectLicensedEnvironments,selectEnvironmentsLoading}from'redux/selectors/enterpriseSelectors';
57
import{Environment}from'../types/environment.types';
68
import{DeployableItemConfig}from'../types/deployable-item.types';
7-
import{useEnvironmentContext}from'../context/EnvironmentContext';
89
import{getEnvironmentTagColor,formatEnvironmentType}from'../utils/environmentUtils';
910
import{ExclamationCircleOutlined}from'@ant-design/icons';
1011
import{showFirstCredentialOverwriteConfirm,showSecondCredentialOverwriteConfirm}from'./credentialConfirmations';
@@ -27,7 +28,8 @@ function DeployItemModal({
2728
onSuccess
2829
}:DeployItemModalProps){
2930
const[form]=Form.useForm();
30-
const{ environments, isLoading}=useEnvironmentContext();
31+
constlicensedEnvironments=useSelector(selectLicensedEnvironments);
32+
constisLoading=useSelector(selectEnvironmentsLoading);
3133
const[deploying,setDeploying]=useState(false);
3234
const[credentialConfirmationStep,setCredentialConfirmationStep]=useState(0);// 0: not started, 1: first confirmation, 2: confirmed
3335

@@ -39,8 +41,8 @@ function DeployItemModal({
3941
},[visible,form]);
4042

4143
// Filter out source environment from target list
42-
consttargetEnvironments=environments.filter(
43-
(env:Environment)=>env.environmentId!==sourceEnvironment.environmentId&&env.isLicensed!==false
44+
consttargetEnvironments=licensedEnvironments.filter(
45+
(env:Environment)=>env.environmentId!==sourceEnvironment.environmentId
4446
);
4547

4648
// Handle credential checkbox change with double confirmation
@@ -82,7 +84,7 @@ function DeployItemModal({
8284

8385
try{
8486
constvalues=awaitform.validateFields();
85-
consttargetEnv=environments.find(env=>env.environmentId===values.targetEnvId);
87+
consttargetEnv=licensedEnvironments.find(env=>env.environmentId===values.targetEnvId);
8688

8789
if(!targetEnv){
8890
messageInstance.error('Target environment not found');

‎client/packages/lowcoder/src/pages/setting/environments/context/SingleEnvironmentContext.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ import React, {
99
}from"react";
1010
import{messageInstance}from"lowcoder-design/src/components/GlobalInstances";
1111
import{useParams}from"react-router-dom";
12+
import{useDispatch}from"react-redux";
13+
import{fetchEnvironments}from"redux/reduxActions/enterpriseActions";
1214
import{getEnvironmentById,updateEnvironment}from"../services/environments.service";
1315
import{Environment}from"../types/environment.types";
14-
import{useEnvironmentContext}from'./EnvironmentContext';
15-
16+
1617
interfaceSingleEnvironmentContextState{
1718
// Environment data
1819
environment:Environment|null;
@@ -53,8 +54,8 @@ import React, {
5354
const{ envId}=useParams<{envId:string}>();
5455
constenvironmentId=propEnvironmentId||envId;
5556

56-
//Access the environments contextto refreshthe list
57-
const{ refreshEnvironments}=useEnvironmentContext();
57+
//Use Redux dispatchto refreshenvironments instead of context
58+
constdispatch=useDispatch();
5859

5960
// State for environment data
6061
const[environment,setEnvironment]=useState<Environment|null>(null);
@@ -103,18 +104,16 @@ import React, {
103104
messageInstance.success("Environment updated successfully");
104105

105106
// Refresh both the single environment and environments list
106-
awaitPromise.all([
107-
fetchEnvironment(),// Refresh the current environment
108-
refreshEnvironments()// Refresh the environments list
109-
]);
107+
awaitfetchEnvironment();// Refresh the current environment
108+
dispatch(fetchEnvironments());// Refresh the environments list using Redux
110109

111110
returnupdatedEnv;
112111
}catch(err){
113112
consterrorMessage=errinstanceofError ?err.message :"Failed to update environment";
114113
messageInstance.error(errorMessage);
115114
throwerr;
116115
}
117-
},[environment,environmentId,fetchEnvironment,refreshEnvironments]);
116+
},[environment,environmentId,fetchEnvironment,dispatch]);
118117

119118
// Load environment data when the component mounts or environmentId changes
120119
useEffect(()=>{

‎client/packages/lowcoder/src/redux/reducers/uiReducers/enterpriseReducer.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
import{BrandingConfig,BrandingSettingResponse,EnterpriseLicenseResponse}from"@lowcoder-ee/api/enterpriseApi";
22
import{createReducer}from"@lowcoder-ee/util/reducerUtils";
33
import{ReduxAction,ReduxActionTypes}from"constants/reduxActionConstants";
4-
4+
import{Environment}from"pages/setting/environments/types/environment.types";
55
exportinterfaceEnterpriseReduxState{
66
enterprise:EnterpriseLicenseResponse,
77
globalBranding?:BrandingConfig,
88
workspaceBranding?:BrandingConfig,
9+
environments:Environment[],
10+
environmentsLoading:boolean,
11+
environmentsError:string|null,
912
}
1013

1114
constinitialState:EnterpriseReduxState={
1215
enterprise:{
1316
eeActive:false,
1417
remainingAPICalls:0,
1518
eeLicenses:[],
16-
}
19+
},
20+
environments:[],
21+
environmentsLoading:false,
22+
environmentsError:null,
1723
};
1824

1925
constenterpriseReducer=createReducer(initialState,{
@@ -38,6 +44,29 @@ const enterpriseReducer = createReducer(initialState, {
3844
...state,
3945
workspaceBranding:action.payload,
4046
}),
47+
48+
[ReduxActionTypes.FETCH_ENVIRONMENTS]:(
49+
state:EnterpriseReduxState
50+
)=>({
51+
...state,
52+
environmentsLoading:true,
53+
}),
54+
[ReduxActionTypes.FETCH_ENVIRONMENTS_SUCCESS]:(
55+
state:EnterpriseReduxState,
56+
action:ReduxAction<Environment[]>
57+
)=>({
58+
...state,
59+
environments:action.payload,
60+
environmentsLoading:false,
61+
}),
62+
[ReduxActionTypes.FETCH_ENVIRONMENTS_FAILURE]:(
63+
state:EnterpriseReduxState,
64+
action:ReduxAction<string>
65+
)=>({
66+
...state,
67+
environmentsLoading:false,
68+
environmentsError:action.payload,
69+
}),
4170
});
4271

4372
exportdefaultenterpriseReducer;

‎client/packages/lowcoder/src/redux/reduxActions/enterpriseActions.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import{EnterpriseLicenseResponse,FetchBrandingSettingPayload}from"@lowcoder-ee/api/enterpriseApi";
22
import{ReduxActionTypes}from"constants/reduxActionConstants";
3+
import{Environment}from"pages/setting/environments/types/environment.types";
34

45
exportconstfetchEnterpriseLicense=()=>({
56
type:ReduxActionTypes.FETCH_ENTERPRISE_LICENSE,
@@ -16,3 +17,18 @@ export const fetchBrandingSetting = (payload: FetchBrandingSettingPayload) => {
1617
payload,
1718
};
1819
};
20+
21+
exportconstfetchEnvironments=()=>({
22+
type:ReduxActionTypes.FETCH_ENVIRONMENTS,
23+
});
24+
25+
exportconstfetchEnvironmentsSuccess=(environments:Environment[])=>({
26+
type:ReduxActionTypes.FETCH_ENVIRONMENTS_SUCCESS,
27+
payload:environments,
28+
});
29+
30+
exportconstfetchEnvironmentsFailure=(error:string)=>({
31+
type:ReduxActionTypes.FETCH_ENVIRONMENTS_FAILURE,
32+
payload:error,
33+
});
34+

‎client/packages/lowcoder/src/redux/sagas/enterpriseSagas.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import{call,put,takeLatest}from'redux-saga/effects';
22
import{ReduxAction,ReduxActionTypes}from"constants/reduxActionConstants";
3-
import{setEnterpriseLicense}from"redux/reduxActions/enterpriseActions";
3+
import{setEnterpriseLicense,fetchEnvironmentsSuccess,fetchEnvironmentsFailure}from"redux/reduxActions/enterpriseActions";
44
import{BrandingSettingResponse,EnterpriseLicenseResponse,FetchBrandingSettingPayload,getBranding,getEnterpriseLicense}from"api/enterpriseApi";
5+
import{getEnvironmentsWithLicenseStatus}from"pages/setting/environments/services/environments.service";
6+
import{Environment}from"pages/setting/environments/types/environment.types";
7+
58
import{AxiosResponse}from'axios';
69

710
function*fetchEnterpriseLicenseSaga():Generator<any,void,EnterpriseLicenseResponse>{
@@ -14,6 +17,16 @@ function* fetchEnterpriseLicenseSaga(): Generator<any, void, EnterpriseLicenseRe
1417
}
1518
}
1619

20+
function*fetchEnvironmentsSaga():Generator<any,void,Environment[]>{
21+
try{
22+
constenvironments:Environment[]=yieldcall(getEnvironmentsWithLicenseStatus);
23+
yieldput(fetchEnvironmentsSuccess(environments));
24+
}catch(error){
25+
console.error('Failed to fetch environments:',error);
26+
yieldput(fetchEnvironmentsFailure(errorasstring));
27+
}
28+
}
29+
1730
function*fetchBrandingSettingSaga(action:ReduxAction<FetchBrandingSettingPayload>){
1831
try{
1932
constresponse:BrandingSettingResponse=yieldgetBranding(action.payload.orgId);
@@ -45,4 +58,5 @@ function* fetchBrandingSettingSaga(action: ReduxAction<FetchBrandingSettingPaylo
4558
exportdefaultfunction*enterpriseSagas(){
4659
yieldtakeLatest(ReduxActionTypes.FETCH_ENTERPRISE_LICENSE,fetchEnterpriseLicenseSaga);
4760
yieldtakeLatest(ReduxActionTypes.FETCH_BRANDING_SETTING,fetchBrandingSettingSaga);
61+
yieldtakeLatest(ReduxActionTypes.FETCH_ENVIRONMENTS,fetchEnvironmentsSaga);
4862
}

‎client/packages/lowcoder/src/redux/selectors/enterpriseSelectors.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import{AppState}from"../reducers";
22

3+
34
exportconstselectEnterpriseEditionStatus=(state:AppState)=>
45
state.ui.enterprise?.enterprise?.eeActive??false;
56

@@ -25,3 +26,23 @@ export const getGlobalBrandingSetting = (state: AppState) => {
2526
exportconstgetWorkspaceBrandingSetting=(state:AppState)=>{
2627
returnstate.ui.enterprise?.workspaceBranding;
2728
}
29+
// Environment selectors
30+
exportconstselectEnvironments=(state:AppState)=>
31+
state.ui.enterprise?.environments??[];
32+
33+
exportconstselectEnvironmentsLoading=(state:AppState)=>
34+
state.ui.enterprise?.environmentsLoading??false;
35+
36+
exportconstselectEnvironmentsError=(state:AppState)=>
37+
state.ui.enterprise?.environmentsError??null;
38+
39+
exportconstselectUnlicensedEnvironments=(state:AppState)=>{
40+
constenvironments=state.ui.enterprise?.environments??[];
41+
returnenvironments.filter(env=>env.isLicensed===false);
42+
};
43+
44+
exportconstselectLicensedEnvironments=(state:AppState)=>{
45+
constenvironments=state.ui.enterprise?.environments??[];
46+
returnenvironments.filter(env=>env.isLicensed!==false);
47+
};
48+

‎client/packages/lowcoder/src/util/context/EnterpriseContext.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
importReact,{createContext,useContext,useState,useEffect}from'react';
2-
import{fetchEnterpriseLicense}from'redux/reduxActions/enterpriseActions';
2+
import{fetchEnterpriseLicense,fetchEnvironments}from'redux/reduxActions/enterpriseActions';
33
import{selectEnterpriseEditionStatus}from'@lowcoder-ee/redux/selectors/enterpriseSelectors';
44
import{useDispatch,useSelector}from'react-redux';
55
import{isEEEnvironment}from"util/envUtils";
@@ -23,6 +23,7 @@ export const EnterpriseProvider: React.FC<ProviderProps> = ({ children }) => {
2323
if(isEEEnvironment()){
2424
// Fetch the enterprise license only if we're in an EE environment
2525
dispatch(fetchEnterpriseLicense());
26+
dispatch(fetchEnvironments());
2627
}else{
2728
// Set the state to false for non-EE environments
2829
// setEEActiveState(false);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp