♻️ front: introduce confirm modal (#50)
This commit is contained in:
committed by
ericlinagora
parent
7bc6e36207
commit
ce1180d25d
@@ -2,8 +2,10 @@
|
||||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
|
||||
export type ButtonTheme = 'primary' | 'secondary' | 'danger' | 'default' | 'outline' | 'dark' | 'white' | 'green';
|
||||
|
||||
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
theme?: 'primary' | 'secondary' | 'danger' | 'default' | 'outline' | 'dark' | 'white' | 'green';
|
||||
theme?: ButtonTheme;
|
||||
size?: 'md' | 'lg' | 'sm';
|
||||
icon?: (props: any) => JSX.Element;
|
||||
iconSize?: 'md' | 'lg';
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import React, { useState } from 'react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
import { RecoilRoot } from 'recoil';
|
||||
import { ComponentStory } from '@storybook/react';
|
||||
import { CheckCircleIcon, ExclamationCircleIcon } from '@heroicons/react/outline';
|
||||
import { Title } from '../text';
|
||||
|
||||
import { ConfirmModal, ConfirmModalProps } from './confirm';
|
||||
const icons = {
|
||||
check: CheckCircleIcon,
|
||||
exclamation: ExclamationCircleIcon,
|
||||
none: null,
|
||||
}
|
||||
export default {
|
||||
title: '@atoms/modal/confirm',
|
||||
component: ConfirmModal,
|
||||
argTypes: {
|
||||
theme: {
|
||||
options: "success danger warning gray".split(' '),
|
||||
},
|
||||
buttonTheme: {
|
||||
options: "primary secondary danger default outline dark white green",
|
||||
},
|
||||
open: { table: { disable: true } },
|
||||
icon: {
|
||||
options: [...Object.keys(icons)],
|
||||
mapping: icons,
|
||||
}
|
||||
},
|
||||
args: {
|
||||
title: "Very brief description",
|
||||
text: "Long description no one will probably really read",
|
||||
buttonOkLabel: 'general.continue',
|
||||
skipCancelOnClose: false,
|
||||
}
|
||||
};
|
||||
|
||||
const Template: ComponentStory<any> = (props: ConfirmModalProps) => {
|
||||
const [open, setOpen] = useState(true);
|
||||
|
||||
return (
|
||||
<RecoilRoot>
|
||||
<button className='dark:text-white' onClick={() => setOpen(true)}>Open</button>
|
||||
<ConfirmModal
|
||||
{...props}
|
||||
open={open}
|
||||
onClose={(...a) => {
|
||||
setOpen(false);
|
||||
action("onClose")(...a);
|
||||
}}
|
||||
onOk={action("onOk")}
|
||||
onCancel={action("onCancel")}
|
||||
/>
|
||||
</RecoilRoot>
|
||||
);
|
||||
}
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {};
|
||||
@@ -0,0 +1,59 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Modal, ModalContent, ModalContentTheme } from '.';
|
||||
import { Button, ButtonTheme } from 'app/atoms/button/button';
|
||||
|
||||
import Languages from 'features/global/services/languages-service';
|
||||
|
||||
export type ConfirmModalProps = {
|
||||
open: boolean;
|
||||
title: string;
|
||||
text: string;
|
||||
theme?: ModalContentTheme;
|
||||
icon: React.ComponentType;
|
||||
skipCancelOnClose?: boolean;
|
||||
buttonOkTheme?: ButtonTheme;
|
||||
buttonOkLabel: string;
|
||||
buttonCancelLabel?: string;
|
||||
onClose: () => void;
|
||||
onCancel?: () => void;
|
||||
onOk: () => void;
|
||||
};
|
||||
export const ConfirmModal = (props: ConfirmModalProps) => {
|
||||
function dialogCloseHandler(confirm?: boolean) {
|
||||
return () => {
|
||||
if (confirm === true)
|
||||
props.onOk();
|
||||
else if (confirm === false || !props.skipCancelOnClose)
|
||||
props.onCancel && props.onCancel();
|
||||
props.onClose();
|
||||
};
|
||||
}
|
||||
return <>
|
||||
<Modal open={props.open} onClose={dialogCloseHandler()}>
|
||||
<ModalContent
|
||||
title={props.title}
|
||||
text={props.text}
|
||||
theme={props.theme}
|
||||
icon={props.icon}
|
||||
buttons={
|
||||
<>
|
||||
<Button
|
||||
className="ml-2"
|
||||
theme='default'
|
||||
onClick={dialogCloseHandler(false)}
|
||||
>
|
||||
{Languages.t(props.buttonCancelLabel || "general.cancel")}
|
||||
</Button>
|
||||
<Button
|
||||
theme={props.buttonOkTheme || "danger"}
|
||||
onClick={dialogCloseHandler(true)}
|
||||
>
|
||||
{Languages.t(props.buttonOkLabel)}
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</Modal>
|
||||
</>;
|
||||
};
|
||||
@@ -144,7 +144,7 @@ export const Modal = (props: {
|
||||
</Transition.Root>
|
||||
);
|
||||
};
|
||||
|
||||
export type ModalContentTheme = 'success' | 'danger' | 'warning' | 'gray';
|
||||
export const ModalContent = (props: {
|
||||
title: ReactNode | string;
|
||||
text?: string;
|
||||
@@ -152,7 +152,7 @@ export const ModalContent = (props: {
|
||||
buttons?: ReactNode;
|
||||
children?: ReactNode;
|
||||
icon?: any;
|
||||
theme?: 'success' | 'danger' | 'warning' | 'gray';
|
||||
theme?: ModalContentTheme;
|
||||
}) => {
|
||||
let color = 'blue';
|
||||
if (props.theme === 'success') color = 'green';
|
||||
|
||||
+13
-32
@@ -12,7 +12,7 @@ import { Input } from 'app/atoms/input/input-text';
|
||||
import { CheckboxSlider } from 'app/atoms/input/input-checkbox-slider';
|
||||
import { Button } from 'app/atoms/button/button';
|
||||
import { ShieldExclamationIcon, CalendarIcon, PencilAltIcon } from '@heroicons/react/outline';
|
||||
import { Modal, ModalContent } from 'app/atoms/modal';
|
||||
import { ConfirmModal } from 'app/atoms/modal/confirm';
|
||||
|
||||
import Styles from './styles';
|
||||
|
||||
@@ -153,37 +153,18 @@ export const ExpiryEditorRow = (props: {
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<Modal open={isConfirmingExpiryRemoval} onClose={() => setIsConfirmingExpiryRemoval(false)}>
|
||||
<ModalContent
|
||||
title={Languages.t("components.public-link-security_expiration_removal_title")}
|
||||
text={props.isLinkPasswordProtected
|
||||
? Languages.t("components.public-link-security_expiration_removal_but_password")
|
||||
: Languages.t("components.public-link-security_expiration_removal_no_password")
|
||||
}
|
||||
theme="danger"
|
||||
icon={ShieldExclamationIcon}
|
||||
buttons={
|
||||
<>
|
||||
<Button
|
||||
className="ml-2"
|
||||
theme='default'
|
||||
onClick={() => setIsConfirmingExpiryRemoval(false)}
|
||||
>
|
||||
{Languages.t("general.cancel")}
|
||||
</Button>
|
||||
<Button
|
||||
theme="danger"
|
||||
onClick={() => {
|
||||
setIsConfirmingExpiryRemoval(false)
|
||||
saveValue(0);
|
||||
}}
|
||||
>
|
||||
{Languages.t("components.public-link-security_expiration_removal_confirm")}
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
<ConfirmModal
|
||||
open={isConfirmingExpiryRemoval}
|
||||
onClose={() => setIsConfirmingExpiryRemoval(false)}
|
||||
onOk={() => saveValue(0)}
|
||||
title={Languages.t("components.public-link-security_expiration_removal_title")}
|
||||
text={props.isLinkPasswordProtected
|
||||
? Languages.t("components.public-link-security_expiration_removal_but_password")
|
||||
: Languages.t("components.public-link-security_expiration_removal_no_password")
|
||||
}
|
||||
icon={ShieldExclamationIcon}
|
||||
buttonOkLabel="components.public-link-security_expiration_removal_confirm"
|
||||
buttonOkTheme='danger'
|
||||
/>
|
||||
</Modal>
|
||||
</>;
|
||||
}
|
||||
+12
-28
@@ -9,7 +9,7 @@ import { Input } from 'app/atoms/input/input-text';
|
||||
import { CheckboxSlider } from 'app/atoms/input/input-checkbox-slider';
|
||||
import { Button } from 'app/atoms/button/button';
|
||||
import { ShieldCheckIcon, PencilAltIcon, ShieldExclamationIcon } from '@heroicons/react/outline';
|
||||
import { Modal, ModalContent } from 'app/atoms/modal';
|
||||
import { ConfirmModal } from 'app/atoms/modal/confirm';
|
||||
|
||||
import Styles from './styles';
|
||||
|
||||
@@ -136,33 +136,17 @@ export const PasswordEditorRow = (props: {
|
||||
}
|
||||
/>
|
||||
|
||||
<Modal open={isConfirmingPasswordRemoval} onClose={() => setIsConfirmingPasswordRemoval(false)}>
|
||||
<ModalContent
|
||||
title={Languages.t("components.public-link-security_password_removal_title")}
|
||||
text={Languages.t("components.public-link-security_password_removal_body")}
|
||||
theme="danger"
|
||||
icon={ShieldExclamationIcon}
|
||||
buttons={
|
||||
<>
|
||||
<Button
|
||||
className="ml-2"
|
||||
theme='default'
|
||||
onClick={() => setIsConfirmingPasswordRemoval(false)}
|
||||
>
|
||||
{Languages.t("general.cancel")}
|
||||
</Button>
|
||||
<Button
|
||||
theme="danger"
|
||||
onClick={() => {
|
||||
setIsConfirmingPasswordRemoval(false)
|
||||
savePassword("");
|
||||
}}
|
||||
>
|
||||
{Languages.t("components.public-link-security_password_removal_confirm")}
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
<ConfirmModal
|
||||
open={isConfirmingPasswordRemoval}
|
||||
title={Languages.t("components.public-link-security_password_removal_title")}
|
||||
text={Languages.t("components.public-link-security_password_removal_body")}
|
||||
theme="danger"
|
||||
icon={ShieldExclamationIcon}
|
||||
buttonOkTheme='danger'
|
||||
buttonOkLabel='components.public-link-security_password_removal_confirm'
|
||||
|
||||
onClose={() => setIsConfirmingPasswordRemoval(false)}
|
||||
onOk={() => savePassword("")}
|
||||
/>
|
||||
</Modal>
|
||||
</>;
|
||||
}
|
||||
@@ -31,10 +31,7 @@ export const AccessModal = () => {
|
||||
open={state.open}
|
||||
onClose={() => setState({ ...state, open: false })}
|
||||
>
|
||||
{!!state.id &&
|
||||
<AccessModalContent
|
||||
id={state.id}
|
||||
/>}
|
||||
{!!state.id && <AccessModalContent id={state.id} />}
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user