fix: modal, dialog & typography styling
parent
11662c8421
commit
00da5012d8
|
@ -1,8 +1,8 @@
|
||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
import { Button } from '@strapi/design-system';
|
import { Button, Typography } from '@strapi/design-system';
|
||||||
import { Map } from 'immutable';
|
import { Map } from 'immutable';
|
||||||
import { getFetchClient, useNotification } from '@strapi/strapi/admin';
|
import { getFetchClient, useNotification } from '@strapi/strapi/admin';
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
|
@ -14,38 +14,32 @@ const ActionButtons = () => {
|
||||||
const { post, get } = getFetchClient();
|
const { post, get } = getFetchClient();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { toggleNotification } = useNotification();
|
const { toggleNotification } = useNotification();
|
||||||
const [modalIsOpen, setModalIsOpen] = useState(false);
|
|
||||||
const [actionType, setActionType] = useState('');
|
|
||||||
const partialDiff = useSelector((state) => state.getIn(['config', 'partialDiff'], Map({}))).toJS();
|
const partialDiff = useSelector((state) => state.getIn(['config', 'partialDiff'], Map({}))).toJS();
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
|
|
||||||
const closeModal = () => {
|
|
||||||
setActionType('');
|
|
||||||
setModalIsOpen(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const openModal = (type) => {
|
|
||||||
setActionType(type);
|
|
||||||
setModalIsOpen(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ActionButtonsStyling>
|
<ActionButtonsStyling>
|
||||||
<Button disabled={isEmpty(partialDiff)} onClick={() => openModal('import')}>
|
<ConfirmModal
|
||||||
|
type="import"
|
||||||
|
trigger={(
|
||||||
|
<Button disabled={isEmpty(partialDiff)}>
|
||||||
{formatMessage({ id: 'config-sync.Buttons.Import' })}
|
{formatMessage({ id: 'config-sync.Buttons.Import' })}
|
||||||
</Button>
|
</Button>
|
||||||
<Button disabled={isEmpty(partialDiff)} onClick={() => openModal('export')}>
|
)}
|
||||||
|
onSubmit={(force) => dispatch(importAllConfig(partialDiff, force, toggleNotification, formatMessage, post, get))}
|
||||||
|
/>
|
||||||
|
<ConfirmModal
|
||||||
|
type="export"
|
||||||
|
trigger={(
|
||||||
|
<Button disabled={isEmpty(partialDiff)}>
|
||||||
{formatMessage({ id: 'config-sync.Buttons.Export' })}
|
{formatMessage({ id: 'config-sync.Buttons.Export' })}
|
||||||
</Button>
|
</Button>
|
||||||
{!isEmpty(partialDiff) && (
|
|
||||||
<h4 style={{ display: 'inline' }}>{Object.keys(partialDiff).length} {Object.keys(partialDiff).length === 1 ? "config change" : "config changes"}</h4>
|
|
||||||
)}
|
)}
|
||||||
<ConfirmModal
|
onSubmit={(force) => dispatch(exportAllConfig(partialDiff, toggleNotification, formatMessage, post, get))}
|
||||||
isOpen={modalIsOpen}
|
|
||||||
onClose={closeModal}
|
|
||||||
type={actionType}
|
|
||||||
onSubmit={(force) => actionType === 'import' ? dispatch(importAllConfig(partialDiff, force, toggleNotification, formatMessage, post, get)) : dispatch(exportAllConfig(partialDiff, toggleNotification, formatMessage, post, get))}
|
|
||||||
/>
|
/>
|
||||||
|
{!isEmpty(partialDiff) && (
|
||||||
|
<Typography variant="epsilon">{Object.keys(partialDiff).length} {Object.keys(partialDiff).length === 1 ? "config change" : "config changes"}</Typography>
|
||||||
|
)}
|
||||||
</ActionButtonsStyling>
|
</ActionButtonsStyling>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,15 +8,15 @@ import {
|
||||||
Typography,
|
Typography,
|
||||||
} from '@strapi/design-system';
|
} from '@strapi/design-system';
|
||||||
|
|
||||||
const ConfigDiff = ({ isOpen, onClose, oldValue, newValue, configName }) => {
|
const ConfigDiff = ({ oldValue, newValue, configName, trigger }) => {
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
if (!isOpen) return null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal.Root
|
<Modal.Root>
|
||||||
onClose={onClose}
|
<Modal.Trigger>
|
||||||
labelledBy="title"
|
{trigger}
|
||||||
>
|
</Modal.Trigger>
|
||||||
|
<Modal.Content>
|
||||||
<Modal.Header>
|
<Modal.Header>
|
||||||
<Typography variant="omega" fontWeight="bold" textColor="neutral800">
|
<Typography variant="omega" fontWeight="bold" textColor="neutral800">
|
||||||
{formatMessage({ id: 'config-sync.ConfigDiff.Title' })} {configName}
|
{formatMessage({ id: 'config-sync.ConfigDiff.Title' })} {configName}
|
||||||
|
@ -25,19 +25,22 @@ const ConfigDiff = ({ isOpen, onClose, oldValue, newValue, configName }) => {
|
||||||
<Modal.Body>
|
<Modal.Body>
|
||||||
<Grid.Root paddingBottom={4} style={{ textAlign: 'center' }}>
|
<Grid.Root paddingBottom={4} style={{ textAlign: 'center' }}>
|
||||||
<Grid.Item col={6}>
|
<Grid.Item col={6}>
|
||||||
<Typography variant="delta">{formatMessage({ id: 'config-sync.ConfigDiff.SyncDirectory' })}</Typography>
|
<Typography variant="delta" style={{ width: '100%' }}>{formatMessage({ id: 'config-sync.ConfigDiff.SyncDirectory' })}</Typography>
|
||||||
</Grid.Item>
|
</Grid.Item>
|
||||||
<Grid.Item col={6}>
|
<Grid.Item col={6}>
|
||||||
<Typography variant="delta">{formatMessage({ id: 'config-sync.ConfigDiff.Database' })}</Typography>
|
<Typography variant="delta" style={{ width: '100%' }}>{formatMessage({ id: 'config-sync.ConfigDiff.Database' })}</Typography>
|
||||||
</Grid.Item>
|
</Grid.Item>
|
||||||
</Grid.Root>
|
</Grid.Root>
|
||||||
|
<Typography variant="pi">
|
||||||
<ReactDiffViewer
|
<ReactDiffViewer
|
||||||
oldValue={JSON.stringify(oldValue, null, 2)}
|
oldValue={JSON.stringify(oldValue, null, 2)}
|
||||||
newValue={JSON.stringify(newValue, null, 2)}
|
newValue={JSON.stringify(newValue, null, 2)}
|
||||||
splitView
|
splitView
|
||||||
compareMethod={DiffMethod.WORDS}
|
compareMethod={DiffMethod.WORDS}
|
||||||
/>
|
/>
|
||||||
|
</Typography>
|
||||||
</Modal.Body>
|
</Modal.Body>
|
||||||
|
</Modal.Content>
|
||||||
</Modal.Root>
|
</Modal.Root>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Tr, Td, Checkbox } from '@strapi/design-system';
|
import { Tr, Td, Checkbox, Typography } from '@strapi/design-system';
|
||||||
|
|
||||||
const CustomRow = ({ row, checked, updateValue }) => {
|
const CustomRow = ({ row, checked, updateValue, ...props }) => {
|
||||||
const { configName, configType, state, onClick } = row;
|
const { configName, configType, state, onClick } = row;
|
||||||
|
|
||||||
const stateStyle = (stateStr) => {
|
const stateStyle = (stateStr) => {
|
||||||
|
@ -34,10 +34,14 @@ const CustomRow = ({ row, checked, updateValue }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tr
|
<Tr
|
||||||
|
{...props}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
if (e.target.type !== 'checkbox') {
|
if (e.target.type !== 'checkbox') {
|
||||||
onClick(configType, configName);
|
onClick(configType, configName);
|
||||||
}
|
}
|
||||||
|
if (props.onClick) {
|
||||||
|
props.onClick(e);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
style={{ cursor: 'pointer' }}
|
style={{ cursor: 'pointer' }}
|
||||||
>
|
>
|
||||||
|
@ -49,13 +53,13 @@ const CustomRow = ({ row, checked, updateValue }) => {
|
||||||
/>
|
/>
|
||||||
</Td>
|
</Td>
|
||||||
<Td>
|
<Td>
|
||||||
<p>{configName}</p>
|
<Typography variant="omega">{configName}</Typography>
|
||||||
</Td>
|
</Td>
|
||||||
<Td>
|
<Td>
|
||||||
<p>{configType}</p>
|
<Typography variant="omega">{configType}</Typography>
|
||||||
</Td>
|
</Td>
|
||||||
<Td>
|
<Td>
|
||||||
<p style={stateStyle(state)}>{state}</p>
|
<Typography variant="omega" style={stateStyle(state)}>{state}</Typography>
|
||||||
</Td>
|
</Td>
|
||||||
</Tr>
|
</Tr>
|
||||||
);
|
);
|
||||||
|
|
|
@ -117,13 +117,6 @@ const ConfigList = ({ diff, isLoading }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ConfigDiff
|
|
||||||
isOpen={openModal}
|
|
||||||
oldValue={originalConfig}
|
|
||||||
newValue={newConfig}
|
|
||||||
onClose={closeModal}
|
|
||||||
configName={cName}
|
|
||||||
/>
|
|
||||||
<Table colCount={4} rowCount={rows.length + 1}>
|
<Table colCount={4} rowCount={rows.length + 1}>
|
||||||
<Thead>
|
<Thead>
|
||||||
<Tr>
|
<Tr>
|
||||||
|
@ -148,8 +141,13 @@ const ConfigList = ({ diff, isLoading }) => {
|
||||||
</Thead>
|
</Thead>
|
||||||
<Tbody>
|
<Tbody>
|
||||||
{rows.map((row, index) => (
|
{rows.map((row, index) => (
|
||||||
<ConfigListRow
|
<ConfigDiff
|
||||||
key={row.configName}
|
key={row.configName}
|
||||||
|
oldValue={originalConfig}
|
||||||
|
newValue={newConfig}
|
||||||
|
configName={cName}
|
||||||
|
trigger={(
|
||||||
|
<ConfigListRow
|
||||||
row={row}
|
row={row}
|
||||||
checked={checkedItems[index]}
|
checked={checkedItems[index]}
|
||||||
updateValue={() => {
|
updateValue={() => {
|
||||||
|
@ -157,6 +155,8 @@ const ConfigList = ({ diff, isLoading }) => {
|
||||||
setCheckedItems([...checkedItems]);
|
setCheckedItems([...checkedItems]);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</Tbody>
|
</Tbody>
|
||||||
</Table>
|
</Table>
|
||||||
|
|
|
@ -10,23 +10,24 @@ import {
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Divider,
|
Divider,
|
||||||
Box,
|
Box,
|
||||||
|
Field,
|
||||||
} from '@strapi/design-system';
|
} from '@strapi/design-system';
|
||||||
import { WarningCircle } from '@strapi/icons';
|
import { WarningCircle } from '@strapi/icons';
|
||||||
|
|
||||||
const ConfirmModal = ({ isOpen, onClose, onSubmit, type }) => {
|
const ConfirmModal = ({ onClose, onSubmit, type, trigger }) => {
|
||||||
const soft = useSelector((state) => state.getIn(['config', 'appEnv', 'config', 'soft'], false));
|
const soft = useSelector((state) => state.getIn(['config', 'appEnv', 'config', 'soft'], false));
|
||||||
const [force, setForce] = useState(false);
|
const [force, setForce] = useState(false);
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
|
|
||||||
if (!isOpen) return null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog.Root
|
<Dialog.Root>
|
||||||
onClose={onClose}
|
<Dialog.Trigger>
|
||||||
title={formatMessage({ id: "config-sync.popUpWarning.Confirmation" })}
|
{trigger}
|
||||||
isOpen={isOpen}
|
</Dialog.Trigger>
|
||||||
>
|
<Dialog.Content>
|
||||||
<Dialog.Body icon={<WarningCircle />}>
|
<Dialog.Header>{formatMessage({ id: "config-sync.popUpWarning.Confirmation" })}</Dialog.Header>
|
||||||
|
<Dialog.Body>
|
||||||
|
<WarningCircle fill="danger600" width="32px" height="32px" />
|
||||||
<Flex size={2}>
|
<Flex size={2}>
|
||||||
<Flex justifyContent="center">
|
<Flex justifyContent="center">
|
||||||
<Typography variant="omega" id="confirm-description" style={{ textAlign: 'center' }}>
|
<Typography variant="omega" id="confirm-description" style={{ textAlign: 'center' }}>
|
||||||
|
@ -35,44 +36,43 @@ const ConfirmModal = ({ isOpen, onClose, onSubmit, type }) => {
|
||||||
</Typography>
|
</Typography>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Dialog.Body>
|
|
||||||
{(soft && type === 'import') && (
|
{(soft && type === 'import') && (
|
||||||
<React.Fragment>
|
<Box width="100%">
|
||||||
<Divider />
|
<Divider marginTop={4} />
|
||||||
<Box padding={4}>
|
<Box paddingTop={6}>
|
||||||
|
<Field.Root hint="Check this to ignore the soft setting.">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
onValueChange={(value) => setForce(value)}
|
onValueChange={(value) => setForce(value)}
|
||||||
value={force}
|
value={force}
|
||||||
name="force"
|
name="force"
|
||||||
hint="Check this to ignore the soft setting."
|
|
||||||
>
|
>
|
||||||
{formatMessage({ id: 'config-sync.popUpWarning.force' })}
|
{formatMessage({ id: 'config-sync.popUpWarning.force' })}
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
|
<Field.Hint />
|
||||||
|
</Field.Root>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</React.Fragment>
|
|
||||||
)}
|
)}
|
||||||
<Dialog.Footer
|
</Dialog.Body>
|
||||||
startAction={(
|
<Dialog.Footer>
|
||||||
<Button
|
<Dialog.Cancel>
|
||||||
onClick={() => {
|
<Button fullWidth variant="tertiary">
|
||||||
onClose();
|
|
||||||
}}
|
|
||||||
variant="tertiary"
|
|
||||||
>
|
|
||||||
{formatMessage({ id: 'config-sync.popUpWarning.button.cancel' })}
|
{formatMessage({ id: 'config-sync.popUpWarning.button.cancel' })}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
</Dialog.Cancel>
|
||||||
endAction={(
|
<Dialog.Action>
|
||||||
<Button
|
<Button
|
||||||
|
fullWidth
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onClose();
|
|
||||||
onSubmit(force);
|
onSubmit(force);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{formatMessage({ id: `config-sync.popUpWarning.button.${type}` })}
|
{formatMessage({ id: `config-sync.popUpWarning.button.${type}` })}
|
||||||
</Button>
|
</Button>
|
||||||
)} />
|
</Dialog.Action>
|
||||||
|
</Dialog.Footer>
|
||||||
|
</Dialog.Content>
|
||||||
</Dialog.Root>
|
</Dialog.Root>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { getFetchClient, useNotification } from '@strapi/strapi/admin';
|
import { getFetchClient, useNotification } from '@strapi/strapi/admin';
|
||||||
|
@ -13,20 +13,21 @@ const FirstExport = () => {
|
||||||
const { post, get } = getFetchClient();
|
const { post, get } = getFetchClient();
|
||||||
const { toggleNotification } = useNotification();
|
const { toggleNotification } = useNotification();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const [modalIsOpen, setModalIsOpen] = useState(false);
|
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ConfirmModal
|
|
||||||
isOpen={modalIsOpen}
|
|
||||||
onClose={() => setModalIsOpen(false)}
|
|
||||||
type="export"
|
|
||||||
onSubmit={() => dispatch(exportAllConfig([], toggleNotification, formatMessage, post, get))}
|
|
||||||
/>
|
|
||||||
<EmptyStateLayout
|
<EmptyStateLayout
|
||||||
content={formatMessage({ id: 'config-sync.FirstExport.Message' })}
|
content={formatMessage({ id: 'config-sync.FirstExport.Message' })}
|
||||||
action={<Button onClick={() => setModalIsOpen(true)}>{formatMessage({ id: 'config-sync.FirstExport.Button' })}</Button>}
|
action={(
|
||||||
|
<ConfirmModal
|
||||||
|
type="export"
|
||||||
|
onSubmit={() => dispatch(exportAllConfig([], toggleNotification, formatMessage, post, get))}
|
||||||
|
trigger={(
|
||||||
|
<Button>{formatMessage({ id: 'config-sync.FirstExport.Button' })}</Button>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
icon={<EmptyDocuments width={160} />}
|
icon={<EmptyDocuments width={160} />}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue