Skip to content

Commit af7ce6c

Browse files
WIP: Continue memoizing for quick starts page
modified: frontend/packages/console-app/src/components/quick-starts/QuickStartConfiguration.tsx modified: frontend/packages/console-app/src/components/quick-starts/loader/QuickStartsLoader.tsx modified: frontend/packages/console-app/src/components/quick-starts/utils/useQuickStartPermission.ts modified: frontend/packages/console-app/src/components/quick-starts/utils/useQuickStarts.ts modified: frontend/packages/console-app/src/components/resource-quota/AppliedClusterResourceQuotaCharts.tsx modified: frontend/packages/console-app/src/components/resource-quota/ClusterResourceQuotaCharts.tsx modified: frontend/packages/console-app/src/components/resource-quota/ResourceQuotaCharts.tsx modified: frontend/packages/console-app/src/components/storage/StorageClassProviders.ts modified: frontend/packages/console-app/src/components/tour/GuidedTour.tsx modified: frontend/packages/console-app/src/components/tour/GuidedTourMastheadTrigger.tsx modified: frontend/packages/console-app/src/components/tour/StepComponent.tsx modified: frontend/packages/console-app/src/components/tour/TourStepComponent.tsx modified: frontend/packages/console-app/src/components/tour/tour-context.ts
1 parent 4dd9a7c commit af7ce6c

13 files changed

+69
-52
lines changed

frontend/packages/console-app/src/components/quick-starts/QuickStartConfiguration.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ const QuickStartConfiguration: React.FC<{ readonly: boolean }> = ({ readonly })
121121
const patch: DisabledQuickStartsConsoleConfig = {
122122
spec: {
123123
customization: {
124+
// @ts-ignore
124125
quickStarts: {
125-
disabled,
126126
},
127127
},
128128
},
@@ -169,7 +169,7 @@ const QuickStartConfiguration: React.FC<{ readonly: boolean }> = ({ readonly })
169169
/>
170170

171171
<LoadError error={consoleConfigError} />
172-
<SaveStatus {...saveStatus} />
172+
{saveStatus && <SaveStatus {...saveStatus} />}
173173
</FormSection>
174174
);
175175
};

