Skip to content

Commit

Permalink
Merge pull request #1100 from GowthamShanmugam/RHSTOR-4922-part-2
Browse files Browse the repository at this point in the history
Modified wizard flow with 4.15 specific changes
  • Loading branch information
openshift-merge-bot[bot] authored Nov 27, 2023
2 parents ee80530 + 7a699fc commit 5646fc8
Show file tree
Hide file tree
Showing 21 changed files with 608 additions and 268 deletions.
17 changes: 15 additions & 2 deletions locales/en/plugin__odf-console.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
"Data policies": "Data policies",
"Disaster recovery": "Disaster recovery",
"Validated": "Validated",
"Not Validated": "Not Validated",
"Not validated": "Not validated",
"{{async}}, interval: {{syncInterval}}": "{{async}}, interval: {{syncInterval}}",
"Application": "Application",
"Applications": "Applications",
"DRPolicies": "DRPolicies",
Expand Down Expand Up @@ -245,6 +246,19 @@
"Use PVC label selectors to effortlessly specify the application resources that need protection.": "Use PVC label selectors to effortlessly specify the application resources that need protection.",
"Application resource": "Application resource",
"Add application resource": "Add application resource",
"{{count}} placements_one": "{{count}} placements",
"{{count}} placements_other": "{{count}} placements",
"Data policy": "Data policy",
"Policy name:": "Policy name:",
"Clusters:": "Clusters:",
"Replication type:": "Replication type:",
"Sync interval:": "Sync interval:",
"PVC details": "PVC details",
"Application resource:": "Application resource:",
"PVC label selector:": "PVC label selector:",
"Replication type: {{type}}, Interval: {{interval}}, Clusters: {{clusters}}": "Replication type: {{type}}, Interval: {{interval}}, Clusters: {{clusters}}",
"Replication type: {{type}}, Clusters: {{clusters}}": "Replication type: {{type}}, Clusters: {{clusters}}",
"Status: {{status}}": "Status: {{status}}",
"Select a policy": "Select a policy",
"Search": "Search",
"Search input": "Search input",
Expand Down Expand Up @@ -274,7 +288,6 @@
"Policy": "Policy",
"PersistentVolumeClaim": "PersistentVolumeClaim",
"Review and assign": "Review and assign",
"{{async}}, interval: {{interval}}": "{{async}}, interval: {{interval}}",
"In use: {{targetClusters}}": "In use: {{targetClusters}}",
"Used: {{targetClusters}}": "Used: {{targetClusters}}",
"View documentation": "View documentation",
Expand Down
13 changes: 10 additions & 3 deletions packages/mco/components/drpolicy-list-page/drpolicy-list-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
} from '@openshift-console/dynamic-plugin-sdk';
import { Trans } from 'react-i18next';
import { useHistory, useLocation } from 'react-router';
import { HUB_CLUSTER_NAME } from '../../constants';
import { HUB_CLUSTER_NAME, REPLICATION_TYPE } from '../../constants';
import {
ApplicationRefKind,
getDRPolicyResourceObj,
Expand Down Expand Up @@ -56,6 +56,8 @@ const DRPolicyRow: React.FC<RowProps<DRPolicyKind, RowData>> = ({
));
const filteredApps = findAppsUsingDRPolicy(applicationRefs, obj);
const appCount = filteredApps?.length;
const syncInterval = obj?.spec?.schedulingInterval;
const replicationType = getReplicationType(syncInterval);

const onClick = () => {
openModal(true);
Expand All @@ -68,13 +70,18 @@ const DRPolicyRow: React.FC<RowProps<DRPolicyKind, RowData>> = ({
{obj?.metadata?.name}
</TableData>
<TableData {...tableColumnInfo[1]} activeColumnIDs={activeColumnIDs}>
{isDRPolicyValidated(obj) ? t('Validated') : t('Not Validated')}
{isDRPolicyValidated(obj) ? t('Validated') : t('Not validated')}
</TableData>
<TableData {...tableColumnInfo[2]} activeColumnIDs={activeColumnIDs}>
{clusterNames}
</TableData>
<TableData {...tableColumnInfo[3]} activeColumnIDs={activeColumnIDs}>
{getReplicationType(obj?.spec?.schedulingInterval, t)}
{replicationType === REPLICATION_TYPE.ASYNC
? t('{{async}}, interval: {{syncInterval}}', {
async: REPLICATION_TYPE.ASYNC,
syncInterval,
})
: REPLICATION_TYPE.SYNC}
</TableData>
<TableData {...tableColumnInfo[4]} activeColumnIDs={activeColumnIDs}>
{appCount > 0 ? (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import * as React from 'react';
import { AssignPolicySteps, AssignPolicyStepsNames } from '@odf/mco/constants';
import { createRefFromK8Resource } from '@odf/mco/utils';
import { ModalBody } from '@odf/shared/modals/Modal';
import {
APPLICATION_TYPE,
AssignPolicySteps,
AssignPolicyStepsNames,
} from '@odf/mco/constants';
import { ModalBody } from '@odf/shared/modals';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import { getErrorMessage } from '@odf/shared/utils';
import { TFunction } from 'i18next';
import { Wizard, WizardStep, AlertVariant } from '@patternfly/react-core';
import { AssignPolicyViewFooter } from './helper/assign-policy-view-footer';
import { PolicyConfigViewer } from './helper/policy-config-viewer';
import { PVCDetailsWizardContent } from './helper/pvc-details-wizard-content';
import { ReviewAndAssign } from './helper/review-and-assign';
import { SelectPolicyWizardContent } from './helper/select-policy-wizard-content';
import { assignPromises } from './utils/k8s-utils';
import {
Expand All @@ -21,59 +24,76 @@ import {
} from './utils/reducer';
import {
ApplicationType,
DRPlacementControlType,
DRPolicyType,
DataPolicyType,
PlacementType,
} from './utils/types';

export const createSteps = (
appType: APPLICATION_TYPE,
workloadNamespace: string,
unProtectedPlacements: PlacementType[],
matchingPolicies: DRPolicyType[],
state: AssignPolicyViewState,
stepIdReached: number,
isValidationEnabled: boolean,
t: TFunction,
setPolicy: (policy?: DataPolicyType) => void,
setDRPlacementControls: (
drPlacementControls: DRPlacementControlType[]
) => void
): WizardStep[] => [
{
id: 1,
name: AssignPolicyStepsNames(t)[AssignPolicySteps.Policy],
component: (
<SelectPolicyWizardContent
matchingPolicies={matchingPolicies}
policy={state.policy}
isValidationEnabled={isValidationEnabled}
setPolicy={setPolicy}
/>
),
},
{
id: 2,
name: AssignPolicyStepsNames(t)[AssignPolicySteps.PersistentVolumeClaim],
component: (
<PVCDetailsWizardContent
placementControInfo={state.policy?.placementControlInfo}
unProtectedPlacements={unProtectedPlacements}
workloadNamespace={workloadNamespace}
isValidationEnabled={isValidationEnabled}
policyRef={createRefFromK8Resource(state.policy)}
setDRPlacementControls={setDRPlacementControls}
/>
),
canJumpTo: stepIdReached >= 2,
},
{
id: 3,
name: AssignPolicyStepsNames(t)[AssignPolicySteps.ReviewAndAssign],
component: <PolicyConfigViewer policy={state.policy} hideSelector={true} />,
canJumpTo: stepIdReached >= 3,
},
];
dispatch: React.Dispatch<ManagePolicyStateAction>
): WizardStep[] => {
const commonSteps = {
policy: {
name: AssignPolicyStepsNames(t)[AssignPolicySteps.Policy],
component: (
<SelectPolicyWizardContent
matchingPolicies={matchingPolicies}
policy={state.policy}
isValidationEnabled={isValidationEnabled}
dispatch={dispatch}
/>
),
},
persistentVolumeClaim: {
name: AssignPolicyStepsNames(t)[AssignPolicySteps.PersistentVolumeClaim],
component: (
<PVCDetailsWizardContent
pvcSelectors={state.persistentVolumeClaim.pvcSelectors}
unProtectedPlacements={unProtectedPlacements}
workloadNamespace={workloadNamespace}
isValidationEnabled={isValidationEnabled}
dispatch={dispatch}
/>
),
},
reviewAndAssign: {
name: AssignPolicyStepsNames(t)[AssignPolicySteps.ReviewAndAssign],
component: <ReviewAndAssign state={state} />,
},
};

switch (appType) {
case APPLICATION_TYPE.APPSET:
case APPLICATION_TYPE.SUBSCRIPTION:
return [
{
id: 1,
...commonSteps.policy,
canJumpTo: stepIdReached >= 1,
},
{
id: 2,
...commonSteps.persistentVolumeClaim,
canJumpTo: stepIdReached >= 2,
},
{
id: 3,
...commonSteps.reviewAndAssign,
canJumpTo: stepIdReached >= 3,
},
];
default:
return [];
}
};

export const AssignPolicyView: React.FC<AssignPolicyViewProps> = ({
state,
Expand All @@ -88,20 +108,12 @@ export const AssignPolicyView: React.FC<AssignPolicyViewProps> = ({
const [stepIdReached, setStepIdReached] = React.useState(1);
const [isValidationEnabled, setIsValidationEnabled] = React.useState(false);

const setPolicy = (policy: DataPolicyType = null) =>
dispatch({
type: ManagePolicyStateType.SET_SELECTED_POLICY,
context: ModalViewContext.ASSIGN_POLICY_VIEW,
payload: policy,
});
const { type: appType, workloadNamespace, placements } = applicaitonInfo;

const setDRPlacementControls = (
drPlacementControls: DRPlacementControlType[]
) =>
const resetAssignState = () =>
dispatch({
type: ManagePolicyStateType.SET_PLACEMENT_CONTROLS,
type: ManagePolicyStateType.RESET_ASSIGN_POLICY_STATE,
context: ModalViewContext.ASSIGN_POLICY_VIEW,
payload: drPlacementControls,
});

const onSubmit = async () => {
Expand All @@ -123,11 +135,11 @@ export const AssignPolicyView: React.FC<AssignPolicyViewProps> = ({
setModalActionContext(actionContext, ModalViewContext.POLICY_LIST_VIEW);
// switch to list policy view
setModalContext(ModalViewContext.POLICY_LIST_VIEW);
// reset policy info
setPolicy();
// reset info
resetAssignState();
};
// assign DRPolicy
const promises = assignPromises(state.policy);
const promises = assignPromises(state, applicaitonInfo.placements);
await Promise.all(promises)
.then(() => {
updateContext(
Expand All @@ -149,8 +161,8 @@ export const AssignPolicyView: React.FC<AssignPolicyViewProps> = ({

const onClose = () => {
setModalContext(ModalViewContext.POLICY_LIST_VIEW);
// reset policy info
setPolicy();
// reset info
resetAssignState();
};

return (
Expand All @@ -159,19 +171,20 @@ export const AssignPolicyView: React.FC<AssignPolicyViewProps> = ({
navAriaLabel={t('Assign policy nav')}
mainAriaLabel={t('Assign policy content')}
steps={createSteps(
applicaitonInfo.workloadNamespace,
applicaitonInfo.placements,
appType,
workloadNamespace,
placements,
matchingPolicies,
state,
stepIdReached,
isValidationEnabled,
t,
setPolicy,
setDRPlacementControls
dispatch
)}
footer={
<AssignPolicyViewFooter
dataPolicy={state.policy}
state={state}
appType={appType}
stepIdReached={stepIdReached}
isValidationEnabled={isValidationEnabled}
setStepIdReached={setStepIdReached}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import * as React from 'react';
import { AssignPolicySteps, AssignPolicyStepsNames } from '@odf/mco/constants';
import {
APPLICATION_TYPE,
AssignPolicySteps,
AssignPolicyStepsNames,
} from '@odf/mco/constants';
import { getName } from '@odf/shared/selectors';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import { TFunction } from 'i18next';
Expand All @@ -11,33 +15,34 @@ import {
Alert,
AlertVariant,
} from '@patternfly/react-core';
import { DRPolicyType, DataPolicyType } from '../utils/types';
import { AssignPolicyViewState, PVCSelectorType } from '../utils/reducer';
import { DRPolicyType } from '../utils/types';
import '../../../../style.scss';
import '../style.scss';

const isPVCSelectorFound = (dataPolicy: DRPolicyType) =>
!!dataPolicy?.placementControlInfo?.length &&
!!dataPolicy.placementControlInfo.every((drpc) => !!drpc.pvcSelector?.length);
const isPVCSelectorFound = (pvcSelectors: PVCSelectorType[]) =>
!!pvcSelectors.length &&
!!pvcSelectors.every((pvcSelector) => !!pvcSelector.labels?.length);

const isDRPolicySelected = (dataPolicy: DRPolicyType) => !!getName(dataPolicy);

const canJumpToNextStep = (
stepName: string,
dataPolicy: DataPolicyType,
state: AssignPolicyViewState,
t: TFunction
) => {
switch (stepName) {
case AssignPolicyStepsNames(t)[AssignPolicySteps.Policy]:
return isDRPolicySelected(dataPolicy);
return isDRPolicySelected(state.policy);
case AssignPolicyStepsNames(t)[AssignPolicySteps.PersistentVolumeClaim]:
return isPVCSelectorFound(dataPolicy);
return isPVCSelectorFound(state.persistentVolumeClaim.pvcSelectors);
default:
return false;
}
};

export const AssignPolicyViewFooter: React.FC<AssignPolicyViewFooterProps> = ({
dataPolicy,
state,
stepIdReached,
isValidationEnabled,
setStepIdReached,
Expand All @@ -53,7 +58,7 @@ export const AssignPolicyViewFooter: React.FC<AssignPolicyViewFooterProps> = ({
const stepId = activeStep.id as number;
const stepName = activeStep.name as string;

const canJumpToNext = canJumpToNextStep(stepName, dataPolicy, t);
const canJumpToNext = canJumpToNextStep(stepName, state, t);
const validationError = isValidationEnabled && !canJumpToNext;

const moveToNextStep = () => {
Expand Down Expand Up @@ -127,7 +132,8 @@ export const AssignPolicyViewFooter: React.FC<AssignPolicyViewFooterProps> = ({
};

type AssignPolicyViewFooterProps = {
dataPolicy: DataPolicyType;
state: AssignPolicyViewState;
appType: APPLICATION_TYPE;
stepIdReached: number;
isValidationEnabled: boolean;
setStepIdReached: React.Dispatch<React.SetStateAction<number>>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const DataPolicyStatus: React.FC<DataPolicyStatusProps> = ({
{...(isValidated
? { title: t('Validated'), icon: <GreenCheckCircleIcon /> }
: {
title: t('Not Validated'),
title: t('Not validated'),
icon: <RedExclamationCircleIcon />,
})}
/>
Expand Down Expand Up @@ -199,7 +199,7 @@ export const PolicyConfigViewer: React.FC<PolicyConfigViewerProps> = ({
)}
<DescriptionListItem
term={t('PVC label selector')}
description={<Labels numLabels={3} labels={labels} />}
description={<Labels numLabels={5} labels={labels} />}
/>
</DescriptionList>
</div>
Expand Down
Loading

0 comments on commit 5646fc8

Please sign in to comment.