Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
'use client'

import { useModal } from '@faceless-ui/modal'
import React from 'react'

import type { DocumentDrawerProps } from './types.js'

import { useEditDepth } from '../../providers/EditDepth/index.js'
import { DocumentDrawer, formatDocumentDrawerSlug } from './index.js'

type ControlledDocumentDrawerProps = {
readonly isOpen: boolean
readonly onOpenChange?: (isOpen: boolean) => void
} & Omit<DocumentDrawerProps, 'drawerSlug'>

/**
* A controlled wrapper around `DocumentDrawer` for views that want to drive
* drawer visibility from state instead of the imperative `useDocumentDrawer` hook.
*/
export const ControlledDocumentDrawer: React.FC<ControlledDocumentDrawerProps> = ({
id,
collectionSlug,
isOpen,
onOpenChange,
...rest
}) => {
const drawerDepth = useEditDepth()
const uuid = React.useId()
const { closeModal, modalState, openModal } = useModal()
const drawerSlug = React.useMemo(
() =>
formatDocumentDrawerSlug({
id,
collectionSlug,
depth: drawerDepth,
uuid,
}),
[collectionSlug, drawerDepth, id, uuid],
)
const isDrawerOpen = Boolean(modalState[drawerSlug]?.isOpen)
const previousIsDrawerOpen = React.useRef(isDrawerOpen)

React.useEffect(() => {
if (isOpen && !isDrawerOpen) {
openModal(drawerSlug)
}

if (!isOpen && isDrawerOpen) {
closeModal(drawerSlug)
}
}, [closeModal, drawerSlug, isDrawerOpen, isOpen, openModal])

React.useEffect(() => {
if (previousIsDrawerOpen.current !== isDrawerOpen) {
previousIsDrawerOpen.current = isDrawerOpen
onOpenChange?.(isDrawerOpen)
}
}, [isDrawerOpen, onOpenChange])

React.useEffect(() => {
return () => {
closeModal(drawerSlug)
}
}, [closeModal, drawerSlug])

return (
<DocumentDrawer {...rest} collectionSlug={collectionSlug} drawerSlug={drawerSlug} id={id} />
)
}
2 changes: 1 addition & 1 deletion packages/ui/src/elements/DocumentDrawer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import './index.scss'

export const documentDrawerBaseClass = 'doc-drawer'

