From 490a895f51160b0437edf4e423597046d7cec09e Mon Sep 17 00:00:00 2001 From: Ricky Smith Date: Wed, 24 Jul 2024 11:55:40 +0200 Subject: [PATCH 1/2] Allow setting `readOnly` on `FileSelect` --- .../admin/admin/src/form/file/FileSelect.tsx | 104 +++++++++++------- .../src/form/file/fileSelectItemTypes.ts | 2 +- storybook/src/admin/form/file/FileSelect.tsx | 2 + .../FileSelect/FileSelect.stories.mdx | 6 + .../FileSelect/FileSelect.stories.tsx | 28 +++++ 5 files changed, 99 insertions(+), 43 deletions(-) diff --git a/packages/admin/admin/src/form/file/FileSelect.tsx b/packages/admin/admin/src/form/file/FileSelect.tsx index b6d0ee71f3..16a5f9b03e 100644 --- a/packages/admin/admin/src/form/file/FileSelect.tsx +++ b/packages/admin/admin/src/form/file/FileSelect.tsx @@ -3,7 +3,7 @@ import { ComponentsOverrides, FormHelperText, Typography } from "@mui/material"; import { css, Theme, useThemeProps } from "@mui/material/styles"; import * as React from "react"; import { Accept, DropzoneOptions } from "react-dropzone"; -import { FormattedMessage } from "react-intl"; +import { FormattedMessage, useIntl } from "react-intl"; import { Alert } from "../../alert/Alert"; import { createComponentSlot } from "../../helpers/createComponentSlot"; @@ -40,6 +40,7 @@ export type FileSelectProps> onRemove: (file: FileSelectItem) => void; onDownload?: (file: FileSelectItem) => void; disabled?: boolean; + readOnly?: boolean; accept?: Accept; maxFileSize?: number; maxFiles?: number; @@ -53,6 +54,7 @@ export type FileSelectProps> export const FileSelect = ,>(inProps: FileSelectProps) => { const { slotProps, + readOnly, disabled, accept, maxFileSize, @@ -71,6 +73,7 @@ export const FileSelect = ,> }); const { error: errorIcon = } = iconMapping; + const intl = useIntl(); const multiple = passedMultiple || (typeof passedMaxFiles !== "undefined" && passedMaxFiles > 1); const maxFiles = typeof passedMaxFiles === "undefined" ? (multiple ? undefined : 1) : passedMaxFiles; @@ -79,51 +82,68 @@ export const FileSelect = ,> const maxAmountOfFilesSelected = typeof maxFiles !== "undefined" && multiple && numberOfValidFiles >= maxFiles; const maxNumberOfFilesToBeAdded = maxFiles ? maxFiles - numberOfValidFiles : undefined; const filesInfoText = getFilesInfoText(maxFiles, maxFileSize); + const showFileList = files.length > 0 || readOnly; return ( - {maxAmountOfFilesSelected ? ( - } - severity="info" - {...slotProps?.maxFilesReachedInfo} - > - - - ) : ( - + {!readOnly && ( + <> + {maxAmountOfFilesSelected ? ( + } + severity="info" + {...slotProps?.maxFilesReachedInfo} + > + + + ) : ( + + )} + )} - {files.length > 0 && ( + {showFileList && ( - {files.map((file, index) => { - return ( - { - onDownload(file); - } - } - onClickDelete={() => onRemove(file)} - {...slotProps?.fileListItem} - /> - ); - })} + {files.length > 0 ? ( + <> + {files.map((file, index) => ( + { + onDownload(file); + } + } + onClickDelete={readOnly ? undefined : () => onRemove(file)} + {...slotProps?.fileListItem} + /> + ))} + + ) : ( + + )} )} {Boolean(error) && ( @@ -134,7 +154,7 @@ export const FileSelect = ,> )} - {Boolean(filesInfoText) && {filesInfoText}} + {Boolean(filesInfoText && !readOnly) && {filesInfoText}} ); }; diff --git a/packages/admin/admin/src/form/file/fileSelectItemTypes.ts b/packages/admin/admin/src/form/file/fileSelectItemTypes.ts index 6e8a8a04f5..240a1080d2 100644 --- a/packages/admin/admin/src/form/file/fileSelectItemTypes.ts +++ b/packages/admin/admin/src/form/file/fileSelectItemTypes.ts @@ -2,7 +2,7 @@ import { ReactNode } from "react"; export type ValidFileSelectItem> = { name: string; - size: number; + size?: number; } & AdditionalFileValues; export type ErrorFileSelectItem = { diff --git a/storybook/src/admin/form/file/FileSelect.tsx b/storybook/src/admin/form/file/FileSelect.tsx index 0b37eca5b6..2f9ead5a09 100644 --- a/storybook/src/admin/form/file/FileSelect.tsx +++ b/storybook/src/admin/form/file/FileSelect.tsx @@ -56,6 +56,7 @@ storiesOf("@comet/admin/form/File", module) }; const disabled = boolean("Disabled", false); + const readOnly = boolean("ReadOnly", false); const multiple = boolean("Multiple", false); const hasError = boolean("Has Error", false); const hasMaxFileSize = boolean("Limit file size (5 MB)", false); @@ -80,6 +81,7 @@ storiesOf("@comet/admin/form/File", module) }} files={filesMapping[filesSelection]} disabled={disabled} + readOnly={readOnly} multiple={multiple} maxFileSize={ hasMaxFileSize diff --git a/storybook/src/docs/components/FileSelect/FileSelect.stories.mdx b/storybook/src/docs/components/FileSelect/FileSelect.stories.mdx index edbbceaed1..ead5c2fb19 100644 --- a/storybook/src/docs/components/FileSelect/FileSelect.stories.mdx +++ b/storybook/src/docs/components/FileSelect/FileSelect.stories.mdx @@ -17,3 +17,9 @@ Used to combine `FileDropzone` and `FileSelectListItem` to handle the user's sel + +### ReadOnly FileSelect + + + + diff --git a/storybook/src/docs/components/FileSelect/FileSelect.stories.tsx b/storybook/src/docs/components/FileSelect/FileSelect.stories.tsx index 89cb170a53..ed32eb037a 100644 --- a/storybook/src/docs/components/FileSelect/FileSelect.stories.tsx +++ b/storybook/src/docs/components/FileSelect/FileSelect.stories.tsx @@ -46,4 +46,32 @@ storiesOf("stories/components/FileSelect", module) maxFiles={5} /> ); + }) + .add("ReadOnly FileSelect", () => { + const value: FileSelectItem[] = [ + { + name: "Filename.xyz", + size: 4.3 * 1024 * 1024, // 4.3 MB + }, + { + name: "Another file.png", + size: 568 * 1024, // 568 KB + }, + ]; + + return ( + { + // Handle what happens with the dropped files + }} + onRemove={(file) => { + // Handle remove + }} + onDownload={(file) => { + // Handle download + }} + files={value} + readOnly + /> + ); }); From c5874613fe11de1e624f4131643d54b1cf1039df Mon Sep 17 00:00:00 2001 From: Ricky Smith Date: Wed, 24 Jul 2024 12:06:53 +0200 Subject: [PATCH 2/2] Make `onDrop` and `onRemove` optional as they are not needed when `readOnly` is set --- packages/admin/admin/src/form/file/FileSelect.tsx | 6 +++--- .../src/docs/components/FileSelect/FileSelect.stories.tsx | 6 ------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/admin/admin/src/form/file/FileSelect.tsx b/packages/admin/admin/src/form/file/FileSelect.tsx index 16a5f9b03e..b86860f48b 100644 --- a/packages/admin/admin/src/form/file/FileSelect.tsx +++ b/packages/admin/admin/src/form/file/FileSelect.tsx @@ -36,8 +36,8 @@ type ThemeProps = ThemedComponentBaseProps<{ export type FileSelectProps> = { files: FileSelectItem[]; - onDrop: DropzoneOptions["onDrop"]; - onRemove: (file: FileSelectItem) => void; + onDrop?: DropzoneOptions["onDrop"]; + onRemove?: (file: FileSelectItem) => void; onDownload?: (file: FileSelectItem) => void; disabled?: boolean; readOnly?: boolean; @@ -128,7 +128,7 @@ export const FileSelect = ,> onDownload(file); } } - onClickDelete={readOnly ? undefined : () => onRemove(file)} + onClickDelete={readOnly || !onRemove ? undefined : () => onRemove(file)} {...slotProps?.fileListItem} /> ))} diff --git a/storybook/src/docs/components/FileSelect/FileSelect.stories.tsx b/storybook/src/docs/components/FileSelect/FileSelect.stories.tsx index ed32eb037a..a076d50d81 100644 --- a/storybook/src/docs/components/FileSelect/FileSelect.stories.tsx +++ b/storybook/src/docs/components/FileSelect/FileSelect.stories.tsx @@ -61,12 +61,6 @@ storiesOf("stories/components/FileSelect", module) return ( { - // Handle what happens with the dropped files - }} - onRemove={(file) => { - // Handle remove - }} onDownload={(file) => { // Handle download }}