payload-nested-docs-page-tree 1.1.0
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/LICENSE +21 -0
- package/README.md +132 -0
- package/dist/components/PageTreeContext.d.ts +15 -0
- package/dist/components/PageTreeContext.js +26 -0
- package/dist/components/PageTreeContext.js.map +1 -0
- package/dist/components/PageTreeListView.client.d.ts +17 -0
- package/dist/components/PageTreeListView.client.js +960 -0
- package/dist/components/PageTreeListView.client.js.map +1 -0
- package/dist/components/PageTreeListView.module.css +358 -0
- package/dist/components/PageTreeListView.server.d.ts +3 -0
- package/dist/components/PageTreeListView.server.js +390 -0
- package/dist/components/PageTreeListView.server.js.map +1 -0
- package/dist/components/PageTreeTitleCell.d.ts +6 -0
- package/dist/components/PageTreeTitleCell.js +80 -0
- package/dist/components/PageTreeTitleCell.js.map +1 -0
- package/dist/endpoints/createMovePageEndpoint.d.ts +5 -0
- package/dist/endpoints/createMovePageEndpoint.js +265 -0
- package/dist/endpoints/createMovePageEndpoint.js.map +1 -0
- package/dist/exports/client.d.ts +1 -0
- package/dist/exports/client.js +3 -0
- package/dist/exports/client.js.map +1 -0
- package/dist/exports/rsc.d.ts +1 -0
- package/dist/exports/rsc.js +3 -0
- package/dist/exports/rsc.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +142 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +35 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/utilities/badgeConfig.d.ts +2 -0
- package/dist/utilities/badgeConfig.js +30 -0
- package/dist/utilities/badgeConfig.js.map +1 -0
- package/dist/utilities/dropTargets.d.ts +31 -0
- package/dist/utilities/dropTargets.js +73 -0
- package/dist/utilities/dropTargets.js.map +1 -0
- package/dist/utilities/moveValidation.d.ts +11 -0
- package/dist/utilities/moveValidation.js +44 -0
- package/dist/utilities/moveValidation.js.map +1 -0
- package/dist/utilities/pageTree.d.ts +37 -0
- package/dist/utilities/pageTree.js +300 -0
- package/dist/utilities/pageTree.js.map +1 -0
- package/dist/utilities/pageTreeCollision.d.ts +16 -0
- package/dist/utilities/pageTreeCollision.js +70 -0
- package/dist/utilities/pageTreeCollision.js.map +1 -0
- package/dist/utilities/pageTreeConfig.d.ts +3 -0
- package/dist/utilities/pageTreeConfig.js +21 -0
- package/dist/utilities/pageTreeConfig.js.map +1 -0
- package/dist/utilities/status.d.ts +17 -0
- package/dist/utilities/status.js +72 -0
- package/dist/utilities/status.js.map +1 -0
- package/package.json +115 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 WLF Studios
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Payload Nested Docs Page Tree
|
|
2
|
+
|
|
3
|
+
Companion admin plugin for [`@payloadcms/plugin-nested-docs`](https://payloadcms.com/docs/plugins/nested-docs).
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img alt="Page tree demo" src="assets/page-tree.gif" width="100%" />
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
Adds a nested tree list view for nested docs collections in Payload admin, with drag-and-drop parent changes and status badges for published / changed / draft documents.
|
|
10
|
+
|
|
11
|
+
It works alongside `@payloadcms/plugin-nested-docs`. It does not replace nested docs persistence, breadcrumbs generation, or routing.
|
|
12
|
+
|
|
13
|
+
Tested with Payload `3.84.1` and Next.js `16.2`.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pnpm add payload-nested-docs-page-tree
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Setup
|
|
23
|
+
|
|
24
|
+
`@payloadcms/plugin-nested-docs` should already be installed, and each target collection should already have:
|
|
25
|
+
|
|
26
|
+
- a nested docs parent field
|
|
27
|
+
- a nested docs breadcrumbs field
|
|
28
|
+
- a top-level `admin.useAsTitle` field
|
|
29
|
+
|
|
30
|
+
Add `nestedDocsPageTreePlugin(...)` right after `nestedDocsPlugin(...)`:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { nestedDocsPlugin } from '@payloadcms/plugin-nested-docs'
|
|
34
|
+
import { nestedDocsPageTreePlugin } from 'payload-nested-docs-page-tree'
|
|
35
|
+
|
|
36
|
+
export const plugins = [
|
|
37
|
+
nestedDocsPlugin({
|
|
38
|
+
// your existing nested docs config
|
|
39
|
+
}),
|
|
40
|
+
nestedDocsPageTreePlugin({
|
|
41
|
+
collections: ['pages'],
|
|
42
|
+
}),
|
|
43
|
+
]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
If needed, refresh the admin import map:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
payload generate:importmap
|
|
50
|
+
```
|
|
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
|
+
- hides the read-only breadcrumbs field by default
|
|
58
|
+
|
|
59
|
+
## Status Badges
|
|
60
|
+
|
|
61
|
+
The tree view supports three document states:
|
|
62
|
+
|
|
63
|
+
- `published`: live and up to date
|
|
64
|
+
- `changed`: live, but has unpublished changes
|
|
65
|
+
- `draft`: not published
|
|
66
|
+
|
|
67
|
+
To override badge labels or colors, pass a `badges` object:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
nestedDocsPageTreePlugin({
|
|
71
|
+
collections: ['pages'],
|
|
72
|
+
badges: {
|
|
73
|
+
labels: {
|
|
74
|
+
published: 'Live',
|
|
75
|
+
changed: 'Has Changes',
|
|
76
|
+
draft: 'Draft Only',
|
|
77
|
+
},
|
|
78
|
+
colors: {
|
|
79
|
+
published: '#1e90ff',
|
|
80
|
+
changed: '#9333ea',
|
|
81
|
+
draft: '#dc2626',
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
}),
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`labels` and `colors` are optional partial overrides. Missing entries fall back to the built-in defaults.
|
|
88
|
+
|
|
89
|
+
## Configuration
|
|
90
|
+
|
|
91
|
+
- `collections`: target collection slugs
|
|
92
|
+
- `parentFieldSlug`: defaults to `'parent'`
|
|
93
|
+
- `breadcrumbsFieldSlug`: defaults to `'breadcrumbs'`
|
|
94
|
+
- `defaultLimit`: defaults to `100`
|
|
95
|
+
- `hideBreadcrumbs`: defaults to `true`
|
|
96
|
+
- `disabled`: defaults to `false`
|
|
97
|
+
- `badges`: optional label and color overrides for `published`, `changed`, and `draft`
|
|
98
|
+
|
|
99
|
+
## Development
|
|
100
|
+
|
|
101
|
+
For local plugin development, use the internal `dev/` app:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
pnpm install
|
|
105
|
+
pnpm dev
|
|
106
|
+
pnpm generate:types
|
|
107
|
+
pnpm generate:importmap
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Plugin source is in `src/`. The internal test app is in `dev/`.
|
|
111
|
+
|
|
112
|
+
For checks:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
pnpm test:int
|
|
116
|
+
pnpm exec tsc --noEmit
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Test in Another Project
|
|
120
|
+
|
|
121
|
+
For release validation, test the packed artifact instead of a live source-folder dependency:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
pnpm build
|
|
125
|
+
pnpm pack
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Then in the external consumer app:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
pnpm add /path/payload-nested-docs-page-tree-*.tgz
|
|
132
|
+
```
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
type PageTreeContextValue = {
|
|
3
|
+
activeDragRowID: null | string;
|
|
4
|
+
canMoveDocs: boolean;
|
|
5
|
+
collapsedIDs: ReadonlySet<string>;
|
|
6
|
+
disableMoveDrag?: boolean;
|
|
7
|
+
pendingMoveRowID: null | string;
|
|
8
|
+
toggleRow: (rowID: string) => void;
|
|
9
|
+
};
|
|
10
|
+
export declare function PageTreeProvider({ children, value, }: {
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
value: PageTreeContextValue;
|
|
13
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export declare function usePageTree(): PageTreeContextValue;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import React from 'react';
|
|
4
|
+
const PageTreeContext = /*#__PURE__*/ React.createContext(null);
|
|
5
|
+
export function PageTreeProvider({ children, value }) {
|
|
6
|
+
return /*#__PURE__*/ _jsx(PageTreeContext.Provider, {
|
|
7
|
+
value: value,
|
|
8
|
+
children: children
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
export function usePageTree() {
|
|
12
|
+
const context = React.useContext(PageTreeContext);
|
|
13
|
+
if (!context) {
|
|
14
|
+
return {
|
|
15
|
+
activeDragRowID: null,
|
|
16
|
+
canMoveDocs: false,
|
|
17
|
+
collapsedIDs: new Set(),
|
|
18
|
+
disableMoveDrag: false,
|
|
19
|
+
pendingMoveRowID: null,
|
|
20
|
+
toggleRow: ()=>{}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return context;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=PageTreeContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/PageTreeContext.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\n\ntype PageTreeContextValue = {\n activeDragRowID: null | string\n canMoveDocs: boolean\n collapsedIDs: ReadonlySet<string>\n disableMoveDrag?: boolean\n pendingMoveRowID: null | string\n toggleRow: (rowID: string) => void\n}\n\nconst PageTreeContext = React.createContext<null | PageTreeContextValue>(null)\n\nexport function PageTreeProvider({\n children,\n value,\n}: {\n children: React.ReactNode\n value: PageTreeContextValue\n}) {\n return <PageTreeContext.Provider value={value}>{children}</PageTreeContext.Provider>\n}\n\nexport function usePageTree(): PageTreeContextValue {\n const context = React.useContext(PageTreeContext)\n\n if (!context) {\n return {\n activeDragRowID: null,\n canMoveDocs: false,\n collapsedIDs: new Set<string>(),\n disableMoveDrag: false,\n pendingMoveRowID: null,\n toggleRow: () => {},\n }\n }\n\n return context\n}\n"],"names":["React","PageTreeContext","createContext","PageTreeProvider","children","value","Provider","usePageTree","context","useContext","activeDragRowID","canMoveDocs","collapsedIDs","Set","disableMoveDrag","pendingMoveRowID","toggleRow"],"mappings":"AAAA;;AAEA,OAAOA,WAAW,QAAO;AAWzB,MAAMC,gCAAkBD,MAAME,aAAa,CAA8B;AAEzE,OAAO,SAASC,iBAAiB,EAC/BC,QAAQ,EACRC,KAAK,EAIN;IACC,qBAAO,KAACJ,gBAAgBK,QAAQ;QAACD,OAAOA;kBAAQD;;AAClD;AAEA,OAAO,SAASG;IACd,MAAMC,UAAUR,MAAMS,UAAU,CAACR;IAEjC,IAAI,CAACO,SAAS;QACZ,OAAO;YACLE,iBAAiB;YACjBC,aAAa;YACbC,cAAc,IAAIC;YAClBC,iBAAiB;YACjBC,kBAAkB;YAClBC,WAAW,KAAO;QACpB;IACF;IAEA,OAAOR;AACT"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Column, ListQuery, ListViewClientProps } from 'payload';
|
|
2
|
+
import type { NestedDocsPageTreePluginResolvedBadgeConfig, PageTreeSourceDoc } from '../types.js';
|
|
3
|
+
import { type PageTreeDoc } from '../utilities/pageTree.js';
|
|
4
|
+
type PageTreeListViewClientOwnProps = {
|
|
5
|
+
allDocs: PageTreeDoc[];
|
|
6
|
+
badgeConfig: NestedDocsPageTreePluginResolvedBadgeConfig;
|
|
7
|
+
canMoveDocs: boolean;
|
|
8
|
+
columnState: Column[];
|
|
9
|
+
orderableFieldName?: string;
|
|
10
|
+
parentFieldSlug: string;
|
|
11
|
+
query: ListQuery;
|
|
12
|
+
sourceDocs: PageTreeSourceDoc[];
|
|
13
|
+
useAsTitle: string;
|
|
14
|
+
};
|
|
15
|
+
type PageTreeListViewClientProps = Omit<ListViewClientProps, 'columnState' | 'Table'> & PageTreeListViewClientOwnProps;
|
|
16
|
+
export default function PageTreeListViewClient({ allDocs, badgeConfig, canMoveDocs, columnState, orderableFieldName, parentFieldSlug, query, sourceDocs, useAsTitle, ...props }: PageTreeListViewClientProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export {};
|