@questpie/admin 3.5.3 → 3.5.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.
- package/README.md +8 -0
- package/dist/client/blocks/block-renderer.d.mts +2 -2
- package/dist/client/builder/index.d.mts +1 -1
- package/dist/client/builder/types/collection-types.d.mts +80 -5
- package/dist/client/builder/types/common.d.mts +5 -0
- package/dist/client/builder/types/field-types.d.mts +41 -1
- package/dist/client/builder/view/view.d.mts +3 -2
- package/dist/client/components/admin-link.d.mts +2 -2
- package/dist/client/components/fields/boolean-field.mjs +2 -1
- package/dist/client/components/fields/date-field.mjs +2 -1
- package/dist/client/components/fields/datetime-field.mjs +2 -1
- package/dist/client/components/fields/email-field.mjs +2 -1
- package/dist/client/components/fields/field-utils.d.mts +11 -0
- package/dist/client/components/fields/field-utils.mjs +3 -1
- package/dist/client/components/fields/field-wrapper.mjs +3 -3
- package/dist/client/components/fields/number-field.mjs +2 -1
- package/dist/client/components/fields/object-field.mjs +2 -1
- package/dist/client/components/fields/relation/displays/types.mjs +3 -3
- package/dist/client/components/fields/rich-text-editor/extensions.mjs +2 -1
- package/dist/client/components/fields/rich-text-editor/image-popover.mjs +6 -2
- package/dist/client/components/fields/rich-text-editor/image-upload.mjs +2 -1
- package/dist/client/components/fields/rich-text-editor/index.d.mts +3 -2
- package/dist/client/components/fields/rich-text-editor/index.mjs +4 -3
- package/dist/client/components/fields/select-field.mjs +2 -1
- package/dist/client/components/fields/text-field.mjs +2 -1
- package/dist/client/components/fields/textarea-field.mjs +2 -1
- package/dist/client/components/fields/time-field.mjs +2 -1
- package/dist/client/components/layout/field-layout-renderer.mjs +4 -4
- package/dist/client/components/media/media-grid.mjs +2 -1
- package/dist/client/components/primitives/asset-preview.mjs +4 -2
- package/dist/client/components/primitives/dropzone.d.mts +100 -0
- package/dist/client/components/primitives/field-select-control.mjs +2 -1
- package/dist/client/components/ui/button.d.mts +23 -0
- package/dist/client/components/ui/button.mjs +2 -2
- package/dist/client/components/ui/dropdown-menu.d.mts +49 -0
- package/dist/client/components/ui/dropdown-menu.mjs +22 -1
- package/dist/client/components/ui/popover.mjs +1 -1
- package/dist/client/components/ui/search-input.d.mts +56 -0
- package/dist/client/components/ui/select.mjs +2 -2
- package/dist/client/components/ui/sheet.d.mts +40 -0
- package/dist/client/components/ui/table.d.mts +49 -0
- package/dist/client/components/ui/table.mjs +15 -1
- package/dist/client/components/ui/tooltip.d.mts +21 -0
- package/dist/client/contexts/focus-context.d.mts +2 -2
- package/dist/client/hooks/use-admin-config.mjs +20 -1
- package/dist/client/hooks/use-autosave.mjs +91 -0
- package/dist/client/hooks/use-collection.mjs +65 -23
- package/dist/client/hooks/use-upload.d.mts +40 -0
- package/dist/client/hooks/use-upload.mjs +4 -2
- package/dist/client/i18n/hooks.d.mts +20 -0
- package/dist/client/lib/utils.d.mts +6 -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/runtime/provider.mjs +22 -3
- package/dist/client/scope/picker.d.mts +2 -2
- package/dist/client/scope/provider.d.mts +2 -2
- package/dist/client/styles/base.css +22 -18
- package/dist/client/utils/asset-url.mjs +27 -0
- package/dist/client/views/auth/accept-invite-form.d.mts +2 -2
- package/dist/client/views/auth/auth-layout.d.mts +3 -3
- package/dist/client/views/auth/forgot-password-form.d.mts +2 -2
- package/dist/client/views/auth/login-form.d.mts +2 -2
- package/dist/client/views/auth/reset-password-form.d.mts +2 -2
- package/dist/client/views/auth/setup-form.d.mts +2 -2
- package/dist/client/views/collection/auto-form-fields.mjs +4 -4
- package/dist/client/views/collection/cells/shared/asset-thumbnail.d.mts +7 -0
- package/dist/client/views/collection/cells/shared/asset-thumbnail.mjs +3 -2
- package/dist/client/views/collection/cells/shared/cell-helpers.mjs +3 -2
- package/dist/client/views/collection/cells/upload-cells.mjs +2 -1
- package/dist/client/views/collection/document-view.d.mts +30 -0
- package/dist/client/views/collection/document-view.mjs +377 -0
- package/dist/client/views/collection/field-context.mjs +3 -2
- package/dist/client/views/collection/field-renderer.mjs +2 -2
- package/dist/client/views/collection/form-view.mjs +14 -80
- package/dist/client/views/collection/list-view.mjs +19 -15
- package/dist/client/views/collection/table-view.mjs +1 -1
- package/dist/client/views/layout/admin-layout-provider.mjs +4 -3
- package/dist/client/views/layout/admin-layout.mjs +107 -20
- package/dist/client/views/layout/admin-router.mjs +19 -3
- package/dist/client/views/layout/admin-sidebar.mjs +50 -6
- package/dist/client/views/layout/admin-view-layout.d.mts +36 -0
- package/dist/client/views/pages/accept-invite-page.d.mts +2 -2
- package/dist/client/views/pages/dashboard-page.d.mts +2 -2
- package/dist/client/views/pages/forgot-password-page.d.mts +2 -2
- package/dist/client/views/pages/invite-page.d.mts +2 -2
- package/dist/client/views/pages/login-page.d.mts +2 -2
- package/dist/client/views/pages/reset-password-page.d.mts +2 -2
- package/dist/client/views/pages/setup-page.d.mts +2 -2
- package/dist/client.d.mts +17 -2
- package/dist/client.mjs +16 -1
- package/dist/components/rich-text/rich-text-renderer.d.mts +2 -2
- package/dist/factories.d.mts +2 -2
- package/dist/factories.mjs +2 -2
- package/dist/index.d.mts +17 -3
- package/dist/index.mjs +16 -1
- package/dist/server/augmentation/actions.d.mts +5 -0
- package/dist/server/augmentation/form-layout.d.mts +5 -0
- package/dist/server/augmentation/views.d.mts +4 -1
- package/dist/server/fields/blocks.mjs +4 -1
- package/dist/server/fields/reactive-runtime.mjs +3 -0
- package/dist/server/modules/admin/.generated/module.d.mts +1 -1
- package/dist/server/modules/admin/auth-helpers.mjs +7 -1
- package/dist/server/modules/admin/block/introspection.mjs +28 -4
- package/dist/server/modules/admin/block/prefetch.d.mts +11 -0
- package/dist/server/modules/admin/block/prefetch.mjs +108 -27
- package/dist/server/modules/admin/client/.generated/module.d.mts +68 -67
- package/dist/server/modules/admin/client/.generated/module.mjs +2 -0
- package/dist/server/modules/admin/client/views/collection-document.d.mts +6 -0
- package/dist/server/modules/admin/client/views/collection-document.mjs +10 -0
- package/dist/server/modules/admin/collections/account.d.mts +46 -46
- package/dist/server/modules/admin/collections/admin-locks.d.mts +57 -57
- package/dist/server/modules/admin/collections/admin-preferences.d.mts +42 -42
- package/dist/server/modules/admin/collections/admin-saved-views.d.mts +50 -50
- package/dist/server/modules/admin/collections/apikey.d.mts +79 -71
- package/dist/server/modules/admin/collections/assets.d.mts +42 -42
- package/dist/server/modules/admin/collections/session.d.mts +45 -45
- package/dist/server/modules/admin/collections/user.d.mts +66 -66
- package/dist/server/modules/admin/collections/verification.d.mts +39 -39
- package/dist/server/modules/admin/dto/admin-config.dto.mjs +34 -4
- package/dist/server/modules/admin/factories.mjs +4 -34
- package/dist/server/modules/admin/routes/admin-config.d.mts +3 -2
- package/dist/server/modules/admin/routes/admin-config.mjs +18 -2
- package/dist/server/modules/admin/routes/execute-action.d.mts +9 -9
- package/dist/server/modules/admin/routes/execute-action.mjs +10 -4
- package/dist/server/modules/admin/routes/locales.d.mts +2 -2
- package/dist/server/modules/admin/routes/locales.mjs +1 -1
- package/dist/server/modules/admin/routes/preview.d.mts +11 -11
- package/dist/server/modules/admin/routes/preview.mjs +6 -5
- package/dist/server/modules/admin/routes/reactive.d.mts +9 -9
- package/dist/server/modules/admin/routes/reactive.mjs +2 -2
- package/dist/server/modules/admin/routes/route-helpers.mjs +1 -1
- package/dist/server/modules/admin/routes/setup.d.mts +7 -7
- package/dist/server/modules/admin/routes/translations.d.mts +4 -4
- package/dist/server/modules/admin/routes/widget-data.d.mts +5 -5
- package/dist/server/modules/admin/routes/widget-data.mjs +1 -1
- package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +27 -27
- package/dist/server/plugin.mjs +8 -3
- package/dist/server/proxy-factories.d.mts +8 -1
- package/dist/server/proxy-factories.mjs +33 -1
- package/package.json +4 -4
|
@@ -1,7 +1,33 @@
|
|
|
1
1
|
import { useQuestpieQueryOptions } from "./use-questpie-query-options.mjs";
|
|
2
|
+
import { useEffect } from "react";
|
|
2
3
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
4
|
+
import { buildCollectionTopic } from "@questpie/tanstack-query";
|
|
3
5
|
|
|
4
6
|
//#region src/client/hooks/use-collection.ts
|
|
7
|
+
function useCollectionRealtimeInvalidation({ client, collection, options, realtime, queryClient }) {
|
|
8
|
+
const topicSignature = JSON.stringify(collection ? buildCollectionTopic(collection, options) : null);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (!collection || !realtime) return;
|
|
11
|
+
const realtimeApi = client?.realtime;
|
|
12
|
+
if (!realtimeApi?.subscribe) return;
|
|
13
|
+
const topic = JSON.parse(topicSignature);
|
|
14
|
+
if (!topic) return;
|
|
15
|
+
return realtimeApi.subscribe(topic, () => {
|
|
16
|
+
queryClient.invalidateQueries({ queryKey: [
|
|
17
|
+
"questpie",
|
|
18
|
+
"collections",
|
|
19
|
+
"collections",
|
|
20
|
+
collection
|
|
21
|
+
] });
|
|
22
|
+
});
|
|
23
|
+
}, [
|
|
24
|
+
client,
|
|
25
|
+
collection,
|
|
26
|
+
queryClient,
|
|
27
|
+
realtime,
|
|
28
|
+
topicSignature
|
|
29
|
+
]);
|
|
30
|
+
}
|
|
5
31
|
/**
|
|
6
32
|
* Hook to fetch collection list with filters, sorting, pagination
|
|
7
33
|
*
|
|
@@ -14,24 +40,32 @@ import { useMutation, useQuery } from "@tanstack/react-query";
|
|
|
14
40
|
* ```
|
|
15
41
|
*/
|
|
16
42
|
function useCollectionList(collection, options, queryOptions, realtimeOptions) {
|
|
17
|
-
const { queryOpts, locale } = useQuestpieQueryOptions();
|
|
43
|
+
const { queryOpts, queryClient, locale, client } = useQuestpieQueryOptions();
|
|
18
44
|
const findOptions = {
|
|
19
45
|
...options,
|
|
20
46
|
locale
|
|
21
47
|
};
|
|
48
|
+
const baseQuery = collection ? queryOpts.collections[collection].find(findOptions, { realtime: realtimeOptions?.realtime }) : {
|
|
49
|
+
queryKey: [
|
|
50
|
+
"questpie",
|
|
51
|
+
"collections",
|
|
52
|
+
"__none__",
|
|
53
|
+
"find"
|
|
54
|
+
],
|
|
55
|
+
queryFn: () => ({
|
|
56
|
+
docs: [],
|
|
57
|
+
totalDocs: 0
|
|
58
|
+
})
|
|
59
|
+
};
|
|
60
|
+
useCollectionRealtimeInvalidation({
|
|
61
|
+
client,
|
|
62
|
+
collection: collection ? String(collection) : void 0,
|
|
63
|
+
options: findOptions,
|
|
64
|
+
realtime: realtimeOptions?.realtime,
|
|
65
|
+
queryClient
|
|
66
|
+
});
|
|
22
67
|
return useQuery({
|
|
23
|
-
...
|
|
24
|
-
queryKey: [
|
|
25
|
-
"questpie",
|
|
26
|
-
"collections",
|
|
27
|
-
"__none__",
|
|
28
|
-
"find"
|
|
29
|
-
],
|
|
30
|
-
queryFn: () => ({
|
|
31
|
-
docs: [],
|
|
32
|
-
totalDocs: 0
|
|
33
|
-
})
|
|
34
|
-
},
|
|
68
|
+
...baseQuery,
|
|
35
69
|
enabled: !!collection && (queryOptions?.enabled ?? true),
|
|
36
70
|
...queryOptions
|
|
37
71
|
});
|
|
@@ -54,21 +88,29 @@ function useCollectionList(collection, options, queryOptions, realtimeOptions) {
|
|
|
54
88
|
* ```
|
|
55
89
|
*/
|
|
56
90
|
function useCollectionCount(collection, options, queryOptions, realtimeOptions) {
|
|
57
|
-
const { queryOpts, locale } = useQuestpieQueryOptions();
|
|
91
|
+
const { queryOpts, queryClient, locale, client } = useQuestpieQueryOptions();
|
|
58
92
|
const countOptions = {
|
|
59
93
|
...options,
|
|
60
94
|
locale
|
|
61
95
|
};
|
|
96
|
+
const baseQuery = collection ? queryOpts.collections[collection].count(countOptions, { realtime: realtimeOptions?.realtime }) : {
|
|
97
|
+
queryKey: [
|
|
98
|
+
"questpie",
|
|
99
|
+
"collections",
|
|
100
|
+
"__none__",
|
|
101
|
+
"count"
|
|
102
|
+
],
|
|
103
|
+
queryFn: () => 0
|
|
104
|
+
};
|
|
105
|
+
useCollectionRealtimeInvalidation({
|
|
106
|
+
client,
|
|
107
|
+
collection: collection ? String(collection) : void 0,
|
|
108
|
+
options: countOptions,
|
|
109
|
+
realtime: realtimeOptions?.realtime,
|
|
110
|
+
queryClient
|
|
111
|
+
});
|
|
62
112
|
return useQuery({
|
|
63
|
-
...
|
|
64
|
-
queryKey: [
|
|
65
|
-
"questpie",
|
|
66
|
-
"collections",
|
|
67
|
-
"__none__",
|
|
68
|
-
"count"
|
|
69
|
-
],
|
|
70
|
-
queryFn: () => 0
|
|
71
|
-
},
|
|
113
|
+
...baseQuery,
|
|
72
114
|
enabled: !!collection && (queryOptions?.enabled ?? true),
|
|
73
115
|
...queryOptions
|
|
74
116
|
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//#region src/client/hooks/use-upload.d.ts
|
|
2
|
+
interface Asset {
|
|
3
|
+
id: string;
|
|
4
|
+
key: string;
|
|
5
|
+
filename: string;
|
|
6
|
+
mimeType: string;
|
|
7
|
+
size: number;
|
|
8
|
+
visibility: "public" | "private";
|
|
9
|
+
url?: string;
|
|
10
|
+
width?: number | null;
|
|
11
|
+
height?: number | null;
|
|
12
|
+
alt?: string | null;
|
|
13
|
+
caption?: string | null;
|
|
14
|
+
createdAt?: string;
|
|
15
|
+
updatedAt?: string;
|
|
16
|
+
}
|
|
17
|
+
interface UploadOptions {
|
|
18
|
+
to?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Optional destination path/folder forwarded to the collection's upload so a
|
|
21
|
+
* blob upload lands inside a folder (e.g. an `assets` row's required `path`).
|
|
22
|
+
*/
|
|
23
|
+
path?: string;
|
|
24
|
+
onProgress?: (progress: number) => void;
|
|
25
|
+
signal?: AbortSignal;
|
|
26
|
+
}
|
|
27
|
+
interface UploadManyOptions extends UploadOptions {
|
|
28
|
+
onProgress?: (progress: number, fileIndex?: number) => void;
|
|
29
|
+
}
|
|
30
|
+
interface UseUploadReturn {
|
|
31
|
+
upload: (file: File, options?: UploadOptions) => Promise<Asset>;
|
|
32
|
+
uploadMany: (files: File[], options?: UploadManyOptions) => Promise<Asset[]>;
|
|
33
|
+
isUploading: boolean;
|
|
34
|
+
progress: number;
|
|
35
|
+
error: Error | null;
|
|
36
|
+
reset: () => void;
|
|
37
|
+
}
|
|
38
|
+
declare function useUpload(): UseUploadReturn;
|
|
39
|
+
//#endregion
|
|
40
|
+
export { Asset, useUpload };
|
|
@@ -29,7 +29,7 @@ function useUpload() {
|
|
|
29
29
|
}, [uploadCollections]);
|
|
30
30
|
const uploadMutation = useMutation({
|
|
31
31
|
mutationFn: async ({ file, options }) => {
|
|
32
|
-
const { to, onProgress, signal } = options ?? {};
|
|
32
|
+
const { to, path, onProgress, signal } = options ?? {};
|
|
33
33
|
const targetCollection = resolveTargetCollection(to);
|
|
34
34
|
if (!targetCollection) throw new Error(getMissingCollectionMessage());
|
|
35
35
|
const collectionApi = client.collections[targetCollection];
|
|
@@ -38,6 +38,7 @@ function useUpload() {
|
|
|
38
38
|
return {
|
|
39
39
|
asset: await collectionApi.upload(file, {
|
|
40
40
|
signal,
|
|
41
|
+
path,
|
|
41
42
|
onProgress: (p) => {
|
|
42
43
|
setProgress(p);
|
|
43
44
|
onProgress?.(p);
|
|
@@ -56,7 +57,7 @@ function useUpload() {
|
|
|
56
57
|
});
|
|
57
58
|
const uploadManyMutation = useMutation({
|
|
58
59
|
mutationFn: async ({ files, options }) => {
|
|
59
|
-
const { to, onProgress, signal } = options ?? {};
|
|
60
|
+
const { to, path, onProgress, signal } = options ?? {};
|
|
60
61
|
const targetCollection = resolveTargetCollection(to);
|
|
61
62
|
if (!targetCollection) throw new Error(getMissingCollectionMessage());
|
|
62
63
|
if (files.length === 0) return {
|
|
@@ -68,6 +69,7 @@ function useUpload() {
|
|
|
68
69
|
setProgress(0);
|
|
69
70
|
const results = await collectionApi.uploadMany(files, {
|
|
70
71
|
signal,
|
|
72
|
+
path,
|
|
71
73
|
onProgress: (p, fileIndex) => {
|
|
72
74
|
setProgress(p);
|
|
73
75
|
onProgress?.(p, fileIndex);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { I18nText } from "./types.mjs";
|
|
2
|
+
import "react";
|
|
3
|
+
import "date-fns";
|
|
4
|
+
|
|
5
|
+
//#region src/client/i18n/hooks.d.ts
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Resolve I18nText to string
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* function Label({ text }: { text: I18nText }) {
|
|
13
|
+
* const resolve = useResolveText();
|
|
14
|
+
* return <span>{resolve(text)}</span>;
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
declare function useResolveText(): (text: I18nText | ((values: Record<string, any>) => I18nText) | undefined, fallback?: string, contextValues?: Record<string, any>) => string;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { useResolveText };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime59 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/client/preview/block-scope-context.d.ts
|
|
5
5
|
|
|
@@ -35,7 +35,7 @@ declare function BlockScopeProvider({
|
|
|
35
35
|
blockId,
|
|
36
36
|
basePath,
|
|
37
37
|
children
|
|
38
|
-
}: BlockScopeProviderProps):
|
|
38
|
+
}: BlockScopeProviderProps): react_jsx_runtime59.JSX.Element;
|
|
39
39
|
/**
|
|
40
40
|
* Get current block scope context.
|
|
41
41
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime58 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/client/preview/preview-banner.d.ts
|
|
4
4
|
|
|
@@ -40,6 +40,6 @@ declare function PreviewBanner({
|
|
|
40
40
|
isPreviewMode,
|
|
41
41
|
className,
|
|
42
42
|
exitPreviewUrl
|
|
43
|
-
}: PreviewBannerProps):
|
|
43
|
+
}: PreviewBannerProps): react_jsx_runtime58.JSX.Element | null;
|
|
44
44
|
//#endregion
|
|
45
45
|
export { PreviewBanner, PreviewBannerProps };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime55 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/client/preview/preview-field.d.ts
|
|
5
5
|
|
|
@@ -68,7 +68,7 @@ declare function PreviewProvider({
|
|
|
68
68
|
}) => void;
|
|
69
69
|
onFieldValueEdited?: (payload: PreviewFieldValueEditedPayload) => void;
|
|
70
70
|
children: React.ReactNode;
|
|
71
|
-
}):
|
|
71
|
+
}): react_jsx_runtime55.JSX.Element;
|
|
72
72
|
/**
|
|
73
73
|
* Hook to access preview context.
|
|
74
74
|
*/
|
|
@@ -107,7 +107,7 @@ declare function PreviewField({
|
|
|
107
107
|
style,
|
|
108
108
|
onClick,
|
|
109
109
|
onValueCommit
|
|
110
|
-
}: PreviewFieldProps):
|
|
110
|
+
}: PreviewFieldProps): react_jsx_runtime55.JSX.Element;
|
|
111
111
|
/**
|
|
112
112
|
* Standalone PreviewField that works without context.
|
|
113
113
|
* Useful when you can't use PreviewProvider.
|
|
@@ -131,6 +131,6 @@ declare function StandalonePreviewField({
|
|
|
131
131
|
blockId?: string;
|
|
132
132
|
fieldType?: "regular" | "block" | "relation";
|
|
133
133
|
}) => void;
|
|
134
|
-
}):
|
|
134
|
+
}): react_jsx_runtime55.JSX.Element;
|
|
135
135
|
//#endregion
|
|
136
136
|
export { PreviewField, PreviewFieldProps, PreviewProvider, StandalonePreviewField, usePreviewContext };
|
|
@@ -19,6 +19,13 @@ const CONTENT_LOCALE_COOKIE = "questpie_content_locale";
|
|
|
19
19
|
/** Cookie max age (1 year) */
|
|
20
20
|
const LOCALE_COOKIE_MAX_AGE = 3600 * 24 * 365;
|
|
21
21
|
const LEGACY_LOCALE_COOKIE = "questpie_locale";
|
|
22
|
+
const PUBLIC_BRANDING_PATHS = [
|
|
23
|
+
"/login",
|
|
24
|
+
"/forgot-password",
|
|
25
|
+
"/reset-password",
|
|
26
|
+
"/accept-invite",
|
|
27
|
+
"/setup"
|
|
28
|
+
];
|
|
22
29
|
function setCookie(name, value) {
|
|
23
30
|
if (typeof document === "undefined") return;
|
|
24
31
|
document.cookie = `${name}=${value}; path=/; max-age=${LOCALE_COOKIE_MAX_AGE}; SameSite=Lax`;
|
|
@@ -201,13 +208,25 @@ function applyFavicon(href) {
|
|
|
201
208
|
}
|
|
202
209
|
link.href = href;
|
|
203
210
|
}
|
|
211
|
+
function isPublicBrandingPath(basePath) {
|
|
212
|
+
if (typeof window === "undefined") return false;
|
|
213
|
+
const currentPath = window.location.pathname.replace(/\/+$/, "");
|
|
214
|
+
const normalizedBase = basePath.replace(/\/+$/, "");
|
|
215
|
+
return PUBLIC_BRANDING_PATHS.some((path) => {
|
|
216
|
+
const fullPath = `${normalizedBase}${path}`.replace(/\/+$/, "");
|
|
217
|
+
return currentPath === fullPath || currentPath.startsWith(`${fullPath}/`);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
204
220
|
function BrandingSync() {
|
|
205
221
|
const store = useContext(AdminStoreContext);
|
|
206
222
|
useEffect(() => {
|
|
207
223
|
if (!store) return;
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
224
|
+
const state = store.getState();
|
|
225
|
+
const routes = state.client?.routes;
|
|
226
|
+
if (!routes) return;
|
|
227
|
+
const configRequest = isPublicBrandingPath(state.basePath) && typeof routes.getPublicAdminConfig === "function" ? routes.getPublicAdminConfig() : routes.getAdminConfig?.();
|
|
228
|
+
if (!configRequest) return;
|
|
229
|
+
configRequest.then((config) => {
|
|
211
230
|
const branding = config?.branding;
|
|
212
231
|
if (!branding) return;
|
|
213
232
|
const next = {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ScopePickerProps } from "./types.mjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime61 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/client/scope/picker.d.ts
|
|
5
5
|
|
|
@@ -48,6 +48,6 @@ declare function ScopePicker({
|
|
|
48
48
|
clearText,
|
|
49
49
|
className,
|
|
50
50
|
compact
|
|
51
|
-
}: ScopePickerProps):
|
|
51
|
+
}: ScopePickerProps): react_jsx_runtime61.JSX.Element;
|
|
52
52
|
//#endregion
|
|
53
53
|
export { ScopePicker };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ScopeContextValue, ScopeProviderProps } from "./types.mjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime60 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/client/scope/provider.d.ts
|
|
5
5
|
|
|
@@ -29,7 +29,7 @@ declare function ScopeProvider({
|
|
|
29
29
|
headerName,
|
|
30
30
|
storageKey,
|
|
31
31
|
defaultScope
|
|
32
|
-
}: ScopeProviderProps):
|
|
32
|
+
}: ScopeProviderProps): react_jsx_runtime60.JSX.Element;
|
|
33
33
|
/**
|
|
34
34
|
* Hook to access the current scope context.
|
|
35
35
|
*
|
|
@@ -596,29 +596,31 @@
|
|
|
596
596
|
padding: 0;
|
|
597
597
|
}
|
|
598
598
|
|
|
599
|
-
/* Slash command menu —
|
|
599
|
+
/* Slash command menu — compact command density */
|
|
600
600
|
.qp-rich-text-editor__slash {
|
|
601
601
|
display: flex;
|
|
602
602
|
flex-direction: column;
|
|
603
|
-
gap: 0.
|
|
604
|
-
min-width:
|
|
605
|
-
max-width: min(
|
|
606
|
-
|
|
603
|
+
gap: 0.125rem;
|
|
604
|
+
min-width: 280px;
|
|
605
|
+
max-width: min(340px, calc(100vw - 2rem));
|
|
606
|
+
max-height: min(19rem, calc(100vh - 4rem));
|
|
607
|
+
overflow-y: auto;
|
|
608
|
+
padding: 0.375rem;
|
|
607
609
|
}
|
|
608
610
|
|
|
609
611
|
.qp-rich-text-editor__slash-item {
|
|
610
612
|
display: flex;
|
|
611
613
|
width: 100%;
|
|
612
|
-
min-height:
|
|
614
|
+
min-height: 2.25rem;
|
|
613
615
|
align-items: center;
|
|
614
|
-
gap: 0.
|
|
616
|
+
gap: 0.5rem;
|
|
615
617
|
border: 1px solid transparent;
|
|
616
|
-
border-radius: var(--
|
|
618
|
+
border-radius: var(--radius-sm);
|
|
617
619
|
background: transparent;
|
|
618
|
-
padding: 0.
|
|
620
|
+
padding: 0.3125rem 0.5rem;
|
|
619
621
|
color: var(--foreground);
|
|
620
622
|
font-size: 0.8125rem;
|
|
621
|
-
line-height: 1.
|
|
623
|
+
line-height: 1.2;
|
|
622
624
|
text-align: left;
|
|
623
625
|
transition:
|
|
624
626
|
background-color 150ms ease,
|
|
@@ -635,8 +637,8 @@
|
|
|
635
637
|
|
|
636
638
|
.qp-rich-text-editor__slash-icon {
|
|
637
639
|
display: inline-flex;
|
|
638
|
-
width:
|
|
639
|
-
height:
|
|
640
|
+
width: 1.5rem;
|
|
641
|
+
height: 1.5rem;
|
|
640
642
|
flex: 0 0 auto;
|
|
641
643
|
align-items: center;
|
|
642
644
|
justify-content: center;
|
|
@@ -651,25 +653,27 @@
|
|
|
651
653
|
min-width: 0;
|
|
652
654
|
flex: 1;
|
|
653
655
|
flex-direction: column;
|
|
654
|
-
gap: 0.
|
|
656
|
+
gap: 0.0625rem;
|
|
655
657
|
}
|
|
656
658
|
|
|
657
659
|
.qp-rich-text-editor__slash-title {
|
|
658
660
|
font-family: var(--font-chrome);
|
|
659
|
-
font-weight:
|
|
661
|
+
font-weight: 500;
|
|
660
662
|
}
|
|
661
663
|
|
|
662
664
|
.qp-rich-text-editor__slash-description {
|
|
663
665
|
color: var(--muted-foreground);
|
|
666
|
+
font-size: 0.6875rem;
|
|
667
|
+
line-height: 1.25;
|
|
664
668
|
overflow: hidden;
|
|
665
669
|
text-overflow: ellipsis;
|
|
666
670
|
white-space: nowrap;
|
|
667
671
|
}
|
|
668
672
|
|
|
669
673
|
.qp-rich-text-editor__slash-group {
|
|
670
|
-
padding: 0.
|
|
674
|
+
padding: 0.3125rem 0.5rem 0.125rem;
|
|
671
675
|
font-family: var(--font-chrome);
|
|
672
|
-
font-size: 0.
|
|
676
|
+
font-size: 0.625rem;
|
|
673
677
|
font-weight: 600;
|
|
674
678
|
letter-spacing: 0.04em;
|
|
675
679
|
text-transform: uppercase;
|
|
@@ -677,7 +681,7 @@
|
|
|
677
681
|
}
|
|
678
682
|
|
|
679
683
|
.qp-rich-text-editor__slash-empty {
|
|
680
|
-
padding: 0.
|
|
684
|
+
padding: 0.625rem;
|
|
681
685
|
font-size: 0.8125rem;
|
|
682
686
|
color: var(--muted-foreground);
|
|
683
687
|
}
|
|
@@ -706,7 +710,7 @@
|
|
|
706
710
|
}
|
|
707
711
|
|
|
708
712
|
.qp-rich-text-editor__slash {
|
|
709
|
-
min-width: min(
|
|
713
|
+
min-width: min(280px, calc(100vw - 2rem));
|
|
710
714
|
}
|
|
711
715
|
}
|
|
712
716
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/client/utils/asset-url.ts
|
|
2
|
+
const STORAGE_FILE_PATH_PATTERN = /^\/api\/[^/]+\/files(?:\/|$)/;
|
|
3
|
+
function isStorageFilePath(pathname) {
|
|
4
|
+
return STORAGE_FILE_PATH_PATTERN.test(pathname);
|
|
5
|
+
}
|
|
6
|
+
function currentOrigin() {
|
|
7
|
+
if (typeof window === "undefined" || !window.location?.origin) return null;
|
|
8
|
+
return window.location.origin;
|
|
9
|
+
}
|
|
10
|
+
function resolveAssetUrl(url) {
|
|
11
|
+
if (typeof url !== "string") return void 0;
|
|
12
|
+
const trimmed = url.trim();
|
|
13
|
+
if (!trimmed) return void 0;
|
|
14
|
+
if (trimmed.startsWith("/")) return trimmed;
|
|
15
|
+
const origin = currentOrigin();
|
|
16
|
+
if (!origin) return trimmed;
|
|
17
|
+
try {
|
|
18
|
+
const parsed = new URL(trimmed);
|
|
19
|
+
if (isStorageFilePath(parsed.pathname) && parsed.origin === origin) return `${parsed.pathname}${parsed.search}${parsed.hash}`;
|
|
20
|
+
} catch {
|
|
21
|
+
return trimmed;
|
|
22
|
+
}
|
|
23
|
+
return trimmed;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
export { resolveAssetUrl };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime34 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/client/views/auth/accept-invite-form.d.ts
|
|
4
4
|
/**
|
|
@@ -67,6 +67,6 @@ declare function AcceptInviteForm({
|
|
|
67
67
|
className,
|
|
68
68
|
error,
|
|
69
69
|
minPasswordLength
|
|
70
|
-
}: AcceptInviteFormProps):
|
|
70
|
+
}: AcceptInviteFormProps): react_jsx_runtime34.JSX.Element;
|
|
71
71
|
//#endregion
|
|
72
72
|
export { AcceptInviteForm };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime35 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/client/views/auth/auth-layout.d.ts
|
|
5
5
|
|
|
@@ -26,7 +26,7 @@ declare function AuthDefaultLogo({
|
|
|
26
26
|
brandName
|
|
27
27
|
}: {
|
|
28
28
|
brandName: string;
|
|
29
|
-
}):
|
|
29
|
+
}): react_jsx_runtime35.JSX.Element;
|
|
30
30
|
/**
|
|
31
31
|
* Minimal split layout for authentication pages (login, register, forgot password, etc.)
|
|
32
32
|
*
|
|
@@ -50,6 +50,6 @@ declare function AuthDefaultLogo({
|
|
|
50
50
|
* </AuthLayout>
|
|
51
51
|
* ```
|
|
52
52
|
*/
|
|
53
|
-
declare function AuthLayout(props: AuthLayoutProps):
|
|
53
|
+
declare function AuthLayout(props: AuthLayoutProps): react_jsx_runtime35.JSX.Element;
|
|
54
54
|
//#endregion
|
|
55
55
|
export { AuthDefaultLogo, AuthLayout, AuthLayoutProps };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime37 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/client/views/auth/forgot-password-form.d.ts
|
|
4
4
|
/**
|
|
@@ -53,6 +53,6 @@ declare function ForgotPasswordForm({
|
|
|
53
53
|
defaultValues,
|
|
54
54
|
className,
|
|
55
55
|
error
|
|
56
|
-
}: ForgotPasswordFormProps):
|
|
56
|
+
}: ForgotPasswordFormProps): react_jsx_runtime37.JSX.Element;
|
|
57
57
|
//#endregion
|
|
58
58
|
export { ForgotPasswordForm };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime38 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/client/views/auth/login-form.d.ts
|
|
4
4
|
/**
|
|
@@ -70,6 +70,6 @@ declare function LoginForm({
|
|
|
70
70
|
className,
|
|
71
71
|
error,
|
|
72
72
|
minPasswordLength
|
|
73
|
-
}: LoginFormProps):
|
|
73
|
+
}: LoginFormProps): react_jsx_runtime38.JSX.Element;
|
|
74
74
|
//#endregion
|
|
75
75
|
export { LoginForm };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime39 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/client/views/auth/reset-password-form.d.ts
|
|
4
4
|
/**
|
|
@@ -60,6 +60,6 @@ declare function ResetPasswordForm({
|
|
|
60
60
|
minPasswordLength,
|
|
61
61
|
className,
|
|
62
62
|
error
|
|
63
|
-
}: ResetPasswordFormProps):
|
|
63
|
+
}: ResetPasswordFormProps): react_jsx_runtime39.JSX.Element;
|
|
64
64
|
//#endregion
|
|
65
65
|
export { ResetPasswordForm };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime40 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/client/views/auth/setup-form.d.ts
|
|
4
4
|
/**
|
|
@@ -55,6 +55,6 @@ declare function SetupForm({
|
|
|
55
55
|
className,
|
|
56
56
|
error,
|
|
57
57
|
minPasswordLength
|
|
58
|
-
}: SetupFormProps):
|
|
58
|
+
}: SetupFormProps): react_jsx_runtime40.JSX.Element;
|
|
59
59
|
//#endregion
|
|
60
60
|
export { SetupForm, SetupFormValues };
|
|
@@ -274,18 +274,18 @@ function SectionLayoutRenderer({ section, index, fields, collection, mode = "col
|
|
|
274
274
|
const value = `section-${index}`;
|
|
275
275
|
return /* @__PURE__ */ jsx(Accordion, {
|
|
276
276
|
defaultValue: section.defaultCollapsed !== true ? [value] : [],
|
|
277
|
-
className: "
|
|
277
|
+
className: "qa-form-fields__section qa-form-fields__section--collapsible panel-surface bg-card overflow-hidden",
|
|
278
278
|
children: /* @__PURE__ */ jsxs(AccordionItem, {
|
|
279
279
|
value,
|
|
280
|
-
className: "border-
|
|
280
|
+
className: "border-none px-0 data-open:bg-transparent",
|
|
281
281
|
children: [/* @__PURE__ */ jsx(AccordionTrigger, {
|
|
282
|
-
className: "hover:no-underline",
|
|
282
|
+
className: "hover:bg-surface-low aria-expanded:bg-surface-low min-h-12 px-4 py-3 hover:no-underline",
|
|
283
283
|
children: /* @__PURE__ */ jsx("span", {
|
|
284
284
|
className: "font-semibold",
|
|
285
285
|
children: resolveText(section.label, "Section", formValues)
|
|
286
286
|
})
|
|
287
287
|
}), /* @__PURE__ */ jsxs(AccordionContent, {
|
|
288
|
-
className: "pt-
|
|
288
|
+
className: "border-border-subtle border-t px-4 pt-3 pb-4",
|
|
289
289
|
children: [section.description && /* @__PURE__ */ jsx("p", {
|
|
290
290
|
className: "text-muted-foreground mb-4 text-sm text-pretty",
|
|
291
291
|
children: resolveText(section.description, "", formValues)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { cn } from "../../../../lib/utils.mjs";
|
|
2
2
|
import { Button } from "../../../../components/ui/button.mjs";
|
|
3
|
+
import { resolveAssetUrl } from "../../../../utils/asset-url.mjs";
|
|
3
4
|
import { Icon } from "@iconify/react";
|
|
4
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
6
|
|
|
@@ -51,7 +52,7 @@ function AssetThumbnail({ asset, size = "sm", showFilename = false, showControls
|
|
|
51
52
|
})
|
|
52
53
|
});
|
|
53
54
|
const assetObj = asset;
|
|
54
|
-
const url = assetObj.url;
|
|
55
|
+
const url = resolveAssetUrl(assetObj.url);
|
|
55
56
|
const filename = assetObj.filename;
|
|
56
57
|
const mimeType = assetObj.mimeType;
|
|
57
58
|
const alt = assetObj.alt;
|
|
@@ -223,4 +224,4 @@ function AssetThumbnail({ asset, size = "sm", showFilename = false, showControls
|
|
|
223
224
|
}
|
|
224
225
|
|
|
225
226
|
//#endregion
|
|
226
|
-
export { AssetThumbnail };
|
|
227
|
+
export { AssetThumbnail, getFileIcon };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { formatLabel } from "../../../../lib/utils.mjs";
|
|
2
|
+
import { resolveAssetUrl } from "../../../../utils/asset-url.mjs";
|
|
2
3
|
|
|
3
4
|
//#region src/client/views/collection/cells/shared/cell-helpers.ts
|
|
4
5
|
function getNestedValue(item, path) {
|
|
@@ -15,9 +16,9 @@ function toImageUrl(value) {
|
|
|
15
16
|
if (!value || typeof value !== "object") return null;
|
|
16
17
|
const obj = value;
|
|
17
18
|
const url = obj.url;
|
|
18
|
-
if (typeof url === "string" && url.length > 0) return url;
|
|
19
|
+
if (typeof url === "string" && url.length > 0) return resolveAssetUrl(url) ?? null;
|
|
19
20
|
const src = obj.src;
|
|
20
|
-
if (typeof src === "string" && src.length > 0) return src;
|
|
21
|
+
if (typeof src === "string" && src.length > 0) return resolveAssetUrl(src) ?? null;
|
|
21
22
|
return null;
|
|
22
23
|
}
|
|
23
24
|
/**
|