go to pending modal on successfully drop file

This commit is contained in:
ronronscelestes 2022-04-04 15:12:21 +02:00
parent a6fecbb914
commit d5c74ba1ae
9 changed files with 126 additions and 59 deletions

View File

@ -58,7 +58,7 @@ const LogoInput = ({ customLogo, defaultLogo }) => {
</CarouselInput> </CarouselInput>
<LogoModalStepper <LogoModalStepper
onClose={() => setIsDialogOpen(false)} onClose={() => setIsDialogOpen(false)}
initialStep={customLogo ? 'pending' : 'add'} initialStep={customLogo ? 'pending' : 'upload'}
isOpen={isDialogOpen} isOpen={isDialogOpen}
/> />
</> </>

View File

@ -1,23 +1,37 @@
import React from 'react'; import React from 'react';
import { useIntl } from 'react-intl';
import PropTypes from 'prop-types';
import { Tabs, Tab, TabGroup, TabPanels, TabPanel } from '@strapi/design-system/Tabs'; import { Tabs, Tab, TabGroup, TabPanels, TabPanel } from '@strapi/design-system/Tabs';
import { Box } from '@strapi/design-system/Box'; import { Box } from '@strapi/design-system/Box';
import { Divider } from '@strapi/design-system/Divider'; import { Divider } from '@strapi/design-system/Divider';
import FromComputerForm from './FromComputerForm'; import FromComputerForm from './FromComputerForm';
const AddLogoDialog = () => { const AddLogoDialog = ({ setLocalImage, goTo, next }) => {
const { formatMessage } = useIntl();
return ( return (
<TabGroup label="How do you want to upload your assets?" variant="simple"> <TabGroup label="How do you want to upload your assets?" variant="simple">
<Box paddingLeft={2} paddingRight={2}> <Box paddingLeft={2} paddingRight={2}>
<Tabs> <Tabs>
<Tab>From computer</Tab> <Tab>
<Tab>From URL</Tab> {formatMessage({
id: 'Settings.application.customization.modal.upload.from-computer',
defaultMessage: 'From computer',
})}
</Tab>
<Tab>
{formatMessage({
id: 'Settings.application.customization.modal.upload.from-url',
defaultMessage: 'From URL',
})}
</Tab>
</Tabs> </Tabs>
<Divider /> <Divider />
</Box> </Box>
<TabPanels> <TabPanels>
<TabPanel> <TabPanel>
<FromComputerForm /> <FromComputerForm setLocalImage={setLocalImage} goTo={goTo} next={next} />
</TabPanel> </TabPanel>
<TabPanel>TO DO</TabPanel> <TabPanel>TO DO</TabPanel>
</TabPanels> </TabPanels>
@ -25,4 +39,14 @@ const AddLogoDialog = () => {
); );
}; };
AddLogoDialog.defaultProps = {
next: null,
};
AddLogoDialog.propTypes = {
setLocalImage: PropTypes.func.isRequired,
goTo: PropTypes.func.isRequired,
next: PropTypes.string,
};
export default AddLogoDialog; export default AddLogoDialog;

View File

@ -1,4 +1,5 @@
import React, { useState, useRef } from 'react'; import React, { useState, useRef } from 'react';
import PropTypes from 'prop-types';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import styled from 'styled-components'; import styled from 'styled-components';
import { Box } from '@strapi/design-system/Box'; import { Box } from '@strapi/design-system/Box';
@ -14,7 +15,7 @@ const FileInput = styled(Box)`
opacity: 0; opacity: 0;
`; `;
const FromComputerForm = () => { const FromComputerForm = ({ setLocalImage, goTo, next }) => {
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const [dragOver, setDragOver] = useState(false); const [dragOver, setDragOver] = useState(false);
const [fileError, setFileError] = useState(false); const [fileError, setFileError] = useState(false);
@ -37,8 +38,9 @@ const FromComputerForm = () => {
} }
try { try {
const fileToAsset = await parseFileMetadatas(file); const asset = await parseFileMetadatas(file);
console.log(fileToAsset); setLocalImage(asset);
goTo(next);
} catch (err) { } catch (err) {
if (err.displayMessage) { if (err.displayMessage) {
setFileError(formatMessage(err.displayMessage)); setFileError(formatMessage(err.displayMessage));
@ -77,47 +79,52 @@ const FromComputerForm = () => {
onDragEnter={handleDragEnter} onDragEnter={handleDragEnter}
onDragLeave={handleDragLeave} onDragLeave={handleDragLeave}
> >
<Flex justifyContent="center"> <Flex justifyContent="center" direction="column">
<Flex direction="column"> <Icon
<Icon color="primary600"
color="primary600" width={`${60 / 16}rem`}
width={`${60 / 16}rem`} height={`${60 / 16}rem`}
height={`${60 / 16}rem`} as={PicturePlus}
as={PicturePlus} aria-hidden
/> />
<Box paddingTop={3} paddingBottom={5}> <Box paddingTop={3} paddingBottom={5}>
<Typography variant="delta">Drag & Drop here or</Typography> <Typography variant="delta" as="span">
</Box> Drag and Drop here or
</Typography>
</Box>
<FileInput <FileInput
accept={ACCEPTED_FORMAT.map(format => `.${format}`)} accept={ACCEPTED_FORMAT.map(format => `.${format}`)}
cursor="pointer" cursor="pointer"
as="input" as="input"
position="absolute" position="absolute"
left={0} left={0}
right={0} right={0}
bottom={0} bottom={0}
top={0} top={0}
width="100%" width="100%"
type="file" type="file"
name="files" name="files"
tabIndex={-1} tabIndex={-1}
zIndex={1} zIndex={1}
onChange={handleChange} onChange={handleChange}
ref={inputRef} ref={inputRef}
/> />
<Button type="button" onClick={handleClick}> <Button type="button" onClick={handleClick}>
Browse files {formatMessage({
</Button> id: 'Settings.application.customization.modal.upload.cta.browse',
defaultMessage: 'Browse files',
})}
</Button>
<Box paddingTop={6}> <Box paddingTop={6}>
<Typography variant="pi" textColor="neutral600"> <Typography variant="pi" textColor="neutral600">
Max dimension: 750*750, Max size: TBC {/* Add translation once we know more about max size */}
</Typography> Max dimension: 750*750, Max size: TBC
</Box> </Typography>
</Flex> </Box>
</Flex> </Flex>
</Box> </Box>
{fileError && ( {fileError && (
@ -133,4 +140,14 @@ const FromComputerForm = () => {
); );
}; };
FromComputerForm.defaultProps = {
next: null,
};
FromComputerForm.propTypes = {
setLocalImage: PropTypes.func.isRequired,
goTo: PropTypes.func.isRequired,
next: PropTypes.string,
};
export default FromComputerForm; export default FromComputerForm;

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
const PendingLogoDialog = () => { const PendingLogoDialog = () => {
return <div>PendingLogoDialog</div>; return <div>PENDING DIALOG - TO DO</div>;
}; };
export default PendingLogoDialog; export default PendingLogoDialog;

View File

@ -1,5 +1,6 @@
import React, { useReducer, useEffect } from 'react'; import React, { useReducer, useEffect } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
import { import {
ModalLayout, ModalLayout,
ModalBody, ModalBody,
@ -11,15 +12,16 @@ import reducer, { initialState } from './reducer';
import stepper from './stepper'; import stepper from './stepper';
const LogoModalStepper = ({ initialStep, isOpen, onClose }) => { const LogoModalStepper = ({ initialStep, isOpen, onClose }) => {
const [{ currentStep }, dispatch] = useReducer(reducer, initialState); const [{ currentStep, localImage }, dispatch] = useReducer(reducer, initialState);
const { Component, modalTitle } = stepper[currentStep]; const { Component, modalTitle, next } = stepper[currentStep];
const { formatMessage } = useIntl();
useEffect(() => { useEffect(() => {
if (isOpen) { if (isOpen) {
goTo(initialStep); goTo(initialStep);
} }
// Disabling the rule because we just want to let the ability to open the modal // Disabling the rule because we just want to open the modal at a specific step
// at a specific step then we will let the stepper handle the navigation // then we let the stepper handle the navigation
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [isOpen]); }, [isOpen]);
@ -30,6 +32,13 @@ const LogoModalStepper = ({ initialStep, isOpen, onClose }) => {
}); });
}; };
const setLocalImage = asset => {
dispatch({
type: 'SET_LOCAL_IMAGE',
value: asset,
});
};
if (!isOpen) { if (!isOpen) {
return null; return null;
} }
@ -37,12 +46,12 @@ const LogoModalStepper = ({ initialStep, isOpen, onClose }) => {
return ( return (
<ModalLayout labelledBy="modal" onClose={onClose}> <ModalLayout labelledBy="modal" onClose={onClose}>
<ModalHeader> <ModalHeader>
<Typography fontWeight="bold" as="h2" id="title"> <Typography fontWeight="bold" as="h2" id="modal">
{modalTitle} {formatMessage(modalTitle)}
</Typography> </Typography>
</ModalHeader> </ModalHeader>
<ModalBody> <ModalBody>
<Component /> <Component setLocalImage={setLocalImage} localImage={localImage} goTo={goTo} next={next} />
</ModalBody> </ModalBody>
<ModalFooter /> <ModalFooter />
</ModalLayout> </ModalLayout>

View File

@ -8,7 +8,8 @@
import produce from 'immer'; import produce from 'immer';
const initialState = { const initialState = {
currentStep: 'add', currentStep: 'upload',
localImage: undefined,
}; };
const reducer = (state = initialState, action) => const reducer = (state = initialState, action) =>
@ -18,6 +19,10 @@ const reducer = (state = initialState, action) =>
draftState.currentStep = action.to; draftState.currentStep = action.to;
break; break;
} }
case 'SET_LOCAL_IMAGE': {
draftState.localImage = action.value;
break;
}
default: { default: {
return draftState; return draftState;
} }

View File

@ -2,17 +2,23 @@ import AddLogoDialog from './AddLogoDialog';
import PendingLogoDialog from './PendingLogoDialog'; import PendingLogoDialog from './PendingLogoDialog';
const stepper = { const stepper = {
add: { upload: {
Component: AddLogoDialog, Component: AddLogoDialog,
modalTitle: 'Upload logo', modalTitle: {
id: 'Settings.application.customization.modal.upload',
defaultMessage: 'Upload logo',
},
next: 'pending', next: 'pending',
prev: null, prev: null,
}, },
pending: { pending: {
Component: PendingLogoDialog, Component: PendingLogoDialog,
modalTitle: 'Pending logo', modalTitle: {
id: 'Settings.application.customization.modal.pending',
defaultMessage: 'Pending logo',
},
next: null, next: null,
prev: 'add', prev: 'upload',
}, },
}; };

View File

@ -34,9 +34,10 @@ const rawFileToAsset = rawFile => {
}; };
export const parseFileMetadatas = async file => { export const parseFileMetadatas = async file => {
const isFormatAuthorized = ACCEPTED_FORMAT.some(format => file.type.includes(format));
let error; let error;
const isFormatAuthorized = ACCEPTED_FORMAT.some(format => file.type.includes(format));
if (!isFormatAuthorized) { if (!isFormatAuthorized) {
error = new Error('File format'); error = new Error('File format');
error.displayMessage = FILE_FORMAT_ERROR_MESSAGE; error.displayMessage = FILE_FORMAT_ERROR_MESSAGE;

View File

@ -103,6 +103,11 @@
"Settings.application.customization.carousel.title": "Logo", "Settings.application.customization.carousel.title": "Logo",
"Settings.application.customization.carousel.change-action": "Change logo", "Settings.application.customization.carousel.change-action": "Change logo",
"Settings.application.customization.carousel-slide.label": "Logo slide", "Settings.application.customization.carousel-slide.label": "Logo slide",
"Settings.application.customization.modal.upload": "Upload logo",
"Settings.application.customization.modal.upload.from-computer": "From computer",
"Settings.application.customization.modal.upload.cta.browse": "Browse files",
"Settings.application.customization.modal.upload.from-url": "From URL",
"Settings.application.customization.modal.pending": "Pending logo",
"Settings.error": "Error", "Settings.error": "Error",
"Settings.global": "Global Settings", "Settings.global": "Global Settings",
"Settings.permissions": "Administration panel", "Settings.permissions": "Administration panel",