diff --git a/packages/ui/src/elements/ListDrawer/DrawerContent.tsx b/packages/ui/src/elements/ListDrawer/DrawerContent.tsx index d08f437006..9b33597dbf 100644 --- a/packages/ui/src/elements/ListDrawer/DrawerContent.tsx +++ b/packages/ui/src/elements/ListDrawer/DrawerContent.tsx @@ -87,6 +87,7 @@ export const ListDrawerContent: React.FC = ({ const { List: ViewResult } = (await serverFunction({ name: 'render-list', args: { + allowCreate, collectionSlug: slug, disableBulkDelete: true, disableBulkEdit: true, @@ -160,6 +161,7 @@ export const ListDrawerContent: React.FC = ({ return ( [1] readonly drawerSlug?: string diff --git a/packages/ui/src/views/List/index.tsx b/packages/ui/src/views/List/index.tsx index 7b43336d50..07dbf69a49 100644 --- a/packages/ui/src/views/List/index.tsx +++ b/packages/ui/src/views/List/index.tsx @@ -51,7 +51,7 @@ export function DefaultListView(props: ListViewClientProps) { disableBulkDelete, disableBulkEdit, enableRowSelections, - hasCreatePermission, + hasCreatePermission: hasCreatePermissionFromProps, listMenuItems, listPreferences, newDocumentURL, @@ -63,7 +63,17 @@ export function DefaultListView(props: ListViewClientProps) { const [Table, setTable] = useState(InitialTable) - const { createNewDrawerSlug, drawerSlug: listDrawerSlug, onBulkSelect } = useListDrawerContext() + const { + allowCreate, + createNewDrawerSlug, + drawerSlug: listDrawerSlug, + onBulkSelect, + } = useListDrawerContext() + + const hasCreatePermission = + allowCreate !== undefined + ? allowCreate && hasCreatePermissionFromProps + : hasCreatePermissionFromProps useEffect(() => { if (InitialTable) { @@ -145,7 +155,6 @@ export function DefaultListView(props: ListViewClientProps) { ]) } }, [setStepNav, labels, drawerDepth]) - return ( [0] + +export const SelectPostsButton = () => { + const listDrawerArgs = useMemo( + () => ({ + collectionSlugs: ['with-list-drawer'], + }), + [], + ) + const [ListDrawer, _, { toggleDrawer }] = useListDrawer(listDrawerArgs) + + return ( + <> + + + + ) +} diff --git a/test/admin/config.ts b/test/admin/config.ts index 4f5ede8e4b..b17dc86f4c 100644 --- a/test/admin/config.ts +++ b/test/admin/config.ts @@ -14,6 +14,7 @@ import { CollectionGroup1B } from './collections/Group1B.js' import { CollectionGroup2A } from './collections/Group2A.js' import { CollectionGroup2B } from './collections/Group2B.js' import { CollectionHidden } from './collections/Hidden.js' +import { ListDrawer } from './collections/ListDrawer.js' import { CollectionNoApiView } from './collections/NoApiView.js' import { CollectionNotInView } from './collections/NotInView.js' import { Posts } from './collections/Posts.js' @@ -39,7 +40,6 @@ import { protectedCustomNestedViewPath, publicCustomViewPath, } from './shared.js' - export default buildConfigWithDefaults({ admin: { importMap: { @@ -157,6 +157,7 @@ export default buildConfigWithDefaults({ DisableDuplicate, BaseListFilter, with300Documents, + ListDrawer, ], globals: [ GlobalHidden, diff --git a/test/admin/e2e/list-view/e2e.spec.ts b/test/admin/e2e/list-view/e2e.spec.ts index 90c77f9c2b..30c6490b78 100644 --- a/test/admin/e2e/list-view/e2e.spec.ts +++ b/test/admin/e2e/list-view/e2e.spec.ts @@ -19,6 +19,7 @@ import { customAdminRoutes } from '../../shared.js' import { customViews1CollectionSlug, geoCollectionSlug, + listDrawerSlug, postsCollectionSlug, with300DocumentsSlug, } from '../../slugs.js' @@ -56,6 +57,7 @@ describe('List View', () => { let baseListFiltersUrl: AdminUrlUtil let customViewsUrl: AdminUrlUtil let with300DocumentsUrl: AdminUrlUtil + let withListViewUrl: AdminUrlUtil let serverURL: string let adminRoutes: ReturnType @@ -76,6 +78,7 @@ describe('List View', () => { with300DocumentsUrl = new AdminUrlUtil(serverURL, with300DocumentsSlug) baseListFiltersUrl = new AdminUrlUtil(serverURL, 'base-list-filters') customViewsUrl = new AdminUrlUtil(serverURL, customViews1CollectionSlug) + withListViewUrl = new AdminUrlUtil(serverURL, listDrawerSlug) const context = await browser.newContext() page = await context.newPage() @@ -156,6 +159,20 @@ describe('List View', () => { `${adminRoutes.routes?.admin}/collections/posts/${id}`, ) }) + + test('should hide create new button when allowCreate is false', async () => { + await page.goto(withListViewUrl.list) + + const drawerButton = page.locator('button', { hasText: 'Select Posts' }) + await expect(drawerButton).toBeVisible() + await drawerButton.click() + + const drawer = page.locator('.drawer__content') + await expect(drawer).toBeVisible() + + const createButton = page.locator('button', { hasText: 'Create New' }) + await expect(createButton).toBeHidden() + }) }) describe('list view custom components', () => { diff --git a/test/admin/payload-types.ts b/test/admin/payload-types.ts index 5b56f309cc..08f3e7a75e 100644 --- a/test/admin/payload-types.ts +++ b/test/admin/payload-types.ts @@ -83,6 +83,7 @@ export interface Config { 'disable-duplicate': DisableDuplicate; 'base-list-filters': BaseListFilter; with300documents: With300Document; + 'with-list-drawer': WithListDrawer; 'payload-locked-documents': PayloadLockedDocument; 'payload-preferences': PayloadPreference; 'payload-migrations': PayloadMigration; @@ -106,6 +107,7 @@ export interface Config { 'disable-duplicate': DisableDuplicateSelect | DisableDuplicateSelect; 'base-list-filters': BaseListFiltersSelect | BaseListFiltersSelect; with300documents: With300DocumentsSelect | With300DocumentsSelect; + 'with-list-drawer': WithListDrawerSelect | WithListDrawerSelect; 'payload-locked-documents': PayloadLockedDocumentsSelect | PayloadLockedDocumentsSelect; 'payload-preferences': PayloadPreferencesSelect | PayloadPreferencesSelect; 'payload-migrations': PayloadMigrationsSelect | PayloadMigrationsSelect; @@ -445,6 +447,18 @@ export interface With300Document { updatedAt: string; createdAt: string; } +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "with-list-drawer". + */ +export interface WithListDrawer { + id: string; + title?: string | null; + description?: string | null; + number?: number | null; + updatedAt: string; + createdAt: string; +} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "payload-locked-documents". @@ -519,6 +533,10 @@ export interface PayloadLockedDocument { | ({ relationTo: 'with300documents'; value: string | With300Document; + } | null) + | ({ + relationTo: 'with-list-drawer'; + value: string | WithListDrawer; } | null); globalSlug?: string | null; user: { @@ -822,6 +840,17 @@ export interface With300DocumentsSelect { updatedAt?: T; createdAt?: T; } +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "with-list-drawer_select". + */ +export interface WithListDrawerSelect { + title?: T; + description?: T; + number?: T; + updatedAt?: T; + createdAt?: T; +} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "payload-locked-documents_select". diff --git a/test/admin/slugs.ts b/test/admin/slugs.ts index 2370222b23..5bd73c26ce 100644 --- a/test/admin/slugs.ts +++ b/test/admin/slugs.ts @@ -13,6 +13,8 @@ export const noApiViewCollectionSlug = 'collection-no-api-view' export const disableDuplicateSlug = 'disable-duplicate' export const uploadCollectionSlug = 'uploads' export const customFieldsSlug = 'custom-fields' + +export const listDrawerSlug = 'with-list-drawer' export const collectionSlugs = [ usersCollectionSlug, customViews1CollectionSlug, @@ -27,6 +29,7 @@ export const collectionSlugs = [ noApiViewCollectionSlug, customFieldsSlug, disableDuplicateSlug, + listDrawerSlug, ] export const customGlobalViews1GlobalSlug = 'custom-global-views-one'