fix: overrides entity visibility within drawers (#9546)
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.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -25,6 +25,7 @@ export const DocumentDrawerContent: React.FC<DocumentDrawerProps> = ({
|
||||
onDelete: onDeleteFromProps,
|
||||
onDuplicate: onDuplicateFromProps,
|
||||
onSave: onSaveFromProps,
|
||||
overrideEntityVisibility = true,
|
||||
redirectAfterDelete,
|
||||
redirectAfterDuplicate,
|
||||
}) => {
|
||||
@@ -64,6 +65,7 @@ export const DocumentDrawerContent: React.FC<DocumentDrawerProps> = ({
|
||||
docID,
|
||||
drawerSlug,
|
||||
initialData,
|
||||
overrideEntityVisibility,
|
||||
redirectAfterDelete: redirectAfterDelete !== undefined ? redirectAfterDelete : false,
|
||||
redirectAfterDuplicate:
|
||||
redirectAfterDuplicate !== undefined ? redirectAfterDuplicate : false,
|
||||
@@ -92,6 +94,7 @@ export const DocumentDrawerContent: React.FC<DocumentDrawerProps> = ({
|
||||
redirectAfterDuplicate,
|
||||
renderDocument,
|
||||
closeModal,
|
||||
overrideEntityVisibility,
|
||||
t,
|
||||
],
|
||||
)
|
||||
|
||||
@@ -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()
|
||||
@@ -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) => (
|
||||
|
||||
@@ -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'> &
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@ export const ListDrawerContent: React.FC<ListDrawerProps> = ({
|
||||
filterOptions,
|
||||
onBulkSelect,
|
||||
onSelect,
|
||||
overrideEntityVisibility = true,
|
||||
selectedCollection: selectedCollectionFromProps,
|
||||
}) => {
|
||||
const { closeModal, isModalOpen } = useModal()
|
||||
@@ -86,6 +87,7 @@ export const ListDrawerContent: React.FC<ListDrawerProps> = ({
|
||||
disableBulkEdit: true,
|
||||
drawerSlug,
|
||||
enableRowSelections,
|
||||
overrideEntityVisibility,
|
||||
query: newQuery,
|
||||
},
|
||||
})) as { List: React.ReactNode }
|
||||
@@ -100,7 +102,15 @@ export const ListDrawerContent: React.FC<ListDrawerProps> = ({
|
||||
}
|
||||
}
|
||||
},
|
||||
[serverFunction, closeModal, drawerSlug, isOpen, enableRowSelections, filterOptions],
|
||||
[
|
||||
serverFunction,
|
||||
closeModal,
|
||||
drawerSlug,
|
||||
isOpen,
|
||||
enableRowSelections,
|
||||
filterOptions,
|
||||
overrideEntityVisibility,
|
||||
],
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -10,6 +10,7 @@ export type ListDrawerProps = {
|
||||
readonly drawerSlug?: string
|
||||
readonly enableRowSelections?: boolean
|
||||
readonly filterOptions?: FilterOptionsResult
|
||||
readonly overrideEntityVisibility?: boolean
|
||||
readonly selectedCollection?: string
|
||||
} & ListDrawerContextProps
|
||||
|
||||
@@ -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
|
||||
}) => [
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -30,6 +30,7 @@ type RenderDocument = (args: {
|
||||
docID?: number | string
|
||||
drawerSlug?: string
|
||||
initialData?: Data
|
||||
overrideEntityVisibility?: boolean
|
||||
redirectAfterDelete?: boolean
|
||||
redirectAfterDuplicate?: boolean
|
||||
signal?: AbortSignal
|
||||
|
||||
Reference in New Issue
Block a user