@uxf/cms 11.122.3 → 11.122.5

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.
Files changed (2) hide show
  1. package/README.md +167 -0
  2. package/package.json +11 -11
package/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # @uxf/cms
2
+
3
+ Building blocks for UXF admin / CMS applications: authentication pages and forms, a role-gated page wrapper, an admin layout shell (layout, sidebar, menu, breadcrumbs), a data-grid listing page, a structured content builder, and typed clients for the UXF CMS backend (`/api/cms/*`). It composes `@uxf/ui`, `@uxf/form`, `@uxf/data-grid` and `@uxf/wysiwyg` rather than replacing them.
4
+
5
+ The package has no root entry — everything is consumed through subpath imports (e.g. `import { LoginPage } from "@uxf/cms/pages/login-page"`). It is Next.js-oriented: pages use `getInitialProps` and `next/router`.
6
+
7
+ ## When to use
8
+
9
+ Use `@uxf/cms` when you build an admin interface backed by a UXF CMS API. It gives you the ready-made auth flow (login, forgotten / renew password, user invite), the admin chrome (layout, navigation menu, breadcrumbs), role-based access control, list screens driven by `@uxf/data-grid` schemas, and the content builder for editing structured page content.
10
+
11
+ It is not a general UI kit (`@uxf/ui`), a form library (`@uxf/form`), or a data grid (`@uxf/data-grid`) — it wires those together for the CMS use case. For a plain UI primitive or a standalone form field, reach for those packages directly.
12
+
13
+ ## Installation
14
+
15
+ ```
16
+ yarn add @uxf/cms
17
+ ```
18
+
19
+ Peer dependencies: `@uxf/core`, `@uxf/core-react`, `@uxf/data-grid`, `@uxf/form`, `@uxf/router`, `@uxf/styles`, `@uxf/ui`, `@uxf/wysiwyg`, `@dnd-kit/core`, `@dnd-kit/sortable`, `@dnd-kit/utilities`, `@floating-ui/react`, `axios`, `axios-hooks`, `swr`, `react-hook-form`, `next` (>= 13.2.0), `react` (>= 18.2.0), `react-dom` (>= 18.2.0).
20
+
21
+ Because it builds on `@uxf/ui`, `@uxf/form` and `@uxf/data-grid`, complete their setup as well (see [`@uxf/ui`](../ui/README.md) and [`@uxf/form`](../form/README.md)) — the `UiContextProvider`, the token layer, and the component CSS they require.
22
+
23
+ ## Setup
24
+
25
+ ### 1. Providers
26
+
27
+ Two providers must wrap the app:
28
+
29
+ - `UiContextProvider` — configures translations, locale, color scheme and the icon sprite. It internally provides `TranslationsProvider` (`@uxf/core-react/translations`), which every `@uxf/cms` component needs because they use `useUxfTranslation`. Re-exported as `@uxf/cms/ui`; see the [`@uxf/ui` setup](../ui/README.md) for its full `value`.
30
+ - `CmsProvider` — sets up `swr` (`SWRConfig`) with a default `fetch`-based fetcher and an in-memory cache. Accepts an optional `swrConfig` prop to override the fetcher/provider/config.
31
+
32
+ ```tsx
33
+ import { AppProps } from "next/app";
34
+ import { CmsProvider } from "@uxf/cms/context/cms-provider";
35
+ import { UiContextProvider } from "@uxf/cms/ui";
36
+
37
+ export default function App(props: AppProps) {
38
+ return (
39
+ <UiContextProvider value={/* icons, translations, locale, colorScheme — see @uxf/ui setup */}>
40
+ <CmsProvider>
41
+ <props.Component {...props.pageProps} />
42
+ </CmsProvider>
43
+ </UiContextProvider>
44
+ );
45
+ }
46
+ ```
47
+
48
+ ### 2. Styles
49
+
50
+ CSS ships at the same path in the published package as in the source tree (unlike `@uxf/ui`, there is no flattening). Import the admin-shell bundle once, and the content-builder stylesheet where you render it:
51
+
52
+ ```css
53
+ /* admin layout, sidebar, menu, mobile bar, breadcrumbs, login layout, avatar */
54
+ @import url("@uxf/cms/utils/styles.css");
55
+
56
+ /* only where the content builder is used */
57
+ @import url("@uxf/cms/content-builder/content-builder.css");
58
+ ```
59
+
60
+ Individual admin stylesheets are also published under `@uxf/cms/ui/styles/<name>.css` (`avatar`, `breadcrumbs`, `layout`, `login-layout`, `menu`, `mobile-bar`, `sidebar`) if you prefer to import them selectively. These are on top of the `@uxf/ui` / `@uxf/data-grid` / `@uxf/form` token and component CSS, which you set up per those packages.
61
+
62
+ ### 3. Tailwind
63
+
64
+ `@uxf/cms` ships a Tailwind preset (which itself extends the `@uxf/ui` preset and adds avatar sizes and data-grid colors). Add it as a preset and include the package's compiled files in `content` so its class names are not purged:
65
+
66
+ ```js
67
+ const cmsTailwindConfig = require("@uxf/cms/utils/tailwind.config");
68
+
69
+ module.exports = {
70
+ presets: [cmsTailwindConfig],
71
+ content: [
72
+ "./node_modules/@uxf/cms/**/*.js",
73
+ // ...your own app files
74
+ ],
75
+ };
76
+ ```
77
+
78
+ ### 4. Translations
79
+
80
+ `@uxf/cms` ships its translation dictionaries: the merged default export at `@uxf/cms/translations/translations` and per-locale JSON at `@uxf/cms/translations/{cs,de,en,sk}.json` (namespaces such as `uxf-cms-login-form`, `uxf-cms-content-builder`, `uxf-cms-restricted-page`, …). Merge them into the translation function you pass to `UiContextProvider`, alongside the dictionaries of `@uxf/ui`, `@uxf/form`, `@uxf/data-grid` and `@uxf/wysiwyg`.
81
+
82
+ The package also ships `translations.d.ts`, an ambient augmentation that makes `useUxfTranslation` type-safe over the combined key set of `@uxf/cms` + `@uxf/data-grid` + `@uxf/form` + `@uxf/ui` + `@uxf/wysiwyg`.
83
+
84
+ ### 5. Icons
85
+
86
+ `@uxf/cms/icons-config` re-exports the merged icon set required by the package (the `@uxf/ui`, `@uxf/data-grid` and `@uxf/wysiwyg` sets plus CMS-specific glyphs), in the shape expected by `@uxf/icons-generator`. Feed it into your icon generation and pass the resulting sprite to `UiContextProvider`. The shipped `icons.d.ts` augments the `@uxf/ui` icon set (`@uxf/ui/icon/theme`) with these names.
87
+
88
+ ## Quick start
89
+
90
+ Each page is a factory that returns a Next.js page component. A login page:
91
+
92
+ ```tsx
93
+ // pages/admin/login.tsx
94
+ import { LoginPage } from "@uxf/cms/pages/login-page";
95
+
96
+ export default LoginPage({
97
+ title: "Sign in",
98
+ handleError: (error) => {
99
+ // surface the error to the user
100
+ },
101
+ onLoginDone: async (loginResponse, redirectUrl) => {
102
+ // persist loginResponse.access_token / refresh_token, then redirect
103
+ },
104
+ loggedUserRedirectUrl: "/admin",
105
+ });
106
+ ```
107
+
108
+ Gate any authenticated screen with `restrictedPage`, which checks the current user's roles against the backend before rendering:
109
+
110
+ ```tsx
111
+ import { restrictedPage } from "@uxf/cms/security/restricted-page";
112
+
113
+ function DashboardPage() {
114
+ return <div>Dashboard</div>;
115
+ }
116
+
117
+ export default restrictedPage(DashboardPage, { allowedRole: ["ROLE_ROOT"] });
118
+ ```
119
+
120
+ ## Entry points
121
+
122
+ Import paths resolve by filesystem to the compiled output (there is no `exports` map). This is an overview of the main areas, not an exhaustive list of every submodule.
123
+
124
+ | Import path | Provides |
125
+ | --- | --- |
126
+ | `@uxf/cms/context/cms-provider` | `CmsProvider` — the `swr` provider. |
127
+ | `@uxf/cms/ui` | Re-exports `UiContextProvider`, `useComponentContext` from `@uxf/ui/context`. |
128
+ | `@uxf/cms/api` | Typed request functions against `/api/cms/*` (`login`, `getLoggedUser`, `contentGet` / `contentCreate` / `contentUpdate`, `getFormSchema` / `getFormValues` / `saveFormValues`, `dataGridSchemaGet`, `autocomplete`, `userConfigGet` / `userConfigSave`, …) and their request/response types. |
129
+ | `@uxf/cms/api/swr` | SWR hooks (`useCmsMeQuery`, `useCmsUserConfigQuery`, `useCmsUserConfigUpdateMutation`) and the `ApiError` class. |
130
+ | `@uxf/cms/security/restricted-page` | `restrictedPage` — role-gated page wrapper. |
131
+ | `@uxf/cms/security/use-logged-user` | `useLoggedUser` — current-user SWR hook. |
132
+ | `@uxf/cms/pages/login-page` | `LoginPage` factory. |
133
+ | `@uxf/cms/pages/forgotten-password-page` | `ForgottenPasswordPage` factory. |
134
+ | `@uxf/cms/pages/renew-password-page` | `RenewPasswordPage` factory. |
135
+ | `@uxf/cms/pages/invite-user-page` | `InviteUserPage` factory. |
136
+ | `@uxf/cms/pages/content-builder` | `ContentBuilderPage`, `ContentField` and content mapping helpers. |
137
+ | `@uxf/cms/pages/grid-page` | `GridPage` factory (deprecated — prefer a project-specific `DataGrid`). |
138
+ | `@uxf/cms/forms/login-form` | `LoginForm`. |
139
+ | `@uxf/cms/forms/forgotten-password-form` | `ForgottenPasswordForm`. |
140
+ | `@uxf/cms/forms/renew-password-form` | `RenewPasswordForm`. |
141
+ | `@uxf/cms/forms/invite-user-form` | `InviteUserForm`. |
142
+ | `@uxf/cms/forms/change-password-form` | `ChangePasswordForm`. |
143
+ | `@uxf/cms/forms/components/wysiwyg-input` | `WysiwygInput` — `@uxf/form`-bound WYSIWYG field. |
144
+ | `@uxf/cms/content-builder` | `ContentBuilder`, `ContentBuilderRoot`, `mapContentResponseToFormData`, `mapFormDataToContentRequest`. |
145
+ | `@uxf/cms/lib/layout` | `Layout`, `Breadcrumbs` — the admin shell. |
146
+ | `@uxf/cms/lib/login-layout` | `LoginLayout`. |
147
+ | `@uxf/cms/lib/menu` | `Menu` and the menu-item factory (`createSection`, `createLink`, `createTableLink`, `createExternalLink`, `createUserMenu`, `createSuperSection`, `createCustomContent`). |
148
+ | `@uxf/cms/lib/api` | `createAxiosInstance` — the axios client factory used by `@uxf/cms/api`. |
149
+ | `@uxf/cms/config` | `container` — a small DI registry the app populates (route resolver, active-route hook, logged-user hooks, notification service) for `@uxf/cms` internals to consume. |
150
+ | `@uxf/cms/ui/avatar` · `@uxf/cms/ui/widget` · `@uxf/cms/ui/copy-to-clipboard` · `@uxf/cms/ui/copy-to-clipboard-button` | `Avatar`, `Widget`, `CopyToClipboard`, `CopyToClipboardButton`. |
151
+ | `@uxf/cms/utils/tailwind.config` | The Tailwind preset. |
152
+ | `@uxf/cms/errors/*` | `BadRequestError`, `ForbiddenError`, `NetworkError`, `UnauthorizedError`, `ValidationError` (one class per file). |
153
+
154
+ ## Gotchas
155
+
156
+ - No root import. `import … from "@uxf/cms"` does not resolve; always use a subpath (`main` points at an `index.js` that the build does not emit).
157
+ - Client components only. Pages, forms and the layout use `next/router`, `useId`, SWR and DOM APIs; they are not React Server Component-safe.
158
+ - Next.js Pages Router. The page factories return components with `getInitialProps` and use `next/router` — they target the Pages Router, not the App Router.
159
+ - Both providers are required. `UiContextProvider` (translations + icons) must be an ancestor of every `@uxf/cms` component, and `CmsProvider` must wrap anything using the SWR hooks (`useCmsMeQuery`, `useLoggedUser`, `GridPage`, `restrictedPage`).
160
+ - API base URLs come from env. `@uxf/cms/api` reads `NEXT_PUBLIC_FRONTEND_URL` and `@uxf/cms/api/swr` reads `API_URL`; requests hit `/api/cms/*` on that origin.
161
+ - The `deprecated/` directory (`withAuthenticate`, the security authorizator) and `GridPage` are kept for backward compatibility — do not use them in new code.
162
+
163
+ ## Links
164
+
165
+ - [`@uxf/ui`](../ui/README.md) — UI primitives and the `UiContextProvider` / CSS setup this package builds on.
166
+ - [`@uxf/form`](../form/README.md) — the react-hook-form fields the CMS forms are built from.
167
+ - [`@uxf/data-grid`](../data-grid) — the grid behind the list screens.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uxf/cms",
3
- "version": "11.122.3",
3
+ "version": "11.122.5",
4
4
  "description": "UXF Cms",
