fix(ui): field bulk upload showing stale data (#13006)
This commit is contained in:
@@ -146,7 +146,7 @@ export const DefaultTemplate: React.FC<DefaultTemplateProps> = ({
|
||||
|
||||
return (
|
||||
<EntityVisibilityProvider visibleEntities={visibleEntities}>
|
||||
<BulkUploadProvider>
|
||||
<BulkUploadProvider drawerSlugPrefix={collectionSlug}>
|
||||
<ActionsProvider Actions={Actions}>
|
||||
{RenderServerComponent({
|
||||
clientProps,
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import { useRouter, useSearchParams } from 'next/navigation.js'
|
||||
import { formatAdminURL } from 'payload/shared'
|
||||
import React, { useCallback, useEffect } from 'react'
|
||||
|
||||
import type { EditFormProps } from './types.js'
|
||||
@@ -12,9 +10,7 @@ import { WatchChildErrors } from '../../../forms/WatchChildErrors/index.js'
|
||||
import { useConfig } from '../../../providers/Config/index.js'
|
||||
import { useDocumentEvents } from '../../../providers/DocumentEvents/index.js'
|
||||
import { useDocumentInfo } from '../../../providers/DocumentInfo/index.js'
|
||||
import { useEditDepth } from '../../../providers/EditDepth/index.js'
|
||||
import { OperationProvider } from '../../../providers/Operation/index.js'
|
||||
import { useRouteTransition } from '../../../providers/RouteTransition/index.js'
|
||||
import { useServerFunctions } from '../../../providers/ServerFunctions/index.js'
|
||||
import { abortAndIgnore, handleAbortRef } from '../../../utilities/abortAndIgnore.js'
|
||||
import { useDocumentDrawerContext } from '../../DocumentDrawer/Provider.js'
|
||||
@@ -23,7 +19,6 @@ import { MoveDocToFolder } from '../../FolderView/MoveDocToFolder/index.js'
|
||||
import { Upload_v4 } from '../../Upload/index.js'
|
||||
import { useFormsManager } from '../FormsManager/index.js'
|
||||
import './index.scss'
|
||||
import { BulkUploadProvider } from '../index.js'
|
||||
|
||||
const baseClass = 'collection-edit'
|
||||
|
||||
@@ -44,7 +39,6 @@ export function EditForm({
|
||||
getDocPreferences,
|
||||
hasSavePermission,
|
||||
initialState,
|
||||
isEditing,
|
||||
isInitializing,
|
||||
Upload: CustomUpload,
|
||||
} = useDocumentInfo()
|
||||
@@ -54,23 +48,14 @@ export function EditForm({
|
||||
const { getFormState } = useServerFunctions()
|
||||
|
||||
const {
|
||||
config: {
|
||||
folders,
|
||||
routes: { admin: adminRoute },
|
||||
},
|
||||
config: { folders },
|
||||
getEntityConfig,
|
||||
} = useConfig()
|
||||
|
||||
const abortOnChangeRef = React.useRef<AbortController>(null)
|
||||
|
||||
const collectionConfig = getEntityConfig({ collectionSlug: docSlug })
|
||||
const router = useRouter()
|
||||
const depth = useEditDepth()
|
||||
const params = useSearchParams()
|
||||
const { reportUpdate } = useDocumentEvents()
|
||||
const { startRouteTransition } = useRouteTransition()
|
||||
|
||||
const locale = params.get('locale')
|
||||
|
||||
const collectionSlug = collectionConfig.slug
|
||||
|
||||
@@ -89,31 +74,9 @@ export function EditForm({
|
||||
operation: 'create',
|
||||
})
|
||||
}
|
||||
|
||||
if (!isEditing && depth < 2) {
|
||||
// Redirect to the same locale if it's been set
|
||||
const redirectRoute = formatAdminURL({
|
||||
adminRoute,
|
||||
path: `/collections/${collectionSlug}/${json?.doc?.id}${locale ? `?locale=${locale}` : ''}`,
|
||||
})
|
||||
|
||||
startRouteTransition(() => router.push(redirectRoute))
|
||||
} else {
|
||||
resetUploadEdits()
|
||||
}
|
||||
resetUploadEdits()
|
||||
},
|
||||
[
|
||||
adminRoute,
|
||||
collectionSlug,
|
||||
depth,
|
||||
isEditing,
|
||||
locale,
|
||||
onSaveFromContext,
|
||||
reportUpdate,
|
||||
resetUploadEdits,
|
||||
router,
|
||||
startRouteTransition,
|
||||
],
|
||||
[collectionSlug, onSaveFromContext, reportUpdate, resetUploadEdits],
|
||||
)
|
||||
|
||||
const onChange: NonNullable<FormProps['onChange']>[0] = useCallback(
|
||||
@@ -150,54 +113,52 @@ export function EditForm({
|
||||
|
||||
return (
|
||||
<OperationProvider operation="create">
|
||||
<BulkUploadProvider>
|
||||
<Form
|
||||
action={action}
|
||||
className={`${baseClass}__form`}
|
||||
disabled={isInitializing || !hasSavePermission}
|
||||
initialState={isInitializing ? undefined : initialState}
|
||||
isInitializing={isInitializing}
|
||||
method="POST"
|
||||
onChange={[onChange]}
|
||||
onSuccess={onSave}
|
||||
submitted={submitted}
|
||||
>
|
||||
<DocumentFields
|
||||
BeforeFields={
|
||||
<React.Fragment>
|
||||
{CustomUpload || (
|
||||
<Upload_v4
|
||||
collectionSlug={collectionConfig.slug}
|
||||
customActions={[
|
||||
folders && collectionConfig.folders && (
|
||||
<MoveDocToFolder
|
||||
buttonProps={{
|
||||
buttonStyle: 'pill',
|
||||
size: 'small',
|
||||
}}
|
||||
folderCollectionSlug={folders.slug}
|
||||
folderFieldName={folders.fieldName}
|
||||
key="move-doc-to-folder"
|
||||
/>
|
||||
),
|
||||
].filter(Boolean)}
|
||||
initialState={initialState}
|
||||
resetUploadEdits={resetUploadEdits}
|
||||
updateUploadEdits={updateUploadEdits}
|
||||
uploadConfig={collectionConfig.upload}
|
||||
uploadEdits={uploadEdits}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
}
|
||||
docPermissions={docPermissions}
|
||||
fields={collectionConfig.fields}
|
||||
schemaPathSegments={[collectionConfig.slug]}
|
||||
/>
|
||||
<ReportAllErrors />
|
||||
<GetFieldProxy />
|
||||
</Form>
|
||||
</BulkUploadProvider>
|
||||
<Form
|
||||
action={action}
|
||||
className={`${baseClass}__form`}
|
||||
disabled={isInitializing || !hasSavePermission}
|
||||
initialState={isInitializing ? undefined : initialState}
|
||||
isInitializing={isInitializing}
|
||||
method="POST"
|
||||
onChange={[onChange]}
|
||||
onSuccess={onSave}
|
||||
submitted={submitted}
|
||||
>
|
||||
<DocumentFields
|
||||
BeforeFields={
|
||||
<React.Fragment>
|
||||
{CustomUpload || (
|
||||
<Upload_v4
|
||||
collectionSlug={collectionConfig.slug}
|
||||
customActions={[
|
||||
folders && collectionConfig.folders && (
|
||||
<MoveDocToFolder
|
||||
buttonProps={{
|
||||
buttonStyle: 'pill',
|
||||
size: 'small',
|
||||
}}
|
||||
folderCollectionSlug={folders.slug}
|
||||
folderFieldName={folders.fieldName}
|
||||
key="move-doc-to-folder"
|
||||
/>
|
||||
),
|
||||
].filter(Boolean)}
|
||||
initialState={initialState}
|
||||
resetUploadEdits={resetUploadEdits}
|
||||
updateUploadEdits={updateUploadEdits}
|
||||
uploadConfig={collectionConfig.upload}
|
||||
uploadEdits={uploadEdits}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
}
|
||||
docPermissions={docPermissions}
|
||||
fields={collectionConfig.fields}
|
||||
schemaPathSegments={[collectionConfig.slug]}
|
||||
/>
|
||||
<ReportAllErrors />
|
||||
<GetFieldProxy />
|
||||
</Form>
|
||||
</OperationProvider>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -11,9 +11,11 @@ import type { FormProps } from '../../../forms/Form/index.js'
|
||||
import type { OnFieldSelect } from '../../FieldSelect/index.js'
|
||||
import type { FieldOption } from '../../FieldSelect/reduceFieldOptions.js'
|
||||
import type { State } from '../FormsManager/reducer.js'
|
||||
import type { EditManyBulkUploadsProps } from './index.js'
|
||||
|
||||
import { Button } from '../../../elements/Button/index.js'
|
||||
import { Form } from '../../../forms/Form/index.js'
|
||||
import { FieldPathContext } from '../../../forms/RenderFields/context.js'
|
||||
import { RenderField } from '../../../forms/RenderFields/RenderField.js'
|
||||
import { XIcon } from '../../../icons/X/index.js'
|
||||
import { useAuth } from '../../../providers/Auth/index.js'
|
||||
@@ -22,7 +24,7 @@ import { useTranslation } from '../../../providers/Translation/index.js'
|
||||
import { abortAndIgnore, handleAbortRef } from '../../../utilities/abortAndIgnore.js'
|
||||
import { FieldSelect } from '../../FieldSelect/index.js'
|
||||
import { useFormsManager } from '../FormsManager/index.js'
|
||||
import { baseClass, type EditManyBulkUploadsProps } from './index.js'
|
||||
import { baseClass } from './index.js'
|
||||
import './index.scss'
|
||||
import '../../../forms/RenderFields/index.scss'
|
||||
|
||||
@@ -169,23 +171,25 @@ export const EditManyBulkUploadsDrawerContent: React.FC<
|
||||
/>
|
||||
{selectedFields.length === 0 ? null : (
|
||||
<div className="render-fields">
|
||||
{selectedFields.map((option, i) => {
|
||||
const {
|
||||
value: { field, fieldPermissions, path },
|
||||
} = option
|
||||
<FieldPathContext value={undefined}>
|
||||
{selectedFields.map((option, i) => {
|
||||
const {
|
||||
value: { field, fieldPermissions, path },
|
||||
} = option
|
||||
|
||||
return (
|
||||
<RenderField
|
||||
clientFieldConfig={field}
|
||||
indexPath=""
|
||||
key={`${path}-${i}`}
|
||||
parentPath=""
|
||||
parentSchemaPath=""
|
||||
path={path}
|
||||
permissions={fieldPermissions}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
return (
|
||||
<RenderField
|
||||
clientFieldConfig={field}
|
||||
indexPath=""
|
||||
key={`${path}-${i}`}
|
||||
parentPath=""
|
||||
parentSchemaPath=""
|
||||
path={path}
|
||||
permissions={fieldPermissions}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</FieldPathContext>
|
||||
</div>
|
||||
)}
|
||||
<div className={`${baseClass}__sidebar-wrap`}>
|
||||
|
||||
@@ -118,7 +118,7 @@ export function FormsManagerProvider({ children }: FormsManagerProps) {
|
||||
|
||||
const { toggleLoadingOverlay } = useLoadingOverlay()
|
||||
const { closeModal } = useModal()
|
||||
const { collectionSlug, drawerSlug, initialFiles, onSuccess } = useBulkUpload()
|
||||
const { collectionSlug, drawerSlug, initialFiles, onSuccess, setInitialFiles } = useBulkUpload()
|
||||
|
||||
const [isUploading, setIsUploading] = React.useState(false)
|
||||
const [loadingText, setLoadingText] = React.useState('')
|
||||
@@ -366,13 +366,10 @@ export function FormsManagerProvider({ children }: FormsManagerProps) {
|
||||
setIsUploading(false)
|
||||
|
||||
const remainingForms = []
|
||||
const thumbnailIndexesToRemove = []
|
||||
|
||||
currentForms.forEach(({ errorCount }, i) => {
|
||||
if (errorCount) {
|
||||
remainingForms.push(currentForms[i])
|
||||
} else {
|
||||
thumbnailIndexesToRemove.push(i)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -401,8 +398,13 @@ export function FormsManagerProvider({ children }: FormsManagerProps) {
|
||||
totalErrorCount: remainingForms.reduce((acc, { errorCount }) => acc + errorCount, 0),
|
||||
},
|
||||
})
|
||||
|
||||
if (remainingForms.length === 0) {
|
||||
setInitialFiles(undefined)
|
||||
}
|
||||
},
|
||||
[
|
||||
setInitialFiles,
|
||||
actionURL,
|
||||
collectionSlug,
|
||||
getUploadHandler,
|
||||
|
||||
@@ -89,61 +89,57 @@ export function BulkUploadDrawer() {
|
||||
|
||||
type BulkUploadContext = {
|
||||
collectionSlug: string
|
||||
currentActivePath: string
|
||||
drawerSlug: string
|
||||
initialFiles: FileList
|
||||
maxFiles: number
|
||||
onCancel: () => void
|
||||
onSuccess: (newDocs: JsonObject[], errorCount: number) => void
|
||||
setCollectionSlug: (slug: string) => void
|
||||
setCurrentActivePath: (path: string) => void
|
||||
setInitialFiles: (files: FileList) => void
|
||||
setMaxFiles: (maxFiles: number) => void
|
||||
setOnCancel: (onCancel: BulkUploadContext['onCancel']) => void
|
||||
setOnSuccess: (path: string, onSuccess: BulkUploadContext['onSuccess']) => void
|
||||
setOnSuccess: (onSuccess: BulkUploadContext['onSuccess']) => void
|
||||
}
|
||||
|
||||
const Context = React.createContext<BulkUploadContext>({
|
||||
collectionSlug: '',
|
||||
currentActivePath: undefined,
|
||||
drawerSlug: '',
|
||||
initialFiles: undefined,
|
||||
maxFiles: undefined,
|
||||
onCancel: () => null,
|
||||
onSuccess: () => null,
|
||||
setCollectionSlug: () => null,
|
||||
setCurrentActivePath: () => null,
|
||||
setInitialFiles: () => null,
|
||||
setMaxFiles: () => null,
|
||||
setOnCancel: () => null,
|
||||
setOnSuccess: () => null,
|
||||
})
|
||||
export function BulkUploadProvider({ children }: { readonly children: React.ReactNode }) {
|
||||
export function BulkUploadProvider({
|
||||
children,
|
||||
drawerSlugPrefix,
|
||||
}: {
|
||||
readonly children: React.ReactNode
|
||||
readonly drawerSlugPrefix?: string
|
||||
}) {
|
||||
const [collection, setCollection] = React.useState<string>()
|
||||
const [onSuccessFunctionMap, setOnSuccessFunctionMap] =
|
||||
React.useState<Record<string, BulkUploadContext['onSuccess']>>()
|
||||
const [onSuccessFunction, setOnSuccessFunction] = React.useState<BulkUploadContext['onSuccess']>()
|
||||
const [onCancelFunction, setOnCancelFunction] = React.useState<BulkUploadContext['onCancel']>()
|
||||
const [initialFiles, setInitialFiles] = React.useState<FileList>(undefined)
|
||||
const [maxFiles, setMaxFiles] = React.useState<number>(undefined)
|
||||
const [currentActivePath, setCurrentActivePath] = React.useState<string>(undefined)
|
||||
const drawerSlug = useBulkUploadDrawerSlug()
|
||||
const drawerSlug = `${drawerSlugPrefix ? `${drawerSlugPrefix}-` : ''}${useBulkUploadDrawerSlug()}`
|
||||
|
||||
const setCollectionSlug: BulkUploadContext['setCollectionSlug'] = (slug) => {
|
||||
setCollection(slug)
|
||||
}
|
||||
|
||||
const setOnSuccess: BulkUploadContext['setOnSuccess'] = React.useCallback((path, onSuccess) => {
|
||||
setOnSuccessFunctionMap((prev) => ({
|
||||
...prev,
|
||||
[path]: onSuccess,
|
||||
}))
|
||||
}, [])
|
||||
const setOnSuccess: BulkUploadContext['setOnSuccess'] = (onSuccess) => {
|
||||
setOnSuccessFunction(() => onSuccess)
|
||||
}
|
||||
|
||||
return (
|
||||
<Context
|
||||
value={{
|
||||
collectionSlug: collection,
|
||||
currentActivePath,
|
||||
drawerSlug,
|
||||
initialFiles,
|
||||
maxFiles,
|
||||
@@ -153,13 +149,11 @@ export function BulkUploadProvider({ children }: { readonly children: React.Reac
|
||||
}
|
||||
},
|
||||
onSuccess: (docIDs, errorCount) => {
|
||||
if (onSuccessFunctionMap && Object.hasOwn(onSuccessFunctionMap, currentActivePath)) {
|
||||
const onSuccessFunction = onSuccessFunctionMap[currentActivePath]
|
||||
if (typeof onSuccessFunction === 'function') {
|
||||
onSuccessFunction(docIDs, errorCount)
|
||||
}
|
||||
},
|
||||
setCollectionSlug,
|
||||
setCurrentActivePath,
|
||||
setInitialFiles,
|
||||
setMaxFiles,
|
||||
setOnCancel: setOnCancelFunction,
|
||||
|
||||
@@ -27,12 +27,7 @@ export function ListBulkUploadButton({
|
||||
*/
|
||||
openBulkUpload?: () => void
|
||||
}) {
|
||||
const {
|
||||
drawerSlug: bulkUploadDrawerSlug,
|
||||
setCollectionSlug,
|
||||
setCurrentActivePath,
|
||||
setOnSuccess,
|
||||
} = useBulkUpload()
|
||||
const { drawerSlug: bulkUploadDrawerSlug, setCollectionSlug, setOnSuccess } = useBulkUpload()
|
||||
const { t } = useTranslation()
|
||||
const { openModal } = useModal()
|
||||
const router = useRouter()
|
||||
@@ -42,9 +37,8 @@ export function ListBulkUploadButton({
|
||||
openBulkUploadFromProps()
|
||||
} else {
|
||||
setCollectionSlug(collectionSlug)
|
||||
setCurrentActivePath(collectionSlug)
|
||||
openModal(bulkUploadDrawerSlug)
|
||||
setOnSuccess(collectionSlug, () => {
|
||||
setOnSuccess(() => {
|
||||
if (typeof onBulkUploadSuccess === 'function') {
|
||||
onBulkUploadSuccess()
|
||||
} else {
|
||||
@@ -58,7 +52,6 @@ export function ListBulkUploadButton({
|
||||
bulkUploadDrawerSlug,
|
||||
openModal,
|
||||
setCollectionSlug,
|
||||
setCurrentActivePath,
|
||||
setOnSuccess,
|
||||
onBulkUploadSuccess,
|
||||
openBulkUploadFromProps,
|
||||
|
||||
@@ -118,14 +118,8 @@ export function UploadInput(props: UploadInputProps) {
|
||||
)
|
||||
|
||||
const { openModal } = useModal()
|
||||
const {
|
||||
drawerSlug,
|
||||
setCollectionSlug,
|
||||
setCurrentActivePath,
|
||||
setInitialFiles,
|
||||
setMaxFiles,
|
||||
setOnSuccess,
|
||||
} = useBulkUpload()
|
||||
const { drawerSlug, setCollectionSlug, setInitialFiles, setMaxFiles, setOnSuccess } =
|
||||
useBulkUpload()
|
||||
const { permissions } = useAuth()
|
||||
const { code } = useLocale()
|
||||
const { i18n, t } = useTranslation()
|
||||
@@ -294,7 +288,6 @@ export function UploadInput(props: UploadInputProps) {
|
||||
if (typeof maxRows === 'number') {
|
||||
setMaxFiles(maxRows)
|
||||
}
|
||||
setCurrentActivePath(path)
|
||||
openModal(drawerSlug)
|
||||
},
|
||||
[
|
||||
@@ -306,8 +299,6 @@ export function UploadInput(props: UploadInputProps) {
|
||||
setInitialFiles,
|
||||
maxRows,
|
||||
setMaxFiles,
|
||||
path,
|
||||
setCurrentActivePath,
|
||||
],
|
||||
)
|
||||
|
||||
@@ -461,7 +452,7 @@ export function UploadInput(props: UploadInputProps) {
|
||||
}, [populateDocs, activeRelationTo, value])
|
||||
|
||||
useEffect(() => {
|
||||
setOnSuccess(path, onUploadSuccess)
|
||||
setOnSuccess(onUploadSuccess)
|
||||
}, [value, path, onUploadSuccess, setOnSuccess])
|
||||
|
||||
const showDropzone =
|
||||
|
||||
@@ -4,12 +4,13 @@ import type { UploadFieldClientProps } from 'payload'
|
||||
|
||||
import React, { useMemo } from 'react'
|
||||
|
||||
import { BulkUploadProvider } from '../../elements/BulkUpload/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
import { useConfig } from '../../providers/Config/index.js'
|
||||
import './index.scss'
|
||||
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||
import { UploadInput } from './Input.js'
|
||||
import './index.scss'
|
||||
|
||||
export { UploadInput } from './Input.js'
|
||||
export type { UploadInputProps } from './Input.js'
|
||||
@@ -62,33 +63,35 @@ export function UploadComponent(props: UploadFieldClientProps) {
|
||||
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||
|
||||
return (
|
||||
<UploadInput
|
||||
AfterInput={AfterInput}
|
||||
allowCreate={allowCreate !== false}
|
||||
api={config.routes.api}
|
||||
BeforeInput={BeforeInput}
|
||||
className={className}
|
||||
Description={Description}
|
||||
description={description}
|
||||
displayPreview={displayPreview}
|
||||
Error={Error}
|
||||
filterOptions={filterOptions}
|
||||
hasMany={hasMany}
|
||||
isSortable={isSortable}
|
||||
label={label}
|
||||
Label={Label}
|
||||
localized={localized}
|
||||
maxRows={maxRows}
|
||||
onChange={setValue}
|
||||
path={path}
|
||||
readOnly={readOnly || disabled}
|
||||
relationTo={relationTo}
|
||||
required={required}
|
||||
serverURL={config.serverURL}
|
||||
showError={showError}
|
||||
style={styles}
|
||||
value={value}
|
||||
/>
|
||||
<BulkUploadProvider drawerSlugPrefix={pathFromProps}>
|
||||
<UploadInput
|
||||
AfterInput={AfterInput}
|
||||
allowCreate={allowCreate !== false}
|
||||
api={config.routes.api}
|
||||
BeforeInput={BeforeInput}
|
||||
className={className}
|
||||
Description={Description}
|
||||
description={description}
|
||||
displayPreview={displayPreview}
|
||||
Error={Error}
|
||||
filterOptions={filterOptions}
|
||||
hasMany={hasMany}
|
||||
isSortable={isSortable}
|
||||
label={label}
|
||||
Label={Label}
|
||||
localized={localized}
|
||||
maxRows={maxRows}
|
||||
onChange={setValue}
|
||||
path={path}
|
||||
readOnly={readOnly || disabled}
|
||||
relationTo={relationTo}
|
||||
required={required}
|
||||
serverURL={config.serverURL}
|
||||
showError={showError}
|
||||
style={styles}
|
||||
value={value}
|
||||
/>
|
||||
</BulkUploadProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -86,12 +86,7 @@ export function DefaultListView(props: ListViewClientProps) {
|
||||
} = useListQuery()
|
||||
|
||||
const { openModal } = useModal()
|
||||
const {
|
||||
drawerSlug: bulkUploadDrawerSlug,
|
||||
setCollectionSlug,
|
||||
setCurrentActivePath,
|
||||
setOnSuccess,
|
||||
} = useBulkUpload()
|
||||
const { drawerSlug: bulkUploadDrawerSlug, setCollectionSlug, setOnSuccess } = useBulkUpload()
|
||||
|
||||
const collectionConfig = getEntityConfig({ collectionSlug })
|
||||
|
||||
@@ -124,18 +119,9 @@ export function DefaultListView(props: ListViewClientProps) {
|
||||
|
||||
const openBulkUpload = React.useCallback(() => {
|
||||
setCollectionSlug(collectionSlug)
|
||||
setCurrentActivePath(collectionSlug)
|
||||
openModal(bulkUploadDrawerSlug)
|
||||
setOnSuccess(collectionSlug, () => router.refresh())
|
||||
}, [
|
||||
router,
|
||||
collectionSlug,
|
||||
bulkUploadDrawerSlug,
|
||||
openModal,
|
||||
setCollectionSlug,
|
||||
setCurrentActivePath,
|
||||
setOnSuccess,
|
||||
])
|
||||
setOnSuccess(() => router.refresh())
|
||||
}, [router, collectionSlug, bulkUploadDrawerSlug, openModal, setCollectionSlug, setOnSuccess])
|
||||
|
||||
useEffect(() => {
|
||||
if (!isInDrawer) {
|
||||
|
||||
@@ -199,15 +199,8 @@ describe('Uploads', () => {
|
||||
await page.locator('.upload-relationship-details__edit').nth(0).click()
|
||||
await page.locator('.file-details__remove').click()
|
||||
|
||||
const fileChooserPromise = page.waitForEvent('filechooser')
|
||||
await page.getByText('Select a file').click()
|
||||
const fileChooser = await fileChooserPromise
|
||||
await wait(1000)
|
||||
await fileChooser.setFiles(path.join(dirname, 'test-image.jpg'))
|
||||
|
||||
await page.locator('button#action-save').nth(1).click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
|
||||
await wait(1000)
|
||||
await page.setInputFiles('input[type="file"]', path.join(dirname, 'test-image.jpg'))
|
||||
await saveDocAndAssert(page, '.doc-drawer button#action-save')
|
||||
|
||||
await page.locator('.doc-drawer__header-close').click()
|
||||
|
||||
@@ -695,16 +688,8 @@ describe('Uploads', () => {
|
||||
test('should upload image with metadata', async () => {
|
||||
await page.goto(withMetadataURL.create)
|
||||
|
||||
const fileChooserPromise = page.waitForEvent('filechooser')
|
||||
await page.getByText('Select a file').click()
|
||||
const fileChooser = await fileChooserPromise
|
||||
await wait(1000)
|
||||
await fileChooser.setFiles(path.join(dirname, 'test-image.jpg'))
|
||||
|
||||
await page.waitForSelector('button#action-save')
|
||||
await page.locator('button#action-save').click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
|
||||
await wait(1000)
|
||||
await page.setInputFiles('input[type="file"]', path.join(dirname, 'test-image.jpg'))
|
||||
await saveDocAndAssert(page)
|
||||
|
||||
const mediaID = page.url().split('/').pop()
|
||||
|
||||
@@ -716,22 +701,16 @@ describe('Uploads', () => {
|
||||
|
||||
const acceptableFileSizes = [9431, 9435]
|
||||
|
||||
expect(acceptableFileSizes).toContain(mediaDoc.sizes.sizeOne.filesize)
|
||||
await expect
|
||||
.poll(() => acceptableFileSizes.includes(mediaDoc.sizes.sizeOne.filesize))
|
||||
.toBe(true)
|
||||
})
|
||||
|
||||
test('should upload image without metadata', async () => {
|
||||
await page.goto(withoutMetadataURL.create)
|
||||
|
||||
const fileChooserPromise = page.waitForEvent('filechooser')
|
||||
await page.getByText('Select a file').click()
|
||||
const fileChooser = await fileChooserPromise
|
||||
await wait(1000)
|
||||
await fileChooser.setFiles(path.join(dirname, 'test-image.jpg'))
|
||||
|
||||
await page.waitForSelector('button#action-save')
|
||||
await page.locator('button#action-save').click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
|
||||
await wait(1000)
|
||||
await page.setInputFiles('input[type="file"]', path.join(dirname, 'test-image.jpg'))
|
||||
await saveDocAndAssert(page)
|
||||
|
||||
const mediaID = page.url().split('/').pop()
|
||||
|
||||
@@ -743,22 +722,16 @@ describe('Uploads', () => {
|
||||
|
||||
const acceptableFileSizes = [2424, 2445]
|
||||
|
||||
expect(acceptableFileSizes).toContain(mediaDoc.sizes.sizeTwo.filesize)
|
||||
await expect
|
||||
.poll(() => acceptableFileSizes.includes(mediaDoc.sizes.sizeTwo.filesize))
|
||||
.toBe(true)
|
||||
})
|
||||
|
||||
test('should only upload image with metadata if jpeg mimetype', async () => {
|
||||
await page.goto(withOnlyJPEGMetadataURL.create)
|
||||
|
||||
const fileChooserPromiseForJPEG = page.waitForEvent('filechooser')
|
||||
await page.getByText('Select a file').click()
|
||||
const fileChooserForJPEG = await fileChooserPromiseForJPEG
|
||||
await wait(1000)
|
||||
await fileChooserForJPEG.setFiles(path.join(dirname, 'test-image.jpg'))
|
||||
|
||||
await page.waitForSelector('button#action-save')
|
||||
await page.locator('button#action-save').click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
|
||||
await wait(1000)
|
||||
await page.setInputFiles('input[type="file"]', path.join(dirname, 'test-image.jpg'))
|
||||
await saveDocAndAssert(page)
|
||||
|
||||
const jpegMediaID = page.url().split('/').pop()
|
||||
|
||||
@@ -771,20 +744,14 @@ describe('Uploads', () => {
|
||||
const acceptableFileSizesForJPEG = [9554, 9575]
|
||||
|
||||
// without metadata appended, the jpeg image filesize would be 2424
|
||||
expect(acceptableFileSizesForJPEG).toContain(jpegMediaDoc.sizes.sizeThree.filesize)
|
||||
await expect
|
||||
.poll(() => acceptableFileSizesForJPEG.includes(jpegMediaDoc.sizes.sizeThree.filesize))
|
||||
.toBe(true)
|
||||
|
||||
await page.goto(withOnlyJPEGMetadataURL.create)
|
||||
|
||||
const fileChooserPromiseForWEBP = page.waitForEvent('filechooser')
|
||||
await page.getByText('Select a file').click()
|
||||
const fileChooserForWEBP = await fileChooserPromiseForWEBP
|
||||
await wait(1000)
|
||||
await fileChooserForWEBP.setFiles(path.join(dirname, 'animated.webp'))
|
||||
|
||||
await page.waitForSelector('button#action-save')
|
||||
await page.locator('button#action-save').click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
|
||||
await wait(1000)
|
||||
await page.setInputFiles('input[type="file"]', path.join(dirname, 'animated.webp'))
|
||||
await saveDocAndAssert(page)
|
||||
|
||||
const webpMediaID = page.url().split('/').pop()
|
||||
|
||||
@@ -795,7 +762,7 @@ describe('Uploads', () => {
|
||||
})
|
||||
|
||||
// With metadata, the animated image filesize would be 218762
|
||||
expect(webpMediaDoc.sizes.sizeThree.filesize).toEqual(211638)
|
||||
await expect.poll(() => webpMediaDoc.sizes.sizeThree.filesize).toBe(211638)
|
||||
})
|
||||
|
||||
test('should show custom upload component', async () => {
|
||||
@@ -831,7 +798,8 @@ describe('Uploads', () => {
|
||||
const filename = page.locator('[id^="doc-drawer_admin-thumbnail-size"] .file-field__filename')
|
||||
await expect(filename).toHaveValue('test-image.png')
|
||||
|
||||
await page.waitForSelector('[id^="doc-drawer_admin-thumbnail-size"] #action-save')
|
||||
await expect(page.locator('[id^="doc-drawer_admin-thumbnail-size"] #action-save')).toBeVisible()
|
||||
|
||||
await page.locator('[id^="doc-drawer_admin-thumbnail-size"] #action-save').click()
|
||||
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
|
||||
@@ -839,10 +807,12 @@ describe('Uploads', () => {
|
||||
const href = await page.locator('#field-singleThumbnailUpload a').getAttribute('href')
|
||||
|
||||
// Ensure the URL starts correctly
|
||||
expect(href).toMatch(/^\/api\/admin-thumbnail-size\/file\/test-image(-\d+)?\.png$/i)
|
||||
await expect
|
||||
.poll(() => href)
|
||||
.toMatch(/^\/api\/admin-thumbnail-size\/file\/test-image(-\d+)?\.png$/i)
|
||||
|
||||
// Ensure no "-100x100" or any similar suffix
|
||||
expect(href).not.toMatch(/-\d+x\d+\.png$/)
|
||||
await expect.poll(() => !/-\d+x\d+\.png$/.test(href!)).toBe(true)
|
||||
})
|
||||
|
||||
test('should show original image url on a hasMany upload card for an upload with adminThumbnail defined', async () => {
|
||||
@@ -853,23 +823,29 @@ describe('Uploads', () => {
|
||||
})
|
||||
await hasManyThumbnailButton.click()
|
||||
|
||||
const hasManyThumbnailModal = page.locator('#bulk-upload-drawer-slug-1')
|
||||
const hasManyThumbnailModal = page.locator('#hasManyThumbnailUpload-bulk-upload-drawer-slug-1')
|
||||
await expect(hasManyThumbnailModal).toBeVisible()
|
||||
|
||||
await page.setInputFiles('#bulk-upload-drawer-slug-1 .dropzone input[type="file"]', [
|
||||
path.resolve(dirname, './test-image.png'),
|
||||
])
|
||||
await hasManyThumbnailModal
|
||||
.locator('.dropzone input[type="file"]')
|
||||
.setInputFiles([path.resolve(dirname, './test-image.png')])
|
||||
|
||||
const saveButton = page.locator('.bulk-upload--actions-bar__saveButtons button')
|
||||
const saveButton = hasManyThumbnailModal.locator(
|
||||
'.bulk-upload--actions-bar__saveButtons button',
|
||||
)
|
||||
await saveButton.click()
|
||||
|
||||
await page.waitForSelector('#field-hasManyThumbnailUpload .upload--has-many__dragItem')
|
||||
await expect(
|
||||
page.locator('#field-hasManyThumbnailUpload .upload--has-many__dragItem'),
|
||||
).toBeVisible()
|
||||
const itemCount = await page
|
||||
.locator('#field-hasManyThumbnailUpload .upload--has-many__dragItem')
|
||||
.count()
|
||||
expect(itemCount).toEqual(1)
|
||||
await expect.poll(() => itemCount).toBe(1)
|
||||
|
||||
await page.waitForSelector('#field-hasManyThumbnailUpload .upload--has-many__dragItem a')
|
||||
await expect(
|
||||
page.locator('#field-hasManyThumbnailUpload .upload--has-many__dragItem a'),
|
||||
).toBeVisible()
|
||||
const href = await page
|
||||
.locator('#field-hasManyThumbnailUpload .upload--has-many__dragItem a')
|
||||
.getAttribute('href')
|
||||
@@ -913,36 +889,37 @@ describe('Uploads', () => {
|
||||
})
|
||||
await bulkUploadButton.click()
|
||||
|
||||
const bulkUploadModal = page.locator('#bulk-upload-drawer-slug-1')
|
||||
const bulkUploadModal = page.locator('#hasManyUpload-bulk-upload-drawer-slug-1')
|
||||
await expect(bulkUploadModal).toBeVisible()
|
||||
|
||||
// Bulk upload multiple files at once
|
||||
await page.setInputFiles('#bulk-upload-drawer-slug-1 .dropzone input[type="file"]', [
|
||||
path.resolve(dirname, './image.png'),
|
||||
path.resolve(dirname, './test-image.png'),
|
||||
])
|
||||
await bulkUploadModal
|
||||
.locator('.dropzone input[type="file"]')
|
||||
.setInputFiles([
|
||||
path.resolve(dirname, './image.png'),
|
||||
path.resolve(dirname, './test-image.png'),
|
||||
])
|
||||
|
||||
await page
|
||||
await bulkUploadModal
|
||||
.locator('.bulk-upload--file-manager .render-fields #field-prefix')
|
||||
.fill('prefix-one')
|
||||
|
||||
const nextImageChevronButton = page.locator(
|
||||
const nextImageChevronButton = bulkUploadModal.locator(
|
||||
'.bulk-upload--actions-bar__controls button:nth-of-type(2)',
|
||||
)
|
||||
await nextImageChevronButton.click()
|
||||
|
||||
await page
|
||||
await bulkUploadModal
|
||||
.locator('.bulk-upload--file-manager .render-fields #field-prefix')
|
||||
.fill('prefix-two')
|
||||
|
||||
const saveButton = page.locator('.bulk-upload--actions-bar__saveButtons button')
|
||||
const saveButton = bulkUploadModal.locator('.bulk-upload--actions-bar__saveButtons button')
|
||||
await saveButton.click()
|
||||
|
||||
await page.waitForSelector('#field-hasManyUpload .upload--has-many__dragItem')
|
||||
const itemCount = await page
|
||||
.locator('#field-hasManyUpload .upload--has-many__dragItem')
|
||||
.count()
|
||||
expect(itemCount).toEqual(2)
|
||||
const items = page.locator('#field-hasManyUpload .upload--has-many__dragItem')
|
||||
await expect(items).toHaveCount(2)
|
||||
await expect(items.nth(0)).toBeVisible()
|
||||
await expect(items.nth(1)).toBeVisible()
|
||||
|
||||
await saveDocAndAssert(page)
|
||||
})
|
||||
@@ -967,29 +944,27 @@ describe('Uploads', () => {
|
||||
})
|
||||
await bulkUploadButton.click()
|
||||
|
||||
const bulkUploadModal = page.locator('#bulk-upload-drawer-slug-1')
|
||||
const bulkUploadModal = page.locator('#hasManyUpload-bulk-upload-drawer-slug-1')
|
||||
await expect(bulkUploadModal).toBeVisible()
|
||||
|
||||
await page.setInputFiles('#bulk-upload-drawer-slug-1 .dropzone input[type="file"]', [
|
||||
path.resolve(dirname, './test-pdf.pdf'),
|
||||
])
|
||||
await bulkUploadModal
|
||||
.locator('.dropzone input[type="file"]')
|
||||
.setInputFiles([path.resolve(dirname, './test-pdf.pdf')])
|
||||
|
||||
await page
|
||||
await bulkUploadModal
|
||||
.locator('.bulk-upload--file-manager .render-fields #field-prefix')
|
||||
.fill('prefix-one')
|
||||
const saveButton = page.locator('.bulk-upload--actions-bar__saveButtons button')
|
||||
const saveButton = bulkUploadModal.locator('.bulk-upload--actions-bar__saveButtons button')
|
||||
await saveButton.click()
|
||||
|
||||
await page.waitForSelector('#field-hasManyUpload .upload--has-many__dragItem')
|
||||
const itemCount = await page
|
||||
.locator('#field-hasManyUpload .upload--has-many__dragItem')
|
||||
.count()
|
||||
expect(itemCount).toEqual(1)
|
||||
const items = page.locator('#field-hasManyUpload .upload--has-many__dragItem')
|
||||
await expect(items).toHaveCount(1)
|
||||
await expect(items.nth(0)).toBeVisible()
|
||||
|
||||
await saveDocAndAssert(page)
|
||||
|
||||
// Assert no console errors occurred for this test only
|
||||
expect(consoleErrorsFromPage).toEqual([])
|
||||
await expect.poll(() => consoleErrorsFromPage).toEqual([])
|
||||
|
||||
// Reset global behavior for other tests
|
||||
stopCollectingErrorsFromPage()
|
||||
@@ -1013,34 +988,37 @@ describe('Uploads', () => {
|
||||
|
||||
await bulkUploadButton.click()
|
||||
|
||||
const bulkUploadModal = page.locator('#bulk-upload-drawer-slug-1')
|
||||
const bulkUploadModal = page.locator('#hasManyUpload-bulk-upload-drawer-slug-1')
|
||||
await expect(bulkUploadModal).toBeVisible()
|
||||
|
||||
// Bulk upload multiple files at once
|
||||
await page.setInputFiles('#bulk-upload-drawer-slug-1 .dropzone input[type="file"]', [
|
||||
path.resolve(dirname, './image.png'),
|
||||
path.resolve(dirname, './test-image.png'),
|
||||
])
|
||||
await bulkUploadModal
|
||||
.locator('.dropzone input[type="file"]')
|
||||
.setInputFiles([
|
||||
path.resolve(dirname, './image.png'),
|
||||
path.resolve(dirname, './test-image.png'),
|
||||
])
|
||||
|
||||
await page.locator('#bulk-upload-drawer-slug-1 .edit-many-bulk-uploads__toggle').click()
|
||||
await bulkUploadModal.locator('.edit-many-bulk-uploads__toggle').click()
|
||||
const editManyBulkUploadModal = page.locator('#edit-uploads-2-bulk-uploads')
|
||||
await expect(editManyBulkUploadModal).toBeVisible()
|
||||
|
||||
await page.locator('.edit-many-bulk-uploads__form .react-select').click({ delay: 100 })
|
||||
const options = page.locator('.rs__option')
|
||||
await editManyBulkUploadModal
|
||||
.locator('.edit-many-bulk-uploads__form .react-select')
|
||||
.click({ delay: 100 })
|
||||
const options = editManyBulkUploadModal.locator('.rs__option')
|
||||
|
||||
await options.locator('text=Prefix').click()
|
||||
|
||||
await page.locator('#edit-uploads-2-bulk-uploads #field-prefix').fill('some prefix')
|
||||
await editManyBulkUploadModal.locator('#field-prefix').fill('some prefix')
|
||||
|
||||
await page.locator('.edit-many-bulk-uploads__sidebar-wrap button').click()
|
||||
await page.locator('.bulk-upload--actions-bar__saveButtons button').click()
|
||||
await page.waitForSelector('#field-hasManyUpload .upload--has-many__dragItem')
|
||||
await editManyBulkUploadModal.locator('.edit-many-bulk-uploads__sidebar-wrap button').click()
|
||||
await bulkUploadModal.locator('.bulk-upload--actions-bar__saveButtons button').click()
|
||||
|
||||
const itemCount = await page
|
||||
.locator('#field-hasManyUpload .upload--has-many__dragItem')
|
||||
.count()
|
||||
expect(itemCount).toEqual(2)
|
||||
const items = page.locator('#field-hasManyUpload .upload--has-many__dragItem')
|
||||
await expect(items).toHaveCount(2)
|
||||
await expect(items.nth(0)).toBeVisible()
|
||||
await expect(items.nth(1)).toBeVisible()
|
||||
|
||||
await saveDocAndAssert(page)
|
||||
})
|
||||
@@ -1062,37 +1040,39 @@ describe('Uploads', () => {
|
||||
})
|
||||
await bulkUploadButton.click()
|
||||
|
||||
const bulkUploadModal = page.locator('#bulk-upload-drawer-slug-1')
|
||||
const bulkUploadModal = page.locator('#hasManyUpload-bulk-upload-drawer-slug-1')
|
||||
await expect(bulkUploadModal).toBeVisible()
|
||||
|
||||
// Bulk upload multiple files at once
|
||||
await page.setInputFiles('#bulk-upload-drawer-slug-1 .dropzone input[type="file"]', [
|
||||
path.resolve(dirname, './image.png'),
|
||||
path.resolve(dirname, './test-image.png'),
|
||||
])
|
||||
await bulkUploadModal
|
||||
.locator('.dropzone input[type="file"]')
|
||||
.setInputFiles([
|
||||
path.resolve(dirname, './image.png'),
|
||||
path.resolve(dirname, './test-image.png'),
|
||||
])
|
||||
|
||||
const saveButton = page.locator('.bulk-upload--actions-bar__saveButtons button')
|
||||
const saveButton = bulkUploadModal.locator('.bulk-upload--actions-bar__saveButtons button')
|
||||
await saveButton.click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('Failed to save 2 files')
|
||||
|
||||
const errorCount = page
|
||||
.locator('#bulk-upload-drawer-slug-1 .file-selections .error-pill__count')
|
||||
.first()
|
||||
const errorCount = bulkUploadModal.locator('.file-selections .error-pill__count').first()
|
||||
await expect(errorCount).toHaveText('3')
|
||||
|
||||
await page.locator('#bulk-upload-drawer-slug-1 .edit-many-bulk-uploads__toggle').click()
|
||||
await bulkUploadModal.locator('.edit-many-bulk-uploads__toggle').click()
|
||||
const editManyBulkUploadModal = page.locator('#edit-uploads-2-bulk-uploads')
|
||||
await expect(editManyBulkUploadModal).toBeVisible()
|
||||
|
||||
const fieldSelector = page.locator('.edit-many-bulk-uploads__form .react-select')
|
||||
const fieldSelector = editManyBulkUploadModal.locator(
|
||||
'.edit-many-bulk-uploads__form .react-select',
|
||||
)
|
||||
await fieldSelector.click({ delay: 100 })
|
||||
const options = page.locator('.rs__option')
|
||||
const options = editManyBulkUploadModal.locator('.rs__option')
|
||||
// Select an option
|
||||
await options.locator('text=Prefix').click()
|
||||
|
||||
await page.locator('#edit-uploads-2-bulk-uploads #field-prefix').fill('some prefix')
|
||||
await editManyBulkUploadModal.locator('#field-prefix').fill('some prefix')
|
||||
|
||||
await page.locator('.edit-many-bulk-uploads__sidebar-wrap button').click()
|
||||
await editManyBulkUploadModal.locator('.edit-many-bulk-uploads__sidebar-wrap button').click()
|
||||
|
||||
await saveButton.click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText(
|
||||
@@ -1119,53 +1099,51 @@ describe('Uploads', () => {
|
||||
})
|
||||
await bulkUploadButton.click()
|
||||
|
||||
const bulkUploadModal = page.locator('#bulk-upload-drawer-slug-1')
|
||||
const bulkUploadModal = page.locator('#hasManyUpload-bulk-upload-drawer-slug-1')
|
||||
await expect(bulkUploadModal).toBeVisible()
|
||||
|
||||
// Bulk upload multiple files at once
|
||||
await page.setInputFiles('#bulk-upload-drawer-slug-1 .dropzone input[type="file"]', [
|
||||
path.resolve(dirname, './image.png'),
|
||||
path.resolve(dirname, './test-image.png'),
|
||||
])
|
||||
await bulkUploadModal
|
||||
.locator('.dropzone input[type="file"]')
|
||||
.setInputFiles([
|
||||
path.resolve(dirname, './image.png'),
|
||||
path.resolve(dirname, './test-image.png'),
|
||||
])
|
||||
|
||||
await page.locator('#bulk-upload-drawer-slug-1 .edit-many-bulk-uploads__toggle').click()
|
||||
await bulkUploadModal.locator('.edit-many-bulk-uploads__toggle').click()
|
||||
const editManyBulkUploadModal = page.locator('#edit-uploads-2-bulk-uploads')
|
||||
await expect(editManyBulkUploadModal).toBeVisible()
|
||||
|
||||
const fieldSelector = page.locator('.edit-many-bulk-uploads__form .react-select')
|
||||
const fieldSelector = editManyBulkUploadModal.locator(
|
||||
'.edit-many-bulk-uploads__form .react-select',
|
||||
)
|
||||
await fieldSelector.click({ delay: 100 })
|
||||
const options = page.locator('.rs__option')
|
||||
const options = editManyBulkUploadModal.locator('.rs__option')
|
||||
// Select an option
|
||||
await options.locator('text=Prefix').click()
|
||||
|
||||
await page.locator('#edit-uploads-2-bulk-uploads #field-prefix').fill('some prefix')
|
||||
await editManyBulkUploadModal.locator('#field-prefix').fill('some prefix')
|
||||
|
||||
await page.locator('.edit-many-bulk-uploads__sidebar-wrap button').click()
|
||||
await editManyBulkUploadModal.locator('.edit-many-bulk-uploads__sidebar-wrap button').click()
|
||||
|
||||
await page
|
||||
.locator('#bulk-upload-drawer-slug-1 .file-field__upload .file-field__remove')
|
||||
.click()
|
||||
await bulkUploadModal.locator('.file-field__upload .file-field__remove').click()
|
||||
|
||||
const chevronRight = page.locator(
|
||||
'#bulk-upload-drawer-slug-1 .bulk-upload--actions-bar__controls button:nth-of-type(2)',
|
||||
const chevronRight = bulkUploadModal.locator(
|
||||
'.bulk-upload--actions-bar__controls button:nth-of-type(2)',
|
||||
)
|
||||
|
||||
await chevronRight.click()
|
||||
|
||||
await expect(
|
||||
page
|
||||
.locator(
|
||||
'#bulk-upload-drawer-slug-1 .file-selections .file-selections__fileRow .file-selections__fileName',
|
||||
)
|
||||
bulkUploadModal
|
||||
.locator('.file-selections .file-selections__fileRow .file-selections__fileName')
|
||||
.first(),
|
||||
).toContainText('No file')
|
||||
|
||||
const saveButton = page.locator('.bulk-upload--actions-bar__saveButtons button')
|
||||
const saveButton = bulkUploadModal.locator('.bulk-upload--actions-bar__saveButtons button')
|
||||
await saveButton.click()
|
||||
|
||||
const errorCount = page
|
||||
.locator('#bulk-upload-drawer-slug-1 .file-selections .error-pill__count')
|
||||
.first()
|
||||
const errorCount = bulkUploadModal.locator('.file-selections .error-pill__count').first()
|
||||
await expect(errorCount).toHaveText('1')
|
||||
})
|
||||
|
||||
@@ -1216,6 +1194,32 @@ describe('Uploads', () => {
|
||||
'Related Document Title',
|
||||
)
|
||||
})
|
||||
|
||||
test('should reset state once all files are saved successfully from field bulk upload', async () => {
|
||||
await page.goto(uploadsOne.create)
|
||||
const fieldBulkUploadButton = page.locator('#field-hasManyThumbnailUpload button', {
|
||||
hasText: exactText('Create New'),
|
||||
})
|
||||
await fieldBulkUploadButton.click()
|
||||
const fieldBulkUploadDrawer = page.locator(
|
||||
'#hasManyThumbnailUpload-bulk-upload-drawer-slug-1',
|
||||
)
|
||||
await expect(fieldBulkUploadDrawer).toBeVisible()
|
||||
await fieldBulkUploadDrawer
|
||||
.locator('.dropzone input[type="file"]')
|
||||
.setInputFiles([
|
||||
path.resolve(dirname, './image.png'),
|
||||
path.resolve(dirname, './test-image.png'),
|
||||
])
|
||||
await fieldBulkUploadDrawer
|
||||
.locator('.bulk-upload--actions-bar button', { hasText: 'Save' })
|
||||
.click()
|
||||
await expect(fieldBulkUploadDrawer).toBeHidden()
|
||||
await fieldBulkUploadButton.click()
|
||||
|
||||
// should show add files dropzone view
|
||||
await expect(fieldBulkUploadDrawer.locator('.bulk-upload--add-files')).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
describe('remote url fetching', () => {
|
||||
@@ -1314,12 +1318,8 @@ describe('Uploads', () => {
|
||||
const createFocalCrop = async (page: Page, position: 'bottom-right' | 'top-left') => {
|
||||
const { dragX, dragY, focalX, focalY } = positions[position]
|
||||
await page.goto(mediaURL.create)
|
||||
// select and upload file
|
||||
const fileChooserPromise = page.waitForEvent('filechooser')
|
||||
await page.getByText('Select a file').click()
|
||||
const fileChooser = await fileChooserPromise
|
||||
await wait(1000)
|
||||
await fileChooser.setFiles(path.join(dirname, 'test-image.jpg'))
|
||||
|
||||
await page.setInputFiles('input[type="file"]', path.join(dirname, 'test-image.jpg'))
|
||||
|
||||
await page.locator('.file-field__edit').click()
|
||||
|
||||
@@ -1342,10 +1342,7 @@ describe('Uploads', () => {
|
||||
|
||||
// apply crop
|
||||
await page.locator('button:has-text("Apply Changes")').click()
|
||||
await page.waitForSelector('button#action-save')
|
||||
await page.locator('button#action-save').click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
|
||||
await wait(1000) // Wait for the save
|
||||
await saveDocAndAssert(page)
|
||||
}
|
||||
|
||||
await createFocalCrop(page, 'bottom-right') // green square
|
||||
@@ -1373,12 +1370,7 @@ describe('Uploads', () => {
|
||||
test('should update image alignment based on focal point', async () => {
|
||||
const updateFocalPosition = async (page: Page) => {
|
||||
await page.goto(focalOnlyURL.create)
|
||||
// select and upload file
|
||||
const fileChooserPromise = page.waitForEvent('filechooser')
|
||||
await page.getByText('Select a file').click()
|
||||
const fileChooser = await fileChooserPromise
|
||||
await wait(1000)
|
||||
await fileChooser.setFiles(path.join(dirname, 'horizontal-squares.jpg'))
|
||||
await page.setInputFiles('input[type="file"]', path.join(dirname, 'horizontal-squares.jpg'))
|
||||
|
||||
await page.locator('.file-field__edit').click()
|
||||
|
||||
@@ -1388,10 +1380,7 @@ describe('Uploads', () => {
|
||||
|
||||
// apply focal point
|
||||
await page.locator('button:has-text("Apply Changes")').click()
|
||||
await page.waitForSelector('button#action-save')
|
||||
await page.locator('button#action-save').click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
|
||||
await wait(1000) // Wait for the save
|
||||
await saveDocAndAssert(page)
|
||||
}
|
||||
|
||||
await updateFocalPosition(page) // red square
|
||||
@@ -1404,17 +1393,13 @@ describe('Uploads', () => {
|
||||
})
|
||||
|
||||
// without focal point update this generated size was equal to 1736
|
||||
expect(redDoc.sizes.focalTest.filesize).toEqual(1586)
|
||||
await expect.poll(() => redDoc.sizes.focalTest.filesize).toBe(1586)
|
||||
})
|
||||
|
||||
test('should resize image after crop if resizeOptions defined', async () => {
|
||||
await page.goto(animatedTypeMediaURL.create)
|
||||
|
||||
const fileChooserPromise = page.waitForEvent('filechooser')
|
||||
await page.getByText('Select a file').click()
|
||||
const fileChooser = await fileChooserPromise
|
||||
await wait(1000)
|
||||
await fileChooser.setFiles(path.join(dirname, 'test-image.jpg'))
|
||||
await page.setInputFiles('input[type="file"]', path.join(dirname, 'test-image.jpg'))
|
||||
|
||||
await page.locator('.file-field__edit').click()
|
||||
|
||||
@@ -1426,10 +1411,7 @@ describe('Uploads', () => {
|
||||
await page.locator('.edit-upload__input input[name="Y %"]').fill('50') // init top focal point
|
||||
|
||||
await page.locator('button:has-text("Apply Changes")').click()
|
||||
await page.waitForSelector('button#action-save')
|
||||
await page.locator('button#action-save').click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
|
||||
await wait(1000) // Wait for the save
|
||||
await saveDocAndAssert(page)
|
||||
|
||||
const resizeOptionMedia = page.locator('.file-meta .file-meta__size-type')
|
||||
await expect(resizeOptionMedia).toContainText('200x200')
|
||||
@@ -1505,25 +1487,14 @@ describe('Uploads', () => {
|
||||
test('should skip applying resizeOptions after updating an image if resizeOptions.withoutEnlargement is true and the original image size is smaller than the dimensions defined in resizeOptions', async () => {
|
||||
await page.goto(withoutEnlargementResizeOptionsURL.create)
|
||||
|
||||
const fileChooserPromise = page.waitForEvent('filechooser')
|
||||
await page.getByText('Select a file').click()
|
||||
const fileChooser = await fileChooserPromise
|
||||
await wait(1000)
|
||||
await fileChooser.setFiles(path.join(dirname, 'test-image.jpg'))
|
||||
|
||||
await page.waitForSelector('button#action-save')
|
||||
await page.locator('button#action-save').click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
|
||||
await wait(1000)
|
||||
await page.setInputFiles('input[type="file"]', path.join(dirname, 'test-image.jpg'))
|
||||
await saveDocAndAssert(page)
|
||||
|
||||
await page.locator('.file-field__edit').click()
|
||||
|
||||
// no need to make any changes to the image if resizeOptions.withoutEnlargement is actually being respected now
|
||||
await page.locator('button:has-text("Apply Changes")').click()
|
||||
await page.waitForSelector('button#action-save')
|
||||
await page.locator('button#action-save').click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
|
||||
await wait(1000)
|
||||
await saveDocAndAssert(page)
|
||||
|
||||
const resizeOptionMedia = page.locator('.file-meta .file-meta__size-type')
|
||||
|
||||
@@ -1546,10 +1517,7 @@ describe('Uploads', () => {
|
||||
test('should select an image within target range', async () => {
|
||||
await page.goto(bestFitURL.create)
|
||||
await page.locator('#field-withinRange button.upload__createNewToggler').click()
|
||||
const fileChooserPromise = page.waitForEvent('filechooser')
|
||||
await page.getByText('Select a file').click()
|
||||
const fileChooser = await fileChooserPromise
|
||||
await fileChooser.setFiles(path.join(dirname, 'test-image.jpg'))
|
||||
await page.setInputFiles('input[type="file"]', path.join(dirname, 'test-image.jpg'))
|
||||
await page.locator('dialog button#action-save').click()
|
||||
const thumbnail = page.locator('#field-withinRange div.thumbnail > img')
|
||||
await expect(thumbnail).toHaveAttribute('src', '/api/enlarge/file/test-image-180x50.jpg')
|
||||
@@ -1558,10 +1526,7 @@ describe('Uploads', () => {
|
||||
test('should select next smallest image outside of range but smaller than original', async () => {
|
||||
await page.goto(bestFitURL.create)
|
||||
await page.locator('#field-nextSmallestOutOfRange button.upload__createNewToggler').click()
|
||||
const fileChooserPromise = page.waitForEvent('filechooser')
|
||||
await page.getByText('Select a file').click()
|
||||
const fileChooser = await fileChooserPromise
|
||||
await fileChooser.setFiles(path.join(dirname, 'test-image.jpg'))
|
||||
await page.setInputFiles('input[type="file"]', path.join(dirname, 'test-image.jpg'))
|
||||
await page.locator('dialog button#action-save').click()
|
||||
const thumbnail = page.locator('#field-nextSmallestOutOfRange div.thumbnail > img')
|
||||
await expect(thumbnail).toHaveAttribute('src', '/api/focal-only/file/test-image-400x300.jpg')
|
||||
@@ -1570,10 +1535,7 @@ describe('Uploads', () => {
|
||||
test('should select original if smaller than next available size', async () => {
|
||||
await page.goto(bestFitURL.create)
|
||||
await page.locator('#field-original button.upload__createNewToggler').click()
|
||||
const fileChooserPromise = page.waitForEvent('filechooser')
|
||||
await page.getByText('Select a file').click()
|
||||
const fileChooser = await fileChooserPromise
|
||||
await fileChooser.setFiles(path.join(dirname, 'small.png'))
|
||||
await page.setInputFiles('input[type="file"]', path.join(dirname, 'small.png'))
|
||||
await page.locator('dialog button#action-save').click()
|
||||
const thumbnail = page.locator('#field-original div.thumbnail > img')
|
||||
await expect(thumbnail).toHaveAttribute('src', '/api/focal-only/file/small.png')
|
||||
|
||||
Reference in New Issue
Block a user