chore: re-exports languages in payload (#5771)

This commit is contained in:
Jarrod Flesch
2024-04-10 15:55:01 -04:00
committed by GitHub
parent 7cf2686097
commit 94af06466b
40 changed files with 79 additions and 517 deletions

View File

@@ -19,7 +19,9 @@ export const getRequestLanguage = ({
}: GetRequestLanguageArgs): AcceptedLanguages => {
const langCookie = cookies.get(`${config.cookiePrefix || 'payload'}-lng`)
const languageFromCookie = typeof langCookie === 'string' ? langCookie : langCookie?.value
const languageFromHeader = extractHeaderLanguage(headers.get('Accept-Language'))
const languageFromHeader = headers.get('Accept-Language')
? extractHeaderLanguage(headers.get('Accept-Language'))
: undefined
const fallbackLang = config?.i18n?.fallbackLanguage || defaultLanguage
const supportedLanguageKeys = Object.keys(config?.i18n?.supportedLanguages || {})

View File

@@ -0,0 +1 @@
export { ar } from '@payloadcms/translations/languages/ar'

View File

@@ -0,0 +1 @@
export { az } from '@payloadcms/translations/languages/az'

View File

@@ -0,0 +1 @@
export { bg } from '@payloadcms/translations/languages/bg'

View File

@@ -0,0 +1 @@
export { cs } from '@payloadcms/translations/languages/cs'

View File

@@ -0,0 +1 @@
export { de } from '@payloadcms/translations/languages/de'

View File

@@ -0,0 +1 @@
export { en } from '@payloadcms/translations/languages/en'

View File

@@ -0,0 +1 @@
export { es } from '@payloadcms/translations/languages/es'

View File

@@ -0,0 +1 @@
export { fa } from '@payloadcms/translations/languages/fa'

View File

@@ -0,0 +1 @@
export { fr } from '@payloadcms/translations/languages/fr'

View File

@@ -0,0 +1 @@
export { hr } from '@payloadcms/translations/languages/hr'

View File

@@ -0,0 +1 @@
export { hu } from '@payloadcms/translations/languages/hu'

View File

@@ -0,0 +1 @@
export { it } from '@payloadcms/translations/languages/it'

View File

@@ -0,0 +1 @@
export { ja } from '@payloadcms/translations/languages/ja'

View File

@@ -0,0 +1 @@
export { ko } from '@payloadcms/translations/languages/ko'

View File

@@ -0,0 +1 @@
export { my } from '@payloadcms/translations/languages/my'

View File

@@ -0,0 +1 @@
export { nb } from '@payloadcms/translations/languages/nb'

View File

@@ -0,0 +1 @@
export { nl } from '@payloadcms/translations/languages/nl'

View File

@@ -0,0 +1 @@
export { pl } from '@payloadcms/translations/languages/pl'

View File

@@ -0,0 +1 @@
export { pt } from '@payloadcms/translations/languages/pt'

View File

@@ -0,0 +1 @@
export { ro } from '@payloadcms/translations/languages/ro'

View File

@@ -0,0 +1 @@
export { rs } from '@payloadcms/translations/languages/rs'

View File

@@ -0,0 +1 @@
export { rsLatin } from '@payloadcms/translations/languages/rsLatin'

View File

@@ -0,0 +1 @@
export { ru } from '@payloadcms/translations/languages/ru'

View File

@@ -0,0 +1 @@
export { sv } from '@payloadcms/translations/languages/sv'

View File

@@ -0,0 +1 @@
export { th } from '@payloadcms/translations/languages/th'

View File

@@ -0,0 +1 @@
export { tr } from '@payloadcms/translations/languages/tr'

View File

@@ -0,0 +1 @@
export { uk } from '@payloadcms/translations/languages/uk'

View File

@@ -0,0 +1 @@
export { vi } from '@payloadcms/translations/languages/vi'

View File

@@ -0,0 +1 @@
export { zh } from '@payloadcms/translations/languages/zh'

View File

@@ -0,0 +1 @@
export { zhTw } from '@payloadcms/translations/languages/zhTw'

View File

@@ -1,14 +1,13 @@
# Payload Translations
These are the translations for Payload. Translations are used on both the server and the client. The admin panel uses translations to display text to the user in their selected language. The server uses translations when sending API responses.
The home of Payloads API and Admin Panel translations.
## How to contribute
#### Updating a translation
1. Open the language file you wish to edit located within the `src/all` folder
2. Update the translation value
3. Run one of the following:
1. Update the translation value
2. Run one of the following:
```sh
yarn build
// or
@@ -19,9 +18,8 @@ These are the translations for Payload. Translations are used on both the server
#### Adding a new translation
1. Add the new translation key/value pair for all languages located in the `src/all` folder
2. Open the `writeTranslationFiles.ts` file and add the key to either `clientTranslationKeys` or `serverTranslationKeys` depending on where the translation will be used.
3. Run one of the following:
1. Add the new translation key/value pair for **all** languages located in the `<payload-repo-root>/packages/translations/src/languages` folder
2. Run one of the following:
```sh
yarn build
// or
@@ -32,10 +30,9 @@ These are the translations for Payload. Translations are used on both the server
#### Adding a new language
1. Create a new JSON file in the `src/all` folder with the language code as the file name (e.g. `en.json` for English)
2. Translate all of the keys in the new file
3. Open the `src/index.ts` file and import your json file and then export it inside the `translations` object
4. Run one of the following:
1. Create a new TS file in the `<payload-repo-root>/packages/translations/src/languages` folder, use the language code as the file name (e.g. `<payload-repo-root>/packages/translations/src/languages/en.ts` for English)
2. Copy all translations from an existing language file and update all of the translations to match your new language
3. Run one of the following:
```sh
yarn build
// or
@@ -43,6 +40,8 @@ These are the translations for Payload. Translations are used on both the server
// or
pnpm build
```
4. Import and export your new language file from within `<payload-repo-root>/packages/translations/src/exports/all.ts`
5. Re-export the file from within `<payload-repo-root>/packages/payload/src/exports/i18n/[your-new-language].ts`
Here is a full list of language keys. Note that these are not all implemented, but if you would like to contribute and add a new language, you can use this list as a reference:

View File

@@ -1,480 +0,0 @@
/* eslint-disable no-console */
import { exec } from 'child_process'
import * as fs from 'fs'
import * as path from 'path'
import { fileURLToPath } from 'url'
import { translations } from './src/all/index.js'
import { copyFile } from './src/utilities/copyFile.js'
import { ensureDirectoryExists } from './src/utilities/ensureDirExists.js'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
const serverTranslationKeys = [
'authentication:account',
'authentication:api',
'authentication:apiKey',
'authentication:enableAPIKey',
'authentication:newAccountCreated',
'authentication:resetYourPassword',
'authentication:verifyYourEmail',
'authentication:youAreReceivingResetPassword',
'authentication:loggedInChangePassword',
'authentication:youDidNotRequestPassword',
'authentication:verified',
'fields:textToDisplay',
'fields:linkType',
'fields:chooseBetweenCustomTextOrDocument',
'fields:customURL',
'fields:internalLink',
'fields:enterURL',
'fields:chooseDocumentToLink',
'fields:openInNewTab',
'general:copy',
'general:createdAt',
'general:deletedCountSuccessfully',
'general:deletedSuccessfully',
'general:email',
'general:notFound',
'general:successfullyCreated',
'general:successfullyDuplicated',
'general:thisLanguage',
'general:user',
'general:users',
'general:updatedAt',
'general:updatedSuccessfully',
'general:updatedCountSuccessfully',
'general:value',
'general:row',
'general:rows',
'error:deletingFile',
'error:emailOrPasswordIncorrect',
'error:followingFieldsInvalid',
'error:noFilesUploaded',
'error:notAllowedToPerformAction',
'error:problemUploadingFile',
'error:unableToDeleteCount',
'error:unableToUpdateCount',
'error:unauthorized',
'error:userLocked',
'error:valueMustBeUnique',
'upload:width',
'upload:height',
'upload:fileSize',
'upload:fileName',
'upload:sizes',
'validation:emailAddress',
'validation:enterNumber',
'validation:greaterThanMax',
'validation:invalidInput',
'validation:invalidSelection',
'validation:invalidSelections',
'validation:lessThanMin',
'validation:longerThanMin',
'validation:notValidDate',
'validation:required',
'validation:requiresAtLeast',
'validation:requiresNoMoreThan',
'validation:requiresTwoNumbers',
'validation:shorterThanMax',
'validation:trueOrFalse',
'validation:validUploadID',
'version:autosavedSuccessfully',
'version:draftSavedSuccessfully',
'version:restoredSuccessfully',
'version:draft',
'version:published',
'version:status',
]
const clientTranslationKeys = [
'authentication:account',
'authentication:accountOfCurrentUser',
'authentication:alreadyActivated',
'authentication:alreadyLoggedIn',
'authentication:backToLogin',
'authentication:beginCreateFirstUser',
'authentication:changePassword',
'authentication:confirmGeneration',
'authentication:confirmPassword',
'authentication:createFirstUser',
'authentication:emailNotValid',
'authentication:emailSent',
'authentication:enableAPIKey',
'authentication:failedToUnlock',
'authentication:forceUnlock',
'authentication:forgotPassword',
'authentication:forgotPasswordEmailInstructions',
'authentication:forgotPasswordQuestion',
'authentication:generate',
'authentication:generateNewAPIKey',
'authentication:logBackIn',
'authentication:loggedOutInactivity',
'authentication:loggedOutSuccessfully',
'authentication:login',
'authentication:logOut',
'authentication:logout',
'authentication:logoutUser',
'authentication:newAPIKeyGenerated',
'authentication:newPassword',
'authentication:resetPassword',
'authentication:stayLoggedIn',
'authentication:successfullyUnlocked',
'authentication:unableToVerify',
'authentication:verified',
'authentication:verifiedSuccessfully',
'authentication:verify',
'authentication:verifyUser',
'authentication:youAreInactive',
'error:autosaving',
'error:correctInvalidFields',
'error:deletingTitle',
'error:loadingDocument',
'error:noMatchedField',
'error:notAllowedToAccessPage',
'error:previewing',
'error:unableToDeleteCount',
'error:unableToUpdateCount',
'error:unauthorized',
'error:unknown',
'error:unspecific',
'fields:addLabel',
'fields:addLink',
'fields:addNew',
'fields:addNewLabel',
'fields:addRelationship',
'fields:addUpload',
'fields:block',
'fields:blocks',
'fields:blockType',
'fields:chooseFromExisting',
'fields:collapseAll',
'fields:editLink',
'fields:editRelationship',
'fields:itemsAndMore',
'fields:labelRelationship',
'fields:latitude',
'fields:linkedTo',
'fields:longitude',
'fields:passwordsDoNotMatch',
'fields:removeRelationship',
'fields:removeUpload',
'fields:saveChanges',
'fields:searchForBlock',
'fields:selectFieldsToEdit',
'fields:showAll',
'fields:swapRelationship',
'fields:swapUpload',
'fields:toggleBlock',
'fields:uploadNewLabel',
'general:aboutToDeleteCount',
'general:aboutToDelete',
'general:addBelow',
'general:addFilter',
'general:adminTheme',
'general:and',
'general:applyChanges',
'general:ascending',
'general:automatic',
'general:backToDashboard',
'general:cancel',
'general:changesNotSaved',
'general:close',
'general:collapse',
'general:collections',
'general:columns',
'general:columnToSort',
'general:confirm',
'general:confirmDeletion',
'general:confirmDuplication',
'general:copied',
'general:copy',
'general:create',
'general:created',
'general:createNew',
'general:createNewLabel',
'general:creating',
'general:creatingNewLabel',
'general:dark',
'general:dashboard',
'general:delete',
'general:deletedCountSuccessfully',
'general:deleting',
'general:descending',
'general:deselectAllRows',
'general:duplicate',
'general:duplicateWithoutSaving',
'general:edit',
'general:editing',
'general:editingLabel',
'general:editLabel',
'general:email',
'general:emailAddress',
'general:enterAValue',
'general:error',
'general:errors',
'general:fallbackToDefaultLocale',
'general:filters',
'general:filterWhere',
'general:globals',
'general:language',
'general:lastModified',
'general:leaveAnyway',
'general:leaveWithoutSaving',
'general:light',
'general:livePreview',
'general:loading',
'general:locale',
'general:menu',
'general:moveDown',
'general:moveUp',
'general:noFiltersSet',
'general:noLabel',
'general:none',
'general:noOptions',
'general:noResults',
'general:notFound',
'general:nothingFound',
'general:noValue',
'general:of',
'general:open',
'general:or',
'general:order',
'general:pageNotFound',
'general:password',
'general:payloadSettings',
'general:perPage',
'general:remove',
'general:reset',
'general:row',
'general:rows',
'general:save',
'general:saving',
'general:searchBy',
'general:selectAll',
'general:selectAllRows',
'general:selectedCount',
'general:selectValue',
'general:showAllLabel',
'general:sorryNotFound',
'general:sort',
'general:sortByLabelDirection',
'general:stayOnThisPage',
'general:submissionSuccessful',
'general:submit',
'general:successfullyCreated',
'general:successfullyDeleted',
'general:thisLanguage',
'general:titleDeleted',
'general:unauthorized',
'general:unsavedChangesDuplicate',
'general:untitled',
'general:updatedAt',
'general:updatedCountSuccessfully',
'general:updatedSuccessfully',
'general:updating',
'general:welcome',
'operators:equals',
'operators:exists',
'operators:isNotIn',
'operators:isIn',
'operators:contains',
'operators:isLike',
'operators:isNotEqualTo',
'operators:near',
'operators:isGreaterThan',
'operators:isLessThan',
'operators:isGreaterThanOrEqualTo',
'operators:isLessThanOrEqualTo',
'upload:crop',
'upload:cropToolDescription',
'upload:dragAndDrop',
'upload:editImage',
'upload:focalPoint',
'upload:focalPointDescription',
'upload:height',
'upload:previewSizes',
'upload:selectCollectionToBrowse',
'upload:selectFile',
'upload:setCropArea',
'upload:setFocalPoint',
'upload:sizesFor',
'upload:width',
'validation:fieldHasNo',
'validation:limitReached',
'validation:required',
'validation:requiresAtLeast',
'version:aboutToPublishSelection',
'version:aboutToRestore',
'version:aboutToRestoreGlobal',
'version:aboutToRevertToPublished',
'version:aboutToUnpublish',
'version:aboutToUnpublishSelection',
'version:autosave',
'version:autosavedSuccessfully',
'version:changed',
'version:confirmRevertToSaved',
'version:compareVersion',
'version:confirmPublish',
'version:confirmUnpublish',
'version:confirmVersionRestoration',
'version:draft',
'version:draftSavedSuccessfully',
'version:lastSavedAgo',
'version:noFurtherVersionsFound',
'version:noRowsFound',
'version:preview',
'version:problemRestoringVersion',
'version:publish',
'version:publishChanges',
'version:published',
'version:publishing',
'version:restoredSuccessfully',
'version:restoreThisVersion',
'version:restoring',
'version:revertToPublished',
'version:saveDraft',
'version:selectLocales',
'version:selectVersionToCompare',
'version:showLocales',
'version:status',
'version:type',
'version:unpublish',
'version:unpublishing',
'version:versionCreatedOn',
'version:versionID',
'version:version',
'version:versions',
'version:viewingVersion',
'version:viewingVersionGlobal',
'version:viewingVersions',
'version:viewingVersionsGlobal',
]
const DESTINATION_ROOT = './src/_generatedFiles_'
const SOURCE_DIR = './src/all'
function filterKeys(obj, parentGroupKey = '', keys) {
const result = {}
for (const [namespaceKey, value] of Object.entries(obj)) {
// Skip $schema key
if (namespaceKey === '$schema') {
result[namespaceKey] = value
continue
}
if (typeof value === 'object') {
const filteredObject = filterKeys(value, namespaceKey, keys)
if (Object.keys(filteredObject).length > 0) {
result[namespaceKey] = filteredObject
}
} else {
for (const key of keys) {
const [groupKey, selector] = key.split(':')
if (parentGroupKey === groupKey) {
if (namespaceKey === selector) {
result[selector] = value
} else {
const pluralKeys = ['zero', 'one', 'two', 'few', 'many', 'other']
pluralKeys.forEach((pluralKey) => {
if (namespaceKey === `${selector}_${pluralKey}`) {
result[`${selector}_${pluralKey}`] = value
}
})
}
}
}
}
}
return result
}
function sortObject(obj) {
const sortedObject = {}
Object.keys(obj)
.sort()
.forEach((key) => {
if (typeof obj[key] === 'object') {
sortedObject[key] = sortObject(obj[key])
} else {
sortedObject[key] = obj[key]
}
})
return sortedObject
}
function build() {
return new Promise((resolve, reject) => {
ensureDirectoryExists(path.resolve(dirname, `${DESTINATION_ROOT}/client`))
ensureDirectoryExists(path.resolve(dirname, `${DESTINATION_ROOT}/api`))
try {
// build up the client and server translation files
for (const [locale, values] of Object.entries(translations)) {
const dest1 = path.resolve(dirname, `${DESTINATION_ROOT}/client/${locale}.js`)
const clientTranslations = sortObject(filterKeys(values, '', clientTranslationKeys))
fs.writeFileSync(dest1, 'export default ' + JSON.stringify(clientTranslations, null, 2), {
flag: 'w+',
})
const serverTranslations = sortObject(filterKeys(values, '', serverTranslationKeys))
const dest2 = path.resolve(dirname, `${DESTINATION_ROOT}/api/${locale}.js`)
fs.writeFileSync(dest2, 'export default ' + JSON.stringify(serverTranslations, null, 2), {
flag: 'w+',
})
console.info('Rebuilt:', filename)
}
// Copy barrel file to both client and api folders
copyFile(
path.resolve(dirname, `${SOURCE_DIR}/index.ts`),
path.resolve(dirname, `${DESTINATION_ROOT}/api/index.ts`),
)
copyFile(
path.resolve(dirname, `${SOURCE_DIR}/index.ts`),
path.resolve(dirname, `${DESTINATION_ROOT}/client/index.ts`),
)
// Run prettier from CLI so that files pass the pre-commit hook:
console.info('Running prettier...')
exec('prettier --write "**/*.js"', (err, stdout) => {
if (err) {
console.error(err)
} else {
console.info(stdout)
}
})
} catch (error) {
reject(error)
}
})
}
build()
.then(() => {
console.log('Built client and api translation files.')
})
.catch((error) => {
console.error('Error occurred:', error)
})

View File

@@ -62,7 +62,7 @@ export const _ArrayField: React.FC<ArrayFieldProps> = (props) => {
labelProps,
localized,
maxRows,
minRows,
minRows: minRowsProp,
path: pathFromProps,
permissions,
readOnly: readOnlyFromProps,
@@ -72,6 +72,7 @@ export const _ArrayField: React.FC<ArrayFieldProps> = (props) => {
const { indexPath, readOnly: readOnlyFromContext } = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const minRows = minRowsProp ?? required ? 1 : 0
const { setDocFieldPreferences } = useDocumentInfo()
const { addFieldRow, dispatchFields, setModified } = useForm()
@@ -300,7 +301,7 @@ export const _ArrayField: React.FC<ArrayFieldProps> = (props) => {
{t('validation:requiresAtLeast', {
count: minRows,
label:
getTranslation(minRows ? labels.plural : labels.singular, i18n) ||
getTranslation(minRows > 1 ? labels.plural : labels.singular, i18n) ||
t(minRows > 1 ? 'general:row' : 'general:rows'),
})}
</Banner>

View File

@@ -67,7 +67,7 @@ const _BlocksField: React.FC<BlocksFieldProps> = (props) => {
labels: labelsFromProps,
localized,
maxRows,
minRows,
minRows: minRowsProp,
path: pathFromProps,
readOnly: readOnlyFromProps,
required,
@@ -76,6 +76,7 @@ const _BlocksField: React.FC<BlocksFieldProps> = (props) => {
const { indexPath, readOnly: readOnlyFromContext } = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const minRows = minRowsProp ?? required ? 1 : 0
const { setDocFieldPreferences } = useDocumentInfo()
const { addFieldRow, dispatchFields, setModified } = useForm()
@@ -313,12 +314,9 @@ const _BlocksField: React.FC<BlocksFieldProps> = (props) => {
<Banner type="error">
{t('validation:requiresAtLeast', {
count: minRows,
label: getTranslation(
minRows === 1 || typeof minRows === 'undefined'
? labels.singular
: labels.plural,
i18n,
),
label:
getTranslation(minRows > 1 ? labels.plural : labels.singular, i18n) ||
t(minRows > 1 ? 'general:row' : 'general:rows'),
})}
</Banner>
)}

View File

@@ -15,6 +15,7 @@ import {
exactText,
initPageConsoleErrorCatch,
openDocControls,
openDocDrawer,
openNav,
saveDocAndAssert,
saveDocHotkeyAndAssert,
@@ -1052,8 +1053,8 @@ describe('admin', () => {
await createPost()
await page.goto(postsUrl.create)
// Open the drawer
await page.locator('.rich-text .list-drawer__toggler').click()
await openDocDrawer(page, '.rich-text .list-drawer__toggler')
const listDrawer = page.locator('[id^=list-drawer_1_]')
await expect(listDrawer).toBeVisible()
@@ -1092,7 +1093,7 @@ describe('admin', () => {
await page.goto(postsUrl.create)
// Open the drawer
await page.locator('.rich-text .list-drawer__toggler').click()
await openDocDrawer(page, '.rich-text .list-drawer__toggler')
const listDrawer = page.locator('[id^=list-drawer_1_]')
await expect(listDrawer).toBeVisible()

View File

@@ -25,11 +25,11 @@ import {
UploadFeature,
lexicalEditor,
} from '@payloadcms/richtext-lexical'
import { de } from '@payloadcms/translations/languages/de'
import { en } from '@payloadcms/translations/languages/en'
import { es } from '@payloadcms/translations/languages/es'
// import { slateEditor } from '@payloadcms/richtext-slate'
import { type Config, buildConfig } from 'payload/config'
import { de } from 'payload/i18n/de'
import { en } from 'payload/i18n/en'
import { es } from 'payload/i18n/es'
import sharp from 'sharp'
import { reInitEndpoint } from './helpers/reInit.js'

View File

@@ -12,6 +12,7 @@ import {
ensureAutoLoginAndCompilationIsDone,
initPageConsoleErrorCatch,
navigateToListCellLink,
openDocDrawer,
saveDocAndAssert,
switchTab,
} from '../helpers.js'
@@ -767,8 +768,9 @@ describe('fields', () => {
await uploadImage()
await wait(500)
// Open the media drawer and create a png upload
await page.locator('.field-type.upload .upload__toggler.doc-drawer__toggler').click()
await wait(1000) // TODO: Fix this. Need to wait a bit until the form in the drawer mounted, otherwise values sometimes disappear. This is an issue for all drawers
await openDocDrawer(page, '.field-type.upload .upload__toggler.doc-drawer__toggler')
await page
.locator('[id^=doc-drawer_uploads_1_] .file-field__upload input[type="file"]')
.setInputFiles(path.resolve(dirname, './uploads/payload.png'))
@@ -795,7 +797,8 @@ describe('fields', () => {
test('should clear selected upload', async () => {
await uploadImage()
await wait(1000) // TODO: Fix this. Need to wait a bit until the form in the drawer mounted, otherwise values sometimes disappear. This is an issue for all drawers
await page.locator('.field-type.upload .upload__toggler.doc-drawer__toggler').click()
await openDocDrawer(page, '.field-type.upload .upload__toggler.doc-drawer__toggler')
await page
.locator('[id^=doc-drawer_uploads_1_] .file-field__upload input[type="file"]')
@@ -811,8 +814,7 @@ describe('fields', () => {
test('should select using the list drawer and restrict mimetype based on filterOptions', async () => {
await uploadImage()
await page.locator('.field-type.upload .upload__toggler.list-drawer__toggler').click()
await wait(500) // TODO: Fix this. Need to wait a bit until the form in the drawer mounted, otherwise values sometimes disappear. This is an issue for all drawers
await openDocDrawer(page, '.field-type.upload .upload__toggler.list-drawer__toggler')
const jpgImages = page.locator('[id^=list-drawer_1_] .upload-gallery img[src$=".jpg"]')
await expect
@@ -834,7 +836,7 @@ describe('fields', () => {
await wait(200)
// open drawer
await page.locator('.field-type.upload .list-drawer__toggler').click()
await openDocDrawer(page, '.field-type.upload .list-drawer__toggler')
// check title
await expect(page.locator('.list-drawer__header-text')).toContainText('Uploads 3')
})

View File

@@ -130,6 +130,11 @@ export async function openNav(page: Page): Promise<void> {
await expect(page.locator('.template-default.template-default--nav-open')).toBeVisible()
}
export async function openDocDrawer(page: Page, selector: string): Promise<void> {
await page.locator(selector).click()
await wait(300) // wait for drawer form state to initialize
}
export async function closeNav(page: Page): Promise<void> {
if (!(await page.locator('.template-default.template-default--nav-open').isVisible())) return
await page.locator('.nav-toggler >> visible=true').click()

View File

@@ -11,6 +11,7 @@ import type { Media } from './payload-types.js'
import {
ensureAutoLoginAndCompilationIsDone,
initPageConsoleErrorCatch,
openDocDrawer,
saveDocAndAssert,
} from '../helpers.js'
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
@@ -203,7 +204,7 @@ describe('uploads', () => {
await page.locator('.field-type:nth-of-type(2) .icon--x').click()
// choose from existing
await page.locator('.list-drawer__toggler').click()
await openDocDrawer(page, '.list-drawer__toggler')
await expect(page.locator('.cell-title')).toContainText('draft')
})
@@ -214,13 +215,16 @@ describe('uploads', () => {
// remove the selection and open the list drawer
await page.locator('.file-details__remove').click()
await page.locator('.upload__toggler.list-drawer__toggler').click()
await openDocDrawer(page, '.upload__toggler.list-drawer__toggler')
const listDrawer = page.locator('[id^=list-drawer_1_]')
await expect(listDrawer).toBeVisible()
// upload an image and try to select it
await listDrawer.locator('button.list-drawer__create-new-button.doc-drawer__toggler').click()
await openDocDrawer(page, 'button.list-drawer__create-new-button.doc-drawer__toggler')
await expect(page.locator('[id^=doc-drawer_media_2_]')).toBeVisible()
// upload an image and try to select it
await page
.locator('[id^=doc-drawer_media_2_] .file-field__upload input[type="file"]')
.setInputFiles(path.resolve(dirname, './image.png'))