@openshift-assisted/ui-lib 2.9.10-cim → 2.9.11-cim
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/@types/cim/index.d.ts +1 -0
- package/build/@types/cim/index.d.ts.map +1 -1
- package/build/@types/common/api/utils.d.ts +1 -1
- package/build/@types/common/api/utils.d.ts.map +1 -1
- package/build/@types/common/index.d.ts +1 -0
- package/build/@types/common/index.d.ts.map +1 -1
- package/build/@types/common/types/index.d.ts +0 -8
- package/build/@types/common/types/index.d.ts.map +1 -1
- package/build/@types/common/types/resource-ui-state.d.ts +9 -0
- package/build/@types/common/types/resource-ui-state.d.ts.map +1 -0
- package/build/@types/ocm/components/Routes.d.ts.map +1 -1
- package/build/@types/ocm/components/hosts/DeleteHostModal.d.ts.map +1 -1
- package/build/@types/ocm/config/external-features.d.ts +8 -0
- package/build/@types/ocm/config/external-features.d.ts.map +1 -0
- package/build/@types/ocm/config/index.d.ts +1 -1
- package/build/@types/ocm/config/{routeBaseBath.d.ts → routeBasePath.d.ts} +1 -1
- package/build/@types/ocm/config/routeBasePath.d.ts.map +1 -0
- package/build/@types/ocm/hooks/use-feature-detection.d.ts +3 -0
- package/build/@types/ocm/hooks/use-feature-detection.d.ts.map +1 -0
- package/build/@types/ocm/services/ClustersService.d.ts +3 -3
- package/build/@types/ocm/services/ClustersService.d.ts.map +1 -1
- package/build/@types/ocm/services/InfraEnvIdsCacheService.d.ts +2 -2
- package/build/@types/ocm/services/InfraEnvIdsCacheService.d.ts.map +1 -1
- package/build/@types/ocm/store/hooks.d.ts +17 -5
- package/build/@types/ocm/store/hooks.d.ts.map +1 -1
- package/build/@types/ocm/store/index.d.ts +1 -3
- package/build/@types/ocm/store/index.d.ts.map +1 -1
- package/build/@types/ocm/store/slices/clusters/selectors.d.ts +6 -3
- package/build/@types/ocm/store/slices/clusters/selectors.d.ts.map +1 -1
- package/build/@types/ocm/store/slices/clusters/slice.d.ts +2 -2
- package/build/@types/ocm/store/slices/clusters/slice.d.ts.map +1 -1
- package/build/@types/ocm/store/slices/current-cluster/slice.d.ts +4 -3
- package/build/@types/ocm/store/slices/current-cluster/slice.d.ts.map +1 -1
- package/build/@types/ocm/store/slices/current-user/slice.d.ts +46 -0
- package/build/@types/ocm/store/slices/current-user/slice.d.ts.map +1 -0
- package/build/@types/ocm/store/slices/feature-flags/selectors.d.ts +18 -4
- package/build/@types/ocm/store/slices/feature-flags/selectors.d.ts.map +1 -1
- package/build/@types/ocm/store/slices/feature-flags/slice.d.ts +26 -5
- package/build/@types/ocm/store/slices/feature-flags/slice.d.ts.map +1 -1
- package/build/@types/ocm/store/slices/infra-envs/selectors.d.ts +2 -1
- package/build/@types/ocm/store/slices/infra-envs/selectors.d.ts.map +1 -1
- package/build/@types/ocm/store/store-day1.d.ts +4 -2
- package/build/@types/ocm/store/store-day1.d.ts.map +1 -1
- package/build/@types/ocm/store/types/state-slice.d.ts +16 -0
- package/build/@types/ocm/store/types/state-slice.d.ts.map +1 -0
- package/build/cjs/cim/index.js +3 -1
- package/build/cjs/cim/index.js.map +1 -1
- package/build/cjs/common/index.js +3 -0
- package/build/cjs/common/index.js.map +1 -1
- package/build/cjs/common/types/index.js +0 -10
- package/build/cjs/common/types/index.js.map +1 -1
- package/build/cjs/common/types/resource-ui-state.js +13 -0
- package/build/cjs/common/types/resource-ui-state.js.map +1 -0
- package/build/cjs/ocm/components/HostsClusterDetailTab/HostsClusterDetailTab.js +2 -2
- package/build/cjs/ocm/components/HostsClusterDetailTab/HostsClusterDetailTab.js.map +1 -1
- package/build/cjs/ocm/components/Routes.js +3 -5
- package/build/cjs/ocm/components/Routes.js.map +1 -1
- package/build/cjs/ocm/components/hosts/DeleteHostModal.js +8 -7
- package/build/cjs/ocm/components/hosts/DeleteHostModal.js.map +1 -1
- package/build/cjs/ocm/config/external-features.js +10 -0
- package/build/cjs/ocm/config/external-features.js.map +1 -0
- package/build/cjs/ocm/config/index.js +1 -1
- package/build/cjs/ocm/config/{routeBaseBath.js → routeBasePath.js} +1 -1
- package/build/cjs/ocm/config/routeBasePath.js.map +1 -0
- package/build/cjs/ocm/hooks/use-feature-detection.js +14 -0
- package/build/cjs/ocm/hooks/use-feature-detection.js.map +1 -0
- package/build/cjs/ocm/services/ClustersService.js +19 -19
- package/build/cjs/ocm/services/ClustersService.js.map +1 -1
- package/build/cjs/ocm/services/InfraEnvIdsCacheService.js +5 -5
- package/build/cjs/ocm/services/InfraEnvIdsCacheService.js.map +1 -1
- package/build/cjs/ocm/store/hooks.js +2 -4
- package/build/cjs/ocm/store/hooks.js.map +1 -1
- package/build/cjs/ocm/store/index.js +1 -5
- package/build/cjs/ocm/store/index.js.map +1 -1
- package/build/cjs/ocm/store/slices/clusters/slice.js +9 -8
- package/build/cjs/ocm/store/slices/clusters/slice.js.map +1 -1
- package/build/cjs/ocm/store/slices/current-cluster/slice.js +14 -13
- package/build/cjs/ocm/store/slices/current-cluster/slice.js.map +1 -1
- package/build/cjs/ocm/store/slices/current-user/slice.js +109 -0
- package/build/cjs/ocm/store/slices/current-user/slice.js.map +1 -0
- package/build/cjs/ocm/store/slices/feature-flags/selectors.js +1 -4
- package/build/cjs/ocm/store/slices/feature-flags/selectors.js.map +1 -1
- package/build/cjs/ocm/store/slices/feature-flags/slice.js +79 -6
- package/build/cjs/ocm/store/slices/feature-flags/slice.js.map +1 -1
- package/build/cjs/ocm/store/slices/infra-envs/thunks.js +1 -1
- package/build/cjs/ocm/store/slices/infra-envs/thunks.js.map +1 -1
- package/build/cjs/ocm/store/store-day1.js +2 -4
- package/build/cjs/ocm/store/store-day1.js.map +1 -1
- package/build/cjs/ocm/store/types/state-slice.js +3 -0
- package/build/cjs/ocm/store/types/state-slice.js.map +1 -0
- package/lib/@types/assets.d.ts +1 -1
- package/lib/@types/global.d.ts +1 -0
- package/lib/_test-helpers/mock-container.ts +42 -0
- package/lib/_test-helpers/mock-server.ts +26 -0
- package/lib/_test-helpers/vitest-setup.ts +17 -0
- package/lib/cim/index.ts +1 -0
- package/lib/common/api/utils.ts +1 -1
- package/lib/common/index.ts +1 -0
- package/lib/common/types/index.ts +0 -9
- package/lib/common/types/resource-ui-state.ts +8 -0
- package/lib/ocm/components/HostsClusterDetailTab/HostsClusterDetailTab.tsx +2 -2
- package/lib/ocm/components/Routes.tsx +3 -5
- package/lib/ocm/components/hosts/DeleteHostModal.tsx +28 -23
- package/lib/ocm/config/external-features.ts +12 -0
- package/lib/ocm/config/index.ts +1 -1
- package/lib/ocm/hooks/_use-feature-detection.test.tsx +125 -0
- package/lib/ocm/hooks/use-feature-detection.ts +17 -0
- package/lib/ocm/services/ClustersService.ts +9 -9
- package/lib/ocm/services/InfraEnvIdsCacheService.ts +2 -2
- package/lib/ocm/store/hooks.ts +1 -4
- package/lib/ocm/store/index.ts +1 -3
- package/lib/ocm/store/slices/clusters/slice.ts +5 -4
- package/lib/ocm/store/slices/current-cluster/slice.ts +9 -15
- package/lib/ocm/store/slices/current-user/slice.ts +129 -0
- package/lib/ocm/store/slices/feature-flags/selectors.ts +6 -7
- package/lib/ocm/store/slices/feature-flags/slice.ts +102 -7
- package/lib/ocm/store/slices/infra-envs/thunks.ts +1 -1
- package/lib/ocm/store/store-day1.ts +2 -4
- package/lib/ocm/store/types/state-slice.ts +16 -0
- package/package.json +12 -4
- package/build/@types/ocm/config/routeBaseBath.d.ts.map +0 -1
- package/build/@types/ocm/store/store-day2.d.ts +0 -10
- package/build/@types/ocm/store/store-day2.d.ts.map +0 -1
- package/build/cjs/ocm/config/routeBaseBath.js.map +0 -1
- package/build/cjs/ocm/store/store-day2.js +0 -20
- package/build/cjs/ocm/store/store-day2.js.map +0 -1
- package/lib/ocm/store/store-day2.ts +0 -19
- /package/lib/cim/components/ClusterDeployment/{wizardTransition.test.ts → _wizardTransition.test.ts} +0 -0
- /package/lib/common/components/ui/formik/{validationSchemas.test.ts → _validationSchemas.test.ts} +0 -0
- /package/lib/ocm/components/clusterWizard/{wizardTransition.test.ts → _wizardTransition.test.ts} +0 -0
- /package/lib/ocm/config/{routeBaseBath.ts → routeBasePath.ts} +0 -0
|
@@ -4,8 +4,5 @@ exports.isFeatureEnabled = exports.selectFeatureFlagsSlice = void 0;
|
|
|
4
4
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
5
5
|
const selectFeatureFlagsSlice = (state) => state.featureFlags;
|
|
6
6
|
exports.selectFeatureFlagsSlice = selectFeatureFlagsSlice;
|
|
7
|
-
exports.isFeatureEnabled = (0, toolkit_1.createSelector)(
|
|
8
|
-
// Configured via Unleash in the OCM
|
|
9
|
-
return !!featureFlags[feature];
|
|
10
|
-
});
|
|
7
|
+
exports.isFeatureEnabled = (0, toolkit_1.createSelector)(exports.selectFeatureFlagsSlice, (_featureFlags, featureId) => featureId, (featureFlags, featureId) => featureFlags.data[featureId]);
|
|
11
8
|
//# sourceMappingURL=selectors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.js","sourceRoot":"","sources":["../../../../../../lib/ocm/store/slices/feature-flags/selectors.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"selectors.js","sourceRoot":"","sources":["../../../../../../lib/ocm/store/slices/feature-flags/selectors.ts"],"names":[],"mappings":";;;AAEA,8CAAkD;AAE3C,MAAM,uBAAuB,GAAG,CAAC,KAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC;AAAvE,QAAA,uBAAuB,2BAAgD;AAEvE,QAAA,gBAAgB,GAAG,IAAA,wBAAc,EAC5C,+BAAuB,EACvB,CAAC,aAAyD,EAAE,SAAgC,EAAE,EAAE,CAC9F,SAAS,EACX,CAAC,YAAY,EAAE,SAAS,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAC1D,CAAC"}
|
|
@@ -1,16 +1,89 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.featureFlagsReducer = exports.featureFlagsActions = void 0;
|
|
3
|
+
exports.featureFlagsReducer = exports.featureFlagsActions = exports.featureFlagsAsyncActions = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
6
|
+
const featureGate_1 = require("../../../../common/features/featureGate");
|
|
7
|
+
const external_features_1 = require("../../../config/external-features");
|
|
8
|
+
const slice_1 = require("../current-user/slice");
|
|
9
|
+
const featureFlagsAsyncActions = {
|
|
10
|
+
detectFeaturesAsync: (0, toolkit_1.createAsyncThunk)('featureFlags/detectFeatures', (featuresOverride = null, thunkApi) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
11
|
+
var _a, _b, _c;
|
|
12
|
+
yield thunkApi.dispatch(slice_1.currentUserAsyncActions.getCapabilitiesAsync());
|
|
13
|
+
const state = thunkApi.getState();
|
|
14
|
+
for (const { featureId, capabilityId } of external_features_1.externalFeaturesMappings) {
|
|
15
|
+
const capability = (_c = (_b = (_a = state.currentUser.data) === null || _a === void 0 ? void 0 : _a.organization) === null || _b === void 0 ? void 0 : _b.capabilities) === null || _c === void 0 ? void 0 : _c.find((capability) => capability.name === capabilityId);
|
|
16
|
+
if (capability) {
|
|
17
|
+
thunkApi.dispatch(featureFlagsActions.setFeatureFlag({
|
|
18
|
+
featureId,
|
|
19
|
+
isEnabled: capability.value === 'true',
|
|
20
|
+
}));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (featuresOverride !== null) {
|
|
24
|
+
for (const [k, v] of Object.entries(featuresOverride)) {
|
|
25
|
+
thunkApi.dispatch(featureFlagsActions.setFeatureFlag({
|
|
26
|
+
featureId: k,
|
|
27
|
+
isEnabled: v,
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
})),
|
|
32
|
+
};
|
|
33
|
+
exports.featureFlagsAsyncActions = featureFlagsAsyncActions;
|
|
34
|
+
const initialState = {
|
|
35
|
+
data: featureGate_1.STANDALONE_DEPLOYMENT_ENABLED_FEATURES,
|
|
36
|
+
error: null,
|
|
37
|
+
meta: {
|
|
38
|
+
status: 'idle',
|
|
39
|
+
updatedAt: null,
|
|
40
|
+
currentRequestId: null,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
5
43
|
const featureFlagsSlice = (0, toolkit_1.createSlice)({
|
|
6
44
|
name: 'featureFlags',
|
|
7
|
-
initialState
|
|
45
|
+
initialState,
|
|
8
46
|
reducers: {
|
|
9
|
-
|
|
10
|
-
|
|
47
|
+
setMeta: (state, action) => {
|
|
48
|
+
state.meta.updatedAt = new Date().toUTCString();
|
|
49
|
+
state.meta.status = action.payload.meta.requestStatus;
|
|
50
|
+
state.meta.currentRequestId = action.payload.meta.requestId;
|
|
51
|
+
return state;
|
|
52
|
+
},
|
|
53
|
+
setFeatureFlag: (state, action) => {
|
|
54
|
+
const { featureId, isEnabled } = action.payload;
|
|
55
|
+
state.data[featureId] = isEnabled;
|
|
56
|
+
state.error = null;
|
|
57
|
+
state.meta.updatedAt = new Date().toUTCString();
|
|
58
|
+
return state;
|
|
11
59
|
},
|
|
12
60
|
},
|
|
61
|
+
extraReducers: (builder) => {
|
|
62
|
+
for (const { pending, fulfilled, rejected } of Object.values(featureFlagsAsyncActions)) {
|
|
63
|
+
builder.addCase(pending, (state, action) => {
|
|
64
|
+
if (/idle|fulfilled|rejected/.test(state.meta.status)) {
|
|
65
|
+
featureFlagsActions.setMeta(action);
|
|
66
|
+
}
|
|
67
|
+
return state;
|
|
68
|
+
});
|
|
69
|
+
builder.addCase(fulfilled, (state, action) => {
|
|
70
|
+
if (/idle|pending/.test(state.meta.status)) {
|
|
71
|
+
featureFlagsActions.setMeta(action);
|
|
72
|
+
}
|
|
73
|
+
return state;
|
|
74
|
+
});
|
|
75
|
+
builder.addCase(rejected, (state, action) => {
|
|
76
|
+
if (/idle|pending/.test(state.meta.status)) {
|
|
77
|
+
featureFlagsActions.setMeta(action);
|
|
78
|
+
state.error = action.error;
|
|
79
|
+
}
|
|
80
|
+
return state;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
},
|
|
13
84
|
});
|
|
14
|
-
|
|
15
|
-
exports.
|
|
85
|
+
const featureFlagsActions = featureFlagsSlice.actions;
|
|
86
|
+
exports.featureFlagsActions = featureFlagsActions;
|
|
87
|
+
const featureFlagsReducer = featureFlagsSlice.reducer;
|
|
88
|
+
exports.featureFlagsReducer = featureFlagsReducer;
|
|
16
89
|
//# sourceMappingURL=slice.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slice.js","sourceRoot":"","sources":["../../../../../../lib/ocm/store/slices/feature-flags/slice.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"slice.js","sourceRoot":"","sources":["../../../../../../lib/ocm/store/slices/feature-flags/slice.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ exports.listInfraEnvsByClusterId = (0, toolkit_1.createAsyncThunk)('infraEnvs/li
|
|
|
9
9
|
const { data: infraEnvs } = yield apis_1.InfraEnvsAPI.list(clusterId);
|
|
10
10
|
return infraEnvs;
|
|
11
11
|
}));
|
|
12
|
-
exports.createInfraEnv = (0, toolkit_1.createAsyncThunk)('', (params) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
12
|
+
exports.createInfraEnv = (0, toolkit_1.createAsyncThunk)('infraEnvs/createInfraEnv', (params) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
13
13
|
const { data: infraEnv } = yield apis_1.InfraEnvsAPI.register(params);
|
|
14
14
|
// dispatch({ type: 'currentCluster/updateStaticNetworkConfig' payload: infraEnv.staticNetworkConfig });
|
|
15
15
|
return infraEnv;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thunks.js","sourceRoot":"","sources":["../../../../../../lib/ocm/store/slices/infra-envs/thunks.ts"],"names":[],"mappings":";;;;AAAA,8CAAoD;AAEpD,iDAAsD;AAEtD,2CAA8D;AAQjD,QAAA,wBAAwB,GAAG,IAAA,0BAAgB,EACtD,2BAA2B,EAC3B,CAAO,SAAwB,EAAE,EAAE;IACjC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,MAAM,mBAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/D,OAAO,SAAS,CAAC;AACnB,CAAC,CAAA,CACF,CAAC;AAEW,QAAA,cAAc,GAAG,IAAA,0BAAgB,EAC5C,
|
|
1
|
+
{"version":3,"file":"thunks.js","sourceRoot":"","sources":["../../../../../../lib/ocm/store/slices/infra-envs/thunks.ts"],"names":[],"mappings":";;;;AAAA,8CAAoD;AAEpD,iDAAsD;AAEtD,2CAA8D;AAQjD,QAAA,wBAAwB,GAAG,IAAA,0BAAgB,EACtD,2BAA2B,EAC3B,CAAO,SAAwB,EAAE,EAAE;IACjC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,MAAM,mBAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/D,OAAO,SAAS,CAAC;AACnB,CAAC,CAAA,CACF,CAAC;AAEW,QAAA,cAAc,GAAG,IAAA,0BAAgB,EAC5C,0BAA0B,EAC1B,CAAO,MAAuD,EAAE,EAAE;IAChE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,mBAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/D,wGAAwG;IACxG,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAA,CACF,CAAC;AAEW,QAAA,kBAAkB,GAAG,IAAA,0BAAgB,EAAC,qBAAqB,EAAE,CAAO,CAAC,EAAE,QAAQ,EAAE,EAAE;IAC9F,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAmB,CAAC;IACnD,MAAM,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnE,MAAM,QAAQ,GAAG,EAAE,CAAC;IACpB,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE;QACpC,QAAQ,CAAC,IAAI,CAAC,mBAAY,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;KACpD;IACD,OAAO,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACrC,CAAC,CAAA,CAAC,CAAC;AAEU,QAAA,cAAc,GAAG,IAAA,0BAAgB,EAC5C,kBAAkB,EAClB,CAAO,EAAgF,EAAE,EAAE;QAApF,EAAE,UAAU,OAAoE,EAA/D,MAAM,sBAAvB,cAAyB,CAAF;IAC5B,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,mBAAY,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACzE,wGAAwG;IACxG,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAA,CACF,CAAC;AAEW,QAAA,WAAW,GAAG,IAAA,0BAAgB,EACzC,uBAAuB,EACvB,CAAO,eAAgC,EAAE,QAAQ,EAAE,EAAE;IACnD,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAmB,CAAC;IACnD,kFAAkF;IAClF,mFAAmF;IACnF,0BAA0B;IAC1B,MAAM,QAAQ,GAAG,IAAA,2CAA+B,EAAC,KAAK,EAAE,eAAe,CAAa,CAAC;IACrF,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,MAAM,mBAAY,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC3E,OAAO,YAAY,CAAC;AACtB,CAAC,CAAA,CACF,CAAC"}
|
|
@@ -6,7 +6,7 @@ const slice_1 = require("./slices/clusters/slice");
|
|
|
6
6
|
const slice_2 = require("./slices/current-cluster/slice");
|
|
7
7
|
const slice_3 = require("./slices/infra-envs/slice");
|
|
8
8
|
const slice_4 = require("./slices/feature-flags/slice");
|
|
9
|
-
const
|
|
9
|
+
const slice_5 = require("./slices/current-user/slice");
|
|
10
10
|
exports.storeDay1 = (0, toolkit_1.configureStore)({
|
|
11
11
|
devTools: {
|
|
12
12
|
name: 'Assisted Installer - Day 1',
|
|
@@ -16,9 +16,7 @@ exports.storeDay1 = (0, toolkit_1.configureStore)({
|
|
|
16
16
|
currentCluster: slice_2.currentClusterReducer,
|
|
17
17
|
infraEnvs: slice_3.infraEnvsReducer,
|
|
18
18
|
featureFlags: slice_4.featureFlagsReducer,
|
|
19
|
-
|
|
20
|
-
preloadedState: {
|
|
21
|
-
featureFlags: common_1.STANDALONE_DEPLOYMENT_ENABLED_FEATURES,
|
|
19
|
+
currentUser: slice_5.currentUserReducer,
|
|
22
20
|
},
|
|
23
21
|
});
|
|
24
22
|
//# sourceMappingURL=store-day1.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store-day1.js","sourceRoot":"","sources":["../../../../lib/ocm/store/store-day1.ts"],"names":[],"mappings":";;;AAAA,8CAAkD;AAClD,mDAA0D;AAC1D,0DAAuE;AACvE,qDAA6D;AAC7D,wDAAmE;AACnE,
|
|
1
|
+
{"version":3,"file":"store-day1.js","sourceRoot":"","sources":["../../../../lib/ocm/store/store-day1.ts"],"names":[],"mappings":";;;AAAA,8CAAkD;AAClD,mDAA0D;AAC1D,0DAAuE;AACvE,qDAA6D;AAC7D,wDAAmE;AACnE,uDAAiE;AAEpD,QAAA,SAAS,GAAG,IAAA,wBAAc,EAAC;IACtC,QAAQ,EAAE;QACR,IAAI,EAAE,4BAA4B;KACnC;IACD,OAAO,EAAE;QACP,QAAQ,EAAE,uBAAe;QACzB,cAAc,EAAE,6BAAqB;QACrC,SAAS,EAAE,wBAAgB;QAC3B,YAAY,EAAE,2BAAmB;QACjC,WAAW,EAAE,0BAAkB;KAChC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-slice.js","sourceRoot":"","sources":["../../../../../lib/ocm/store/types/state-slice.ts"],"names":[],"mappings":""}
|
package/lib/@types/assets.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@redhat-cloud-services/types';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { unmountComponentAtNode } from 'react-dom';
|
|
2
|
+
|
|
3
|
+
let element: HTMLDivElement | null = null;
|
|
4
|
+
|
|
5
|
+
function getMockContainer() {
|
|
6
|
+
return element;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Call this in your test if you intend to render a React component
|
|
11
|
+
* @example
|
|
12
|
+
* beforeEach(() => {
|
|
13
|
+
* initMockContainer();
|
|
14
|
+
* });
|
|
15
|
+
*/
|
|
16
|
+
function initMockContainer(
|
|
17
|
+
value: HTMLDivElement = document.createElement('div'),
|
|
18
|
+
baseElement: HTMLElement = document.body,
|
|
19
|
+
) {
|
|
20
|
+
element = value;
|
|
21
|
+
element.id = 'root';
|
|
22
|
+
baseElement.appendChild(element);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Attempts to unmount and remove the underlying DOM element.
|
|
27
|
+
*
|
|
28
|
+
* Returns true when the underlying DOM element is reset successfully; false otherwise.
|
|
29
|
+
*/
|
|
30
|
+
function tryResetMockContainer() {
|
|
31
|
+
let didResetMockContainer = false;
|
|
32
|
+
if (element) {
|
|
33
|
+
unmountComponentAtNode(element);
|
|
34
|
+
element.remove();
|
|
35
|
+
element = null;
|
|
36
|
+
didResetMockContainer = true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return didResetMockContainer;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { getMockContainer, initMockContainer, tryResetMockContainer };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { SetupServer } from 'msw/node';
|
|
2
|
+
|
|
3
|
+
let mockServer: SetupServer | null = null;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Call this function if you intend to use a mock server.
|
|
7
|
+
* @param value the value returned from calling `import('msw/node').setupServer(handlers)`
|
|
8
|
+
* @see https://mswjs.io/docs/getting-started/mocks/rest-api
|
|
9
|
+
* @example
|
|
10
|
+
* import { setupServer, rest } from 'mws/node';
|
|
11
|
+
*
|
|
12
|
+
* beforeAll(() => {
|
|
13
|
+
* const handlers = []; // <-- Define `rest` handlers there
|
|
14
|
+
* setMockServer(setupServer(...handlers));
|
|
15
|
+
* getMockServer()?.listen({ onUnhandledRequest: 'error' });
|
|
16
|
+
* });
|
|
17
|
+
*/
|
|
18
|
+
function setMockServer(value: SetupServer | null) {
|
|
19
|
+
mockServer = value;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function getMockServer() {
|
|
23
|
+
return mockServer;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { setMockServer, getMockServer };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { afterAll, afterEach, beforeEach, vi } from 'vitest';
|
|
2
|
+
import { initMockContainer, tryResetMockContainer } from './mock-container';
|
|
3
|
+
import { getMockServer } from './mock-server';
|
|
4
|
+
|
|
5
|
+
afterAll(() => {
|
|
6
|
+
getMockServer()?.close();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
initMockContainer();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
getMockServer()?.resetHandlers();
|
|
15
|
+
tryResetMockContainer();
|
|
16
|
+
vi.clearAllMocks();
|
|
17
|
+
});
|
package/lib/cim/index.ts
CHANGED
package/lib/common/api/utils.ts
CHANGED
package/lib/common/index.ts
CHANGED
|
@@ -5,10 +5,10 @@ import { AlertsContextProvider, FeatureGateContextProvider } from '../../../comm
|
|
|
5
5
|
import { HostsClusterDetailTabContent } from './HostsClusterDetailTabContent';
|
|
6
6
|
import { HostsClusterDetailTabProps } from './types';
|
|
7
7
|
import { storeDay1 } from '../../store';
|
|
8
|
-
import {
|
|
8
|
+
import { useFeatureDetection } from '../../hooks/use-feature-detection';
|
|
9
9
|
|
|
10
10
|
const HostsClusterDetailTab = (props: HostsClusterDetailTabProps) => {
|
|
11
|
-
|
|
11
|
+
useFeatureDetection();
|
|
12
12
|
|
|
13
13
|
return (
|
|
14
14
|
<Provider store={storeDay1}>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { Provider } from 'react-redux';
|
|
3
3
|
import { Switch, Route, Redirect } from 'react-router-dom';
|
|
4
4
|
import { Clusters, ClusterPage, NewClusterPage } from './clusters';
|
|
@@ -7,15 +7,13 @@ import type { FeatureListType } from '../../common/features/featureGate';
|
|
|
7
7
|
import { routeBasePath } from '../config';
|
|
8
8
|
import { AssistedUILibVersion } from './ui';
|
|
9
9
|
import { storeDay1 } from '../store';
|
|
10
|
-
import {
|
|
10
|
+
import { useFeatureDetection } from '../hooks/use-feature-detection';
|
|
11
11
|
|
|
12
12
|
export const Routes: React.FC<{ allEnabledFeatures: FeatureListType }> = ({
|
|
13
13
|
allEnabledFeatures,
|
|
14
14
|
children,
|
|
15
15
|
}) => {
|
|
16
|
-
|
|
17
|
-
storeDay1.dispatch(featureFlagsActions.setFeatureFlags(allEnabledFeatures));
|
|
18
|
-
}, [allEnabledFeatures]);
|
|
16
|
+
useFeatureDetection(allEnabledFeatures);
|
|
19
17
|
|
|
20
18
|
return (
|
|
21
19
|
<Provider store={storeDay1}>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Modal, ModalVariant, Button, ButtonVariant } from '@patternfly/react-core';
|
|
3
|
+
import { useTranslation } from '../../../common/hooks/use-translation-wrapper';
|
|
3
4
|
|
|
4
5
|
type DeleteHostModalProps = {
|
|
5
6
|
hostname?: string;
|
|
@@ -8,28 +9,32 @@ type DeleteHostModalProps = {
|
|
|
8
9
|
onDelete: () => void;
|
|
9
10
|
};
|
|
10
11
|
|
|
11
|
-
const DeleteHostModal = ({ isOpen, hostname, onClose, onDelete }: DeleteHostModalProps) =>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
12
|
+
const DeleteHostModal = ({ isOpen, hostname, onClose, onDelete }: DeleteHostModalProps) => {
|
|
13
|
+
const { t } = useTranslation();
|
|
14
|
+
return (
|
|
15
|
+
<Modal
|
|
16
|
+
title={t('ai:Remove host?')}
|
|
17
|
+
isOpen={isOpen}
|
|
18
|
+
onClose={onClose}
|
|
19
|
+
variant={ModalVariant.small}
|
|
20
|
+
titleIconVariant="warning"
|
|
21
|
+
actions={[
|
|
22
|
+
<Button
|
|
23
|
+
data-testid="delete-host-submit"
|
|
24
|
+
key="confirm"
|
|
25
|
+
variant={ButtonVariant.danger}
|
|
26
|
+
onClick={onDelete}
|
|
27
|
+
>
|
|
28
|
+
{t('ai:Remove host')}
|
|
29
|
+
</Button>,
|
|
30
|
+
<Button key="cancel" variant={ButtonVariant.link} onClick={onClose}>
|
|
31
|
+
{t('ai:Cancel')}
|
|
32
|
+
</Button>,
|
|
33
|
+
]}
|
|
34
|
+
>
|
|
35
|
+
{t('ai:Host {{hostname}} will be removed', { hostname: hostname || '' })}
|
|
36
|
+
</Modal>
|
|
37
|
+
);
|
|
38
|
+
};
|
|
34
39
|
|
|
35
40
|
export default DeleteHostModal;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FeatureListType } from '../../common/features/featureGate';
|
|
2
|
+
|
|
3
|
+
type FeatureMapping = {
|
|
4
|
+
featureId: keyof FeatureListType;
|
|
5
|
+
capabilityId: string;
|
|
6
|
+
};
|
|
7
|
+
export const externalFeaturesMappings: Array<FeatureMapping> = [
|
|
8
|
+
{
|
|
9
|
+
featureId: 'ASSISTED_INSTALLER_PLATFORM_OCI',
|
|
10
|
+
capabilityId: 'capability.organization.bare_metal_installer_platform_oci',
|
|
11
|
+
},
|
|
12
|
+
];
|
package/lib/ocm/config/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './routeBasePath';
|
|
2
2
|
export * from './constants';
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { Account, Organization } from '@openshift-assisted/types/accounts-management-service';
|
|
2
|
+
import { describe, it, vi, expect } from 'vitest';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Provider } from 'react-redux';
|
|
5
|
+
import { render } from 'react-dom';
|
|
6
|
+
import { act } from 'react-dom/test-utils';
|
|
7
|
+
import { featureFlagsActions, FeatureFlagsState } from '../store/slices/feature-flags/slice';
|
|
8
|
+
import { isFeatureEnabled } from '../store/slices/feature-flags/selectors';
|
|
9
|
+
import { RootStateDay1, storeDay1 } from '../store/store-day1';
|
|
10
|
+
import { useFeatureDetection } from './use-feature-detection';
|
|
11
|
+
import { CurrentAccountApi } from '../../common/api/accounts-management-service/current-account-api';
|
|
12
|
+
import { OrganizationsApi } from '../../common/api/accounts-management-service/organizations-api';
|
|
13
|
+
import { getMockContainer } from '../../_test-helpers/mock-container';
|
|
14
|
+
|
|
15
|
+
vi.spyOn(featureFlagsActions, 'setFeatureFlag');
|
|
16
|
+
vi.spyOn(CurrentAccountApi, 'getCurrentAccount').mockImplementation(() => {
|
|
17
|
+
return Promise.resolve({
|
|
18
|
+
username: 'jdoe',
|
|
19
|
+
} as Account);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const makeSpyOn$OrganizationsApi$getOrganization = (mockResponse: Organization) =>
|
|
23
|
+
vi.spyOn(OrganizationsApi, 'getOrganization').mockImplementation(() => {
|
|
24
|
+
return Promise.resolve(mockResponse);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('use-feature-detection.ts', () => {
|
|
28
|
+
it('Sets only external features when no overrides are provided', async () => {
|
|
29
|
+
const DummyComponent: React.FC = () => {
|
|
30
|
+
useFeatureDetection();
|
|
31
|
+
return null;
|
|
32
|
+
};
|
|
33
|
+
makeSpyOn$OrganizationsApi$getOrganization({
|
|
34
|
+
capabilities: [
|
|
35
|
+
{
|
|
36
|
+
name: 'capability.organization.bare_metal_installer_platform_oci',
|
|
37
|
+
value: 'true',
|
|
38
|
+
inherited: true,
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
await act(() =>
|
|
44
|
+
Promise.resolve(
|
|
45
|
+
render(
|
|
46
|
+
<Provider store={storeDay1}>
|
|
47
|
+
<DummyComponent />
|
|
48
|
+
</Provider>,
|
|
49
|
+
getMockContainer(),
|
|
50
|
+
),
|
|
51
|
+
),
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
expect(
|
|
55
|
+
isFeatureEnabled(
|
|
56
|
+
storeDay1.getState() as RootStateDay1 & FeatureFlagsState,
|
|
57
|
+
'ASSISTED_INSTALLER_PLATFORM_OCI',
|
|
58
|
+
),
|
|
59
|
+
).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('Internal features override external features', async () => {
|
|
63
|
+
const featuresOverride = { ASSISTED_INSTALLER_PLATFORM_OCI: true };
|
|
64
|
+
const DummyComponent: React.FC = () => {
|
|
65
|
+
useFeatureDetection(featuresOverride);
|
|
66
|
+
return null;
|
|
67
|
+
};
|
|
68
|
+
makeSpyOn$OrganizationsApi$getOrganization({
|
|
69
|
+
capabilities: [
|
|
70
|
+
{
|
|
71
|
+
name: 'capability.organization.bare_metal_installer_platform_oci',
|
|
72
|
+
value: 'false',
|
|
73
|
+
inherited: true,
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
await act(() =>
|
|
79
|
+
Promise.resolve(
|
|
80
|
+
render(
|
|
81
|
+
<Provider store={storeDay1}>
|
|
82
|
+
<DummyComponent />
|
|
83
|
+
</Provider>,
|
|
84
|
+
getMockContainer(),
|
|
85
|
+
),
|
|
86
|
+
),
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
expect(
|
|
90
|
+
isFeatureEnabled(
|
|
91
|
+
storeDay1.getState() as RootStateDay1 & FeatureFlagsState,
|
|
92
|
+
'ASSISTED_INSTALLER_PLATFORM_OCI',
|
|
93
|
+
),
|
|
94
|
+
).toBe(featuresOverride.ASSISTED_INSTALLER_PLATFORM_OCI);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('Processes only features prefixed with ASSISTED_INSTALLER', async () => {
|
|
98
|
+
const featuresOverride = { NON_ASSISTED_INSTALLER_FEATURE: true };
|
|
99
|
+
const DummyComponent: React.FC = () => {
|
|
100
|
+
useFeatureDetection(featuresOverride);
|
|
101
|
+
return null;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
await act(() =>
|
|
105
|
+
Promise.resolve(
|
|
106
|
+
render(
|
|
107
|
+
<Provider store={storeDay1}>
|
|
108
|
+
<DummyComponent />
|
|
109
|
+
</Provider>,
|
|
110
|
+
getMockContainer(),
|
|
111
|
+
),
|
|
112
|
+
),
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
/* Here we don't mock the call to the user organization API, therefore the
|
|
116
|
+
* capabilities in the currentUser slice should remain undefined, since the list
|
|
117
|
+
* of featuresOverride should get filtered out of features not prefixed with
|
|
118
|
+
* "ASSISTED_INSTALLER" there should be no call to setFeatureFlag.
|
|
119
|
+
*/
|
|
120
|
+
expect(featureFlagsActions.setFeatureFlag).not.toHaveBeenCalled();
|
|
121
|
+
expect(
|
|
122
|
+
storeDay1.getState().featureFlags.data['NON_ASSISTED_INSTALLER_FEATURE'],
|
|
123
|
+
).not.toBeDefined();
|
|
124
|
+
});
|
|
125
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FeatureListType } from '../../common/features/featureGate';
|
|
2
|
+
import { featureFlagsAsyncActions } from '../store/slices/feature-flags/slice';
|
|
3
|
+
import { storeDay1 } from '../store/store-day1';
|
|
4
|
+
import { useEffect } from 'react';
|
|
5
|
+
|
|
6
|
+
export function useFeatureDetection<T extends Partial<Record<string, boolean> & FeatureListType>>(
|
|
7
|
+
overrides: T | null = null,
|
|
8
|
+
) {
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
const onlyAssistedInstallerFeatures = Object.fromEntries(
|
|
11
|
+
Object.entries(overrides ?? {}).filter(([k, _v]) => k.startsWith('ASSISTED_INSTALLER')),
|
|
12
|
+
);
|
|
13
|
+
void storeDay1.dispatch(
|
|
14
|
+
featureFlagsAsyncActions.detectFeaturesAsync(onlyAssistedInstallerFeatures),
|
|
15
|
+
);
|
|
16
|
+
}, [overrides]);
|
|
17
|
+
}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import InfraEnvsService from './InfraEnvsService';
|
|
4
|
-
import { AI_UI_TAG } from '../../common';
|
|
5
|
-
import { isInOcm } from '../api';
|
|
6
|
-
import { ClusterCreateParamsWithStaticNetworking } from './types';
|
|
7
|
-
import omit from 'lodash-es/omit.js';
|
|
8
|
-
import {
|
|
1
|
+
import type { ClusterCreateParamsWithStaticNetworking } from './types';
|
|
2
|
+
import type {
|
|
9
3
|
CustomManifestValues,
|
|
10
4
|
ListManifestsExtended,
|
|
11
5
|
} from '../components/clusterConfiguration/manifestsConfiguration/data/dataTypes';
|
|
12
|
-
import {
|
|
6
|
+
import type {
|
|
13
7
|
Cluster,
|
|
14
8
|
Host,
|
|
15
9
|
InfraEnvCreateParams,
|
|
16
10
|
UpdateManifestParams,
|
|
17
11
|
V2ClusterUpdateParams,
|
|
18
12
|
} from '@openshift-assisted/types/assisted-installer-service';
|
|
13
|
+
import omit from 'lodash-es/omit.js';
|
|
14
|
+
import ClustersAPI from '../../common/api/assisted-service/ClustersAPI';
|
|
15
|
+
import HostsService from './HostsService';
|
|
16
|
+
import InfraEnvsService from './InfraEnvsService';
|
|
17
|
+
import { AI_UI_TAG } from '../../common/config/constants';
|
|
18
|
+
import { isInOcm } from '../../common/api/axiosClient';
|
|
19
19
|
|
|
20
20
|
const ClustersService = {
|
|
21
21
|
findHost(hosts: Cluster['hosts'] = [], hostId: Host['id']) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { Cluster, InfraEnv } from '@openshift-assisted/types/assisted-installer-service';
|
|
2
|
+
import { CpuArchitecture, getAllCpuArchitectures } from '../../common//types/cpuArchitecture';
|
|
3
3
|
|
|
4
4
|
const CACHE_KEY = 'infra-env-ids-cache-v2';
|
|
5
5
|
|
package/lib/ocm/store/hooks.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { useDispatch, useSelector } from 'react-redux';
|
|
2
2
|
import type { TypedUseSelectorHook } from 'react-redux';
|
|
3
3
|
import type { DispatchDay1, RootStateDay1 } from './store-day1';
|
|
4
|
-
import type { DispatchDay2, RootStateDay2 } from './store-day2';
|
|
5
4
|
|
|
6
|
-
export const useDispatchDay1
|
|
5
|
+
export const useDispatchDay1 = useDispatch<DispatchDay1>;
|
|
7
6
|
export const useSelectorDay1: TypedUseSelectorHook<RootStateDay1> = useSelector;
|
|
8
|
-
export const useDispatchDay2: () => DispatchDay2 = useDispatch;
|
|
9
|
-
export const useSelectorDay2: TypedUseSelectorHook<RootStateDay2> = useSelector;
|