Skip to content

Commit

Permalink
EES-4567 replace react-modal with radix-ui dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
amyb-hiveit committed Sep 28, 2023
1 parent 04a7b0a commit 4e91e5e
Show file tree
Hide file tree
Showing 55 changed files with 1,985 additions and 2,162 deletions.
407 changes: 384 additions & 23 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import RouteLeavingGuard from '@admin/components/RouteLeavingGuard';
import { render, screen, within } from '@testing-library/react';
import { render, screen, waitFor, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { createMemoryHistory } from 'history';
import React from 'react';
Expand Down Expand Up @@ -37,7 +37,7 @@ describe('RouteLeavingGuard', () => {
expect(screen.queryByText('Other route')).not.toBeInTheDocument();
});

test('shows modal when route change is blocked on `history.push`', () => {
test('shows modal when route change is blocked on `history.push`', async () => {
const history = createMemoryHistory();

render(
Expand All @@ -61,9 +61,13 @@ describe('RouteLeavingGuard', () => {

expect(history.location.pathname).toBe('/');

const modal = within(screen.getByRole('dialog'));
expect(modal.getByText('Test modal title')).toBeInTheDocument();
expect(modal.getByText('Test modal content')).toBeInTheDocument();
await waitFor(() => {
expect(screen.getByText('Test modal title')).toBeInTheDocument();
});

expect(
within(screen.getByRole('dialog')).getByText('Test modal content'),
).toBeInTheDocument();

expect(screen.getByText('Change route')).toBeInTheDocument();
expect(screen.queryByText('Other route')).not.toBeInTheDocument();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ const EditableAccordionSection = (props: EditableAccordionSectionProps) => {

const { editingMode } = useEditingContext();

const [showRemoveModal, toggleRemoveModal] = useToggle(false);
const [isEditingHeading, toggleEditingHeading] = useToggle(false);

const [newHeading, setNewHeading] = useState(heading);
Expand Down Expand Up @@ -163,37 +162,32 @@ const EditableAccordionSection = (props: EditableAccordionSectionProps) => {
{headerButtons}

{onRemoveSection && (
<>
<Tooltip
text={disabledRemoveSectionTooltip}
enabled={!!disabledRemoveSectionTooltip}
>
{({ ref }) => (
<Button
ariaDisabled={!!disabledRemoveSectionTooltip}
ref={ref}
variant="warning"
onClick={toggleRemoveModal.on}
>
Remove this section
</Button>
)}
</Tooltip>

<ModalConfirm
title="Removing section"
open={showRemoveModal}
onConfirm={onRemoveSection}
onExit={toggleRemoveModal.off}
onCancel={toggleRemoveModal.off}
>
<p>
Are you sure you want to remove the following section?
<br />
<strong>"{heading}"</strong>
</p>
</ModalConfirm>
</>
<Tooltip
text={disabledRemoveSectionTooltip}
enabled={!!disabledRemoveSectionTooltip}
>
{({ ref }) => (
<ModalConfirm
title="Removing section"
triggerButton={
<Button
ariaDisabled={!!disabledRemoveSectionTooltip}
ref={ref}
variant="warning"
>
Remove this section
</Button>
}
onConfirm={onRemoveSection}
>
<p>
Are you sure you want to remove the following section?
<br />
<strong>"{heading}"</strong>
</p>
</ModalConfirm>
)}
</Tooltip>
)}
</ButtonGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import ButtonGroup from '@common/components/ButtonGroup';
import LoadingSpinner from '@common/components/LoadingSpinner';
import ModalConfirm from '@common/components/ModalConfirm';
import Tooltip from '@common/components/Tooltip';
import useToggle from '@common/hooks/useToggle';
import React, { ReactNode } from 'react';

export interface EditableBlockProps {
Expand All @@ -27,8 +26,6 @@ const EditableBlockWrapper = ({
onDelete,
onEmbedBlockEdit,
}: EditableBlockProps & { children: ReactNode }) => {
const [showConfirmDelete, toggleConfirmDelete] = useToggle(false);

const lockedTooltip = lockedBy
? `This block is being edited by ${lockedBy?.displayName}`
: undefined;
Expand Down Expand Up @@ -72,37 +69,29 @@ const EditableBlockWrapper = ({
)}

{onDelete && (
<>
<Tooltip text={lockedTooltip} enabled={!!lockedTooltip}>
{({ ref }) => (
<Button
ariaDisabled={!!lockedTooltip}
disabled={isLoading}
ref={ref}
variant="warning"
onClick={toggleConfirmDelete.on}
>
Remove block
</Button>
)}
</Tooltip>

<ModalConfirm
title="Remove block"
open={showConfirmDelete}
onConfirm={async () => {
await onDelete();
toggleConfirmDelete.off();
}}
onExit={toggleConfirmDelete.off}
onCancel={toggleConfirmDelete.off}
>
<p>
Are you sure you want to remove this block from this content
section?
</p>
</ModalConfirm>
</>
<Tooltip text={lockedTooltip} enabled={!!lockedTooltip}>
{({ ref }) => (
<ModalConfirm
title="Remove block"
triggerButton={
<Button
ariaDisabled={!!lockedTooltip}
disabled={isLoading}
ref={ref}
variant="warning"
>
Remove block
</Button>
}
onConfirm={onDelete}
>
<p>
Are you sure you want to remove this block from this content
section?
</p>
</ModalConfirm>
)}
</Tooltip>
)}
</ButtonGroup>
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import ModalConfirm from '@common/components/ModalConfirm';
import React from 'react';
import { IdTitlePair } from '@admin/services/types/common';
import ModalConfirm from '@common/components/ModalConfirm';
import React, { ReactNode } from 'react';

interface Props {
scheduledMethodologies: IdTitlePair[];
scheduledMethodologies?: IdTitlePair[];
triggerButton: ReactNode;
onCancel: () => void;
onConfirm: () => void;
}

const CancelAmendmentModal = ({
scheduledMethodologies,
triggerButton,
onCancel,
onConfirm,
}: Props) => {
return (
<ModalConfirm
open
title="Confirm you want to cancel this amended release"
triggerButton={triggerButton}
onCancel={onCancel}
onConfirm={onConfirm}
onExit={onCancel}
Expand All @@ -25,14 +27,14 @@ const CancelAmendmentModal = ({
By cancelling the amendments you will lose any changes made, and the
original release will remain unchanged.
</p>
{scheduledMethodologies.length > 0 && (
{scheduledMethodologies && scheduledMethodologies.length > 0 && (
<>
<p>
The following methodologies are scheduled to be published with this
amended release:
</p>
<ul>
{scheduledMethodologies.map(methodology => (
{scheduledMethodologies?.map(methodology => (
<li key={methodology.id}>{methodology.title}</li>
))}
</ul>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import Link from '@admin/components/Link';
import DraftReleaseRowIssues from '@admin/pages/admin-dashboard/components/DraftReleaseRowIssues';
import { getReleaseApprovalStatusLabel } from '@admin/pages/release/utils/releaseSummaryUtil';
import {
import releaseService, {
ReleaseSummaryWithPermissions,
DashboardReleaseSummary,
DeleteReleasePlan,
} from '@admin/services/releaseService';
import {
ReleaseRouteParams,
Expand All @@ -12,16 +13,22 @@ import {
import ButtonText from '@common/components/ButtonText';
import Tag from '@common/components/Tag';
import VisuallyHidden from '@common/components/VisuallyHidden';
import React from 'react';
import React, { useState } from 'react';
import { generatePath } from 'react-router';
import CancelAmendmentModal from './CancelAmendmentModal';

interface Props {
isBauUser: boolean;
release: DashboardReleaseSummary & ReleaseSummaryWithPermissions;
onDelete: () => void;
onChangeRelease: () => void;
}

const DraftReleaseRow = ({ isBauUser, release, onDelete }: Props) => {
const DraftReleaseRow = ({ isBauUser, release, onChangeRelease }: Props) => {
const [deleteReleasePlan, setDeleteReleasePlan] = useState<
DeleteReleasePlan & {
releaseId: string;
}
>();
return (
<tr>
<td>{release.title}</td>
Expand Down Expand Up @@ -59,10 +66,31 @@ const DraftReleaseRow = ({ isBauUser, release, onDelete }: Props) => {
)}

{release.permissions?.canDeleteRelease && release.amendment && (
<ButtonText variant="warning" onClick={onDelete}>
Cancel amendment
<VisuallyHidden> for {release.title}</VisuallyHidden>
</ButtonText>
<CancelAmendmentModal
scheduledMethodologies={deleteReleasePlan?.scheduledMethodologies}
triggerButton={
<ButtonText
variant="warning"
onClick={async () => {
setDeleteReleasePlan({
...(await releaseService.getDeleteReleasePlan(release.id)),
releaseId: release.id,
});
}}
>
Cancel amendment
<VisuallyHidden> for {release.title}</VisuallyHidden>
</ButtonText>
}
onConfirm={async () => {
if (deleteReleasePlan) {
await releaseService.deleteRelease(deleteReleasePlan.releaseId);
setDeleteReleasePlan(undefined);
onChangeRelease();
}
}}
onCancel={() => setDeleteReleasePlan(undefined)}
/>
)}
</td>
</tr>
Expand Down
Loading

0 comments on commit 4e91e5e

Please sign in to comment.