Skip to content

Commit 4728f57

Browse files
Merge pull request #1856 from GowthamShanmugam/RHSTOR-6968
RHSTOR-6968: Disaster recovery UI for Kubevirt VM - managed application
2 parents 217ddda + dd2a94a commit 4728f57

25 files changed

+693
-353
lines changed

locales/en/plugin__odf-console.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@
342342
"Select the subscriptions groups you wish to replicate via": "Select the subscriptions groups you wish to replicate via",
343343
"Enroll managed application": "Enroll managed application",
344344
"Manage disaster recovery": "Manage disaster recovery",
345-
"<0>Application:</0> {getName(applicationInfo)} (Namespace: {getNamespace(applicationInfo)})": "<0>Application:</0> {getName(applicationInfo)} (Namespace: {getNamespace(applicationInfo)})",
345+
"<0>Application:</0> {applicationName} (Namespace: {applicationNamespace})": "<0>Application:</0> {applicationName} (Namespace: {applicationNamespace})",
346346
"Assign policy nav": "Assign policy nav",
347347
"Assign policy content": "Assign policy content",
348348
"Labels must start and end with an alphanumeric character, can consist of lower-case letters, numbers, dots (.), hyphens (-), forward slash (/), underscore(_) and equal to (=)": "Labels must start and end with an alphanumeric character, can consist of lower-case letters, numbers, dots (.), hyphens (-), forward slash (/), underscore(_) and equal to (=)",

packages/mco/components/modals/app-manage-policies/acm-action-callback.tsx

-42
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import * as React from 'react';
2+
import { ArgoApplicationSetModel, VirtualMachineModel } from '@odf/mco/models';
3+
import { ApplicationModel } from '@odf/shared/models';
4+
import { getGVKofResource, referenceForModel } from '@odf/shared/utils';
5+
import { K8sResourceCommon } from '@openshift-console/dynamic-plugin-sdk';
6+
import {
7+
ApplicationSetParser,
8+
SubscriptionParser,
9+
VirtualMachineParser,
10+
} from './parsers';
11+
import { ModalViewContext } from './utils/reducer';
12+
13+
const ComponentMap = {
14+
[referenceForModel(ArgoApplicationSetModel)]: ApplicationSetParser,
15+
[referenceForModel(ApplicationModel)]: SubscriptionParser,
16+
[referenceForModel(VirtualMachineModel)]: VirtualMachineParser,
17+
};
18+
19+
export const AppManagePoliciesModalBody: React.FC<
20+
AppManagePoliciesModalBodyProps
21+
> = ({ application, cluster, setCurrentModalContext }) => {
22+
const gvk = getGVKofResource(application);
23+
const SelectedComponent = ComponentMap[gvk];
24+
25+
return SelectedComponent ? (
26+
<SelectedComponent
27+
application={application as any}
28+
cluster={cluster}
29+
setCurrentModalContext={setCurrentModalContext}
30+
/>
31+
) : null;
32+
};
33+
34+
type AppManagePoliciesModalBodyProps = {
35+
application: K8sResourceCommon;
36+
cluster?: string;
37+
setCurrentModalContext: React.Dispatch<
38+
React.SetStateAction<ModalViewContext>
39+
>;
40+
};
Original file line numberDiff line numberDiff line change
@@ -1,144 +1,70 @@
11
import * as React from 'react';
2-
import { DRApplication } from '@odf/mco/constants';
2+
import { SearchResultItemType } from '@odf/mco/types';
3+
import { convertSearchResult } from '@odf/mco/utils';
34
import { getName, getNamespace } from '@odf/shared/selectors';
45
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
6+
import { K8sResourceCommon } from '@openshift-console/dynamic-plugin-sdk';
57
import { Trans } from 'react-i18next';
68
import { Modal, ModalVariant } from '@patternfly/react-core';
7-
import { AssignPolicyView } from './assign-policy-view';
8-
import { ManagePolicyView } from './manage-policy-view';
9-
import {
10-
ManagePolicyStateAction,
11-
ManagePolicyStateType,
12-
ModalActionContext,
13-
ModalViewContext,
14-
initialPolicyState,
15-
managePolicyStateReducer,
16-
ManagePolicyState,
17-
} from './utils/reducer';
18-
import { ApplicationType, DRInfoType, DRPolicyType } from './utils/types';
9+
import { AppManagePoliciesModalBody } from './app-manage-policies-modal-body';
10+
import { ModalViewContext } from './utils/reducer';
1911

