payload-nested-docs-page-tree 1.2.2 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -46
- package/dist/components/PageTreeListView.client.d.ts +2 -2
- package/dist/components/PageTreeListView.client.js +12 -285
- package/dist/components/PageTreeListView.client.js.map +1 -1
- package/dist/endpoints/createMovePageEndpoint.js +4 -0
- package/dist/endpoints/createMovePageEndpoint.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +29 -2
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -49,47 +49,47 @@ If needed, refresh the admin import map:
|
|
|
49
49
|
payload generate:importmap
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
## What It Adds
|
|
53
|
-
|
|
54
|
-
- replaces the collection list view with a nested tree table
|
|
55
|
-
- preserves sorting, filters, pagination, bulk selection, and row actions
|
|
56
|
-
- adds `POST /:id/move` for drag-and-drop parent changes
|
|
57
|
-
- marks the root page with slug `home` using a home icon on the title link
|
|
58
|
-
- hides the read-only breadcrumbs field by default
|
|
59
|
-
|
|
60
|
-
## Home Indicator
|
|
61
|
-
|
|
62
|
-
By default, the home icon is enabled only for the `pages` collection.
|
|
63
|
-
|
|
64
|
-
```ts
|
|
65
|
-
nestedDocsPageTreePlugin({
|
|
66
|
-
collections: ['pages'],
|
|
67
|
-
})
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
For custom page collection slugs, pass an exact allow-list:
|
|
71
|
-
|
|
72
|
-
```ts
|
|
73
|
-
nestedDocsPageTreePlugin({
|
|
74
|
-
collections: ['page-tree', 'categories'],
|
|
75
|
-
homeIndicator: {
|
|
76
|
-
collections: ['page-tree'],
|
|
77
|
-
},
|
|
78
|
-
})
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
To disable the home icon everywhere:
|
|
82
|
-
|
|
83
|
-
```ts
|
|
84
|
-
nestedDocsPageTreePlugin({
|
|
85
|
-
collections: ['pages'],
|
|
86
|
-
homeIndicator: false,
|
|
87
|
-
})
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## Status Badges
|
|
91
|
-
|
|
92
|
-
The tree view supports three document states:
|
|
52
|
+
## What It Adds
|
|
53
|
+
|
|
54
|
+
- replaces the collection list view with a nested tree table
|
|
55
|
+
- preserves sorting, filters, pagination, bulk selection, and row actions
|
|
56
|
+
- adds `POST /:id/move` for drag-and-drop parent changes
|
|
57
|
+
- marks the root page with slug `home` using a home icon on the title link
|
|
58
|
+
- hides the read-only breadcrumbs field by default
|
|
59
|
+
|
|
60
|
+
## Home Indicator
|
|
61
|
+
|
|
62
|
+
By default, the home icon is enabled only for the `pages` collection.
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
nestedDocsPageTreePlugin({
|
|
66
|
+
collections: ['pages'],
|
|
67
|
+
})
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
For custom page collection slugs, pass an exact allow-list:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
nestedDocsPageTreePlugin({
|
|
74
|
+
collections: ['page-tree', 'categories'],
|
|
75
|
+
homeIndicator: {
|
|
76
|
+
collections: ['page-tree'],
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
To disable the home icon everywhere:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
nestedDocsPageTreePlugin({
|
|
85
|
+
collections: ['pages'],
|
|
86
|
+
homeIndicator: false,
|
|
87
|
+
})
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Status Badges
|
|
91
|
+
|
|
92
|
+
The tree view supports three document states:
|
|
93
93
|
|
|
94
94
|
- `published`: live and up to date
|
|
95
95
|
- `changed`: live, but has unpublished changes
|
|
@@ -117,16 +117,74 @@ nestedDocsPageTreePlugin({
|
|
|
117
117
|
|
|
118
118
|
`labels` and `colors` are optional partial overrides. Missing entries fall back to the built-in defaults.
|
|
119
119
|
|
|
120
|
+
## Drag-And-Drop Is Triggering A Deploy?
|
|
121
|
+
|
|
122
|
+
A drag-and-drop move calls `payload.update()` on the draft only. The published version of the live site is never touched. So in most setups, dragging a page does not trigger any rebuild and you can skip this section.
|
|
123
|
+
|
|
124
|
+
### When you can skip this section
|
|
125
|
+
|
|
126
|
+
- The default Payload website template on Vercel (or any host using Next.js ISR), with drafts and autosave on. The template's `afterChange` hook only calls `revalidatePath` and `revalidateTag` from `next/cache`. Those just clear the edge cache. They do not trigger a Vercel build, do not consume build minutes, and do not change what visitors see when the published HTML hasn't changed.
|
|
127
|
+
- Any setup where your `afterChange` hooks only do in-process cache work (`revalidatePath`, `revalidateTag`, in-memory caches, etc.).
|
|
128
|
+
|
|
129
|
+
### When you need the one-line fix
|
|
130
|
+
|
|
131
|
+
You need the fix if **you** wrote an `afterChange` hook that calls something external or expensive on every save. Common cases:
|
|
132
|
+
|
|
133
|
+
- **Cloudflare Pages / Netlify / Vercel Deploy Hooks** (`fetch(DEPLOY_HOOK_URL)`) - these trigger full rebuilds and burn build minutes.
|
|
134
|
+
- **GitHub Actions** `repository_dispatch` triggers.
|
|
135
|
+
- **Manually-invoked SSG rebuilds**.
|
|
136
|
+
- **Publish notifications** (email, Slack) on status transitions.
|
|
137
|
+
- **Heavy search reindex jobs** (Algolia, Meilisearch full-document push).
|
|
138
|
+
|
|
139
|
+
Why a tree move trips these: a typical deploy hook fires when `previousDoc?._status === 'published'` so that it catches unpublish events too. A tree move on a published doc matches that condition (the previous draft state was published) - but the live site hasn't actually changed. Without the fix, every drag fires your deploy.
|
|
140
|
+
|
|
141
|
+
### The fix
|
|
142
|
+
|
|
143
|
+
Add one line at the top of your hook. The plugin sets a flag on Payload's [hook context](https://payloadcms.com/docs/hooks/context) for every move, and your hook reads it to bail out early:
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
import { pageTreeMoveContextKey } from 'payload-nested-docs-page-tree'
|
|
147
|
+
|
|
148
|
+
// at the top of your afterChange hook:
|
|
149
|
+
if (req.context?.[pageTreeMoveContextKey]) return
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
This goes in **your** hook - the one that calls the deploy webhook. Not in any of the template's stock files.
|
|
153
|
+
|
|
154
|
+
Full example:
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import type { CollectionAfterChangeHook } from 'payload'
|
|
158
|
+
import { pageTreeMoveContextKey } from 'payload-nested-docs-page-tree'
|
|
159
|
+
|
|
160
|
+
export const triggerDeployOnPublishedChange: CollectionAfterChangeHook = async ({
|
|
161
|
+
doc,
|
|
162
|
+
previousDoc,
|
|
163
|
+
req,
|
|
164
|
+
}) => {
|
|
165
|
+
// -- plugin opt-out --
|
|
166
|
+
if (req.context?.[pageTreeMoveContextKey]) return
|
|
167
|
+
|
|
168
|
+
// -- your deploy logic (example) --
|
|
169
|
+
// Fire on publish, republish, or unpublish - every transition the live site cares about.
|
|
170
|
+
if (doc._status === 'published' || previousDoc?._status === 'published') {
|
|
171
|
+
// POST to your Cloudflare / Netlify / Vercel deploy hook here
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
See [`dev/lib/rebuild.ts`](https://github.com/WLF-Studios/payload-nested-docs-page-tree/blob/main/dev/lib/rebuild.ts) for the full reference example.
|
|
177
|
+
|
|
120
178
|
## Configuration
|
|
121
179
|
|
|
122
180
|
- `collections`: target collection slugs
|
|
123
181
|
- `parentFieldSlug`: defaults to `'parent'`
|
|
124
182
|
- `breadcrumbsFieldSlug`: defaults to `'breadcrumbs'`
|
|
125
|
-
- `defaultLimit`: defaults to `100`
|
|
126
|
-
- `hideBreadcrumbs`: defaults to `true`
|
|
127
|
-
- `homeIndicator`: defaults to `{ collections: ['pages'] }`; set to `false` to disable
|
|
128
|
-
- `disabled`: defaults to `false`
|
|
129
|
-
- `badges`: optional label and color overrides for `published`, `changed`, and `draft`
|
|
183
|
+
- `defaultLimit`: defaults to `100`
|
|
184
|
+
- `hideBreadcrumbs`: defaults to `true`
|
|
185
|
+
- `homeIndicator`: defaults to `{ collections: ['pages'] }`; set to `false` to disable
|
|
186
|
+
- `disabled`: defaults to `false`
|
|
187
|
+
- `badges`: optional label and color overrides for `published`, `changed`, and `draft`
|
|
130
188
|
|
|
131
189
|
## Development
|
|
132
190
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Column, ListQuery, ListViewClientProps } from 'payload';
|
|
2
|
-
import type
|
|
2
|
+
import { type NestedDocsPageTreePluginResolvedBadgeConfig, type PageTreeSourceDoc } from '../types.js';
|
|
3
3
|
import { type PageTreeDoc } from '../utilities/pageTree.js';
|
|
4
4
|
type PageTreeListViewClientOwnProps = {
|
|
5
5
|
allDocs: PageTreeDoc[];
|
|
@@ -14,5 +14,5 @@ type PageTreeListViewClientOwnProps = {
|
|
|
14
14
|
useAsTitle: string;
|
|
15
15
|
};
|
|
16
16
|
type PageTreeListViewClientProps = Omit<ListViewClientProps, 'columnState' | 'Table'> & PageTreeListViewClientOwnProps;
|
|
17
|
-
export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDocs, columnState, homeIndicatorEnabled, orderableFieldName, parentFieldSlug, query, sourceDocs, useAsTitle, ...props }: PageTreeListViewClientProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDocs, columnState, homeIndicatorEnabled, orderableFieldName: _orderableFieldName, parentFieldSlug, query, sourceDocs, useAsTitle, ...props }: PageTreeListViewClientProps): import("react/jsx-runtime").JSX.Element;
|
|
18
18
|
export {};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { DndContext, DragOverlay, PointerSensor, useDroppable, useSensor, useSensors } from '@dnd-kit/core';
|
|
4
|
-
import { DefaultListView, ListQueryProvider, SelectAll, SelectRow,
|
|
4
|
+
import { DefaultListView, ListQueryProvider, SelectAll, SelectRow, toast, useConfig, useLocale, useTranslation } from '@payloadcms/ui';
|
|
5
5
|
import { useRouter, useSearchParams } from 'next/navigation';
|
|
6
6
|
import React from 'react';
|
|
7
|
-
import {
|
|
7
|
+
import { pageTreeMoveRequestHeader, pageTreeMoveRequestHeaderValue } from '../types.js';
|
|
8
|
+
import { buildInsertDropTargets, getDropTargetParentDoc } from '../utilities/dropTargets.js';
|
|
8
9
|
import { CANCEL_DRAG_MESSAGE, getDropValidation } from '../utilities/moveValidation.js';
|
|
9
10
|
import { buildDocSlugPath, buildPageTreeDocs, buildProspectiveDocSlugPath, getDocDisplayLabel, getVisibleTreeDocs } from '../utilities/pageTree.js';
|
|
10
11
|
import { pageTreeCollisionDetectionStrategy } from '../utilities/pageTreeCollision.js';
|
|
@@ -22,85 +23,6 @@ function getRowDropID(rowID) {
|
|
|
22
23
|
function getPageTreeDragData(value) {
|
|
23
24
|
return value && typeof value === 'object' ? value : {};
|
|
24
25
|
}
|
|
25
|
-
function getPayloadDocID(doc) {
|
|
26
|
-
return typeof doc.id === 'number' || typeof doc.id === 'string' ? doc.id : undefined;
|
|
27
|
-
}
|
|
28
|
-
function getManualOrderDropValidation(args) {
|
|
29
|
-
const { activeDoc, targetDoc } = args;
|
|
30
|
-
if (!targetDoc) {
|
|
31
|
-
return {
|
|
32
|
-
isValid: true,
|
|
33
|
-
parentID: null
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
if (targetDoc.__pageTreeID === activeDoc.__pageTreeID) {
|
|
37
|
-
return {
|
|
38
|
-
isValid: false,
|
|
39
|
-
message: CANCEL_DRAG_MESSAGE,
|
|
40
|
-
parentID: targetDoc.__pageTreeID
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
if (targetDoc.__pageTreeAncestorIDs.includes(activeDoc.__pageTreeID)) {
|
|
44
|
-
return {
|
|
45
|
-
isValid: false,
|
|
46
|
-
message: 'A document cannot be moved under one of its descendants.',
|
|
47
|
-
parentID: targetDoc.__pageTreeID
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
return {
|
|
51
|
-
isValid: true,
|
|
52
|
-
parentID: targetDoc.__pageTreeID
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
function getDropValidationForMode(args) {
|
|
56
|
-
const { activeDoc, allowSameParent, targetDoc } = args;
|
|
57
|
-
if (allowSameParent) {
|
|
58
|
-
return getManualOrderDropValidation({
|
|
59
|
-
activeDoc,
|
|
60
|
-
targetDoc
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
return getDropValidation({
|
|
64
|
-
activeDoc,
|
|
65
|
-
targetDoc
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
function getCurrentOrderPlacement(args) {
|
|
69
|
-
const { activeDoc, docs } = args;
|
|
70
|
-
const activeIndex = docs.findIndex((doc)=>doc.__pageTreeID === activeDoc.__pageTreeID);
|
|
71
|
-
const movingSubtreeIDs = new Set(docs.filter((doc)=>doc.__pageTreeID === activeDoc.__pageTreeID || doc.__pageTreeAncestorIDs.includes(activeDoc.__pageTreeID)).map((doc)=>doc.__pageTreeID));
|
|
72
|
-
const siblingIsNotMoving = (doc)=>doc.__pageTreeParentID === activeDoc.__pageTreeParentID && !movingSubtreeIDs.has(doc.__pageTreeID);
|
|
73
|
-
if (activeIndex < 0) {
|
|
74
|
-
return {
|
|
75
|
-
nextSiblingID: null,
|
|
76
|
-
parentID: activeDoc.__pageTreeParentID,
|
|
77
|
-
previousSiblingID: null
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
return {
|
|
81
|
-
nextSiblingID: docs.slice(activeIndex + 1).find(siblingIsNotMoving)?.__pageTreeID ?? null,
|
|
82
|
-
parentID: activeDoc.__pageTreeParentID,
|
|
83
|
-
previousSiblingID: docs.slice(0, activeIndex).filter(siblingIsNotMoving).at(-1)?.__pageTreeID ?? null
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
function orderPlacementHasChanged(currentPlacement, nextPlacement) {
|
|
87
|
-
return currentPlacement.parentID !== nextPlacement.parentID || currentPlacement.previousSiblingID !== nextPlacement.previousSiblingID || currentPlacement.nextSiblingID !== nextPlacement.nextSiblingID;
|
|
88
|
-
}
|
|
89
|
-
function getReorderTargetFromPlacement(args) {
|
|
90
|
-
const { currentSort, docsByID, orderableFieldName, placement } = args;
|
|
91
|
-
const targetDocID = placement.previousSiblingID ?? placement.nextSiblingID;
|
|
92
|
-
if (!targetDocID) {
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
const targetDoc = docsByID.get(targetDocID);
|
|
96
|
-
if (!targetDoc) {
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
return {
|
|
100
|
-
newKeyWillBe: placement.previousSiblingID !== null && currentSort === orderableFieldName || placement.previousSiblingID === null && currentSort === `-${orderableFieldName}` ? 'greater' : 'less',
|
|
101
|
-
targetDoc
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
26
|
function buildPaginatedData(docs, limit, requestedPage) {
|
|
105
27
|
const totalDocs = docs.length;
|
|
106
28
|
const totalPages = totalDocs > 0 ? Math.max(1, Math.ceil(totalDocs / limit)) : 1;
|
|
@@ -191,28 +113,8 @@ function renderStatusBadge(args) {
|
|
|
191
113
|
})
|
|
192
114
|
}, doc.__pageTreeID ?? index);
|
|
193
115
|
}
|
|
194
|
-
function createManualOrderColumn(docs) {
|
|
195
|
-
return {
|
|
196
|
-
accessor: MANUAL_ORDER_COLUMN_ACCESSOR,
|
|
197
|
-
active: true,
|
|
198
|
-
field: {
|
|
199
|
-
hidden: true
|
|
200
|
-
},
|
|
201
|
-
Heading: /*#__PURE__*/ _jsx(SortHeader, {}),
|
|
202
|
-
renderedCells: docs.map(()=>null)
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
function insertManualOrderColumn(columns, orderColumn) {
|
|
206
|
-
const selectColumnIndex = columns.findIndex((column)=>column.accessor === '_select');
|
|
207
|
-
const insertIndex = selectColumnIndex >= 0 ? selectColumnIndex + 1 : 0;
|
|
208
|
-
return [
|
|
209
|
-
...columns.slice(0, insertIndex),
|
|
210
|
-
orderColumn,
|
|
211
|
-
...columns.slice(insertIndex)
|
|
212
|
-
];
|
|
213
|
-
}
|
|
214
116
|
function buildTableColumns(args) {
|
|
215
|
-
const { badgeConfig, columnState, docs, enableRowSelections, homeIndicatorEnabled,
|
|
117
|
+
const { badgeConfig, columnState, docs, enableRowSelections, homeIndicatorEnabled, parentFieldSlug, t, useAsTitle } = args;
|
|
216
118
|
const columnsToUse = columnState.map((column)=>{
|
|
217
119
|
if (column.accessor === useAsTitle) {
|
|
218
120
|
return {
|
|
@@ -260,9 +162,6 @@ function buildTableColumns(args) {
|
|
|
260
162
|
}, doc.__pageTreeID ?? index))
|
|
261
163
|
});
|
|
262
164
|
}
|
|
263
|
-
if (orderableFieldName && !columnsToUse.some((column)=>column.accessor === MANUAL_ORDER_COLUMN_ACCESSOR)) {
|
|
264
|
-
return insertManualOrderColumn(columnsToUse, createManualOrderColumn(docs));
|
|
265
|
-
}
|
|
266
165
|
return columnsToUse;
|
|
267
166
|
}
|
|
268
167
|
function HierarchyInsertRow({ activeColumnsCount, activeDragRowID, dropTarget, dropValidation, isMovePending }) {
|
|
@@ -319,7 +218,7 @@ function HierarchyTableRow({ activeColumns, activeDragRowID, doc, dropValidation
|
|
|
319
218
|
})
|
|
320
219
|
});
|
|
321
220
|
}
|
|
322
|
-
function HierarchyTable({ activeDragRowID, allDocsByID,
|
|
221
|
+
function HierarchyTable({ activeDragRowID, allDocsByID, columns, data, isMovePending, titleCellAccessor }) {
|
|
323
222
|
const activeColumns = React.useMemo(()=>columns.filter((column)=>column?.active), [
|
|
324
223
|
columns
|
|
325
224
|
]);
|
|
@@ -336,15 +235,13 @@ function HierarchyTable({ activeDragRowID, allDocsByID, allowSameParentDrops, co
|
|
|
336
235
|
}
|
|
337
236
|
return new Map(data.map((doc)=>[
|
|
338
237
|
doc.__pageTreeID,
|
|
339
|
-
|
|
238
|
+
getDropValidation({
|
|
340
239
|
activeDoc,
|
|
341
|
-
allowSameParent: allowSameParentDrops,
|
|
342
240
|
targetDoc: doc
|
|
343
241
|
})
|
|
344
242
|
]));
|
|
345
243
|
}, [
|
|
346
244
|
activeDoc,
|
|
347
|
-
allowSameParentDrops,
|
|
348
245
|
data
|
|
349
246
|
]);
|
|
350
247
|
const insertDropValidationByID = React.useMemo(()=>{
|
|
@@ -353,15 +250,13 @@ function HierarchyTable({ activeDragRowID, allDocsByID, allowSameParentDrops, co
|
|
|
353
250
|
}
|
|
354
251
|
return new Map(insertDropTargets.map((dropTarget)=>[
|
|
355
252
|
dropTarget.dropID,
|
|
356
|
-
|
|
253
|
+
getDropValidation({
|
|
357
254
|
activeDoc,
|
|
358
|
-
allowSameParent: allowSameParentDrops,
|
|
359
255
|
targetDoc: dropTarget.parentID === null ? undefined : allDocsByID.get(dropTarget.parentID) ?? undefined
|
|
360
256
|
})
|
|
361
257
|
]));
|
|
362
258
|
}, [
|
|
363
259
|
activeDoc,
|
|
364
|
-
allowSameParentDrops,
|
|
365
260
|
allDocsByID,
|
|
366
261
|
insertDropTargets
|
|
367
262
|
]);
|
|
@@ -430,7 +325,7 @@ function HierarchyTable({ activeDragRowID, allDocsByID, allowSameParentDrops, co
|
|
|
430
325
|
})
|
|
431
326
|
});
|
|
432
327
|
}
|
|
433
|
-
export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDocs, columnState, homeIndicatorEnabled, orderableFieldName, parentFieldSlug, query, sourceDocs, useAsTitle, ...props }) {
|
|
328
|
+
export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDocs, columnState, homeIndicatorEnabled, orderableFieldName: _orderableFieldName, parentFieldSlug, query, sourceDocs, useAsTitle, ...props }) {
|
|
434
329
|
const router = useRouter();
|
|
435
330
|
const searchParams = useSearchParams();
|
|
436
331
|
const { config } = useConfig();
|
|
@@ -467,7 +362,6 @@ export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDo
|
|
|
467
362
|
query.sort,
|
|
468
363
|
searchParams
|
|
469
364
|
]);
|
|
470
|
-
const manualOrderIsActive = Boolean(orderableFieldName && (currentSort === orderableFieldName || currentSort === `-${orderableFieldName}`));
|
|
471
365
|
const currentLimit = React.useMemo(()=>normalizePositiveInt(searchParams.get('limit'), typeof query.limit === 'number' && query.limit > 0 ? query.limit : 10), [
|
|
472
366
|
query.limit,
|
|
473
367
|
searchParams
|
|
@@ -556,7 +450,6 @@ export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDo
|
|
|
556
450
|
docs: paginatedDocs,
|
|
557
451
|
enableRowSelections: props.enableRowSelections,
|
|
558
452
|
homeIndicatorEnabled,
|
|
559
|
-
orderableFieldName,
|
|
560
453
|
parentFieldSlug,
|
|
561
454
|
t: i18n.t,
|
|
562
455
|
useAsTitle
|
|
@@ -565,7 +458,6 @@ export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDo
|
|
|
565
458
|
paginatedDocs,
|
|
566
459
|
badgeConfig,
|
|
567
460
|
homeIndicatorEnabled,
|
|
568
|
-
orderableFieldName,
|
|
569
461
|
parentFieldSlug,
|
|
570
462
|
props.enableRowSelections,
|
|
571
463
|
i18n.t,
|
|
@@ -586,9 +478,8 @@ export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDo
|
|
|
586
478
|
docsByID: allDocsByID,
|
|
587
479
|
dropTarget: activeDropTarget
|
|
588
480
|
});
|
|
589
|
-
const dropValidation =
|
|
481
|
+
const dropValidation = getDropValidation({
|
|
590
482
|
activeDoc: activeDragDoc,
|
|
591
|
-
allowSameParent: manualOrderIsActive,
|
|
592
483
|
targetDoc: targetDoc ?? undefined
|
|
593
484
|
});
|
|
594
485
|
if (!dropValidation.isValid) {
|
|
@@ -605,8 +496,7 @@ export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDo
|
|
|
605
496
|
}, [
|
|
606
497
|
activeDragDoc,
|
|
607
498
|
activeDropTarget,
|
|
608
|
-
allDocsByID
|
|
609
|
-
manualOrderIsActive
|
|
499
|
+
allDocsByID
|
|
610
500
|
]);
|
|
611
501
|
const isMovePending = pendingMoveRowID !== null;
|
|
612
502
|
const sensors = useSensors(useSensor(PointerSensor, {
|
|
@@ -627,7 +517,8 @@ export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDo
|
|
|
627
517
|
credentials: 'include',
|
|
628
518
|
headers: {
|
|
629
519
|
'Accept-Language': i18n.language,
|
|
630
|
-
'Content-Type': 'application/json'
|
|
520
|
+
'Content-Type': 'application/json',
|
|
521
|
+
[pageTreeMoveRequestHeader]: pageTreeMoveRequestHeaderValue
|
|
631
522
|
},
|
|
632
523
|
method: 'POST'
|
|
633
524
|
});
|
|
@@ -642,156 +533,6 @@ export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDo
|
|
|
642
533
|
locale?.code,
|
|
643
534
|
props.collectionSlug
|
|
644
535
|
]);
|
|
645
|
-
const reorderDocument = React.useCallback(async (args)=>{
|
|
646
|
-
const { movedDocID, newKeyWillBe, targetDoc } = args;
|
|
647
|
-
const targetID = getPayloadDocID(targetDoc);
|
|
648
|
-
if (!orderableFieldName || targetID === undefined) {
|
|
649
|
-
return undefined;
|
|
650
|
-
}
|
|
651
|
-
const params = new URLSearchParams();
|
|
652
|
-
if (locale?.code) {
|
|
653
|
-
params.set('locale', locale.code);
|
|
654
|
-
}
|
|
655
|
-
const response = await fetch(`${config.routes.api}/reorder${params.size > 0 ? `?${params.toString()}` : ''}`, {
|
|
656
|
-
body: JSON.stringify({
|
|
657
|
-
collectionSlug: props.collectionSlug,
|
|
658
|
-
docsToMove: [
|
|
659
|
-
movedDocID
|
|
660
|
-
],
|
|
661
|
-
newKeyWillBe,
|
|
662
|
-
orderableFieldName,
|
|
663
|
-
target: {
|
|
664
|
-
id: targetID,
|
|
665
|
-
key: targetDoc[orderableFieldName]
|
|
666
|
-
}
|
|
667
|
-
}),
|
|
668
|
-
credentials: 'include',
|
|
669
|
-
headers: {
|
|
670
|
-
'Accept-Language': i18n.language,
|
|
671
|
-
'Content-Type': 'application/json'
|
|
672
|
-
},
|
|
673
|
-
method: 'POST'
|
|
674
|
-
});
|
|
675
|
-
const result = await response.json().catch(()=>null);
|
|
676
|
-
if (response.status === 403) {
|
|
677
|
-
throw new Error('You do not have permission to reorder these rows');
|
|
678
|
-
}
|
|
679
|
-
if (!response.ok) {
|
|
680
|
-
throw new Error('Failed to reorder. This can happen if you reorder several rows too quickly. Please try again.');
|
|
681
|
-
}
|
|
682
|
-
if (result?.message === 'initial migration') {
|
|
683
|
-
throw new Error('You have enabled "orderable" on a collection with existing documents and this is the first time you have sorted documents. We have run an automatic migration to add an initial order to the documents. Please refresh the page and try again.');
|
|
684
|
-
}
|
|
685
|
-
return result?.orderValues?.[0];
|
|
686
|
-
}, [
|
|
687
|
-
config.routes.api,
|
|
688
|
-
i18n.language,
|
|
689
|
-
locale?.code,
|
|
690
|
-
orderableFieldName,
|
|
691
|
-
props.collectionSlug
|
|
692
|
-
]);
|
|
693
|
-
const handleManualOrderMoveEnd = React.useCallback(async (args)=>{
|
|
694
|
-
const { activeDoc, dropTarget, rowID } = args;
|
|
695
|
-
if (!orderableFieldName) {
|
|
696
|
-
return;
|
|
697
|
-
}
|
|
698
|
-
const targetDoc = getDropTargetParentDoc({
|
|
699
|
-
docsByID: allDocsByID,
|
|
700
|
-
dropTarget
|
|
701
|
-
});
|
|
702
|
-
const dropValidation = getManualOrderDropValidation({
|
|
703
|
-
activeDoc,
|
|
704
|
-
targetDoc: targetDoc ?? undefined
|
|
705
|
-
});
|
|
706
|
-
if (!dropValidation.isValid) {
|
|
707
|
-
if (!shouldSilenceMoveMessage(dropValidation.message)) {
|
|
708
|
-
toast.error(dropValidation.message ?? 'Could not move document.');
|
|
709
|
-
}
|
|
710
|
-
return;
|
|
711
|
-
}
|
|
712
|
-
const placement = getOrderPlacementFromDropTarget({
|
|
713
|
-
activeDoc,
|
|
714
|
-
docs: paginatedDocs,
|
|
715
|
-
docsByID: allDocsByID,
|
|
716
|
-
dropTarget
|
|
717
|
-
});
|
|
718
|
-
if (!placement) {
|
|
719
|
-
return;
|
|
720
|
-
}
|
|
721
|
-
const currentPlacement = getCurrentOrderPlacement({
|
|
722
|
-
activeDoc,
|
|
723
|
-
docs: paginatedDocs
|
|
724
|
-
});
|
|
725
|
-
const parentChanged = activeDoc.__pageTreeParentID !== placement.parentID;
|
|
726
|
-
const orderChanged = orderPlacementHasChanged(currentPlacement, placement);
|
|
727
|
-
const reorderTarget = orderChanged ? getReorderTargetFromPlacement({
|
|
728
|
-
currentSort,
|
|
729
|
-
docsByID: allDocsByID,
|
|
730
|
-
orderableFieldName,
|
|
731
|
-
placement
|
|
732
|
-
}) : null;
|
|
733
|
-
if (!parentChanged && !reorderTarget) {
|
|
734
|
-
return;
|
|
735
|
-
}
|
|
736
|
-
const movedDocID = getPayloadDocID(activeDoc);
|
|
737
|
-
if (movedDocID === undefined) {
|
|
738
|
-
return;
|
|
739
|
-
}
|
|
740
|
-
const parentDoc = placement.parentID ? allDocsByID.get(placement.parentID) : undefined;
|
|
741
|
-
const nextParentValue = placement.parentID === null ? null : parentDoc ? getPayloadDocID(parentDoc) ?? placement.parentID : placement.parentID;
|
|
742
|
-
let parentMoveSucceeded = false;
|
|
743
|
-
setPendingMoveRowID(rowID);
|
|
744
|
-
try {
|
|
745
|
-
if (parentChanged) {
|
|
746
|
-
await moveDocument({
|
|
747
|
-
parentID: placement.parentID,
|
|
748
|
-
rowID
|
|
749
|
-
});
|
|
750
|
-
parentMoveSucceeded = true;
|
|
751
|
-
}
|
|
752
|
-
const nextOrderValue = reorderTarget ? await reorderDocument({
|
|
753
|
-
movedDocID,
|
|
754
|
-
newKeyWillBe: reorderTarget.newKeyWillBe,
|
|
755
|
-
targetDoc: reorderTarget.targetDoc
|
|
756
|
-
}) : undefined;
|
|
757
|
-
if (parentChanged || typeof nextOrderValue === 'string') {
|
|
758
|
-
setLocalSourceDocs((currentDocs)=>currentDocs.map((doc)=>String(doc.id ?? '') === String(movedDocID) ? {
|
|
759
|
-
...doc,
|
|
760
|
-
...parentChanged ? {
|
|
761
|
-
[parentFieldSlug]: nextParentValue
|
|
762
|
-
} : {},
|
|
763
|
-
...typeof nextOrderValue === 'string' ? {
|
|
764
|
-
[orderableFieldName]: nextOrderValue
|
|
765
|
-
} : {}
|
|
766
|
-
} : doc));
|
|
767
|
-
}
|
|
768
|
-
if (parentChanged) {
|
|
769
|
-
toast.success(`Moved "${getDocDisplayLabel(activeDoc)}".`);
|
|
770
|
-
}
|
|
771
|
-
React.startTransition(()=>{
|
|
772
|
-
router.refresh();
|
|
773
|
-
});
|
|
774
|
-
} catch (error) {
|
|
775
|
-
const message = error instanceof Error && error.message ? error.message : 'Could not move document.';
|
|
776
|
-
toast.error(parentMoveSucceeded ? `Moved "${getDocDisplayLabel(activeDoc)}", but could not update its manual order. ${message}` : message);
|
|
777
|
-
if (parentMoveSucceeded) {
|
|
778
|
-
React.startTransition(()=>{
|
|
779
|
-
router.refresh();
|
|
780
|
-
});
|
|
781
|
-
}
|
|
782
|
-
} finally{
|
|
783
|
-
setPendingMoveRowID(null);
|
|
784
|
-
}
|
|
785
|
-
}, [
|
|
786
|
-
allDocsByID,
|
|
787
|
-
currentSort,
|
|
788
|
-
moveDocument,
|
|
789
|
-
orderableFieldName,
|
|
790
|
-
paginatedDocs,
|
|
791
|
-
parentFieldSlug,
|
|
792
|
-
reorderDocument,
|
|
793
|
-
router
|
|
794
|
-
]);
|
|
795
536
|
const handleDragCancel = React.useCallback(()=>{
|
|
796
537
|
setActiveDragRowID(null);
|
|
797
538
|
setActiveDropTarget(null);
|
|
@@ -837,14 +578,6 @@ export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDo
|
|
|
837
578
|
if (!rowID || !activeDoc || !overData) {
|
|
838
579
|
return;
|
|
839
580
|
}
|
|
840
|
-
if (manualOrderIsActive && orderableFieldName) {
|
|
841
|
-
await handleManualOrderMoveEnd({
|
|
842
|
-
activeDoc,
|
|
843
|
-
dropTarget: overData,
|
|
844
|
-
rowID
|
|
845
|
-
});
|
|
846
|
-
return;
|
|
847
|
-
}
|
|
848
581
|
const targetDoc = getDropTargetParentDoc({
|
|
849
582
|
docsByID: allDocsByID,
|
|
850
583
|
dropTarget: overData
|
|
@@ -880,10 +613,7 @@ export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDo
|
|
|
880
613
|
}
|
|
881
614
|
}, [
|
|
882
615
|
allDocsByID,
|
|
883
|
-
handleManualOrderMoveEnd,
|
|
884
|
-
manualOrderIsActive,
|
|
885
616
|
moveDocument,
|
|
886
|
-
orderableFieldName,
|
|
887
617
|
paginatedDocsByID,
|
|
888
618
|
router
|
|
889
619
|
]);
|
|
@@ -903,7 +633,6 @@ export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDo
|
|
|
903
633
|
/*#__PURE__*/ _jsx(HierarchyTable, {
|
|
904
634
|
activeDragRowID: activeDragRowID,
|
|
905
635
|
allDocsByID: allDocsByID,
|
|
906
|
-
allowSameParentDrops: manualOrderIsActive,
|
|
907
636
|
columns: tableColumns,
|
|
908
637
|
data: paginatedDocs,
|
|
909
638
|
isMovePending: isMovePending,
|
|
@@ -929,7 +658,6 @@ export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDo
|
|
|
929
658
|
handleDragStart,
|
|
930
659
|
isMovePending,
|
|
931
660
|
allDocsByID,
|
|
932
|
-
manualOrderIsActive,
|
|
933
661
|
paginatedDocs,
|
|
934
662
|
sensors,
|
|
935
663
|
tableColumns,
|
|
@@ -943,7 +671,6 @@ export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDo
|
|
|
943
671
|
collectionSlug: props.collectionSlug,
|
|
944
672
|
data: paginatedData,
|
|
945
673
|
modifySearchParams: true,
|
|
946
|
-
orderableFieldName: orderableFieldName,
|
|
947
674
|
query: {
|
|
948
675
|
...query,
|
|
949
676
|
limit: currentLimit,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/PageTreeListView.client.tsx"],"sourcesContent":["'use client'\r\n\r\nimport type { Column, ListQuery, ListViewClientProps, PaginatedDocs } from 'payload'\r\n\r\nimport {\r\n DndContext,\r\n type DragEndEvent,\r\n type DragOverEvent,\r\n DragOverlay,\r\n type DragStartEvent,\r\n PointerSensor,\r\n useDroppable,\r\n useSensor,\r\n useSensors,\r\n} from '@dnd-kit/core'\r\nimport {\r\n DefaultListView,\r\n ListQueryProvider,\r\n SelectAll,\r\n SelectRow,\r\n SortHeader,\r\n toast,\r\n useConfig,\r\n useLocale,\r\n useTranslation,\r\n} from '@payloadcms/ui'\r\nimport { useRouter, useSearchParams } from 'next/navigation'\r\nimport React from 'react'\r\n\r\nimport type {\r\n NestedDocsPageTreePluginResolvedBadgeConfig,\r\n PageTreeSourceDoc,\r\n} from '../types.js'\r\n\r\nimport {\r\n buildInsertDropTargets,\r\n getDropTargetParentDoc,\r\n getOrderPlacementFromDropTarget,\r\n type PageTreeDropTarget,\r\n type PageTreeOrderPlacement,\r\n} from '../utilities/dropTargets.js'\r\nimport {\r\n CANCEL_DRAG_MESSAGE,\r\n getDropValidation,\r\n type PageTreeDropValidation,\r\n} from '../utilities/moveValidation.js'\r\nimport {\r\n buildDocSlugPath,\r\n buildPageTreeDocs,\r\n buildProspectiveDocSlugPath,\r\n getDocDisplayLabel,\r\n getVisibleTreeDocs,\r\n type PageTreeDoc,\r\n} from '../utilities/pageTree.js'\r\nimport { pageTreeCollisionDetectionStrategy } from '../utilities/pageTreeCollision.js'\r\nimport {\r\n getPageTreeBadgeColor,\r\n getPageTreeBadgeLabel,\r\n getPageTreeDisplayStatus,\r\n type PageTreeDisplayStatus,\r\n} from '../utilities/status.js'\r\nimport { PageTreeProvider } from './PageTreeContext.js'\r\nimport styles from './PageTreeListView.module.css'\r\nimport { PageTreeTitleCell } from './PageTreeTitleCell.js'\r\n\r\ntype PageTreeListViewClientOwnProps = {\r\n allDocs: PageTreeDoc[]\r\n badgeConfig: NestedDocsPageTreePluginResolvedBadgeConfig\r\n canMoveDocs: boolean\r\n columnState: Column[]\r\n homeIndicatorEnabled: boolean\r\n orderableFieldName?: string\r\n parentFieldSlug: string\r\n query: ListQuery\r\n sourceDocs: PageTreeSourceDoc[]\r\n useAsTitle: string\r\n}\r\n\r\ntype PageTreeListViewClientProps = Omit<ListViewClientProps, 'columnState' | 'Table'> &\r\n PageTreeListViewClientOwnProps\r\n\r\ntype SelectableRowData = React.ComponentProps<typeof SelectRow>['rowData']\r\ntype PageTreeDragData = {\r\n dragType?: 'move'\r\n rowID?: string\r\n}\r\ntype ReorderDirection = 'greater' | 'less'\r\n\r\nconst MANUAL_ORDER_COLUMN_ACCESSOR = '_dragHandle'\r\nconst SILENT_MOVE_MESSAGES = new Set([CANCEL_DRAG_MESSAGE])\r\n\r\nfunction getRowDropID(rowID: string): string {\r\n return `page-drop:${rowID}`\r\n}\r\n\r\nfunction getPageTreeDragData(value: unknown): PageTreeDragData {\r\n return value && typeof value === 'object' ? (value as PageTreeDragData) : {}\r\n}\r\n\r\nfunction getPayloadDocID(doc: PageTreeDoc): number | string | undefined {\r\n return typeof doc.id === 'number' || typeof doc.id === 'string' ? doc.id : undefined\r\n}\r\n\r\nfunction getManualOrderDropValidation(args: {\r\n activeDoc: PageTreeDoc\r\n targetDoc?: PageTreeDoc\r\n}): PageTreeDropValidation {\r\n const { activeDoc, targetDoc } = args\r\n\r\n if (!targetDoc) {\r\n return {\r\n isValid: true,\r\n parentID: null,\r\n }\r\n }\r\n\r\n if (targetDoc.__pageTreeID === activeDoc.__pageTreeID) {\r\n return {\r\n isValid: false,\r\n message: CANCEL_DRAG_MESSAGE,\r\n parentID: targetDoc.__pageTreeID,\r\n }\r\n }\r\n\r\n if (targetDoc.__pageTreeAncestorIDs.includes(activeDoc.__pageTreeID)) {\r\n return {\r\n isValid: false,\r\n message: 'A document cannot be moved under one of its descendants.',\r\n parentID: targetDoc.__pageTreeID,\r\n }\r\n }\r\n\r\n return {\r\n isValid: true,\r\n parentID: targetDoc.__pageTreeID,\r\n }\r\n}\r\n\r\nfunction getDropValidationForMode(args: {\r\n activeDoc: PageTreeDoc\r\n allowSameParent: boolean\r\n targetDoc?: PageTreeDoc\r\n}): PageTreeDropValidation {\r\n const { activeDoc, allowSameParent, targetDoc } = args\r\n\r\n if (allowSameParent) {\r\n return getManualOrderDropValidation({\r\n activeDoc,\r\n targetDoc,\r\n })\r\n }\r\n\r\n return getDropValidation({\r\n activeDoc,\r\n targetDoc,\r\n })\r\n}\r\n\r\nfunction getCurrentOrderPlacement(args: {\r\n activeDoc: PageTreeDoc\r\n docs: PageTreeDoc[]\r\n}): PageTreeOrderPlacement {\r\n const { activeDoc, docs } = args\r\n const activeIndex = docs.findIndex((doc) => doc.__pageTreeID === activeDoc.__pageTreeID)\r\n const movingSubtreeIDs = new Set(\r\n docs\r\n .filter(\r\n (doc) =>\r\n doc.__pageTreeID === activeDoc.__pageTreeID ||\r\n doc.__pageTreeAncestorIDs.includes(activeDoc.__pageTreeID),\r\n )\r\n .map((doc) => doc.__pageTreeID),\r\n )\r\n const siblingIsNotMoving = (doc: PageTreeDoc) =>\r\n doc.__pageTreeParentID === activeDoc.__pageTreeParentID &&\r\n !movingSubtreeIDs.has(doc.__pageTreeID)\r\n\r\n if (activeIndex < 0) {\r\n return {\r\n nextSiblingID: null,\r\n parentID: activeDoc.__pageTreeParentID,\r\n previousSiblingID: null,\r\n }\r\n }\r\n\r\n return {\r\n nextSiblingID: docs.slice(activeIndex + 1).find(siblingIsNotMoving)?.__pageTreeID ?? null,\r\n parentID: activeDoc.__pageTreeParentID,\r\n previousSiblingID:\r\n docs.slice(0, activeIndex).filter(siblingIsNotMoving).at(-1)?.__pageTreeID ?? null,\r\n }\r\n}\r\n\r\nfunction orderPlacementHasChanged(\r\n currentPlacement: PageTreeOrderPlacement,\r\n nextPlacement: PageTreeOrderPlacement,\r\n): boolean {\r\n return (\r\n currentPlacement.parentID !== nextPlacement.parentID ||\r\n currentPlacement.previousSiblingID !== nextPlacement.previousSiblingID ||\r\n currentPlacement.nextSiblingID !== nextPlacement.nextSiblingID\r\n )\r\n}\r\n\r\nfunction getReorderTargetFromPlacement(args: {\r\n currentSort?: string\r\n docsByID: ReadonlyMap<string, PageTreeDoc>\r\n orderableFieldName: string\r\n placement: PageTreeOrderPlacement\r\n}): {\r\n newKeyWillBe: ReorderDirection\r\n targetDoc: PageTreeDoc\r\n} | null {\r\n const { currentSort, docsByID, orderableFieldName, placement } = args\r\n const targetDocID = placement.previousSiblingID ?? placement.nextSiblingID\r\n\r\n if (!targetDocID) {\r\n return null\r\n }\r\n\r\n const targetDoc = docsByID.get(targetDocID)\r\n\r\n if (!targetDoc) {\r\n return null\r\n }\r\n\r\n return {\r\n newKeyWillBe:\r\n (placement.previousSiblingID !== null && currentSort === orderableFieldName) ||\r\n (placement.previousSiblingID === null && currentSort === `-${orderableFieldName}`)\r\n ? 'greater'\r\n : 'less',\r\n targetDoc,\r\n }\r\n}\r\n\r\nfunction buildPaginatedData(\r\n docs: PageTreeDoc[],\r\n limit: number,\r\n requestedPage: number,\r\n): PaginatedDocs {\r\n const totalDocs = docs.length\r\n const totalPages = totalDocs > 0 ? Math.max(1, Math.ceil(totalDocs / limit)) : 1\r\n const page = Math.min(Math.max(requestedPage, 1), totalPages)\r\n const startIndex = (page - 1) * limit\r\n const pageDocs = docs.slice(startIndex, startIndex + limit)\r\n\r\n return {\r\n docs: pageDocs,\r\n hasNextPage: page < totalPages,\r\n hasPrevPage: page > 1,\r\n limit,\r\n nextPage: page < totalPages ? page + 1 : null,\r\n page,\r\n pagingCounter: totalDocs === 0 ? 0 : startIndex + 1,\r\n prevPage: page > 1 ? page - 1 : null,\r\n totalDocs,\r\n totalPages,\r\n }\r\n}\r\n\r\nfunction normalizeSort(value: string | string[] | undefined): string | undefined {\r\n if (Array.isArray(value)) {\r\n const sortValues = value.filter((entry) => typeof entry === 'string' && entry.length > 0)\r\n return sortValues.length > 0 ? sortValues.join(',') : undefined\r\n }\r\n\r\n return typeof value === 'string' && value.length > 0 ? value : undefined\r\n}\r\n\r\nfunction normalizePositiveInt(value: null | string, fallback: number): number {\r\n if (typeof value !== 'string') {\r\n return fallback\r\n }\r\n\r\n const parsedValue = Number.parseInt(value, 10)\r\n return Number.isNaN(parsedValue) || parsedValue <= 0 ? fallback : parsedValue\r\n}\r\n\r\nfunction normalizePageTreeColumnState(columnState: Column[], useAsTitle: string): Column[] {\r\n return columnState\r\n .filter((column) => column.accessor !== MANUAL_ORDER_COLUMN_ACCESSOR)\r\n .map((column) =>\r\n column.accessor === useAsTitle\r\n ? {\r\n ...column,\r\n active: true,\r\n }\r\n : column,\r\n )\r\n}\r\n\r\nfunction sliceColumnState(\r\n columnState: Column[],\r\n docs: PageTreeDoc[],\r\n renderedCellIndexByDocID: ReadonlyMap<string, number>,\r\n): Column[] {\r\n return columnState.map((column) => ({\r\n ...column,\r\n renderedCells: docs.map((doc) => {\r\n const renderedCellIndex =\r\n renderedCellIndexByDocID.get(doc.__pageTreeID) ?? doc.__pageTreeOrderIndex\r\n\r\n return column.renderedCells?.[renderedCellIndex] ?? null\r\n }),\r\n }))\r\n}\r\n\r\nfunction getSelectableRowData(doc: PageTreeDoc): SelectableRowData {\r\n const record = doc as Record<string, unknown>\r\n\r\n return {\r\n id: String(doc.id ?? doc.__pageTreeID),\r\n _isLocked: Boolean(record._isLocked),\r\n _userEditing: record._userEditing as SelectableRowData['_userEditing'],\r\n }\r\n}\r\n\r\nfunction shouldSilenceMoveMessage(message?: string): boolean {\r\n return typeof message === 'string' && SILENT_MOVE_MESSAGES.has(message)\r\n}\r\n\r\nfunction getStatusClassName(\r\n status: PageTreeDisplayStatus,\r\n): 'changed' | 'draft' | 'published' | 'unknown' {\r\n if (status === 'changed' || status === 'draft' || status === 'published') {\r\n return status\r\n }\r\n\r\n return 'unknown'\r\n}\r\n\r\nfunction renderStatusBadge(args: {\r\n badgeConfig: NestedDocsPageTreePluginResolvedBadgeConfig\r\n doc: PageTreeDoc\r\n index: number\r\n t: (key: 'general:noValue' | 'version:changed' | 'version:draft' | 'version:published') => string\r\n}): React.ReactNode {\r\n const { badgeConfig, doc, index, t } = args\r\n const status = getPageTreeDisplayStatus(doc)\r\n const customColor = getPageTreeBadgeColor({\r\n badgeColors: badgeConfig.colors,\r\n status,\r\n })\r\n const statusClass = getStatusClassName(status)\r\n const style = customColor\r\n ? ({ '--page-tree-badge-base': customColor } as React.CSSProperties)\r\n : undefined\r\n\r\n return (\r\n <span\r\n className={[\r\n 'pages-hierarchy-status-badge',\r\n `pages-hierarchy-status-badge--${statusClass}`,\r\n ].join(' ')}\r\n data-custom-color={customColor ? 'true' : undefined}\r\n key={doc.__pageTreeID ?? index}\r\n style={style}\r\n >\r\n {getPageTreeBadgeLabel({\r\n badgeLabels: badgeConfig.labels,\r\n status,\r\n t,\r\n })}\r\n </span>\r\n )\r\n}\r\n\r\nfunction createManualOrderColumn(docs: PageTreeDoc[]): Column {\r\n return {\r\n accessor: MANUAL_ORDER_COLUMN_ACCESSOR,\r\n active: true,\r\n field: { hidden: true } as Column['field'],\r\n Heading: <SortHeader />,\r\n renderedCells: docs.map(() => null),\r\n }\r\n}\r\n\r\nfunction insertManualOrderColumn(columns: Column[], orderColumn: Column): Column[] {\r\n const selectColumnIndex = columns.findIndex((column) => column.accessor === '_select')\r\n const insertIndex = selectColumnIndex >= 0 ? selectColumnIndex + 1 : 0\r\n\r\n return [\r\n ...columns.slice(0, insertIndex),\r\n orderColumn,\r\n ...columns.slice(insertIndex),\r\n ]\r\n}\r\n\r\nfunction buildTableColumns(args: {\r\n badgeConfig: NestedDocsPageTreePluginResolvedBadgeConfig\r\n columnState: Column[]\r\n docs: PageTreeDoc[]\r\n enableRowSelections?: boolean\r\n homeIndicatorEnabled: boolean\r\n orderableFieldName?: string\r\n parentFieldSlug: string\r\n t: (key: 'general:noValue' | 'version:changed' | 'version:draft' | 'version:published') => string\r\n useAsTitle: string\r\n}): Column[] {\r\n const {\r\n badgeConfig,\r\n columnState,\r\n docs,\r\n enableRowSelections,\r\n homeIndicatorEnabled,\r\n orderableFieldName,\r\n parentFieldSlug,\r\n t,\r\n useAsTitle,\r\n } = args\r\n const columnsToUse = columnState.map((column) => {\r\n if (column.accessor === useAsTitle) {\r\n return {\r\n ...column,\r\n active: true,\r\n renderedCells: docs.map((doc, index) => (\r\n <PageTreeTitleCell\r\n doc={doc}\r\n homeIndicatorEnabled={homeIndicatorEnabled}\r\n key={doc.__pageTreeID ?? index}\r\n >\r\n {column.renderedCells?.[index] ?? getDocDisplayLabel(doc)}\r\n </PageTreeTitleCell>\r\n )),\r\n }\r\n }\r\n\r\n if (column.accessor === '_status') {\r\n return {\r\n ...column,\r\n renderedCells: docs.map((doc, index) =>\r\n renderStatusBadge({\r\n badgeConfig,\r\n doc,\r\n index,\r\n t,\r\n }),\r\n ),\r\n }\r\n }\r\n\r\n if (column.accessor === parentFieldSlug) {\r\n return {\r\n ...column,\r\n renderedCells: docs.map((doc, index) =>\r\n doc.__pageTreeParentID !== null ? (\r\n column.renderedCells?.[index] ?? null\r\n ) : (\r\n <span className=\"pages-hierarchy-empty-cell\" key={doc.__pageTreeID ?? index}>\r\n -\r\n </span>\r\n ),\r\n ),\r\n }\r\n }\r\n\r\n return column\r\n })\r\n\r\n if (enableRowSelections) {\r\n columnsToUse.unshift({\r\n accessor: '_select',\r\n active: true,\r\n field: { hidden: true } as Column['field'],\r\n Heading: <SelectAll />,\r\n renderedCells: docs.map((doc, index) => (\r\n <SelectRow key={doc.__pageTreeID ?? index} rowData={getSelectableRowData(doc)} />\r\n )),\r\n })\r\n }\r\n\r\n if (\r\n orderableFieldName &&\r\n !columnsToUse.some((column) => column.accessor === MANUAL_ORDER_COLUMN_ACCESSOR)\r\n ) {\r\n return insertManualOrderColumn(columnsToUse, createManualOrderColumn(docs))\r\n }\r\n\r\n return columnsToUse\r\n}\r\n\r\nfunction HierarchyInsertRow({\r\n activeColumnsCount,\r\n activeDragRowID,\r\n dropTarget,\r\n dropValidation,\r\n isMovePending,\r\n}: {\r\n activeColumnsCount: number\r\n activeDragRowID: null | string\r\n dropTarget: Extract<PageTreeDropTarget, { dropType: 'insert' }>\r\n dropValidation?: PageTreeDropValidation\r\n isMovePending: boolean\r\n}) {\r\n const { isOver, setNodeRef } = useDroppable({\r\n id: dropTarget.dropID,\r\n data: dropTarget,\r\n disabled: isMovePending,\r\n })\r\n const hasActiveDrag = Boolean(activeDragRowID)\r\n\r\n return (\r\n <tr\r\n className=\"pages-hierarchy-insert-row\"\r\n data-drag-over={isOver ? 'true' : 'false'}\r\n data-drop-valid={hasActiveDrag ? (dropValidation?.isValid ? 'true' : 'false') : undefined}\r\n data-page-tree-insert=\"true\"\r\n >\r\n <td colSpan={activeColumnsCount}>\r\n <div\r\n className=\"pages-hierarchy-insert-row__target\"\r\n data-insert-depth={dropTarget.depth}\r\n ref={setNodeRef}\r\n />\r\n </td>\r\n </tr>\r\n )\r\n}\r\n\r\nfunction HierarchyTableRow({\r\n activeColumns,\r\n activeDragRowID,\r\n doc,\r\n dropValidation,\r\n insertAfterDropID,\r\n insertBeforeDropID,\r\n isMovePending,\r\n rowIndex,\r\n titleCellAccessor,\r\n}: {\r\n activeColumns: Column[]\r\n activeDragRowID: null | string\r\n doc: PageTreeDoc\r\n dropValidation?: PageTreeDropValidation\r\n insertAfterDropID: string\r\n insertBeforeDropID: string\r\n isMovePending: boolean\r\n rowIndex: number\r\n titleCellAccessor: string\r\n}) {\r\n const { isOver, setNodeRef } = useDroppable({\r\n id: getRowDropID(doc.__pageTreeID),\r\n data: {\r\n dropType: 'row',\r\n insertAfterDropID,\r\n insertBeforeDropID,\r\n rowID: doc.__pageTreeID,\r\n } satisfies Extract<PageTreeDropTarget, { dropType: 'row' }>,\r\n disabled: isMovePending,\r\n })\r\n const hasActiveDrag = Boolean(activeDragRowID)\r\n const isActiveDragRow = activeDragRowID === doc.__pageTreeID\r\n\r\n return (\r\n <tr\r\n className={`row-${rowIndex + 1}`}\r\n data-drag-over={isOver ? 'true' : 'false'}\r\n data-drop-valid={hasActiveDrag ? (dropValidation?.isValid ? 'true' : 'false') : undefined}\r\n data-id={doc.id}\r\n data-is-drag-source={isActiveDragRow ? 'true' : 'false'}\r\n data-page-tree-row=\"true\"\r\n ref={setNodeRef}\r\n >\r\n {activeColumns.map((column, columnIndex) => {\r\n const { accessor } = column\r\n\r\n return (\r\n <td\r\n className={`cell-${accessor.replace(/\\./g, '__')}`}\r\n data-page-tree-manual-order-cell={\r\n accessor === MANUAL_ORDER_COLUMN_ACCESSOR ? 'true' : undefined\r\n }\r\n data-page-tree-title-cell={accessor === titleCellAccessor ? 'true' : undefined}\r\n key={columnIndex}\r\n >\r\n {column.renderedCells?.[rowIndex] ?? null}\r\n </td>\r\n )\r\n })}\r\n </tr>\r\n )\r\n}\r\n\r\nfunction HierarchyTable({\r\n activeDragRowID,\r\n allDocsByID,\r\n allowSameParentDrops,\r\n columns,\r\n data,\r\n isMovePending,\r\n titleCellAccessor,\r\n}: {\r\n activeDragRowID: null | string\r\n allDocsByID: ReadonlyMap<string, PageTreeDoc>\r\n allowSameParentDrops: boolean\r\n columns: Column[]\r\n data: PageTreeDoc[]\r\n isMovePending: boolean\r\n titleCellAccessor: string\r\n}) {\r\n const activeColumns = React.useMemo(\r\n () => columns.filter((column) => column?.active),\r\n [columns],\r\n )\r\n const hasManualOrderColumn = React.useMemo(\r\n () => activeColumns.some((column) => column.accessor === MANUAL_ORDER_COLUMN_ACCESSOR),\r\n [activeColumns],\r\n )\r\n const insertDropTargets = React.useMemo(() => buildInsertDropTargets(data), [data])\r\n const activeDoc = activeDragRowID ? allDocsByID.get(activeDragRowID) ?? null : null\r\n const rowDropValidationByID = React.useMemo(() => {\r\n if (!activeDoc) {\r\n return new Map<string, PageTreeDropValidation>()\r\n }\r\n\r\n return new Map(\r\n data.map((doc) => [\r\n doc.__pageTreeID,\r\n getDropValidationForMode({\r\n activeDoc,\r\n allowSameParent: allowSameParentDrops,\r\n targetDoc: doc,\r\n }),\r\n ]),\r\n )\r\n }, [activeDoc, allowSameParentDrops, data])\r\n const insertDropValidationByID = React.useMemo(() => {\r\n if (!activeDoc) {\r\n return new Map<string, PageTreeDropValidation>()\r\n }\r\n\r\n return new Map(\r\n insertDropTargets.map((dropTarget) => [\r\n dropTarget.dropID,\r\n getDropValidationForMode({\r\n activeDoc,\r\n allowSameParent: allowSameParentDrops,\r\n targetDoc:\r\n dropTarget.parentID === null\r\n ? undefined\r\n : allDocsByID.get(dropTarget.parentID) ?? undefined,\r\n }),\r\n ]),\r\n )\r\n }, [activeDoc, allowSameParentDrops, allDocsByID, insertDropTargets])\r\n\r\n if (activeColumns.length === 0) {\r\n return <div>No columns selected</div>\r\n }\r\n\r\n return (\r\n <div\r\n className={[\r\n 'table-wrap pages-hierarchy-table',\r\n activeDoc ? 'pages-hierarchy-table--dragging' : '',\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n data-page-tree-orderable={hasManualOrderColumn ? 'true' : undefined}\r\n >\r\n <div className=\"table table--appearance-default\">\r\n <table cellPadding=\"0\" cellSpacing=\"0\">\r\n <thead>\r\n <tr>\r\n {activeColumns.map((column, index) => (\r\n <th\r\n data-page-tree-manual-order-cell={\r\n column.accessor === MANUAL_ORDER_COLUMN_ACCESSOR ? 'true' : undefined\r\n }\r\n data-page-tree-title-cell={\r\n column.accessor === titleCellAccessor ? 'true' : undefined\r\n }\r\n id={`heading-${column.accessor.replace(/\\./g, '__')}`}\r\n key={index}\r\n >\r\n {column.Heading}\r\n </th>\r\n ))}\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {insertDropTargets[0] ? (\r\n <HierarchyInsertRow\r\n activeColumnsCount={activeColumns.length}\r\n activeDragRowID={activeDragRowID}\r\n dropTarget={insertDropTargets[0]}\r\n dropValidation={insertDropValidationByID.get(insertDropTargets[0].dropID)}\r\n isMovePending={isMovePending}\r\n key={insertDropTargets[0].dropID}\r\n />\r\n ) : null}\r\n {data.map((doc, rowIndex) => (\r\n <React.Fragment key={doc.__pageTreeID}>\r\n <HierarchyTableRow\r\n activeColumns={activeColumns}\r\n activeDragRowID={activeDragRowID}\r\n doc={doc}\r\n dropValidation={rowDropValidationByID.get(doc.__pageTreeID)}\r\n insertAfterDropID={insertDropTargets[rowIndex + 1].dropID}\r\n insertBeforeDropID={insertDropTargets[rowIndex].dropID}\r\n isMovePending={isMovePending}\r\n rowIndex={rowIndex}\r\n titleCellAccessor={titleCellAccessor}\r\n />\r\n {insertDropTargets[rowIndex + 1] ? (\r\n <HierarchyInsertRow\r\n activeColumnsCount={activeColumns.length}\r\n activeDragRowID={activeDragRowID}\r\n dropTarget={insertDropTargets[rowIndex + 1]}\r\n dropValidation={insertDropValidationByID.get(\r\n insertDropTargets[rowIndex + 1].dropID,\r\n )}\r\n isMovePending={isMovePending}\r\n key={insertDropTargets[rowIndex + 1].dropID}\r\n />\r\n ) : null}\r\n </React.Fragment>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nexport default function PageTreeListViewClient({\r\n allDocs,\r\n badgeConfig,\r\n canMoveDocs,\r\n columnState,\r\n homeIndicatorEnabled,\r\n orderableFieldName,\r\n parentFieldSlug,\r\n query,\r\n sourceDocs,\r\n useAsTitle,\r\n ...props\r\n}: PageTreeListViewClientProps) {\r\n const router = useRouter()\r\n const searchParams = useSearchParams()\r\n const { config } = useConfig()\r\n const locale = useLocale()\r\n const { i18n } = useTranslation()\r\n const [activeDragRowID, setActiveDragRowID] = React.useState<null | string>(null)\r\n const [activeDropTarget, setActiveDropTarget] = React.useState<null | PageTreeDropTarget>(null)\r\n const [collapsedIDs, setCollapsedIDs] = React.useState<Set<string>>(() => new Set())\r\n const [localSourceDocs, setLocalSourceDocs] = React.useState(sourceDocs)\r\n const [pendingMoveRowID, setPendingMoveRowID] = React.useState<null | string>(null)\r\n\r\n React.useEffect(() => {\r\n setLocalSourceDocs(sourceDocs)\r\n }, [sourceDocs])\r\n\r\n const toggleRow = React.useCallback((rowID: string) => {\r\n setCollapsedIDs((currentState) => {\r\n const nextState = new Set(currentState)\r\n\r\n if (nextState.has(rowID)) {\r\n nextState.delete(rowID)\r\n } else {\r\n nextState.add(rowID)\r\n }\r\n\r\n return nextState\r\n })\r\n }, [])\r\n const currentSort = React.useMemo(() => {\r\n const searchParamSort = searchParams.getAll('sort')\r\n\r\n if (searchParamSort.length > 0) {\r\n return normalizeSort(searchParamSort)\r\n }\r\n\r\n return normalizeSort(query.sort as string | string[] | undefined)\r\n }, [query.sort, searchParams])\r\n const manualOrderIsActive = Boolean(\r\n orderableFieldName &&\r\n (currentSort === orderableFieldName || currentSort === `-${orderableFieldName}`),\r\n )\r\n const currentLimit = React.useMemo(\r\n () =>\r\n normalizePositiveInt(\r\n searchParams.get('limit'),\r\n typeof query.limit === 'number' && query.limit > 0 ? query.limit : 10,\r\n ),\r\n [query.limit, searchParams],\r\n )\r\n const currentRequestedPage = React.useMemo(\r\n () =>\r\n normalizePositiveInt(\r\n searchParams.get('page'),\r\n typeof query.page === 'number' && query.page > 0 ? query.page : 1,\r\n ),\r\n [query.page, searchParams],\r\n )\r\n const liveAllDocs = React.useMemo(\r\n () =>\r\n buildPageTreeDocs(localSourceDocs, {\r\n parentFieldSlug,\r\n sort: currentSort,\r\n }),\r\n [currentSort, localSourceDocs, parentFieldSlug],\r\n )\r\n const collapseResetKey = React.useMemo(\r\n () => JSON.stringify([props.collectionSlug, props.viewType, searchParams.toString()]),\r\n [props.collectionSlug, props.viewType, searchParams],\r\n )\r\n const hierarchyValue = React.useMemo(\r\n () => ({\r\n activeDragRowID,\r\n canMoveDocs,\r\n collapsedIDs,\r\n pendingMoveRowID,\r\n toggleRow,\r\n }),\r\n [activeDragRowID, canMoveDocs, collapsedIDs, pendingMoveRowID, toggleRow],\r\n )\r\n\r\n React.useEffect(() => {\r\n setActiveDragRowID(null)\r\n setActiveDropTarget(null)\r\n setCollapsedIDs(new Set())\r\n }, [collapseResetKey])\r\n\r\n const visibleDocs = React.useMemo(\r\n () => getVisibleTreeDocs(liveAllDocs, collapsedIDs),\r\n [liveAllDocs, collapsedIDs],\r\n )\r\n const paginatedData = React.useMemo(\r\n () => buildPaginatedData(visibleDocs, currentLimit, currentRequestedPage),\r\n [currentLimit, currentRequestedPage, visibleDocs],\r\n )\r\n const paginatedDocs = paginatedData.docs as PageTreeDoc[]\r\n const allDocsByID = React.useMemo(\r\n () => new Map(liveAllDocs.map((doc) => [doc.__pageTreeID, doc])),\r\n [liveAllDocs],\r\n )\r\n const paginatedDocsByID = React.useMemo(\r\n () => new Map(paginatedDocs.map((doc) => [doc.__pageTreeID, doc])),\r\n [paginatedDocs],\r\n )\r\n const renderedCellIndexByDocID = React.useMemo(\r\n () => new Map(allDocs.map((doc, index) => [doc.__pageTreeID, index])),\r\n [allDocs],\r\n )\r\n const normalizedColumnState = React.useMemo(\r\n () => normalizePageTreeColumnState(columnState, useAsTitle),\r\n [columnState, useAsTitle],\r\n )\r\n const paginatedColumnState = React.useMemo(\r\n () => sliceColumnState(normalizedColumnState, paginatedDocs, renderedCellIndexByDocID),\r\n [normalizedColumnState, paginatedDocs, renderedCellIndexByDocID],\r\n )\r\n const tableColumns = React.useMemo(\r\n () =>\r\n buildTableColumns({\r\n badgeConfig,\r\n columnState: paginatedColumnState,\r\n docs: paginatedDocs,\r\n enableRowSelections: props.enableRowSelections,\r\n homeIndicatorEnabled,\r\n orderableFieldName,\r\n parentFieldSlug,\r\n t: i18n.t,\r\n useAsTitle,\r\n }),\r\n [\r\n paginatedColumnState,\r\n paginatedDocs,\r\n badgeConfig,\r\n homeIndicatorEnabled,\r\n orderableFieldName,\r\n parentFieldSlug,\r\n props.enableRowSelections,\r\n i18n.t,\r\n useAsTitle,\r\n ],\r\n )\r\n const activeDragDoc = activeDragRowID ? paginatedDocsByID.get(activeDragRowID) ?? null : null\r\n const activeDragPreviewPath = React.useMemo(() => {\r\n if (!activeDragDoc) {\r\n return null\r\n }\r\n\r\n if (!activeDropTarget) {\r\n return buildDocSlugPath({\r\n doc: activeDragDoc,\r\n docsByID: allDocsByID,\r\n })\r\n }\r\n\r\n const targetDoc = getDropTargetParentDoc({\r\n docsByID: allDocsByID,\r\n dropTarget: activeDropTarget,\r\n })\r\n const dropValidation = getDropValidationForMode({\r\n activeDoc: activeDragDoc,\r\n allowSameParent: manualOrderIsActive,\r\n targetDoc: targetDoc ?? undefined,\r\n })\r\n\r\n if (!dropValidation.isValid) {\r\n return buildDocSlugPath({\r\n doc: activeDragDoc,\r\n docsByID: allDocsByID,\r\n })\r\n }\r\n\r\n return buildProspectiveDocSlugPath({\r\n activeDoc: activeDragDoc,\r\n docsByID: allDocsByID,\r\n targetDoc: targetDoc ?? undefined,\r\n })\r\n }, [activeDragDoc, activeDropTarget, allDocsByID, manualOrderIsActive])\r\n const isMovePending = pendingMoveRowID !== null\r\n const sensors = useSensors(\r\n useSensor(PointerSensor, {\r\n activationConstraint: {\r\n distance: 4,\r\n },\r\n }),\r\n )\r\n const moveDocument = React.useCallback(\r\n async (args: { parentID: null | string; rowID: string }) => {\r\n const { parentID, rowID } = args\r\n const params = new URLSearchParams()\r\n\r\n if (locale?.code) {\r\n params.set('locale', locale.code)\r\n }\r\n\r\n const response = await fetch(\r\n `${config.routes.api}/${props.collectionSlug}/${encodeURIComponent(rowID)}/move${\r\n params.size > 0 ? `?${params.toString()}` : ''\r\n }`,\r\n {\r\n body: JSON.stringify({\r\n parentID,\r\n }),\r\n credentials: 'include',\r\n headers: {\r\n 'Accept-Language': i18n.language,\r\n 'Content-Type': 'application/json',\r\n },\r\n method: 'POST',\r\n },\r\n )\r\n const result = (await response.json().catch(() => null)) as\r\n | {\r\n message?: string\r\n }\r\n | null\r\n\r\n if (!response.ok) {\r\n throw new Error(result?.message ?? 'Could not move document.')\r\n }\r\n\r\n return result\r\n },\r\n [config.routes.api, i18n.language, locale?.code, props.collectionSlug],\r\n )\r\n const reorderDocument = React.useCallback(\r\n async (args: {\r\n movedDocID: number | string\r\n newKeyWillBe: ReorderDirection\r\n targetDoc: PageTreeDoc\r\n }) => {\r\n const { movedDocID, newKeyWillBe, targetDoc } = args\r\n const targetID = getPayloadDocID(targetDoc)\r\n\r\n if (!orderableFieldName || targetID === undefined) {\r\n return undefined\r\n }\r\n\r\n const params = new URLSearchParams()\r\n\r\n if (locale?.code) {\r\n params.set('locale', locale.code)\r\n }\r\n\r\n const response = await fetch(\r\n `${config.routes.api}/reorder${params.size > 0 ? `?${params.toString()}` : ''}`,\r\n {\r\n body: JSON.stringify({\r\n collectionSlug: props.collectionSlug,\r\n docsToMove: [movedDocID],\r\n newKeyWillBe,\r\n orderableFieldName,\r\n target: {\r\n id: targetID,\r\n key: targetDoc[orderableFieldName],\r\n },\r\n }),\r\n credentials: 'include',\r\n headers: {\r\n 'Accept-Language': i18n.language,\r\n 'Content-Type': 'application/json',\r\n },\r\n method: 'POST',\r\n },\r\n )\r\n const result = (await response.json().catch(() => null)) as\r\n | {\r\n message?: string\r\n orderValues?: unknown[]\r\n }\r\n | null\r\n\r\n if (response.status === 403) {\r\n throw new Error('You do not have permission to reorder these rows')\r\n }\r\n\r\n if (!response.ok) {\r\n throw new Error(\r\n 'Failed to reorder. This can happen if you reorder several rows too quickly. Please try again.',\r\n )\r\n }\r\n\r\n if (result?.message === 'initial migration') {\r\n throw new Error(\r\n 'You have enabled \"orderable\" on a collection with existing documents and this is the first time you have sorted documents. We have run an automatic migration to add an initial order to the documents. Please refresh the page and try again.',\r\n )\r\n }\r\n\r\n return result?.orderValues?.[0]\r\n },\r\n [\r\n config.routes.api,\r\n i18n.language,\r\n locale?.code,\r\n orderableFieldName,\r\n props.collectionSlug,\r\n ],\r\n )\r\n const handleManualOrderMoveEnd = React.useCallback(\r\n async (args: {\r\n activeDoc: PageTreeDoc\r\n dropTarget: PageTreeDropTarget\r\n rowID: string\r\n }) => {\r\n const { activeDoc, dropTarget, rowID } = args\r\n\r\n if (!orderableFieldName) {\r\n return\r\n }\r\n\r\n const targetDoc = getDropTargetParentDoc({\r\n docsByID: allDocsByID,\r\n dropTarget,\r\n })\r\n const dropValidation = getManualOrderDropValidation({\r\n activeDoc,\r\n targetDoc: targetDoc ?? undefined,\r\n })\r\n\r\n if (!dropValidation.isValid) {\r\n if (!shouldSilenceMoveMessage(dropValidation.message)) {\r\n toast.error(dropValidation.message ?? 'Could not move document.')\r\n }\r\n\r\n return\r\n }\r\n\r\n const placement = getOrderPlacementFromDropTarget({\r\n activeDoc,\r\n docs: paginatedDocs,\r\n docsByID: allDocsByID,\r\n dropTarget,\r\n })\r\n\r\n if (!placement) {\r\n return\r\n }\r\n\r\n const currentPlacement = getCurrentOrderPlacement({\r\n activeDoc,\r\n docs: paginatedDocs,\r\n })\r\n const parentChanged = activeDoc.__pageTreeParentID !== placement.parentID\r\n const orderChanged = orderPlacementHasChanged(currentPlacement, placement)\r\n const reorderTarget = orderChanged\r\n ? getReorderTargetFromPlacement({\r\n currentSort,\r\n docsByID: allDocsByID,\r\n orderableFieldName,\r\n placement,\r\n })\r\n : null\r\n\r\n if (!parentChanged && !reorderTarget) {\r\n return\r\n }\r\n\r\n const movedDocID = getPayloadDocID(activeDoc)\r\n\r\n if (movedDocID === undefined) {\r\n return\r\n }\r\n\r\n const parentDoc = placement.parentID ? allDocsByID.get(placement.parentID) : undefined\r\n const nextParentValue =\r\n placement.parentID === null\r\n ? null\r\n : parentDoc\r\n ? getPayloadDocID(parentDoc) ?? placement.parentID\r\n : placement.parentID\r\n let parentMoveSucceeded = false\r\n\r\n setPendingMoveRowID(rowID)\r\n\r\n try {\r\n if (parentChanged) {\r\n await moveDocument({\r\n parentID: placement.parentID,\r\n rowID,\r\n })\r\n parentMoveSucceeded = true\r\n }\r\n\r\n const nextOrderValue = reorderTarget\r\n ? await reorderDocument({\r\n movedDocID,\r\n newKeyWillBe: reorderTarget.newKeyWillBe,\r\n targetDoc: reorderTarget.targetDoc,\r\n })\r\n : undefined\r\n\r\n if (parentChanged || typeof nextOrderValue === 'string') {\r\n setLocalSourceDocs((currentDocs) =>\r\n currentDocs.map((doc) =>\r\n String(doc.id ?? '') === String(movedDocID)\r\n ? {\r\n ...doc,\r\n ...(parentChanged\r\n ? {\r\n [parentFieldSlug]: nextParentValue,\r\n }\r\n : {}),\r\n ...(typeof nextOrderValue === 'string'\r\n ? {\r\n [orderableFieldName]: nextOrderValue,\r\n }\r\n : {}),\r\n }\r\n : doc,\r\n ),\r\n )\r\n }\r\n\r\n if (parentChanged) {\r\n toast.success(`Moved \"${getDocDisplayLabel(activeDoc)}\".`)\r\n }\r\n\r\n React.startTransition(() => {\r\n router.refresh()\r\n })\r\n } catch (error) {\r\n const message =\r\n error instanceof Error && error.message ? error.message : 'Could not move document.'\r\n\r\n toast.error(\r\n parentMoveSucceeded\r\n ? `Moved \"${getDocDisplayLabel(activeDoc)}\", but could not update its manual order. ${message}`\r\n : message,\r\n )\r\n\r\n if (parentMoveSucceeded) {\r\n React.startTransition(() => {\r\n router.refresh()\r\n })\r\n }\r\n } finally {\r\n setPendingMoveRowID(null)\r\n }\r\n },\r\n [\r\n allDocsByID,\r\n currentSort,\r\n moveDocument,\r\n orderableFieldName,\r\n paginatedDocs,\r\n parentFieldSlug,\r\n reorderDocument,\r\n router,\r\n ],\r\n )\r\n const handleDragCancel = React.useCallback(() => {\r\n setActiveDragRowID(null)\r\n setActiveDropTarget(null)\r\n }, [])\r\n const handleDragStart = React.useCallback(\r\n (event: DragStartEvent) => {\r\n const dragData = getPageTreeDragData(event.active.data.current)\r\n\r\n if (!canMoveDocs || isMovePending) {\r\n return\r\n }\r\n\r\n const rowID = dragData.rowID\r\n\r\n if (typeof rowID === 'string' && paginatedDocsByID.has(rowID)) {\r\n setActiveDragRowID(rowID)\r\n setActiveDropTarget(null)\r\n }\r\n },\r\n [canMoveDocs, isMovePending, paginatedDocsByID],\r\n )\r\n const handleDragOver = React.useCallback((event: DragOverEvent) => {\r\n const overData = event.over?.data.current as PageTreeDropTarget | undefined\r\n\r\n if (!overData) {\r\n setActiveDropTarget(null)\r\n return\r\n }\r\n\r\n if (overData.dropType === 'insert') {\r\n setActiveDropTarget(overData)\r\n return\r\n }\r\n\r\n if (overData.dropType === 'row') {\r\n setActiveDropTarget(overData)\r\n return\r\n }\r\n\r\n setActiveDropTarget(null)\r\n }, [])\r\n const handleDragEnd = React.useCallback(\r\n async (event: DragEndEvent) => {\r\n const dragData = getPageTreeDragData(event.active.data.current)\r\n\r\n const rowID = dragData.rowID\r\n const activeDoc = typeof rowID === 'string' ? paginatedDocsByID.get(rowID) ?? null : null\r\n const overData = event.over?.data.current as PageTreeDropTarget | undefined\r\n\r\n setActiveDragRowID(null)\r\n setActiveDropTarget(null)\r\n\r\n if (!rowID || !activeDoc || !overData) {\r\n return\r\n }\r\n\r\n if (manualOrderIsActive && orderableFieldName) {\r\n await handleManualOrderMoveEnd({\r\n activeDoc,\r\n dropTarget: overData,\r\n rowID,\r\n })\r\n return\r\n }\r\n\r\n const targetDoc = getDropTargetParentDoc({\r\n docsByID: allDocsByID,\r\n dropTarget: overData,\r\n })\r\n const dropValidation = getDropValidation({\r\n activeDoc,\r\n targetDoc: targetDoc ?? undefined,\r\n })\r\n\r\n if (!dropValidation.isValid) {\r\n if (!shouldSilenceMoveMessage(dropValidation.message)) {\r\n toast.error(dropValidation.message ?? 'Could not move document.')\r\n }\r\n\r\n return\r\n }\r\n\r\n setPendingMoveRowID(rowID)\r\n\r\n try {\r\n await moveDocument({\r\n parentID: dropValidation.parentID,\r\n rowID,\r\n })\r\n\r\n toast.success(`Moved \"${getDocDisplayLabel(activeDoc)}\".`)\r\n React.startTransition(() => {\r\n router.refresh()\r\n })\r\n } catch (error) {\r\n const message =\r\n error instanceof Error && error.message ? error.message : 'Could not move document.'\r\n\r\n if (shouldSilenceMoveMessage(message)) {\r\n return\r\n }\r\n\r\n toast.error(message)\r\n } finally {\r\n setPendingMoveRowID(null)\r\n }\r\n },\r\n [\r\n allDocsByID,\r\n handleManualOrderMoveEnd,\r\n manualOrderIsActive,\r\n moveDocument,\r\n orderableFieldName,\r\n paginatedDocsByID,\r\n router,\r\n ],\r\n )\r\n const handleDragEndSync = React.useCallback(\r\n (event: DragEndEvent) => {\r\n void handleDragEnd(event)\r\n },\r\n [handleDragEnd],\r\n )\r\n\r\n const tableNode = React.useMemo(\r\n () => (\r\n <DndContext\r\n collisionDetection={pageTreeCollisionDetectionStrategy}\r\n onDragCancel={handleDragCancel}\r\n onDragEnd={handleDragEndSync}\r\n onDragOver={handleDragOver}\r\n onDragStart={handleDragStart}\r\n sensors={sensors}\r\n >\r\n <HierarchyTable\r\n activeDragRowID={activeDragRowID}\r\n allDocsByID={allDocsByID}\r\n allowSameParentDrops={manualOrderIsActive}\r\n columns={tableColumns}\r\n data={paginatedDocs}\r\n isMovePending={isMovePending}\r\n titleCellAccessor={useAsTitle}\r\n />\r\n <DragOverlay dropAnimation={null} style={{ cursor: 'grabbing' }}>\r\n {activeDragPreviewPath ? (\r\n <div className=\"pages-hierarchy-drag-overlay\">{activeDragPreviewPath}</div>\r\n ) : null}\r\n </DragOverlay>\r\n </DndContext>\r\n ),\r\n [\r\n activeDragPreviewPath,\r\n activeDragRowID,\r\n handleDragCancel,\r\n handleDragEndSync,\r\n handleDragOver,\r\n handleDragStart,\r\n isMovePending,\r\n allDocsByID,\r\n manualOrderIsActive,\r\n paginatedDocs,\r\n sensors,\r\n tableColumns,\r\n useAsTitle,\r\n ],\r\n )\r\n\r\n return (\r\n <div className={styles.root}>\r\n <PageTreeProvider value={hierarchyValue}>\r\n <ListQueryProvider\r\n collectionSlug={props.collectionSlug}\r\n data={paginatedData}\r\n modifySearchParams\r\n orderableFieldName={orderableFieldName}\r\n query={{\r\n ...query,\r\n limit: currentLimit,\r\n page: paginatedData.page,\r\n sort: currentSort,\r\n }}\r\n >\r\n <DefaultListView {...props} columnState={paginatedColumnState} Table={tableNode} />\r\n </ListQueryProvider>\r\n </PageTreeProvider>\r\n </div>\r\n )\r\n}\r\n"],"names":["DndContext","DragOverlay","PointerSensor","useDroppable","useSensor","useSensors","DefaultListView","ListQueryProvider","SelectAll","SelectRow","SortHeader","toast","useConfig","useLocale","useTranslation","useRouter","useSearchParams","React","buildInsertDropTargets","getDropTargetParentDoc","getOrderPlacementFromDropTarget","CANCEL_DRAG_MESSAGE","getDropValidation","buildDocSlugPath","buildPageTreeDocs","buildProspectiveDocSlugPath","getDocDisplayLabel","getVisibleTreeDocs","pageTreeCollisionDetectionStrategy","getPageTreeBadgeColor","getPageTreeBadgeLabel","getPageTreeDisplayStatus","PageTreeProvider","styles","PageTreeTitleCell","MANUAL_ORDER_COLUMN_ACCESSOR","SILENT_MOVE_MESSAGES","Set","getRowDropID","rowID","getPageTreeDragData","value","getPayloadDocID","doc","id","undefined","getManualOrderDropValidation","args","activeDoc","targetDoc","isValid","parentID","__pageTreeID","message","__pageTreeAncestorIDs","includes","getDropValidationForMode","allowSameParent","getCurrentOrderPlacement","docs","activeIndex","findIndex","movingSubtreeIDs","filter","map","siblingIsNotMoving","__pageTreeParentID","has","nextSiblingID","previousSiblingID","slice","find","at","orderPlacementHasChanged","currentPlacement","nextPlacement","getReorderTargetFromPlacement","currentSort","docsByID","orderableFieldName","placement","targetDocID","get","newKeyWillBe","buildPaginatedData","limit","requestedPage","totalDocs","length","totalPages","Math","max","ceil","page","min","startIndex","pageDocs","hasNextPage","hasPrevPage","nextPage","pagingCounter","prevPage","normalizeSort","Array","isArray","sortValues","entry","join","normalizePositiveInt","fallback","parsedValue","Number","parseInt","isNaN","normalizePageTreeColumnState","columnState","useAsTitle","column","accessor","active","sliceColumnState","renderedCellIndexByDocID","renderedCells","renderedCellIndex","__pageTreeOrderIndex","getSelectableRowData","record","String","_isLocked","Boolean","_userEditing","shouldSilenceMoveMessage","getStatusClassName","status","renderStatusBadge","badgeConfig","index","t","customColor","badgeColors","colors","statusClass","style","span","className","data-custom-color","badgeLabels","labels","createManualOrderColumn","field","hidden","Heading","insertManualOrderColumn","columns","orderColumn","selectColumnIndex","insertIndex","buildTableColumns","enableRowSelections","homeIndicatorEnabled","parentFieldSlug","columnsToUse","unshift","rowData","some","HierarchyInsertRow","activeColumnsCount","activeDragRowID","dropTarget","dropValidation","isMovePending","isOver","setNodeRef","dropID","data","disabled","hasActiveDrag","tr","data-drag-over","data-drop-valid","data-page-tree-insert","td","colSpan","div","data-insert-depth","depth","ref","HierarchyTableRow","activeColumns","insertAfterDropID","insertBeforeDropID","rowIndex","titleCellAccessor","dropType","isActiveDragRow","data-id","data-is-drag-source","data-page-tree-row","columnIndex","replace","data-page-tree-manual-order-cell","data-page-tree-title-cell","HierarchyTable","allDocsByID","allowSameParentDrops","useMemo","hasManualOrderColumn","insertDropTargets","rowDropValidationByID","Map","insertDropValidationByID","data-page-tree-orderable","table","cellPadding","cellSpacing","thead","th","tbody","Fragment","PageTreeListViewClient","allDocs","canMoveDocs","query","sourceDocs","props","router","searchParams","config","locale","i18n","setActiveDragRowID","useState","activeDropTarget","setActiveDropTarget","collapsedIDs","setCollapsedIDs","localSourceDocs","setLocalSourceDocs","pendingMoveRowID","setPendingMoveRowID","useEffect","toggleRow","useCallback","currentState","nextState","delete","add","searchParamSort","getAll","sort","manualOrderIsActive","currentLimit","currentRequestedPage","liveAllDocs","collapseResetKey","JSON","stringify","collectionSlug","viewType","toString","hierarchyValue","visibleDocs","paginatedData","paginatedDocs","paginatedDocsByID","normalizedColumnState","paginatedColumnState","tableColumns","activeDragDoc","activeDragPreviewPath","sensors","activationConstraint","distance","moveDocument","params","URLSearchParams","code","set","response","fetch","routes","api","encodeURIComponent","size","body","credentials","headers","language","method","result","json","catch","ok","Error","reorderDocument","movedDocID","targetID","docsToMove","target","key","orderValues","handleManualOrderMoveEnd","error","parentChanged","orderChanged","reorderTarget","parentDoc","nextParentValue","parentMoveSucceeded","nextOrderValue","currentDocs","success","startTransition","refresh","handleDragCancel","handleDragStart","event","dragData","current","handleDragOver","overData","over","handleDragEnd","handleDragEndSync","tableNode","collisionDetection","onDragCancel","onDragEnd","onDragOver","onDragStart","dropAnimation","cursor","root","modifySearchParams","Table"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/components/PageTreeListView.client.tsx"],"sourcesContent":["'use client'\r\n\r\nimport type { Column, ListQuery, ListViewClientProps, PaginatedDocs } from 'payload'\r\n\r\nimport {\r\n DndContext,\r\n type DragEndEvent,\r\n type DragOverEvent,\r\n DragOverlay,\r\n type DragStartEvent,\r\n PointerSensor,\r\n useDroppable,\r\n useSensor,\r\n useSensors,\r\n} from '@dnd-kit/core'\r\nimport {\r\n DefaultListView,\n ListQueryProvider,\n SelectAll,\n SelectRow,\n toast,\n useConfig,\n useLocale,\n useTranslation,\n} from '@payloadcms/ui'\nimport { useRouter, useSearchParams } from 'next/navigation'\r\nimport React from 'react'\n\nimport {\n type NestedDocsPageTreePluginResolvedBadgeConfig,\n pageTreeMoveRequestHeader,\n pageTreeMoveRequestHeaderValue,\n type PageTreeSourceDoc,\n} from '../types.js'\nimport {\n buildInsertDropTargets,\n getDropTargetParentDoc,\n type PageTreeDropTarget,\n} from '../utilities/dropTargets.js'\nimport {\n CANCEL_DRAG_MESSAGE,\n getDropValidation,\n type PageTreeDropValidation,\r\n} from '../utilities/moveValidation.js'\r\nimport {\r\n buildDocSlugPath,\r\n buildPageTreeDocs,\r\n buildProspectiveDocSlugPath,\n getDocDisplayLabel,\n getVisibleTreeDocs,\n type PageTreeDoc,\n} from '../utilities/pageTree.js'\nimport { pageTreeCollisionDetectionStrategy } from '../utilities/pageTreeCollision.js'\r\nimport {\r\n getPageTreeBadgeColor,\r\n getPageTreeBadgeLabel,\r\n getPageTreeDisplayStatus,\r\n type PageTreeDisplayStatus,\r\n} from '../utilities/status.js'\r\nimport { PageTreeProvider } from './PageTreeContext.js'\r\nimport styles from './PageTreeListView.module.css'\r\nimport { PageTreeTitleCell } from './PageTreeTitleCell.js'\r\n\r\ntype PageTreeListViewClientOwnProps = {\r\n allDocs: PageTreeDoc[]\r\n badgeConfig: NestedDocsPageTreePluginResolvedBadgeConfig\r\n canMoveDocs: boolean\r\n columnState: Column[]\r\n homeIndicatorEnabled: boolean\r\n orderableFieldName?: string\r\n parentFieldSlug: string\r\n query: ListQuery\r\n sourceDocs: PageTreeSourceDoc[]\r\n useAsTitle: string\r\n}\r\n\r\ntype PageTreeListViewClientProps = Omit<ListViewClientProps, 'columnState' | 'Table'> &\r\n PageTreeListViewClientOwnProps\r\n\r\ntype SelectableRowData = React.ComponentProps<typeof SelectRow>['rowData']\r\ntype PageTreeDragData = {\n dragType?: 'move'\n rowID?: string\n}\n\nconst MANUAL_ORDER_COLUMN_ACCESSOR = '_dragHandle'\nconst SILENT_MOVE_MESSAGES = new Set([CANCEL_DRAG_MESSAGE])\n\r\nfunction getRowDropID(rowID: string): string {\r\n return `page-drop:${rowID}`\r\n}\r\n\r\nfunction getPageTreeDragData(value: unknown): PageTreeDragData {\n return value && typeof value === 'object' ? (value as PageTreeDragData) : {}\n}\n\nfunction buildPaginatedData(\n docs: PageTreeDoc[],\n limit: number,\n requestedPage: number,\r\n): PaginatedDocs {\r\n const totalDocs = docs.length\r\n const totalPages = totalDocs > 0 ? Math.max(1, Math.ceil(totalDocs / limit)) : 1\r\n const page = Math.min(Math.max(requestedPage, 1), totalPages)\r\n const startIndex = (page - 1) * limit\r\n const pageDocs = docs.slice(startIndex, startIndex + limit)\r\n\r\n return {\r\n docs: pageDocs,\r\n hasNextPage: page < totalPages,\r\n hasPrevPage: page > 1,\r\n limit,\r\n nextPage: page < totalPages ? page + 1 : null,\r\n page,\r\n pagingCounter: totalDocs === 0 ? 0 : startIndex + 1,\r\n prevPage: page > 1 ? page - 1 : null,\r\n totalDocs,\r\n totalPages,\r\n }\r\n}\r\n\r\nfunction normalizeSort(value: string | string[] | undefined): string | undefined {\r\n if (Array.isArray(value)) {\r\n const sortValues = value.filter((entry) => typeof entry === 'string' && entry.length > 0)\r\n return sortValues.length > 0 ? sortValues.join(',') : undefined\r\n }\r\n\r\n return typeof value === 'string' && value.length > 0 ? value : undefined\r\n}\r\n\r\nfunction normalizePositiveInt(value: null | string, fallback: number): number {\r\n if (typeof value !== 'string') {\r\n return fallback\r\n }\r\n\r\n const parsedValue = Number.parseInt(value, 10)\r\n return Number.isNaN(parsedValue) || parsedValue <= 0 ? fallback : parsedValue\r\n}\r\n\r\nfunction normalizePageTreeColumnState(columnState: Column[], useAsTitle: string): Column[] {\r\n return columnState\r\n .filter((column) => column.accessor !== MANUAL_ORDER_COLUMN_ACCESSOR)\r\n .map((column) =>\r\n column.accessor === useAsTitle\r\n ? {\r\n ...column,\r\n active: true,\r\n }\r\n : column,\r\n )\r\n}\r\n\r\nfunction sliceColumnState(\r\n columnState: Column[],\r\n docs: PageTreeDoc[],\r\n renderedCellIndexByDocID: ReadonlyMap<string, number>,\r\n): Column[] {\r\n return columnState.map((column) => ({\r\n ...column,\r\n renderedCells: docs.map((doc) => {\r\n const renderedCellIndex =\r\n renderedCellIndexByDocID.get(doc.__pageTreeID) ?? doc.__pageTreeOrderIndex\r\n\r\n return column.renderedCells?.[renderedCellIndex] ?? null\r\n }),\r\n }))\r\n}\r\n\r\nfunction getSelectableRowData(doc: PageTreeDoc): SelectableRowData {\r\n const record = doc as Record<string, unknown>\r\n\r\n return {\r\n id: String(doc.id ?? doc.__pageTreeID),\r\n _isLocked: Boolean(record._isLocked),\r\n _userEditing: record._userEditing as SelectableRowData['_userEditing'],\r\n }\r\n}\r\n\r\nfunction shouldSilenceMoveMessage(message?: string): boolean {\r\n return typeof message === 'string' && SILENT_MOVE_MESSAGES.has(message)\r\n}\r\n\r\nfunction getStatusClassName(\r\n status: PageTreeDisplayStatus,\r\n): 'changed' | 'draft' | 'published' | 'unknown' {\r\n if (status === 'changed' || status === 'draft' || status === 'published') {\r\n return status\r\n }\r\n\r\n return 'unknown'\r\n}\r\n\r\nfunction renderStatusBadge(args: {\r\n badgeConfig: NestedDocsPageTreePluginResolvedBadgeConfig\r\n doc: PageTreeDoc\r\n index: number\r\n t: (key: 'general:noValue' | 'version:changed' | 'version:draft' | 'version:published') => string\r\n}): React.ReactNode {\r\n const { badgeConfig, doc, index, t } = args\r\n const status = getPageTreeDisplayStatus(doc)\r\n const customColor = getPageTreeBadgeColor({\r\n badgeColors: badgeConfig.colors,\r\n status,\r\n })\r\n const statusClass = getStatusClassName(status)\r\n const style = customColor\r\n ? ({ '--page-tree-badge-base': customColor } as React.CSSProperties)\r\n : undefined\r\n\r\n return (\r\n <span\r\n className={[\r\n 'pages-hierarchy-status-badge',\r\n `pages-hierarchy-status-badge--${statusClass}`,\r\n ].join(' ')}\r\n data-custom-color={customColor ? 'true' : undefined}\r\n key={doc.__pageTreeID ?? index}\r\n style={style}\r\n >\r\n {getPageTreeBadgeLabel({\r\n badgeLabels: badgeConfig.labels,\r\n status,\r\n t,\r\n })}\r\n </span>\r\n )\r\n}\r\n\r\nfunction buildTableColumns(args: {\n badgeConfig: NestedDocsPageTreePluginResolvedBadgeConfig\n columnState: Column[]\n docs: PageTreeDoc[]\n enableRowSelections?: boolean\n homeIndicatorEnabled: boolean\n parentFieldSlug: string\n t: (key: 'general:noValue' | 'version:changed' | 'version:draft' | 'version:published') => string\n useAsTitle: string\n}): Column[] {\n const {\r\n badgeConfig,\r\n columnState,\r\n docs,\n enableRowSelections,\n homeIndicatorEnabled,\n parentFieldSlug,\n t,\n useAsTitle,\n } = args\n const columnsToUse = columnState.map((column) => {\r\n if (column.accessor === useAsTitle) {\r\n return {\r\n ...column,\r\n active: true,\r\n renderedCells: docs.map((doc, index) => (\r\n <PageTreeTitleCell\r\n doc={doc}\r\n homeIndicatorEnabled={homeIndicatorEnabled}\r\n key={doc.__pageTreeID ?? index}\r\n >\r\n {column.renderedCells?.[index] ?? getDocDisplayLabel(doc)}\r\n </PageTreeTitleCell>\r\n )),\r\n }\r\n }\r\n\r\n if (column.accessor === '_status') {\r\n return {\r\n ...column,\r\n renderedCells: docs.map((doc, index) =>\r\n renderStatusBadge({\r\n badgeConfig,\r\n doc,\r\n index,\r\n t,\r\n }),\r\n ),\r\n }\r\n }\r\n\r\n if (column.accessor === parentFieldSlug) {\r\n return {\r\n ...column,\r\n renderedCells: docs.map((doc, index) =>\r\n doc.__pageTreeParentID !== null ? (\r\n column.renderedCells?.[index] ?? null\r\n ) : (\r\n <span className=\"pages-hierarchy-empty-cell\" key={doc.__pageTreeID ?? index}>\r\n -\r\n </span>\r\n ),\r\n ),\r\n }\r\n }\r\n\r\n return column\r\n })\r\n\r\n if (enableRowSelections) {\r\n columnsToUse.unshift({\r\n accessor: '_select',\r\n active: true,\r\n field: { hidden: true } as Column['field'],\r\n Heading: <SelectAll />,\r\n renderedCells: docs.map((doc, index) => (\r\n <SelectRow key={doc.__pageTreeID ?? index} rowData={getSelectableRowData(doc)} />\r\n )),\r\n })\n }\n\n return columnsToUse\n}\n\r\nfunction HierarchyInsertRow({\r\n activeColumnsCount,\r\n activeDragRowID,\r\n dropTarget,\r\n dropValidation,\r\n isMovePending,\r\n}: {\r\n activeColumnsCount: number\r\n activeDragRowID: null | string\r\n dropTarget: Extract<PageTreeDropTarget, { dropType: 'insert' }>\r\n dropValidation?: PageTreeDropValidation\r\n isMovePending: boolean\r\n}) {\r\n const { isOver, setNodeRef } = useDroppable({\r\n id: dropTarget.dropID,\r\n data: dropTarget,\r\n disabled: isMovePending,\r\n })\r\n const hasActiveDrag = Boolean(activeDragRowID)\r\n\r\n return (\r\n <tr\r\n className=\"pages-hierarchy-insert-row\"\r\n data-drag-over={isOver ? 'true' : 'false'}\r\n data-drop-valid={hasActiveDrag ? (dropValidation?.isValid ? 'true' : 'false') : undefined}\r\n data-page-tree-insert=\"true\"\r\n >\r\n <td colSpan={activeColumnsCount}>\r\n <div\r\n className=\"pages-hierarchy-insert-row__target\"\r\n data-insert-depth={dropTarget.depth}\r\n ref={setNodeRef}\r\n />\r\n </td>\r\n </tr>\r\n )\r\n}\r\n\r\nfunction HierarchyTableRow({\r\n activeColumns,\r\n activeDragRowID,\r\n doc,\r\n dropValidation,\r\n insertAfterDropID,\r\n insertBeforeDropID,\r\n isMovePending,\r\n rowIndex,\r\n titleCellAccessor,\r\n}: {\r\n activeColumns: Column[]\r\n activeDragRowID: null | string\r\n doc: PageTreeDoc\r\n dropValidation?: PageTreeDropValidation\r\n insertAfterDropID: string\r\n insertBeforeDropID: string\r\n isMovePending: boolean\r\n rowIndex: number\r\n titleCellAccessor: string\r\n}) {\r\n const { isOver, setNodeRef } = useDroppable({\r\n id: getRowDropID(doc.__pageTreeID),\r\n data: {\r\n dropType: 'row',\r\n insertAfterDropID,\r\n insertBeforeDropID,\r\n rowID: doc.__pageTreeID,\r\n } satisfies Extract<PageTreeDropTarget, { dropType: 'row' }>,\r\n disabled: isMovePending,\r\n })\r\n const hasActiveDrag = Boolean(activeDragRowID)\r\n const isActiveDragRow = activeDragRowID === doc.__pageTreeID\r\n\r\n return (\r\n <tr\r\n className={`row-${rowIndex + 1}`}\r\n data-drag-over={isOver ? 'true' : 'false'}\r\n data-drop-valid={hasActiveDrag ? (dropValidation?.isValid ? 'true' : 'false') : undefined}\r\n data-id={doc.id}\r\n data-is-drag-source={isActiveDragRow ? 'true' : 'false'}\r\n data-page-tree-row=\"true\"\r\n ref={setNodeRef}\r\n >\r\n {activeColumns.map((column, columnIndex) => {\r\n const { accessor } = column\r\n\r\n return (\r\n <td\r\n className={`cell-${accessor.replace(/\\./g, '__')}`}\r\n data-page-tree-manual-order-cell={\r\n accessor === MANUAL_ORDER_COLUMN_ACCESSOR ? 'true' : undefined\r\n }\r\n data-page-tree-title-cell={accessor === titleCellAccessor ? 'true' : undefined}\r\n key={columnIndex}\r\n >\r\n {column.renderedCells?.[rowIndex] ?? null}\r\n </td>\r\n )\r\n })}\r\n </tr>\r\n )\r\n}\r\n\r\nfunction HierarchyTable({\n activeDragRowID,\n allDocsByID,\n columns,\n data,\n isMovePending,\n titleCellAccessor,\r\n}: {\n activeDragRowID: null | string\n allDocsByID: ReadonlyMap<string, PageTreeDoc>\n columns: Column[]\n data: PageTreeDoc[]\n isMovePending: boolean\n titleCellAccessor: string\r\n}) {\r\n const activeColumns = React.useMemo(\r\n () => columns.filter((column) => column?.active),\r\n [columns],\r\n )\r\n const hasManualOrderColumn = React.useMemo(\r\n () => activeColumns.some((column) => column.accessor === MANUAL_ORDER_COLUMN_ACCESSOR),\r\n [activeColumns],\r\n )\r\n const insertDropTargets = React.useMemo(() => buildInsertDropTargets(data), [data])\r\n const activeDoc = activeDragRowID ? allDocsByID.get(activeDragRowID) ?? null : null\r\n const rowDropValidationByID = React.useMemo(() => {\r\n if (!activeDoc) {\r\n return new Map<string, PageTreeDropValidation>()\r\n }\r\n\r\n return new Map(\r\n data.map((doc) => [\n doc.__pageTreeID,\n getDropValidation({\n activeDoc,\n targetDoc: doc,\n }),\n ]),\n )\n }, [activeDoc, data])\n const insertDropValidationByID = React.useMemo(() => {\n if (!activeDoc) {\n return new Map<string, PageTreeDropValidation>()\n }\r\n\r\n return new Map(\n insertDropTargets.map((dropTarget) => [\n dropTarget.dropID,\n getDropValidation({\n activeDoc,\n targetDoc:\n dropTarget.parentID === null\n ? undefined\n : allDocsByID.get(dropTarget.parentID) ?? undefined,\n }),\r\n ]),\n )\n }, [activeDoc, allDocsByID, insertDropTargets])\n\r\n if (activeColumns.length === 0) {\r\n return <div>No columns selected</div>\r\n }\r\n\r\n return (\r\n <div\r\n className={[\r\n 'table-wrap pages-hierarchy-table',\r\n activeDoc ? 'pages-hierarchy-table--dragging' : '',\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n data-page-tree-orderable={hasManualOrderColumn ? 'true' : undefined}\r\n >\r\n <div className=\"table table--appearance-default\">\r\n <table cellPadding=\"0\" cellSpacing=\"0\">\r\n <thead>\r\n <tr>\r\n {activeColumns.map((column, index) => (\r\n <th\r\n data-page-tree-manual-order-cell={\r\n column.accessor === MANUAL_ORDER_COLUMN_ACCESSOR ? 'true' : undefined\r\n }\r\n data-page-tree-title-cell={\r\n column.accessor === titleCellAccessor ? 'true' : undefined\r\n }\r\n id={`heading-${column.accessor.replace(/\\./g, '__')}`}\r\n key={index}\r\n >\r\n {column.Heading}\r\n </th>\r\n ))}\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {insertDropTargets[0] ? (\r\n <HierarchyInsertRow\r\n activeColumnsCount={activeColumns.length}\r\n activeDragRowID={activeDragRowID}\r\n dropTarget={insertDropTargets[0]}\r\n dropValidation={insertDropValidationByID.get(insertDropTargets[0].dropID)}\r\n isMovePending={isMovePending}\r\n key={insertDropTargets[0].dropID}\r\n />\r\n ) : null}\r\n {data.map((doc, rowIndex) => (\r\n <React.Fragment key={doc.__pageTreeID}>\r\n <HierarchyTableRow\r\n activeColumns={activeColumns}\r\n activeDragRowID={activeDragRowID}\r\n doc={doc}\r\n dropValidation={rowDropValidationByID.get(doc.__pageTreeID)}\r\n insertAfterDropID={insertDropTargets[rowIndex + 1].dropID}\r\n insertBeforeDropID={insertDropTargets[rowIndex].dropID}\r\n isMovePending={isMovePending}\r\n rowIndex={rowIndex}\r\n titleCellAccessor={titleCellAccessor}\r\n />\r\n {insertDropTargets[rowIndex + 1] ? (\r\n <HierarchyInsertRow\r\n activeColumnsCount={activeColumns.length}\r\n activeDragRowID={activeDragRowID}\r\n dropTarget={insertDropTargets[rowIndex + 1]}\r\n dropValidation={insertDropValidationByID.get(\r\n insertDropTargets[rowIndex + 1].dropID,\r\n )}\r\n isMovePending={isMovePending}\r\n key={insertDropTargets[rowIndex + 1].dropID}\r\n />\r\n ) : null}\r\n </React.Fragment>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nexport default function PageTreeListViewClient({\r\n allDocs,\r\n badgeConfig,\r\n canMoveDocs,\n columnState,\n homeIndicatorEnabled,\n orderableFieldName: _orderableFieldName,\n parentFieldSlug,\n query,\n sourceDocs,\n useAsTitle,\r\n ...props\r\n}: PageTreeListViewClientProps) {\r\n const router = useRouter()\r\n const searchParams = useSearchParams()\r\n const { config } = useConfig()\r\n const locale = useLocale()\r\n const { i18n } = useTranslation()\r\n const [activeDragRowID, setActiveDragRowID] = React.useState<null | string>(null)\r\n const [activeDropTarget, setActiveDropTarget] = React.useState<null | PageTreeDropTarget>(null)\r\n const [collapsedIDs, setCollapsedIDs] = React.useState<Set<string>>(() => new Set())\r\n const [localSourceDocs, setLocalSourceDocs] = React.useState(sourceDocs)\r\n const [pendingMoveRowID, setPendingMoveRowID] = React.useState<null | string>(null)\r\n\r\n React.useEffect(() => {\r\n setLocalSourceDocs(sourceDocs)\r\n }, [sourceDocs])\r\n\r\n const toggleRow = React.useCallback((rowID: string) => {\r\n setCollapsedIDs((currentState) => {\r\n const nextState = new Set(currentState)\r\n\r\n if (nextState.has(rowID)) {\r\n nextState.delete(rowID)\r\n } else {\r\n nextState.add(rowID)\r\n }\r\n\r\n return nextState\r\n })\r\n }, [])\r\n const currentSort = React.useMemo(() => {\r\n const searchParamSort = searchParams.getAll('sort')\r\n\r\n if (searchParamSort.length > 0) {\r\n return normalizeSort(searchParamSort)\r\n }\r\n\r\n return normalizeSort(query.sort as string | string[] | undefined)\r\n }, [query.sort, searchParams])\r\n const currentLimit = React.useMemo(\n () =>\r\n normalizePositiveInt(\r\n searchParams.get('limit'),\r\n typeof query.limit === 'number' && query.limit > 0 ? query.limit : 10,\r\n ),\r\n [query.limit, searchParams],\r\n )\r\n const currentRequestedPage = React.useMemo(\r\n () =>\r\n normalizePositiveInt(\r\n searchParams.get('page'),\r\n typeof query.page === 'number' && query.page > 0 ? query.page : 1,\r\n ),\r\n [query.page, searchParams],\r\n )\r\n const liveAllDocs = React.useMemo(\r\n () =>\r\n buildPageTreeDocs(localSourceDocs, {\r\n parentFieldSlug,\r\n sort: currentSort,\r\n }),\r\n [currentSort, localSourceDocs, parentFieldSlug],\r\n )\r\n const collapseResetKey = React.useMemo(\r\n () => JSON.stringify([props.collectionSlug, props.viewType, searchParams.toString()]),\r\n [props.collectionSlug, props.viewType, searchParams],\r\n )\r\n const hierarchyValue = React.useMemo(\r\n () => ({\r\n activeDragRowID,\r\n canMoveDocs,\r\n collapsedIDs,\r\n pendingMoveRowID,\r\n toggleRow,\r\n }),\r\n [activeDragRowID, canMoveDocs, collapsedIDs, pendingMoveRowID, toggleRow],\r\n )\r\n\r\n React.useEffect(() => {\r\n setActiveDragRowID(null)\r\n setActiveDropTarget(null)\r\n setCollapsedIDs(new Set())\r\n }, [collapseResetKey])\r\n\r\n const visibleDocs = React.useMemo(\r\n () => getVisibleTreeDocs(liveAllDocs, collapsedIDs),\r\n [liveAllDocs, collapsedIDs],\r\n )\r\n const paginatedData = React.useMemo(\r\n () => buildPaginatedData(visibleDocs, currentLimit, currentRequestedPage),\r\n [currentLimit, currentRequestedPage, visibleDocs],\r\n )\r\n const paginatedDocs = paginatedData.docs as PageTreeDoc[]\r\n const allDocsByID = React.useMemo(\r\n () => new Map(liveAllDocs.map((doc) => [doc.__pageTreeID, doc])),\r\n [liveAllDocs],\r\n )\r\n const paginatedDocsByID = React.useMemo(\r\n () => new Map(paginatedDocs.map((doc) => [doc.__pageTreeID, doc])),\r\n [paginatedDocs],\r\n )\r\n const renderedCellIndexByDocID = React.useMemo(\r\n () => new Map(allDocs.map((doc, index) => [doc.__pageTreeID, index])),\r\n [allDocs],\r\n )\r\n const normalizedColumnState = React.useMemo(\r\n () => normalizePageTreeColumnState(columnState, useAsTitle),\r\n [columnState, useAsTitle],\r\n )\r\n const paginatedColumnState = React.useMemo(\r\n () => sliceColumnState(normalizedColumnState, paginatedDocs, renderedCellIndexByDocID),\r\n [normalizedColumnState, paginatedDocs, renderedCellIndexByDocID],\r\n )\r\n const tableColumns = React.useMemo(\r\n () =>\r\n buildTableColumns({\r\n badgeConfig,\r\n columnState: paginatedColumnState,\r\n docs: paginatedDocs,\n enableRowSelections: props.enableRowSelections,\n homeIndicatorEnabled,\n parentFieldSlug,\n t: i18n.t,\n useAsTitle,\n }),\r\n [\r\n paginatedColumnState,\r\n paginatedDocs,\n badgeConfig,\n homeIndicatorEnabled,\n parentFieldSlug,\n props.enableRowSelections,\n i18n.t,\n useAsTitle,\r\n ],\r\n )\r\n const activeDragDoc = activeDragRowID ? paginatedDocsByID.get(activeDragRowID) ?? null : null\r\n const activeDragPreviewPath = React.useMemo(() => {\r\n if (!activeDragDoc) {\r\n return null\r\n }\r\n\r\n if (!activeDropTarget) {\r\n return buildDocSlugPath({\r\n doc: activeDragDoc,\r\n docsByID: allDocsByID,\r\n })\r\n }\r\n\r\n const targetDoc = getDropTargetParentDoc({\r\n docsByID: allDocsByID,\r\n dropTarget: activeDropTarget,\r\n })\n const dropValidation = getDropValidation({\n activeDoc: activeDragDoc,\n targetDoc: targetDoc ?? undefined,\n })\n\r\n if (!dropValidation.isValid) {\r\n return buildDocSlugPath({\r\n doc: activeDragDoc,\r\n docsByID: allDocsByID,\r\n })\r\n }\r\n\r\n return buildProspectiveDocSlugPath({\r\n activeDoc: activeDragDoc,\r\n docsByID: allDocsByID,\r\n targetDoc: targetDoc ?? undefined,\n })\n }, [activeDragDoc, activeDropTarget, allDocsByID])\n const isMovePending = pendingMoveRowID !== null\r\n const sensors = useSensors(\r\n useSensor(PointerSensor, {\r\n activationConstraint: {\r\n distance: 4,\r\n },\r\n }),\r\n )\r\n const moveDocument = React.useCallback(\r\n async (args: { parentID: null | string; rowID: string }) => {\r\n const { parentID, rowID } = args\r\n const params = new URLSearchParams()\r\n\r\n if (locale?.code) {\r\n params.set('locale', locale.code)\r\n }\r\n\r\n const response = await fetch(\r\n `${config.routes.api}/${props.collectionSlug}/${encodeURIComponent(rowID)}/move${\r\n params.size > 0 ? `?${params.toString()}` : ''\r\n }`,\r\n {\r\n body: JSON.stringify({\r\n parentID,\r\n }),\r\n credentials: 'include',\r\n headers: {\r\n 'Accept-Language': i18n.language,\r\n 'Content-Type': 'application/json',\r\n [pageTreeMoveRequestHeader]: pageTreeMoveRequestHeaderValue,\r\n },\r\n method: 'POST',\r\n },\r\n )\r\n const result = (await response.json().catch(() => null)) as\r\n | {\r\n message?: string\r\n }\r\n | null\r\n\r\n if (!response.ok) {\r\n throw new Error(result?.message ?? 'Could not move document.')\r\n }\r\n\r\n return result\r\n },\r\n [config.routes.api, i18n.language, locale?.code, props.collectionSlug],\r\n )\r\n const handleDragCancel = React.useCallback(() => {\n setActiveDragRowID(null)\r\n setActiveDropTarget(null)\r\n }, [])\r\n const handleDragStart = React.useCallback(\r\n (event: DragStartEvent) => {\r\n const dragData = getPageTreeDragData(event.active.data.current)\r\n\r\n if (!canMoveDocs || isMovePending) {\r\n return\r\n }\r\n\r\n const rowID = dragData.rowID\r\n\r\n if (typeof rowID === 'string' && paginatedDocsByID.has(rowID)) {\r\n setActiveDragRowID(rowID)\r\n setActiveDropTarget(null)\r\n }\r\n },\r\n [canMoveDocs, isMovePending, paginatedDocsByID],\r\n )\r\n const handleDragOver = React.useCallback((event: DragOverEvent) => {\r\n const overData = event.over?.data.current as PageTreeDropTarget | undefined\r\n\r\n if (!overData) {\r\n setActiveDropTarget(null)\r\n return\r\n }\r\n\r\n if (overData.dropType === 'insert') {\r\n setActiveDropTarget(overData)\r\n return\r\n }\r\n\r\n if (overData.dropType === 'row') {\r\n setActiveDropTarget(overData)\r\n return\r\n }\r\n\r\n setActiveDropTarget(null)\r\n }, [])\r\n const handleDragEnd = React.useCallback(\r\n async (event: DragEndEvent) => {\r\n const dragData = getPageTreeDragData(event.active.data.current)\r\n\r\n const rowID = dragData.rowID\r\n const activeDoc = typeof rowID === 'string' ? paginatedDocsByID.get(rowID) ?? null : null\r\n const overData = event.over?.data.current as PageTreeDropTarget | undefined\r\n\r\n setActiveDragRowID(null)\r\n setActiveDropTarget(null)\r\n\r\n if (!rowID || !activeDoc || !overData) {\r\n return\r\n }\r\n\r\n const targetDoc = getDropTargetParentDoc({\n docsByID: allDocsByID,\n dropTarget: overData,\n })\r\n const dropValidation = getDropValidation({\r\n activeDoc,\r\n targetDoc: targetDoc ?? undefined,\r\n })\r\n\r\n if (!dropValidation.isValid) {\r\n if (!shouldSilenceMoveMessage(dropValidation.message)) {\r\n toast.error(dropValidation.message ?? 'Could not move document.')\r\n }\r\n\r\n return\r\n }\r\n\r\n setPendingMoveRowID(rowID)\r\n\r\n try {\r\n await moveDocument({\r\n parentID: dropValidation.parentID,\r\n rowID,\r\n })\r\n\r\n toast.success(`Moved \"${getDocDisplayLabel(activeDoc)}\".`)\r\n React.startTransition(() => {\r\n router.refresh()\r\n })\r\n } catch (error) {\r\n const message =\r\n error instanceof Error && error.message ? error.message : 'Could not move document.'\r\n\r\n if (shouldSilenceMoveMessage(message)) {\r\n return\r\n }\r\n\r\n toast.error(message)\r\n } finally {\r\n setPendingMoveRowID(null)\r\n }\r\n },\r\n [\r\n allDocsByID,\n moveDocument,\n paginatedDocsByID,\n router,\n ],\n )\r\n const handleDragEndSync = React.useCallback(\r\n (event: DragEndEvent) => {\r\n void handleDragEnd(event)\r\n },\r\n [handleDragEnd],\r\n )\r\n\r\n const tableNode = React.useMemo(\r\n () => (\r\n <DndContext\r\n collisionDetection={pageTreeCollisionDetectionStrategy}\r\n onDragCancel={handleDragCancel}\r\n onDragEnd={handleDragEndSync}\r\n onDragOver={handleDragOver}\r\n onDragStart={handleDragStart}\r\n sensors={sensors}\r\n >\r\n <HierarchyTable\n activeDragRowID={activeDragRowID}\n allDocsByID={allDocsByID}\n columns={tableColumns}\n data={paginatedDocs}\n isMovePending={isMovePending}\n titleCellAccessor={useAsTitle}\r\n />\r\n <DragOverlay dropAnimation={null} style={{ cursor: 'grabbing' }}>\r\n {activeDragPreviewPath ? (\r\n <div className=\"pages-hierarchy-drag-overlay\">{activeDragPreviewPath}</div>\r\n ) : null}\r\n </DragOverlay>\r\n </DndContext>\r\n ),\r\n [\r\n activeDragPreviewPath,\r\n activeDragRowID,\r\n handleDragCancel,\r\n handleDragEndSync,\r\n handleDragOver,\r\n handleDragStart,\n isMovePending,\n allDocsByID,\n paginatedDocs,\n sensors,\n tableColumns,\n useAsTitle,\r\n ],\r\n )\r\n\r\n return (\r\n <div className={styles.root}>\r\n <PageTreeProvider value={hierarchyValue}>\r\n <ListQueryProvider\r\n collectionSlug={props.collectionSlug}\n data={paginatedData}\n modifySearchParams\n query={{\n ...query,\n limit: currentLimit,\n page: paginatedData.page,\r\n sort: currentSort,\r\n }}\r\n >\r\n <DefaultListView {...props} columnState={paginatedColumnState} Table={tableNode} />\r\n </ListQueryProvider>\r\n </PageTreeProvider>\r\n </div>\r\n )\r\n}\r\n"],"names":["DndContext","DragOverlay","PointerSensor","useDroppable","useSensor","useSensors","DefaultListView","ListQueryProvider","SelectAll","SelectRow","toast","useConfig","useLocale","useTranslation","useRouter","useSearchParams","React","pageTreeMoveRequestHeader","pageTreeMoveRequestHeaderValue","buildInsertDropTargets","getDropTargetParentDoc","CANCEL_DRAG_MESSAGE","getDropValidation","buildDocSlugPath","buildPageTreeDocs","buildProspectiveDocSlugPath","getDocDisplayLabel","getVisibleTreeDocs","pageTreeCollisionDetectionStrategy","getPageTreeBadgeColor","getPageTreeBadgeLabel","getPageTreeDisplayStatus","PageTreeProvider","styles","PageTreeTitleCell","MANUAL_ORDER_COLUMN_ACCESSOR","SILENT_MOVE_MESSAGES","Set","getRowDropID","rowID","getPageTreeDragData","value","buildPaginatedData","docs","limit","requestedPage","totalDocs","length","totalPages","Math","max","ceil","page","min","startIndex","pageDocs","slice","hasNextPage","hasPrevPage","nextPage","pagingCounter","prevPage","normalizeSort","Array","isArray","sortValues","filter","entry","join","undefined","normalizePositiveInt","fallback","parsedValue","Number","parseInt","isNaN","normalizePageTreeColumnState","columnState","useAsTitle","column","accessor","map","active","sliceColumnState","renderedCellIndexByDocID","renderedCells","doc","renderedCellIndex","get","__pageTreeID","__pageTreeOrderIndex","getSelectableRowData","record","id","String","_isLocked","Boolean","_userEditing","shouldSilenceMoveMessage","message","has","getStatusClassName","status","renderStatusBadge","args","badgeConfig","index","t","customColor","badgeColors","colors","statusClass","style","span","className","data-custom-color","badgeLabels","labels","buildTableColumns","enableRowSelections","homeIndicatorEnabled","parentFieldSlug","columnsToUse","__pageTreeParentID","unshift","field","hidden","Heading","rowData","HierarchyInsertRow","activeColumnsCount","activeDragRowID","dropTarget","dropValidation","isMovePending","isOver","setNodeRef","dropID","data","disabled","hasActiveDrag","tr","data-drag-over","data-drop-valid","isValid","data-page-tree-insert","td","colSpan","div","data-insert-depth","depth","ref","HierarchyTableRow","activeColumns","insertAfterDropID","insertBeforeDropID","rowIndex","titleCellAccessor","dropType","isActiveDragRow","data-id","data-is-drag-source","data-page-tree-row","columnIndex","replace","data-page-tree-manual-order-cell","data-page-tree-title-cell","HierarchyTable","allDocsByID","columns","useMemo","hasManualOrderColumn","some","insertDropTargets","activeDoc","rowDropValidationByID","Map","targetDoc","insertDropValidationByID","parentID","data-page-tree-orderable","table","cellPadding","cellSpacing","thead","th","tbody","Fragment","PageTreeListViewClient","allDocs","canMoveDocs","orderableFieldName","_orderableFieldName","query","sourceDocs","props","router","searchParams","config","locale","i18n","setActiveDragRowID","useState","activeDropTarget","setActiveDropTarget","collapsedIDs","setCollapsedIDs","localSourceDocs","setLocalSourceDocs","pendingMoveRowID","setPendingMoveRowID","useEffect","toggleRow","useCallback","currentState","nextState","delete","add","currentSort","searchParamSort","getAll","sort","currentLimit","currentRequestedPage","liveAllDocs","collapseResetKey","JSON","stringify","collectionSlug","viewType","toString","hierarchyValue","visibleDocs","paginatedData","paginatedDocs","paginatedDocsByID","normalizedColumnState","paginatedColumnState","tableColumns","activeDragDoc","activeDragPreviewPath","docsByID","sensors","activationConstraint","distance","moveDocument","params","URLSearchParams","code","set","response","fetch","routes","api","encodeURIComponent","size","body","credentials","headers","language","method","result","json","catch","ok","Error","handleDragCancel","handleDragStart","event","dragData","current","handleDragOver","overData","over","handleDragEnd","error","success","startTransition","refresh","handleDragEndSync","tableNode","collisionDetection","onDragCancel","onDragEnd","onDragOver","onDragStart","dropAnimation","cursor","root","modifySearchParams","Table"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CANCEL_DRAG_MESSAGE } from '../utilities/moveValidation.js';
|
|
2
2
|
import { buildChildrenByParentID, collectDescendantIDs, getDocParentID, stringifyDocID } from '../utilities/pageTree.js';
|
|
3
|
+
import { pageTreeMoveContextKey } from '../types.js';
|
|
3
4
|
function respond(status, body) {
|
|
4
5
|
return Response.json(body, {
|
|
5
6
|
status
|
|
@@ -234,6 +235,9 @@ export function createMovePageEndpoint(args) {
|
|
|
234
235
|
}
|
|
235
236
|
await req.payload.update({
|
|
236
237
|
collection: collectionSlug,
|
|
238
|
+
context: {
|
|
239
|
+
[pageTreeMoveContextKey]: true
|
|
240
|
+
},
|
|
237
241
|
data: {
|
|
238
242
|
[parentFieldSlug]: body.parentID === null ? null : toCollectionID({
|
|
239
243
|
collectionSlug,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/endpoints/createMovePageEndpoint.ts"],"sourcesContent":["import type { Endpoint, PayloadRequest, Where } from 'payload'\r\n\r\nimport { CANCEL_DRAG_MESSAGE } from '../utilities/moveValidation.js'\r\nimport {\r\n buildChildrenByParentID,\r\n collectDescendantIDs,\r\n getDocParentID,\r\n stringifyDocID,\r\n} from '../utilities/pageTree.js'\r\nimport type { PageTreeSourceDoc } from '../types.js'\r\n\r\ntype MoveDocumentRequestBody = {\r\n parentID: null | string\r\n}\r\n\r\ntype PayloadCollectionLike = {\r\n config?: {\r\n access?: {\r\n update?: ((args: Record<string, unknown>) => Promise<Record<string, unknown> | boolean> | Record<string, unknown> | boolean) | undefined\r\n }\r\n versions?: {\r\n drafts?: unknown\r\n }\r\n }\r\n customIDType?: string\r\n}\r\n\r\nfunction respond(status: number, body: Record<string, unknown>) {\r\n return Response.json(body, { status })\r\n}\r\n\r\nfunction hasOwnProperty(value: object, key: PropertyKey): boolean {\r\n return Object.prototype.hasOwnProperty.call(value, key)\r\n}\r\n\r\nfunction normalizeID(value: unknown): null | string {\r\n if (value === null || value === undefined || value === '') {\r\n return null\r\n }\r\n\r\n if (typeof value === 'number' || typeof value === 'string') {\r\n return stringifyDocID(value)\r\n }\r\n\r\n return null\r\n}\r\n\r\nfunction normalizeMoveDocumentBody(value: unknown): MoveDocumentRequestBody | null {\r\n const incomingData =\r\n typeof value === 'string'\r\n ? (() => {\r\n try {\r\n return JSON.parse(value) as unknown\r\n } catch {\r\n return null\r\n }\r\n })()\r\n : value\r\n\r\n if (!incomingData || typeof incomingData !== 'object' || Array.isArray(incomingData)) {\r\n return null\r\n }\r\n\r\n if (!hasOwnProperty(incomingData, 'parentID')) {\r\n return null\r\n }\r\n\r\n const parentID = normalizeID((incomingData as { parentID?: unknown }).parentID)\r\n\r\n if (\r\n (incomingData as { parentID?: unknown }).parentID !== null &&\r\n (incomingData as { parentID?: unknown }).parentID !== undefined &&\r\n parentID === null\r\n ) {\r\n return null\r\n }\r\n\r\n return {\r\n parentID,\r\n }\r\n}\r\n\r\nasync function readBodyFromRequest(req: PayloadRequest): Promise<MoveDocumentRequestBody | null> {\r\n const directBody = normalizeMoveDocumentBody(req.data)\r\n\r\n if (directBody) {\r\n return directBody\r\n }\r\n\r\n if (typeof req.json === 'function') {\r\n try {\r\n const jsonBody = normalizeMoveDocumentBody(await req.json())\r\n\r\n if (jsonBody) {\r\n return jsonBody\r\n }\r\n } catch {\r\n // Fall through to the text-based fallback when the runtime does not hydrate req.data.\r\n }\r\n }\r\n\r\n if (typeof req.text === 'function') {\r\n try {\r\n return normalizeMoveDocumentBody(await req.text())\r\n } catch {\r\n return null\r\n }\r\n }\r\n\r\n return null\r\n}\r\n\r\nfunction getPayloadCollection({\r\n collectionSlug,\r\n req,\r\n}: {\r\n collectionSlug: string\r\n req: PayloadRequest\r\n}): PayloadCollectionLike | undefined {\r\n return (req.payload.collections as unknown as Record<string, PayloadCollectionLike | undefined>)[\r\n collectionSlug\r\n ]\r\n}\r\n\r\nfunction usesNumericID({\r\n collectionSlug,\r\n req,\r\n}: {\r\n collectionSlug: string\r\n req: PayloadRequest\r\n}): boolean {\r\n const collection = getPayloadCollection({ collectionSlug, req })\r\n\r\n if (!collection) {\r\n return false\r\n }\r\n\r\n const idType = collection.customIDType ?? req.payload.db.defaultIDType\r\n\r\n return idType === 'number'\r\n}\r\n\r\nfunction toCollectionID(args: {\r\n collectionSlug: string\r\n id: string\r\n req: PayloadRequest\r\n}): number | string {\r\n const { collectionSlug, id, req } = args\r\n\r\n if (!usesNumericID({ collectionSlug, req })) {\r\n return id\r\n }\r\n\r\n return Number(id)\r\n}\r\n\r\nfunction getRequestedLocale(req: PayloadRequest): string | undefined {\r\n return req.locale && req.locale !== 'all' ? req.locale : undefined\r\n}\r\n\r\nfunction collectionHasDrafts(args: {\r\n collectionSlug: string\r\n req: PayloadRequest\r\n}): boolean {\r\n return Boolean(getPayloadCollection(args)?.config?.versions?.drafts)\r\n}\r\n\r\nasync function assertUpdateAccess(args: {\r\n collectionSlug: string\r\n movedID: number | string\r\n nextParentID: null | number | string\r\n parentFieldSlug: string\r\n req: PayloadRequest\r\n}): Promise<Response | null> {\r\n const { collectionSlug, movedID, nextParentID, parentFieldSlug, req } = args\r\n const collection = getPayloadCollection({ collectionSlug, req })\r\n const updateAccess = collection?.config?.access?.update\r\n\r\n if (!updateAccess) {\r\n return null\r\n }\r\n\r\n const accessResult = await updateAccess({\r\n data: { [parentFieldSlug]: nextParentID } as never,\r\n id: movedID as never,\r\n req,\r\n })\r\n\r\n if (accessResult === false) {\r\n return respond(403, {\r\n message: req.i18n.t('error:unauthorized'),\r\n })\r\n }\r\n\r\n if (accessResult && typeof accessResult === 'object') {\r\n const matchingDocs = await req.payload.find({\r\n collection: collectionSlug as never,\r\n depth: 0,\r\n draft: collectionHasDrafts({ collectionSlug, req }) ? true : undefined,\r\n limit: 1,\r\n locale: getRequestedLocale(req) as never,\r\n overrideAccess: true,\r\n req,\r\n where: {\r\n and: [\r\n {\r\n id: {\r\n equals: movedID,\r\n },\r\n },\r\n accessResult as Where,\r\n ],\r\n },\r\n } as never)\r\n\r\n if (matchingDocs.docs.length === 0) {\r\n return respond(403, {\r\n message: req.i18n.t('error:unauthorized'),\r\n })\r\n }\r\n }\r\n\r\n return null\r\n}\r\n\r\nexport function createMovePageEndpoint(args: {\r\n collectionSlug: string\r\n parentFieldSlug: string\r\n}): Endpoint {\r\n const { collectionSlug, parentFieldSlug } = args\r\n\r\n return {\r\n handler: async (req) => {\r\n const movedIDFromRoute = normalizeID(req.routeParams?.id)\r\n\r\n if (!movedIDFromRoute) {\r\n return respond(400, {\r\n message: 'Document ID was not specified.',\r\n })\r\n }\r\n\r\n const body = await readBodyFromRequest(req)\r\n\r\n if (!body) {\r\n return respond(400, {\r\n message: 'A valid parentID is required.',\r\n })\r\n }\r\n\r\n const movedID = toCollectionID({\r\n collectionSlug,\r\n id: movedIDFromRoute,\r\n req,\r\n })\r\n const nextParentID =\r\n body.parentID === null\r\n ? null\r\n : toCollectionID({\r\n collectionSlug,\r\n id: body.parentID,\r\n req,\r\n })\r\n const accessError = await assertUpdateAccess({\r\n collectionSlug,\r\n movedID,\r\n nextParentID,\r\n parentFieldSlug,\r\n req,\r\n })\r\n\r\n if (accessError) {\r\n return accessError\r\n }\r\n\r\n const docsResult = await req.payload.find({\r\n collection: collectionSlug as never,\r\n depth: 0,\r\n draft: collectionHasDrafts({ collectionSlug, req }) ? true : undefined,\r\n fallbackLocale: false as never,\r\n limit: 0,\r\n locale: getRequestedLocale(req) as never,\r\n overrideAccess: true,\r\n req,\r\n } as never)\r\n const docs = docsResult.docs as unknown as PageTreeSourceDoc[]\r\n const docsByID = new Map(docs.map((doc) => [stringifyDocID(doc.id), doc]))\r\n const movedDoc = docsByID.get(movedIDFromRoute)\r\n\r\n if (!movedDoc) {\r\n return respond(404, {\r\n message: 'Document not found.',\r\n })\r\n }\r\n\r\n if (body.parentID !== null && !docsByID.has(body.parentID)) {\r\n return respond(400, {\r\n message: 'Parent document not found.',\r\n })\r\n }\r\n\r\n const currentParentID = getDocParentID(movedDoc, parentFieldSlug)\r\n\r\n if (currentParentID === body.parentID) {\r\n return respond(400, {\r\n message: 'Document already has that parent.',\r\n })\r\n }\r\n\r\n if (body.parentID === movedIDFromRoute) {\r\n return respond(400, {\r\n message: CANCEL_DRAG_MESSAGE,\r\n })\r\n }\r\n\r\n const childrenByParentID = buildChildrenByParentID({\r\n docs,\r\n parentFieldSlug,\r\n })\r\n const descendantIDs = collectDescendantIDs(movedIDFromRoute, childrenByParentID)\r\n\r\n if (body.parentID !== null && descendantIDs.includes(body.parentID)) {\r\n return respond(400, {\r\n message: 'A document cannot be moved under one of its descendants.',\r\n })\r\n }\r\n\r\n await req.payload.update({\r\n collection: collectionSlug as never,\r\n data: {\r\n [parentFieldSlug]:\r\n body.parentID === null\r\n ? null\r\n : toCollectionID({\r\n collectionSlug,\r\n id: body.parentID,\r\n req,\r\n }),\r\n } as never,\r\n depth: 0,\r\n draft: collectionHasDrafts({ collectionSlug, req }) ? true : undefined,\r\n id: movedID as never,\r\n locale: getRequestedLocale(req) as never,\r\n overrideAccess: true,\r\n req,\r\n } as never)\r\n\r\n return respond(200, {\r\n movedID: movedIDFromRoute,\r\n ok: true,\r\n parentID: body.parentID,\r\n })\r\n },\r\n method: 'post',\r\n path: '/:id/move',\r\n }\r\n}\r\n"],"names":["CANCEL_DRAG_MESSAGE","buildChildrenByParentID","collectDescendantIDs","getDocParentID","stringifyDocID","respond","status","body","Response","json","hasOwnProperty","value","key","Object","prototype","call","normalizeID","undefined","normalizeMoveDocumentBody","incomingData","JSON","parse","Array","isArray","parentID","readBodyFromRequest","req","directBody","data","jsonBody","text","getPayloadCollection","collectionSlug","payload","collections","usesNumericID","collection","idType","customIDType","db","defaultIDType","toCollectionID","args","id","Number","getRequestedLocale","locale","collectionHasDrafts","Boolean","config","versions","drafts","assertUpdateAccess","movedID","nextParentID","parentFieldSlug","updateAccess","access","update","accessResult","message","i18n","t","matchingDocs","find","depth","draft","limit","overrideAccess","where","and","equals","docs","length","createMovePageEndpoint","handler","movedIDFromRoute","routeParams","accessError","docsResult","fallbackLocale","docsByID","Map","map","doc","movedDoc","get","has","currentParentID","childrenByParentID","descendantIDs","includes","ok","method","path"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/endpoints/createMovePageEndpoint.ts"],"sourcesContent":["import type { Endpoint, PayloadRequest, Where } from 'payload'\r\n\r\nimport { CANCEL_DRAG_MESSAGE } from '../utilities/moveValidation.js'\r\nimport {\r\n buildChildrenByParentID,\r\n collectDescendantIDs,\r\n getDocParentID,\r\n stringifyDocID,\r\n} from '../utilities/pageTree.js'\r\nimport { pageTreeMoveContextKey, type PageTreeSourceDoc } from '../types.js'\r\n\r\ntype MoveDocumentRequestBody = {\r\n parentID: null | string\r\n}\r\n\r\ntype PayloadCollectionLike = {\r\n config?: {\r\n access?: {\r\n update?: ((args: Record<string, unknown>) => Promise<Record<string, unknown> | boolean> | Record<string, unknown> | boolean) | undefined\r\n }\r\n versions?: {\r\n drafts?: unknown\r\n }\r\n }\r\n customIDType?: string\r\n}\r\n\r\nfunction respond(status: number, body: Record<string, unknown>) {\r\n return Response.json(body, { status })\r\n}\r\n\r\nfunction hasOwnProperty(value: object, key: PropertyKey): boolean {\r\n return Object.prototype.hasOwnProperty.call(value, key)\r\n}\r\n\r\nfunction normalizeID(value: unknown): null | string {\r\n if (value === null || value === undefined || value === '') {\r\n return null\r\n }\r\n\r\n if (typeof value === 'number' || typeof value === 'string') {\r\n return stringifyDocID(value)\r\n }\r\n\r\n return null\r\n}\r\n\r\nfunction normalizeMoveDocumentBody(value: unknown): MoveDocumentRequestBody | null {\r\n const incomingData =\r\n typeof value === 'string'\r\n ? (() => {\r\n try {\r\n return JSON.parse(value) as unknown\r\n } catch {\r\n return null\r\n }\r\n })()\r\n : value\r\n\r\n if (!incomingData || typeof incomingData !== 'object' || Array.isArray(incomingData)) {\r\n return null\r\n }\r\n\r\n if (!hasOwnProperty(incomingData, 'parentID')) {\r\n return null\r\n }\r\n\r\n const parentID = normalizeID((incomingData as { parentID?: unknown }).parentID)\r\n\r\n if (\r\n (incomingData as { parentID?: unknown }).parentID !== null &&\r\n (incomingData as { parentID?: unknown }).parentID !== undefined &&\r\n parentID === null\r\n ) {\r\n return null\r\n }\r\n\r\n return {\r\n parentID,\r\n }\r\n}\r\n\r\nasync function readBodyFromRequest(req: PayloadRequest): Promise<MoveDocumentRequestBody | null> {\r\n const directBody = normalizeMoveDocumentBody(req.data)\r\n\r\n if (directBody) {\r\n return directBody\r\n }\r\n\r\n if (typeof req.json === 'function') {\r\n try {\r\n const jsonBody = normalizeMoveDocumentBody(await req.json())\r\n\r\n if (jsonBody) {\r\n return jsonBody\r\n }\r\n } catch {\r\n // Fall through to the text-based fallback when the runtime does not hydrate req.data.\r\n }\r\n }\r\n\r\n if (typeof req.text === 'function') {\r\n try {\r\n return normalizeMoveDocumentBody(await req.text())\r\n } catch {\r\n return null\r\n }\r\n }\r\n\r\n return null\r\n}\r\n\r\nfunction getPayloadCollection({\r\n collectionSlug,\r\n req,\r\n}: {\r\n collectionSlug: string\r\n req: PayloadRequest\r\n}): PayloadCollectionLike | undefined {\r\n return (req.payload.collections as unknown as Record<string, PayloadCollectionLike | undefined>)[\r\n collectionSlug\r\n ]\r\n}\r\n\r\nfunction usesNumericID({\r\n collectionSlug,\r\n req,\r\n}: {\r\n collectionSlug: string\r\n req: PayloadRequest\r\n}): boolean {\r\n const collection = getPayloadCollection({ collectionSlug, req })\r\n\r\n if (!collection) {\r\n return false\r\n }\r\n\r\n const idType = collection.customIDType ?? req.payload.db.defaultIDType\r\n\r\n return idType === 'number'\r\n}\r\n\r\nfunction toCollectionID(args: {\r\n collectionSlug: string\r\n id: string\r\n req: PayloadRequest\r\n}): number | string {\r\n const { collectionSlug, id, req } = args\r\n\r\n if (!usesNumericID({ collectionSlug, req })) {\r\n return id\r\n }\r\n\r\n return Number(id)\r\n}\r\n\r\nfunction getRequestedLocale(req: PayloadRequest): string | undefined {\r\n return req.locale && req.locale !== 'all' ? req.locale : undefined\r\n}\r\n\r\nfunction collectionHasDrafts(args: {\r\n collectionSlug: string\r\n req: PayloadRequest\r\n}): boolean {\r\n return Boolean(getPayloadCollection(args)?.config?.versions?.drafts)\r\n}\r\n\r\nasync function assertUpdateAccess(args: {\r\n collectionSlug: string\r\n movedID: number | string\r\n nextParentID: null | number | string\r\n parentFieldSlug: string\r\n req: PayloadRequest\r\n}): Promise<Response | null> {\r\n const { collectionSlug, movedID, nextParentID, parentFieldSlug, req } = args\r\n const collection = getPayloadCollection({ collectionSlug, req })\r\n const updateAccess = collection?.config?.access?.update\r\n\r\n if (!updateAccess) {\r\n return null\r\n }\r\n\r\n const accessResult = await updateAccess({\r\n data: { [parentFieldSlug]: nextParentID } as never,\r\n id: movedID as never,\r\n req,\r\n })\r\n\r\n if (accessResult === false) {\r\n return respond(403, {\r\n message: req.i18n.t('error:unauthorized'),\r\n })\r\n }\r\n\r\n if (accessResult && typeof accessResult === 'object') {\r\n const matchingDocs = await req.payload.find({\r\n collection: collectionSlug as never,\r\n depth: 0,\r\n draft: collectionHasDrafts({ collectionSlug, req }) ? true : undefined,\r\n limit: 1,\r\n locale: getRequestedLocale(req) as never,\r\n overrideAccess: true,\r\n req,\r\n where: {\r\n and: [\r\n {\r\n id: {\r\n equals: movedID,\r\n },\r\n },\r\n accessResult as Where,\r\n ],\r\n },\r\n } as never)\r\n\r\n if (matchingDocs.docs.length === 0) {\r\n return respond(403, {\r\n message: req.i18n.t('error:unauthorized'),\r\n })\r\n }\r\n }\r\n\r\n return null\r\n}\r\n\r\nexport function createMovePageEndpoint(args: {\r\n collectionSlug: string\r\n parentFieldSlug: string\r\n}): Endpoint {\r\n const { collectionSlug, parentFieldSlug } = args\r\n\r\n return {\r\n handler: async (req) => {\r\n const movedIDFromRoute = normalizeID(req.routeParams?.id)\r\n\r\n if (!movedIDFromRoute) {\r\n return respond(400, {\r\n message: 'Document ID was not specified.',\r\n })\r\n }\r\n\r\n const body = await readBodyFromRequest(req)\r\n\r\n if (!body) {\r\n return respond(400, {\r\n message: 'A valid parentID is required.',\r\n })\r\n }\r\n\r\n const movedID = toCollectionID({\r\n collectionSlug,\r\n id: movedIDFromRoute,\r\n req,\r\n })\r\n const nextParentID =\r\n body.parentID === null\r\n ? null\r\n : toCollectionID({\r\n collectionSlug,\r\n id: body.parentID,\r\n req,\r\n })\r\n const accessError = await assertUpdateAccess({\r\n collectionSlug,\r\n movedID,\r\n nextParentID,\r\n parentFieldSlug,\r\n req,\r\n })\r\n\r\n if (accessError) {\r\n return accessError\r\n }\r\n\r\n const docsResult = await req.payload.find({\r\n collection: collectionSlug as never,\r\n depth: 0,\r\n draft: collectionHasDrafts({ collectionSlug, req }) ? true : undefined,\r\n fallbackLocale: false as never,\r\n limit: 0,\r\n locale: getRequestedLocale(req) as never,\r\n overrideAccess: true,\r\n req,\r\n } as never)\r\n const docs = docsResult.docs as unknown as PageTreeSourceDoc[]\r\n const docsByID = new Map(docs.map((doc) => [stringifyDocID(doc.id), doc]))\r\n const movedDoc = docsByID.get(movedIDFromRoute)\r\n\r\n if (!movedDoc) {\r\n return respond(404, {\r\n message: 'Document not found.',\r\n })\r\n }\r\n\r\n if (body.parentID !== null && !docsByID.has(body.parentID)) {\r\n return respond(400, {\r\n message: 'Parent document not found.',\r\n })\r\n }\r\n\r\n const currentParentID = getDocParentID(movedDoc, parentFieldSlug)\r\n\r\n if (currentParentID === body.parentID) {\r\n return respond(400, {\r\n message: 'Document already has that parent.',\r\n })\r\n }\r\n\r\n if (body.parentID === movedIDFromRoute) {\r\n return respond(400, {\r\n message: CANCEL_DRAG_MESSAGE,\r\n })\r\n }\r\n\r\n const childrenByParentID = buildChildrenByParentID({\r\n docs,\r\n parentFieldSlug,\r\n })\r\n const descendantIDs = collectDescendantIDs(movedIDFromRoute, childrenByParentID)\r\n\r\n if (body.parentID !== null && descendantIDs.includes(body.parentID)) {\r\n return respond(400, {\r\n message: 'A document cannot be moved under one of its descendants.',\r\n })\r\n }\r\n\r\n await req.payload.update({\r\n collection: collectionSlug as never,\r\n context: {\r\n [pageTreeMoveContextKey]: true,\r\n },\r\n data: {\r\n [parentFieldSlug]:\r\n body.parentID === null\r\n ? null\r\n : toCollectionID({\r\n collectionSlug,\r\n id: body.parentID,\r\n req,\r\n }),\r\n } as never,\r\n depth: 0,\r\n draft: collectionHasDrafts({ collectionSlug, req }) ? true : undefined,\r\n id: movedID as never,\r\n locale: getRequestedLocale(req) as never,\r\n overrideAccess: true,\r\n req,\r\n } as never)\r\n\r\n return respond(200, {\r\n movedID: movedIDFromRoute,\r\n ok: true,\r\n parentID: body.parentID,\r\n })\r\n },\r\n method: 'post',\r\n path: '/:id/move',\r\n }\r\n}\r\n"],"names":["CANCEL_DRAG_MESSAGE","buildChildrenByParentID","collectDescendantIDs","getDocParentID","stringifyDocID","pageTreeMoveContextKey","respond","status","body","Response","json","hasOwnProperty","value","key","Object","prototype","call","normalizeID","undefined","normalizeMoveDocumentBody","incomingData","JSON","parse","Array","isArray","parentID","readBodyFromRequest","req","directBody","data","jsonBody","text","getPayloadCollection","collectionSlug","payload","collections","usesNumericID","collection","idType","customIDType","db","defaultIDType","toCollectionID","args","id","Number","getRequestedLocale","locale","collectionHasDrafts","Boolean","config","versions","drafts","assertUpdateAccess","movedID","nextParentID","parentFieldSlug","updateAccess","access","update","accessResult","message","i18n","t","matchingDocs","find","depth","draft","limit","overrideAccess","where","and","equals","docs","length","createMovePageEndpoint","handler","movedIDFromRoute","routeParams","accessError","docsResult","fallbackLocale","docsByID","Map","map","doc","movedDoc","get","has","currentParentID","childrenByParentID","descendantIDs","includes","context","ok","method","path"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Config } from 'payload';
|
|
2
2
|
import type { NestedDocsPageTreePluginConfig } from './types.js';
|
|
3
|
-
export type { NestedDocsPageTreePluginBadgeConfig, NestedDocsPageTreePluginBadgeMap, NestedDocsPageTreePluginBadgeStatus, NestedDocsPageTreePluginConfig, NestedDocsPageTreePluginHomeIndicatorConfig, } from './types.js';
|
|
3
|
+
export type { NestedDocsPageTreePluginBadgeConfig, NestedDocsPageTreePluginBadgeMap, NestedDocsPageTreePluginBadgeStatus, NestedDocsPageTreePluginConfig, NestedDocsPageTreePluginHomeIndicatorConfig, PageTreeMoveContext, } from './types.js';
|
|
4
|
+
export { pageTreeMoveContextKey } from './types.js';
|
|
4
5
|
export declare const nestedDocsPageTreePlugin: (pluginOptions: NestedDocsPageTreePluginConfig) => (config: Config) => Config;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createMovePageEndpoint } from './endpoints/createMovePageEndpoint.js';
|
|
2
|
-
import { nestedDocsPageTreePluginCustomKey } from './types.js';
|
|
2
|
+
import { nestedDocsPageTreePluginCustomKey, pageTreeMoveContextKey, pageTreeMoveRequestHeader, pageTreeMoveRequestHeaderValue } from './types.js';
|
|
3
3
|
import { normalizeNestedDocsPageTreePluginBadgeConfig } from './utilities/badgeConfig.js';
|
|
4
4
|
const DEFAULT_BREADCRUMBS_FIELD_SLUG = 'breadcrumbs';
|
|
5
5
|
const DEFAULT_HOME_INDICATOR_COLLECTIONS = [
|
|
@@ -8,6 +8,25 @@ const DEFAULT_HOME_INDICATOR_COLLECTIONS = [
|
|
|
8
8
|
const DEFAULT_LIMIT = 100;
|
|
9
9
|
const DEFAULT_PARENT_FIELD_SLUG = 'parent';
|
|
10
10
|
const PAGE_TREE_LIST_VIEW_PATH = 'payload-nested-docs-page-tree/rsc#NestedDocsPageTreeListView';
|
|
11
|
+
// Page-tree owns parent moves, so those pass Local API context directly.
|
|
12
|
+
// Reorders go through Payload's shared /api/reorder endpoint; this hook
|
|
13
|
+
// bridges the plugin-owned request signal into the same hook context flag.
|
|
14
|
+
// The bridge requires an authenticated request — the header alone is not a
|
|
15
|
+
// trust boundary, but rejecting anonymous callers closes the only path that
|
|
16
|
+
// could set the flag without already holding update access.
|
|
17
|
+
const tagPageTreeMoveContextHook = ({ data, req })=>{
|
|
18
|
+
if (req.headers?.get(pageTreeMoveRequestHeader) !== pageTreeMoveRequestHeaderValue) {
|
|
19
|
+
return data;
|
|
20
|
+
}
|
|
21
|
+
if (!req.user) {
|
|
22
|
+
return data;
|
|
23
|
+
}
|
|
24
|
+
if (!req.context) {
|
|
25
|
+
req.context = {};
|
|
26
|
+
}
|
|
27
|
+
req.context[pageTreeMoveContextKey] = true;
|
|
28
|
+
return data;
|
|
29
|
+
};
|
|
11
30
|
function getTopLevelField(collection, fieldName) {
|
|
12
31
|
return collection.fields.find((field)=>'name' in field && field.name === fieldName);
|
|
13
32
|
}
|
|
@@ -69,6 +88,7 @@ function getHomeIndicatorCollectionSlugs(homeIndicator) {
|
|
|
69
88
|
}
|
|
70
89
|
return new Set(homeIndicator?.collections ?? DEFAULT_HOME_INDICATOR_COLLECTIONS);
|
|
71
90
|
}
|
|
91
|
+
export { pageTreeMoveContextKey } from './types.js';
|
|
72
92
|
export const nestedDocsPageTreePlugin = (pluginOptions)=>(config)=>{
|
|
73
93
|
if (!pluginOptions.collections?.length) {
|
|
74
94
|
throw new Error('payload-nested-docs-page-tree requires at least one collection slug.');
|
|
@@ -140,7 +160,14 @@ export const nestedDocsPageTreePlugin = (pluginOptions)=>(config)=>{
|
|
|
140
160
|
breadcrumbsFieldSlug,
|
|
141
161
|
field,
|
|
142
162
|
hideBreadcrumbs
|
|
143
|
-
}))
|
|
163
|
+
})),
|
|
164
|
+
hooks: collection.orderable ? {
|
|
165
|
+
...collection.hooks ?? {},
|
|
166
|
+
beforeChange: [
|
|
167
|
+
tagPageTreeMoveContextHook,
|
|
168
|
+
...collection.hooks?.beforeChange ?? []
|
|
169
|
+
]
|
|
170
|
+
} : collection.hooks
|
|
144
171
|
};
|
|
145
172
|
});
|
|
146
173
|
const missingCollections = pluginOptions.collections.filter((collectionSlug)=>!foundCollectionSlugs.has(collectionSlug));
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { CollectionConfig, Config } from 'payload'\r\n\r\nimport { createMovePageEndpoint } from './endpoints/createMovePageEndpoint.js'\r\nimport type {\r\n NestedDocsPageTreePluginCollectionCustom,\r\n NestedDocsPageTreePluginConfig,\r\n} from './types.js'\r\nimport { nestedDocsPageTreePluginCustomKey } from './types.js'\r\nimport { normalizeNestedDocsPageTreePluginBadgeConfig } from './utilities/badgeConfig.js'\r\n\r\nconst DEFAULT_BREADCRUMBS_FIELD_SLUG = 'breadcrumbs'\nconst DEFAULT_HOME_INDICATOR_COLLECTIONS = ['pages']\nconst DEFAULT_LIMIT = 100\nconst DEFAULT_PARENT_FIELD_SLUG = 'parent'\nconst PAGE_TREE_LIST_VIEW_PATH =\n 'payload-nested-docs-page-tree/rsc#NestedDocsPageTreeListView'\ntype CollectionEndpoint = NonNullable<Exclude<CollectionConfig['endpoints'], false>>[number]\n\r\nfunction getTopLevelField(\r\n collection: Pick<CollectionConfig, 'fields'>,\r\n fieldName: string,\r\n) {\r\n return collection.fields.find((field) => 'name' in field && field.name === fieldName)\r\n}\r\n\r\nfunction getCollectionEndpoints(collection: CollectionConfig): CollectionEndpoint[] {\r\n return Array.isArray(collection.endpoints) ? [...collection.endpoints] : []\r\n}\r\n\r\nfunction patchBreadcrumbField<TField extends CollectionConfig['fields'][number]>(args: {\r\n breadcrumbsFieldSlug: string\r\n field: TField\r\n hideBreadcrumbs: boolean\r\n}): TField {\r\n const { breadcrumbsFieldSlug, field, hideBreadcrumbs } = args\r\n\r\n if (!('name' in field) || field.name !== breadcrumbsFieldSlug) {\r\n return field\r\n }\r\n\r\n return {\r\n ...field,\r\n admin: {\r\n ...(field.admin ?? {}),\r\n hidden: hideBreadcrumbs,\r\n },\r\n } as TField\r\n}\r\n\r\nfunction validateTargetCollection(args: {\r\n breadcrumbsFieldSlug: string\r\n collection: CollectionConfig\r\n parentFieldSlug: string\r\n}) {\r\n const { breadcrumbsFieldSlug, collection, parentFieldSlug } = args\r\n\r\n if (typeof collection.admin?.useAsTitle !== 'string' || collection.admin.useAsTitle.includes('.')) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree requires \"${collection.slug}\" to define a top-level admin.useAsTitle field.`,\r\n )\r\n }\r\n\r\n if (!getTopLevelField(collection, collection.admin.useAsTitle)) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree could not find the useAsTitle field \"${collection.admin.useAsTitle}\" on \"${collection.slug}\".`,\r\n )\r\n }\r\n\r\n if (!getTopLevelField(collection, parentFieldSlug)) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree requires \"${collection.slug}\" to already define the nested docs parent field \"${parentFieldSlug}\". Register @payloadcms/plugin-nested-docs before payload-nested-docs-page-tree.`,\r\n )\r\n }\r\n\r\n if (!getTopLevelField(collection, breadcrumbsFieldSlug)) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree requires \"${collection.slug}\" to already define the nested docs breadcrumbs field \"${breadcrumbsFieldSlug}\". Register @payloadcms/plugin-nested-docs before payload-nested-docs-page-tree.`,\r\n )\r\n }\r\n\r\n const existingListView = collection.admin?.components?.views?.list?.Component\r\n\r\n if (existingListView && existingListView !== PAGE_TREE_LIST_VIEW_PATH) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree cannot own the \"${collection.slug}\" list view because the collection already defines a custom admin.components.views.list.Component.`,\r\n )\r\n }\r\n\r\n const existingMoveEndpoint = getCollectionEndpoints(collection).find(\r\n (endpoint) => endpoint.path === '/:id/move',\r\n )\r\n\r\n if (existingMoveEndpoint) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree cannot add the move endpoint to \"${collection.slug}\" because the collection already defines POST /:id/move.`,\r\n )\r\n }\r\n}\r\n\r\nfunction buildCollectionCustom(args: {\n badges: NestedDocsPageTreePluginCollectionCustom['badges']\n breadcrumbsFieldSlug: string\n defaultLimit: number\n hideBreadcrumbs: boolean\n homeIndicator: NestedDocsPageTreePluginCollectionCustom['homeIndicator']\n parentFieldSlug: string\n}): NestedDocsPageTreePluginCollectionCustom {\n const {\n badges,\n breadcrumbsFieldSlug,\n defaultLimit,\n hideBreadcrumbs,\n homeIndicator,\n parentFieldSlug,\n } = args\n\n return {\n badges,\n breadcrumbsFieldSlug,\n defaultLimit,\n hideBreadcrumbs,\n homeIndicator,\n parentFieldSlug,\n }\n}\n\nfunction getHomeIndicatorCollectionSlugs(\n homeIndicator: NestedDocsPageTreePluginConfig['homeIndicator'],\n): Set<string> {\n if (homeIndicator === false) {\n return new Set()\n }\n\n return new Set(homeIndicator?.collections ?? DEFAULT_HOME_INDICATOR_COLLECTIONS)\n}\n\r\nexport type {\r\n NestedDocsPageTreePluginBadgeConfig,\n NestedDocsPageTreePluginBadgeMap,\n NestedDocsPageTreePluginBadgeStatus,\n NestedDocsPageTreePluginConfig,\n NestedDocsPageTreePluginHomeIndicatorConfig,\n} from './types.js'\n\r\nexport const nestedDocsPageTreePlugin =\r\n (pluginOptions: NestedDocsPageTreePluginConfig) =>\r\n (config: Config): Config => {\r\n if (!pluginOptions.collections?.length) {\r\n throw new Error('payload-nested-docs-page-tree requires at least one collection slug.')\r\n }\r\n\r\n if (pluginOptions.disabled) {\r\n return config\r\n }\r\n\r\n const breadcrumbsFieldSlug =\r\n pluginOptions.breadcrumbsFieldSlug ?? DEFAULT_BREADCRUMBS_FIELD_SLUG\r\n const defaultLimit = pluginOptions.defaultLimit ?? DEFAULT_LIMIT\r\n const hideBreadcrumbs = pluginOptions.hideBreadcrumbs ?? true\n const parentFieldSlug = pluginOptions.parentFieldSlug ?? DEFAULT_PARENT_FIELD_SLUG\n const badges = normalizeNestedDocsPageTreePluginBadgeConfig(pluginOptions.badges)\n const homeIndicatorCollectionSlugs = getHomeIndicatorCollectionSlugs(\n pluginOptions.homeIndicator,\n )\n const targetedCollectionSlugs = new Set<string>(pluginOptions.collections)\n\r\n if (!config.collections?.length) {\r\n throw new Error('payload-nested-docs-page-tree could not find any collections to patch.')\r\n }\r\n\r\n const foundCollectionSlugs = new Set<string>()\r\n const nextCollections = config.collections.map((collection) => {\r\n if (!targetedCollectionSlugs.has(collection.slug)) {\r\n return collection\r\n }\r\n\r\n foundCollectionSlugs.add(collection.slug)\r\n validateTargetCollection({\r\n breadcrumbsFieldSlug,\r\n collection,\r\n parentFieldSlug,\r\n })\r\n\r\n return {\r\n ...collection,\r\n admin: {\r\n ...(collection.admin ?? {}),\r\n components: {\r\n ...(collection.admin?.components ?? {}),\r\n views: {\r\n ...(collection.admin?.components?.views ?? {}),\r\n list: {\r\n ...(collection.admin?.components?.views?.list ?? {}),\r\n Component: PAGE_TREE_LIST_VIEW_PATH,\r\n },\r\n },\r\n },\r\n pagination: {\r\n ...(collection.admin?.pagination ?? {}),\r\n defaultLimit:\r\n collection.admin?.pagination?.defaultLimit === undefined\r\n ? defaultLimit\r\n : collection.admin.pagination.defaultLimit,\r\n },\r\n },\r\n custom: {\r\n ...(collection.custom ?? {}),\r\n [nestedDocsPageTreePluginCustomKey]: buildCollectionCustom({\n badges,\n breadcrumbsFieldSlug,\n defaultLimit,\n hideBreadcrumbs,\n homeIndicator: {\n enabled: homeIndicatorCollectionSlugs.has(collection.slug),\n },\n parentFieldSlug,\n }),\n },\n endpoints: [\r\n ...getCollectionEndpoints(collection),\r\n createMovePageEndpoint({\r\n collectionSlug: collection.slug,\r\n parentFieldSlug,\r\n }),\r\n ],\r\n fields: collection.fields.map((field) =>\r\n patchBreadcrumbField({\r\n breadcrumbsFieldSlug,\r\n field,\r\n hideBreadcrumbs,\r\n }),\r\n ),\r\n }\r\n })\r\n\r\n const missingCollections = pluginOptions.collections.filter(\r\n (collectionSlug) => !foundCollectionSlugs.has(collectionSlug),\r\n )\r\n\r\n if (missingCollections.length > 0) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree could not find the following collections: ${missingCollections.join(', ')}`,\r\n )\r\n }\r\n\r\n return {\r\n ...config,\r\n collections: nextCollections as CollectionConfig[],\r\n }\r\n }\r\n"],"names":["createMovePageEndpoint","nestedDocsPageTreePluginCustomKey","normalizeNestedDocsPageTreePluginBadgeConfig","DEFAULT_BREADCRUMBS_FIELD_SLUG","DEFAULT_HOME_INDICATOR_COLLECTIONS","DEFAULT_LIMIT","DEFAULT_PARENT_FIELD_SLUG","PAGE_TREE_LIST_VIEW_PATH","getTopLevelField","collection","fieldName","fields","find","field","name","getCollectionEndpoints","Array","isArray","endpoints","patchBreadcrumbField","args","breadcrumbsFieldSlug","hideBreadcrumbs","admin","hidden","validateTargetCollection","parentFieldSlug","useAsTitle","includes","Error","slug","existingListView","components","views","list","Component","existingMoveEndpoint","endpoint","path","buildCollectionCustom","badges","defaultLimit","homeIndicator","getHomeIndicatorCollectionSlugs","Set","collections","nestedDocsPageTreePlugin","pluginOptions","config","length","disabled","homeIndicatorCollectionSlugs","targetedCollectionSlugs","foundCollectionSlugs","nextCollections","map","has","add","pagination","undefined","custom","enabled","collectionSlug","missingCollections","filter","join"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { CollectionBeforeChangeHook, CollectionConfig, Config } from 'payload'\r\n\r\nimport { createMovePageEndpoint } from './endpoints/createMovePageEndpoint.js'\r\nimport type {\r\n NestedDocsPageTreePluginCollectionCustom,\r\n NestedDocsPageTreePluginConfig,\r\n} from './types.js'\r\nimport {\r\n nestedDocsPageTreePluginCustomKey,\r\n pageTreeMoveContextKey,\r\n pageTreeMoveRequestHeader,\r\n pageTreeMoveRequestHeaderValue,\r\n} from './types.js'\r\nimport { normalizeNestedDocsPageTreePluginBadgeConfig } from './utilities/badgeConfig.js'\r\n\r\nconst DEFAULT_BREADCRUMBS_FIELD_SLUG = 'breadcrumbs'\r\nconst DEFAULT_HOME_INDICATOR_COLLECTIONS = ['pages']\r\nconst DEFAULT_LIMIT = 100\r\nconst DEFAULT_PARENT_FIELD_SLUG = 'parent'\r\nconst PAGE_TREE_LIST_VIEW_PATH =\r\n 'payload-nested-docs-page-tree/rsc#NestedDocsPageTreeListView'\r\ntype CollectionEndpoint = NonNullable<Exclude<CollectionConfig['endpoints'], false>>[number]\r\n\r\n// Page-tree owns parent moves, so those pass Local API context directly.\r\n// Reorders go through Payload's shared /api/reorder endpoint; this hook\r\n// bridges the plugin-owned request signal into the same hook context flag.\r\n// The bridge requires an authenticated request — the header alone is not a\r\n// trust boundary, but rejecting anonymous callers closes the only path that\r\n// could set the flag without already holding update access.\r\nconst tagPageTreeMoveContextHook: CollectionBeforeChangeHook = ({ data, req }) => {\r\n if (req.headers?.get(pageTreeMoveRequestHeader) !== pageTreeMoveRequestHeaderValue) {\r\n return data\r\n }\r\n\r\n if (!req.user) {\r\n return data\r\n }\r\n\r\n if (!req.context) {\r\n req.context = {}\r\n }\r\n\r\n req.context[pageTreeMoveContextKey] = true\r\n\r\n return data\r\n}\r\n\r\nfunction getTopLevelField(\r\n collection: Pick<CollectionConfig, 'fields'>,\r\n fieldName: string,\r\n) {\r\n return collection.fields.find((field) => 'name' in field && field.name === fieldName)\r\n}\r\n\r\nfunction getCollectionEndpoints(collection: CollectionConfig): CollectionEndpoint[] {\r\n return Array.isArray(collection.endpoints) ? [...collection.endpoints] : []\r\n}\r\n\r\nfunction patchBreadcrumbField<TField extends CollectionConfig['fields'][number]>(args: {\r\n breadcrumbsFieldSlug: string\r\n field: TField\r\n hideBreadcrumbs: boolean\r\n}): TField {\r\n const { breadcrumbsFieldSlug, field, hideBreadcrumbs } = args\r\n\r\n if (!('name' in field) || field.name !== breadcrumbsFieldSlug) {\r\n return field\r\n }\r\n\r\n return {\r\n ...field,\r\n admin: {\r\n ...(field.admin ?? {}),\r\n hidden: hideBreadcrumbs,\r\n },\r\n } as TField\r\n}\r\n\r\nfunction validateTargetCollection(args: {\r\n breadcrumbsFieldSlug: string\r\n collection: CollectionConfig\r\n parentFieldSlug: string\r\n}) {\r\n const { breadcrumbsFieldSlug, collection, parentFieldSlug } = args\r\n\r\n if (typeof collection.admin?.useAsTitle !== 'string' || collection.admin.useAsTitle.includes('.')) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree requires \"${collection.slug}\" to define a top-level admin.useAsTitle field.`,\r\n )\r\n }\r\n\r\n if (!getTopLevelField(collection, collection.admin.useAsTitle)) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree could not find the useAsTitle field \"${collection.admin.useAsTitle}\" on \"${collection.slug}\".`,\r\n )\r\n }\r\n\r\n if (!getTopLevelField(collection, parentFieldSlug)) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree requires \"${collection.slug}\" to already define the nested docs parent field \"${parentFieldSlug}\". Register @payloadcms/plugin-nested-docs before payload-nested-docs-page-tree.`,\r\n )\r\n }\r\n\r\n if (!getTopLevelField(collection, breadcrumbsFieldSlug)) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree requires \"${collection.slug}\" to already define the nested docs breadcrumbs field \"${breadcrumbsFieldSlug}\". Register @payloadcms/plugin-nested-docs before payload-nested-docs-page-tree.`,\r\n )\r\n }\r\n\r\n const existingListView = collection.admin?.components?.views?.list?.Component\r\n\r\n if (existingListView && existingListView !== PAGE_TREE_LIST_VIEW_PATH) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree cannot own the \"${collection.slug}\" list view because the collection already defines a custom admin.components.views.list.Component.`,\r\n )\r\n }\r\n\r\n const existingMoveEndpoint = getCollectionEndpoints(collection).find(\r\n (endpoint) => endpoint.path === '/:id/move',\r\n )\r\n\r\n if (existingMoveEndpoint) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree cannot add the move endpoint to \"${collection.slug}\" because the collection already defines POST /:id/move.`,\r\n )\r\n }\r\n}\r\n\r\nfunction buildCollectionCustom(args: {\r\n badges: NestedDocsPageTreePluginCollectionCustom['badges']\r\n breadcrumbsFieldSlug: string\r\n defaultLimit: number\r\n hideBreadcrumbs: boolean\r\n homeIndicator: NestedDocsPageTreePluginCollectionCustom['homeIndicator']\r\n parentFieldSlug: string\r\n}): NestedDocsPageTreePluginCollectionCustom {\r\n const {\r\n badges,\r\n breadcrumbsFieldSlug,\r\n defaultLimit,\r\n hideBreadcrumbs,\r\n homeIndicator,\r\n parentFieldSlug,\r\n } = args\r\n\r\n return {\r\n badges,\r\n breadcrumbsFieldSlug,\r\n defaultLimit,\r\n hideBreadcrumbs,\r\n homeIndicator,\r\n parentFieldSlug,\r\n }\r\n}\r\n\r\nfunction getHomeIndicatorCollectionSlugs(\r\n homeIndicator: NestedDocsPageTreePluginConfig['homeIndicator'],\r\n): Set<string> {\r\n if (homeIndicator === false) {\r\n return new Set()\r\n }\r\n\r\n return new Set(homeIndicator?.collections ?? DEFAULT_HOME_INDICATOR_COLLECTIONS)\r\n}\r\n\r\nexport type {\r\n NestedDocsPageTreePluginBadgeConfig,\r\n NestedDocsPageTreePluginBadgeMap,\r\n NestedDocsPageTreePluginBadgeStatus,\r\n NestedDocsPageTreePluginConfig,\r\n NestedDocsPageTreePluginHomeIndicatorConfig,\r\n PageTreeMoveContext,\r\n} from './types.js'\r\n\r\nexport { pageTreeMoveContextKey } from './types.js'\r\n\r\nexport const nestedDocsPageTreePlugin =\r\n (pluginOptions: NestedDocsPageTreePluginConfig) =>\r\n (config: Config): Config => {\r\n if (!pluginOptions.collections?.length) {\r\n throw new Error('payload-nested-docs-page-tree requires at least one collection slug.')\r\n }\r\n\r\n if (pluginOptions.disabled) {\r\n return config\r\n }\r\n\r\n const breadcrumbsFieldSlug =\r\n pluginOptions.breadcrumbsFieldSlug ?? DEFAULT_BREADCRUMBS_FIELD_SLUG\r\n const defaultLimit = pluginOptions.defaultLimit ?? DEFAULT_LIMIT\r\n const hideBreadcrumbs = pluginOptions.hideBreadcrumbs ?? true\r\n const parentFieldSlug = pluginOptions.parentFieldSlug ?? DEFAULT_PARENT_FIELD_SLUG\r\n const badges = normalizeNestedDocsPageTreePluginBadgeConfig(pluginOptions.badges)\r\n const homeIndicatorCollectionSlugs = getHomeIndicatorCollectionSlugs(\r\n pluginOptions.homeIndicator,\r\n )\r\n const targetedCollectionSlugs = new Set<string>(pluginOptions.collections)\r\n\r\n if (!config.collections?.length) {\r\n throw new Error('payload-nested-docs-page-tree could not find any collections to patch.')\r\n }\r\n\r\n const foundCollectionSlugs = new Set<string>()\r\n const nextCollections = config.collections.map((collection) => {\r\n if (!targetedCollectionSlugs.has(collection.slug)) {\r\n return collection\r\n }\r\n\r\n foundCollectionSlugs.add(collection.slug)\r\n validateTargetCollection({\r\n breadcrumbsFieldSlug,\r\n collection,\r\n parentFieldSlug,\r\n })\r\n\r\n return {\r\n ...collection,\r\n admin: {\r\n ...(collection.admin ?? {}),\r\n components: {\r\n ...(collection.admin?.components ?? {}),\r\n views: {\r\n ...(collection.admin?.components?.views ?? {}),\r\n list: {\r\n ...(collection.admin?.components?.views?.list ?? {}),\r\n Component: PAGE_TREE_LIST_VIEW_PATH,\r\n },\r\n },\r\n },\r\n pagination: {\r\n ...(collection.admin?.pagination ?? {}),\r\n defaultLimit:\r\n collection.admin?.pagination?.defaultLimit === undefined\r\n ? defaultLimit\r\n : collection.admin.pagination.defaultLimit,\r\n },\r\n },\r\n custom: {\r\n ...(collection.custom ?? {}),\r\n [nestedDocsPageTreePluginCustomKey]: buildCollectionCustom({\r\n badges,\r\n breadcrumbsFieldSlug,\r\n defaultLimit,\r\n hideBreadcrumbs,\r\n homeIndicator: {\r\n enabled: homeIndicatorCollectionSlugs.has(collection.slug),\r\n },\r\n parentFieldSlug,\r\n }),\r\n },\r\n endpoints: [\r\n ...getCollectionEndpoints(collection),\r\n createMovePageEndpoint({\r\n collectionSlug: collection.slug,\r\n parentFieldSlug,\r\n }),\r\n ],\r\n fields: collection.fields.map((field) =>\r\n patchBreadcrumbField({\r\n breadcrumbsFieldSlug,\r\n field,\r\n hideBreadcrumbs,\r\n }),\r\n ),\r\n hooks: collection.orderable\r\n ? {\r\n ...(collection.hooks ?? {}),\r\n beforeChange: [\r\n tagPageTreeMoveContextHook,\r\n ...(collection.hooks?.beforeChange ?? []),\r\n ],\r\n }\r\n : collection.hooks,\r\n }\r\n })\r\n\r\n const missingCollections = pluginOptions.collections.filter(\r\n (collectionSlug) => !foundCollectionSlugs.has(collectionSlug),\r\n )\r\n\r\n if (missingCollections.length > 0) {\r\n throw new Error(\r\n `payload-nested-docs-page-tree could not find the following collections: ${missingCollections.join(', ')}`,\r\n )\r\n }\r\n\r\n return {\r\n ...config,\r\n collections: nextCollections as CollectionConfig[],\r\n }\r\n }\r\n"],"names":["createMovePageEndpoint","nestedDocsPageTreePluginCustomKey","pageTreeMoveContextKey","pageTreeMoveRequestHeader","pageTreeMoveRequestHeaderValue","normalizeNestedDocsPageTreePluginBadgeConfig","DEFAULT_BREADCRUMBS_FIELD_SLUG","DEFAULT_HOME_INDICATOR_COLLECTIONS","DEFAULT_LIMIT","DEFAULT_PARENT_FIELD_SLUG","PAGE_TREE_LIST_VIEW_PATH","tagPageTreeMoveContextHook","data","req","headers","get","user","context","getTopLevelField","collection","fieldName","fields","find","field","name","getCollectionEndpoints","Array","isArray","endpoints","patchBreadcrumbField","args","breadcrumbsFieldSlug","hideBreadcrumbs","admin","hidden","validateTargetCollection","parentFieldSlug","useAsTitle","includes","Error","slug","existingListView","components","views","list","Component","existingMoveEndpoint","endpoint","path","buildCollectionCustom","badges","defaultLimit","homeIndicator","getHomeIndicatorCollectionSlugs","Set","collections","nestedDocsPageTreePlugin","pluginOptions","config","length","disabled","homeIndicatorCollectionSlugs","targetedCollectionSlugs","foundCollectionSlugs","nextCollections","map","has","add","pagination","undefined","custom","enabled","collectionSlug","hooks","orderable","beforeChange","missingCollections","filter","join"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -41,3 +41,9 @@ export type PageTreeSourceDoc = Record<string, unknown> & {
|
|
|
41
41
|
slug?: null | string;
|
|
42
42
|
};
|
|
43
43
|
export declare const nestedDocsPageTreePluginCustomKey = "nestedDocsPageTreePlugin";
|
|
44
|
+
export declare const pageTreeMoveContextKey = "pageTreeMove";
|
|
45
|
+
export declare const pageTreeMoveRequestHeader = "x-payload-nested-docs-page-tree-move";
|
|
46
|
+
export declare const pageTreeMoveRequestHeaderValue = "true";
|
|
47
|
+
export type PageTreeMoveContext = {
|
|
48
|
+
[pageTreeMoveContextKey]?: boolean;
|
|
49
|
+
};
|
package/dist/types.js
CHANGED
|
@@ -4,5 +4,8 @@ export const nestedDocsPageTreePluginBadgeStatuses = [
|
|
|
4
4
|
'draft'
|
|
5
5
|
];
|
|
6
6
|
export const nestedDocsPageTreePluginCustomKey = 'nestedDocsPageTreePlugin';
|
|
7
|
+
export const pageTreeMoveContextKey = 'pageTreeMove';
|
|
8
|
+
export const pageTreeMoveRequestHeader = 'x-payload-nested-docs-page-tree-move';
|
|
9
|
+
export const pageTreeMoveRequestHeaderValue = 'true';
|
|
7
10
|
|
|
8
11
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { CollectionSlug } from 'payload'\r\n\r\nexport const nestedDocsPageTreePluginBadgeStatuses = ['published', 'changed', 'draft'] as const\r\n\r\nexport type NestedDocsPageTreePluginBadgeStatus =\r\n (typeof nestedDocsPageTreePluginBadgeStatuses)[number]\r\n\r\nexport type NestedDocsPageTreePluginBadgeMap = Partial<\r\n Record<NestedDocsPageTreePluginBadgeStatus, string>\r\n>\r\n\r\nexport type NestedDocsPageTreePluginBadgeConfig = {\r\n colors?: NestedDocsPageTreePluginBadgeMap\r\n labels?: NestedDocsPageTreePluginBadgeMap\r\n}\r\n\r\nexport type NestedDocsPageTreePluginResolvedBadgeConfig = {\n colors: NestedDocsPageTreePluginBadgeMap\n labels: NestedDocsPageTreePluginBadgeMap\n}\n\nexport type NestedDocsPageTreePluginHomeIndicatorConfig =\n | false\n | {\n collections?: CollectionSlug[]\n }\n\nexport type NestedDocsPageTreePluginResolvedHomeIndicatorConfig = {\n enabled: boolean\n}\n\nexport type NestedDocsPageTreePluginConfig = {\n badges?: NestedDocsPageTreePluginBadgeConfig\n breadcrumbsFieldSlug?: string\n collections: CollectionSlug[]\n defaultLimit?: number\n disabled?: boolean\n hideBreadcrumbs?: boolean\n homeIndicator?: NestedDocsPageTreePluginHomeIndicatorConfig\n parentFieldSlug?: string\n}\n\nexport type NestedDocsPageTreePluginCollectionCustom = {\n badges: NestedDocsPageTreePluginResolvedBadgeConfig\n breadcrumbsFieldSlug: string\n defaultLimit: number\n hideBreadcrumbs: boolean\n homeIndicator: NestedDocsPageTreePluginResolvedHomeIndicatorConfig\n parentFieldSlug: string\n}\n\r\nexport type PageTreeSourceDoc = Record<string, unknown> & {\r\n _displayStatus?: null | string\r\n _status?: null | string\r\n id?: number | string\r\n slug?: null | string\r\n}\r\n\r\nexport const nestedDocsPageTreePluginCustomKey = 'nestedDocsPageTreePlugin'\r\n"],"names":["nestedDocsPageTreePluginBadgeStatuses","nestedDocsPageTreePluginCustomKey"],"mappings":"AAEA,OAAO,MAAMA,wCAAwC;IAAC;IAAa;IAAW;CAAQ,CAAS;AAwD/F,OAAO,MAAMC,oCAAoC,2BAA0B"}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { CollectionSlug } from 'payload'\r\n\r\nexport const nestedDocsPageTreePluginBadgeStatuses = ['published', 'changed', 'draft'] as const\r\n\r\nexport type NestedDocsPageTreePluginBadgeStatus =\r\n (typeof nestedDocsPageTreePluginBadgeStatuses)[number]\r\n\r\nexport type NestedDocsPageTreePluginBadgeMap = Partial<\r\n Record<NestedDocsPageTreePluginBadgeStatus, string>\r\n>\r\n\r\nexport type NestedDocsPageTreePluginBadgeConfig = {\r\n colors?: NestedDocsPageTreePluginBadgeMap\r\n labels?: NestedDocsPageTreePluginBadgeMap\r\n}\r\n\r\nexport type NestedDocsPageTreePluginResolvedBadgeConfig = {\r\n colors: NestedDocsPageTreePluginBadgeMap\r\n labels: NestedDocsPageTreePluginBadgeMap\r\n}\r\n\r\nexport type NestedDocsPageTreePluginHomeIndicatorConfig =\r\n | false\r\n | {\r\n collections?: CollectionSlug[]\r\n }\r\n\r\nexport type NestedDocsPageTreePluginResolvedHomeIndicatorConfig = {\r\n enabled: boolean\r\n}\r\n\r\nexport type NestedDocsPageTreePluginConfig = {\r\n badges?: NestedDocsPageTreePluginBadgeConfig\r\n breadcrumbsFieldSlug?: string\r\n collections: CollectionSlug[]\r\n defaultLimit?: number\r\n disabled?: boolean\r\n hideBreadcrumbs?: boolean\r\n homeIndicator?: NestedDocsPageTreePluginHomeIndicatorConfig\r\n parentFieldSlug?: string\r\n}\r\n\r\nexport type NestedDocsPageTreePluginCollectionCustom = {\r\n badges: NestedDocsPageTreePluginResolvedBadgeConfig\r\n breadcrumbsFieldSlug: string\r\n defaultLimit: number\r\n hideBreadcrumbs: boolean\r\n homeIndicator: NestedDocsPageTreePluginResolvedHomeIndicatorConfig\r\n parentFieldSlug: string\r\n}\r\n\r\nexport type PageTreeSourceDoc = Record<string, unknown> & {\r\n _displayStatus?: null | string\r\n _status?: null | string\r\n id?: number | string\r\n slug?: null | string\r\n}\r\n\r\nexport const nestedDocsPageTreePluginCustomKey = 'nestedDocsPageTreePlugin'\r\n\r\nexport const pageTreeMoveContextKey = 'pageTreeMove'\r\n\r\nexport const pageTreeMoveRequestHeader = 'x-payload-nested-docs-page-tree-move'\r\n\r\nexport const pageTreeMoveRequestHeaderValue = 'true'\r\n\r\nexport type PageTreeMoveContext = {\r\n [pageTreeMoveContextKey]?: boolean\r\n}\r\n"],"names":["nestedDocsPageTreePluginBadgeStatuses","nestedDocsPageTreePluginCustomKey","pageTreeMoveContextKey","pageTreeMoveRequestHeader","pageTreeMoveRequestHeaderValue"],"mappings":"AAEA,OAAO,MAAMA,wCAAwC;IAAC;IAAa;IAAW;CAAQ,CAAS;AAwD/F,OAAO,MAAMC,oCAAoC,2BAA0B;AAE3E,OAAO,MAAMC,yBAAyB,eAAc;AAEpD,OAAO,MAAMC,4BAA4B,uCAAsC;AAE/E,OAAO,MAAMC,iCAAiC,OAAM"}
|