frontend/packages/console-app/src/components/quick-starts/loader/QuickStartsLoader.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,29 @@ const QuickStartsLoader: React.FC<QuickStartsLoaderProps> = ({ children }) => {
1010
const [allowedQuickStarts, setAllowedQuickStarts] = React.useState<QuickStart[]>([]);
1111
const [permissionsLoaded, setPermissionsLoaded] = React.useState<boolean>(false);
1212
const permissionChecks = React.useRef<{ [name: string]: boolean }>({});
13+
const permissionsInitialized = React.useRef<boolean>(false);
14+
15+
React.useEffect(() => {
16+
if (quickStarts.length > 0) {
17+
permissionChecks.current = {};
18+
setPermissionsLoaded(false);
19+
permissionsInitialized.current = false;
20+
}
21+
}, [quickStarts.length]);
1322

1423
const handlePermissionCheck = React.useCallback(
1524
(quickStart, hasPermission) => {
1625
permissionChecks.current[quickStart.metadata.name] = hasPermission;
17-
if (Object.keys(permissionChecks.current).length === quickStarts.length) {
26+
if (Object.keys(permissionChecks.current).length === quickStarts.length && !permissionsInitialized.current) {
1827
const filteredQuickStarts = quickStarts.filter(
1928
(quickstart) => permissionChecks.current[quickstart.metadata.name],
2029
);
2130
setAllowedQuickStarts(filteredQuickStarts);
2231
setPermissionsLoaded(true);
32+
permissionsInitialized.current = true;
2333
}
2434
},
25-
[quickStarts],
35+
[quickStarts.length],
2636
);
2737

2838
return (

frontend/packages/console-app/src/components/quick-starts/utils/useQuickStartPermission.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ const useQuickStartPermission = (quickStart: QuickStart): [boolean, boolean] =>
66
spec: { accessReviewResources },
77
} = quickStart;
88

9-
const accessReviews = [];
10-
const accessReviewsLoading = [];
9+
const accessReviews: boolean[] = [];
10+
const accessReviewsLoading: boolean[] = [];
1111

1212
if (accessReviewResources) {
1313
accessReviewResources.forEach((descriptor) => {

frontend/packages/console-app/src/components/quick-starts/utils/useQuickStarts.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,5 +117,9 @@ export const useQuickStarts = (filterDisabledQuickStarts = true): WatchK8sResult
117117
);
118118
}, [quickStarts, quickStartsLoaded, filterDisabledQuickStarts, preferredLanguage]);
119119

120-
return [bestMatchQuickStarts, quickStartsLoaded, quickStartsError];
120+
return [
121+
bestMatchQuickStarts.filter((quickStart) => quickStart !== null),
122+
quickStartsLoaded,
123+
quickStartsError,
124+
];
121125
};

frontend/packages/console-app/src/components/resource-quota/AppliedClusterResourceQuotaCharts.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ const AppliedClusterResourceQuotaCharts = ({
2020
);
2121

2222
const charts = Object.keys(nsQuotas?.status?.hard ?? {}).map((resourceName) => {
23-
const clusterHard = appliedClusterResourceQuota.status.total?.hard?.[resourceName];
24-
const clusterUsed = appliedClusterResourceQuota.status.total?.used?.[resourceName];
25-
const nsUsed = nsQuotas.status.used?.[resourceName];
23+
const clusterHard = appliedClusterResourceQuota.status?.total?.hard?.[resourceName] ?? '';
24+
const clusterUsed = appliedClusterResourceQuota.status?.total?.used?.[resourceName] ?? '';
25+
const nsUsed = nsQuotas?.status?.used?.[resourceName] ?? '';
2626
const clusterUsage = getUsedPercentage(clusterHard, clusterUsed);
2727
const unused = 100 - clusterUsage;
2828

frontend/packages/console-app/src/components/resource-quota/ClusterResourceQuotaCharts.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ const ClusterResourceQuotaCharts = ({
1414
}: ClusterResourceQuotaChartsProps): JSX.Element => {
1515
const { t } = useTranslation();
1616
const charts = Object.keys(clusterResourceQuota.status?.total?.hard ?? {}).map((resourceName) => {
17-
const clusterHard = clusterResourceQuota.status.total.hard[resourceName];
18-
const clusterUsed = clusterResourceQuota.status.total.used?.[resourceName];
17+
const clusterHard = clusterResourceQuota.status?.total?.hard?.[resourceName];
18+
const clusterUsed = clusterResourceQuota.status?.total?.used?.[resourceName];
1919

2020
const { label, percent } = getLabelAndUsage({
2121
resourceName,
22-
used: clusterUsed,
23-
hard: clusterHard,
22+
used: clusterUsed ?? '',
23+
hard: clusterHard ?? '',
2424
});
2525

2626
return (

frontend/packages/console-app/src/components/resource-quota/ResourceQuotaCharts.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@ type ResourceQuotaChartsProps = {
1212
const ResourceQuotaCharts = ({ resourceQuota }: ResourceQuotaChartsProps): JSX.Element => {
1313
const { t } = useTranslation();
1414
const charts = Object.keys(resourceQuota.status?.hard ?? {}).map((resourceName) => {
15-
const hard = resourceQuota.status.hard[resourceName];
16-
const used = resourceQuota.status.used?.[resourceName];
15+
const hard = resourceQuota.status?.hard?.[resourceName || ''] ?? '';
16+
const used = resourceQuota.status?.used?.[resourceName || ''] ?? '';
1717

18-
const { label, percent } = getLabelAndUsage({ resourceName, used, hard });
18+
const { label, percent } = getLabelAndUsage({
19+
resourceName,
20+
used,
21+
hard,
22+
});
1923
return (
2024
<div
2125
key={resourceName}

frontend/packages/console-app/src/components/storage/StorageClassProviders.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,71 +13,71 @@ export const isStorageOsAdminSecretNSRequired = (params: Parameters) => {
1313
};
1414

1515
export const validateAWSIopsPerGB = (params: Parameters) => {
16-
if (params.iopsPerGB.value && !params.iopsPerGB.value.match(/^\d+$/)) {
16+
if (params?.iopsPerGB?.value && !params?.iopsPerGB?.value?.match(/^\d+$/)) {
1717
// t(''console-app~IOPS per GiB must be a number')
1818
return 'console-app~IOPS per GiB must be a number';
1919
}
2020
return null;
2121
};
2222

2323
export const validateGcePdZone = (params: Parameters) => {
24-
if (params.zone.value !== '' && (params?.zones?.value ?? '') !== '') {
24+
if (params?.zone?.value !== '' && (params?.zones?.value ?? '') !== '') {
2525
// t('console-app~Zone and zones parameters must not be used at the same time')
2626
return 'console-app~Zone and zones parameters must not be used at the same time';
2727
}
2828
return null;
2929
};
3030

3131
export const validateGcePdZones = (params: Parameters) => {
32-
if (params.zones.value !== '' && (params?.zone?.value ?? '') !== '') {
32+
if (params?.zones?.value !== '' && (params?.zone?.value ?? '') !== '') {
3333
// t('console-app~Zone and zones parameters must not be used at the same time')
3434
return 'console-app~Zone and zones parameters must not be used at the same time';
3535
}
3636
return null;
3737
};
3838

3939
export const validateGCEReplicationType = (params: Parameters) => {
40-
if (params['replication-type'].value === 'regional-pd' && (params?.zone?.value ?? '') !== '') {
40+
if (params?.['replication-type']?.value === 'regional-pd' && (params?.zone?.value ?? '') !== '') {
4141
// t('console-app~Zone cannot be specified when replication type regional-pd is chosen. Use zones instead.')
4242
return 'console-app~Zone cannot be specified when replication type regional-pd is chosen. Use zones instead.';
4343
}
4444
return null;
4545
};
4646

4747
export const validateGlusterGidMin = (params: Parameters) => {
48-
if (params.gidMin.value !== '' && !params.gidMin.value.match(/^[1-9]\d*$/)) {
48+
if (params?.gidMin?.value !== '' && !params?.gidMin?.value?.match(/^[1-9]\d*$/)) {
4949
// t('console-app~GID min must be number')
5050
return 'console-app~GID min must be number';
5151
}
5252
return null;
5353
};
5454

5555
export const validateGlusterGidMax = (params: Parameters) => {
56-
if (params.gidMax.value !== '' && !params.gidMax.value.match(/^[1-9]\d*$/)) {
56+
if (params?.gidMax?.value !== '' && !params?.gidMax?.value?.match(/^[1-9]\d*$/)) {
5757
// t('console-app~GID max must be number')
5858
return 'console-app~GID max must be number';
5959
}
6060
return null;
6161
};
6262

6363
export const validatePortworxBlockSize = (params: Parameters) => {
64-
if (params.block_size.value !== '' && !params.block_size.value.match(/^[1-9]\d*$/)) {
64+
if (params?.block_size?.value !== '' && !params?.block_size?.value?.match(/^[1-9]\d*$/)) {
6565
// t('console-app~Snapshot interval must be a number')
6666
return 'console-app~Snapshot interval must be a number';
6767
}
6868
return null;
6969
};
7070

7171
export const validatePortworxReplicas = (params: Parameters) => {
72-
if (params.repl.value !== '' && !params.repl.value.match(/^[1-9]\d*$/)) {
72+
if (params?.repl?.value !== '' && !params?.repl?.value?.match(/^[1-9]\d*$/)) {
7373
// t('console-app~Number of replicas must be a number')
7474
return 'console-app~Number of replicas must be a number';
7575
}
7676
return null;
7777
};
7878

7979
export const validatePortworxSnapshotInterval = (params: Parameters) => {
80-
if (params.repl.value !== '' && !params.repl.value.match(/^[1-9]\d*$/)) {
80+
if (params?.repl?.value !== '' && !params?.repl?.value?.match(/^[1-9]\d*$/)) {
8181
// t('console-app~Snapshot interval must be a number')
8282
return 'console-app~Snapshot interval must be a number';
8383
}
@@ -86,8 +86,8 @@ export const validatePortworxSnapshotInterval = (params: Parameters) => {
8686

8787
export const validatePortworxAggregationLevel = (params: Parameters) => {
8888
if (
89-
params.aggregation_level.value !== '' &&
90-
!params.aggregation_level.value.match(/^[1-9]\d*$/)
89+
params?.aggregation_level?.value !== '' &&
90+
!params?.aggregation_level?.value?.match(/^[1-9]\d*$/)
9191
) {
9292
// t('console-app~Aggregation level must be a number')
9393
return 'console-app~Aggregation level must be a number';

frontend/packages/console-app/src/components/tour/GuidedTour.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ const GuidedTour: React.FC = () => {
88
const { t } = useTranslation();
99
if (!tour) return null;
1010
const { intro, steps, end } = tour;
11-
const { stepNumber, startTour, completedTour } = tourState;
11+
const { stepNumber, startTour, completedTour } = tourState || {};
12+
const currentStepNumber = stepNumber || 0;
1213

1314
if (completedTour) {
14-
onComplete();
15+
onComplete?.();
1516
return null;
1617
}
17-
if (startTour || stepNumber === 0)
18+
if (startTour || currentStepNumber === 0)
1819
return (
1920
<StepComponent
2021
{...intro}
@@ -23,7 +24,7 @@ const GuidedTour: React.FC = () => {
2324
backButtonText={t('console-app~Skip tour')}
2425
/>
2526
);
26-
if (stepNumber > totalSteps)
27+
if (currentStepNumber && totalSteps && currentStepNumber > totalSteps)
2728
return (
2829
<StepComponent
2930
{...end}
@@ -32,7 +33,7 @@ const GuidedTour: React.FC = () => {
3233
backButtonText={t('console-app~Back')}
3334
/>
3435
);
35-
const step = steps[stepNumber - 1];
36+
const step = steps?.[currentStepNumber - 1];
3637
return (
3738
<StepComponent
3839
{...step}

frontend/packages/console-app/src/components/tour/GuidedTourMastheadTrigger.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const GuidedTourMastheadTrigger: React.FC<GuidedTourMastheadTriggerProps> = Reac
1818
className={className}
1919
type="button"
2020
ref={ref}
21-
onClick={() => tourDispatch({ type: TourActions.start })}
21+
onClick={() => tourDispatch?.({ type: TourActions.start })}
2222
>
2323
{t('console-app~Guided tour')}
2424
</button>

0 commit comments

Comments
 (0)