@questpie/admin 3.5.1 → 3.5.3
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/dist/client/builder/types/collection-types.d.mts +9 -0
- package/dist/client/components/actions/action-dialog.mjs +5 -0
- package/dist/client/components/fields/rich-text-editor/bubble-menu.mjs +7 -0
- package/dist/client/components/fields/rich-text-editor/extensions.mjs +17 -1
- package/dist/client/components/fields/rich-text-editor/index.d.mts +2 -1
- package/dist/client/components/fields/rich-text-editor/index.mjs +35 -74
- package/dist/client/components/fields/rich-text-editor/slash-commands.mjs +30 -7
- package/dist/client/components/fields/rich-text-editor/toolbar.mjs +1 -312
- package/dist/client/components/fields/rich-text-editor/types.d.mts +4 -0
- package/dist/client/components/fields/rich-text-editor/types.mjs +1 -1
- package/dist/client/components/fields/rich-text-editor/utils.mjs +6 -12
- package/dist/client/components/filter-builder/filter-builder-sheet.mjs +75 -22
- package/dist/client/components/ui/dropdown-menu.mjs +1 -34
- package/dist/client/hooks/query-access.d.mts +9 -0
- package/dist/client/hooks/query-access.mjs +20 -0
- package/dist/client/hooks/typed-hooks.d.mts +4 -2
- package/dist/client/hooks/typed-hooks.mjs +30 -29
- package/dist/client/hooks/use-reactive-fields.d.mts +1 -0
- package/dist/client/hooks/use-reactive-fields.mjs +16 -1
- package/dist/client/hooks/use-server-actions.mjs +12 -1
- package/dist/client/hooks/use-view-state.mjs +15 -7
- package/dist/client/lib/view-filter-utils.mjs +30 -0
- package/dist/client/preview/block-scope-context.d.mts +2 -2
- package/dist/client/preview/preview-banner.d.mts +2 -2
- package/dist/client/preview/preview-field.d.mts +4 -4
- package/dist/client/scope/picker.d.mts +2 -2
- package/dist/client/scope/provider.d.mts +2 -2
- package/dist/client/styles/base.css +69 -77
- package/dist/client/utils/build-field-definitions-from-schema.mjs +1 -0
- package/dist/client/views/collection/auto-form-fields.mjs +3 -2
- package/dist/client/views/collection/cells/primitive-cells.mjs +9 -6
- package/dist/client/views/collection/columns/build-columns.mjs +3 -1
- package/dist/client/views/collection/field-renderer.mjs +11 -3
- package/dist/client/views/collection/form-view.mjs +207 -202
- package/dist/client/views/collection/list-view.mjs +581 -183
- package/dist/client/views/collection/outline.mjs +44 -19
- package/dist/client/views/collection/quick-filter-bar.mjs +45 -0
- package/dist/client/views/collection/table-view.mjs +60 -16
- package/dist/client/views/globals/global-form-view.mjs +12 -9
- package/dist/client/views/layout/admin-layout.mjs +1 -1
- package/dist/client/views/layout/admin-sidebar.mjs +20 -14
- package/dist/client/views/layout/admin-theme.mjs +5 -4
- package/dist/client.mjs +1 -1
- package/dist/components/rich-text/rich-text-renderer.d.mts +5 -5
- package/dist/components/rich-text/rich-text-renderer.mjs +5 -2
- package/dist/index.mjs +1 -1
- package/dist/modules/admin.d.mts +1 -1
- package/dist/server/augmentation/actions.d.mts +4 -3
- package/dist/server/augmentation/dashboard.d.mts +11 -11
- package/dist/server/augmentation/form-layout.d.mts +11 -6
- package/dist/server/augmentation/index.d.mts +7 -0
- package/dist/server/augmentation/sidebar.d.mts +8 -8
- package/dist/server/codegen/admin-client-template.mjs +55 -38
- package/dist/server/fields/index.d.mts +1 -1
- package/dist/server/fields/rich-text.d.mts +16 -17
- package/dist/server/fields/rich-text.mjs +18 -7
- package/dist/server/i18n/messages/cs.mjs +2 -0
- package/dist/server/i18n/messages/de.mjs +2 -0
- package/dist/server/i18n/messages/en.mjs +4 -0
- package/dist/server/i18n/messages/es.mjs +2 -0
- package/dist/server/i18n/messages/fr.mjs +2 -0
- package/dist/server/i18n/messages/pl.mjs +2 -0
- package/dist/server/i18n/messages/pt.mjs +2 -0
- package/dist/server/i18n/messages/sk.mjs +2 -0
- package/dist/server/modules/admin/block/block-builder.d.mts +0 -8
- package/dist/server/modules/admin/block/introspection.d.mts +2 -2
- package/dist/server/modules/admin/collections/account.d.mts +53 -52
- package/dist/server/modules/admin/collections/admin-locks.d.mts +57 -56
- package/dist/server/modules/admin/collections/admin-preferences.d.mts +3 -2
- package/dist/server/modules/admin/collections/admin-saved-views.d.mts +50 -49
- package/dist/server/modules/admin/collections/apikey.d.mts +72 -71
- package/dist/server/modules/admin/collections/assets.d.mts +42 -41
- package/dist/server/modules/admin/collections/session.d.mts +46 -45
- package/dist/server/modules/admin/collections/user.d.mts +67 -66
- package/dist/server/modules/admin/collections/verification.d.mts +39 -38
- package/dist/server/modules/admin/index.d.mts +3 -3
- package/dist/server/modules/admin/routes/admin-config.d.mts +2 -2
- package/dist/server/modules/admin/routes/admin-config.mjs +39 -23
- package/dist/server/modules/admin/routes/execute-action.d.mts +9 -9
- package/dist/server/modules/admin/routes/execute-action.mjs +28 -8
- package/dist/server/modules/admin/routes/locales.d.mts +2 -2
- package/dist/server/modules/admin/routes/reactive.mjs +2 -2
- package/dist/server/modules/admin/routes/route-helpers.d.mts +11 -7
- package/dist/server/modules/admin/routes/translations.d.mts +4 -4
- package/dist/server/modules/admin/routes/widget-data.mjs +12 -4
- package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +27 -27
- package/dist/server/modules/audit/.generated/module.d.mts +6 -6
- package/dist/server/modules/audit/collections/audit-log.d.mts +40 -39
- package/dist/server/plugin.mjs +3 -3
- package/dist/server.d.mts +1 -1
- package/dist/shared/types/index.d.mts +1 -0
- package/dist/shared/types/saved-views.types.d.mts +14 -7
- package/dist/shared.d.mts +3 -2
- package/package.json +4 -3
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ComponentReference } from "./common.mjs";
|
|
1
|
+
import { ComponentReference as ComponentReference$1 } from "./common.mjs";
|
|
2
2
|
import { ComponentFactory } from "./views.mjs";
|
|
3
3
|
import { I18nText } from "questpie/shared";
|
|
4
|
+
import { ZodType } from "zod";
|
|
4
5
|
|
|
5
6
|
//#region src/server/augmentation/actions.d.ts
|
|
6
7
|
|
|
@@ -146,7 +147,7 @@ interface ServerActionFormFieldDefinition {
|
|
|
146
147
|
required?: boolean;
|
|
147
148
|
};
|
|
148
149
|
/** Generate Zod schema for validation */
|
|
149
|
-
toZodSchema():
|
|
150
|
+
toZodSchema(): ZodType;
|
|
150
151
|
}
|
|
151
152
|
/**
|
|
152
153
|
* Server-side action form configuration
|
|
@@ -176,7 +177,7 @@ interface ServerActionDefinition<TData = Record<string, unknown>> {
|
|
|
176
177
|
/** Action description */
|
|
177
178
|
description?: I18nText;
|
|
178
179
|
/** Icon reference */
|
|
179
|
-
icon?: ComponentReference;
|
|
180
|
+
icon?: ComponentReference$1;
|
|
180
181
|
/** Button variant */
|
|
181
182
|
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost";
|
|
182
183
|
/** Where the action appears */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComponentReference } from "./common.mjs";
|
|
1
|
+
import { ComponentReference as ComponentReference$1 } from "./common.mjs";
|
|
2
2
|
import { ComponentFactory } from "./views.mjs";
|
|
3
3
|
import { I18nText } from "questpie/shared";
|
|
4
4
|
import { AppContext } from "questpie";
|
|
@@ -39,7 +39,7 @@ interface ServerStatsWidget {
|
|
|
39
39
|
/** Widget label */
|
|
40
40
|
label?: I18nText;
|
|
41
41
|
/** Icon reference */
|
|
42
|
-
icon?: ComponentReference;
|
|
42
|
+
icon?: ComponentReference$1;
|
|
43
43
|
/** Collection to count */
|
|
44
44
|
collection: string;
|
|
45
45
|
/** Filter to apply */
|
|
@@ -141,7 +141,7 @@ interface ServerQuickAction {
|
|
|
141
141
|
/** Action label */
|
|
142
142
|
label: I18nText;
|
|
143
143
|
/** Action icon */
|
|
144
|
-
icon?: ComponentReference;
|
|
144
|
+
icon?: ComponentReference$1;
|
|
145
145
|
/** Visual variant */
|
|
146
146
|
variant?: "default" | "primary" | "secondary" | "outline";
|
|
147
147
|
/** Action to perform */
|
|
@@ -189,7 +189,7 @@ interface ServerValueWidget {
|
|
|
189
189
|
/** Widget label */
|
|
190
190
|
label?: I18nText;
|
|
191
191
|
/** Icon reference */
|
|
192
|
-
icon?: ComponentReference;
|
|
192
|
+
icon?: ComponentReference$1;
|
|
193
193
|
/** Card visual variant */
|
|
194
194
|
cardVariant?: "default" | "compact" | "featured";
|
|
195
195
|
/** Grid span (1-4) */
|
|
@@ -205,10 +205,10 @@ interface ServerValueWidget {
|
|
|
205
205
|
label?: I18nText | string;
|
|
206
206
|
subtitle?: I18nText | string;
|
|
207
207
|
footer?: I18nText | string;
|
|
208
|
-
icon?: ComponentReference;
|
|
208
|
+
icon?: ComponentReference$1;
|
|
209
209
|
trend?: {
|
|
210
210
|
value: string;
|
|
211
|
-
icon?: ComponentReference;
|
|
211
|
+
icon?: ComponentReference$1;
|
|
212
212
|
};
|
|
213
213
|
classNames?: Record<string, string>;
|
|
214
214
|
}>;
|
|
@@ -275,7 +275,7 @@ interface ServerTimelineWidget {
|
|
|
275
275
|
title: string;
|
|
276
276
|
description?: string;
|
|
277
277
|
timestamp: Date | string;
|
|
278
|
-
icon?: ComponentReference;
|
|
278
|
+
icon?: ComponentReference$1;
|
|
279
279
|
variant?: "default" | "success" | "warning" | "error" | "info";
|
|
280
280
|
href?: string;
|
|
281
281
|
}>>;
|
|
@@ -321,7 +321,7 @@ interface ServerDashboardSection {
|
|
|
321
321
|
/** Section description */
|
|
322
322
|
description?: I18nText;
|
|
323
323
|
/** Section icon */
|
|
324
|
-
icon?: ComponentReference;
|
|
324
|
+
icon?: ComponentReference$1;
|
|
325
325
|
/** Layout mode */
|
|
326
326
|
layout?: "grid" | "stack";
|
|
327
327
|
/** Grid columns */
|
|
@@ -362,7 +362,7 @@ interface ServerDashboardTab {
|
|
|
362
362
|
/** Tab label */
|
|
363
363
|
label: I18nText;
|
|
364
364
|
/** Tab icon */
|
|
365
|
-
icon?: ComponentReference;
|
|
365
|
+
icon?: ComponentReference$1;
|
|
366
366
|
/** Tab items */
|
|
367
367
|
items: ServerDashboardItem[];
|
|
368
368
|
/** Grid columns for this tab */
|
|
@@ -387,7 +387,7 @@ interface ServerDashboardAction {
|
|
|
387
387
|
/** Action label */
|
|
388
388
|
label: I18nText;
|
|
389
389
|
/** Action icon */
|
|
390
|
-
icon?: ComponentReference;
|
|
390
|
+
icon?: ComponentReference$1;
|
|
391
391
|
/** Action URL */
|
|
392
392
|
href: string;
|
|
393
393
|
/** Visual variant */
|
|
@@ -427,7 +427,7 @@ type BrandLogo = string | {
|
|
|
427
427
|
alt?: string;
|
|
428
428
|
width?: number;
|
|
429
429
|
height?: number;
|
|
430
|
-
} | ComponentReference;
|
|
430
|
+
} | ComponentReference$1;
|
|
431
431
|
/**
|
|
432
432
|
* Branding configuration for the admin panel. Covers content only — name,
|
|
433
433
|
* logo, tagline, favicon. Visual tokens (colors, fonts, radius, shadows)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ActionReference, ComponentReference } from "./common.mjs";
|
|
1
|
+
import { ActionReference, ComponentReference as ComponentReference$1 } from "./common.mjs";
|
|
2
|
+
import { FilterRule, QuickFilterConfig } from "../../shared/types/saved-views.types.mjs";
|
|
2
3
|
import { I18nText } from "questpie/shared";
|
|
3
4
|
|
|
4
5
|
//#region src/server/augmentation/form-layout.d.ts
|
|
@@ -13,7 +14,7 @@ interface AdminCollectionConfig {
|
|
|
13
14
|
/** Description shown in tooltips/help text */
|
|
14
15
|
description?: I18nText;
|
|
15
16
|
/** Icon reference (resolved by client's icon component) */
|
|
16
|
-
icon?: ComponentReference;
|
|
17
|
+
icon?: ComponentReference$1;
|
|
17
18
|
/** Hide from admin sidebar */
|
|
18
19
|
hidden?: boolean;
|
|
19
20
|
/** Group in sidebar */
|
|
@@ -37,7 +38,7 @@ interface BlockCategoryConfig {
|
|
|
37
38
|
/** Display label for the category */
|
|
38
39
|
label: I18nText;
|
|
39
40
|
/** Icon for the category */
|
|
40
|
-
icon?: ComponentReference;
|
|
41
|
+
icon?: ComponentReference$1;
|
|
41
42
|
/** Order in block picker (lower = first) */
|
|
42
43
|
order?: number;
|
|
43
44
|
}
|
|
@@ -64,7 +65,7 @@ interface AdminBlockConfig {
|
|
|
64
65
|
/** Description shown in tooltips/help text */
|
|
65
66
|
description?: I18nText;
|
|
66
67
|
/** Icon reference (resolved by client's icon component) */
|
|
67
|
-
icon?: ComponentReference;
|
|
68
|
+
icon?: ComponentReference$1;
|
|
68
69
|
/** Category for grouping in block picker */
|
|
69
70
|
category?: BlockCategoryConfig;
|
|
70
71
|
/** Order within category in block picker (lower = first) */
|
|
@@ -137,6 +138,10 @@ interface ListViewConfig {
|
|
|
137
138
|
field: string;
|
|
138
139
|
direction: "asc" | "desc";
|
|
139
140
|
};
|
|
141
|
+
/** Initial filters used when the user has no saved view state */
|
|
142
|
+
defaultFilters?: FilterRule[];
|
|
143
|
+
/** Header-level quick filter presets */
|
|
144
|
+
quickFilters?: QuickFilterConfig[];
|
|
140
145
|
/**
|
|
141
146
|
* Enables reorder mode for this list.
|
|
142
147
|
* Requires a numeric field named `order` on the collection.
|
|
@@ -250,7 +255,7 @@ interface FormTabConfig {
|
|
|
250
255
|
/** Tab label */
|
|
251
256
|
label: I18nText;
|
|
252
257
|
/** Tab icon */
|
|
253
|
-
icon?: ComponentReference;
|
|
258
|
+
icon?: ComponentReference$1;
|
|
254
259
|
/** Fields in this tab */
|
|
255
260
|
fields: FieldLayoutItem[];
|
|
256
261
|
/** Conditional visibility */
|
|
@@ -416,7 +421,7 @@ interface AdminGlobalConfig {
|
|
|
416
421
|
/** Description */
|
|
417
422
|
description?: I18nText;
|
|
418
423
|
/** Icon reference */
|
|
419
|
-
icon?: ComponentReference;
|
|
424
|
+
icon?: ComponentReference$1;
|
|
420
425
|
/** Hide from admin */
|
|
421
426
|
hidden?: boolean;
|
|
422
427
|
/** Group in sidebar */
|
|
@@ -5,6 +5,7 @@ import { BrandLogo, DashboardActionFactory, DashboardActionProxy, DashboardCallb
|
|
|
5
5
|
import { ServerSidebarCollectionItem, ServerSidebarConfig, ServerSidebarDividerItem, ServerSidebarGlobalItem, ServerSidebarItem, ServerSidebarLinkItem, ServerSidebarPageItem, ServerSidebarSection, SidebarCallback, SidebarCallbackContext, SidebarConfigContext, SidebarContribution, SidebarItemDef, SidebarProxy, SidebarSectionDef } from "./sidebar.mjs";
|
|
6
6
|
import { AdminShellRailPlacement, AdminShellRouteRules, ServerAdminShellConfig, ServerAdminShellRailConfig } from "./shell.mjs";
|
|
7
7
|
import { ActionsConfigContext, BuiltinActionType, ServerActionContext, ServerActionDefinition, ServerActionDownload, ServerActionEffects, ServerActionError, ServerActionForm, ServerActionFormField, ServerActionFormFieldConfig, ServerActionFormFieldDefinition, ServerActionHandler, ServerActionRedirect, ServerActionResult, ServerActionSuccess, ServerActionsConfig } from "./actions.mjs";
|
|
8
|
+
import { AdminSidebarMode } from "questpie";
|
|
8
9
|
|
|
9
10
|
//#region src/server/augmentation/index.d.ts
|
|
10
11
|
|
|
@@ -27,6 +28,12 @@ import { ActionsConfigContext, BuiltinActionType, ServerActionContext, ServerAct
|
|
|
27
28
|
* ```
|
|
28
29
|
*/
|
|
29
30
|
interface AdminConfigInput {
|
|
31
|
+
/**
|
|
32
|
+
* How module `sidebar` contributions combine with the app config.
|
|
33
|
+
* `append` (default): merge module items into the app sidebar.
|
|
34
|
+
* `replace`: keep only this file's `sidebar` (no module nav injection).
|
|
35
|
+
*/
|
|
36
|
+
sidebarMode?: AdminSidebarMode;
|
|
30
37
|
sidebar?: SidebarContribution;
|
|
31
38
|
dashboard?: DashboardContribution | ServerDashboardConfig;
|
|
32
39
|
shell?: ServerAdminShellConfig;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComponentReference } from "./common.mjs";
|
|
1
|
+
import { ComponentReference as ComponentReference$1 } from "./common.mjs";
|
|
2
2
|
import { ComponentFactory } from "./views.mjs";
|
|
3
3
|
import { I18nText } from "questpie/shared";
|
|
4
4
|
|
|
@@ -18,7 +18,7 @@ interface ServerSidebarCollectionItem {
|
|
|
18
18
|
/** Override display label */
|
|
19
19
|
label?: I18nText;
|
|
20
20
|
/** Override icon */
|
|
21
|
-
icon?: ComponentReference;
|
|
21
|
+
icon?: ComponentReference$1;
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
24
|
* Global item in sidebar
|
|
@@ -30,7 +30,7 @@ interface ServerSidebarGlobalItem {
|
|
|
30
30
|
/** Override display label */
|
|
31
31
|
label?: I18nText;
|
|
32
32
|
/** Override icon */
|
|
33
|
-
icon?: ComponentReference;
|
|
33
|
+
icon?: ComponentReference$1;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
36
|
* Custom page item in sidebar
|
|
@@ -42,7 +42,7 @@ interface ServerSidebarPageItem {
|
|
|
42
42
|
/** Display label */
|
|
43
43
|
label?: I18nText;
|
|
44
44
|
/** Icon */
|
|
45
|
-
icon?: ComponentReference;
|
|
45
|
+
icon?: ComponentReference$1;
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
48
48
|
* External link item in sidebar
|
|
@@ -54,7 +54,7 @@ interface ServerSidebarLinkItem {
|
|
|
54
54
|
/** Link URL */
|
|
55
55
|
href: string;
|
|
56
56
|
/** Icon */
|
|
57
|
-
icon?: ComponentReference;
|
|
57
|
+
icon?: ComponentReference$1;
|
|
58
58
|
/** Open in new tab */
|
|
59
59
|
external?: boolean;
|
|
60
60
|
}
|
|
@@ -73,7 +73,7 @@ interface ServerSidebarSection {
|
|
|
73
73
|
/** Section title */
|
|
74
74
|
title?: I18nText;
|
|
75
75
|
/** Section icon */
|
|
76
|
-
icon?: ComponentReference;
|
|
76
|
+
icon?: ComponentReference$1;
|
|
77
77
|
/** Whether this section can be collapsed/expanded by the user */
|
|
78
78
|
collapsible?: boolean;
|
|
79
79
|
/** Section items */
|
|
@@ -108,7 +108,7 @@ interface SidebarSectionDef {
|
|
|
108
108
|
/** Section title. */
|
|
109
109
|
title?: I18nText;
|
|
110
110
|
/** Section icon. */
|
|
111
|
-
icon?: ComponentReference;
|
|
111
|
+
icon?: ComponentReference$1;
|
|
112
112
|
/** Whether section is collapsible. */
|
|
113
113
|
collapsible?: boolean;
|
|
114
114
|
}
|
|
@@ -134,7 +134,7 @@ interface SidebarItemDef extends Omit<ServerSidebarItem, "type"> {
|
|
|
134
134
|
/** URL (for links). */
|
|
135
135
|
href?: string;
|
|
136
136
|
/** Icon reference. */
|
|
137
|
-
icon?: ComponentReference;
|
|
137
|
+
icon?: ComponentReference$1;
|
|
138
138
|
/** Open in new tab (for links). */
|
|
139
139
|
external?: boolean;
|
|
140
140
|
}
|
|
@@ -1,5 +1,47 @@
|
|
|
1
|
+
import { categoryRecordEntry, importStatement, sortedValues } from "questpie/codegen";
|
|
2
|
+
|
|
1
3
|
//#region src/server/codegen/admin-client-template.ts
|
|
2
4
|
/**
|
|
5
|
+
* Admin Client Template Generator
|
|
6
|
+
*
|
|
7
|
+
* Custom generator for the `admin-client` codegen target.
|
|
8
|
+
* Produces `questpie/admin/.generated/client.ts` — a plain admin config
|
|
9
|
+
* object that merges module defaults with user-discovered files.
|
|
10
|
+
*
|
|
11
|
+
* ## Architecture
|
|
12
|
+
*
|
|
13
|
+
* The admin-client target works identically to the server target:
|
|
14
|
+
*
|
|
15
|
+
* 1. **Package mode** (`generatePackageModules`): discovers files from
|
|
16
|
+
* `modules/admin/client/` → generates `modules/admin/client/.generated/module.ts`
|
|
17
|
+
* using the standard `generateModuleTemplate()` primitive.
|
|
18
|
+
*
|
|
19
|
+
* 2. **Root app mode** (`runAllTargets`): user has `admin/modules.ts` that imports
|
|
20
|
+
* module packages → this template imports `_mod` and merges generically with
|
|
21
|
+
* user-discovered files from `admin/{blocks,views,fields,...}/`.
|
|
22
|
+
*
|
|
23
|
+
* ## How to create an admin-client module (for third-party packages)
|
|
24
|
+
*
|
|
25
|
+
* 1. Create wrapper files in `modules/<name>/client/{fields,views,...}/`
|
|
26
|
+
* 2. Run `questpie generate` — generates `client/.generated/module.ts`
|
|
27
|
+
* 3. Create `client/index.ts` that re-exports the generated module
|
|
28
|
+
* 4. Add `"./client/module"` to `package.json` exports
|
|
29
|
+
*
|
|
30
|
+
* ## How users extend admin
|
|
31
|
+
*
|
|
32
|
+
* Add files in `questpie/admin/{views,fields,pages,widgets,blocks,components}/`.
|
|
33
|
+
* They are discovered automatically and merged over module defaults.
|
|
34
|
+
*
|
|
35
|
+
* ## Category key strategies
|
|
36
|
+
*
|
|
37
|
+
* - Default: use file key — `"bookingCta": _block_bookingCta`
|
|
38
|
+
* - `keyFromProperty: "name"`: use runtime key — `[_view_kanban.name]: _view_kanban`
|
|
39
|
+
*
|
|
40
|
+
* The strategy is declared per-category in `CategoryDeclaration.keyFromProperty`.
|
|
41
|
+
*
|
|
42
|
+
* @see PLAN-PLUGIN-CONSISTENCY.md §6.2 (admin-client target)
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
3
45
|
* Generate the admin client config file.
|
|
4
46
|
*
|
|
5
47
|
* Called by `runAllTargets()` for the `admin-client` target.
|
|
@@ -18,24 +60,25 @@ function generateAdminClientTemplate(ctx) {
|
|
|
18
60
|
lines.push(" */");
|
|
19
61
|
lines.push("");
|
|
20
62
|
if (modulesFile) {
|
|
21
|
-
lines.push(
|
|
22
|
-
lines.push(
|
|
23
|
-
lines.push(
|
|
24
|
-
lines.push(
|
|
63
|
+
lines.push(importStatement(modulesFile));
|
|
64
|
+
lines.push("type _AdminModuleMergeAcc = Record<string, unknown>;");
|
|
65
|
+
lines.push(`const _mergedModules = (Array.isArray(${modulesFile.varName})`);
|
|
66
|
+
lines.push(`\t? ${modulesFile.varName}.reduce<_AdminModuleMergeAcc>((acc, mod) => {`);
|
|
67
|
+
lines.push(" for (const [k, v] of Object.entries(mod)) acc[k] = typeof v === \"object\" && v !== null && !Array.isArray(v) ? { ...(typeof acc[k] === \"object\" && acc[k] !== null && !Array.isArray(acc[k]) ? acc[k] as Record<string, unknown> : {}), ...(v as Record<string, unknown>) } : v;");
|
|
25
68
|
lines.push(" return acc;");
|
|
26
|
-
lines.push(`\t}, {}
|
|
69
|
+
lines.push(`\t}, {}) : ${modulesFile.varName}) as _AdminModuleMergeAcc;`);
|
|
27
70
|
}
|
|
28
71
|
const categoryFiles = /* @__PURE__ */ new Map();
|
|
29
72
|
for (const [cat, fileMap] of ctx.discovered.categories) if (fileMap.size > 0) {
|
|
30
|
-
const sorted =
|
|
73
|
+
const sorted = sortedValues(fileMap);
|
|
31
74
|
categoryFiles.set(cat, sorted);
|
|
32
|
-
for (const file of sorted) lines.push(
|
|
75
|
+
for (const file of sorted) lines.push(importStatement(file));
|
|
33
76
|
}
|
|
34
77
|
const singleFiles = /* @__PURE__ */ new Map();
|
|
35
78
|
for (const [key, file] of ctx.discovered.singles) {
|
|
36
79
|
if (key === "modules") continue;
|
|
37
80
|
singleFiles.set(key, file);
|
|
38
|
-
lines.push(
|
|
81
|
+
lines.push(importStatement(file));
|
|
39
82
|
}
|
|
40
83
|
for (const imp of ctx.extraImports) lines.push(`import ${imp.name} from "${imp.path}";`);
|
|
41
84
|
lines.push("");
|
|
@@ -52,11 +95,11 @@ function generateAdminClientTemplate(ctx) {
|
|
|
52
95
|
const files = categoryFiles.get(cat);
|
|
53
96
|
const catDecl = ctx.target.categories?.[cat];
|
|
54
97
|
if (modulesFile && files && files.length > 0) {
|
|
55
|
-
const entries =
|
|
56
|
-
lines.push(`\t${cat}: { ..._mergedModules
|
|
57
|
-
} else if (modulesFile && (!files || files.length === 0)) lines.push(`\t${cat}: { ..._mergedModules
|
|
98
|
+
const entries = files.map((f) => categoryRecordEntry(f, catDecl)).join(", ");
|
|
99
|
+
lines.push(`\t${cat}: { ...(_mergedModules[${JSON.stringify(cat)}] as Record<string, unknown>), ${entries} },`);
|
|
100
|
+
} else if (modulesFile && (!files || files.length === 0)) lines.push(`\t${cat}: { ...(_mergedModules[${JSON.stringify(cat)}] as Record<string, unknown>) },`);
|
|
58
101
|
else if (files && files.length > 0) {
|
|
59
|
-
const entries =
|
|
102
|
+
const entries = files.map((f) => categoryRecordEntry(f, catDecl)).join(", ");
|
|
60
103
|
lines.push(`\t${cat}: { ${entries} },`);
|
|
61
104
|
}
|
|
62
105
|
}
|
|
@@ -73,32 +116,6 @@ function generateAdminClientTemplate(ctx) {
|
|
|
73
116
|
lines.push("");
|
|
74
117
|
return { code: lines.join("\n") };
|
|
75
118
|
}
|
|
76
|
-
/**
|
|
77
|
-
* Generate category entries string based on the category's key strategy.
|
|
78
|
-
*
|
|
79
|
-
* When `keyFromProperty` is set (e.g., views with `keyFromProperty: "name"`),
|
|
80
|
-
* uses runtime property as key: `[_view_kanban.name]: _view_kanban`.
|
|
81
|
-
*
|
|
82
|
-
* Otherwise uses the file-derived key: `"bookingCta": _block_bookingCta`.
|
|
83
|
-
*/
|
|
84
|
-
function generateCategoryEntries(files, catDecl) {
|
|
85
|
-
const keyProp = catDecl?.keyFromProperty;
|
|
86
|
-
return files.map((f) => {
|
|
87
|
-
if (keyProp) return `[${f.varName}.${keyProp}]: ${f.varName}`;
|
|
88
|
-
if (catDecl?.keyFromSource === "basename") return `${JSON.stringify(getSourceBasename(f))}: ${f.varName}`;
|
|
89
|
-
return `${JSON.stringify(f.key)}: ${f.varName}`;
|
|
90
|
-
}).join(", ");
|
|
91
|
-
}
|
|
92
|
-
function getSourceBasename(file) {
|
|
93
|
-
return (file.source.replaceAll("\\", "/").split("/").pop() ?? file.key).replace(/\.[^.]+$/, "");
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Generate an import line for a discovered file.
|
|
97
|
-
*/
|
|
98
|
-
function generateImportLine(file) {
|
|
99
|
-
if (file.exportType === "named" && file.namedExportName) return `import { ${file.namedExportName} as ${file.varName} } from "${file.importPath}";`;
|
|
100
|
-
return `import ${file.varName} from "${file.importPath}";`;
|
|
101
|
-
}
|
|
102
119
|
|
|
103
120
|
//#endregion
|
|
104
121
|
export { generateAdminClientTemplate };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BlockNode, BlockValues, BlocksDocument, BlocksFieldMeta, BlocksFieldState, blocks, blocksFieldType } from "./blocks.mjs";
|
|
2
|
-
import { RichTextFeature, RichTextFieldMeta, RichTextFieldState, TipTapDocument, TipTapNode, richText, richTextFieldType } from "./rich-text.mjs";
|
|
2
|
+
import { RichTextFeature, RichTextFieldMeta, RichTextFieldState, RichTextMode, RichTextOptions, TipTapDocument, TipTapNode, richText, richTextFieldType } from "./rich-text.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/server/fields/index.d.ts
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DefaultFieldState, Field, FieldTypeDefinition } from "questpie";
|
|
2
|
-
import { PgJsonbBuilder } from "questpie/drizzle-pg-core";
|
|
2
|
+
import { PgJsonbBuilder, PgTextBuilder } from "questpie/drizzle-pg-core";
|
|
3
3
|
|
|
4
4
|
//#region src/server/fields/rich-text.d.ts
|
|
5
5
|
|
|
@@ -48,28 +48,27 @@ interface RichTextFieldMeta {
|
|
|
48
48
|
* Available rich text editor features.
|
|
49
49
|
*/
|
|
50
50
|
type RichTextFeature = "bold" | "italic" | "underline" | "strike" | "code" | "subscript" | "superscript" | "heading" | "bulletList" | "orderedList" | "taskList" | "blockquote" | "codeBlock" | "horizontalRule" | "link" | "image" | "table" | "textAlign" | "textColor" | "highlight" | "mention";
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
* content: f.richText().required().localized()
|
|
59
|
-
* ```
|
|
60
|
-
*/
|
|
61
|
-
type RichTextFieldState = DefaultFieldState & {
|
|
51
|
+
type RichTextMode = "json" | "markdown";
|
|
52
|
+
type RichTextOptions = {
|
|
53
|
+
mode?: RichTextMode;
|
|
54
|
+
};
|
|
55
|
+
type RichTextData<TMode extends RichTextMode> = TMode extends "markdown" ? string : TipTapDocument;
|
|
56
|
+
type RichTextColumn<TMode extends RichTextMode> = TMode extends "markdown" ? PgTextBuilder : PgJsonbBuilder;
|
|
57
|
+
type RichTextFieldState<TMode extends RichTextMode = "json"> = DefaultFieldState & {
|
|
62
58
|
type: "richText";
|
|
63
|
-
data:
|
|
64
|
-
column:
|
|
59
|
+
data: RichTextData<TMode>;
|
|
60
|
+
column: RichTextColumn<TMode>;
|
|
65
61
|
};
|
|
66
|
-
declare function richText(): Field<RichTextFieldState
|
|
62
|
+
declare function richText(): Field<RichTextFieldState<"json">>;
|
|
63
|
+
declare function richText<const TMode extends RichTextMode>(options: {
|
|
64
|
+
mode: TMode;
|
|
65
|
+
}): Field<RichTextFieldState<TMode>>;
|
|
67
66
|
/**
|
|
68
67
|
* Rich text field type definition (v3 API).
|
|
69
68
|
*
|
|
70
69
|
* Use this with the `fieldType()` discovery system instead of the
|
|
71
70
|
* legacy `richText()` factory function.
|
|
72
71
|
*/
|
|
73
|
-
declare const richTextFieldType: FieldTypeDefinition<"richText", []>;
|
|
72
|
+
declare const richTextFieldType: FieldTypeDefinition<"richText", [RichTextOptions?]>;
|
|
74
73
|
//#endregion
|
|
75
|
-
export { RichTextFeature, RichTextFieldMeta, RichTextFieldState, TipTapDocument, TipTapNode, richText, richTextFieldType };
|
|
74
|
+
export { RichTextFeature, RichTextFieldMeta, RichTextFieldState, RichTextMode, RichTextOptions, TipTapDocument, TipTapNode, richText, richTextFieldType };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { field, fieldType, isNotNull, isNull, jsonb, sql } from "questpie";
|
|
3
|
+
import { text } from "questpie/drizzle-pg-core";
|
|
3
4
|
|
|
4
5
|
//#region src/server/fields/rich-text.ts
|
|
5
6
|
/**
|
|
@@ -85,6 +86,13 @@ function getRichTextOperators() {
|
|
|
85
86
|
}
|
|
86
87
|
};
|
|
87
88
|
}
|
|
89
|
+
const markdownOperators = {
|
|
90
|
+
contains: (col, value) => sql`${col} ILIKE ${"%" + value + "%"}`,
|
|
91
|
+
isEmpty: (col) => sql`(${col} IS NULL OR length(trim(${col})) = 0)`,
|
|
92
|
+
isNotEmpty: (col) => sql`(${col} IS NOT NULL AND length(trim(${col})) > 0)`,
|
|
93
|
+
isNull: (col) => isNull(col),
|
|
94
|
+
isNotNull: (col) => isNotNull(col)
|
|
95
|
+
};
|
|
88
96
|
/**
|
|
89
97
|
* Create a rich text field.
|
|
90
98
|
*
|
|
@@ -97,11 +105,13 @@ function getRichTextOperators() {
|
|
|
97
105
|
* Rich text field runtime state factory.
|
|
98
106
|
* Shared between the legacy `richText()` function and the new `richTextFieldType`.
|
|
99
107
|
*/
|
|
100
|
-
function createRichTextState() {
|
|
108
|
+
function createRichTextState(options) {
|
|
109
|
+
const mode = options?.mode ?? "json";
|
|
110
|
+
const isMarkdown = mode === "markdown";
|
|
101
111
|
return {
|
|
102
112
|
type: "richText",
|
|
103
|
-
columnFactory: (name) => jsonb(name),
|
|
104
|
-
schemaFactory: () => {
|
|
113
|
+
columnFactory: isMarkdown ? (name) => text(name) : (name) => jsonb(name),
|
|
114
|
+
schemaFactory: isMarkdown ? () => z.string() : () => {
|
|
105
115
|
const nodeSchema = z.lazy(() => z.object({
|
|
106
116
|
type: z.string(),
|
|
107
117
|
attrs: z.record(z.string(), z.any()).optional(),
|
|
@@ -117,7 +127,7 @@ function createRichTextState() {
|
|
|
117
127
|
content: z.array(nodeSchema).optional()
|
|
118
128
|
});
|
|
119
129
|
},
|
|
120
|
-
operatorSet: {
|
|
130
|
+
operatorSet: isMarkdown ? markdownOperators : {
|
|
121
131
|
jsonbCast: null,
|
|
122
132
|
column: getRichTextOperators().column
|
|
123
133
|
},
|
|
@@ -129,7 +139,8 @@ function createRichTextState() {
|
|
|
129
139
|
localized: state.localized ?? false,
|
|
130
140
|
readOnly: state.input === false ? true : void 0,
|
|
131
141
|
writeOnly: state.output === false ? true : void 0,
|
|
132
|
-
meta: state.extensions?.admin
|
|
142
|
+
meta: state.extensions?.admin,
|
|
143
|
+
outputMode: mode
|
|
133
144
|
}),
|
|
134
145
|
notNull: false,
|
|
135
146
|
hasDefault: false,
|
|
@@ -140,8 +151,8 @@ function createRichTextState() {
|
|
|
140
151
|
isArray: false
|
|
141
152
|
};
|
|
142
153
|
}
|
|
143
|
-
function richText() {
|
|
144
|
-
return field(createRichTextState());
|
|
154
|
+
function richText(options) {
|
|
155
|
+
return field(createRichTextState(options));
|
|
145
156
|
}
|
|
146
157
|
/**
|
|
147
158
|
* Rich text field type definition (v3 API).
|
|
@@ -719,6 +719,8 @@ var cs_default = {
|
|
|
719
719
|
"viewOptions.groupByDescription": "Seskupit aktuální stránku podle nakonfigurovaného pole.",
|
|
720
720
|
"viewOptions.noGrouping": "Bez seskupení",
|
|
721
721
|
"viewOptions.sort": "Řazení",
|
|
722
|
+
"viewOptions.noSort": "Bez řazení",
|
|
723
|
+
"viewOptions.sortDescription": "Vyberte pole a směr řazení pro tento pohled.",
|
|
722
724
|
"version.history": "Historie verzí",
|
|
723
725
|
"version.historyDescription": "Procházejte předchozí verze a v případě potřeby některou obnovte.",
|
|
724
726
|
"version.globalHistoryDescription": "Procházejte předchozí verze globálních nastavení a v případě potřeby některou obnovte.",
|
|
@@ -717,6 +717,8 @@ var de_default = {
|
|
|
717
717
|
"viewOptions.groupByDescription": "Die aktuelle Seite nach einem konfigurierten Feld gruppieren.",
|
|
718
718
|
"viewOptions.noGrouping": "Keine Gruppierung",
|
|
719
719
|
"viewOptions.sort": "Sortierung",
|
|
720
|
+
"viewOptions.noSort": "Keine Sortierung",
|
|
721
|
+
"viewOptions.sortDescription": "Wählen Sie Feld und Richtung für diese Ansicht.",
|
|
720
722
|
"version.history": "Versionsverlauf",
|
|
721
723
|
"version.historyDescription": "Durchsuchen Sie frühere Versionen und stellen Sie bei Bedarf eine wieder her.",
|
|
722
724
|
"version.globalHistoryDescription": "Durchsuchen Sie frühere globale Versionen und stellen Sie bei Bedarf eine wieder her.",
|
|
@@ -370,6 +370,8 @@ var en_default = {
|
|
|
370
370
|
"table.noItemsInCollection": "No items found in this collection",
|
|
371
371
|
"table.emptyDescription": "Records will appear here once they are created.",
|
|
372
372
|
"table.pagination": "Pagination",
|
|
373
|
+
"table.items": "items",
|
|
374
|
+
"table.loadMore": "Load more",
|
|
373
375
|
"table.editing": "Editing",
|
|
374
376
|
"upload.dropzone": "Drop files here or click to upload",
|
|
375
377
|
"upload.browse": "Browse files",
|
|
@@ -636,6 +638,8 @@ var en_default = {
|
|
|
636
638
|
"viewOptions.groupByDescription": "Group the current page by a configured field.",
|
|
637
639
|
"viewOptions.noGrouping": "No grouping",
|
|
638
640
|
"viewOptions.sort": "Sort",
|
|
641
|
+
"viewOptions.noSort": "No sorting",
|
|
642
|
+
"viewOptions.sortDescription": "Choose the field and direction used by this view.",
|
|
639
643
|
"version.history": "Version history",
|
|
640
644
|
"version.historyDescription": "Browse previous versions and restore one if needed.",
|
|
641
645
|
"version.globalHistoryDescription": "Browse previous global versions and restore one if needed.",
|
|
@@ -862,6 +862,8 @@ var es_default = {
|
|
|
862
862
|
"viewOptions.showDeleted": "Mostrar eliminados",
|
|
863
863
|
"viewOptions.showDeletedDescription": "Incluir registros eliminados de forma reversible en esta vista.",
|
|
864
864
|
"viewOptions.sort": "Ordenar",
|
|
865
|
+
"viewOptions.noSort": "Sin ordenación",
|
|
866
|
+
"viewOptions.sortDescription": "Elige el campo y la dirección para esta vista.",
|
|
865
867
|
"widget.chart.emptyDescription": "Configure una fuente de datos para mostrar un gráfico.",
|
|
866
868
|
"widget.chart.emptyTitle": "No hay datos de gráfico",
|
|
867
869
|
"widget.progress.emptyDescription": "Configure datos de progreso para mostrar este widget.",
|
|
@@ -862,6 +862,8 @@ var fr_default = {
|
|
|
862
862
|
"viewOptions.showDeleted": "Afficher les supprimés",
|
|
863
863
|
"viewOptions.showDeletedDescription": "Inclure les enregistrements supprimés de façon réversible dans cette vue.",
|
|
864
864
|
"viewOptions.sort": "Trier",
|
|
865
|
+
"viewOptions.noSort": "Aucun tri",
|
|
866
|
+
"viewOptions.sortDescription": "Choisissez le champ et le sens utilisés par cette vue.",
|
|
865
867
|
"widget.chart.emptyDescription": "Configurez une source de données pour afficher un graphique.",
|
|
866
868
|
"widget.chart.emptyTitle": "Aucune donnée de graphique",
|
|
867
869
|
"widget.progress.emptyDescription": "Configurez des données de progression pour afficher ce widget.",
|
|
@@ -866,6 +866,8 @@ var pl_default = {
|
|
|
866
866
|
"viewOptions.showDeleted": "Pokaż usunięte",
|
|
867
867
|
"viewOptions.showDeletedDescription": "Uwzględnij w tym widoku rekordy usunięte miękko.",
|
|
868
868
|
"viewOptions.sort": "Sortuj",
|
|
869
|
+
"viewOptions.noSort": "Bez sortowania",
|
|
870
|
+
"viewOptions.sortDescription": "Wybierz pole i kierunek używane w tym widoku.",
|
|
869
871
|
"widget.chart.emptyDescription": "Skonfiguruj źródło danych, aby wyświetlić wykres.",
|
|
870
872
|
"widget.chart.emptyTitle": "Brak danych wykresu",
|
|
871
873
|
"widget.progress.emptyDescription": "Skonfiguruj dane postępu, aby wyświetlić ten widget.",
|
|
@@ -862,6 +862,8 @@ var pt_default = {
|
|
|
862
862
|
"viewOptions.showDeleted": "Mostrar excluídos",
|
|
863
863
|
"viewOptions.showDeletedDescription": "Incluir registros excluídos de forma reversível nesta visualização.",
|
|
864
864
|
"viewOptions.sort": "Ordenar",
|
|
865
|
+
"viewOptions.noSort": "Sem ordenação",
|
|
866
|
+
"viewOptions.sortDescription": "Escolha o campo e a direção usados nesta visualização.",
|
|
865
867
|
"widget.chart.emptyDescription": "Configure uma fonte de dados para exibir um gráfico.",
|
|
866
868
|
"widget.chart.emptyTitle": "Nenhum dado de gráfico",
|
|
867
869
|
"widget.progress.emptyDescription": "Configure dados de progresso para exibir este widget.",
|
|
@@ -602,6 +602,8 @@ var sk_default = {
|
|
|
602
602
|
"viewOptions.groupByDescription": "Zoskupí aktuálnu stránku podľa nakonfigurovaného poľa.",
|
|
603
603
|
"viewOptions.noGrouping": "Bez zoskupenia",
|
|
604
604
|
"viewOptions.sort": "Zoradenie",
|
|
605
|
+
"viewOptions.noSort": "Bez zoradenia",
|
|
606
|
+
"viewOptions.sortDescription": "Vyberte pole a smer zoradenia pre tento pohľad.",
|
|
605
607
|
"viewOptions.saveCurrentConfig": "Uložiť aktuálnu konfiguráciu",
|
|
606
608
|
"viewOptions.viewNamePlaceholder": "Názov zobrazenia...",
|
|
607
609
|
"viewOptions.saveDescription": "Uloží aktuálne stĺpce, filtre, zoskupenie a zoradenie.",
|
|
@@ -27,14 +27,6 @@ type AdminBlockFields = BuiltinFields & typeof adminFields;
|
|
|
27
27
|
* ```
|
|
28
28
|
*/
|
|
29
29
|
type BlockPrefetchContext = AppContext & {
|
|
30
|
-
/** App instance — populated at runtime by extractAppServices */
|
|
31
|
-
app: unknown;
|
|
32
|
-
/** Database handle — populated at runtime by extractAppServices */
|
|
33
|
-
db: unknown;
|
|
34
|
-
/** Collection APIs — populated at runtime by extractAppServices */
|
|
35
|
-
collections: Record<string, any>;
|
|
36
|
-
/** Global APIs — populated at runtime by extractAppServices */
|
|
37
|
-
globals: Record<string, any>;
|
|
38
30
|
/** Block instance ID */
|
|
39
31
|
blockId: string;
|
|
40
32
|
/** Block type name */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComponentReference } from "../../../augmentation/common.mjs";
|
|
1
|
+
import { ComponentReference as ComponentReference$1 } from "../../../augmentation/common.mjs";
|
|
2
2
|
import { BlockCategoryConfig, FieldLayoutItem } from "../../../augmentation/form-layout.mjs";
|
|
3
3
|
import "../../../augmentation.mjs";
|
|
4
4
|
import { AnyBlockDefinition } from "./block-builder.mjs";
|
|
@@ -21,7 +21,7 @@ interface BlockSchema {
|
|
|
21
21
|
/** Description */
|
|
22
22
|
description?: I18nText;
|
|
23
23
|
/** Icon reference */
|
|
24
|
-
icon?: ComponentReference;
|
|
24
|
+
icon?: ComponentReference$1;
|
|
25
25
|
/** Category for grouping in block picker */
|
|
26
26
|
category?: BlockCategoryConfig;
|
|
27
27
|
/** Order within category in block picker */
|