fix: several media lib ui issues

fix: using open prop does not clear any state and create a lot of bugs

fix: crop
This commit is contained in:
Alexandre Bodin 2024-06-20 12:21:02 +02:00
parent 5285f8db42
commit 3aee925501
19 changed files with 129 additions and 93 deletions

View File

@ -8,7 +8,7 @@ import { useIntl } from 'react-intl';
* ConfirmDialog
* -----------------------------------------------------------------------------------------------*/
interface ConfirmDialogProps extends Pick<ButtonProps, 'variant'>, Pick<Dialog.BodyProps, 'icon'> {
onConfirm?: () => Promise<void> | void;
onConfirm?: (e?: React.MouseEvent<HTMLButtonElement>) => Promise<void> | void;
children?: React.ReactNode;
endAction?: React.ReactNode;
startAction?: React.ReactNode;
@ -66,14 +66,14 @@ const ConfirmDialog = ({
defaultMessage: 'Are you sure?',
});
const handleConfirm = async () => {
const handleConfirm = async (e: React.MouseEvent<HTMLButtonElement>) => {
if (!onConfirm) {
return;
}
try {
setIsConfirming(true);
await onConfirm();
await onConfirm(e);
} finally {
setIsConfirming(false);
}

View File

@ -309,7 +309,7 @@ const ListPage = () => {
<Td>
<Typography textColor="neutral800">{webhook.url}</Typography>
</Td>
<Td>
<Td onClick={(e) => e.stopPropagation()}>
<Flex>
<Switch
onLabel={formatMessage({

View File

@ -298,7 +298,11 @@ export const BrowseStep = ({
onClick={() => handleClickFolderCard(folder.id, folder.path)}
>
<Flex tag="h2" direction="column" alignItems="start" maxWidth="100%">
<TypographyMaxWidth fontWeight="semiBold" ellipsis>
<TypographyMaxWidth
fontWeight="semiBold"
ellipsis
textColor="neutral800"
>
{folder.name}
{/* VisuallyHidden dash here allows to separate folder title and count informations
for voice reading structure purpose */}

View File

@ -278,7 +278,7 @@ exports[`BrowseStep renders and match snapshot 1`] = `
overflow: hidden;
text-overflow: ellipsis;
font-weight: 500;
color: currentcolor;
color: #32324d;
}
.c56 {

View File

@ -214,7 +214,7 @@ export const AssetContent = ({
</Modal.Title>
</Modal.Header>
<Tabs.Root variant="simple" defaultValue={selectedAssets.length > 0 ? 'selected' : 'browse'}>
<TabsRoot variant="simple" defaultValue={selectedAssets.length > 0 ? 'selected' : 'browse'}>
<Flex paddingLeft={8} paddingRight={8} paddingTop={6} justifyContent="space-between">
<Tabs.List>
<Tabs.Trigger value="browse">
@ -283,7 +283,7 @@ export const AssetContent = ({
/>
</Tabs.Content>
</Modal.Body>
</Tabs.Root>
</TabsRoot>
<DialogFooter onClose={onClose} onValidate={() => onValidate(selectedAssets)} />
</>
);
@ -342,3 +342,9 @@ AssetDialog.propTypes = {
onValidate: PropTypes.func.isRequired,
trackedLocation: PropTypes.string,
};
const TabsRoot = styled(Tabs.Root)`
display: flex;
flex-direction: column;
overflow: hidden;
`;

View File

@ -4,7 +4,7 @@ import { Flex, FocusTrap, IconButton, Menu } from '@strapi/design-system';
import { Check, Cross } from '@strapi/icons';
import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
import { styled } from 'styled-components';
import { styled, useTheme } from 'styled-components';
import getTrad from '../../../utils/getTrad';
@ -12,6 +12,7 @@ import { CroppingActionRow } from './components';
export const CroppingActions = ({ onCancel, onValidate, onDuplicate }) => {
const { formatMessage } = useIntl();
const theme = useTheme();
return (
<FocusTrap onEscape={onCancel}>
@ -45,7 +46,7 @@ export const CroppingActions = ({ onCancel, onValidate, onDuplicate }) => {
fill="#C0C0D0"
/>
</Trigger>
<Menu.Content zIndex={5}>
<Menu.Content zIndex={theme.zIndices.dialog}>
<Menu.Item onSelect={onValidate}>
{formatMessage({
id: getTrad('checkControl.crop-original'),

View File

@ -7,7 +7,8 @@ export const RelativeBox = styled(Box)`
export const Wrapper = styled.div`
position: relative;
text-align: center;
display: flex;
justify-content: center;
background: repeating-conic-gradient(
${({ theme }) => theme.colors.neutral100} 0% 25%,
transparent 0% 50%

View File

@ -8,9 +8,12 @@ import { useRemoveAsset } from '../../hooks/useRemoveAsset';
export const RemoveAssetDialog = ({ open, onClose, asset }) => {
// `null` means asset is deleted
const { removeAsset } = useRemoveAsset(() => onClose(null));
const { removeAsset } = useRemoveAsset(() => {
onClose(null);
});
const handleConfirm = async () => {
const handleConfirm = async (event) => {
event.preventDefault();
await removeAsset(asset.id);
};

View File

@ -485,7 +485,8 @@ exports[`<EditAssetDialog /> renders and matches the snapshot 1`] = `
.c24 {
position: relative;
text-align: center;
display: flex;
justify-content: center;
background: repeating-conic-gradient( #f6f6f9 0% 25%, transparent 0% 50% ) 50%/20px 20px;
}

View File

@ -485,7 +485,8 @@ exports[`<EditAssetDialog /> renders and matches the snapshot 1`] = `
.c24 {
position: relative;
text-align: center;
display: flex;
justify-content: center;
background: repeating-conic-gradient( #f6f6f9 0% 25%, transparent 0% 50% ) 50%/20px 20px;
}

View File

@ -179,38 +179,44 @@ export const MediaLibraryInput = forwardRef(
trackedLocation="content-manager"
/>
<AssetDialog
allowedTypes={fieldAllowedTypes}
initiallySelectedAssets={initiallySelectedAssets}
folderId={folderId}
onClose={() => {
setStep(undefined);
setFolderId(null);
}}
open={step === STEPS.AssetSelect}
onValidate={handleValidation}
multiple={multiple}
onAddAsset={() => setStep(STEPS.AssetUpload)}
onAddFolder={() => setStep(STEPS.FolderCreate)}
onChangeFolder={(folder) => setFolderId(folder)}
trackedLocation="content-manager"
/>
{step === STEPS.AssetSelect && (
<AssetDialog
allowedTypes={fieldAllowedTypes}
initiallySelectedAssets={initiallySelectedAssets}
folderId={folderId}
onClose={() => {
setStep(undefined);
setFolderId(null);
}}
open={step === STEPS.AssetSelect}
onValidate={handleValidation}
multiple={multiple}
onAddAsset={() => setStep(STEPS.AssetUpload)}
onAddFolder={() => setStep(STEPS.FolderCreate)}
onChangeFolder={(folder) => setFolderId(folder)}
trackedLocation="content-manager"
/>
)}
<UploadAssetDialog
open={step === STEPS.AssetUpload}
onClose={() => setStep(STEPS.AssetSelect)}
initialAssetsToAdd={droppedAssets}
addUploadedFiles={handleFilesUploadSucceeded}
trackedLocation="content-manager"
folderId={folderId}
validateAssetsTypes={validateAssetsTypes}
/>
{step === STEPS.AssetUpload && (
<UploadAssetDialog
open={step === STEPS.AssetUpload}
onClose={() => setStep(STEPS.AssetSelect)}
initialAssetsToAdd={droppedAssets}
addUploadedFiles={handleFilesUploadSucceeded}
trackedLocation="content-manager"
folderId={folderId}
validateAssetsTypes={validateAssetsTypes}
/>
)}
<EditFolderDialog
open={step === STEPS.FolderCreate}
onClose={() => setStep(STEPS.AssetSelect)}
parentFolderId={folderId}
/>
{step === STEPS.FolderCreate && (
<EditFolderDialog
open={step === STEPS.FolderCreate}
onClose={() => setStep(STEPS.AssetSelect)}
parentFolderId={folderId}
/>
)}
</>
);
}

View File

@ -199,6 +199,11 @@ const getSelectStyles = (theme, error) => {
color: theme.colors.neutral800,
gridTemplateColumns: '0 100%',
}),
menuPortal: (base) => ({
...base,
zIndex: theme.zIndices.dialog,
pointerEvents: 'auto',
}),
menu(base) {
return {
...base,
@ -220,10 +225,6 @@ const getSelectStyles = (theme, error) => {
paddingRight: theme.spaces[1],
paddingBottom: theme.spaces[1],
}),
menuPortal: (base) => ({
...base,
zIndex: 100,
}),
option(base, state) {
let backgroundColor = base.backgroundColor;

View File

@ -77,7 +77,7 @@ export const PendingAssetStep = ({
};
return (
<form onSubmit={handleSubmit}>
<>
<Modal.Header>
<Modal.Title>
{formatMessage({
@ -159,7 +159,7 @@ export const PendingAssetStep = ({
<Button onClick={onClose} variant="tertiary">
{formatMessage({ id: 'app.components.Button.cancel', defaultMessage: 'cancel' })}
</Button>
<Button type="submit" loading={uploadStatus === Status.Uploading}>
<Button onClick={handleSubmit} loading={uploadStatus === Status.Uploading}>
{formatMessage(
{
id: getTrad('modal.upload-list.footer.button'),
@ -170,7 +170,7 @@ export const PendingAssetStep = ({
)}
</Button>
</Modal.Footer>
</form>
</>
);
};

View File

@ -93,16 +93,18 @@ export const UploadAssetDialog = ({
return (
<Modal.Root open={open} onOpenChange={handleClose}>
<Modal.Content>
{step === Steps.AddAsset && (
{step === Steps.AddAsset && (
<Modal.Content>
<AddAssetStep
onClose={onClose}
onAddAsset={handleAddToPendingAssets}
trackedLocation={trackedLocation}
/>
)}
</Modal.Content>
)}
{step === Steps.PendingAsset && (
{step === Steps.PendingAsset && (
<Modal.Content>
<PendingAssetStep
onClose={handleClose}
assets={assets}
@ -116,9 +118,11 @@ export const UploadAssetDialog = ({
folderId={folderId}
trackedLocation={trackedLocation}
/>
)}
</Modal.Content>
)}
{assetToEdit && (
{assetToEdit && (
<Modal.Content>
<EditAssetContent
onClose={handleAssetEditValidation}
asset={assetToEdit}
@ -127,8 +131,8 @@ export const UploadAssetDialog = ({
canDownload={false}
trackedLocation={trackedLocation}
/>
)}
</Modal.Content>
</Modal.Content>
)}
</Modal.Root>
);
};

View File

@ -44,7 +44,7 @@ const ConfigureTheView = ({ config }) => {
const handleConfirm = async () => {
trackUsage('willEditMediaLibraryConfig');
await mutateConfig.mutateAsync(modifiedData);
toggleWarningSubmit();
setWarningSubmit(false);
dispatch(setLoaded());
toggleNotification({
type: 'success',

View File

@ -6,7 +6,7 @@ import { ArrowLeft, Plus } from '@strapi/icons';
import PropTypes from 'prop-types';
import { stringify } from 'qs';
import { useIntl } from 'react-intl';
import { useLocation } from 'react-router-dom';
import { useLocation, NavLink } from 'react-router-dom';
import { Breadcrumbs } from '../../../../components/Breadcrumbs';
import { BreadcrumbsDefinition, FolderDefinition } from '../../../../constants';
@ -51,6 +51,7 @@ export const Header = ({
navigationAction={
folder && (
<Link
tag={NavLink}
startIcon={<ArrowLeft />}
to={`${pathname}?${stringify(backQuery, { encode: false })}`}
>

View File

@ -262,10 +262,11 @@ exports[`Header renders 1`] = `
class="c1"
>
<a
aria-current="page"
aria-disabled="false"
class="c2 c3"
class="c2 c3 active"
href="/?folder=2&folderPath=/1"
target="_self"
to="/?folder=2&folderPath=/1"
>
<svg
fill="currentColor"

View File

@ -486,35 +486,41 @@ export const MediaLibrary = () => {
</Pagination.Root>
</Layouts.Content>
</Page.Main>
<UploadAssetDialog
open={showUploadAssetDialog}
onClose={toggleUploadAssetDialog}
trackedLocation="upload"
folderId={query?.folder}
/>
<EditFolderDialog
open={showEditFolderDialog}
onClose={handleEditFolderClose}
folder={folderToEdit}
parentFolderId={query?.folder}
location="upload"
/>
<EditAssetDialog
onClose={(editedAsset) => {
// The asset has been deleted
if (editedAsset === null) {
handleAssetDeleted(1);
}
{showUploadAssetDialog && (
<UploadAssetDialog
open={showUploadAssetDialog}
onClose={toggleUploadAssetDialog}
trackedLocation="upload"
folderId={query?.folder}
/>
)}
{showEditFolderDialog && (
<EditFolderDialog
open={showEditFolderDialog}
onClose={handleEditFolderClose}
folder={folderToEdit}
parentFolderId={query?.folder}
location="upload"
/>
)}
{assetToEdit && (
<EditAssetDialog
onClose={(editedAsset) => {
// The asset has been deleted
if (editedAsset === null) {
handleAssetDeleted(1);
}
setAssetToEdit(undefined);
}}
open={!!assetToEdit}
asset={assetToEdit}
canUpdate={canUpdate}
canCopyLink={canCopyLink}
canDownload={canDownload}
trackedLocation="upload"
/>
setAssetToEdit(undefined);
}}
open={!!assetToEdit}
asset={assetToEdit}
canUpdate={canUpdate}
canCopyLink={canCopyLink}
canDownload={canDownload}
trackedLocation="upload"
/>
)}
</Layouts.Root>
);
};

View File

@ -475,7 +475,7 @@ describe('CM API - Number of draft relations', () => {
});
// Given products have a oneToMany relation with categories, adding categoryIds[0] here // steals the relation from p1. Hence why we are expecting totalDraftRelations to equal 3 below
const p2 = await rq({
method: 'POST',
url: `/content-manager/collection-types/${UID_PRODUCT}`,