Skip to content

Commit 258cc4d

Browse files
committed
CONSOLE-4575: Refactor CommonActionFactory and getCommonResourceActions to hook form.
- wrap the existing factory into a useCommonActionFactory, while keeping the existing structure of Actions. - adjust consumers of CommonActionFactory and getCommonResourceAction to use the new hook form.
1 parent 1b1c0b8 commit 258cc4d

File tree

20 files changed

+256
-225
lines changed

20 files changed

+256
-225
lines changed

frontend/packages/console-app/locales/en/console-app.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,9 +424,9 @@
424424
"Current selections": "Current selections",
425425
"Clear input value": "Clear input value",
426426
"No results found for \"{{inputValue}}\"": "No results found for \"{{inputValue}}\"",
427+
"This action cannot be undone. Deleting a node will instruct Kubernetes that the node is down or unrecoverable and delete all pods scheduled to that node. If the node is still running but unresponsive and the node is deleted, stateful workloads and persistent volumes may suffer corruption or data loss. Only delete a node that you have confirmed is completely stopped and cannot be restored.": "This action cannot be undone. Deleting a node will instruct Kubernetes that the node is down or unrecoverable and delete all pods scheduled to that node. If the node is still running but unresponsive and the node is deleted, stateful workloads and persistent volumes may suffer corruption or data loss. Only delete a node that you have confirmed is completely stopped and cannot be restored.",
427428
"Mark as schedulable": "Mark as schedulable",
428429
"Mark as unschedulable": "Mark as unschedulable",
429-
"This action cannot be undone. Deleting a node will instruct Kubernetes that the node is down or unrecoverable and delete all pods scheduled to that node. If the node is still running but unresponsive and the node is deleted, stateful workloads and persistent volumes may suffer corruption or data loss. Only delete a node that you have confirmed is completely stopped and cannot be restored.": "This action cannot be undone. Deleting a node will instruct Kubernetes that the node is down or unrecoverable and delete all pods scheduled to that node. If the node is still running but unresponsive and the node is deleted, stateful workloads and persistent volumes may suffer corruption or data loss. Only delete a node that you have confirmed is completely stopped and cannot be restored.",
430430
"Unschedulable nodes won't accept new pods. This is useful for scheduling maintenance or preparing to decommission a node.": "Unschedulable nodes won't accept new pods. This is useful for scheduling maintenance or preparing to decommission a node.",
431431
"Mark unschedulable": "Mark unschedulable",
432432
"View events": "View events",
Lines changed: 101 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import i18next from 'i18next';
1+
import * as React from 'react';
2+
import { useTranslation } from 'react-i18next';
23
import { Action } from '@console/dynamic-plugin-sdk';
34
import {
45
annotationsModalLauncher,
@@ -20,108 +21,117 @@ export type ResourceActionCreator = (
2021

2122
export type ResourceActionFactory = { [name: string]: ResourceActionCreator };
2223

23-
export const CommonActionFactory: ResourceActionFactory = {
24-
Delete: (
25-
kind: K8sKind,
26-
obj: K8sResourceKind,
27-
relatedResource?: K8sResourceKind,
28-
message?: JSX.Element,
29-
): Action => ({
30-
id: `delete-resource`,
31-
label: i18next.t('console-app~Delete {{kind}}', { kind: kind.kind }),
32-
cta: () =>
33-
deleteModal({
34-
kind,
35-
resource: obj,
36-
message,
24+
export const useCommonActionFactory = (): ResourceActionFactory => {
25+
const { t } = useTranslation();
26+
const actionFactory = React.useMemo(() => {
27+
return {
28+
Delete: (
29+
kind: K8sKind,
30+
obj: K8sResourceKind,
31+
relatedResource?: K8sResourceKind,
32+
message?: JSX.Element,
33+
): Action => ({
34+
id: `delete-resource`,
35+
label: t('console-app~Delete {{kind}}', { kind: kind.kind }),
36+
cta: () =>
37+
deleteModal({
38+
kind,
39+
resource: obj,
40+
message,
41+
}),
42+
accessReview: asAccessReview(kind, obj, 'delete'),
3743
}),
38-
accessReview: asAccessReview(kind, obj, 'delete'),
39-
}),
40-
Edit: (kind: K8sKind, obj: K8sResourceKind): Action => ({
41-
id: `edit-resource`,
42-
label: i18next.t('console-app~Edit {{kind}}', { kind: kind.kind }),
43-
cta: {
44-
href: `${resourceObjPath(obj, kind.crd ? referenceForModel(kind) : kind.kind)}/yaml`,
45-
},
46-
// TODO: Fallback to "View YAML"? We might want a similar fallback for annotations, labels, etc.
47-
accessReview: asAccessReview(kind, obj, 'update'),
48-
}),
49-
ModifyLabels: (kind: K8sKind, obj: K8sResourceKind): Action => ({
50-
id: 'edit-labels',
51-
label: i18next.t('console-app~Edit labels'),
52-
cta: () =>
53-
labelsModalLauncher({
54-
kind,
55-
resource: obj,
56-
blocking: true,
44+
Edit: (kind: K8sKind, obj: K8sResourceKind): Action => ({
45+
id: `edit-resource`,
46+
label: t('console-app~Edit {{kind}}', { kind: kind.kind }),
47+
cta: {
48+
href: `${resourceObjPath(obj, kind.crd ? referenceForModel(kind) : kind.kind)}/yaml`,
49+
},
50+
// TODO: Fallback to "View YAML"? We might want a similar fallback for annotations, labels, etc.
51+
accessReview: asAccessReview(kind, obj, 'update'),
5752
}),
58-
accessReview: asAccessReview(kind, obj, 'patch'),
59-
}),
60-
ModifyAnnotations: (kind: K8sKind, obj: K8sResourceKind): Action => ({
61-
id: 'edit-annotations',
62-
label: i18next.t('console-app~Edit annotations'),
63-
cta: () =>
64-
annotationsModalLauncher({
65-
kind,
66-
resource: obj,
67-
blocking: true,
53+
ModifyLabels: (kind: K8sKind, obj: K8sResourceKind): Action => ({
54+
id: 'edit-labels',
55+
label: t('console-app~Edit labels'),
56+
cta: () =>
57+
labelsModalLauncher({
58+
kind,
59+
resource: obj,
60+
blocking: true,
61+
}),
62+
accessReview: asAccessReview(kind, obj, 'patch'),
6863
}),
69-
accessReview: asAccessReview(kind, obj, 'patch'),
70-
}),
71-
ModifyCount: (kind: K8sKind, obj: K8sResourceKind): Action => ({
72-
id: 'edit-pod-count',
73-
label: i18next.t('console-app~Edit Pod count'),
74-
cta: () =>
75-
configureReplicaCountModal({
76-
resourceKind: kind,
77-
resource: obj,
64+
ModifyAnnotations: (kind: K8sKind, obj: K8sResourceKind): Action => ({
65+
id: 'edit-annotations',
66+
label: t('console-app~Edit annotations'),
67+
cta: () =>
68+
annotationsModalLauncher({
69+
kind,
70+
resource: obj,
71+
blocking: true,
72+
}),
73+
accessReview: asAccessReview(kind, obj, 'patch'),
7874
}),
79-
accessReview: asAccessReview(kind, obj, 'patch', 'scale'),
80-
}),
81-
ModifyPodSelector: (kind: K8sKind, obj: K8sResourceKind): Action => ({
82-
id: 'edit-pod-selector',
83-
label: i18next.t('console-app~Edit Pod selector'),
84-
cta: () =>
85-
podSelectorModal({
86-
kind,
87-
resource: obj,
88-
blocking: true,
75+
ModifyCount: (kind: K8sKind, obj: K8sResourceKind): Action => ({
76+
id: 'edit-pod-count',
77+
label: t('console-app~Edit Pod count'),
78+
cta: () =>
79+
configureReplicaCountModal({
80+
resourceKind: kind,
81+
resource: obj,
82+
}),
83+
accessReview: asAccessReview(kind, obj, 'patch', 'scale'),
8984
}),
90-
accessReview: asAccessReview(kind, obj, 'patch'),
91-
}),
92-
ModifyTolerations: (kind: K8sKind, obj: K8sResourceKind): Action => ({
93-
id: 'edit-toleration',
94-
label: i18next.t('console-app~Edit tolerations'),
95-
cta: () =>
96-
tolerationsModal({
97-
resourceKind: kind,
98-
resource: obj,
99-
modalClassName: 'modal-lg',
85+
ModifyPodSelector: (kind: K8sKind, obj: K8sResourceKind): Action => ({
86+
id: 'edit-pod-selector',
87+
label: t('console-app~Edit Pod selector'),
88+
cta: () =>
89+
podSelectorModal({
90+
kind,
91+
resource: obj,
92+
blocking: true,
93+
}),
94+
accessReview: asAccessReview(kind, obj, 'patch'),
10095
}),
101-
accessReview: asAccessReview(kind, obj, 'patch'),
102-
}),
103-
AddStorage: (kind: K8sKind, obj: K8sResourceKind): Action => ({
104-
id: 'add-storage',
105-
label: i18next.t('console-app~Add storage'),
106-
cta: {
107-
href: `${resourceObjPath(
108-
obj,
109-
kind.crd ? referenceForModel(kind) : kind.kind,
110-
)}/attach-storage`,
111-
},
112-
accessReview: asAccessReview(kind, obj, 'patch'),
113-
}),
96+
ModifyTolerations: (kind: K8sKind, obj: K8sResourceKind): Action => ({
97+
id: 'edit-toleration',
98+
label: t('console-app~Edit tolerations'),
99+
cta: () =>
100+
tolerationsModal({
101+
resourceKind: kind,
102+
resource: obj,
103+
modalClassName: 'modal-lg',
104+
}),
105+
accessReview: asAccessReview(kind, obj, 'patch'),
106+
}),
107+
AddStorage: (kind: K8sKind, obj: K8sResourceKind): Action => ({
108+
id: 'add-storage',
109+
label: t('console-app~Add storage'),
110+
cta: {
111+
href: `${resourceObjPath(
112+
obj,
113+
kind.crd ? referenceForModel(kind) : kind.kind,
114+
)}/attach-storage`,
115+
},
116+
accessReview: asAccessReview(kind, obj, 'patch'),
117+
}),
118+
};
119+
}, [t]);
120+
return actionFactory;
114121
};
115122

116-
export const getCommonResourceActions = (
123+
// avoid using both useCommonActionFactory and useCommonResourceActions inside of the action providers
124+
// due to circular dependency on useCommonActionFactory, which causes infinite re-render loop.
125+
export const useCommonResourceActions = (
117126
kind: K8sKind,
118127
obj: K8sResourceKind,
119128
message?: JSX.Element,
120129
): Action[] => {
130+
const actionFactory = useCommonActionFactory();
121131
return [
122-
CommonActionFactory.ModifyLabels(kind, obj),
123-
CommonActionFactory.ModifyAnnotations(kind, obj),
124-
CommonActionFactory.Edit(kind, obj),
125-
CommonActionFactory.Delete(kind, obj, undefined, message),
132+
actionFactory.ModifyLabels(kind, obj),
133+
actionFactory.ModifyAnnotations(kind, obj),
134+
actionFactory.Edit(kind, obj),
135+
actionFactory.Delete(kind, obj, null, message),
126136
];
127137
};

frontend/packages/console-app/src/actions/providers/cronjob-provider.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
import * as React from 'react';
22
import { CronJobKind, referenceFor } from '@console/internal/module/k8s';
33
import { useK8sModel } from '@console/shared/src/hooks/useK8sModel';
4-
import { getCommonResourceActions } from '../creators/common-factory';
4+
import { useCommonResourceActions } from '../creators/common-factory';
55
import { CronJobActionFactory } from '../creators/cronjob-factory';
66
import { usePDBActions } from '../creators/pdb-factory';
77

88
export const useCronJobActionsProvider = (resource: CronJobKind) => {
99
const [kindObj, inFlight] = useK8sModel(referenceFor(resource));
1010
const [pdbActions] = usePDBActions(kindObj, resource);
11-
11+
const commonActions = useCommonResourceActions(kindObj, resource);
1212
const actions = React.useMemo(
13-
() => [
14-
CronJobActionFactory.StartJob(kindObj, resource),
15-
...pdbActions,
16-
...getCommonResourceActions(kindObj, resource),
17-
],
18-
[kindObj, pdbActions, resource],
13+
() => [CronJobActionFactory.StartJob(kindObj, resource), ...pdbActions, ...commonActions],
14+
[kindObj, pdbActions, resource, commonActions],
1915
);
2016

2117
return [actions, !inFlight, undefined];

frontend/packages/console-app/src/actions/providers/daemon-set-provider.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
11
import * as React from 'react';
22
import { K8sResourceKind, referenceFor } from '@console/internal/module/k8s';
33
import { useK8sModel } from '@console/shared/src/hooks/useK8sModel';
4-
import { CommonActionFactory, getCommonResourceActions } from '../creators/common-factory';
4+
import { useCommonActionFactory } from '../creators/common-factory';
55
import { getHealthChecksAction } from '../creators/health-checks-factory';
66
import { usePDBActions } from '../creators/pdb-factory';
77

88
export const useDaemonSetActionsProvider = (resource: K8sResourceKind) => {
99
const [kindObj, inFlight] = useK8sModel(referenceFor(resource));
1010
const [pdbActions] = usePDBActions(kindObj, resource);
11+
const actionFactory = useCommonActionFactory();
1112

1213
const actions = React.useMemo(
1314
() => [
1415
getHealthChecksAction(kindObj, resource),
1516
...pdbActions,
16-
CommonActionFactory.AddStorage(kindObj, resource),
17-
...getCommonResourceActions(kindObj, resource),
17+
actionFactory.AddStorage(kindObj, resource),
18+
actionFactory.ModifyLabels(kindObj, resource),
19+
actionFactory.ModifyAnnotations(kindObj, resource),
20+
actionFactory.Edit(kindObj, resource),
21+
actionFactory.Delete(kindObj, resource),
1822
],
19-
[kindObj, resource, pdbActions],
23+
[kindObj, resource, pdbActions, actionFactory],
2024
);
2125

2226
return [actions, !inFlight, undefined];

frontend/packages/console-app/src/actions/providers/default-provider.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,15 @@ import * as React from 'react';
22
import { Action } from '@console/dynamic-plugin-sdk/';
33
import { K8sResourceCommon, referenceFor } from '@console/internal/module/k8s';
44
import { useK8sModel } from '@console/shared/src/hooks/useK8sModel';
5-
import { getCommonResourceActions } from '../creators/common-factory';
5+
import { useCommonResourceActions } from '../creators/common-factory';
66

77
export const useDefaultActionsProvider = (
88
resource: K8sResourceCommon,
99
): [Action[], boolean, Error] => {
1010
const [kindObj, inFlight] = useK8sModel(referenceFor(resource));
11+
const commonActions = useCommonResourceActions(kindObj, resource);
1112

12-
const actions = React.useMemo(() => [...getCommonResourceActions(kindObj, resource)], [
13-
kindObj,
14-
resource,
15-
]);
13+
const actions = React.useMemo(() => [...commonActions], [commonActions]);
1614

1715
return [actions, !inFlight, undefined];
1816
};

frontend/packages/console-app/src/actions/providers/deployment-provider.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { DeleteResourceAction } from '@console/dev-console/src/actions/context-m
33
import { Action } from '@console/dynamic-plugin-sdk/src';
44
import { DeploymentKind, referenceFor } from '@console/internal/module/k8s';
55
import { useK8sModel } from '@console/shared/src/hooks/useK8sModel';
6-
import { CommonActionFactory } from '../creators/common-factory';
6+
import { useCommonActionFactory } from '../creators/common-factory';
77
import { DeploymentActionFactory } from '../creators/deployment-factory';
88
import { getHealthChecksAction } from '../creators/health-checks-factory';
99
import { useHPAActions } from '../creators/hpa-factory';
@@ -13,26 +13,26 @@ export const useDeploymentActionsProvider = (resource: DeploymentKind) => {
1313
const [kindObj, inFlight] = useK8sModel(referenceFor(resource));
1414
const [hpaActions, relatedHPAs] = useHPAActions(kindObj, resource);
1515
const [pdbActions] = usePDBActions(kindObj, resource);
16-
16+
const actionFactory = useCommonActionFactory();
1717
const deploymentActions = React.useMemo<Action[]>(
1818
() => [
19-
...(relatedHPAs?.length === 0 ? [CommonActionFactory.ModifyCount(kindObj, resource)] : []),
19+
...(relatedHPAs?.length === 0 ? [actionFactory.ModifyCount(kindObj, resource)] : []),
2020
...hpaActions,
2121
...pdbActions,
2222
DeploymentActionFactory.PauseRollout(kindObj, resource),
2323
DeploymentActionFactory.RestartRollout(kindObj, resource),
2424
getHealthChecksAction(kindObj, resource),
25-
CommonActionFactory.AddStorage(kindObj, resource),
25+
actionFactory.AddStorage(kindObj, resource),
2626
DeploymentActionFactory.UpdateStrategy(kindObj, resource),
2727
DeploymentActionFactory.EditResourceLimits(kindObj, resource),
28-
CommonActionFactory.ModifyLabels(kindObj, resource),
29-
CommonActionFactory.ModifyAnnotations(kindObj, resource),
28+
actionFactory.ModifyLabels(kindObj, resource),
29+
actionFactory.ModifyAnnotations(kindObj, resource),
3030
DeploymentActionFactory.EditDeployment(kindObj, resource),
3131
...(resource.metadata.annotations?.['openshift.io/generated-by'] === 'OpenShiftWebConsole'
3232
? [DeleteResourceAction(kindObj, resource)]
33-
: [CommonActionFactory.Delete(kindObj, resource)]),
33+
: [actionFactory.Delete(kindObj, resource)]),
3434
],
35-
[hpaActions, pdbActions, kindObj, relatedHPAs, resource],
35+
[hpaActions, pdbActions, kindObj, relatedHPAs, resource, actionFactory],
3636
);
3737

3838
return [deploymentActions, !inFlight, undefined];

frontend/packages/console-app/src/actions/providers/deploymentconfig-provider.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Action, K8sResourceCommon } from '@console/dynamic-plugin-sdk/src';
66
import { errorModal } from '@console/internal/components/modals';
77
import { DeploymentConfigKind, referenceFor } from '@console/internal/module/k8s';
88
import { useK8sModel } from '@console/shared/src/hooks/useK8sModel';
9-
import { CommonActionFactory } from '../creators/common-factory';
9+
import { useCommonActionFactory } from '../creators/common-factory';
1010
import { DeploymentActionFactory, retryRollout } from '../creators/deployment-factory';
1111
import { getHealthChecksAction } from '../creators/health-checks-factory';
1212
import { useHPAActions } from '../creators/hpa-factory';
@@ -73,27 +73,28 @@ export const useDeploymentConfigActionsProvider = (resource: DeploymentConfigKin
7373
const [hpaActions, relatedHPAs] = useHPAActions(kindObj, resource);
7474
const [pdbActions] = usePDBActions(kindObj, resource);
7575
const retryRolloutAction = useRetryRolloutAction(resource);
76+
const actionFactory = useCommonActionFactory();
7677

7778
const deploymentConfigActions = React.useMemo(() => {
7879
const actions = [
79-
...(relatedHPAs?.length === 0 ? [CommonActionFactory.ModifyCount(kindObj, resource)] : []),
80+
...(relatedHPAs?.length === 0 ? [actionFactory.ModifyCount(kindObj, resource)] : []),
8081
...hpaActions,
8182
...pdbActions,
8283
getHealthChecksAction(kindObj, resource),
8384
DeploymentActionFactory.StartDCRollout(kindObj, resource),
8485
retryRolloutAction,
8586
DeploymentActionFactory.PauseRollout(kindObj, resource),
86-
CommonActionFactory.AddStorage(kindObj, resource),
87+
actionFactory.AddStorage(kindObj, resource),
8788
DeploymentActionFactory.EditResourceLimits(kindObj, resource),
88-
CommonActionFactory.ModifyLabels(kindObj, resource),
89-
CommonActionFactory.ModifyAnnotations(kindObj, resource),
89+
actionFactory.ModifyLabels(kindObj, resource),
90+
actionFactory.ModifyAnnotations(kindObj, resource),
9091
DeploymentActionFactory.EditDeployment(kindObj, resource),
9192
...(resource.metadata.annotations?.['openshift.io/generated-by'] === 'OpenShiftWebConsole'
9293
? [DeleteResourceAction(kindObj, resource)]
93-
: [CommonActionFactory.Delete(kindObj, resource)]),
94+
: [actionFactory.Delete(kindObj, resource)]),
9495
];
9596
return actions;
96-
}, [resource, kindObj, hpaActions, pdbActions, relatedHPAs, retryRolloutAction]);
97+
}, [resource, kindObj, hpaActions, pdbActions, relatedHPAs, retryRolloutAction, actionFactory]);
9798

9899
return [deploymentConfigActions, !inFlight, undefined];
99100
};

0 commit comments

Comments
 (0)