Skip to content

Commit

Permalink
Manage policy
Browse files Browse the repository at this point in the history
Signed-off-by: Gowtham Shanmugasundaram <[email protected]>
  • Loading branch information
GowthamShanmugam committed Jun 6, 2023
1 parent 0a38fb8 commit 720c8dc
Show file tree
Hide file tree
Showing 22 changed files with 1,209 additions and 29 deletions.
14 changes: 13 additions & 1 deletion locales/en/plugin__odf-console.json
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,17 @@
"{{selected}} of {{total}} selected": "{{selected}} of {{total}} selected",
"subscription-selector": "subscription-selector",
"Select the subscriptions groups you wish to replicate via": "Select the subscriptions groups you wish to replicate via",
"Manage Policy": "Manage Policy",
"Assign policy to protect the application and ensure quick recovery. Unassign policy from an application when they no longer require to be managed.": "Assign policy to protect the application and ensure quick recovery. Unassign policy from an application when they no longer require to be managed.",
"Policy type": "Policy type",
"Assigned on": "Assigned on",
"View configurations": "View configurations",
"Unassign policy": "Unassign policy",
"My policies": "My policies",
"Assign policy": "Assign policy",
"New policy assigned to the application": "New policy assigned to the application",
"{{ currentStatus }}": "{{ currentStatus }}",
"No activity": "No activity",
"List all the connected applications under a policy.": "List all the connected applications under a policy.",
"Application name": "Application name",
"application name search": "application name search",
Expand Down Expand Up @@ -816,7 +827,6 @@
"BackingStore details": "BackingStore details",
"Tiers": "Tiers",
"Placement": "Placement",
"Policy type": "Policy type",
"Namespace Policy": "Namespace Policy",
"BucketClass details": "BucketClass details",
"Edit Bucket Class Resources": "Edit Bucket Class Resources",
Expand Down Expand Up @@ -917,6 +927,7 @@
"min": "min",
"Select at least 2 Backing Store resources": "Select at least 2 Backing Store resources",
"Select at least 1 Backing Store resource": "Select at least 1 Backing Store resource",
"Actions": "Actions",
"No {{alertSeverity}} alerts found": "No {{alertSeverity}} alerts found",
"This is an Advanced subscription feature. It requires Advanced Edition subscription. Please contact the account team for more information.": "This is an Advanced subscription feature. It requires Advanced Edition subscription. Please contact the account team for more information.",
"Advanced Subscription": "Advanced Subscription",
Expand Down Expand Up @@ -1027,6 +1038,7 @@
"Subscription": "Subscription",
"Subscriptions": "Subscriptions",
"Project": "Project",
"No rows found": "No rows found",
"Metrics": "Metrics",
"CPU usage": "CPU usage",
"Receive bandwidth": "Receive bandwidth",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ import {
} from '../../../hooks';
import { DRPolicyModel } from '../../../models';
import { DRPolicyKind } from '../../../types';
import { getReplicationType, findAppsUsingDRPolicy } from '../../../utils';
import {
getReplicationType,
findAppsUsingDRPolicy,
isDRPolicyValidated,
} from '../../../utils';
import EmptyPage from '../../empty-state-page/empty-page';
import { ConnectedApplicationsModal } from '../../modals/connected-apps-modal/connected-apps-modal';
import {
Expand Down Expand Up @@ -60,9 +64,6 @@ const DRPolicyRow: React.FC<RowProps<DRPolicyKind, RowData>> = ({
const clusterNames = obj?.spec?.drClusters?.map((clusterName) => (
<p key={clusterName}> {clusterName} </p>
));
const condition = obj?.status?.conditions?.find(
(statusCondition) => statusCondition.type === 'Validated'
);
const filteredApps = findAppsUsingDRPolicy(applicationRefs, obj);
const appCount = filteredApps?.length;

Expand All @@ -77,7 +78,7 @@ const DRPolicyRow: React.FC<RowProps<DRPolicyKind, RowData>> = ({
{obj?.metadata?.name}
</TableData>
<TableData {...tableColumnInfo[1]} activeColumnIDs={activeColumnIDs}>
{condition?.status === 'True' ? t('Validated') : t('Not Validated')}
{isDRPolicyValidated(obj) ? t('Validated') : t('Not Validated')}
</TableData>
<TableData {...tableColumnInfo[2]} activeColumnIDs={activeColumnIDs}>
{clusterNames}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as React from 'react';
import { referenceForModel } from '@odf/shared/utils';
import { ArgoApplicationSetModel } from '../../../models';
import { ArgoApplicationSetKind, ACMActionCallbackType } from '../../../types';
import { getGVKFromK8Resource } from '../../../utils';
import { ApplicationSetModal } from './parsers/application-set-parser';

export const AppManageDataPolicy = (props: ACMActionCallbackType) => {
const { resource, close, isOpen } = props;
const gvk = getGVKFromK8Resource(resource);

return (
<>
{gvk === referenceForModel(ArgoApplicationSetModel) && (
<ApplicationSetModal
application={resource as ArgoApplicationSetKind}
isOpen={isOpen}
close={close}
/>
)}
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import * as React from 'react';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import { Modal, ModalVariant } from '@patternfly/react-core';
import { ModalHeader } from './helpers/modal-header';
import { ModalListView } from './policy-list-view/modal-list-view';
import {
ModalViewContext,
managePolicyState,
managePolicyStateReducer,
} from './utils/reducer';
import { ApplicationType, DRPolicyType } from './utils/types';

export const AppManageDataPolicyModal: React.FC<AppManageDataPolicyModalType> =
(props) => {
const [state, dispatch] = React.useReducer(
managePolicyStateReducer,
managePolicyState()
);
const { applicaitonInfo, isOpen, close } = props;
const { t } = useCustomTranslation();

const modalViewContext = () => {
switch (state.modalViewContext) {
case ModalViewContext.POLICY_LIST_VIEW:
return (
<>
<ModalHeader
title={t('Manage Policy')}
description={t(
'Assign policy to protect the application and ensure quick recovery. Unassign policy from an application when they no longer require to be managed.'
)}
/>
<ModalListView
dataPolicyInfo={applicaitonInfo?.dataPolicies}
state={state}
dispatch={dispatch}
/>
</>
);
case ModalViewContext.ASSIGN_POLICY_VIEW:
return <>ASSIGN_POLICY_VIEW</>;
case ModalViewContext.DISABLE_POLICY_VIEW:
return <>DISABLE_POLICY_VIEW</>;
default:
return <>POLICY_LIST_VIEW</>;
}
};

return (
<React.Fragment>
<Modal
variant={ModalVariant.large}
isOpen={isOpen}
aria-label="Manage policy modal"
aria-describedby="manage-policy-modal"
onClose={close}
hasNoBodyWrapper
>
{modalViewContext()}
</Modal>
</React.Fragment>
);
};

export type AppManageDataPolicyModalType = {
applicaitonInfo: ApplicationType;
matchingDRPolicies: DRPolicyType[];
isOpen: boolean;
close?: () => void;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.mco-modal-box__header {
display: flex;
flex-direction: column;
flex-shrink: 0;
padding-top: var(--pf-global--spacer--lg);
padding-right: var(--pf-global--spacer--lg);
padding-left: var(--pf-global--spacer--lg);
}

.mco-modal-box__description {
padding-top: var(--pf-global--spacer--xs);
}

.mco-modal-box__title {
flex: 0 0 auto;
font-family: var(--pf-global--FontFamily--heading--sans-serif);
font-size: var(--pf-global--FontSize--2xl);
line-height: var(--pf-global--LineHeight--sm);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as React from 'react';
import './modal-header.scss';

export const ModalHeader: React.FC<ModalHeaderType> = (props) => {
const { title, description } = props;

return (
<div className="mco-modal-box__header">
<p
className="mco-modal-box__title"
aria-label={title}
id={'manage-policy-title'}
>
{title}
</p>
<p
className="mco-modal-box__description"
id={'manage-policy-description'}
>
{description}
</p>
</div>
);
};

export type ModalHeaderType = {
title: string;
description?: string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import * as React from 'react';
import {
RowComponentType,
SelectableTable,
} from '@odf/shared/selectable-table/selectable-table';
import { TableRowType } from '@odf/shared/selectable-table/selectable-table';
import {
GreenCheckCircleIcon,
RedExclamationCircleIcon,
} from '@odf/shared/status/icons';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import { StatusIconAndText } from '@openshift-console/dynamic-plugin-sdk';
import { TFunction } from 'i18next';
import { ActionsColumn, IAction } from '@patternfly/react-table';
import { Td } from '@patternfly/react-table';
import { formatDateTime } from '../../../../../utils';
import {
ManagePolicyState,
ManagePolicyStateAction,
ManagePolicyStateType,
ModalViewContext,
} from '../utils/reducer';
import { DRPolicyType, DataPolicyType } from '../utils/types';

const filterRowBySearchText = (
rows: TableRowType<DRPolicyType>[],
searchText
) =>
!!searchText
? rows?.filter((row) => row?.data?.drPolicyName?.includes(searchText))
: rows;

const getRow = (dataPolicyInfo: DataPolicyType): TableRowType<DRPolicyType>[] =>
dataPolicyInfo?.drPolicyInfo?.map((policyInfo) => ({
data: policyInfo,
rowId: policyInfo?.drPolicyName,
isDisabled: false,
}));

const getColumns = (t: TFunction) => [
{ columName: t('Policy name'), sortField: 'drPolicyName', sortable: true },
{ columName: t('Policy type'), sortField: 'policyType', sortable: true },
{ columName: t('Status'), sortField: 'isValidated', sortable: true },
{ columName: t('Activity'), sortField: 'activity', sortable: true },
{ columName: t('Assigned on'), sortField: 'assignedOn', sortable: true },
{ columName: '' },
];

const getRange = (currentPage: number, perPage: number) => {
const indexOfLastRow = currentPage * perPage;
const indexOfFirstRow = indexOfLastRow - perPage;
return [indexOfFirstRow, indexOfLastRow];
};

const ModalListViewRow: React.FC<RowComponentType<DRPolicyType>> = (props) => {
const { t } = useCustomTranslation();
const { row, extraProps } = props || {};
const { data } = row || {};
const { dispatch }: RowExtraPropType = extraProps;

const RowActions = (t: TFunction): IAction[] => [
{
title: t('View configurations'),
onClick: () => {},
},
{
title: t('Unassign policy'),
onClick: () => {
dispatch({
type: ManagePolicyStateType.SET_SELECTED_ROW,
payload: row,
});
dispatch({
type: ManagePolicyStateType.SET_MODAL_VIEW_CONTEXT,
payload: ModalViewContext.DISABLE_POLICY_VIEW,
});
},
},
];

return (
<>
<Td translate={null}>{data?.drPolicyName}</Td>
<Td translate={null}>{data?.policyType}</Td>
<Td translate={null}>
{data?.isValidated ? (
<StatusIconAndText
title={t('Validated')}
icon={<GreenCheckCircleIcon />}
/>
) : (
<StatusIconAndText
title={t('Not Validated')}
icon={<RedExclamationCircleIcon />}
/>
)}
</Td>
<Td translate={null}>{data?.activity}</Td>
<Td translate={null}>{formatDateTime(data?.assignedOn)}</Td>
<Td translate={null}>
<ActionsColumn items={RowActions(t)} isDisabled={false} />
</Td>
</>
);
};

export const ModalListViewTable: React.FC<ModalListViewTableType> = (props) => {
const { t } = useCustomTranslation();
const { currentPage, perPage, searchText, dataPolicyInfo, state, dispatch } =
props;
const [start, end] = getRange(currentPage, perPage);
const rows = filterRowBySearchText(getRow(dataPolicyInfo), searchText);
const paginatedRow = rows?.slice(start, end);

const setSelectedRows = (selectedRows: TableRowType<DRPolicyType>[]) =>
dispatch({
type: ManagePolicyStateType.SET_SELECTED_ROWS,
payload: selectedRows,
});

return (
<SelectableTable<DRPolicyType>
columns={getColumns(t)}
rows={paginatedRow}
RowComponent={ModalListViewRow}
selectedRows={state.selectedRows}
setSelectedRows={setSelectedRows}
extraProps={{
dispatch: dispatch,
}}
/>
);
};

type RowExtraPropType = {
dispatch: React.Dispatch<ManagePolicyStateAction>;
};

type ModalListViewTableType = RowExtraPropType & {
currentPage: number;
perPage: number;
searchText: string;
dataPolicyInfo: DataPolicyType;
state: ManagePolicyState;
dispatch: React.Dispatch<ManagePolicyStateAction>;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.mco-modal-col-padding {
padding: 0 3rem 0 1rem;
}

.mco-modal-box__body {
flex: 1 1 auto;
min-height: calc(var(--pf-global--FontSize--md) * var(--pf-global--LineHeight--md));
padding-top: var(--pf-global--spacer--lg);
padding-right: var(--pf-global--spacer--lg);
padding-left: var(--pf-global--spacer--lg);
padding-bottom: var(--pf-global--spacer--lg);
overflow-x: hidden;
overflow-y: auto;
overscroll-behavior: contain;
word-break: break-word;
-webkit-overflow-scrolling: touch;
}
Loading

0 comments on commit 720c8dc

Please sign in to comment.