20-
export const ModalContextViewer: React.FC<ModalContextViewerProps> = ({
21-
applicationInfo,
22-
state,
23-
matchingPolicies,
24-
dispatch,
25-
loaded,
26-
loadError,
12+
export const AppManagePoliciesModal: React.FC<AppManagePoliciesModalProps> = ({
13+
resource,
14+
cluster,
15+
isOpen,
16+
close,
2717
}) => {
28-
const setModalContext = React.useCallback(
29-
(modalViewContext: ModalViewContext) =>
30-
dispatch({
31-
type: ManagePolicyStateType.SET_MODAL_VIEW_CONTEXT,
32-
payload: modalViewContext,
33-
}),
34-
[dispatch]
18+
const { t } = useCustomTranslation();
19+
const [currentModalContext, setCurrentModalContext] = React.useState(
20+
ModalViewContext.MANAGE_POLICY_VIEW
3521
);
3622

37-
const setModalActionContext = React.useCallback(
38-
(modalActionContext: ModalActionContext) =>
39-
dispatch({
40-
type: ManagePolicyStateType.SET_MODAL_ACTION_CONTEXT,
41-
payload: modalActionContext,
42-
}),
43-
[dispatch]
44-
);
23+
const application =
24+
'apigroup' in resource ? convertSearchResult(resource) : resource;
25+
const applicationName = getName(application) ?? application?.['name'];
26+
const applicationNamespace =
27+
getNamespace(application) ?? application?.['namespace'];
4528

46-
return (
47-
<>
48-
{state.modalViewContext === ModalViewContext.MANAGE_POLICY_VIEW && (
49-
<ManagePolicyView
50-
drInfo={applicationInfo?.drInfo as DRInfoType}
51-
workloadNamespace={applicationInfo?.workloadNamespace}
52-
eligiblePolicies={matchingPolicies}
53-
isSubscriptionAppType={
54-
applicationInfo?.type === DRApplication.SUBSCRIPTION
55-
}
56-
unProtectedPlacementCount={applicationInfo?.placements?.length}
57-
dispatch={dispatch}
58-
setModalContext={setModalContext}
59-
setModalActionContext={setModalActionContext}
60-
loaded={loaded}
61-
loadError={loadError}
62-
modalActionContext={state.modalActionContext}
63-
/>
64-
)}
65-
{state.modalViewContext === ModalViewContext.ASSIGN_POLICY_VIEW && (
66-
<AssignPolicyView
67-
applicationInfo={applicationInfo}
68-
matchingPolicies={matchingPolicies}
69-
state={state.assignPolicyView}
70-
modalActionContext={state.modalActionContext}
71-
dispatch={dispatch}
72-
setModalContext={setModalContext}
73-
setModalActionContext={setModalActionContext}
74-
/>
75-
)}
76-
</>
77-
);
78-
};
29+
const title =
30+
currentModalContext === ModalViewContext.ASSIGN_POLICY_VIEW
31+
? t('Enroll managed application')
32+
: t('Manage disaster recovery');
7933

80-
export const AppManagePoliciesModal: React.FC<AppManagePoliciesModalProps> = ({
81-
applicationInfo,
82-
matchingPolicies,
83-
loaded,
84-
loadError,
85-
isOpen,
86-
close,
87-
}) => {
88-
const [state, dispatch] = React.useReducer(
89-
managePolicyStateReducer,
90-
initialPolicyState
34+
const description = (
35+
<Trans t={t}>
36+
<strong>Application:</strong> {applicationName} (Namespace:{' '}
37+
{applicationNamespace})
38+
</Trans>
9139
);
92-
const { t } = useCustomTranslation();
9340

9441
return (
9542
<Modal
96-
title={
97-
state.modalViewContext === ModalViewContext.ASSIGN_POLICY_VIEW
98-
? t('Enroll managed application')
99-
: t('Manage disaster recovery')
100-
}
101-
description={
102-
loaded &&
103-
!loadError && (
104-
<Trans t={t}>
105-
<strong>Application:</strong> {getName(applicationInfo)} (Namespace:{' '}
106-
{getNamespace(applicationInfo)})
107-
</Trans>
108-
)
109-
}
43+
title={title}
44+
description={description}
11045
variant={ModalVariant.large}
11146
isOpen={isOpen}
11247
aria-label="Manage policy modal"
11348
aria-describedby="manage-policy-modal"
11449
onClose={close}
11550
>
116-
<ModalContextViewer
117-
applicationInfo={applicationInfo}
118-
matchingPolicies={matchingPolicies}
119-
state={state}
120-
dispatch={dispatch}
121-
loaded={loaded}
122-
loadError={loadError}
51+
<AppManagePoliciesModalBody
52+
application={application}
53+
cluster={cluster}
54+
setCurrentModalContext={setCurrentModalContext}
12355
/>
12456
</Modal>
12557
);
12658
};
12759

60+
// ACM action custom plugin callback,
61+
// For more: https://github.com/stolostron/console/blob/main/frontend/src/plugin-extensions/properties/actionExtensionProps.ts#L27
12862
type AppManagePoliciesModalProps = {
129-
applicationInfo: ApplicationType;
130-
matchingPolicies: DRPolicyType[];
131-
loaded: boolean;
132-
loadError: any;
63+
resource: K8sResourceCommon | SearchResultItemType;
13364
isOpen: boolean;
134-
close?: () => void;
65+
close: () => void;
66+
// Specific field for the ACM VM list page
67+
cluster?: string;
13568
};
13669

137-
type ModalContextViewerProps = {
138-
state: ManagePolicyState;
139-
applicationInfo: ApplicationType;
140-
matchingPolicies: DRPolicyType[];
141-
dispatch: React.Dispatch<ManagePolicyStateAction>;
142-
loaded: boolean;
143-
loadError: any;
144-
};
70+
export default AppManagePoliciesModal;

packages/mco/components/modals/app-manage-policies/assign-policy-view.tsx

+5-4
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ import {
2828
DRInfoType,
2929
DRPolicyType,
3030
PlacementType,
31+
PVCQueryFilter,
3132
} from './utils/types';
3233

3334
export const createSteps = (
3435
appType: DRApplication,
35-
workloadNamespace: string,
3636
unProtectedPlacements: PlacementType[],
3737
matchingPolicies: DRPolicyType[],
3838
state: AssignPolicyViewState,
@@ -41,6 +41,7 @@ export const createSteps = (
4141
t: TFunction,
4242
dispatch: React.Dispatch<ManagePolicyStateAction>,
4343
protectedPVCSelectors: PVCSelectorType[],
44+
pvcQueryFilter: PVCQueryFilter,
4445
isEditMode?: boolean
4546
): WizardStep[] => {
4647
const commonSteps = {
@@ -61,10 +62,10 @@ export const createSteps = (
6162
<PVCDetailsWizardContent
6263
pvcSelectors={state.persistentVolumeClaim.pvcSelectors}
6364
unProtectedPlacements={unProtectedPlacements}
64-
workloadNamespace={workloadNamespace}
6565
isValidationEnabled={isValidationEnabled}
6666
dispatch={dispatch}
6767
protectedPVCSelectors={protectedPVCSelectors}
68+
pvcQueryFilter={pvcQueryFilter}
6869
/>
6970
),
7071
},
@@ -130,9 +131,9 @@ export const AssignPolicyView: React.FC<AssignPolicyViewProps> = ({
130131

131132
const {
132133
type: appType,
133-
workloadNamespace,
134134
placements: unProtectedPlacements,
135135
drInfo,
136+
pvcQueryFilter,
136137
} = applicationInfo;
137138

138139
const protectedPVCSelectors: PVCSelectorType[] = isEditMode
@@ -179,7 +180,6 @@ export const AssignPolicyView: React.FC<AssignPolicyViewProps> = ({
179180
mainAriaLabel={t('Assign policy content')}
180181
steps={createSteps(
181182
appType,
182-
workloadNamespace,
183183
unProtectedPlacements,
184184
matchingPolicies,
185185
state,
@@ -188,6 +188,7 @@ export const AssignPolicyView: React.FC<AssignPolicyViewProps> = ({
188188
t,
189189
dispatch,
190190
protectedPVCSelectors,
191+
pvcQueryFilter,
191192
isEditMode
192193
)}
193194
footer={

0 commit comments

Comments
 (0)