Skip to content

Commit

Permalink
feat: Align configuration pages into one flow, create ConfigurationBo…
Browse files Browse the repository at this point in the history
…dy component for creating configuration pages (#26)

Jira: EPMDEDP-12447
Resolves: #26
Change-Id: Ibde75a337ab4d48e534ac4b9a8d2d22324ccdf77
  • Loading branch information
callmevladik committed Aug 22, 2023
1 parent 549fb5f commit daa8bfb
Show file tree
Hide file tree
Showing 9 changed files with 484 additions and 884 deletions.
141 changes: 141 additions & 0 deletions src/pages/edp-configuration/components/ConfigurationBody/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import { Icon } from '@iconify/react';
import { EmptyContent } from '@kinvolk/headlamp-plugin/lib/CommonComponents';
import {
Accordion,
AccordionDetails,
AccordionSummary,
Grid,
Link,
Tooltip,
Typography,
} from '@material-ui/core';
import React from 'react';
import { CreateItemAccordion } from '../../../../components/CreateItemAccordion';
import { PageWithSubMenu } from '../../../../components/PageWithSubMenu';
import { PageWrapper } from '../../../../components/PageWrapper';
import { Render } from '../../../../components/Render';
import { ICONS } from '../../../../icons/iconify-icons-mapping';
import { menu } from '../../menu';
import { ConfigurationBodyProps } from './types';

export const ConfigurationBody = ({
pageData,
renderPlaceHolderData,
items,
emptyMessage,
}: ConfigurationBodyProps) => {
const { label, description, docUrl } = pageData;
const [expandedPanel, setExpandedPanel] = React.useState<string>(null);

const handleChange = (panel: string) => (event: React.SyntheticEvent, isExpanded: boolean) => {
setExpandedPanel(isExpanded ? panel : null);
};

const handleClosePlaceholder = () => {
setExpandedPanel(null);
};

const placeholderData = React.useMemo(
() => renderPlaceHolderData({ handleClosePlaceholder }),
[renderPlaceHolderData]
);

return (
<PageWithSubMenu list={menu}>
<PageWrapper containerMaxWidth={'lg'}>
<Grid container spacing={3}>
<Grid item xs={12}>
<Typography variant={'h5'} gutterBottom>
{label}
</Typography>
<Typography variant={'body1'}>
{description}{' '}
<Link href={docUrl} target={'_blank'}>
<Typography variant={'body2'} component={'span'}>
Learn more.
</Typography>
</Link>
</Typography>
</Grid>
<Grid item xs={12}>
<CreateItemAccordion
isExpanded={expandedPanel === 'placeholder'}
onChange={handleChange('placeholder')}
disabled={placeholderData.disabled}
title={placeholderData.title}
>
<Grid container spacing={2}>
<Grid item xs={12}>
{placeholderData.component}
</Grid>
</Grid>
</CreateItemAccordion>
</Grid>
<Grid item xs={12}>
<Grid container spacing={2}>
{items && items.length ? (
items.map(configurationItem => {
const key = configurationItem?.id;
const ownerReference = configurationItem?.ownerReference;

return (
<Grid item xs={12} key={key}>
<Accordion
expanded={expandedPanel === key}
onChange={handleChange(key)}
>
<AccordionSummary
expandIcon={<Icon icon={ICONS.ARROW_DOWN} />}
>
<Grid
container
spacing={3}
alignItems={'center'}
>
<Grid item>
<Typography variant={'h6'}>
{configurationItem.title}
</Typography>
</Grid>
<Render condition={!!ownerReference}>
<Grid item>
<Tooltip
title={`Managed by ${ownerReference}`}
>
<Icon
icon={ICONS.CLOUD_LOCK}
width={20}
style={{
display: 'block',
}}
/>
</Tooltip>
</Grid>
</Render>
</Grid>
</AccordionSummary>
<AccordionDetails>
<Grid container spacing={2}>
<Grid item xs={12}>
{configurationItem.component}
</Grid>
</Grid>
</AccordionDetails>
</Accordion>
</Grid>
);
})
) : (
<Grid item xs={12}>
<EmptyContent color={'textSecondary'}>
{emptyMessage}
</EmptyContent>
</Grid>
)}
</Grid>
</Grid>
</Grid>
</PageWrapper>
</PageWithSubMenu>
);
};
24 changes: 24 additions & 0 deletions src/pages/edp-configuration/components/ConfigurationBody/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';

export interface ConfigurationItem {
title: string;
component: React.ReactElement;
id?: string;
ownerReference?: string;
disabled?: boolean;
}

export interface ConfigurationBodyProps {
pageData: {
label: string;
description: string;
docUrl?: string;
};
renderPlaceHolderData: ({
handleClosePlaceholder,
}: {
handleClosePlaceholder: () => void;
}) => ConfigurationItem;
items: ConfigurationItem[];
emptyMessage: string;
}
172 changes: 42 additions & 130 deletions src/pages/edp-configuration/pages/edp-cluster-list/view.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,10 @@
import { Icon } from '@iconify/react';
import { EmptyContent } from '@kinvolk/headlamp-plugin/lib/CommonComponents';
import {
Accordion,
AccordionDetails,
AccordionSummary,
Grid,
Link,
Tooltip,
Typography,
} from '@material-ui/core';
import React from 'react';
import { CreateItemAccordion } from '../../../../components/CreateItemAccordion';
import { PageWithSubMenu } from '../../../../components/PageWithSubMenu';
import { PageWrapper } from '../../../../components/PageWrapper';
import { Render } from '../../../../components/Render';
import { EDP_USER_GUIDE } from '../../../../constants/urls';
import { ICONS } from '../../../../icons/iconify-icons-mapping';
import { SecretKubeObject } from '../../../../k8s/Secret';
import { ARGO_CD_SECRET_LABEL_SECRET_TYPE } from '../../../../k8s/Secret/labels';
import { getDefaultNamespace } from '../../../../utils/getDefaultNamespace';
import { ManageClusterSecret } from '../../../../widgets/ManageClusterSecret';
import { menu } from '../../menu';
import { ConfigurationBody } from '../../components/ConfigurationBody';
import { CLUSTER_LIST_PAGE_DESCRIPTION } from './constants';

export const PageView = () => {
Expand All @@ -29,122 +13,50 @@ export const PageView = () => {
labelSelector: `${ARGO_CD_SECRET_LABEL_SECRET_TYPE}=cluster`,
});

const [expandedPanel, setExpandedPanel] = React.useState<string>(null);
const secretsArray = React.useMemo(() => (items ? items.filter(Boolean) : []), [items]);

const handleChange = (panel: string) => (event: React.SyntheticEvent, isExpanded: boolean) => {
setExpandedPanel(isExpanded ? panel : null);
};
const configurationItemList = React.useMemo(
() =>
secretsArray.map(el => {
const ownerReference = el?.metadata?.ownerReferences?.[0].kind;

const handleClosePlaceholder = () => {
setExpandedPanel(null);
};
return {
id: el?.metadata?.name || el?.metadata?.uid,
title: el?.metadata.name,
ownerReference,
component: (
<ManageClusterSecret
formData={{
currentElement: el,
isReadOnly: true,
}}
/>
),
};
}),
[secretsArray]
);

return (
<PageWithSubMenu list={menu}>
<PageWrapper containerMaxWidth={'lg'}>
<Grid container spacing={3}>
<Grid item xs={12}>
<Typography variant={'h5'} gutterBottom>
{CLUSTER_LIST_PAGE_DESCRIPTION.label}
</Typography>
<Typography variant={'body1'}>
{CLUSTER_LIST_PAGE_DESCRIPTION.description}{' '}
<Link
href={EDP_USER_GUIDE.MANAGE_CLUSTER.anchors.VIEW_DATA.url}
target={'_blank'}
>
<Typography variant={'body2'} component={'span'}>
Learn more.
</Typography>
</Link>
</Typography>
</Grid>
<Grid item xs={12}>
<CreateItemAccordion
isExpanded={expandedPanel === 'placeholder'}
onChange={handleChange('placeholder')}
title={'Add Cluster'}
>
<Grid container spacing={2}>
<Grid item xs={12}>
<ManageClusterSecret
formData={{
currentElement: 'placeholder',
handleClosePlaceholder,
}}
/>
</Grid>
</Grid>
</CreateItemAccordion>
</Grid>
<Grid item xs={12}>
<Grid container spacing={2}>
{items && items.length ? (
items.map(el => {
const key = el?.metadata?.name || el?.metadata?.uid;
const ownerReference = el?.metadata?.ownerReferences?.[0].kind;

return (
<Grid item xs={12} key={key}>
<Accordion
expanded={expandedPanel === key}
onChange={handleChange(key)}
>
<AccordionSummary
expandIcon={<Icon icon={ICONS.ARROW_DOWN} />}
>
<Grid
container
spacing={3}
alignItems={'center'}
>
<Grid item>
<Typography variant={'h6'}>
{el?.metadata?.name}
</Typography>
</Grid>
<Render condition={!!ownerReference}>
<Grid item>
<Tooltip
title={`Managed by ${ownerReference}`}
>
<Icon
icon={ICONS.CLOUD_LOCK}
width={20}
style={{
display: 'block',
}}
/>
</Tooltip>
</Grid>
</Render>
</Grid>
</AccordionSummary>
<AccordionDetails>
<Grid container spacing={2}>
<Grid item xs={12}>
<ManageClusterSecret
formData={{
currentElement: el,
isReadOnly: true,
}}
/>
</Grid>
</Grid>
</AccordionDetails>
</Accordion>
</Grid>
);
})
) : (
<Grid item xs={12}>
<EmptyContent color={'textSecondary'}>No clusters</EmptyContent>
</Grid>
)}
</Grid>
</Grid>
</Grid>
</PageWrapper>
</PageWithSubMenu>
<ConfigurationBody
pageData={{
label: CLUSTER_LIST_PAGE_DESCRIPTION.label,
description: CLUSTER_LIST_PAGE_DESCRIPTION.description,
docUrl: EDP_USER_GUIDE.MANAGE_CLUSTER.anchors.VIEW_DATA.url,
}}
renderPlaceHolderData={({ handleClosePlaceholder }) => ({
title: 'Add Cluster',
component: (
<ManageClusterSecret
formData={{
currentElement: 'placeholder',
handleClosePlaceholder,
}}
/>
),
})}
items={configurationItemList}
emptyMessage={'No Cluster secrets found'}
/>
);
};
Loading

0 comments on commit daa8bfb

Please sign in to comment.