@rakun-kit/manager-react 1.5.8 → 1.5.10
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 +312 -292
- package/dist/cjs/app/runtime-app.js +4 -1
- package/dist/cjs/app/runtime-app.js.map +1 -1
- package/dist/cjs/components/app-sidebar.js +3 -2
- package/dist/cjs/components/app-sidebar.js.map +1 -1
- package/dist/cjs/components/editor/themes/editor-theme.css +91 -91
- package/dist/cjs/components/ui/sortable.js +4 -4
- package/dist/cjs/i18n/catalog.js +26 -0
- package/dist/cjs/i18n/catalog.js.map +1 -1
- package/dist/cjs/layouts.js +2 -2
- package/dist/cjs/layouts.js.map +1 -1
- package/dist/cjs/router/dashboard/[contentType]/[edit]/ContentTypeEdit.js +6 -2
- package/dist/cjs/router/dashboard/[contentType]/[edit]/ContentTypeEdit.js.map +1 -1
- package/dist/cjs/router/dashboard/[contentType]/[edit]/_components/EditTabPanels.js +1 -1
- package/dist/cjs/router/dashboard/[contentType]/[edit]/_components/EditTabPanels.js.map +1 -1
- package/dist/cjs/router/dashboard/[contentType]/[edit]/_components/EditToolbar.js +2 -2
- package/dist/cjs/router/dashboard/[contentType]/[edit]/_components/EditToolbar.js.map +1 -1
- package/dist/cjs/router/dashboard/[contentType]/[edit]/_context/EditPageContext.js +9 -1
- package/dist/cjs/router/dashboard/[contentType]/[edit]/_context/EditPageContext.js.map +1 -1
- package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/RelationField/NewRelation.js +1 -1
- package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/RelationField/NewRelation.js.map +1 -1
- package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/RelationField/index.js.map +1 -1
- package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/seoBindings.js +36 -0
- package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/seoBindings.js.map +1 -0
- package/dist/cjs/router/dashboard/[contentType]/[edit]/_hooks/useContentDocumentActions.js +1 -0
- package/dist/cjs/router/dashboard/[contentType]/[edit]/_hooks/useContentDocumentActions.js.map +1 -1
- package/dist/cjs/router/dashboard/[contentType]/[edit]/screen.js +2 -2
- package/dist/cjs/router/dashboard/[contentType]/[edit]/screen.js.map +1 -1
- package/dist/cjs/router/dashboard/settings/llms/index.js +6 -0
- package/dist/cjs/router/dashboard/settings/llms/index.js.map +1 -0
- package/dist/cjs/router/dashboard/settings/llms/screen.js +122 -0
- package/dist/cjs/router/dashboard/settings/llms/screen.js.map +1 -0
- package/dist/cjs/router/dashboard/settings/screen.js +7 -0
- package/dist/cjs/router/dashboard/settings/screen.js.map +1 -1
- package/dist/cjs/router/shared/route-definitions.js +3 -2
- package/dist/cjs/router/shared/route-definitions.js.map +1 -1
- package/dist/cjs/router/shared/route-list.js +9 -1
- package/dist/cjs/router/shared/route-list.js.map +1 -1
- package/dist/cjs/router/shared/route-renderer.js +2 -1
- package/dist/cjs/router/shared/route-renderer.js.map +1 -1
- package/dist/cjs/state/theme-script.js +12 -12
- package/dist/docs/index.md +203 -184
- package/dist/esm/app/runtime-app.d.ts.map +1 -1
- package/dist/esm/app/runtime-app.js +4 -1
- package/dist/esm/app/runtime-app.js.map +1 -1
- package/dist/esm/components/app-sidebar.d.ts +2 -1
- package/dist/esm/components/app-sidebar.d.ts.map +1 -1
- package/dist/esm/components/app-sidebar.js +5 -4
- package/dist/esm/components/app-sidebar.js.map +1 -1
- package/dist/esm/components/editor/themes/editor-theme.css +91 -91
- package/dist/esm/components/ui/sortable.js +4 -4
- package/dist/esm/i18n/catalog.d.ts +84 -0
- package/dist/esm/i18n/catalog.d.ts.map +1 -1
- package/dist/esm/i18n/catalog.js +40 -0
- package/dist/esm/i18n/catalog.js.map +1 -1
- package/dist/esm/i18n/useTranslations.d.ts.map +1 -1
- package/dist/esm/layouts.d.ts +3 -1
- package/dist/esm/layouts.d.ts.map +1 -1
- package/dist/esm/layouts.js +2 -2
- package/dist/esm/layouts.js.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/ContentTypeEdit.d.ts +2 -0
- package/dist/esm/router/dashboard/[contentType]/[edit]/ContentTypeEdit.d.ts.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/ContentTypeEdit.js +7 -3
- package/dist/esm/router/dashboard/[contentType]/[edit]/ContentTypeEdit.js.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_components/ContentCommentsDrawer.d.ts.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_components/ContentCommentsDrawer.js +11 -6
- package/dist/esm/router/dashboard/[contentType]/[edit]/_components/ContentCommentsDrawer.js.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_components/EditTabPanels.d.ts.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_components/EditTabPanels.js +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_components/EditTabPanels.js.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_components/EditToolbar.d.ts.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_components/EditToolbar.js +3 -3
- package/dist/esm/router/dashboard/[contentType]/[edit]/_components/EditToolbar.js.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_context/EditPageContext.d.ts +2 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_context/EditPageContext.d.ts.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_context/EditPageContext.js +9 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_context/EditPageContext.js.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/LinkField/LinkUI.d.ts.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/LinkField/LinkUI.js +11 -2
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/LinkField/LinkUI.js.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/LinkField/index.d.ts +2 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/LinkField/index.d.ts.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/LinkField/index.js.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/RelationField/NewRelation.d.ts.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/RelationField/NewRelation.js +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/RelationField/NewRelation.js.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/RelationField/index.d.ts +1 -0
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/RelationField/index.d.ts.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/RelationField/index.js.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/seoBindings.d.ts +6 -0
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/seoBindings.d.ts.map +1 -0
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/seoBindings.js +32 -0
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/seoBindings.js.map +1 -0
- package/dist/esm/router/dashboard/[contentType]/[edit]/_hooks/useContentDocumentActions.d.ts.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_hooks/useContentDocumentActions.js +2 -0
- package/dist/esm/router/dashboard/[contentType]/[edit]/_hooks/useContentDocumentActions.js.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_hooks/useRouteLayoutData.d.ts.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/edit.types.d.ts +1 -0
- package/dist/esm/router/dashboard/[contentType]/[edit]/edit.types.d.ts.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/screen.d.ts +2 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/screen.d.ts.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/screen.js +2 -2
- package/dist/esm/router/dashboard/[contentType]/[edit]/screen.js.map +1 -1
- package/dist/esm/router/dashboard/settings/llms/index.d.ts +2 -0
- package/dist/esm/router/dashboard/settings/llms/index.d.ts.map +1 -0
- package/dist/esm/router/dashboard/settings/llms/index.js +2 -0
- package/dist/esm/router/dashboard/settings/llms/index.js.map +1 -0
- package/dist/esm/router/dashboard/settings/llms/screen.d.ts +2 -0
- package/dist/esm/router/dashboard/settings/llms/screen.d.ts.map +1 -0
- package/dist/esm/router/dashboard/settings/llms/screen.js +115 -0
- package/dist/esm/router/dashboard/settings/llms/screen.js.map +1 -0
- package/dist/esm/router/dashboard/settings/screen.d.ts.map +1 -1
- package/dist/esm/router/dashboard/settings/screen.js +8 -1
- package/dist/esm/router/dashboard/settings/screen.js.map +1 -1
- package/dist/esm/router/shared/route-definitions.d.ts +4 -2
- package/dist/esm/router/shared/route-definitions.d.ts.map +1 -1
- package/dist/esm/router/shared/route-definitions.js +3 -2
- package/dist/esm/router/shared/route-definitions.js.map +1 -1
- package/dist/esm/router/shared/route-list.d.ts +1 -1
- package/dist/esm/router/shared/route-list.d.ts.map +1 -1
- package/dist/esm/router/shared/route-list.js +9 -1
- package/dist/esm/router/shared/route-list.js.map +1 -1
- package/dist/esm/router/shared/route-renderer.d.ts.map +1 -1
- package/dist/esm/router/shared/route-renderer.js +2 -1
- package/dist/esm/router/shared/route-renderer.js.map +1 -1
- package/dist/esm/router/shared/types.d.ts +3 -0
- package/dist/esm/router/shared/types.d.ts.map +1 -1
- package/dist/esm/state/theme-script.js +12 -12
- package/dist/styles.css +7 -7
- package/dist/styles.css.d.ts +3 -3
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +217 -217
package/README.md
CHANGED
|
@@ -1,298 +1,318 @@
|
|
|
1
|
-
# @rakun-kit/manager-react
|
|
2
|
-
|
|
3
|
-
React manager UI and client utilities for Rakun.
|
|
4
|
-
|
|
5
|
-
Most apps use this package through framework adapters such as
|
|
6
|
-
`@rakun-kit/next/manager`, but the runtime components and clients are also
|
|
7
|
-
published for custom integrations.
|
|
8
|
-
|
|
9
|
-
## Browser App
|
|
10
|
-
|
|
11
|
-
Render the manager with a manager client and navigation implementation:
|
|
12
|
-
|
|
13
|
-
```tsx
|
|
14
|
-
import {
|
|
15
|
-
ManagerBrowserApp,
|
|
16
|
-
createHttpManagerClient,
|
|
17
|
-
} from "@rakun-kit/manager-react";
|
|
18
|
-
import "@rakun-kit/manager-react/styles.css";
|
|
19
|
-
|
|
20
|
-
const client = createHttpManagerClient({
|
|
21
|
-
baseUrl: "/api/rakun",
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
export function ManagerPage() {
|
|
25
|
-
return (
|
|
26
|
-
<ManagerBrowserApp
|
|
27
|
-
client={client}
|
|
28
|
-
pathname={window.location.pathname}
|
|
29
|
-
basePath="/backend"
|
|
30
|
-
/>
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
`ManagerBrowserApp` creates browser path navigation by default. Use
|
|
36
|
-
`ManagerRuntimeApp` when you need to provide custom navigation.
|
|
37
|
-
|
|
38
|
-
## Clients
|
|
39
|
-
|
|
40
|
-
HTTP client:
|
|
41
|
-
|
|
42
|
-
```ts
|
|
43
|
-
import { createHttpManagerClient } from "@rakun-kit/manager-react/client/http";
|
|
44
|
-
|
|
45
|
-
const client = createHttpManagerClient({
|
|
46
|
-
baseUrl: "/api/rakun",
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
const contentTypes = await client.request("manager.contentTypes");
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
tRPC client adapter:
|
|
53
|
-
|
|
54
|
-
```ts
|
|
55
|
-
import { createTrpcManagerClient } from "@rakun-kit/manager-react/client/trpc";
|
|
56
|
-
|
|
57
|
-
const managerClient = createTrpcManagerClient(trpcProxyClient);
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
Custom client:
|
|
61
|
-
|
|
62
|
-
```ts
|
|
63
|
-
import { createManagerClient } from "@rakun-kit/manager-react/client/request";
|
|
64
|
-
|
|
65
|
-
const client = createManagerClient(async (name, input, options) => {
|
|
66
|
-
// call your transport here
|
|
67
|
-
});
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
## Navigation
|
|
71
|
-
|
|
72
|
-
Use `createPathManagerNavigation` for router integrations:
|
|
73
|
-
|
|
74
|
-
```ts
|
|
75
|
-
import { createPathManagerNavigation } from "@rakun-kit/manager-react/state/navigation";
|
|
76
|
-
|
|
77
|
-
const navigation = createPathManagerNavigation({
|
|
78
|
-
basePath: "/backend",
|
|
79
|
-
push: (href) => router.push(href),
|
|
80
|
-
replace: (href) => router.replace(href),
|
|
81
|
-
});
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## Link fields
|
|
85
|
-
|
|
86
|
-
The `f.link()` editor shows a title alongside its destination. Users can paste
|
|
87
|
-
or type a direct URL, choose the home page, or browse configured page-route
|
|
88
|
-
types and select one of their entries. Internal selections automatically use
|
|
89
|
-
the item label when the title is empty. Direct links are stored as
|
|
90
|
-
`{ href, title }`; internal links as `{ routeId, contentTypeId, title }` so core
|
|
91
|
-
can resolve localized paths. Legacy values remain editable.
|
|
92
|
-
|
|
93
|
-
Compound arrays such as `f.array(f.link())` are reorderable from their drag
|
|
94
|
-
handles in the Info editor, without losing unsaved values inside each item.
|
|
95
|
-
|
|
96
|
-
## Media uploads
|
|
97
|
-
|
|
98
|
-
Original file names may contain accents, non-Latin scripts, or emoji. The
|
|
99
|
-
manager transports those names through ASCII-safe upload headers and core
|
|
100
|
-
restores them before saving media metadata.
|
|
101
|
-
|
|
102
|
-
With optimization enabled in the media toolbar, an image's context menu offers
|
|
103
|
-
`Reimport with current optimization`. It regenerates the configured variants
|
|
104
|
-
while retaining the existing media record and all relations to it. Multi-select
|
|
105
|
-
supports the same reimport action from the selection toolbar. Optimization is
|
|
106
|
-
on by default, and generated previews are stored as inline `data:image/...`
|
|
107
|
-
LQIP values on the media record.
|
|
108
|
-
|
|
109
|
-
## Dynamic data mappings
|
|
110
|
-
|
|
111
|
-
The list mapping editor supports recursive `blocks` targets. Select
|
|
112
|
-
`Nested list` for a mapped list property to configure its own source, query,
|
|
113
|
-
filters, item type, and field mapping. `Current document` query values inside
|
|
1
|
+
# @rakun-kit/manager-react
|
|
2
|
+
|
|
3
|
+
React manager UI and client utilities for Rakun.
|
|
4
|
+
|
|
5
|
+
Most apps use this package through framework adapters such as
|
|
6
|
+
`@rakun-kit/next/manager`, but the runtime components and clients are also
|
|
7
|
+
published for custom integrations.
|
|
8
|
+
|
|
9
|
+
## Browser App
|
|
10
|
+
|
|
11
|
+
Render the manager with a manager client and navigation implementation:
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import {
|
|
15
|
+
ManagerBrowserApp,
|
|
16
|
+
createHttpManagerClient,
|
|
17
|
+
} from "@rakun-kit/manager-react";
|
|
18
|
+
import "@rakun-kit/manager-react/styles.css";
|
|
19
|
+
|
|
20
|
+
const client = createHttpManagerClient({
|
|
21
|
+
baseUrl: "/api/rakun",
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export function ManagerPage() {
|
|
25
|
+
return (
|
|
26
|
+
<ManagerBrowserApp
|
|
27
|
+
client={client}
|
|
28
|
+
pathname={window.location.pathname}
|
|
29
|
+
basePath="/backend"
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`ManagerBrowserApp` creates browser path navigation by default. Use
|
|
36
|
+
`ManagerRuntimeApp` when you need to provide custom navigation.
|
|
37
|
+
|
|
38
|
+
## Clients
|
|
39
|
+
|
|
40
|
+
HTTP client:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { createHttpManagerClient } from "@rakun-kit/manager-react/client/http";
|
|
44
|
+
|
|
45
|
+
const client = createHttpManagerClient({
|
|
46
|
+
baseUrl: "/api/rakun",
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const contentTypes = await client.request("manager.contentTypes");
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
tRPC client adapter:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { createTrpcManagerClient } from "@rakun-kit/manager-react/client/trpc";
|
|
56
|
+
|
|
57
|
+
const managerClient = createTrpcManagerClient(trpcProxyClient);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Custom client:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { createManagerClient } from "@rakun-kit/manager-react/client/request";
|
|
64
|
+
|
|
65
|
+
const client = createManagerClient(async (name, input, options) => {
|
|
66
|
+
// call your transport here
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Navigation
|
|
71
|
+
|
|
72
|
+
Use `createPathManagerNavigation` for router integrations:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
import { createPathManagerNavigation } from "@rakun-kit/manager-react/state/navigation";
|
|
76
|
+
|
|
77
|
+
const navigation = createPathManagerNavigation({
|
|
78
|
+
basePath: "/backend",
|
|
79
|
+
push: (href) => router.push(href),
|
|
80
|
+
replace: (href) => router.replace(href),
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Link fields
|
|
85
|
+
|
|
86
|
+
The `f.link()` editor shows a title alongside its destination. Users can paste
|
|
87
|
+
or type a direct URL, choose the home page, or browse configured page-route
|
|
88
|
+
types and select one of their entries. Internal selections automatically use
|
|
89
|
+
the item label when the title is empty. Direct links are stored as
|
|
90
|
+
`{ href, title }`; internal links as `{ routeId, contentTypeId, title }` so core
|
|
91
|
+
can resolve localized paths. Legacy values remain editable.
|
|
92
|
+
|
|
93
|
+
Compound arrays such as `f.array(f.link())` are reorderable from their drag
|
|
94
|
+
handles in the Info editor, without losing unsaved values inside each item.
|
|
95
|
+
|
|
96
|
+
## Media uploads
|
|
97
|
+
|
|
98
|
+
Original file names may contain accents, non-Latin scripts, or emoji. The
|
|
99
|
+
manager transports those names through ASCII-safe upload headers and core
|
|
100
|
+
restores them before saving media metadata.
|
|
101
|
+
|
|
102
|
+
With optimization enabled in the media toolbar, an image's context menu offers
|
|
103
|
+
`Reimport with current optimization`. It regenerates the configured variants
|
|
104
|
+
while retaining the existing media record and all relations to it. Multi-select
|
|
105
|
+
supports the same reimport action from the selection toolbar. Optimization is
|
|
106
|
+
on by default, and generated previews are stored as inline `data:image/...`
|
|
107
|
+
LQIP values on the media record.
|
|
108
|
+
|
|
109
|
+
## Dynamic data mappings
|
|
110
|
+
|
|
111
|
+
The list mapping editor supports recursive `blocks` targets. Select
|
|
112
|
+
`Nested list` for a mapped list property to configure its own source, query,
|
|
113
|
+
filters, item type, and field mapping. `Current document` query values inside
|
|
114
114
|
that nested editor resolve against the parent source item.
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
```ts
|
|
121
|
-
import "@rakun-kit/manager-react/styles.css";
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
## Manager languages
|
|
125
|
-
|
|
126
|
-
English and the locale runtime are built into this package. Extra translations
|
|
127
|
-
ship from a separate package:
|
|
128
|
-
|
|
129
|
-
```sh
|
|
130
|
-
bun add @rakun-kit/manager-locales
|
|
131
|
-
# or: npm install @rakun-kit/manager-locales
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
Import only the locale needed by the server bootstrap:
|
|
135
|
-
|
|
136
|
-
```ts
|
|
137
|
-
import { esManagerLocalePack } from '@rakun-kit/manager-locales/es'
|
|
138
|
-
|
|
139
|
-
rakunBootstrap({
|
|
140
|
-
// ...
|
|
141
|
-
managerLanguages: [esManagerLocalePack],
|
|
142
|
-
})
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
Each language has an independent subpath, so application bundlers only include
|
|
146
|
-
the locales explicitly imported by the host.
|
|
147
|
-
|
|
148
|
-
Content-type titles and categories can use project-defined message keys without
|
|
149
|
-
adding them to the built-in `ManagerMessageKey` union. Add an English partial
|
|
150
|
-
pack and extend installed locales through `managerLanguages`:
|
|
151
|
-
|
|
152
|
-
```ts
|
|
153
|
-
import { extendManagerLanguagePack } from '@rakun-kit/core/contracts'
|
|
154
|
-
import { esManagerLocalePack } from '@rakun-kit/manager-locales/es'
|
|
155
|
-
|
|
156
|
-
const managerLanguages = [
|
|
157
|
-
{
|
|
158
|
-
code: 'en',
|
|
159
|
-
name: 'English',
|
|
160
|
-
messages: {
|
|
161
|
-
'field.title': 'Title',
|
|
162
|
-
'layoutModule.header': 'Header',
|
|
163
|
-
'project.contentTypes.article.menu': 'Articles',
|
|
164
|
-
},
|
|
165
|
-
},
|
|
166
|
-
extendManagerLanguagePack(esManagerLocalePack, {
|
|
167
|
-
'field.title': 'Título',
|
|
168
|
-
'layoutModule.header': 'Cabecera',
|
|
169
|
-
'project.contentTypes.article.menu': 'Artículos',
|
|
170
|
-
}),
|
|
171
|
-
]
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
Then set `menu.title` or `menu.category` to that arbitrary key. Project keys are
|
|
175
|
-
resolved at runtime but remain outside the static manager catalog.
|
|
176
|
-
|
|
177
|
-
Field labels use the dynamic `field.<fieldName>` namespace. A content-type field
|
|
178
|
-
named `title`, for example, automatically resolves `field.title` in edit forms
|
|
179
|
-
and list columns without adding it to `ManagerMessageKey`.
|
|
180
|
-
|
|
181
|
-
Layout module labels follow `layoutModule.<layoutKey>`. For example, the
|
|
182
|
-
`header` slot automatically resolves `layoutModule.header` in its tab and
|
|
183
|
-
configuration panel.
|
|
184
|
-
|
|
185
|
-
## Event Logs
|
|
116
|
+
SEO field mappings can use compatible fields from the full current document.
|
|
117
|
+
New documents also honor core string-field `.seo('<seoField>')` configuration
|
|
118
|
+
as an editable initial dynamic data binding.
|
|
186
119
|
|
|
187
|
-
|
|
188
|
-
`manager.logs.list` operation. The screen supports filters, cursor pagination,
|
|
189
|
-
and structured event details. Both the settings card and the operation require
|
|
190
|
-
the `system.eventLog.read` permission, which can be assigned from Settings →
|
|
191
|
-
User Roles.
|
|
120
|
+
## llms.txt settings
|
|
192
121
|
|
|
193
|
-
|
|
122
|
+
Settings → AI content manages the optional, site-level `llms.txt` Markdown guide served to
|
|
123
|
+
AI tools. Editors can enable publishing, override the SEO-derived title and
|
|
124
|
+
summary, add guidance, and order sections containing internal pages or external
|
|
125
|
+
URLs. Marking a section as Secondary content places it under `## Optional`
|
|
126
|
+
while preserving its title as a subsection in the generated document. For content types with publication states, the internal
|
|
127
|
+
page picker only offers published documents. Nothing is added automatically
|
|
128
|
+
from the sitemap.
|
|
194
129
|
|
|
195
|
-
|
|
196
|
-
|
|
130
|
+
Authenticated manager layouts place a Visit site action at the top-right of the
|
|
131
|
+
logo block. It opens SEO `siteUrl` in a new tab, falling back to `/` on the
|
|
132
|
+
manager host until that setting is configured. A published document with a
|
|
133
|
+
resolved page route also gets a contextual View page button in its edit toolbar;
|
|
134
|
+
the URL follows the selected manager language and locale variant.
|
|
197
135
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
136
|
+
## Styles
|
|
137
|
+
|
|
138
|
+
Import the package stylesheet once:
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
import "@rakun-kit/manager-react/styles.css";
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Manager languages
|
|
145
|
+
|
|
146
|
+
English and the locale runtime are built into this package. Extra translations
|
|
147
|
+
ship from a separate package:
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
bun add @rakun-kit/manager-locales
|
|
151
|
+
# or: npm install @rakun-kit/manager-locales
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Import only the locale needed by the server bootstrap:
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import { esManagerLocalePack } from '@rakun-kit/manager-locales/es'
|
|
158
|
+
|
|
159
|
+
rakunBootstrap({
|
|
160
|
+
// ...
|
|
161
|
+
managerLanguages: [esManagerLocalePack],
|
|
162
|
+
})
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Each language has an independent subpath, so application bundlers only include
|
|
166
|
+
the locales explicitly imported by the host.
|
|
167
|
+
|
|
168
|
+
Content-type titles and categories can use project-defined message keys without
|
|
169
|
+
adding them to the built-in `ManagerMessageKey` union. Add an English partial
|
|
170
|
+
pack and extend installed locales through `managerLanguages`:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
import { extendManagerLanguagePack } from '@rakun-kit/core/contracts'
|
|
174
|
+
import { esManagerLocalePack } from '@rakun-kit/manager-locales/es'
|
|
175
|
+
|
|
176
|
+
const managerLanguages = [
|
|
177
|
+
{
|
|
178
|
+
code: 'en',
|
|
179
|
+
name: 'English',
|
|
180
|
+
messages: {
|
|
181
|
+
'field.title': 'Title',
|
|
182
|
+
'layoutModule.header': 'Header',
|
|
183
|
+
'project.contentTypes.article.menu': 'Articles',
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
extendManagerLanguagePack(esManagerLocalePack, {
|
|
187
|
+
'field.title': 'Título',
|
|
188
|
+
'layoutModule.header': 'Cabecera',
|
|
189
|
+
'project.contentTypes.article.menu': 'Artículos',
|
|
190
|
+
}),
|
|
191
|
+
]
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Then set `menu.title` or `menu.category` to that arbitrary key. Project keys are
|
|
195
|
+
resolved at runtime but remain outside the static manager catalog.
|
|
196
|
+
|
|
197
|
+
Field labels use the dynamic `field.<fieldName>` namespace. A content-type field
|
|
198
|
+
named `title`, for example, automatically resolves `field.title` in edit forms
|
|
199
|
+
and list columns without adding it to `ManagerMessageKey`.
|
|
200
|
+
|
|
201
|
+
Layout module labels follow `layoutModule.<layoutKey>`. For example, the
|
|
202
|
+
`header` slot automatically resolves `layoutModule.header` in its tab and
|
|
203
|
+
configuration panel.
|
|
204
|
+
|
|
205
|
+
## Event Logs
|
|
206
|
+
|
|
207
|
+
Settings → Logs displays the persistent Rakun event stream through the native
|
|
208
|
+
`manager.logs.list` operation. The screen supports filters, cursor pagination,
|
|
209
|
+
and structured event details. Both the settings card and the operation require
|
|
210
|
+
the `system.eventLog.read` permission, which can be assigned from Settings →
|
|
211
|
+
User Roles.
|
|
212
|
+
|
|
213
|
+
## Manager Plugins
|
|
214
|
+
|
|
215
|
+
Manager plugins run inside the normal providers and can add dashboard routes,
|
|
216
|
+
sidebar items, and custom field editors:
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
import {
|
|
220
|
+
defineRakunManagerPlugin,
|
|
221
|
+
ManagerBrowserApp,
|
|
222
|
+
} from '@rakun-kit/manager-react'
|
|
223
|
+
|
|
224
|
+
const analyticsManagerPlugin = defineRakunManagerPlugin({
|
|
225
|
+
id: '@acme/rakun-analytics',
|
|
226
|
+
routes: [{
|
|
227
|
+
id: 'dashboard',
|
|
228
|
+
path: '/analytics',
|
|
229
|
+
component: AnalyticsScreen,
|
|
230
|
+
permissions: ['plugin.analytics.view'],
|
|
231
|
+
}],
|
|
232
|
+
sidebar: [{
|
|
233
|
+
id: 'analytics',
|
|
234
|
+
title: 'Analytics',
|
|
235
|
+
routeId: 'dashboard',
|
|
236
|
+
position: 'primary',
|
|
237
|
+
group: 'Plugins',
|
|
238
|
+
}],
|
|
239
|
+
fieldEditors: {
|
|
240
|
+
'@acme/rakun-analytics.query': QueryEditor,
|
|
241
|
+
},
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
<ManagerBrowserApp plugins={[analyticsManagerPlugin]} {...props} />
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Use `ManagerFieldEditorProps`, `ManagerFieldEditorRef`, and
|
|
248
|
+
`useManagerFieldValue` from `@rakun-kit/manager-react/plugins` when implementing
|
|
249
|
+
field editors. Next.js applications should import plugin objects inside a
|
|
250
|
+
`'use client'` wrapper around `RakunManagerClientPage`; `RakunManagerPage` accepts
|
|
251
|
+
that wrapper through `managerComponent`.
|
|
252
|
+
|
|
253
|
+
### Extending the RichText editor
|
|
254
|
+
|
|
255
|
+
Manager plugins can register Lexical nodes and React plugins for every
|
|
256
|
+
`RichText` field, including fields rendered inside relations, blocks, and
|
|
257
|
+
modules:
|
|
258
|
+
|
|
259
|
+
```tsx
|
|
260
|
+
'use client'
|
|
261
|
+
|
|
262
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
|
|
263
|
+
import {
|
|
264
|
+
defineRakunManagerPlugin,
|
|
265
|
+
type ManagerRichTextPluginProps,
|
|
266
|
+
} from '@rakun-kit/manager-react/plugins'
|
|
267
|
+
import { MentionNode } from './MentionNode'
|
|
268
|
+
|
|
269
|
+
const MentionsPlugin = ({ id }: ManagerRichTextPluginProps) => {
|
|
270
|
+
const [editor] = useLexicalComposerContext()
|
|
271
|
+
|
|
272
|
+
// Register commands and listeners on `editor` here.
|
|
273
|
+
return null
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export const mentionsManagerPlugin = defineRakunManagerPlugin({
|
|
277
|
+
id: '@acme/rakun-mentions',
|
|
278
|
+
richText: {
|
|
279
|
+
nodes: [MentionNode],
|
|
280
|
+
plugins: [
|
|
281
|
+
{
|
|
282
|
+
id: '@acme/rakun-mentions.plugin',
|
|
283
|
+
component: MentionsPlugin,
|
|
284
|
+
placement: 'editor',
|
|
285
|
+
},
|
|
286
|
+
],
|
|
287
|
+
},
|
|
288
|
+
})
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Lexical plugin components receive `ManagerRichTextPluginProps` (the field id,
|
|
292
|
+
configuration, current content type, and related field metadata) and render
|
|
293
|
+
inside `LexicalComposer`, so they can use the normal Lexical React hooks.
|
|
294
|
+
Supported placements are `toolbar`, `block-format`, `editor` (the default),
|
|
295
|
+
`actions-start`, and `actions-end`. `block-format` components render inside the
|
|
296
|
+
manager's block selector and can use `ManagerRichTextBlockFormatItem` from
|
|
297
|
+
`@rakun-kit/manager-react/rich-text`. Contributions keep declaration order
|
|
298
|
+
unless an explicit `order` is provided. Node types and plugin ids must be unique;
|
|
299
|
+
conflicts report both plugin owners. Node replacements use Lexical's standard
|
|
300
|
+
`LexicalNodeReplacement` configuration.
|
|
301
|
+
|
|
302
|
+
## Exports
|
|
303
|
+
|
|
304
|
+
- `@rakun-kit/manager-react`: manager app, providers, clients, navigation, router, layout, media, and state helpers.
|
|
305
|
+
- `@rakun-kit/manager-react/client/http`: HTTP manager client.
|
|
306
|
+
- `@rakun-kit/manager-react/client/request`: transport-agnostic manager client.
|
|
307
|
+
- `@rakun-kit/manager-react/client/trpc`: tRPC proxy client adapter.
|
|
308
|
+
- `@rakun-kit/manager-react/app/runtime-app`: `ManagerRuntimeApp`, `ManagerBrowserApp`.
|
|
309
|
+
- `@rakun-kit/manager-react/state/navigation`: navigation helpers and provider.
|
|
310
|
+
- `@rakun-kit/manager-react/link`: link component provider.
|
|
311
|
+
- `@rakun-kit/manager-react/i18n`: locale runtime, catalog, and locale types.
|
|
312
|
+
- `@rakun-kit/manager-react/styles.css`: bundled manager styles.
|
|
313
|
+
|
|
314
|
+
## Build
|
|
315
|
+
|
|
316
|
+
```sh
|
|
317
|
+
bun run build --workspace @rakun-kit/manager-react
|
|
318
|
+
```
|
|
@@ -35,6 +35,7 @@ const ManagerRuntimeApp = ({ client, navigation, pathname, basePath, searchParam
|
|
|
35
35
|
const queryClient = (0, react_1.useMemo)(() => (0, app_provider_1.createManagerQueryClient)(), []);
|
|
36
36
|
const [localePacks, setLocalePacks] = (0, react_1.useState)([]);
|
|
37
37
|
const [managerUiLoaded, setManagerUiLoaded] = (0, react_1.useState)(false);
|
|
38
|
+
const [siteUrl, setSiteUrl] = (0, react_1.useState)();
|
|
38
39
|
const [passwordRecoveryEnabled, setPasswordRecoveryEnabled] = (0, react_1.useState)(false);
|
|
39
40
|
const [login, setLogin] = (0, react_1.useState)({ password: true, adapters: [] });
|
|
40
41
|
const scopedNavigation = (0, react_1.useMemo)(() => ({
|
|
@@ -69,6 +70,7 @@ const ManagerRuntimeApp = ({ client, navigation, pathname, basePath, searchParam
|
|
|
69
70
|
const uiConfig = result;
|
|
70
71
|
const locales = uiConfig.locales;
|
|
71
72
|
setLocalePacks(Array.isArray(locales) ? locales : []);
|
|
73
|
+
setSiteUrl(uiConfig.siteUrl);
|
|
72
74
|
setPasswordRecoveryEnabled(uiConfig.features?.passwordRecovery === true);
|
|
73
75
|
setLogin({
|
|
74
76
|
password: uiConfig.features?.login?.password !== false,
|
|
@@ -82,6 +84,7 @@ const ManagerRuntimeApp = ({ client, navigation, pathname, basePath, searchParam
|
|
|
82
84
|
if (cancelled)
|
|
83
85
|
return;
|
|
84
86
|
setLocalePacks([]);
|
|
87
|
+
setSiteUrl(undefined);
|
|
85
88
|
setPasswordRecoveryEnabled(false);
|
|
86
89
|
setLogin({ password: true, adapters: [] });
|
|
87
90
|
setManagerUiLoaded(true);
|
|
@@ -178,7 +181,7 @@ const ManagerRuntimeApp = ({ client, navigation, pathname, basePath, searchParam
|
|
|
178
181
|
}, [bootstrap, pathname, searchParams, state.status]);
|
|
179
182
|
const isLoading = state.status === "loading" || !managerUiLoaded;
|
|
180
183
|
return ((0, jsx_runtime_1.jsx)(root_providers_1.ManagerRootProviders, { children: (0, jsx_runtime_1.jsx)(i18n_1.ManagerI18nProvider, { localePacks: localePacks, children: (0, jsx_runtime_1.jsx)(confirm_1.ConfirmProvider, { children: (0, jsx_runtime_1.jsx)(react_query_1.QueryClientProvider, { client: queryClient, children: (0, jsx_runtime_1.jsx)(react_2.ManagerProvider, { client: client, children: (0, jsx_runtime_1.jsx)(runtime_auth_1.ManagerRuntimeAuthProvider, { value: runtimeAuth, children: (0, jsx_runtime_1.jsx)(navigation_1.ManagerNavigationProvider, { navigation: scopedNavigation, children: (0, jsx_runtime_1.jsx)(link_1.ManagerLinkProvider, { component: linkComponent, children: (0, jsx_runtime_1.jsxs)(media_1.ManagerMediaProvider, { renderPicker: renderMediaPicker ?? media_picker_1.renderDefaultManagerMediaPicker, children: [isLoading ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: loadingFallback ??
|
|
181
|
-
(useAuthLoadingFallback ? ((0, jsx_runtime_1.jsx)(manager_loading_fallback_1.ManagerAuthLoadingFallback, {})) : ((0, jsx_runtime_1.jsx)(manager_loading_fallback_1.ManagerLoadingFallback, {}))) })) : null, !isLoading && state.status === "error" ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: errorFallback?.(state.message) ?? ((0, jsx_runtime_1.jsx)(BootstrapFailedMessage, { message: state.message })) })) : null, !isLoading && state.status === "unauthenticated" ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: unauthenticatedFallback ?? ((0, jsx_runtime_1.jsx)(router_1.ManagerApp, { pathname: pathname, basePath: basePath, searchParams: searchParams, passwordRecoveryEnabled: passwordRecoveryEnabled, login: login, preview: preview, plugins: plugins, ...overrides })) })) : null, !isLoading && state.status === "ready" ? ((0, jsx_runtime_1.jsx)(session_1.SessionProvider, { initialUser: state.user, contentTypes: state.contentTypes, children: (0, jsx_runtime_1.jsx)(users_1.ManagerUsersProvider, { children: (0, jsx_runtime_1.jsx)(language_1.LanguageProvider, { languages: state.languages, initialLanguage: state.initialLanguage, children: (0, jsx_runtime_1.jsx)(router_1.ManagerApp, { pathname: pathname, basePath: basePath, searchParams: searchParams, contentTypes: state.contentTypes, authenticated: true, passwordRecoveryEnabled: passwordRecoveryEnabled, login: login, preview: preview, plugins: plugins, ...overrides }) }) }) })) : null] }) }) }) }) }) }) }) }) }));
|
|
184
|
+
(useAuthLoadingFallback ? ((0, jsx_runtime_1.jsx)(manager_loading_fallback_1.ManagerAuthLoadingFallback, {})) : ((0, jsx_runtime_1.jsx)(manager_loading_fallback_1.ManagerLoadingFallback, {}))) })) : null, !isLoading && state.status === "error" ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: errorFallback?.(state.message) ?? ((0, jsx_runtime_1.jsx)(BootstrapFailedMessage, { message: state.message })) })) : null, !isLoading && state.status === "unauthenticated" ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: unauthenticatedFallback ?? ((0, jsx_runtime_1.jsx)(router_1.ManagerApp, { pathname: pathname, basePath: basePath, searchParams: searchParams, passwordRecoveryEnabled: passwordRecoveryEnabled, login: login, siteUrl: siteUrl, preview: preview, plugins: plugins, ...overrides })) })) : null, !isLoading && state.status === "ready" ? ((0, jsx_runtime_1.jsx)(session_1.SessionProvider, { initialUser: state.user, contentTypes: state.contentTypes, children: (0, jsx_runtime_1.jsx)(users_1.ManagerUsersProvider, { children: (0, jsx_runtime_1.jsx)(language_1.LanguageProvider, { languages: state.languages, initialLanguage: state.initialLanguage, children: (0, jsx_runtime_1.jsx)(router_1.ManagerApp, { pathname: pathname, basePath: basePath, searchParams: searchParams, contentTypes: state.contentTypes, authenticated: true, passwordRecoveryEnabled: passwordRecoveryEnabled, login: login, siteUrl: siteUrl, preview: preview, plugins: plugins, ...overrides }) }) }) })) : null] }) }) }) }) }) }) }) }) }));
|
|
182
185
|
};
|
|
183
186
|
exports.ManagerRuntimeApp = ManagerRuntimeApp;
|
|
184
187
|
const ManagerBrowserApp = (props) => {
|