5
5
  "author": "UXFans <dev@uxf.cz>",
6
6
  "homepage": "https://gitlab.com/uxf-npm/cms#readme",
@@ -34,12 +34,12 @@
34
34
  "@floating-ui/react": "^0.27.17",
35
35
  "@uxf/core": "11.114.0",
36
36
  "@uxf/core-react": "11.122.2",
37
- "@uxf/data-grid": "11.122.3",
38
- "@uxf/form": "11.122.3",
37
+ "@uxf/data-grid": "11.122.5",
38
+ "@uxf/form": "11.122.5",
39
39
  "@uxf/router": "11.120.0",
40
- "@uxf/styles": "11.114.0",
41
- "@uxf/ui": "11.122.3",
42
- "@uxf/wysiwyg": "11.122.3",
40
+ "@uxf/styles": "11.122.4",
41
+ "@uxf/ui": "11.122.5",
42
+ "@uxf/wysiwyg": "11.122.5",
43
43
  "axios": "^1.13.4",
44
44
  "axios-hooks": "^5.1.1",
45
45
  "next": ">=13.2.0",
@@ -58,12 +58,12 @@
58
58
  "@types/react-dom": "18.3.7",
59
59
  "@uxf/core": "11.114.0",
60
60
  "@uxf/core-react": "11.122.2",
61
- "@uxf/data-grid": "11.122.3",
62
- "@uxf/form": "11.122.3",
61
+ "@uxf/data-grid": "11.122.5",
62
+ "@uxf/form": "11.122.5",
63
63
  "@uxf/router": "11.120.0",
64
- "@uxf/styles": "11.114.0",
65
- "@uxf/ui": "11.122.3",
66
- "@uxf/wysiwyg": "11.122.3",
64
+ "@uxf/styles": "11.122.4",
65
+ "@uxf/ui": "11.122.5",
66
+ "@uxf/wysiwyg": "11.122.5",
67
67
  "axios": "^1.13.4",
68
68
  "axios-hooks": "^5.1.1",
69
69
  "next": "16.1.6",