Skip to content

Commit

Permalink
NCL-8130 Implement Group Config Build Configs edit page
Browse files Browse the repository at this point in the history
  • Loading branch information
patrikk0123 committed Dec 6, 2023
1 parent 6990060 commit af60680
Show file tree
Hide file tree
Showing 4 changed files with 268 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/AppRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { DemoPage } from 'components/DemoPage/DemoPage';
import { ErrorPage } from 'components/ErrorPage/ErrorPage';
import { GroupBuildDetailPage } from 'components/GroupBuildDetailPage/GroupBuildDetailPage';
import { GroupBuildsPage } from 'components/GroupBuildsPage/GroupBuildsPage';
import { GroupConfigBuildConfigsEditPage } from 'components/GroupConfigBuildConfigsEditPage/GroupConfigBuildConfigsEditPage';
import { GroupConfigDetailPage } from 'components/GroupConfigDetailPage/GroupConfigDetailPage';
import { GroupConfigsPage } from 'components/GroupConfigsPage/GroupConfigsPage';
import { KeycloakStatusPage } from 'components/KeycloakStatusPage/KeycloakStatusPage';
Expand Down Expand Up @@ -237,7 +238,17 @@ export const AppRoutes = (
</Route>
<Route path="group-configs">
<Route index element={<GroupConfigsPage />} />
<Route path=":groupConfigId" element={<GroupConfigDetailPage />} />
<Route path=":groupConfigId">
<Route index element={<GroupConfigDetailPage />} />
<Route
path="build-configs/edit"
element={
<ProtectedRoute title={PageTitles.groupConfigEdit}>
<GroupConfigBuildConfigsEditPage />
</ProtectedRoute>
}
/>
</Route>
</Route>
<Route path="builds">
<Route index element={<BuildsPage />} />
Expand Down
1 change: 1 addition & 0 deletions src/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const PageTitles = {
buildConfigCreate: 'Create Build Config',
buildConfigEdit: 'Edit Build Config',
groupConfigs: 'Group Configs',
groupConfigEdit: 'Edit Group Config',
builds: 'Builds',
buildHistory: 'Build History',
groupBuilds: 'Group Builds',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
import { Button, Grid, GridItem, List, ListItem, Text, TextContent, TextVariants } from '@patternfly/react-core';
import { ExclamationTriangleIcon } from '@patternfly/react-icons';
import { css } from '@patternfly/react-styles';
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';

import { BuildConfiguration } from 'pnc-api-types-ts';

import { useParamsRequired } from 'hooks/useParamsRequired';
import { usePatchOperation } from 'hooks/usePatchOperation';
import { useQueryParamsEffect } from 'hooks/useQueryParamsEffect';
import { useServiceContainer } from 'hooks/useServiceContainer';
import { useTitle } from 'hooks/useTitle';

import { ActionConfirmModal } from 'components/ActionConfirmModal/ActionConfirmModal';
import { PageLayout } from 'components/PageLayout/PageLayout';
import { ConfigsAddList } from 'components/ProductVersionBuildConfigsEditPage/ConfigsAddList';
import { ConfigsChangesList } from 'components/ProductVersionBuildConfigsEditPage/ConfigsChangesList';
import { ConfigsRemoveList } from 'components/ProductVersionBuildConfigsEditPage/ConfigsRemoveList';
import { Toolbar } from 'components/Toolbar/Toolbar';
import { ToolbarItem } from 'components/Toolbar/ToolbarItem';
import { TooltipWrapper } from 'components/TooltipWrapper/TooltipWrapper';

import * as buildConfigApi from 'services/buildConfigApi';
import * as groupConfigApi from 'services/groupConfigApi';

import { createArrayPatchSimple } from 'utils/patchHelper';
import { generatePageTitle } from 'utils/titleHelper';

interface IGroupConfigBuildConfigsEditPageProps {
componentIdGroupConfigBuildConfigs?: string;
componentIdBuildConfigs?: string;
}

export const GroupConfigBuildConfigsEditPage = ({
componentIdGroupConfigBuildConfigs = 'g1',
componentIdBuildConfigs = 'p1',
}: IGroupConfigBuildConfigsEditPageProps) => {
const { groupConfigId } = useParamsRequired();

const navigate = useNavigate();

const serviceContainerGroupConfig = useServiceContainer(groupConfigApi.getGroupConfig);
const serviceContainerGroupConfigRunner = serviceContainerGroupConfig.run;

const serviceContainerGroupConfigBuildConfigs = useServiceContainer(groupConfigApi.getBuildConfigs);
const serviceContainerGroupConfigBuildConfigsRunner = serviceContainerGroupConfigBuildConfigs.run;

const serviceContainerBuildConfigs = useServiceContainer(buildConfigApi.getBuildConfigs);
const serviceContainerBuildConfigsRunner = serviceContainerBuildConfigs.run;

const serviceContainerGroupConfigPatch = useServiceContainer(groupConfigApi.patchGroupConfig);
const [wereBuildConfigsChanged, setWereBuildConfigsChanged] = useState<boolean>(false);

const {
operations: buildConfigChanges,
removedData: removedBuildConfigs,
addedData: addedBuildConfigs,
insertOperation: insertBuildConfigChange,
cancelOperation: cancelBuildConfigChange,
cancelAllOperations: cancelAllBuildConfigChanges,
} = usePatchOperation<BuildConfiguration>();

useEffect(() => {
if (buildConfigChanges.length) {
setWereBuildConfigsChanged(true);
}
}, [buildConfigChanges.length]);

const [isSubmitModalOpen, setIsSubmitModalOpen] = useState<boolean>(false);
const toggleSubmitModal = () => setIsSubmitModalOpen((isSubmitModalOpen) => !isSubmitModalOpen);

const [isCancelAllModalOpen, setIsCancelAllModalOpen] = useState<boolean>(false);
const toggleCancelAllModal = () => setIsCancelAllModalOpen((isCancelAllModalOpen) => !isCancelAllModalOpen);

useEffect(() => {
serviceContainerGroupConfigRunner({ serviceData: { id: groupConfigId } });
}, [serviceContainerGroupConfigRunner, groupConfigId]);

useQueryParamsEffect(
({ requestConfig } = {}) =>
serviceContainerGroupConfigBuildConfigsRunner({ serviceData: { id: groupConfigId }, requestConfig }),
{ componentId: componentIdGroupConfigBuildConfigs }
);

useQueryParamsEffect(serviceContainerBuildConfigsRunner, { componentId: componentIdBuildConfigs });

useTitle(
generatePageTitle({
pageType: 'Edit',
serviceContainer: serviceContainerGroupConfig,
firstLevelEntity: 'Group Config',
entityName: `Build Configs of ${serviceContainerGroupConfig.data?.name}`,
})
);

return (
<PageLayout
title={`Add and remove Build Configs${
serviceContainerGroupConfig.data?.name ? ' in ' + serviceContainerGroupConfig.data.name : ''
}`}
actions={[
<>
<div className={css(!buildConfigChanges.length && 'visibility-hidden')}>
<ExclamationTriangleIcon color="#F0AB00" /> Submit the changes to apply them
</div>
<Button
key="submit-btn"
variant="primary"
onClick={() => {
toggleSubmitModal();
}}
isDisabled={!buildConfigChanges.length}
>
Submit changes
</Button>
</>,
]}
>
<Grid hasGutter>
<GridItem lg={12} xl2={6}>
<Toolbar borderBottom>
<ToolbarItem>
<TextContent>
<Text component={TextVariants.h2}>Build Configs currently in the Group Config</Text>
</TextContent>
</ToolbarItem>
</Toolbar>

<ConfigsRemoveList<BuildConfiguration>
variant="Build"
serviceContainerConfigs={serviceContainerGroupConfigBuildConfigs}
componentId={componentIdGroupConfigBuildConfigs}
onConfigRemove={(buildConfig: BuildConfiguration) => {
insertBuildConfigChange(buildConfig, 'remove');
}}
removedConfigs={removedBuildConfigs}
/>
</GridItem>

<GridItem lg={12} xl2={6}>
<Toolbar borderBottom>
<ToolbarItem>
<TextContent>
<Text component={TextVariants.h2}>
Add new Build Configs{' '}
<TooltipWrapper tooltip="Both unassigned Build Configs and those assigned to another Group Config are displayed since Build Configs can belong to multiple Group Configs." />
</Text>
</TextContent>
</ToolbarItem>
</Toolbar>

<ConfigsAddList<BuildConfiguration>
variant="Build"
serviceContainerConfigs={serviceContainerBuildConfigs}
componentId={componentIdBuildConfigs}
onConfigAdd={(buildConfig: BuildConfiguration) => {
insertBuildConfigChange(buildConfig, 'add');
}}
addedConfigs={addedBuildConfigs}
groupConfigToExclude={groupConfigId}
/>
</GridItem>

<GridItem span={12}>
<Toolbar>
<ToolbarItem>
<TextContent>
<Text component={TextVariants.h2}>Changes Summary</Text>
</TextContent>
</ToolbarItem>
<ToolbarItem>
<Button
variant="tertiary"
onClick={() => {
toggleCancelAllModal();
}}
isDisabled={!buildConfigChanges.length}
>
Cancel all
</Button>
</ToolbarItem>
</Toolbar>
<ConfigsChangesList<BuildConfiguration>
variant="Build"
configChanges={buildConfigChanges}
onCancel={(buildConfig: BuildConfiguration) => {
cancelBuildConfigChange(buildConfig);
}}
/>
</GridItem>
</Grid>

{isSubmitModalOpen && (
<ActionConfirmModal
title="Submit changes?"
isOpen={isSubmitModalOpen}
wereSubmitDataChanged={wereBuildConfigsChanged}
onToggle={toggleSubmitModal}
onSubmit={() => {
setWereBuildConfigsChanged(false);

const patchData = createArrayPatchSimple(removedBuildConfigs, addedBuildConfigs, 'buildConfigs');

serviceContainerGroupConfigPatch
.run({ serviceData: { id: groupConfigId, patchData } })
.then(() => {
navigate('..');
})
.catch(() => {
console.error('Failed to edit Group Config Build Configs.');
});
}}
serviceContainer={serviceContainerGroupConfigPatch}
>
<List>
{!!removedBuildConfigs.length && (
<ListItem>
{removedBuildConfigs.length} Build Config{removedBuildConfigs.length > 1 && 's'} to be removed.
</ListItem>
)}
{!!addedBuildConfigs.length && (
<ListItem>
{addedBuildConfigs.length} Build Config{addedBuildConfigs.length > 1 && 's'} to be added.
</ListItem>
)}
</List>
</ActionConfirmModal>
)}

{isCancelAllModalOpen && (
<ActionConfirmModal
title="Cancel all changes?"
actionTitle="Cancel all"
cancelTitle="Keep the changes"
isOpen={isCancelAllModalOpen}
onToggle={toggleCancelAllModal}
onSubmit={() => {
cancelAllBuildConfigChanges();
toggleCancelAllModal();
}}
>
All changes made will be forgotten.
</ActionConfirmModal>
)}
</PageLayout>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import { useQueryParamsEffect } from 'hooks/useQueryParamsEffect';
import { useServiceContainer } from 'hooks/useServiceContainer';
import { useTitle } from 'hooks/useTitle';

import { ActionButton } from 'components/ActionButton/ActionButton';
import { Attributes } from 'components/Attributes/Attributes';
import { AttributesItem } from 'components/Attributes/AttributesItem';
import { BuildConfigsList } from 'components/BuildConfigsList/BuildConfigsList';
import { BuildHistoryList } from 'components/BuildHistoryList/BuildHistoryList';
import { ContentBox } from 'components/ContentBox/ContentBox';
import { PageLayout } from 'components/PageLayout/PageLayout';
import { ProductVersionLink } from 'components/ProductVersionLink/ProductVersionLink';
import { ProtectedComponent } from 'components/ProtectedContent/ProtectedComponent';
import { ServiceContainerLoading } from 'components/ServiceContainers/ServiceContainerLoading';
import { Toolbar } from 'components/Toolbar/Toolbar';
import { ToolbarItem } from 'components/Toolbar/ToolbarItem';
Expand Down Expand Up @@ -125,6 +127,11 @@ export const GroupConfigDetailPage = ({
<Text component={TextVariants.h2}>Build Configs</Text>
</TextContent>
</ToolbarItem>
<ToolbarItem>
<ProtectedComponent>
<ActionButton link="build-configs/edit">Edit list</ActionButton>
</ProtectedComponent>
</ToolbarItem>
</Toolbar>

<BuildConfigsList
Expand Down

0 comments on commit af60680

Please sign in to comment.