Add Upload from computer step

This commit is contained in:
mfrachet 2021-09-20 12:02:01 +02:00
parent 0ee4d32aae
commit 389166481f
12 changed files with 955 additions and 38 deletions

View File

@ -51,7 +51,7 @@ export const AddAssetStep = ({ onClose, onAddAsset }) => {
</Box>
<TabPanels>
<TabPanel>
<FromComputerForm />
<FromComputerForm onClose={onClose} onAddAsset={onAddAsset} />
</TabPanel>
<TabPanel>
<FromUrlForm onClose={onClose} onAddAsset={onAddAsset} />

View File

@ -1,10 +1,130 @@
import React from 'react';
/* eslint-disable jsx-a11y/label-has-associated-control */
import React, { useRef } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { Box } from '@strapi/parts/Box';
import { Row } from '@strapi/parts/Row';
import { VisuallyHidden } from '@strapi/parts/VisuallyHidden';
import { H3 } from '@strapi/parts/Text';
import { ModalFooter } from '@strapi/parts/ModalLayout';
import { Button } from '@strapi/parts/Button';
import AddAssetIcon from '@strapi/icons/AddAsset';
import { useIntl } from 'react-intl';
import { getTrad } from '../../../utils';
import { typeFromMime } from '../../../utils/typeFromMime';
import { AssetSource } from '../../../constants';
const Wrapper = styled.div`
display: flex;
flex-direction: column;
align-items: center;
`;
const IconWrapper = styled.div`
font-size: ${60 / 16}rem;
svg path {
fill: ${({ theme }) => theme.colors.primary600};
}
`;
const MediaBox = styled(Box)`
border-style: dashed;
`;
export const FromComputerForm = ({ onClose, onAddAsset }) => {
const { formatMessage } = useIntl();
const inputRef = useRef(null);
const handleClick = e => {
e.preventDefault();
inputRef.current.click();
};
const handleChange = () => {
const files = inputRef.current.files;
const assets = [];
for (let i = 0; i < files.length; i++) {
const file = files.item(i);
assets.push({
source: AssetSource.Computer,
type: typeFromMime(file.type),
url: URL.createObjectURL(file),
ext: file.name.split('.').pop(),
mime: file.type,
});
}
onAddAsset(assets);
};
export const FromComputerForm = () => {
return (
<Box paddingTop={4} paddingBottom={4}>
From computer form
</Box>
<form>
<Box paddingLeft={8} paddingRight={8} paddingTop={6} paddingBottom={6}>
<label>
<MediaBox
paddingTop={11}
paddingBottom={11}
hasRadius
justifyContent="center"
borderColor="neutral300"
background="neutral100"
>
<Row justifyContent="center">
<Wrapper>
<IconWrapper>
<AddAssetIcon aria-hidden />
</IconWrapper>
<Box paddingTop={3} paddingBottom={5}>
<H3 textColor="neutral600" as="span">
{formatMessage({
id: getTrad('input.label'),
defaultMessage: 'Drag & Drop here or',
})}
</H3>
</Box>
<Button type="button" onClick={handleClick}>
{formatMessage({
id: getTrad('input.button.label'),
defaultMessage: 'Browse files',
})}
</Button>
<VisuallyHidden>
<input
type="file"
multiple
name="files"
tabIndex={-1}
ref={inputRef}
onChange={handleChange}
/>
</VisuallyHidden>
</Wrapper>
</Row>
</MediaBox>
</label>
</Box>
<ModalFooter
startActions={
<Button onClick={onClose} variant="tertiary">
{formatMessage({
id: 'app.components.Button.cancel',
defaultMessage: 'cancel',
})}
</Button>
}
/>
</form>
);
};
FromComputerForm.propTypes = {
onClose: PropTypes.func.isRequired,
onAddAsset: PropTypes.func.isRequired,
};

View File

@ -56,12 +56,12 @@ export const FromUrlForm = ({ onClose, onAddAsset }) => {
<ModalFooter
startActions={
<Button onClick={onClose} variant="tertiary" loading={loading}>
<Button onClick={onClose} variant="tertiary">
{formatMessage({ id: 'app.components.Button.cancel', defaultMessage: 'cancel' })}
</Button>
}
endActions={
<Button type="submit">
<Button type="submit" loading={loading}>
{formatMessage({
id: getTrad('button.next'),
defaultMessage: 'Next',

View File

@ -0,0 +1,431 @@
import React from 'react';
import { ThemeProvider, lightTheme } from '@strapi/parts';
import { render as renderTL } from '@testing-library/react';
import { FromComputerForm } from '../FromComputerForm';
import en from '../../../../translations/en.json';
jest.mock('../../../../utils', () => ({
...jest.requireActual('../../../../utils'),
getTrad: x => x,
}));
jest.mock('react-intl', () => ({
useIntl: () => ({ formatMessage: jest.fn(({ id }) => en[id] || 'App level translation') }),
}));
describe('FromComputerForm', () => {
it('snapshots the component with 4 URLs: 3 valid and one in failure', async () => {
const { container } = renderTL(
<ThemeProvider theme={lightTheme}>
<FromComputerForm onClose={jest.fn()} onAddAsset={jest.fn()} />
</ThemeProvider>
);
expect(container).toMatchInlineSnapshot(`
.c19 {
border: 0;
-webkit-clip: rect(0 0 0 0);
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
.c0 {
padding-top: 24px;
padding-right: 40px;
padding-bottom: 24px;
padding-left: 40px;
}
.c1 {
background: #f6f6f9;
padding-top: 64px;
padding-bottom: 64px;
border-radius: 4px;
border: 1px solid #c0c0cf;
}
.c6 {
padding-top: 12px;
padding-bottom: 20px;
}
.c3 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.c12 {
border: 0;
-webkit-clip: rect(0 0 0 0);
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
.c7 {
font-weight: 500;
font-size: 1rem;
line-height: 1.25;
color: #666687;
}
.c13 {
background: #f6f6f9;
padding-top: 16px;
padding-right: 20px;
padding-bottom: 16px;
padding-left: 20px;
}
.c15 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.c16 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.c14 {
border-top: 1px solid #eaeaef;
}
.c17 > * + * {
margin-left: 8px;
}
.c11 {
font-weight: 500;
font-size: 0.75rem;
line-height: 1.33;
color: #32324d;
}
.c8 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
cursor: pointer;
padding: 8px;
border-radius: 4px;
background: #ffffff;
border: 1px solid #dcdce4;
}
.c8 svg {
height: 12px;
width: 12px;
}
.c8 svg > g,
.c8 svg path {
fill: #ffffff;
}
.c8[aria-disabled='true'] {
pointer-events: none;
}
.c9 {
padding: 8px 16px;
background: #4945ff;
border: none;
border: 1px solid #4945ff;
background: #4945ff;
}
.c9 .c10 {
color: #ffffff;
}
.c9[aria-disabled='true'] {
border: 1px solid #dcdce4;
background: #eaeaef;
}
.c9[aria-disabled='true'] .c10 {
color: #666687;
}
.c9[aria-disabled='true'] svg > g,
.c9[aria-disabled='true'] svg path {
fill: #666687;
}
.c9[aria-disabled='true']:active {
border: 1px solid #dcdce4;
background: #eaeaef;
}
.c9[aria-disabled='true']:active .c10 {
color: #666687;
}
.c9[aria-disabled='true']:active svg > g,
.c9[aria-disabled='true']:active svg path {
fill: #666687;
}
.c9:hover {
border: 1px solid #7b79ff;
background: #7b79ff;
}
.c9:active {
border: 1px solid #4945ff;
background: #4945ff;
}
.c18 {
padding: 8px 16px;
background: #4945ff;
border: none;
border: 1px solid #dcdce4;
background: #ffffff;
}
.c18 .c10 {
color: #ffffff;
}
.c18[aria-disabled='true'] {
border: 1px solid #dcdce4;
background: #eaeaef;
}
.c18[aria-disabled='true'] .c10 {
color: #666687;
}
.c18[aria-disabled='true'] svg > g,
.c18[aria-disabled='true'] svg path {
fill: #666687;
}
.c18[aria-disabled='true']:active {
border: 1px solid #dcdce4;
background: #eaeaef;
}
.c18[aria-disabled='true']:active .c10 {
color: #666687;
}
.c18[aria-disabled='true']:active svg > g,
.c18[aria-disabled='true']:active svg path {
fill: #666687;
}
.c18:hover {
background-color: #f6f6f9;
}
.c18:active {
background-color: #eaeaef;
}
.c18 .c10 {
color: #32324d;
}
.c18 svg > g,
.c18 svg path {
fill: #32324d;
}
.c4 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.c5 {
font-size: 3.75rem;
}
.c5 svg path {
fill: #4945ff;
}
.c2 {
border-style: dashed;
}
<div>
<form>
<div
class="c0"
>
<label>
<div
class="c1 c2"
>
<div
class="c3"
>
<div
class="c4"
>
<div
class="c5"
>
<svg
aria-hidden="true"
fill="none"
height="1em"
viewBox="0 0 24 20"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M21.569 2.398H7.829v1.586h13.74c.47 0 .826.5.826 1.094v9.853l-2.791-3.17a2.13 2.13 0 00-.74-.55 2.211 2.211 0 00-.912-.196 2.213 2.213 0 00-.912.191 2.13 2.13 0 00-.74.546l-2.93 3.385-2.974-3.36a2.146 2.146 0 00-.74-.545 2.23 2.23 0 00-.911-.193c-.316.002-.628.07-.913.2-.286.13-.538.319-.739.553l-2.931 3.432V7.653H2.51v9.894c.023.153.06.304.108.452v.127l.041.095c.057.142.126.28.207.412l.099.15c.074.107.157.207.247.302l.124.119c.13.118.275.222.43.309h.024c.36.214.775.327 1.198.325h16.515c.36-.004.716-.085 1.039-.24.323-.153.606-.375.827-.648a2.78 2.78 0 00.504-.888c.066-.217.108-.44.124-.666V5.078a2.497 2.497 0 00-.652-1.81 2.706 2.706 0 00-1.776-.87z"
fill="#32324D"
/>
<path
d="M12.552 9.199c.912 0 1.651-.71 1.651-1.586 0-.875-.74-1.585-1.651-1.585-.912 0-1.652.71-1.652 1.585 0 .876.74 1.586 1.652 1.586zM3.303 6.408h.826V3.997h2.477v-.793-.793H4.129V0h-.826c-.219 0-.85.002-.826 0v2.411H0v1.586h2.477v2.41h.826z"
fill="#32324D"
/>
</svg>
</div>
<div
class="c6"
>
<span
class="c7"
>
Drag & Drop here or
</span>
</div>
<button
aria-disabled="false"
class="c8 c9"
type="button"
>
<span
class="c10 c11"
>
Browse files
</span>
</button>
<div
class="c12"
>
<input
multiple=""
name="files"
tabindex="-1"
type="file"
/>
</div>
</div>
</div>
</div>
</label>
</div>
<div
class="c13 c14"
>
<div
class="c15"
>
<div
class="c16 c17"
>
<button
aria-disabled="false"
class="c8 c18"
type="button"
>
<span
class="c10 c11"
>
App level translation
</span>
</button>
</div>
<div
class="c16 c17"
/>
</div>
</div>
</form>
<div
class="c19"
>
<p
aria-live="polite"
aria-relevant="all"
id="live-region-log"
role="log"
/>
<p
aria-live="polite"
aria-relevant="all"
id="live-region-status"
role="status"
/>
<p
aria-live="assertive"
aria-relevant="all"
id="live-region-alert"
role="alert"
/>
</div>
</div>
`);
});
});

View File

@ -15,7 +15,7 @@ import { UnknownAssetCard } from '../../AssetCard/UnknownAssetCard';
import { getTrad } from '../../../utils';
import { AssetType, AssetSource } from '../../../constants';
export const PendingAssetStep = ({ onClose, assets }) => {
export const PendingAssetStep = ({ onClose, assets, onClickAddAsset }) => {
const { formatMessage } = useIntl();
return (
@ -49,7 +49,7 @@ export const PendingAssetStep = ({ onClose, assets }) => {
})}
</Text>
</Stack>
<Button size="S">
<Button size="S" onClick={onClickAddAsset}>
{formatMessage({
id: getTrad('header.actions.upload-new-asset'),
defaultMessage: 'Upload new asset',
@ -142,4 +142,5 @@ PendingAssetStep.propTypes = {
})
).isRequired,
onClose: PropTypes.func.isRequired,
onClickAddAsset: PropTypes.func.isRequired,
};

View File

@ -47,7 +47,12 @@ describe('AddAssetTest', () => {
const { container } = renderTL(
<ThemeProvider theme={lightTheme}>
<PendingAssetStep assets={assets} onClose={jest.fn()} onAddAsset={jest.fn()} />
<PendingAssetStep
assets={assets}
onClose={jest.fn()}
onAddAsset={jest.fn()}
onClickAddAsset={jest.fn()}
/>
</ThemeProvider>
);

View File

@ -19,12 +19,18 @@ export const UploadAssetDialog = ({ onSuccess, onClose }) => {
onSuccess();
};
const moveToAddAsset = () => {
setStep(Steps.AddAsset);
};
return (
<ModalLayout onClose={onClose} labelledBy="title">
{step === Steps.AddAsset && (
<AddAssetStep onClose={onClose} onAddAsset={handleAddToPendingAssets} />
)}
{step === Steps.PendingAsset && <PendingAssetStep onClose={onClose} assets={assets} />}
{step === Steps.PendingAsset && (
<PendingAssetStep onClose={onClose} assets={assets} onClickAddAsset={moveToAddAsset} />
)}
</ModalLayout>
);
};

View File

@ -94,6 +94,20 @@ describe('', () => {
align-items: center;
}
.c35 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.c9 {
display: -webkit-box;
display: -webkit-flex;
@ -147,6 +161,21 @@ describe('', () => {
border-bottom: 1px solid #eaeaef;
}
.c34 {
border-top: 1px solid #eaeaef;
}
.c36 > * + * {
margin-left: 8px;
}
.c28 {
font-weight: 500;
font-size: 1rem;
line-height: 1.25;
color: #666687;
}
.c7 {
font-weight: 400;
font-size: 0.875rem;
@ -176,8 +205,23 @@ describe('', () => {
}
.c21 {
padding-top: 16px;
padding-bottom: 16px;
padding-top: 24px;
padding-right: 40px;
padding-bottom: 24px;
padding-left: 40px;
}
.c22 {
background: #f6f6f9;
padding-top: 64px;
padding-bottom: 64px;
border-radius: 4px;
border: 1px solid #c0c0cf;
}
.c27 {
padding-top: 12px;
padding-bottom: 20px;
}
.c14 {
@ -218,6 +262,202 @@ describe('', () => {
border-bottom: 2px solid transparent;
}
.c32 {
font-weight: 500;
font-size: 0.75rem;
line-height: 1.33;
color: #32324d;
}
.c29 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
cursor: pointer;
padding: 8px;
border-radius: 4px;
background: #ffffff;
border: 1px solid #dcdce4;
}
.c29 svg {
height: 12px;
width: 12px;
}
.c29 svg > g,
.c29 svg path {
fill: #ffffff;
}
.c29[aria-disabled='true'] {
pointer-events: none;
}
.c30 {
padding: 8px 16px;
background: #4945ff;
border: none;
border: 1px solid #4945ff;
background: #4945ff;
}
.c30 .c31 {
color: #ffffff;
}
.c30[aria-disabled='true'] {
border: 1px solid #dcdce4;
background: #eaeaef;
}
.c30[aria-disabled='true'] .c31 {
color: #666687;
}
.c30[aria-disabled='true'] svg > g,
.c30[aria-disabled='true'] svg path {
fill: #666687;
}
.c30[aria-disabled='true']:active {
border: 1px solid #dcdce4;
background: #eaeaef;
}
.c30[aria-disabled='true']:active .c31 {
color: #666687;
}
.c30[aria-disabled='true']:active svg > g,
.c30[aria-disabled='true']:active svg path {
fill: #666687;
}
.c30:hover {
border: 1px solid #7b79ff;
background: #7b79ff;
}
.c30:active {
border: 1px solid #4945ff;
background: #4945ff;
}
.c37 {
padding: 8px 16px;
background: #4945ff;
border: none;
border: 1px solid #dcdce4;
background: #ffffff;
}
.c37 .c31 {
color: #ffffff;
}
.c37[aria-disabled='true'] {
border: 1px solid #dcdce4;
background: #eaeaef;
}
.c37[aria-disabled='true'] .c31 {
color: #666687;
}
.c37[aria-disabled='true'] svg > g,
.c37[aria-disabled='true'] svg path {
fill: #666687;
}
.c37[aria-disabled='true']:active {
border: 1px solid #dcdce4;
background: #eaeaef;
}
.c37[aria-disabled='true']:active .c31 {
color: #666687;
}
.c37[aria-disabled='true']:active svg > g,
.c37[aria-disabled='true']:active svg path {
fill: #666687;
}
.c37:hover {
background-color: #f6f6f9;
}
.c37:active {
background-color: #eaeaef;
}
.c37 .c31 {
color: #32324d;
}
.c37 svg > g,
.c37 svg path {
fill: #32324d;
}
.c24 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.c33 {
border: 0;
-webkit-clip: rect(0 0 0 0);
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
.c25 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.c26 {
font-size: 3.75rem;
}
.c26 svg path {
fill: #4945ff;
}
.c23 {
border-style: dashed;
}
<body
class="lock-body-scroll"
>
@ -344,11 +584,101 @@ describe('', () => {
role="tabpanel"
tabindex="0"
>
<div
class="c21"
>
From computer form
</div>
<form>
<div
class="c21"
>
<label>
<div
class="c22 c23"
>
<div
class="c24"
>
<div
class="c25"
>
<div
class="c26"
>
<svg
aria-hidden="true"
fill="none"
height="1em"
viewBox="0 0 24 20"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M21.569 2.398H7.829v1.586h13.74c.47 0 .826.5.826 1.094v9.853l-2.791-3.17a2.13 2.13 0 00-.74-.55 2.211 2.211 0 00-.912-.196 2.213 2.213 0 00-.912.191 2.13 2.13 0 00-.74.546l-2.93 3.385-2.974-3.36a2.146 2.146 0 00-.74-.545 2.23 2.23 0 00-.911-.193c-.316.002-.628.07-.913.2-.286.13-.538.319-.739.553l-2.931 3.432V7.653H2.51v9.894c.023.153.06.304.108.452v.127l.041.095c.057.142.126.28.207.412l.099.15c.074.107.157.207.247.302l.124.119c.13.118.275.222.43.309h.024c.36.214.775.327 1.198.325h16.515c.36-.004.716-.085 1.039-.24.323-.153.606-.375.827-.648a2.78 2.78 0 00.504-.888c.066-.217.108-.44.124-.666V5.078a2.497 2.497 0 00-.652-1.81 2.706 2.706 0 00-1.776-.87z"
fill="#32324D"
/>
<path
d="M12.552 9.199c.912 0 1.651-.71 1.651-1.586 0-.875-.74-1.585-1.651-1.585-.912 0-1.652.71-1.652 1.585 0 .876.74 1.586 1.652 1.586zM3.303 6.408h.826V3.997h2.477v-.793-.793H4.129V0h-.826c-.219 0-.85.002-.826 0v2.411H0v1.586h2.477v2.41h.826z"
fill="#32324D"
/>
</svg>
</div>
<div
class="c27"
>
<span
class="c28"
>
Drag & Drop here or
</span>
</div>
<button
aria-disabled="false"
class="c29 c30"
type="button"
>
<span
class="c31 c32"
>
Browse files
</span>
</button>
<div
class="c33"
>
<input
multiple=""
name="files"
tabindex="-1"
type="file"
/>
</div>
</div>
</div>
</div>
</label>
</div>
<div
class="c4 c34"
>
<div
class="c6"
>
<div
class="c35 c36"
>
<button
aria-disabled="false"
class="c29 c37"
type="button"
>
<span
class="c31 c32"
/>
</button>
</div>
<div
class="c35 c36"
/>
</div>
</div>
</form>
</div>
</div>
</div>

View File

@ -27,6 +27,7 @@
"header.content.assets-single": "1 asset",
"input.button.label": "Browse files",
"input.label-bold": "Drag & drop",
"input.label": "Drag & Drop here or",
"input.label-normal": "to upload or",
"input.placeholder": "Click to select an asset or drag & drop a file in this area",
"input.placeholder.icon": "Drop the asset in this zone",

View File

@ -0,0 +1,22 @@
import { AssetType } from '../../constants';
import { typeFromMime } from '../typeFromMime';
describe('typeFromMime', () => {
it('gives a type of image when the mime contains "image"', () => {
const type = typeFromMime('image/png');
expect(type).toBe(AssetType.Image);
});
it('gives a type of video when the mime contains "video"', () => {
const type = typeFromMime('video/mp4');
expect(type).toBe(AssetType.Video);
});
it('gives a type of document when the mime is neither video nor image', () => {
const type = typeFromMime('application/pdf');
expect(type).toBe(AssetType.Document);
});
});

View File

@ -0,0 +1,12 @@
import { AssetType } from '../constants';
export const typeFromMime = mime => {
if (mime.includes(AssetType.Image)) {
return AssetType.Image;
}
if (mime.includes(AssetType.Video)) {
return AssetType.Video;
}
return AssetType.Document;
};

View File

@ -1,5 +1,6 @@
import axios from 'axios';
import { AssetType, AssetSource } from '../constants';
import { typeFromMime } from './typeFromMime';
export const urlsToAssets = async urls => {
const assetPromises = urls.map(url =>
@ -19,25 +20,13 @@ export const urlsToAssets = async urls => {
const fullFilledAssets = assetsResults.filter(asset => asset.status === 'fulfilled');
const rejectedAssets = assetsResults.filter(asset => asset.status === 'rejected');
const assets = fullFilledAssets.map(fullFilledAsset => {
let assetType;
if (fullFilledAsset.value.mime.includes(AssetType.Image)) {
assetType = AssetType.Image;
} else if (fullFilledAsset.value.mime.includes(AssetType.Video)) {
assetType = AssetType.Video;
} else {
assetType = AssetType.Document;
}
return {
source: AssetSource.Url,
type: assetType,
url: fullFilledAsset.value.url,
ext: fullFilledAsset.value.url.split('.').pop(),
mime: fullFilledAsset.value.mime,
};
});
const assets = fullFilledAssets.map(fullFilledAsset => ({
source: AssetSource.Url,
type: typeFromMime(fullFilledAsset.value.mime),
url: fullFilledAsset.value.url,
ext: fullFilledAsset.value.url.split('.').pop(),
mime: fullFilledAsset.value.mime,
}));
const unknownAssets = rejectedAssets.map(unknownAsset => ({
source: AssetSource.Url,