diff --git a/packages/next/src/views/List/Default/index.tsx b/packages/next/src/views/List/Default/index.tsx index c29e2eccd..2e7c37353 100644 --- a/packages/next/src/views/List/Default/index.tsx +++ b/packages/next/src/views/List/Default/index.tsx @@ -133,19 +133,31 @@ export const DefaultListView: React.FC = () => { {Header || ( {hasCreatePermission && ( - + <> + + + {isBulkUploadEnabled && ( + + )} + )} {!smallBreak && ( diff --git a/packages/ui/src/elements/BulkUpload/AddFilesView/index.tsx b/packages/ui/src/elements/BulkUpload/AddFilesView/index.tsx index 4ebc8fb6e..18e0b5269 100644 --- a/packages/ui/src/elements/BulkUpload/AddFilesView/index.tsx +++ b/packages/ui/src/elements/BulkUpload/AddFilesView/index.tsx @@ -40,6 +40,7 @@ export function AddFilesView({ onCancel, onDrop }: Props) { aria-hidden="true" className={`${baseClass}__hidden-input`} hidden + multiple onChange={(e) => { if (e.target.files && e.target.files.length > 0) { onDrop(e.target.files) @@ -53,7 +54,6 @@ export function AddFilesView({ onCancel, onDrop }: Props) { {t('general:or')} {t('upload:dragAndDrop')}

- {/* */} ) diff --git a/packages/ui/src/elements/Dropzone/index.scss b/packages/ui/src/elements/Dropzone/index.scss index 3e336c64f..c1dbb1d94 100644 --- a/packages/ui/src/elements/Dropzone/index.scss +++ b/packages/ui/src/elements/Dropzone/index.scss @@ -4,7 +4,7 @@ position: relative; display: flex; align-items: center; - padding: calc(var(--base) * .9) calc(var(--base) / 2); + padding: calc(var(--base) * .9) var(--base); background: transparent; border: 1px dotted var(--theme-elevation-400); border-radius: var(--style-radius-s); diff --git a/packages/ui/src/elements/Table/DefaultCell/fields/File/index.scss b/packages/ui/src/elements/Table/DefaultCell/fields/File/index.scss index 14ea81fac..846db8b63 100644 --- a/packages/ui/src/elements/Table/DefaultCell/fields/File/index.scss +++ b/packages/ui/src/elements/Table/DefaultCell/fields/File/index.scss @@ -3,21 +3,21 @@ .file { display: flex; flex-wrap: nowrap; - margin: base(-0.25) 0; &__thumbnail { display: inline-block; - max-width: base(3); - height: base(3); + max-width: calc(var(--base) * 2); + height: calc(var(--base) * 2); + border-radius: var(--style-radius-s); } &__filename { align-self: center; [dir='ltr'] & { - margin-left: base(1); + margin-left: var(--base); } [dir='rtl'] & { - margin-right: base(1); + margin-right: var(--base); } } } diff --git a/packages/ui/src/elements/Upload/index.scss b/packages/ui/src/elements/Upload/index.scss index e26eb86b3..4f687eeb1 100644 --- a/packages/ui/src/elements/Upload/index.scss +++ b/packages/ui/src/elements/Upload/index.scss @@ -28,6 +28,7 @@ width: 100%; height: 100%; object-fit: contain; + border-radius: var(--style-radius-s) 0 0 var(--style-radius-s); } } @@ -85,11 +86,30 @@ .dropzone { background-color: transparent; + padding-block: calc(var(--base) * 2.25); + } + + &__dropzoneContent { + display: flex; + justify-content: space-between; + width: 100%; } &__dropzoneButtons { display: flex; - gap: var(--base); + gap: calc(var(--base) * .5); + } + + &__orText { + color: var(--theme-elevation-500); + text-transform: lowercase; + } + + &__dragAndDropText { + margin: 0; + text-transform: lowercase; + align-self: center; + color: var(--theme-elevation-500); } @include small-break { @@ -123,4 +143,10 @@ display: none; } } + + @include small-break { + &__dropzoneContent { + display: none; + } + } } diff --git a/packages/ui/src/elements/Upload/index.tsx b/packages/ui/src/elements/Upload/index.tsx index b50a6df65..995e860c0 100644 --- a/packages/ui/src/elements/Upload/index.tsx +++ b/packages/ui/src/elements/Upload/index.tsx @@ -235,43 +235,46 @@ export const Upload: React.FC = (props) => {
{!value && !showUrlInput && ( -
- - { - if (e.target.files && e.target.files.length > 0) { - handleFileSelection(e.target.files) - } - }} - ref={inputRef} - type="file" - /> - +
+
+ + { + if (e.target.files && e.target.files.length > 0) { + handleFileSelection(e.target.files) + } + }} + ref={inputRef} + type="file" + /> + {t('general:or')} + +
+ +

+ {t('general:or')} {t('upload:dragAndDrop')} +

)} diff --git a/packages/ui/src/fields/Upload/Input.tsx b/packages/ui/src/fields/Upload/Input.tsx index 1ad5dce38..1609b4a93 100644 --- a/packages/ui/src/fields/Upload/Input.tsx +++ b/packages/ui/src/fields/Upload/Input.tsx @@ -25,9 +25,11 @@ import type { ListDrawerProps } from '../../elements/ListDrawer/types.js' import { useBulkUpload } from '../../elements/BulkUpload/index.js' import { Button } from '../../elements/Button/index.js' +import { useDocumentDrawer } from '../../elements/DocumentDrawer/index.js' import { Dropzone } from '../../elements/Dropzone/index.js' import { useListDrawer } from '../../elements/ListDrawer/index.js' import { ShimmerEffect } from '../../elements/ShimmerEffect/index.js' +import { PlusIcon } from '../../icons/Plus/index.js' import { useAuth } from '../../providers/Auth/index.js' import { useLocale } from '../../providers/Locale/index.js' import { useTranslation } from '../../providers/Translation/index.js' @@ -143,8 +145,14 @@ export function UploadInput(props: UploadInputProps) { collectionSlugs: typeof relationTo === 'string' ? [relationTo] : relationTo, filterOptions, }) + const [ + CreateDocDrawer, + _, + { closeDrawer: closeCreateDocDrawer, openDrawer: openCreateDocDrawer }, + ] = useDocumentDrawer({ + collectionSlug: activeRelationTo, + }) - const inputRef = React.useRef(null) const loadedValueDocsRef = React.useRef(false) const canCreate = useMemo(() => { @@ -242,7 +250,7 @@ export function UploadInput(props: UploadInputProps) { [value, onChange, activeRelationTo, hasMany], ) - const onFileSelection = React.useCallback( + const onLocalFileSelection = React.useCallback( (fileList?: FileList) => { let fileListToUse = fileList if (!hasMany && fileList && fileList.length > 1) { @@ -295,6 +303,24 @@ export function UploadInput(props: UploadInputProps) { [activeRelationTo, closeListDrawer, onChange, populateDocs, value], ) + const onDocCreate = React.useCallback( + (data) => { + if (data.doc) { + setPopulatedDocs((currentDocs) => [ + ...(currentDocs || []), + { + relationTo: activeRelationTo, + value: data.doc, + }, + ]) + + onChange(data.doc.id) + } + closeCreateDocDrawer() + }, + [closeCreateDocDrawer, activeRelationTo, onChange], + ) + const onListSelect = React.useCallback>( async ({ collectionSlug, docID }) => { const loadedDocs = await populateDocs([docID], collectionSlug) @@ -445,20 +471,18 @@ export function UploadInput(props: UploadInputProps) { ) : null} {showDropzone ? ( - +
- { - if (e.target.files && e.target.files.length > 0) { - onFileSelection(e.target.files) - } - }} - ref={inputRef} - type="file" - /> + {t('general:or')} - + +