const formatDocumentDrawerSlug = ({
export const formatDocumentDrawerSlug = ({
id,
collectionSlug,
depth,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import { useDocumentDrawer } from '../../../DocumentDrawer/index.js'
import { Drawer } from '../../../Drawer/index.js'
import { DrawerActionHeader } from '../../../DrawerActionHeader/index.js'
import { DrawerContentContainer } from '../../../DrawerContentContainer/index.js'
import { ListCreateNewDocInFolderButton } from '../../../ListHeader/TitleActions/ListCreateNewDocInFolderButton.js'
import { LoadingOverlay } from '../../../Loading/index.js'
import { NoListResults } from '../../../NoListResults/index.js'
import { Translation } from '../../../Translation/index.js'
Expand Down Expand Up @@ -102,7 +101,7 @@ function LoadFolderData(props: MoveToFolderDrawerProps) {
setFolderResultsComponent(result.FolderResultsComponent || null)
setFolderID(folderIDToPopulate)
setHasLoaded(true)
} catch (e) {
} catch (_error) {
setBreadcrumbs([])
setSubfolders([])
setDocuments([])
Expand Down Expand Up @@ -178,6 +177,8 @@ function Content({
useDocumentDrawer({
collectionSlug: folderCollectionSlug,
})
const newFolderAssignedCollections =
folderID == null ? props.folderAssignedCollections : folderType

const getSelectedFolder = React.useCallback((): {
id: null | number | string
Expand Down Expand Up @@ -286,53 +287,52 @@ function Content({
]}
/>
{subfolders.length > 0 && (
<>
<Button
buttonStyle="pill"
className={`${baseClass}__add-folder-button`}
margin={false}
onClick={() => {
openFolderDrawer()
}}
>
{t('fields:addLabel', {
label: getTranslation(folderCollectionConfig.labels?.singular, i18n),
})}
</Button>
<FolderDocumentDrawer
initialData={{
[folderFieldName]: folderID,
folderType,
}}
onSave={(result) => {
void onCreateSuccess({
collectionSlug: folderCollectionConfig.slug,
doc: result.doc,
})
closeFolderDrawer()
}}
redirectAfterCreate={false}
/>
</>
<Button
buttonStyle="pill"
className={`${baseClass}__add-folder-button`}
margin={false}
onClick={() => {
openFolderDrawer()
}}
>
{t('fields:addLabel', {
label: getTranslation(folderCollectionConfig.labels?.singular, i18n),
})}
</Button>
)}
</div>
<FolderDocumentDrawer
initialData={{
[folderFieldName]: folderID,
folderType: newFolderAssignedCollections,
}}
onSave={(result) => {
void onCreateSuccess({
collectionSlug: folderCollectionConfig.slug,
doc: result.doc,
})
closeFolderDrawer()
}}
redirectAfterCreate={false}
/>

<DrawerContentContainer className={`${baseClass}__body-section`}>
{subfolders.length > 0 ? (
FolderResultsComponent
) : (
<NoListResults
Actions={[
<ListCreateNewDocInFolderButton
buttonLabel={`${t('general:create')} ${getTranslation(folderCollectionConfig.labels?.singular, i18n).toLowerCase()}`}
buttonSize="medium"
<Button
buttonStyle="primary"
collectionSlugs={[folderCollectionSlug]}
folderAssignedCollections={props.folderAssignedCollections}
className={`${baseClass}__create-folder-button`}
key="create-folder"
onCreateSuccess={onCreateSuccess}
slugPrefix="create-new-folder-from-drawer--no-results"
/>,
onClick={() => {
openFolderDrawer()
}}
size="medium"
>
{`${t('general:create')} ${getTranslation(folderCollectionConfig.labels?.singular, i18n).toLowerCase()}`}
</Button>,
]}
Message={
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@

import type { ClientCollectionConfig, CollectionSlug } from 'payload'

import { useModal } from '@faceless-ui/modal'
import { getTranslation } from '@payloadcms/translations'
import React from 'react'

import { useConfig } from '../../../providers/Config/index.js'
import { useFolder } from '../../../providers/Folders/index.js'
import { useTranslation } from '../../../providers/Translation/index.js'
import { Button } from '../../Button/index.js'
import { DocumentDrawer, useDocumentDrawer } from '../../DocumentDrawer/index.js'
import { Popup, PopupList } from '../../Popup/index.js'

const baseClass = 'create-new-doc-in-folder'
Expand All @@ -20,9 +17,7 @@ export function ListCreateNewDocInFolderButton({
buttonSize = 'small',
buttonStyle = 'pill',
collectionSlugs,
folderAssignedCollections,
onCreateSuccess,
slugPrefix,
onRequestCreate,
}: {
buttonLabel: string
buttonSize?: 'large' | 'medium' | 'small' | 'xsmall'
Expand All @@ -37,23 +32,10 @@ export function ListCreateNewDocInFolderButton({
| 'tab'
| 'transparent'
collectionSlugs: CollectionSlug[]
folderAssignedCollections: CollectionSlug[]
onCreateSuccess: (args: {
collectionSlug: CollectionSlug
doc: Record<string, unknown>
}) => Promise<void> | void
slugPrefix: string
onRequestCreate: (collectionSlug: CollectionSlug) => void
}) {
const newDocInFolderDrawerSlug = `${slugPrefix}-new-doc-in-folder-drawer`
const { i18n } = useTranslation()
const { closeModal, openModal } = useModal()
const { config } = useConfig()
const { folderCollectionConfig, folderCollectionSlug, folderFieldName, folderID } = useFolder()
const [FolderDocumentDrawer, , { closeDrawer: closeFolderDrawer, openDrawer: openFolderDrawer }] =
useDocumentDrawer({
collectionSlug: folderCollectionSlug,
})
const [createCollectionSlug, setCreateCollectionSlug] = React.useState<string | undefined>()
const [enabledCollections] = React.useState<ClientCollectionConfig[]>(() =>
collectionSlugs.reduce((acc, collectionSlug) => {
const collectionConfig = config.collections.find(({ slug }) => slug === collectionSlug)
Expand All @@ -76,14 +58,7 @@ export function ListCreateNewDocInFolderButton({
buttonStyle={buttonStyle}
className={`${baseClass}__button`}
el="div"
onClick={() => {
if (enabledCollections[0].slug === folderCollectionConfig.slug) {
openFolderDrawer()
} else {
setCreateCollectionSlug(enabledCollections[0].slug)
openModal(newDocInFolderDrawerSlug)
}
}}
onClick={() => onRequestCreate(enabledCollections[0].slug)}
size={buttonSize}
>
{buttonLabel}
Expand All @@ -107,61 +82,14 @@ export function ListCreateNewDocInFolderButton({
<PopupList.ButtonGroup>
{enabledCollections.map((collection, index) => {
return (
<PopupList.Button
key={index}
onClick={() => {
if (collection.slug === folderCollectionConfig.slug) {
openFolderDrawer()
} else {
setCreateCollectionSlug(collection.slug)
openModal(newDocInFolderDrawerSlug)
}
}}
>
<PopupList.Button key={index} onClick={() => onRequestCreate(collection.slug)}>
{getTranslation(collection.labels.singular, i18n)}
</PopupList.Button>
)
})}
</PopupList.ButtonGroup>
</Popup>
)}

{createCollectionSlug && (
<DocumentDrawer
collectionSlug={createCollectionSlug}
drawerSlug={newDocInFolderDrawerSlug}
initialData={{
[folderFieldName]: folderID,
}}
onSave={async ({ doc }) => {
await onCreateSuccess({
collectionSlug: createCollectionSlug,
doc,
})
closeModal(newDocInFolderDrawerSlug)
}}
redirectAfterCreate={false}
/>
)}

{collectionSlugs.includes(folderCollectionConfig.slug) && (
<FolderDocumentDrawer
initialData={{
[folderFieldName]: folderID,
folderType: createCollectionSlug
? folderAssignedCollections || [createCollectionSlug]
: folderAssignedCollections,
}}
onSave={async (result) => {
await onCreateSuccess({
collectionSlug: folderCollectionConfig.slug,
doc: result.doc,
})
closeFolderDrawer()
}}
redirectAfterCreate={false}
/>
)}
</React.Fragment>
)
}
Loading
Loading