From ad6684847d7cf8d64b5418f2ac8b13814ef9ec7e Mon Sep 17 00:00:00 2001 From: siimsams Date: Sun, 14 Sep 2025 19:04:28 +0300 Subject: [PATCH] feat: add custom views to the navigation --- .../next/src/elements/Nav/index.client.tsx | 5 +++ packages/next/src/elements/Nav/index.tsx | 20 +++++++++-- .../next/src/utilities/getVisibleEntities.ts | 5 +++ packages/payload/src/admin/types.ts | 1 + packages/payload/src/admin/views/index.ts | 22 ++++++++++++- .../payload/src/utilities/formatAdminURL.ts | 2 +- packages/translations/src/clientKeys.ts | 1 + packages/translations/src/languages/ar.ts | 1 + packages/translations/src/languages/az.ts | 1 + packages/translations/src/languages/bg.ts | 1 + packages/translations/src/languages/bnBd.ts | 1 + packages/translations/src/languages/bnIn.ts | 1 + packages/translations/src/languages/ca.ts | 1 + packages/translations/src/languages/cs.ts | 1 + packages/translations/src/languages/da.ts | 1 + packages/translations/src/languages/de.ts | 1 + packages/translations/src/languages/en.ts | 1 + packages/translations/src/languages/es.ts | 1 + packages/translations/src/languages/et.ts | 1 + packages/translations/src/languages/fa.ts | 1 + packages/translations/src/languages/fr.ts | 1 + packages/translations/src/languages/he.ts | 1 + packages/translations/src/languages/hr.ts | 1 + packages/translations/src/languages/hu.ts | 1 + packages/translations/src/languages/hy.ts | 1 + packages/translations/src/languages/id.ts | 1 + packages/translations/src/languages/is.ts | 1 + packages/translations/src/languages/it.ts | 1 + packages/translations/src/languages/ja.ts | 1 + packages/translations/src/languages/ko.ts | 1 + packages/translations/src/languages/lt.ts | 1 + packages/translations/src/languages/lv.ts | 1 + packages/translations/src/languages/my.ts | 1 + packages/translations/src/languages/nb.ts | 1 + packages/translations/src/languages/nl.ts | 1 + packages/translations/src/languages/pl.ts | 1 + packages/translations/src/languages/pt.ts | 1 + packages/translations/src/languages/ro.ts | 1 + packages/translations/src/languages/rs.ts | 1 + .../translations/src/languages/rsLatin.ts | 1 + packages/translations/src/languages/ru.ts | 1 + packages/translations/src/languages/sk.ts | 1 + packages/translations/src/languages/sl.ts | 1 + packages/translations/src/languages/sv.ts | 1 + packages/translations/src/languages/th.ts | 1 + packages/translations/src/languages/tr.ts | 1 + packages/translations/src/languages/uk.ts | 1 + packages/translations/src/languages/vi.ts | 1 + packages/translations/src/languages/zh.ts | 1 + packages/translations/src/languages/zhTw.ts | 1 + packages/ui/src/utilities/groupNavItems.ts | 33 +++++++++++++++---- test/admin/config.ts | 7 ++++ 52 files changed, 128 insertions(+), 11 deletions(-) diff --git a/packages/next/src/elements/Nav/index.client.tsx b/packages/next/src/elements/Nav/index.client.tsx index 7ba3213421f..33e2a833113 100644 --- a/packages/next/src/elements/Nav/index.client.tsx +++ b/packages/next/src/elements/Nav/index.client.tsx @@ -57,6 +57,11 @@ export const DefaultNavClient: React.FC<{ id = `nav-global-${slug}` } + if (type === EntityType.customView) { + href = formatAdminURL({ adminRoute, path: slug }) + id = `nav-custom-view-${slug}` + } + const isActive = pathname.startsWith(href) && ['/', undefined].includes(pathname[href.length]) diff --git a/packages/next/src/elements/Nav/index.tsx b/packages/next/src/elements/Nav/index.tsx index c7aabc3aecf..cc53cc87ee3 100644 --- a/packages/next/src/elements/Nav/index.tsx +++ b/packages/next/src/elements/Nav/index.tsx @@ -40,7 +40,7 @@ export const DefaultNav: React.FC = async (props) => { const { admin: { - components: { afterNavLinks, beforeNavLinks, logout }, + components: { afterNavLinks, beforeNavLinks, logout, views }, }, collections, globals, @@ -66,11 +66,27 @@ export const DefaultNav: React.FC = async (props) => { entity: global, }) satisfies EntityToGroup, ), + ...Object.values(views || {}) + .filter( + ({ path }) => + // Include when visibleEntities.customViews is missing or includes the path + !visibleEntities.customViews || visibleEntities.customViews.includes(path), + ) + .map( + (customView) => + ({ + type: EntityType.customView, + entity: { + slug: customView.path, + admin: customView.admin, + labels: customView.labels, + }, + }) satisfies EntityToGroup, + ), ], permissions, i18n, ) - const navPreferences = await getNavPrefs(req) const LogoutComponent = RenderServerComponent({ diff --git a/packages/next/src/utilities/getVisibleEntities.ts b/packages/next/src/utilities/getVisibleEntities.ts index 1b47202dbe9..af5438257e6 100644 --- a/packages/next/src/utilities/getVisibleEntities.ts +++ b/packages/next/src/utilities/getVisibleEntities.ts @@ -9,6 +9,11 @@ export function getVisibleEntities({ req }: { req: PayloadRequest }): VisibleEnt !isEntityHidden({ hidden, user: req.user }) ? slug : null, ) .filter(Boolean), + customViews: Object.values(req.payload.config.admin?.components?.views || {}) + .map(({ admin, path }) => + !isEntityHidden({ hidden: admin?.hidden, user: req.user }) ? path : null, + ) + .filter(Boolean), globals: req.payload.config.globals .map(({ slug, admin: { hidden } }) => !isEntityHidden({ hidden, user: req.user }) ? slug : null, diff --git a/packages/payload/src/admin/types.ts b/packages/payload/src/admin/types.ts index ff3792db1c6..2bfc58bf09e 100644 --- a/packages/payload/src/admin/types.ts +++ b/packages/payload/src/admin/types.ts @@ -666,6 +666,7 @@ export type { AdminViewServerProps, AdminViewServerPropsOnly, InitPageResult, + SanitizedCustomViewConfig, ServerPropsFromView, ViewDescriptionClientProps, ViewDescriptionServerProps, diff --git a/packages/payload/src/admin/views/index.ts b/packages/payload/src/admin/views/index.ts index 028abc29e0e..1870a26fc95 100644 --- a/packages/payload/src/admin/views/index.ts +++ b/packages/payload/src/admin/views/index.ts @@ -2,15 +2,20 @@ import type { ClientTranslationsObject } from '@payloadcms/translations' import type { SanitizedPermissions } from '../../auth/index.js' import type { ImportMap } from '../../bin/generateImportMap/index.js' -import type { SanitizedCollectionConfig } from '../../collections/config/types.js' +import type { + CollectionAdminOptions, + SanitizedCollectionConfig, +} from '../../collections/config/types.js' import type { ClientConfig } from '../../config/client.js' import type { CustomComponent, + LabelFunction, Locale, MetaConfig, PayloadComponent, SanitizedConfig, ServerProps, + StaticLabel, } from '../../config/types.js' import type { SanitizedGlobalConfig } from '../../globals/config/types.js' import type { PayloadRequest } from '../../types/index.js' @@ -19,9 +24,17 @@ import type { Data, StaticDescription } from '../types.js' import type { DocumentSubViewTypes } from './document.js' export type AdminViewConfig = { + admin?: { + group?: CollectionAdminOptions['group'] + hidden?: CollectionAdminOptions['hidden'] + } Component: PayloadComponent /** Whether the path should be matched exactly or as a prefix */ exact?: boolean + labels?: { + plural?: LabelFunction | StaticLabel + singular?: LabelFunction | StaticLabel + } meta?: MetaConfig /** * Any valid URL path or array of paths that [`path-to-regexp`](https://www.npmjs.com/package/path-to-regex) understands. Must begin with a forward slash (`/`). @@ -31,6 +44,12 @@ export type AdminViewConfig = { strict?: boolean } +export type SanitizedCustomViewConfig = { + admin: AdminViewConfig['admin'] + labels: AdminViewConfig['labels'] + slug: AdminViewConfig['path'] +} + export type AdminViewClientProps = { browseByFolderSlugs?: SanitizedCollectionConfig['slug'][] clientConfig: ClientConfig @@ -68,6 +87,7 @@ export type AdminViewComponent = PayloadComponent export type VisibleEntities = { collections: SanitizedCollectionConfig['slug'][] + customViews: SanitizedCustomViewConfig['slug'][] globals: SanitizedGlobalConfig['slug'][] } diff --git a/packages/payload/src/utilities/formatAdminURL.ts b/packages/payload/src/utilities/formatAdminURL.ts index 2ba612838ed..364f1c9d6e5 100644 --- a/packages/payload/src/utilities/formatAdminURL.ts +++ b/packages/payload/src/utilities/formatAdminURL.ts @@ -4,7 +4,7 @@ import type { Config } from '../config/types.js' export const formatAdminURL = (args: { adminRoute: NonNullable['admin'] basePath?: string - path: '' | `/${string}` | null | undefined + path: `/${string}` | null | string | undefined serverURL?: Config['serverURL'] }): string => { const { adminRoute, basePath = '', path: pathFromArgs, serverURL } = args diff --git a/packages/translations/src/clientKeys.ts b/packages/translations/src/clientKeys.ts index af0d632a9e3..4fb4442421c 100644 --- a/packages/translations/src/clientKeys.ts +++ b/packages/translations/src/clientKeys.ts @@ -180,6 +180,7 @@ export const clientTranslationKeys = createClientTranslationKeys([ 'general:close', 'general:collapse', 'general:collections', + 'general:customViews', 'general:confirmMove', 'general:yes', 'general:no', diff --git a/packages/translations/src/languages/ar.ts b/packages/translations/src/languages/ar.ts index 7606ea5ea75..ad8cb80d78a 100644 --- a/packages/translations/src/languages/ar.ts +++ b/packages/translations/src/languages/ar.ts @@ -269,6 +269,7 @@ export const arTranslations: DefaultTranslationsObject = { currentlyEditing: 'يقوم حاليًا بتحرير هذا المستند. إذا توليت، سيتم منعه من الاستمرار في التحرير وقد يفقد التغييرات غير المحفوظة.', custom: 'مخصص', + customViews: 'العروض المخصصة', dark: 'غامق', dashboard: 'لوحة التّحكّم', delete: 'حذف', diff --git a/packages/translations/src/languages/az.ts b/packages/translations/src/languages/az.ts index c8220c62027..4ae75c5f9fc 100644 --- a/packages/translations/src/languages/az.ts +++ b/packages/translations/src/languages/az.ts @@ -281,6 +281,7 @@ export const azTranslations: DefaultTranslationsObject = { currentlyEditing: 'hazırda bu sənədi redaktə edir. Siz öhdəliyi götürsəniz, redaktəni davam etdirməkdən bloklanacaqlar və qeydə alınmamış dəyişiklikləri itirə bilərlər.', custom: 'Xüsusi', + customViews: 'Fərdi Görünüşlər', dark: 'Tünd', dashboard: 'Panel', delete: 'Sil', diff --git a/packages/translations/src/languages/bg.ts b/packages/translations/src/languages/bg.ts index 38707a4c4b0..31bb0f17174 100644 --- a/packages/translations/src/languages/bg.ts +++ b/packages/translations/src/languages/bg.ts @@ -278,6 +278,7 @@ export const bgTranslations: DefaultTranslationsObject = { currentlyEditing: 'в момента редактира този документ. Ако поемете управлението, те ще бъдат блокирани от продължаване на редактирането и може да загубят незаписаните промени.', custom: 'Персонализиран', + customViews: 'Персонализирани Изгледи', dark: 'Тъмна', dashboard: 'Табло', delete: 'Изтрий', diff --git a/packages/translations/src/languages/bnBd.ts b/packages/translations/src/languages/bnBd.ts index 1d40b62fd6c..db1b320f9b7 100644 --- a/packages/translations/src/languages/bnBd.ts +++ b/packages/translations/src/languages/bnBd.ts @@ -283,6 +283,7 @@ export const bnBdTranslations: DefaultTranslationsObject = { currentlyEditing: 'বর্তমানে এই ডকুমেন্টটি সম্পাদনা করছেন। আপনি যদি দায়িত্ব নেন, তাহলে তারা সম্পাদনা করা থেকে ব্লক হয়ে যাবে এবং সংরক্ষণ না করা পরিবর্তনগুলি হারাতে পারে।', custom: 'কাস্টম', + customViews: 'কাস্টম ভিউ', dark: 'ডার্ক', dashboard: 'ড্যাশবোর্ড', delete: 'মুছুন', diff --git a/packages/translations/src/languages/bnIn.ts b/packages/translations/src/languages/bnIn.ts index ec2f51ff374..8f6a62f041a 100644 --- a/packages/translations/src/languages/bnIn.ts +++ b/packages/translations/src/languages/bnIn.ts @@ -282,6 +282,7 @@ export const bnInTranslations: DefaultTranslationsObject = { currentlyEditing: 'বর্তমানে এই ডকুমেন্টটি সম্পাদনা করছেন। আপনি যদি দায়িত্ব নেন, তাহলে তারা সম্পাদনা করা থেকে ব্লক হয়ে যাবে এবং সংরক্ষণ না করা পরিবর্তনগুলি হারাতে পারে।', custom: 'কাস্টম', + customViews: 'কাস্টম ভিউ', dark: 'ডার্ক', dashboard: 'ড্যাশবোর্ড', delete: 'মুছুন', diff --git a/packages/translations/src/languages/ca.ts b/packages/translations/src/languages/ca.ts index 2f20a825381..a72f5a81200 100644 --- a/packages/translations/src/languages/ca.ts +++ b/packages/translations/src/languages/ca.ts @@ -280,6 +280,7 @@ export const caTranslations: DefaultTranslationsObject = { currentlyEditing: 'esta editant actualment aquest document. Si prens el control, es bloquejarà per continuar editant i potser perdrà els canvis no desats.', custom: 'Personalitzat', + customViews: 'Vistes Personalitzades', dark: 'Fosc', dashboard: 'Tauler', delete: 'Eliminar', diff --git a/packages/translations/src/languages/cs.ts b/packages/translations/src/languages/cs.ts index 0472b1c10e7..e5c74184e05 100644 --- a/packages/translations/src/languages/cs.ts +++ b/packages/translations/src/languages/cs.ts @@ -277,6 +277,7 @@ export const csTranslations: DefaultTranslationsObject = { currentlyEditing: 'právě upravuje tento dokument. Pokud převezmete kontrolu, budou zablokováni v pokračování úprav a mohou také přijít o neuložené změny.', custom: 'Vlastní', + customViews: 'Vlastní Zobrazení', dark: 'Tmavý', dashboard: 'Nástěnka', delete: 'Odstranit', diff --git a/packages/translations/src/languages/da.ts b/packages/translations/src/languages/da.ts index 704cc4f6fff..cf67884f265 100644 --- a/packages/translations/src/languages/da.ts +++ b/packages/translations/src/languages/da.ts @@ -277,6 +277,7 @@ export const daTranslations: DefaultTranslationsObject = { creatingNewLabel: 'Opretter ny {{label}}', currentlyEditing: 'Du redigerer i øjeblikket', custom: 'Tilpasset', + customViews: 'Brugerdefinerede Visninger', dark: 'Mørk', dashboard: 'Dashboard', delete: 'Slet', diff --git a/packages/translations/src/languages/de.ts b/packages/translations/src/languages/de.ts index c41f51fed84..eaa96b1db0e 100644 --- a/packages/translations/src/languages/de.ts +++ b/packages/translations/src/languages/de.ts @@ -288,6 +288,7 @@ export const deTranslations: DefaultTranslationsObject = { currentlyEditing: 'bearbeitet gerade dieses Dokument. Wenn du übernimmst, wird die Bearbeitung blockiert und nicht gespeicherte Änderungen können verloren gehen.', custom: 'Benutzerdefiniert', + customViews: 'Benutzerdefinierte Ansichten', dark: 'Dunkel', dashboard: 'Übersicht', delete: 'Löschen', diff --git a/packages/translations/src/languages/en.ts b/packages/translations/src/languages/en.ts index ae4122639aa..392f4b5e3ef 100644 --- a/packages/translations/src/languages/en.ts +++ b/packages/translations/src/languages/en.ts @@ -282,6 +282,7 @@ export const enTranslations = { currentlyEditing: 'is currently editing this document. If you take over, they will be blocked from continuing to edit, and may also lose unsaved changes.', custom: 'Custom', + customViews: 'Custom Views', dark: 'Dark', dashboard: 'Dashboard', delete: 'Delete', diff --git a/packages/translations/src/languages/es.ts b/packages/translations/src/languages/es.ts index 0abe30922e3..5c09f4347e6 100644 --- a/packages/translations/src/languages/es.ts +++ b/packages/translations/src/languages/es.ts @@ -284,6 +284,7 @@ export const esTranslations: DefaultTranslationsObject = { currentlyEditing: 'está editando este documento. Si tomas el control, se le impedirá continuar editando y podría perder los cambios no guardados.', custom: 'Personalizado', + customViews: 'Vistas Personalizadas', dark: 'Oscuro', dashboard: 'Panel de Control', delete: 'Eliminar', diff --git a/packages/translations/src/languages/et.ts b/packages/translations/src/languages/et.ts index 6f02d0a873e..b6e44640122 100644 --- a/packages/translations/src/languages/et.ts +++ b/packages/translations/src/languages/et.ts @@ -276,6 +276,7 @@ export const etTranslations: DefaultTranslationsObject = { currentlyEditing: 'muudab praegu seda dokumenti. Kui võtate üle, blokeeritakse neil muutmise jätkamine ja nad võivad kaotada salvestamata muudatused.', custom: 'Kohandatud', + customViews: 'Kohandatud Vaated', dark: 'Tume', dashboard: 'Töölaud', delete: 'Kustuta', diff --git a/packages/translations/src/languages/fa.ts b/packages/translations/src/languages/fa.ts index c5c318ff642..0423b86415f 100644 --- a/packages/translations/src/languages/fa.ts +++ b/packages/translations/src/languages/fa.ts @@ -275,6 +275,7 @@ export const faTranslations: DefaultTranslationsObject = { currentlyEditing: 'در حال حاضر در حال ویرایش این سند است. اگر شما مسئولیت را به عهده بگیرید، از ادامه ویرایش مسدود خواهد شد و ممکن است تغییرات ذخیره نشده را از دست بدهند.', custom: 'سفارشی', + customViews: 'نماهای سفارشی', dark: 'تاریک', dashboard: 'پیشخوان', delete: 'حذف', diff --git a/packages/translations/src/languages/fr.ts b/packages/translations/src/languages/fr.ts index b5fed7992d7..37a2c775e46 100644 --- a/packages/translations/src/languages/fr.ts +++ b/packages/translations/src/languages/fr.ts @@ -289,6 +289,7 @@ export const frTranslations: DefaultTranslationsObject = { currentlyEditing: 'est en train de modifier ce document. Si vous prenez le contrôle, ils seront bloqués pour continuer à modifier et pourraient également perdre les modifications non enregistrées.', custom: 'Personnalisé', + customViews: 'Vues Personnalisées', dark: 'Sombre', dashboard: 'Tableau de bord', delete: 'Supprimer', diff --git a/packages/translations/src/languages/he.ts b/packages/translations/src/languages/he.ts index 883628d6afa..4ac1d6963be 100644 --- a/packages/translations/src/languages/he.ts +++ b/packages/translations/src/languages/he.ts @@ -269,6 +269,7 @@ export const heTranslations: DefaultTranslationsObject = { currentlyEditing: 'עורך כעת את המסמך הזה. אם תשתלט, הם ייחסמו מהמשך העריכה וייתכן שגם יאבדו שינויים שלא נשמרו.', custom: 'מותאם אישית', + customViews: 'תצוגות מותאמות אישית', dark: 'כהה', dashboard: 'לוח מחוונים', delete: 'מחיקה', diff --git a/packages/translations/src/languages/hr.ts b/packages/translations/src/languages/hr.ts index f1de2085f2d..efc00a4173d 100644 --- a/packages/translations/src/languages/hr.ts +++ b/packages/translations/src/languages/hr.ts @@ -279,6 +279,7 @@ export const hrTranslations: DefaultTranslationsObject = { currentlyEditing: 'trenutno uređuje ovaj dokument. Ako preuzmete, bit će im onemogućeno daljnje uređivanje i mogu izgubiti nespremljene promjene.', custom: 'Prilagođen', + customViews: 'Prilagođeni Prikazi', dark: 'Tamno', dashboard: 'Nadzorna ploča', delete: 'Izbriši', diff --git a/packages/translations/src/languages/hu.ts b/packages/translations/src/languages/hu.ts index 21760ae04c5..d6af6311024 100644 --- a/packages/translations/src/languages/hu.ts +++ b/packages/translations/src/languages/hu.ts @@ -283,6 +283,7 @@ export const huTranslations: DefaultTranslationsObject = { currentlyEditing: 'jelenleg szerkeszti ezt a dokumentumot. Ha átveszed, nem tudja folytatni a szerkesztést, és elveszítheti a mentetlen módosításokat.', custom: 'Egyéni', + customViews: 'Egyéni Nézetek', dark: 'Sötét', dashboard: 'Irányítópult', delete: 'Törlés', diff --git a/packages/translations/src/languages/hy.ts b/packages/translations/src/languages/hy.ts index 7e642a0948f..71d8acddbeb 100644 --- a/packages/translations/src/languages/hy.ts +++ b/packages/translations/src/languages/hy.ts @@ -280,6 +280,7 @@ export const hyTranslations: DefaultTranslationsObject = { currentlyEditing: 'ներկայումս խմբագրում է այս փաստաթուղթը։ Եթե Դուք ստանձնեք վերահսկողությունը, նա չի կարողանա շարունակել խմբագրումը և կարող է կորցնել չպահպանված փոփոխությունները։', custom: 'Հատուկ', + customViews: 'Հատուկ Տեսքեր', dark: 'Մուգ', dashboard: 'Վահանակ', delete: 'Ջնջել', diff --git a/packages/translations/src/languages/id.ts b/packages/translations/src/languages/id.ts index c455e688849..58c4ce58ae8 100644 --- a/packages/translations/src/languages/id.ts +++ b/packages/translations/src/languages/id.ts @@ -283,6 +283,7 @@ export const idTranslations = { currentlyEditing: 'sedang mengedit dokumen ini. Jika Anda mengambil alih, mereka akan diblokir untuk melanjutkan pengeditan, dan mungkin juga kehilangan perubahan yang belum disimpan.', custom: 'Kustom', + customViews: 'Tampilan Khusus', dark: 'Gelap', dashboard: 'Dasbor', delete: 'Hapus', diff --git a/packages/translations/src/languages/is.ts b/packages/translations/src/languages/is.ts index 68abee17222..5adf705929b 100644 --- a/packages/translations/src/languages/is.ts +++ b/packages/translations/src/languages/is.ts @@ -279,6 +279,7 @@ export const isTranslations = { currentlyEditing: 'er núna að breyta þessu skjali. Ef þú tekur yfir munu þeir verða hindraðir frá því að halda áfram að breyta og gætu líka misst óvistaðar breytingar.', custom: 'Sérsniðið', + customViews: 'Sérsniðnar Skoðanir', dark: 'Dökkt', dashboard: 'Stjórnborð', delete: 'Eyða', diff --git a/packages/translations/src/languages/it.ts b/packages/translations/src/languages/it.ts index bbef1b85997..a79a9cd6f27 100644 --- a/packages/translations/src/languages/it.ts +++ b/packages/translations/src/languages/it.ts @@ -282,6 +282,7 @@ export const itTranslations: DefaultTranslationsObject = { currentlyEditing: 'sta attualmente modificando questo documento. Se prendi il controllo, verranno bloccati dal continuare a modificare e potrebbero anche perdere le modifiche non salvate.', custom: 'Personalizzato', + customViews: 'Viste Personalizzate', dark: 'Scuro', dashboard: 'Dashboard', delete: 'Elimina', diff --git a/packages/translations/src/languages/ja.ts b/packages/translations/src/languages/ja.ts index ef3ffdb2836..ad3788b038c 100644 --- a/packages/translations/src/languages/ja.ts +++ b/packages/translations/src/languages/ja.ts @@ -281,6 +281,7 @@ export const jaTranslations: DefaultTranslationsObject = { currentlyEditing: 'このドキュメントを編集中です。あなたが引き継ぐと、編集を続けることができなくなり、未保存の変更が失われる可能性があります。', custom: 'カスタム', + customViews: 'カスタムビュー', dark: 'ダークモード', dashboard: 'ダッシュボード', delete: '削除', diff --git a/packages/translations/src/languages/ko.ts b/packages/translations/src/languages/ko.ts index 080e1790d91..5eb7c8658ba 100644 --- a/packages/translations/src/languages/ko.ts +++ b/packages/translations/src/languages/ko.ts @@ -276,6 +276,7 @@ export const koTranslations: DefaultTranslationsObject = { currentlyEditing: '현재 이 문서를 편집 중입니다. 당신이 인수하면, 편집을 계속할 수 없게 되고, 저장되지 않은 변경 사항이 손실될 수 있습니다.', custom: '사용자 정의', + customViews: '사용자 정의 뷰', dark: '다크', dashboard: '대시보드', delete: '삭제', diff --git a/packages/translations/src/languages/lt.ts b/packages/translations/src/languages/lt.ts index 36bd82dc559..e56efb8c106 100644 --- a/packages/translations/src/languages/lt.ts +++ b/packages/translations/src/languages/lt.ts @@ -282,6 +282,7 @@ export const ltTranslations: DefaultTranslationsObject = { currentlyEditing: 'šiuo metu redaguoja šį dokumentą. Jei perimsite, jie bus užblokuoti ir negalės toliau redaguoti, o taip pat gali prarasti neišsaugotus pakeitimus.', custom: 'Paprastas', + customViews: 'Pasirinktiniai Rodiniai', dark: 'Tamsus', dashboard: 'Prietaisų skydelis', delete: 'Ištrinti', diff --git a/packages/translations/src/languages/lv.ts b/packages/translations/src/languages/lv.ts index e1f0b478d2b..3ab73d95e48 100644 --- a/packages/translations/src/languages/lv.ts +++ b/packages/translations/src/languages/lv.ts @@ -280,6 +280,7 @@ export const lvTranslations: DefaultTranslationsObject = { currentlyEditing: 'pašlaik rediģē šo dokumentu. Ja pārņemsiet, viņi tiks bloķēti no turpmākas rediģēšanas un var zaudēt nesaglabātās izmaiņas.', custom: 'Pielāgots', + customViews: 'Pielāgoti Skati', dark: 'Tumšs', dashboard: 'Panelis', delete: 'Dzēst', diff --git a/packages/translations/src/languages/my.ts b/packages/translations/src/languages/my.ts index d81e280eb91..febfb71c28b 100644 --- a/packages/translations/src/languages/my.ts +++ b/packages/translations/src/languages/my.ts @@ -281,6 +281,7 @@ export const myTranslations: DefaultTranslationsObject = { currentlyEditing: 'ဒီစာရွက်စာတမ်းကိုလက်ရှိပြင်ဆင်နေသည်။ သင်ဤတာဝန်ကိုယူပါက၊ သူတို့သည်ဆက်လက်ပြင်ဆင်ခွင့်မရအောင်ပိတ်ထားမည်ဖြစ်ပြီး၊ မသိမ်းဆည်းရသေးသောပြင်ဆင်မှုများကိုလည်းဆုံးရှုံးနိုင်သည်။', custom: 'ထုတ်ကုန် စိတ်ကြိုက်', + customViews: 'စိတ်ကြိုက်မြင်ကွင်းများ', dark: 'အမှောင်', dashboard: 'ပင်မစာမျက်နှာ', delete: 'ဖျက်မည်။', diff --git a/packages/translations/src/languages/nb.ts b/packages/translations/src/languages/nb.ts index d09a7850d6f..108cfbe20e6 100644 --- a/packages/translations/src/languages/nb.ts +++ b/packages/translations/src/languages/nb.ts @@ -278,6 +278,7 @@ export const nbTranslations: DefaultTranslationsObject = { currentlyEditing: 'redigerer for øyeblikket dette dokumentet. Hvis du tar over, blir de blokkert fra å fortsette å redigere, og de kan også miste ulagrede endringer.', custom: 'Tilpasset', + customViews: 'Tilpassede Visninger', dark: 'Mørk', dashboard: 'Kontrollpanel', delete: 'Slett', diff --git a/packages/translations/src/languages/nl.ts b/packages/translations/src/languages/nl.ts index 87e5a204170..6ae43bfc09d 100644 --- a/packages/translations/src/languages/nl.ts +++ b/packages/translations/src/languages/nl.ts @@ -286,6 +286,7 @@ export const nlTranslations: DefaultTranslationsObject = { currentlyEditing: 'is momenteel dit document aan het bewerken. Als je het overneemt, wordt voorkomen dat ze doorgaan met bewerken en kunnen ze ook niet-opgeslagen wijzigingen verliezen.', custom: 'Aangepast', + customViews: 'Aangepaste Weergaven', dark: 'Donker', dashboard: 'Dashboard', delete: 'Verwijderen', diff --git a/packages/translations/src/languages/pl.ts b/packages/translations/src/languages/pl.ts index 474260ce32b..17ae50d0329 100644 --- a/packages/translations/src/languages/pl.ts +++ b/packages/translations/src/languages/pl.ts @@ -278,6 +278,7 @@ export const plTranslations: DefaultTranslationsObject = { currentlyEditing: 'obecnie edytuje ten dokument. Jeśli przejmiesz kontrolę, zostaną zablokowani przed dalszą edycją i mogą również utracić niezapisane zmiany.', custom: 'Niestandardowy', + customViews: 'Niestandardowe Widoki', dark: 'Ciemny', dashboard: 'Panel', delete: 'Usuń', diff --git a/packages/translations/src/languages/pt.ts b/packages/translations/src/languages/pt.ts index 401ba0a9c23..43fa1bc3dbd 100644 --- a/packages/translations/src/languages/pt.ts +++ b/packages/translations/src/languages/pt.ts @@ -280,6 +280,7 @@ export const ptTranslations: DefaultTranslationsObject = { currentlyEditing: 'está editando este documento no momento. Se você assumir, eles serão impedidos de continuar editando e poderão perder alterações não salvas.', custom: 'Personalizado', + customViews: 'Visualizações Personalizadas', dark: 'Escuro', dashboard: 'Painel de Controle', delete: 'Excluir', diff --git a/packages/translations/src/languages/ro.ts b/packages/translations/src/languages/ro.ts index 6183488ac3f..af3f419dd26 100644 --- a/packages/translations/src/languages/ro.ts +++ b/packages/translations/src/languages/ro.ts @@ -284,6 +284,7 @@ export const roTranslations: DefaultTranslationsObject = { currentlyEditing: 'editează în prezent acest document. Dacă preiei controlul, vor fi blocați să continue editarea și ar putea pierde modificările nesalvate.', custom: 'Personalizat', + customViews: 'Vizualizări Personalizate', dark: 'Dark', dashboard: 'Panoul de bord', delete: 'Șterge', diff --git a/packages/translations/src/languages/rs.ts b/packages/translations/src/languages/rs.ts index cd4532168d4..2229649a510 100644 --- a/packages/translations/src/languages/rs.ts +++ b/packages/translations/src/languages/rs.ts @@ -280,6 +280,7 @@ export const rsTranslations: DefaultTranslationsObject = { currentlyEditing: 'тренутно уређује овај документ. Ако преузмете контролу, биће блокирани да наставе са уређивањем и могу изгубити несачуване измене.', custom: 'Prilagođeno', + customViews: 'Прилагођени Прикази', dark: 'Тамно', dashboard: 'Контролни панел', delete: 'Обриши', diff --git a/packages/translations/src/languages/rsLatin.ts b/packages/translations/src/languages/rsLatin.ts index fb3f82fca28..c476d0c07a5 100644 --- a/packages/translations/src/languages/rsLatin.ts +++ b/packages/translations/src/languages/rsLatin.ts @@ -280,6 +280,7 @@ export const rsLatinTranslations: DefaultTranslationsObject = { currentlyEditing: 'trenutno uređuje ovaj dokument. Ako preuzmete kontrolu, biće blokirani da nastave sa uređivanjem i mogu izgubiti nesačuvane izmene.', custom: 'Prilagođen', + customViews: 'Prilagođeni Prikazi', dark: 'Tamno', dashboard: 'Kontrolni panel', delete: 'Obriši', diff --git a/packages/translations/src/languages/ru.ts b/packages/translations/src/languages/ru.ts index 6c9970841ee..5288b20fc3d 100644 --- a/packages/translations/src/languages/ru.ts +++ b/packages/translations/src/languages/ru.ts @@ -281,6 +281,7 @@ export const ruTranslations: DefaultTranslationsObject = { currentlyEditing: 'в настоящее время редактирует этот документ. Если вы возьмете на себя, они будут заблокированы от продолжения редактирования и могут потерять несохраненные изменения.', custom: 'Обычай', + customViews: 'Пользовательские Представления', dark: 'Тёмная', dashboard: 'Панель', delete: 'Удалить', diff --git a/packages/translations/src/languages/sk.ts b/packages/translations/src/languages/sk.ts index b9a09dca8ec..71a409f72e4 100644 --- a/packages/translations/src/languages/sk.ts +++ b/packages/translations/src/languages/sk.ts @@ -280,6 +280,7 @@ export const skTranslations: DefaultTranslationsObject = { currentlyEditing: 'práve upravuje tento dokument. Ak prevezmete kontrolu, budú zablokovaní z pokračovania v úpravách a môžu tiež stratiť neuložené zmeny.', custom: 'Vlastný', + customViews: 'Vlastné Zobrazenia', dark: 'Tmavý', dashboard: 'Nástenka', delete: 'Odstrániť', diff --git a/packages/translations/src/languages/sl.ts b/packages/translations/src/languages/sl.ts index 33fe7b9e2a7..f26190db496 100644 --- a/packages/translations/src/languages/sl.ts +++ b/packages/translations/src/languages/sl.ts @@ -278,6 +278,7 @@ export const slTranslations: DefaultTranslationsObject = { currentlyEditing: 'trenutno ureja ta dokument. Če prevzamete, jim bo onemogočeno nadaljnje urejanje in lahko izgubijo neshranjene spremembe.', custom: 'Po meri', + customViews: 'Prilagojeni Prikazi', dark: 'Temno', dashboard: 'Nadzorna plošča', delete: 'Izbriši', diff --git a/packages/translations/src/languages/sv.ts b/packages/translations/src/languages/sv.ts index 41486246cd6..12dd0399412 100644 --- a/packages/translations/src/languages/sv.ts +++ b/packages/translations/src/languages/sv.ts @@ -279,6 +279,7 @@ export const svTranslations: DefaultTranslationsObject = { currentlyEditing: 'redigerar för närvarande detta dokument. Om du tar över kommer de att blockeras från att fortsätta redigera och kan också förlora osparade ändringar.', custom: 'Anpassad', + customViews: 'Anpassade Vyer', dark: 'Mörkt', dashboard: 'Översikt', delete: 'Ta bort', diff --git a/packages/translations/src/languages/th.ts b/packages/translations/src/languages/th.ts index 626fa1a1937..cd7217d2a28 100644 --- a/packages/translations/src/languages/th.ts +++ b/packages/translations/src/languages/th.ts @@ -272,6 +272,7 @@ export const thTranslations: DefaultTranslationsObject = { currentlyEditing: 'กำลังแก้ไขเอกสารนี้อยู่ในขณะนี้ หากคุณเข้าครอบครอง พวกเขาจะถูกบล็อกจากการแก้ไขต่อไป และอาจสูญเสียการเปลี่ยนแปลงที่ไม่ได้บันทึก', custom: 'ที่ทำขึ้นเฉพาะ', + customViews: 'Custom Views', dark: 'มืด', dashboard: 'แดชบอร์ด', delete: 'ลบ', diff --git a/packages/translations/src/languages/tr.ts b/packages/translations/src/languages/tr.ts index 3d0f2937449..3cc5a9477ed 100644 --- a/packages/translations/src/languages/tr.ts +++ b/packages/translations/src/languages/tr.ts @@ -282,6 +282,7 @@ export const trTranslations: DefaultTranslationsObject = { currentlyEditing: 'şu anda bu belgeyi düzenliyor. Devralırsanız, düzenlemeye devam etmeleri engellenecek ve kaydedilmemiş değişiklikleri de kaybedebilirler.', custom: 'Özel', + customViews: 'Özel Görünümler', dark: 'Karanlık', dashboard: 'Anasayfa', delete: 'Sil', diff --git a/packages/translations/src/languages/uk.ts b/packages/translations/src/languages/uk.ts index 83658ee14bb..8f903e23707 100644 --- a/packages/translations/src/languages/uk.ts +++ b/packages/translations/src/languages/uk.ts @@ -278,6 +278,7 @@ export const ukTranslations: DefaultTranslationsObject = { currentlyEditing: 'зараз редагує цей документ. Якщо ви переберете контроль, їм буде заблоковано продовження редагування, і вони також можуть втратити незбережені зміни.', custom: 'Спеціальне замовлення', + customViews: 'Користувацькі Подання', dark: 'Темна', dashboard: 'Головна', delete: 'Видалити', diff --git a/packages/translations/src/languages/vi.ts b/packages/translations/src/languages/vi.ts index f5f3eb89b6d..c411d0cfc98 100644 --- a/packages/translations/src/languages/vi.ts +++ b/packages/translations/src/languages/vi.ts @@ -278,6 +278,7 @@ export const viTranslations: DefaultTranslationsObject = { currentlyEditing: 'hiện đang chỉnh sửa tài liệu này. Nếu bạn tiếp quản, họ sẽ bị chặn tiếp tục chỉnh sửa và cũng có thể mất các thay đổi chưa lưu.', custom: 'Tùy chỉnh', + customViews: 'Custom Views', dark: 'Nền tối', dashboard: 'Bảng điều khiển', delete: 'Xóa', diff --git a/packages/translations/src/languages/zh.ts b/packages/translations/src/languages/zh.ts index 25523655eef..00d2175d65e 100644 --- a/packages/translations/src/languages/zh.ts +++ b/packages/translations/src/languages/zh.ts @@ -261,6 +261,7 @@ export const zhTranslations: DefaultTranslationsObject = { currentlyEditing: '当前正在编辑此文档。如果您接管,他们将无法继续编辑,并且可能会丢失未保存的更改。', custom: '自定义', + customViews: '自定义视图', dark: '深色', dashboard: '仪表板', delete: '删除', diff --git a/packages/translations/src/languages/zhTw.ts b/packages/translations/src/languages/zhTw.ts index ae38bc0a921..94088074617 100644 --- a/packages/translations/src/languages/zhTw.ts +++ b/packages/translations/src/languages/zhTw.ts @@ -262,6 +262,7 @@ export const zhTwTranslations: DefaultTranslationsObject = { currentlyEditing: '目前正在編輯此文件。若您接手,對方將無法繼續編輯,且未儲存的變更可能會遺失。', custom: '自訂', + customViews: '自定義視圖', dark: '深色', dashboard: '儀表板', delete: '刪除', diff --git a/packages/ui/src/utilities/groupNavItems.ts b/packages/ui/src/utilities/groupNavItems.ts index 7eb4b55c44d..7c94c037261 100644 --- a/packages/ui/src/utilities/groupNavItems.ts +++ b/packages/ui/src/utilities/groupNavItems.ts @@ -1,6 +1,7 @@ import type { I18nClient } from '@payloadcms/translations' import type { SanitizedCollectionConfig, + SanitizedCustomViewConfig, SanitizedGlobalConfig, SanitizedPermissions, StaticLabel, @@ -10,6 +11,7 @@ import { getTranslation } from '@payloadcms/translations' export enum EntityType { collection = 'collections', + customView = 'customViews', global = 'globals', } @@ -18,6 +20,10 @@ export type EntityToGroup = entity: SanitizedCollectionConfig type: EntityType.collection } + | { + entity: SanitizedCustomViewConfig + type: EntityType.customView + } | { entity: SanitizedGlobalConfig type: EntityType.global @@ -44,23 +50,30 @@ export function groupNavItems( return groups } - if (permissions?.[entityToGroup.type.toLowerCase()]?.[entityToGroup.entity.slug]?.read) { - const translatedGroup = getTranslation(entityToGroup.entity.admin.group, i18n) + // Custom views don't have permissions in the same way as collections/globals + // They are public by default and should always be included if they pass visibility checks + const hasPermission = + entityToGroup.type === EntityType.customView + ? true // Custom views are public by default + : permissions?.[entityToGroup.type.toLowerCase()]?.[entityToGroup.entity.slug]?.read + + if (hasPermission) { + const translatedGroup = getTranslation(entityToGroup.entity.admin?.group, i18n) const labelOrFunction = 'labels' in entityToGroup.entity - ? entityToGroup.entity.labels.plural + ? entityToGroup.entity.labels?.plural : entityToGroup.entity.label const label = typeof labelOrFunction === 'function' ? labelOrFunction({ i18n, t: i18n.t }) - : labelOrFunction + : labelOrFunction || entityToGroup.entity.slug - if (entityToGroup.entity.admin.group) { + if (entityToGroup.entity.admin?.group) { const existingGroup = groups.find( (group) => getTranslation(group.label, i18n) === translatedGroup, - ) as NavGroupType + ) let matchedGroup: NavGroupType = existingGroup @@ -75,9 +88,11 @@ export function groupNavItems( label, }) } else { + const expectedGroupLabel = i18n.t(`general:${entityToGroup.type}`) const defaultGroup = groups.find((group) => { - return getTranslation(group.label, i18n) === i18n.t(`general:${entityToGroup.type}`) + return getTranslation(group.label, i18n) === expectedGroupLabel }) as NavGroupType + defaultGroup.entities.push({ slug: entityToGroup.entity.slug, type: entityToGroup.type, @@ -97,6 +112,10 @@ export function groupNavItems( entities: [], label: i18n.t('general:globals'), }, + { + entities: [], + label: i18n.t('general:customViews'), + }, ], ) diff --git a/test/admin/config.ts b/test/admin/config.ts index 34ead5ea94d..bfce6a531bb 100644 --- a/test/admin/config.ts +++ b/test/admin/config.ts @@ -93,6 +93,13 @@ export default buildConfigWithDefaults({ CustomDefaultView: { Component: '/components/views/CustomDefault/index.js#CustomDefaultView', path: '/custom-default-view', + labels: { + plural: 'Custom Default Views', + singular: 'Custom Default View', + }, + admin: { + group: 'One', + }, }, CustomMinimalView: { Component: '/components/views/CustomMinimal/index.js#CustomMinimalView',