Skip to content

Commit 607531c

Browse files
authored
fix: Resource Validation refactor (kyma-project#4506)
* fix: Resource Validation refactor * test: Adjust tests to new layout * fix: Remove unused code * fix: Initial default value * fix * fix: Move the logic to atom * test: Clear localStorage * fix: cleanup * test: move clearLocalStorage * fix: Adjust background * test: adjust test
1 parent 9f84250 commit 607531c

File tree

10 files changed

+141
-196
lines changed

10 files changed

+141
-196
lines changed

public/i18n/en.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1449,12 +1449,12 @@ settings:
14491449
title: Cluster Interaction
14501450
resourcesValidation:
14511451
customize: Customize
1452-
enabled-policies: Enabled Policies
14531452
no-policies-found: No policies found
14541453
reset: Reset
14551454
title: Resource Validation
14561455
validateResources: Validate Resources
14571456
validation-disabled: Resource validation is disabled
1457+
validation-policies: Validation Policies
14581458
showHiddenNamespaces: Show hidden Namespaces
14591459
title: Advanced Options
14601460
language:

src/components/Settings/ResourceValidation/ResourceValidationSettings.scss

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1+
.resource-validation-table {
2+
ui5-table-cell {
3+
overflow-clip-margin: unset !important; // Otherwise switch focus is being cut off
4+
}
5+
6+
ui5-table-header-row {
7+
display: none;
8+
}
9+
}
10+
111
.policy-row {
2-
display: grid;
3-
grid-template-columns: 1fr fit-content(50%);
412
align-items: center;
513
font-size: var(--sapFontSize);
614
}
Lines changed: 63 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,20 @@
11
import { useTranslation } from 'react-i18next';
2-
import { useAtom } from 'jotai';
3-
import { Button, Switch } from '@ui5/webcomponents-react';
4-
import {
5-
getExtendedValidateResourceState,
6-
validateResourcesAtom,
7-
} from 'state/settings/validateResourcesAtom';
8-
import { validationSchemasAtom } from 'state/validationSchemasAtom';
2+
import { useAtomValue } from 'jotai';
3+
import { FlexBox, Label, Switch } from '@ui5/webcomponents-react';
94
import { useMemo } from 'react';
105
import { GenericList } from 'shared/components/GenericList/GenericList';
116

12-
import { useFeature } from 'hooks/useFeature';
13-
import { ValidationFeatureConfig } from 'state/validationEnabledSchemasAtom';
14-
import { UI5Panel } from 'shared/components/UI5Panel/UI5Panel';
15-
7+
import { useSyncedValidateResources } from 'state/settings/validateResourcesAtom';
8+
import { validationSchemasAtom } from 'state/validationSchemasAtom';
169
import './ResourceValidationSettings.scss';
17-
import { configFeaturesNames } from 'state/types';
18-
import { useAtomValue } from 'jotai';
1910

2011
export default function ResourceValidationSettings() {
2112
const { t } = useTranslation();
22-
const [validateResources, setValidateResources] = useAtom(
23-
validateResourcesAtom,
24-
);
25-
const validationFeature = useFeature(
26-
configFeaturesNames.RESOURCE_VALIDATION,
27-
) as ValidationFeatureConfig;
2813

29-
const {
30-
isEnabled,
31-
choosePolicies,
32-
policies: selectedPolicies = (validationFeature?.isEnabled &&
33-
validationFeature?.config?.policies) ||
34-
[],
35-
} = getExtendedValidateResourceState(validateResources);
14+
const [{ isEnabled, policies }, setValidateResources] =
15+
useSyncedValidateResources();
16+
17+
const selectedPolicies = policies;
3618

3719
const validationSchemas = useAtomValue(validationSchemasAtom);
3820
const allOptions = useMemo(
@@ -42,12 +24,8 @@ export default function ResourceValidationSettings() {
4224
.sort((a, b) => (a.key < b.key ? -1 : 1)) ?? [],
4325
[validationSchemas],
4426
);
45-
4627
const policyList = useMemo(() => {
47-
const selectedPolicySet = selectedPolicies.reduce(
48-
(agg, name) => agg.add(name),
49-
new Set(),
50-
);
28+
const selectedPolicySet = new Set(selectedPolicies);
5129
return allOptions.map((option) => ({
5230
...option,
5331
selected: selectedPolicySet.has(option.key),
@@ -57,133 +35,92 @@ export default function ResourceValidationSettings() {
5735
const toggleVisibility = () => {
5836
setValidateResources({
5937
isEnabled: !isEnabled,
60-
choosePolicies,
6138
policies: selectedPolicies,
6239
});
6340
};
6441

65-
const enablePolicyCustomization = () => {
66-
setValidateResources({
67-
isEnabled,
68-
choosePolicies: true,
69-
policies:
70-
(validationFeature?.isEnabled && validationFeature?.config?.policies) ||
71-
[],
72-
});
73-
};
74-
75-
const disablePolicyCustomization = () => {
76-
setValidateResources({
77-
isEnabled,
78-
choosePolicies: false,
79-
});
80-
};
81-
8242
const deleteSelectedPolicy = (policyToDelete: string) => {
8343
setValidateResources({
8444
isEnabled,
85-
choosePolicies,
86-
policies: selectedPolicies.filter((policy) => policy !== policyToDelete),
45+
policies: selectedPolicies.filter(
46+
(policy: string) => policy !== policyToDelete,
47+
),
8748
});
8849
};
8950

9051
const addSelectedPolicy = (policyToAdd: string) => {
9152
setValidateResources({
9253
isEnabled,
93-
choosePolicies,
9454
policies: [...selectedPolicies, policyToAdd].sort(),
9555
});
9656
};
9757

9858
return (
99-
<UI5Panel
100-
title={t('settings.general.resourcesValidation.validateResources')}
101-
accessibleName={t('settings.general.accessible-name.validateResources')}
102-
headerActions={
59+
<>
60+
<FlexBox
61+
alignItems="Center"
62+
gap={'0.5rem'}
63+
className="resource-validation-container sap-margin-small"
64+
>
65+
<Label showColon>
66+
{t('settings.general.resourcesValidation.validateResources')}
67+
</Label>
10368
<Switch
10469
accessibleName={t(
10570
'settings.general.resourcesValidation.validateResources',
10671
)}
10772
checked={isEnabled}
10873
onChange={toggleVisibility}
10974
/>
110-
}
111-
>
75+
</FlexBox>
11276
{!isEnabled && (
11377
<div className="no-validation-info">
11478
<span className="bsl-has-color-status-4">
11579
{t('settings.general.resourcesValidation.validation-disabled')}
11680
</span>
11781
</div>
11882
)}
119-
{isEnabled &&
120-
(choosePolicies ||
121-
policyList.filter((policy) => policy.selected).length > 0) && (
122-
<>
123-
<GenericList
124-
title={t('settings.general.resourcesValidation.enabled-policies')}
125-
//@ts-expect-error Type mismatch between js and ts
126-
entries={
127-
choosePolicies
128-
? policyList
129-
: policyList.filter((policy) => policy.selected)
130-
}
131-
headerRenderer={() => ['policies']}
132-
rowRenderer={(entry) => [
133-
<div key={entry.text} className="policy-row">
134-
<span>{entry.text}</span>
135-
{choosePolicies && (
136-
<Switch
137-
accessibleName={t(
138-
'settings.general.resourcesValidation.select-policy',
139-
{
140-
name: entry.text,
141-
},
142-
)}
143-
checked={entry.selected}
144-
onChange={() => {
145-
if (entry.selected) deleteSelectedPolicy(entry.key);
146-
else addSelectedPolicy(entry.key);
147-
}}
148-
/>
149-
)}
150-
</div>,
151-
]}
152-
extraHeaderContent={
153-
<>
154-
{!choosePolicies && (
155-
<Button
156-
design="Transparent"
157-
endIcon="customize"
158-
onClick={enablePolicyCustomization}
159-
>
160-
{t('settings.general.resourcesValidation.customize')}
161-
</Button>
83+
{isEnabled && policyList.length > 0 && (
84+
<>
85+
<GenericList
86+
className="resource-validation-table"
87+
title={t(
88+
'settings.general.resourcesValidation.validation-policies',
89+
)}
90+
//@ts-expect-error Type mismatch between js and ts
91+
entries={policyList}
92+
headerRenderer={() => ['']} //Throws an error if it's empty - header column is hidden with CSS
93+
rowRenderer={(entry) => [
94+
<FlexBox gap="0.5rem" key={entry.text} className="policy-row">
95+
<Switch
96+
accessibleName={t(
97+
'settings.general.resourcesValidation.select-policy',
98+
{
99+
name: entry.text,
100+
},
162101
)}
163-
{choosePolicies && (
164-
<Button
165-
design="Transparent"
166-
endIcon="reset"
167-
onClick={disablePolicyCustomization}
168-
>
169-
{t('settings.general.resourcesValidation.reset')}
170-
</Button>
171-
)}
172-
</>
173-
}
174-
searchSettings={{
175-
showSearchSuggestion: false,
176-
noSearchResultTitle: t(
177-
'settings.general.resourcesValidation.no-policies-found',
178-
),
179-
noSearchResultSubtitle: '',
180-
textSearchProperties: ['key', 'text'],
181-
showSearchField: true,
182-
allowSlashShortcut: true,
183-
}}
184-
/>
185-
</>
186-
)}
187-
</UI5Panel>
102+
checked={entry.selected}
103+
onChange={() => {
104+
if (entry.selected) deleteSelectedPolicy(entry.key);
105+
else addSelectedPolicy(entry.key);
106+
}}
107+
/>
108+
<span>{entry.text}</span>
109+
</FlexBox>,
110+
]}
111+
searchSettings={{
112+
showSearchSuggestion: false,
113+
noSearchResultTitle: t(
114+
'settings.general.resourcesValidation.no-policies-found',
115+
),
116+
noSearchResultSubtitle: '',
117+
textSearchProperties: ['key', 'text'],
118+
showSearchField: true,
119+
allowSlashShortcut: true,
120+
}}
121+
/>
122+
</>
123+
)}
124+
</>
188125
);
189126
}

src/components/Settings/Settings.scss

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
.settings-dialog::part(content) {
2-
background: var(--sapBackgroundColor);
32
overflow-y: auto;
43
width: 100%;
54
height: 75vh;
6-
padding: 0;
5+
padding: 0 !important;
76
list-style-type: none;
8-
9-
.vertical-tabs-wrapper {
10-
height: 100% !important;
11-
}
127
}
138

149
.settings-row {

src/resources/Namespaces/YamlUpload/ValidationSwitch.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,8 @@ export const ValidationSwitch = () => {
1212
validateResourcesAtom,
1313
);
1414

15-
const {
16-
isEnabled,
17-
choosePolicies,
18-
policies: selectedPolicies = [],
19-
} = getExtendedValidateResourceState(validateResources);
15+
const { isEnabled, policies: selectedPolicies = [] } =
16+
getExtendedValidateResourceState(validateResources);
2017

2118
return (
2219
<div className="validate-resources">
@@ -29,7 +26,6 @@ export const ValidationSwitch = () => {
2926
onChange={() =>
3027
setValidateResources({
3128
isEnabled: !isEnabled,
32-
choosePolicies,
3329
policies: selectedPolicies,
3430
})
3531
}

src/shared/components/VerticalTabs/VerticalTabs.scss

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
.vertical-tabs-wrapper {
22
display: grid;
33
grid-template-columns: 1fr 2fr;
4+
column-gap: 1px;
45
height: 100%;
56

6-
background: var(--sapBackgroundColor);
7-
87
ul {
98
padding: 0;
109
margin: 0;

src/state/settings/validateResourcesAtom.ts

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import { atomWithStorage } from 'jotai/utils';
2+
import { useAtom } from 'jotai';
3+
import { useEffect, useMemo } from 'react';
4+
import { useFeature } from 'hooks/useFeature';
5+
import { configFeaturesNames } from 'state/types';
26

37
export type ExtendedValidateResources = {
48
isEnabled: boolean;
5-
choosePolicies: boolean;
69
policies?: string[];
710
};
811

@@ -23,9 +26,43 @@ export const getExtendedValidateResourceState = (
2326
if (typeof validateResources === 'boolean') {
2427
return {
2528
isEnabled: validateResources,
26-
choosePolicies: false,
2729
};
2830
} else {
2931
return validateResources;
3032
}
3133
};
34+
35+
export const useSyncedValidateResources = () => {
36+
const [validateResources, setValidateResources] = useAtom(
37+
validateResourcesAtom,
38+
);
39+
40+
const validationFeature = useFeature(configFeaturesNames.RESOURCE_VALIDATION);
41+
42+
const configPolicies = useMemo(() => {
43+
return validationFeature?.isEnabled
44+
? validationFeature.config?.policies || []
45+
: [];
46+
}, [validationFeature]);
47+
48+
useEffect(() => {
49+
if (typeof validateResources === 'boolean' && configPolicies.length > 0) {
50+
setValidateResources({
51+
isEnabled: validateResources,
52+
policies: configPolicies,
53+
});
54+
}
55+
}, [validateResources, configPolicies, setValidateResources]);
56+
57+
return useMemo(() => {
58+
const extendedState = getExtendedValidateResourceState(validateResources);
59+
60+
return [
61+
{
62+
isEnabled: extendedState.isEnabled,
63+
policies: extendedState.policies ?? configPolicies,
64+
},
65+
setValidateResources,
66+
] as const;
67+
}, [validateResources, configPolicies, setValidateResources]);
68+
};

0 commit comments

Comments
 (0)