feat(ui): adds admin.components.listMenuItems option (#11230)
### What? Adds new option `admin.components.listMenuItems` to allow custom components to be injected after the existing list controls in the collection list view. ### Why? Needed to facilitate import/export plugin. #### Testing Use `pnpm dev admin` to see example component and see test added to `test/admin/e2e/list-view`. ## Update since feature was reverted The custom list controls and now rendered with no surrounding padding or border radius. <img width="596" alt="Screenshot 2025-02-17 at 5 06 44 PM" src="https://github.com/user-attachments/assets/57209367-5433-4a4c-8797-0f9671da15c8" /> --------- Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
This commit is contained in:
committed by
GitHub
parent
117949b8d9
commit
8a2b712287
@@ -153,11 +153,12 @@ export const MyCollection: CollectionConfig = {
|
||||
The following options are available:
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| --------------------- |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `afterList` | An array of components to inject _after_ the built-in List View. [More details](../custom-components/list-view#afterlist). |
|
||||
| `afterListTable` | An array of components to inject _after_ the built-in List View's table. [More details](../custom-components/list-view#afterlisttable). |
|
||||
| `beforeList` | An array of components to inject _before_ the built-in List View. [More details](../custom-components/list-view#beforelist). |
|
||||
| `beforeListTable` | An array of components to inject _before_ the built-in List View's table. [More details](../custom-components/list-view#beforelisttable). |
|
||||
| `listMenuItems` | An array of components to render within a menu next to the List Controls (after the Columns and Filters options) |
|
||||
| `Description` | A component to render below the Collection label in the List View. An alternative to the `admin.description` property. [More details](../custom-components/list-view#description). |
|
||||
| `edit` | Override specific components within the Edit View. [More details](#edit-view-options). |
|
||||
| `views` | Override or create new views within the Admin Panel. [More details](../custom-components/custom-views). |
|
||||
|
||||
@@ -44,6 +44,18 @@ export const renderListViewSlots = ({
|
||||
})
|
||||
}
|
||||
|
||||
const listMenuItems = collectionConfig.admin.components?.listMenuItems
|
||||
if (Array.isArray(listMenuItems)) {
|
||||
result.listMenuItems = [
|
||||
RenderServerComponent({
|
||||
clientProps,
|
||||
Component: listMenuItems,
|
||||
importMap: payload.importMap,
|
||||
serverProps,
|
||||
}),
|
||||
]
|
||||
}
|
||||
|
||||
if (collectionConfig.admin.components?.afterListTable) {
|
||||
result.AfterListTable = RenderServerComponent({
|
||||
clientProps: clientProps satisfies AfterListTableClientProps,
|
||||
|
||||
@@ -14,6 +14,7 @@ export type ListViewSlots = {
|
||||
BeforeList?: React.ReactNode
|
||||
BeforeListTable?: React.ReactNode
|
||||
Description?: React.ReactNode
|
||||
listMenuItems?: React.ReactNode[]
|
||||
Table: React.ReactNode
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ export function iterateCollections({
|
||||
})
|
||||
|
||||
addToImportMap(collection.admin?.components?.afterList)
|
||||
addToImportMap(collection.admin?.components?.listMenuItems)
|
||||
addToImportMap(collection.admin?.components?.afterListTable)
|
||||
addToImportMap(collection.admin?.components?.beforeList)
|
||||
addToImportMap(collection.admin?.components?.beforeListTable)
|
||||
|
||||
@@ -304,6 +304,7 @@ export type CollectionAdminOptions = {
|
||||
*/
|
||||
Upload?: CustomUpload
|
||||
}
|
||||
listMenuItems?: CustomComponent[]
|
||||
views?: {
|
||||
/**
|
||||
* Set to a React component to replace the entire Edit View, including all nested routes.
|
||||
|
||||
@@ -209,6 +209,7 @@ export const clientTranslationKeys = createClientTranslationKeys([
|
||||
'general:loading',
|
||||
'general:locale',
|
||||
'general:menu',
|
||||
'general:moreOptions',
|
||||
'general:moveDown',
|
||||
'general:moveUp',
|
||||
'general:next',
|
||||
|
||||
@@ -266,6 +266,7 @@ export const arTranslations: DefaultTranslationsObject = {
|
||||
locale: 'اللّغة',
|
||||
locales: 'اللّغات',
|
||||
menu: 'قائمة',
|
||||
moreOptions: 'خيارات أكثر',
|
||||
moveDown: 'التّحريك إلى الأسفل',
|
||||
moveUp: 'التّحريك إلى الأعلى',
|
||||
newPassword: 'كلمة مرور جديدة',
|
||||
|
||||
@@ -270,6 +270,7 @@ export const azTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Lokal',
|
||||
locales: 'Dillər',
|
||||
menu: 'Menyu',
|
||||
moreOptions: 'Daha çox seçimlər',
|
||||
moveDown: 'Aşağı hərəkət et',
|
||||
moveUp: 'Yuxarı hərəkət et',
|
||||
newPassword: 'Yeni şifrə',
|
||||
|
||||
@@ -269,6 +269,7 @@ export const bgTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Локализация',
|
||||
locales: 'Локализации',
|
||||
menu: 'Меню',
|
||||
moreOptions: 'Повече опции',
|
||||
moveDown: 'Надолу',
|
||||
moveUp: 'Нагоре',
|
||||
newPassword: 'Нова парола',
|
||||
|
||||
@@ -270,6 +270,7 @@ export const caTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Idioma',
|
||||
locales: 'Idiomes',
|
||||
menu: 'Menu',
|
||||
moreOptions: 'Més opcions',
|
||||
moveDown: 'Mou avall',
|
||||
moveUp: 'Move amunt',
|
||||
newPassword: 'Nova contrasenya',
|
||||
|
||||
@@ -268,6 +268,7 @@ export const csTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Místní verze',
|
||||
locales: 'Lokality',
|
||||
menu: 'Jídelní lístek',
|
||||
moreOptions: 'Více možností',
|
||||
moveDown: 'Posunout dolů',
|
||||
moveUp: 'Posunout nahoru',
|
||||
newPassword: 'Nové heslo',
|
||||
|
||||
@@ -268,6 +268,7 @@ export const daTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Lokalitet',
|
||||
locales: 'Lokaliteter',
|
||||
menu: 'Menu',
|
||||
moreOptions: 'Flere muligheder',
|
||||
moveDown: 'Ryk ned',
|
||||
moveUp: 'Ryk op',
|
||||
newPassword: 'Ny adgangskode',
|
||||
|
||||
@@ -274,6 +274,7 @@ export const deTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Sprache',
|
||||
locales: 'Sprachen',
|
||||
menu: 'Menü',
|
||||
moreOptions: 'Mehr Optionen',
|
||||
moveDown: 'Nach unten bewegen',
|
||||
moveUp: 'Nach oben bewegen',
|
||||
newPassword: 'Neues Passwort',
|
||||
|
||||
@@ -270,6 +270,7 @@ export const enTranslations = {
|
||||
locale: 'Locale',
|
||||
locales: 'Locales',
|
||||
menu: 'Menu',
|
||||
moreOptions: 'More options',
|
||||
moveDown: 'Move Down',
|
||||
moveUp: 'Move Up',
|
||||
newPassword: 'New Password',
|
||||
|
||||
@@ -274,6 +274,7 @@ export const esTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Regional',
|
||||
locales: 'Locales',
|
||||
menu: 'Menú',
|
||||
moreOptions: 'Más opciones',
|
||||
moveDown: 'Mover abajo',
|
||||
moveUp: 'Mover arriba',
|
||||
newPassword: 'Nueva contraseña',
|
||||
|
||||
@@ -267,6 +267,7 @@ export const etTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Keel',
|
||||
locales: 'Keeled',
|
||||
menu: 'Menüü',
|
||||
moreOptions: 'Rohkem valikuid',
|
||||
moveDown: 'Liiguta alla',
|
||||
moveUp: 'Liiguta üles',
|
||||
newPassword: 'Uus parool',
|
||||
|
||||
@@ -268,6 +268,7 @@ export const faTranslations: DefaultTranslationsObject = {
|
||||
locale: 'زبان',
|
||||
locales: 'زبانها',
|
||||
menu: 'منو',
|
||||
moreOptions: 'گزینههای بیشتر',
|
||||
moveDown: 'حرکت به پایین',
|
||||
moveUp: 'حرکت به بالا',
|
||||
newPassword: 'گذرواژه تازه',
|
||||
|
||||
@@ -277,6 +277,7 @@ export const frTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Paramètres régionaux',
|
||||
locales: 'Paramètres régionaux',
|
||||
menu: 'Menu',
|
||||
moreOptions: "Plus d'options",
|
||||
moveDown: 'Déplacer vers le bas',
|
||||
moveUp: 'Déplacer vers le haut',
|
||||
newPassword: 'Nouveau mot de passe',
|
||||
|
||||
@@ -264,6 +264,7 @@ export const heTranslations: DefaultTranslationsObject = {
|
||||
locale: 'שפה',
|
||||
locales: 'שפות',
|
||||
menu: 'תפריט',
|
||||
moreOptions: 'אפשרויות נוספות',
|
||||
moveDown: 'הזז למטה',
|
||||
moveUp: 'הזז למעלה',
|
||||
newPassword: 'סיסמה חדשה',
|
||||
|
||||
@@ -270,6 +270,7 @@ export const hrTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Jezik',
|
||||
locales: 'Prijevodi',
|
||||
menu: 'Izbornik',
|
||||
moreOptions: 'Više opcija',
|
||||
moveDown: 'Pomakni dolje',
|
||||
moveUp: 'Pomakni gore',
|
||||
newPassword: 'Nova lozinka',
|
||||
|
||||
@@ -272,6 +272,7 @@ export const huTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Nyelv',
|
||||
locales: 'Nyelvek',
|
||||
menu: 'Menü',
|
||||
moreOptions: 'Több opció',
|
||||
moveDown: 'Mozgatás lefelé',
|
||||
moveUp: 'Mozgatás felfelé',
|
||||
newPassword: 'Új jelszó',
|
||||
|
||||
@@ -273,6 +273,7 @@ export const itTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Locale',
|
||||
locales: 'Localizzazioni',
|
||||
menu: 'Menù',
|
||||
moreOptions: 'Più opzioni',
|
||||
moveDown: 'Sposta sotto',
|
||||
moveUp: 'Sposta sopra',
|
||||
newPassword: 'Nuova Password',
|
||||
|
||||
@@ -270,6 +270,7 @@ export const jaTranslations: DefaultTranslationsObject = {
|
||||
locale: 'ロケール',
|
||||
locales: 'ロケール',
|
||||
menu: 'メニュー',
|
||||
moreOptions: 'より多くのオプション',
|
||||
moveDown: '下へ移動',
|
||||
moveUp: '上へ移動',
|
||||
newPassword: '新しいパスワード',
|
||||
|
||||
@@ -268,6 +268,7 @@ export const koTranslations: DefaultTranslationsObject = {
|
||||
locale: 'locale',
|
||||
locales: 'locale',
|
||||
menu: '메뉴',
|
||||
moreOptions: '더 많은 옵션',
|
||||
moveDown: '아래로 이동',
|
||||
moveUp: '위로 이동',
|
||||
newPassword: '새 비밀번호',
|
||||
|
||||
@@ -272,6 +272,7 @@ export const myTranslations: DefaultTranslationsObject = {
|
||||
locale: 'ဒေသ',
|
||||
locales: 'Locales',
|
||||
menu: 'မီနူး',
|
||||
moreOptions: 'ပိုမိုများစွာရွေးချယ်ခွင့်',
|
||||
moveDown: 'Move Down',
|
||||
moveUp: 'Move Up',
|
||||
newPassword: 'စကားဝှက် အသစ်',
|
||||
|
||||
@@ -270,6 +270,7 @@ export const nbTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Lokalitet',
|
||||
locales: 'Språk',
|
||||
menu: 'Meny',
|
||||
moreOptions: 'Flere alternativer',
|
||||
moveDown: 'Flytt ned',
|
||||
moveUp: 'Flytt opp',
|
||||
newPassword: 'Nytt passord',
|
||||
|
||||
@@ -273,6 +273,7 @@ export const nlTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Taal',
|
||||
locales: 'Landinstellingen',
|
||||
menu: 'Menu',
|
||||
moreOptions: 'Meer opties',
|
||||
moveDown: 'Verplaats naar beneden',
|
||||
moveUp: 'Verplaats naar boven',
|
||||
newPassword: 'Nieuw wachtwoord',
|
||||
|
||||
@@ -270,6 +270,7 @@ export const plTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Ustawienia regionalne',
|
||||
locales: 'Ustawienia regionalne',
|
||||
menu: 'Menu',
|
||||
moreOptions: 'Więcej opcji',
|
||||
moveDown: 'Przesuń niżej',
|
||||
moveUp: 'Przesuń wyżej',
|
||||
newPassword: 'Nowe hasło',
|
||||
|
||||
@@ -270,6 +270,7 @@ export const ptTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Local',
|
||||
locales: 'Localizações',
|
||||
menu: 'Cardápio',
|
||||
moreOptions: 'Mais opções',
|
||||
moveDown: 'Mover para Baixo',
|
||||
moveUp: 'Mover para Cima',
|
||||
newPassword: 'Nova Senha',
|
||||
|
||||
@@ -274,6 +274,7 @@ export const roTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Localitate',
|
||||
locales: 'Localuri',
|
||||
menu: 'Meniu',
|
||||
moreOptions: 'Mai multe opțiuni',
|
||||
moveDown: 'Mutați în jos',
|
||||
moveUp: 'Mutați în sus',
|
||||
newPassword: 'Parolă nouă',
|
||||
|
||||
@@ -270,6 +270,7 @@ export const rsTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Језик',
|
||||
locales: 'Преводи',
|
||||
menu: 'Мени',
|
||||
moreOptions: 'Više opcija',
|
||||
moveDown: 'Помери доле',
|
||||
moveUp: 'Помери горе',
|
||||
newPassword: 'Нова лозинка',
|
||||
|
||||
@@ -270,6 +270,7 @@ export const rsLatinTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Jezik',
|
||||
locales: 'Prevodi',
|
||||
menu: 'Meni',
|
||||
moreOptions: 'Više opcija',
|
||||
moveDown: 'Pomeri dole',
|
||||
moveUp: 'Pomeri gore',
|
||||
newPassword: 'Nova lozinka',
|
||||
|
||||
@@ -272,6 +272,7 @@ export const ruTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Локаль',
|
||||
locales: 'Локали',
|
||||
menu: 'Меню',
|
||||
moreOptions: 'Больше вариантов',
|
||||
moveDown: 'Сдвинуть вниз',
|
||||
moveUp: 'Сдвинуть вверх',
|
||||
newPassword: 'Новый пароль',
|
||||
|
||||
@@ -271,6 +271,7 @@ export const skTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Jazyk',
|
||||
locales: 'Jazyky',
|
||||
menu: 'Menu',
|
||||
moreOptions: 'Viac možností',
|
||||
moveDown: 'Presunúť dolu',
|
||||
moveUp: 'Presunúť hore',
|
||||
newPassword: 'Nové heslo',
|
||||
|
||||
@@ -269,6 +269,7 @@ export const slTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Jezik',
|
||||
locales: 'Jeziki',
|
||||
menu: 'Meni',
|
||||
moreOptions: 'Več možnosti',
|
||||
moveDown: 'Premakni dol',
|
||||
moveUp: 'Premakni gor',
|
||||
newPassword: 'Novo geslo',
|
||||
|
||||
@@ -270,6 +270,7 @@ export const svTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Lokal',
|
||||
locales: 'Språk',
|
||||
menu: 'Meny',
|
||||
moreOptions: 'Fler alternativ',
|
||||
moveDown: 'Flytta Ner',
|
||||
moveUp: 'Flytta Upp',
|
||||
newPassword: 'Nytt Lösenord',
|
||||
|
||||
@@ -266,6 +266,7 @@ export const thTranslations: DefaultTranslationsObject = {
|
||||
locale: 'ตำแหน่งที่ตั้ง',
|
||||
locales: 'ภาษา',
|
||||
menu: 'เมนู',
|
||||
moreOptions: 'ตัวเลือกเพิ่มเติม',
|
||||
moveDown: 'ขยับขึ้น',
|
||||
moveUp: 'ขยับลง',
|
||||
newPassword: 'รหัสผ่านใหม่',
|
||||
|
||||
@@ -273,6 +273,7 @@ export const trTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Yerel ayar',
|
||||
locales: 'Diller',
|
||||
menu: 'Menü',
|
||||
moreOptions: 'Daha fazla seçenek',
|
||||
moveDown: 'Aşağı taşı',
|
||||
moveUp: 'Yukarı taşı',
|
||||
newPassword: 'Yeni parola',
|
||||
|
||||
@@ -269,6 +269,7 @@ export const ukTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Локаль',
|
||||
locales: 'Локалі',
|
||||
menu: 'Меню',
|
||||
moreOptions: 'Більше варіантів',
|
||||
moveDown: 'Перемістити нижче',
|
||||
moveUp: 'Перемістити вище',
|
||||
newPassword: 'Новий пароль',
|
||||
|
||||
@@ -269,6 +269,7 @@ export const viTranslations: DefaultTranslationsObject = {
|
||||
locale: 'Ngôn ngữ',
|
||||
locales: 'Khu vực',
|
||||
menu: 'Thực đơn',
|
||||
moreOptions: 'Nhiều lựa chọn hơn',
|
||||
moveDown: 'Di chuyển xuống',
|
||||
moveUp: 'Di chuyển lên',
|
||||
newPassword: 'Mật khảu mới',
|
||||
|
||||
@@ -260,6 +260,7 @@ export const zhTranslations: DefaultTranslationsObject = {
|
||||
locale: '语言环境',
|
||||
locales: '语言环境',
|
||||
menu: '菜单',
|
||||
moreOptions: '更多选项',
|
||||
moveDown: '向下移动',
|
||||
moveUp: '向上移动',
|
||||
newPassword: '新密码',
|
||||
|
||||
@@ -260,6 +260,7 @@ export const zhTwTranslations: DefaultTranslationsObject = {
|
||||
locale: '語言環境',
|
||||
locales: '語言環境',
|
||||
menu: '菜單',
|
||||
moreOptions: '更多選項',
|
||||
moveDown: '向下移動',
|
||||
moveUp: '向上移動',
|
||||
newPassword: '新密碼',
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
&__custom-control {
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
&__buttons-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -5,8 +5,10 @@ import { useWindowInfo } from '@faceless-ui/window-info'
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import React, { Fragment, useEffect, useRef, useState } from 'react'
|
||||
|
||||
import { Popup, PopupList } from '../../elements/Popup/index.js'
|
||||
import { useUseTitleField } from '../../hooks/useUseAsTitle.js'
|
||||
import { ChevronIcon } from '../../icons/Chevron/index.js'
|
||||
import { Dots } from '../../icons/Dots/index.js'
|
||||
import { SearchIcon } from '../../icons/Search/index.js'
|
||||
import { useListQuery } from '../../providers/ListQuery/index.js'
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
@@ -36,6 +38,7 @@ export type ListControlsProps = {
|
||||
readonly handleSearchChange?: (search: string) => void
|
||||
readonly handleSortChange?: (sort: string) => void
|
||||
readonly handleWhereChange?: (where: Where) => void
|
||||
readonly listMenuItems?: React.ReactNode[]
|
||||
readonly renderedFilters?: Map<string, React.ReactNode>
|
||||
readonly resolvedFilterOptions?: Map<string, ResolvedFilterOptions>
|
||||
}
|
||||
@@ -54,10 +57,10 @@ export const ListControls: React.FC<ListControlsProps> = (props) => {
|
||||
disableBulkEdit,
|
||||
enableColumns = true,
|
||||
enableSort = false,
|
||||
listMenuItems,
|
||||
renderedFilters,
|
||||
resolvedFilterOptions,
|
||||
} = props
|
||||
|
||||
const { handleSearchChange, query } = useListQuery()
|
||||
const titleField = useUseTitleField(collectionConfig)
|
||||
const { i18n, t } = useTranslation()
|
||||
@@ -194,6 +197,17 @@ export const ListControls: React.FC<ListControlsProps> = (props) => {
|
||||
{t('general:sort')}
|
||||
</Pill>
|
||||
)}
|
||||
{listMenuItems && (
|
||||
<Popup
|
||||
button={<Dots ariaLabel={t('general:moreOptions')} />}
|
||||
className={`${baseClass}__popup`}
|
||||
horizontalAlign="right"
|
||||
size="large"
|
||||
verticalAlign="bottom"
|
||||
>
|
||||
<PopupList.ButtonGroup>{listMenuItems.map((item) => item)}</PopupList.ButtonGroup>
|
||||
</Popup>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
27
packages/ui/src/icons/Dots/index.scss
Normal file
27
packages/ui/src/icons/Dots/index.scss
Normal file
@@ -0,0 +1,27 @@
|
||||
@import '../../scss/styles';
|
||||
|
||||
@layer payload-default {
|
||||
.dots {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
background-color: var(--theme-elevation-150);
|
||||
border-radius: $style-radius-m;
|
||||
height: calc(var(--base) * 1.2);
|
||||
width: calc(var(--base) * 1.2);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--theme-elevation-100);
|
||||
}
|
||||
|
||||
> div {
|
||||
width: 2.5px;
|
||||
height: 2.5px;
|
||||
border-radius: 100%;
|
||||
background-color: currentColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
17
packages/ui/src/icons/Dots/index.tsx
Normal file
17
packages/ui/src/icons/Dots/index.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import React from 'react'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
export const Dots: React.FC<{ ariaLabel?: string; className?: string }> = ({
|
||||
ariaLabel,
|
||||
className,
|
||||
}) => (
|
||||
<div
|
||||
aria-label={ariaLabel}
|
||||
className={[className && className, 'dots'].filter(Boolean).join(' ')}
|
||||
>
|
||||
<div />
|
||||
<div />
|
||||
<div />
|
||||
</div>
|
||||
)
|
||||
@@ -52,6 +52,7 @@ export function DefaultListView(props: ListViewClientProps) {
|
||||
disableBulkEdit,
|
||||
enableRowSelections,
|
||||
hasCreatePermission,
|
||||
listMenuItems,
|
||||
listPreferences,
|
||||
newDocumentURL,
|
||||
preferenceKey,
|
||||
@@ -195,6 +196,7 @@ export function DefaultListView(props: ListViewClientProps) {
|
||||
collectionSlug={collectionSlug}
|
||||
disableBulkDelete={disableBulkDelete}
|
||||
disableBulkEdit={disableBulkEdit}
|
||||
listMenuItems={listMenuItems}
|
||||
renderedFilters={renderedFilters}
|
||||
resolvedFilterOptions={resolvedFilterOptions}
|
||||
/>
|
||||
|
||||
@@ -33,6 +33,26 @@ export const Posts: CollectionConfig = {
|
||||
},
|
||||
},
|
||||
],
|
||||
listMenuItems: [
|
||||
{
|
||||
path: '/components/Banner/index.js#Banner',
|
||||
clientProps: {
|
||||
message: 'listMenuItems',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/components/Banner/index.js#Banner',
|
||||
clientProps: {
|
||||
message: 'Many of them',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/components/Banner/index.js#Banner',
|
||||
clientProps: {
|
||||
message: 'Ok last one',
|
||||
},
|
||||
},
|
||||
],
|
||||
afterList: [
|
||||
{
|
||||
path: '/components/Banner/index.js#Banner',
|
||||
|
||||
@@ -198,6 +198,19 @@ describe('List View', () => {
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
test('should render custom listMenuItems component', async () => {
|
||||
await page.goto(postsUrl.list)
|
||||
const kebabMenu = page.locator('.list-controls__popup')
|
||||
await expect(kebabMenu).toBeVisible()
|
||||
await kebabMenu.click()
|
||||
|
||||
await expect(
|
||||
page.locator('.popup-button-list').locator('div', {
|
||||
hasText: 'listMenuItems',
|
||||
}),
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
test('should render custom afterListTable component', async () => {
|
||||
await page.goto(postsUrl.list)
|
||||
await expect(
|
||||
|
||||
Reference in New Issue
Block a user