Skip to content

Commit

Permalink
fix: overrides entity visibility within drawers (#9546)
Browse files Browse the repository at this point in the history
When using the `admin.hidden: true` property on a collection, it
rightfully removes all navigation and routing for that particular
collection. However, this also affects the expected behavior of hidden
entities when they are rendered within a drawer, such as the document
drawer or list drawer. For example, when creating a new _admin.hidden_
document through the relationship or join field, the drawer should still
render the view, despite the underlying route for that view being
disabled. This change was a result of the introduction of on-demand
server components in #8364, where we now make a server roundtrip to
render the view in its entirety, which include the logic that redirects
these hidden entities.

Now, we pass a new `overrideEntityVisibility` argument through the
server function that, when true, skips this step. This way documents can
continue to respect `admin.hidden` while also having the ability to
override on a case-by-case basis throughout the UI.
  • Loading branch information
jacobsfletch authored Nov 26, 2024
1 parent defa13e commit 5d18a52
Show file tree
Hide file tree
Showing 21 changed files with 176 additions and 24 deletions.
3 changes: 3 additions & 0 deletions packages/next/src/views/Document/handleServerFunction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const renderDocumentHandler = async (args: {
drawerSlug?: string
initialData?: Data
initialState?: FormState
overrideEntityVisibility?: boolean
redirectAfterDelete: boolean
redirectAfterDuplicate: boolean
req: PayloadRequest
Expand All @@ -29,6 +30,7 @@ export const renderDocumentHandler = async (args: {
docID,
drawerSlug,
initialData,
overrideEntityVisibility,
redirectAfterDelete,
redirectAfterDuplicate,
req,
Expand Down Expand Up @@ -148,6 +150,7 @@ export const renderDocumentHandler = async (args: {
translations: undefined, // TODO
visibleEntities,
},
overrideEntityVisibility,
params: {
segments: ['collections', collectionSlug, docID],
},
Expand Down
10 changes: 8 additions & 2 deletions packages/next/src/views/Document/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,14 @@ export const renderDocument = async ({
importMap,
initialData,
initPageResult,
overrideEntityVisibility,
params,
redirectAfterDelete,
redirectAfterDuplicate,
searchParams,
}: AdminViewProps): Promise<{
}: {
overrideEntityVisibility?: boolean
} & AdminViewProps): Promise<{
data: Data
Document: React.ReactNode
}> => {
Expand Down Expand Up @@ -168,7 +171,10 @@ export const renderDocument = async ({
}

if (collectionConfig) {
if (!visibleEntities?.collections?.find((visibleSlug) => visibleSlug === collectionSlug)) {
if (
!visibleEntities?.collections?.find((visibleSlug) => visibleSlug === collectionSlug) &&
!overrideEntityVisibility
) {
throw new Error('not-found')
}

Expand Down
3 changes: 3 additions & 0 deletions packages/next/src/views/List/handleServerFunction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const renderListHandler = async (args: {
documentDrawerSlug: string
drawerSlug?: string
enableRowSelections: boolean
overrideEntityVisibility?: boolean
query: ListQuery
redirectAfterDelete: boolean
redirectAfterDuplicate: boolean
Expand All @@ -32,6 +33,7 @@ export const renderListHandler = async (args: {
disableBulkEdit,
drawerSlug,
enableRowSelections,
overrideEntityVisibility,
query,
redirectAfterDelete,
redirectAfterDuplicate,
Expand Down Expand Up @@ -149,6 +151,7 @@ export const renderListHandler = async (args: {
translations: undefined, // TODO
visibleEntities,
},
overrideEntityVisibility,
params: {
segments: ['collections', collectionSlug],
},
Expand Down
4 changes: 3 additions & 1 deletion packages/next/src/views/List/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type ListViewArgs = {
disableBulkDelete?: boolean
disableBulkEdit?: boolean
enableRowSelections: boolean
overrideEntityVisibility?: boolean
query: ListQuery
} & AdminViewProps

Expand All @@ -39,6 +40,7 @@ export const renderListView = async (
drawerSlug,
enableRowSelections,
initPageResult,
overrideEntityVisibility,
params,
query: queryFromArgs,
searchParams,
Expand Down Expand Up @@ -111,7 +113,7 @@ export const renderListView = async (
} = config

if (collectionConfig) {
if (!visibleEntities.collections.includes(collectionSlug)) {
if (!visibleEntities.collections.includes(collectionSlug) && !overrideEntityVisibility) {
throw new Error('not-found')
}

Expand Down
2 changes: 1 addition & 1 deletion packages/payload/src/admin/views/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { Locale, MetaConfig, PayloadComponent, ServerProps } from '../../co
import type { SanitizedGlobalConfig } from '../../globals/config/types.js'
import type { PayloadRequest } from '../../types/index.js'
import type { LanguageOptions } from '../LanguageOptions.js'
import type { Data, DocumentSlots, PayloadServerAction } from '../types.js'
import type { Data, DocumentSlots } from '../types.js'

export type AdminViewConfig = {
Component: AdminViewComponent
Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/elements/AddNewRelation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ export const AddNewRelation: React.FC<Props> = ({
const { permissions } = useAuth()
const [show, setShow] = useState(false)
const [selectedCollection, setSelectedCollection] = useState<string>()

const relatedToMany = relatedCollections.length > 1

const [collectionConfig, setCollectionConfig] = useState<ClientCollectionConfig>(() =>
!relatedToMany ? relatedCollections[0] : undefined,
)

const [popupOpen, setPopupOpen] = useState(false)
const { i18n, t } = useTranslation()
const [showTooltip, setShowTooltip] = useState(false)
Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/elements/DocumentDrawer/DrawerContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const DocumentDrawerContent: React.FC<DocumentDrawerProps> = ({
onDelete: onDeleteFromProps,
onDuplicate: onDuplicateFromProps,
onSave: onSaveFromProps,
overrideEntityVisibility = true,
redirectAfterDelete,
redirectAfterDuplicate,
}) => {
Expand Down Expand Up @@ -64,6 +65,7 @@ export const DocumentDrawerContent: React.FC<DocumentDrawerProps> = ({
docID,
drawerSlug,
initialData,
overrideEntityVisibility,
redirectAfterDelete: redirectAfterDelete !== undefined ? redirectAfterDelete : false,
redirectAfterDuplicate:
redirectAfterDuplicate !== undefined ? redirectAfterDuplicate : false,
Expand Down Expand Up @@ -92,6 +94,7 @@ export const DocumentDrawerContent: React.FC<DocumentDrawerProps> = ({
redirectAfterDuplicate,
renderDocument,
closeModal,
overrideEntityVisibility,
t,
],
)
Expand Down
9 changes: 7 additions & 2 deletions packages/ui/src/elements/DocumentDrawer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ export const DocumentDrawer: React.FC<DocumentDrawerProps> = (props) => {
)
}

export const useDocumentDrawer: UseDocumentDrawer = ({ id, collectionSlug }) => {
export const useDocumentDrawer: UseDocumentDrawer = ({
id,
collectionSlug,
overrideEntityVisibility,
}) => {
const editDepth = useEditDepth()
const uuid = useId()
const { closeModal, modalState, openModal, toggleModal } = useModal()
Expand Down Expand Up @@ -101,9 +105,10 @@ export const useDocumentDrawer: UseDocumentDrawer = ({ id, collectionSlug }) =>
drawerSlug={drawerSlug}
id={id}
key={drawerSlug}
overrideEntityVisibility={overrideEntityVisibility}
/>
)
}, [id, drawerSlug, collectionSlug])
}, [id, drawerSlug, collectionSlug, overrideEntityVisibility])

const MemoizedDrawerToggler = useMemo(() => {
return (props) => (
Expand Down
7 changes: 6 additions & 1 deletion packages/ui/src/elements/DocumentDrawer/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export type DocumentDrawerProps = {
readonly id?: null | number | string
readonly initialData?: Data
readonly initialState?: FormState
readonly overrideEntityVisibility?: boolean
readonly redirectAfterDelete?: boolean
readonly redirectAfterDuplicate?: boolean
} & Pick<DocumentDrawerContextProps, 'onDelete' | 'onDuplicate' | 'onSave'> &
Expand All @@ -28,7 +29,11 @@ export type DocumentTogglerProps = {
readonly onClick?: () => void
} & Readonly<HTMLAttributes<HTMLButtonElement>>

export type UseDocumentDrawer = (args: { collectionSlug: string; id?: number | string }) => [
export type UseDocumentDrawer = (args: {
collectionSlug: string
id?: number | string
overrideEntityVisibility?: boolean
}) => [
React.FC<Omit<DocumentDrawerProps, 'collectionSlug' | 'id'>>, // drawer
React.FC<Omit<DocumentTogglerProps, 'collectionSlug' | 'id'>>, // toggler
{
Expand Down
12 changes: 11 additions & 1 deletion packages/ui/src/elements/ListDrawer/DrawerContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const ListDrawerContent: React.FC<ListDrawerProps> = ({
filterOptions,
onBulkSelect,
onSelect,
overrideEntityVisibility = true,
selectedCollection: selectedCollectionFromProps,
}) => {
const { closeModal, isModalOpen } = useModal()
Expand Down Expand Up @@ -86,6 +87,7 @@ export const ListDrawerContent: React.FC<ListDrawerProps> = ({
disableBulkEdit: true,
drawerSlug,
enableRowSelections,
overrideEntityVisibility,
query: newQuery,
},
})) as { List: React.ReactNode }
Expand All @@ -100,7 +102,15 @@ export const ListDrawerContent: React.FC<ListDrawerProps> = ({
}
}
},
[serverFunction, closeModal, drawerSlug, isOpen, enableRowSelections, filterOptions],
[
serverFunction,
closeModal,
drawerSlug,
isOpen,
enableRowSelections,
filterOptions,
overrideEntityVisibility,
],
)

useEffect(() => {
Expand Down
2 changes: 2 additions & 0 deletions packages/ui/src/elements/ListDrawer/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export type ListDrawerProps = {
readonly drawerSlug?: string
readonly enableRowSelections?: boolean
readonly filterOptions?: FilterOptionsResult
readonly overrideEntityVisibility?: boolean
readonly selectedCollection?: string
} & ListDrawerContextProps

Expand All @@ -23,6 +24,7 @@ export type ListTogglerProps = {
export type UseListDrawer = (args: {
collectionSlugs?: SanitizedCollectionConfig['slug'][]
filterOptions?: FilterOptionsResult
overrideEntityVisibility?: boolean
selectedCollection?: SanitizedCollectionConfig['slug']
uploads?: boolean // finds all collections with upload: true
}) => [
Expand Down
6 changes: 5 additions & 1 deletion packages/ui/src/elements/RelationshipTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,11 @@ export const RelationshipTable: React.FC<RelationshipTableComponentProps> = (pro
<div className={`${baseClass}__header`}>
{Label}
<div className={`${baseClass}__actions`}>
{canCreate && <DocumentDrawerToggler>{i18n.t('fields:addNew')}</DocumentDrawerToggler>}
{canCreate && (
<DocumentDrawerToggler className={`${baseClass}__add-new`}>
{i18n.t('fields:addNew')}
</DocumentDrawerToggler>
)}
<Pill
aria-controls={`${baseClass}-columns`}
aria-expanded={openColumnSelector}
Expand Down
5 changes: 4 additions & 1 deletion packages/ui/src/fields/Join/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ const JoinFieldComponent: JoinFieldClientComponent = (props) => {
}, [docID, on, field.where])

return (
<div className={[fieldBaseClass, 'join'].filter(Boolean).join(' ')}>
<div
className={[fieldBaseClass, 'join'].filter(Boolean).join(' ')}
id={`field-${path?.replace(/\./g, '__')}`}
>
{BeforeInput}
<RelationshipTable
allowCreate={typeof docID !== 'undefined' && allowCreate}
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/providers/ServerFunctions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type RenderDocument = (args: {
docID?: number | string
drawerSlug?: string
initialData?: Data
overrideEntityVisibility?: boolean
redirectAfterDelete?: boolean
redirectAfterDuplicate?: boolean
signal?: AbortSignal
Expand Down
8 changes: 7 additions & 1 deletion test/joins/collections/Categories.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { CollectionConfig } from 'payload'

import { categoriesSlug, postsSlug } from '../shared.js'
import { categoriesSlug, hiddenPostsSlug, postsSlug } from '../shared.js'
import { singularSlug } from './Singular.js'

export const Categories: CollectionConfig = {
Expand Down Expand Up @@ -65,6 +65,12 @@ export const Categories: CollectionConfig = {
collection: postsSlug,
on: 'categoriesLocalized',
},
{
name: 'hiddenPosts',
type: 'join',
collection: hiddenPostsSlug,
on: 'category',
},
{
name: 'group',
type: 'group',
Expand Down
23 changes: 23 additions & 0 deletions test/joins/collections/HiddenPosts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { CollectionConfig } from 'payload'

import { categoriesSlug, hiddenPostsSlug } from '../shared.js'

export const HiddenPosts: CollectionConfig = {
slug: hiddenPostsSlug,
admin: {
useAsTitle: 'title',
hidden: true,
defaultColumns: ['title', 'category'],
},
fields: [
{
name: 'title',
type: 'text',
},
{
name: 'category',
type: 'relationship',
relationTo: categoriesSlug,
},
],
}
2 changes: 2 additions & 0 deletions test/joins/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import path from 'path'
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
import { Categories } from './collections/Categories.js'
import { CategoriesVersions } from './collections/CategoriesVersions.js'
import { HiddenPosts } from './collections/HiddenPosts.js'
import { Posts } from './collections/Posts.js'
import { Singular } from './collections/Singular.js'
import { Uploads } from './collections/Uploads.js'
Expand All @@ -24,6 +25,7 @@ export default buildConfigWithDefaults({
collections: [
Posts,
Categories,
HiddenPosts,
Uploads,
Versions,
CategoriesVersions,
Expand Down
Loading

0 comments on commit 5d18a52

Please sign in to comment.