Commit 2a7a3607 authored by Alejandro Celaya's avatar Alejandro Celaya Committed by Alejandro Celaya

Replace local confirm helper with the one in frontend-shared

parent 1e58310e
import { Button, ModalDialog } from '@hypothesis/frontend-shared';
import { render } from 'preact';
import { createRef } from 'preact';
import type { RefObject } from 'preact';
import type { ComponentChildren } from 'preact';
export type ConfirmModalProps = {
title?: string;
message: ComponentChildren;
confirmAction?: string;
};
/**
* Show the user a prompt asking them to confirm an action.
*
* This is like an async version of `window.confirm` except that:
*
* - It can be used inside iframes (browsers are starting to prevent this for
* the native `window.confirm` dialog)
* - The visual style of the dialog matches the Hypothesis design system
*
* @return - Promise that resolves with `true` if the user confirmed the action
* or `false` if they canceled it.
*/
export async function confirm({
title = 'Confirm',
message,
confirmAction = 'Yes',
}: ConfirmModalProps): Promise<boolean> {
const cancelButton = createRef<HTMLElement | undefined>();
const container = document.createElement('div');
container.setAttribute('data-testid', 'confirm-container');
// Ensure dialog appears above any existing content. The Z-index value here
// is Good Enough™ for current usage.
container.style.position = 'relative';
container.style.zIndex = '10';
document.body.appendChild(container);
return new Promise(resolve => {
const close = (result: boolean) => {
render(null, container);
container.remove();
resolve(result);
};
render(
<ModalDialog
buttons={
<>
<Button
elementRef={cancelButton}
data-testid="cancel-button"
onClick={() => close(false)}
>
Cancel
</Button>
<Button
data-testid="confirm-button"
variant="primary"
onClick={() => close(true)}
>
{confirmAction}
</Button>
</>
}
initialFocus={cancelButton as RefObject<HTMLElement>}
title={title}
onClose={() => close(false)}
>
{message}
</ModalDialog>,
container,
);
});
}
import { confirm } from '../prompts';
describe('shared/prompts', () => {
describe('confirm', () => {
function clickClose() {
const closeButton = getCustomDialog().querySelector(
'[aria-label="Close"]',
);
closeButton.click();
}
function clickCancel() {
const cancelButton = getCustomDialog().querySelector(
'[data-testid="cancel-button"]',
);
cancelButton.click();
}
function clickConfirm() {
const confirmButton = getCustomDialog().querySelector(
'[data-testid="confirm-button"]',
);
confirmButton.click();
}
function getCustomDialog() {
return document.querySelector('[data-testid="confirm-container"]');
}
it('renders a custom dialog', async () => {
const result = confirm({
title: 'Confirm action?',
message: 'Do the thing?',
confirmAction: 'Yeah!',
});
const dialog = getCustomDialog();
assert.ok(dialog);
clickClose();
assert.notOk(getCustomDialog());
assert.isFalse(await result);
});
it('returns true if "Confirm" button is clicked', async () => {
const result = confirm({ message: 'Do the thing?' });
clickConfirm();
assert.isTrue(await result);
});
it('returns false if "Cancel" button is clicked', async () => {
const result = confirm({ message: 'Do the thing?' });
clickCancel();
assert.isFalse(await result);
});
});
});
import {
confirm,
IconButton,
EditIcon,
FlagIcon,
......@@ -7,7 +8,6 @@ import {
TrashIcon,
} from '@hypothesis/frontend-shared';
import { confirm } from '../../../shared/prompts';
import type { SavedAnnotation } from '../../../types/api';
import type { SidebarSettings } from '../../../types/config';
import { serviceConfig } from '../../config/service-config';
......
......@@ -92,13 +92,13 @@ describe('AnnotationActionBar', () => {
$imports.$mock(mockImportedComponents());
$imports.$mock({
'@hypothesis/frontend-shared': { confirm: fakeConfirm },
'../../helpers/annotation-sharing': {
sharingEnabled: fakeSharingEnabled,
annotationSharingLink: fakeAnnotationSharingLink,
},
'../../helpers/permissions': { permits: fakePermits },
'../../store': { useSidebarStore: () => fakeStore },
'../../../shared/prompts': { confirm: fakeConfirm },
});
});
......
import { CopyIcon, ExternalIcon, LeaveIcon } from '@hypothesis/frontend-shared';
import {
confirm,
CopyIcon,
ExternalIcon,
LeaveIcon,
} from '@hypothesis/frontend-shared';
import classnames from 'classnames';
import { confirm } from '../../../shared/prompts';
import type { Group } from '../../../types/api';
import { orgName } from '../../helpers/group-list-item-common';
import { withServices } from '../../service-context';
......
......@@ -62,13 +62,13 @@ describe('GroupListItem', () => {
fakeConfirm = sinon.stub().resolves(false);
$imports.$mock({
'@hypothesis/frontend-shared': { confirm: fakeConfirm },
'../MenuItem': FakeMenuItem,
'../../util/copy-to-clipboard': {
copyPlainText: fakeCopyPlainText,
},
'../../helpers/group-list-item-common': fakeGroupListItemCommon,
'../../store': { useSidebarStore: () => fakeStore },
'../../../shared/prompts': { confirm: fakeConfirm },
});
});
......
import { confirm } from '@hypothesis/frontend-shared';
import classnames from 'classnames';
import { useEffect, useMemo } from 'preact/hooks';
import { confirm } from '../../shared/prompts';
import type { SidebarSettings } from '../../types/config';
import { serviceConfig } from '../config/service-config';
import { isThirdPartyService } from '../helpers/is-third-party-service';
......
......@@ -81,13 +81,13 @@ describe('HypothesisApp', () => {
$imports.$mock(mockImportedComponents());
$imports.$mock({
'@hypothesis/frontend-shared': { confirm: fakeConfirm },
'../config/service-config': { serviceConfig: fakeServiceConfig },
'../store': { useSidebarStore: () => fakeStore },
'../helpers/session': {
shouldAutoDisplayTutorial: fakeShouldAutoDisplayTutorial,
},
'../helpers/theme': { applyTheme: fakeApplyTheme },
'../../shared/prompts': { confirm: fakeConfirm },
'../helpers/is-third-party-service': {
isThirdPartyService: fakeIsThirdPartyService,
},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment