@questpie/admin 3.2.0 → 3.2.2

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 (86) hide show
  1. package/dist/client/blocks/block-renderer.d.mts +12 -2
  2. package/dist/client/blocks/block-renderer.mjs +357 -49
  3. package/dist/client/components/blocks/block-editor-context.mjs +11 -1
  4. package/dist/client/components/blocks/block-editor-provider.mjs +68 -26
  5. package/dist/client/components/blocks/block-item.mjs +181 -170
  6. package/dist/client/components/blocks/utils/tree-utils.mjs +13 -1
  7. package/dist/client/components/fields/array-field.mjs +177 -118
  8. package/dist/client/components/filter-builder/filter-builder-sheet.mjs +305 -310
  9. package/dist/client/components/filter-builder/filters-tab.mjs +1 -1
  10. package/dist/client/components/history-sidebar.mjs +121 -114
  11. package/dist/client/components/preview/live-preview-mode.mjs +210 -175
  12. package/dist/client/components/preview/preview-pane.mjs +288 -333
  13. package/dist/client/components/primitives/option-label.mjs +44 -0
  14. package/dist/client/components/primitives/select-multi.mjs +408 -383
  15. package/dist/client/components/primitives/select-single.mjs +387 -357
  16. package/dist/client/components/widgets/chart-widget.mjs +168 -143
  17. package/dist/client/contexts/focus-context.d.mts +16 -1
  18. package/dist/client/contexts/focus-context.mjs +90 -38
  19. package/dist/client/hooks/use-brand.mjs +2 -1
  20. package/dist/client/preview/block-scope-context.d.mts +2 -2
  21. package/dist/client/preview/block-scope-context.mjs +10 -20
  22. package/dist/client/preview/index.d.mts +1 -1
  23. package/dist/client/preview/patch.mjs +100 -0
  24. package/dist/client/preview/preview-banner.d.mts +2 -2
  25. package/dist/client/preview/preview-field.d.mts +34 -5
  26. package/dist/client/preview/preview-field.mjs +385 -118
  27. package/dist/client/preview/types.d.mts +82 -3
  28. package/dist/client/preview/types.mjs +85 -6
  29. package/dist/client/preview/use-collection-preview.d.mts +19 -1
  30. package/dist/client/preview/use-collection-preview.mjs +182 -58
  31. package/dist/client/runtime/index.d.mts +2 -2
  32. package/dist/client/runtime/index.mjs +2 -2
  33. package/dist/client/runtime/provider.d.mts +5 -5
  34. package/dist/client/utils/build-field-definitions-from-schema.mjs +8 -3
  35. package/dist/client/views/auth/accept-invite-form.d.mts +2 -2
  36. package/dist/client/views/auth/auth-layout.d.mts +3 -3
  37. package/dist/client/views/auth/login-form.d.mts +2 -2
  38. package/dist/client/views/auth/reset-password-form.d.mts +2 -2
  39. package/dist/client/views/auth/setup-form.d.mts +2 -2
  40. package/dist/client/views/collection/bulk-action-toolbar.mjs +23 -25
  41. package/dist/client/views/collection/cells/primitive-cells.mjs +63 -13
  42. package/dist/client/views/collection/columns/build-columns.mjs +1 -0
  43. package/dist/client/views/collection/form-view.mjs +262 -33
  44. package/dist/client/views/collection/table-view.mjs +16 -11
  45. package/dist/client/views/layout/admin-layout-provider.d.mts +5 -5
  46. package/dist/client/views/layout/admin-layout-provider.mjs +107 -16
  47. package/dist/client/views/pages/accept-invite-page.d.mts +2 -2
  48. package/dist/client/views/pages/dashboard-page.d.mts +2 -2
  49. package/dist/client/views/pages/forgot-password-page.d.mts +2 -2
  50. package/dist/client/views/pages/reset-password-page.d.mts +2 -2
  51. package/dist/client/views/pages/setup-page.d.mts +2 -2
  52. package/dist/client.d.mts +2 -2
  53. package/dist/client.mjs +1 -1
  54. package/dist/index.d.mts +2 -2
  55. package/dist/index.mjs +1 -1
  56. package/dist/server/augmentation/common.d.mts +8 -4
  57. package/dist/server/augmentation/form-layout.d.mts +1 -1
  58. package/dist/server/i18n/messages/cs.mjs +11 -0
  59. package/dist/server/i18n/messages/de.mjs +11 -0
  60. package/dist/server/i18n/messages/en.mjs +11 -0
  61. package/dist/server/i18n/messages/es.mjs +11 -0
  62. package/dist/server/i18n/messages/fr.mjs +11 -0
  63. package/dist/server/i18n/messages/pl.mjs +11 -0
  64. package/dist/server/i18n/messages/pt.mjs +11 -0
  65. package/dist/server/i18n/messages/sk.mjs +11 -0
  66. package/dist/server/modules/admin/block/block-builder.d.mts +7 -10
  67. package/dist/server/modules/admin/block/block-builder.mjs +7 -10
  68. package/dist/server/modules/admin/collections/apikey.d.mts +64 -64
  69. package/dist/server/modules/admin/collections/assets.d.mts +57 -20
  70. package/dist/server/modules/admin/collections/session.d.mts +38 -38
  71. package/dist/server/modules/admin/collections/user.d.mts +100 -34
  72. package/dist/server/modules/admin/collections/user.mjs +4 -4
  73. package/dist/server/modules/admin/collections/verification.d.mts +31 -31
  74. package/dist/server/modules/admin/index.d.mts +3 -3
  75. package/dist/server/modules/admin/routes/admin-config.d.mts +2 -2
  76. package/dist/server/modules/admin/routes/admin-config.mjs +9 -12
  77. package/dist/server/modules/admin/routes/execute-action.d.mts +9 -9
  78. package/dist/server/modules/admin/routes/locales.d.mts +2 -2
  79. package/dist/server/modules/admin/routes/preview.d.mts +11 -11
  80. package/dist/server/modules/admin/routes/reactive.d.mts +9 -9
  81. package/dist/server/modules/admin/routes/translations.d.mts +4 -4
  82. package/dist/server/modules/admin/routes/translations.mjs +1 -1
  83. package/dist/server/modules/admin-preferences/collections/admin-preferences.mjs +4 -6
  84. package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +4 -6
  85. package/dist/server/modules/admin-preferences/collections/saved-views.mjs +4 -6
  86. package/package.json +3 -3
@@ -4,7 +4,6 @@ import { useTranslation } from "../../i18n/hooks.mjs";
4
4
  import { cn } from "../../lib/utils.mjs";
5
5
  import { selectClient, useAdminStore } from "../../runtime/provider.mjs";
6
6
  import { isPreviewToAdminMessage } from "../../preview/types.mjs";
7
- import { c } from "react/compiler-runtime";
8
7
  import { Icon } from "@iconify/react";
9
8
  import * as React from "react";
10
9
  import { useQuery } from "@tanstack/react-query";
@@ -24,9 +23,7 @@ const DEV_TELEMETRY = process.env.NODE_ENV === "development";
24
23
  * Renders an iframe with the preview page and handles
25
24
  * bidirectional communication via postMessage.
26
25
  */
27
- const PreviewPane = React.forwardRef((t0, ref) => {
28
- const $ = c(59);
29
- const { url, selectedBlockId, onFieldClick, onBlockClick, className, allowedOrigins } = t0;
26
+ const PreviewPane = React.forwardRef(({ url, selectedBlockId, onFieldClick, onBlockClick, onBlockInsertRequest, onFieldValueEdited, onPatchApplied, onResyncRequest, className, allowedOrigins }, ref) => {
30
27
  const { t } = useTranslation();
31
28
  const client = useAdminStore(selectClient);
32
29
  const iframeRef = React.useRef(null);
@@ -36,351 +33,309 @@ const PreviewPane = React.forwardRef((t0, ref) => {
36
33
  const [isRefreshing, setIsRefreshing] = React.useState(false);
37
34
  const isRefreshingRef = React.useRef(false);
38
35
  const pendingRefreshRef = React.useRef(false);
39
- let t1;
40
- if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
41
- t1 = {
42
- startedAt: 0,
43
- requested: 0,
44
- queued: 0,
45
- completed: 0,
46
- lastLogAt: 0
47
- };
48
- $[0] = t1;
49
- } else t1 = $[0];
50
- const refreshMetricsRef = React.useRef(t1);
51
- let t2;
52
- if ($[1] !== url) {
53
- t2 = [
36
+ const seqRef = React.useRef(0);
37
+ const pendingMessagesRef = React.useRef([]);
38
+ const refreshMetricsRef = React.useRef({
39
+ startedAt: 0,
40
+ requested: 0,
41
+ queued: 0,
42
+ completed: 0,
43
+ lastLogAt: 0
44
+ });
45
+ const { data: previewUrl, error: tokenQueryError, isLoading: isTokenLoading } = useQuery({
46
+ queryKey: [
54
47
  "questpie",
55
48
  "preview-token",
56
49
  url
57
- ];
58
- $[1] = url;
59
- $[2] = t2;
60
- } else t2 = $[2];
61
- let t3;
62
- if ($[3] !== client || $[4] !== url) {
63
- t3 = async () => {
50
+ ],
51
+ queryFn: async () => {
64
52
  return `/api/preview?token=${(await client.routes.mintPreviewToken({
65
53
  path: url,
66
- ttlMs: 36e5
54
+ ttlMs: 3600 * 1e3
67
55
  })).token}`;
68
- };
69
- $[3] = client;
70
- $[4] = url;
71
- $[5] = t3;
72
- } else t3 = $[5];
73
- const t4 = !!url && !!client;
74
- let t5;
75
- if ($[6] !== t2 || $[7] !== t3 || $[8] !== t4) {
76
- t5 = {
77
- queryKey: t2,
78
- queryFn: t3,
79
- enabled: t4,
80
- staleTime: 3e6,
81
- retry: false
82
- };
83
- $[6] = t2;
84
- $[7] = t3;
85
- $[8] = t4;
86
- $[9] = t5;
87
- } else t5 = $[9];
88
- const { data: previewUrl, error: tokenQueryError, isLoading: isTokenLoading } = useQuery(t5);
56
+ },
57
+ enabled: !!url && !!client,
58
+ staleTime: 3e3 * 1e3,
59
+ retry: false
60
+ });
89
61
  const previewUrlResolved = previewUrl ?? null;
90
- let t6;
91
- if ($[10] !== t || $[11] !== tokenQueryError) {
92
- t6 = tokenQueryError instanceof Error ? tokenQueryError.message : tokenQueryError ? t("error.failedToGeneratePreviewToken") : null;
93
- $[10] = t;
94
- $[11] = tokenQueryError;
95
- $[12] = t6;
96
- } else t6 = $[12];
97
- const tokenError = t6;
62
+ const tokenError = tokenQueryError instanceof Error ? tokenQueryError.message : tokenQueryError ? t("error.failedToGeneratePreviewToken") : null;
98
63
  const isLoading = isTokenLoading || iframeLoading;
99
- let t7;
100
- if ($[13] !== allowedOrigins || $[14] !== url) {
101
- t7 = (origin) => {
102
- if (!allowedOrigins || allowedOrigins.length === 0) {
103
- if (origin === window.location.origin) return true;
104
- try {
105
- return origin === new URL(url).origin;
106
- } catch {
107
- return false;
108
- }
64
+ const resolveUrlOrigin = React.useCallback((candidate) => {
65
+ if (!candidate) return null;
66
+ try {
67
+ const base = typeof window === "undefined" ? "http://localhost" : window.location.href;
68
+ return new URL(candidate, base).origin;
69
+ } catch {
70
+ return null;
71
+ }
72
+ }, []);
73
+ const targetOrigin = React.useMemo(() => {
74
+ const resolvedPreviewOrigin = resolveUrlOrigin(previewUrlResolved);
75
+ if (resolvedPreviewOrigin) return resolvedPreviewOrigin;
76
+ const configuredPreviewOrigin = resolveUrlOrigin(url);
77
+ if (configuredPreviewOrigin) return configuredPreviewOrigin;
78
+ if (allowedOrigins?.length === 1) return allowedOrigins[0];
79
+ return typeof window === "undefined" ? "*" : window.location.origin;
80
+ }, [
81
+ allowedOrigins,
82
+ previewUrlResolved,
83
+ resolveUrlOrigin,
84
+ url
85
+ ]);
86
+ const expectedOrigins = React.useMemo(() => {
87
+ const origins = /* @__PURE__ */ new Set();
88
+ if (typeof window !== "undefined") origins.add(window.location.origin);
89
+ const resolvedPreviewOrigin_0 = resolveUrlOrigin(previewUrlResolved);
90
+ if (resolvedPreviewOrigin_0) origins.add(resolvedPreviewOrigin_0);
91
+ const configuredPreviewOrigin_0 = resolveUrlOrigin(url);
92
+ if (configuredPreviewOrigin_0) origins.add(configuredPreviewOrigin_0);
93
+ for (const origin of allowedOrigins ?? []) origins.add(origin);
94
+ return origins;
95
+ }, [
96
+ allowedOrigins,
97
+ previewUrlResolved,
98
+ resolveUrlOrigin,
99
+ url
100
+ ]);
101
+ const isValidOrigin = React.useCallback((origin_0) => {
102
+ return expectedOrigins.has(origin_0);
103
+ }, [expectedOrigins]);
104
+ const getNextSeq = React.useCallback(() => {
105
+ seqRef.current += 1;
106
+ return seqRef.current;
107
+ }, []);
108
+ const sendToPreview = React.useCallback((message, queueUntilReady = false) => {
109
+ const iframe = iframeRef.current;
110
+ if (!iframe?.contentWindow) {
111
+ if (queueUntilReady) pendingMessagesRef.current.push(message);
112
+ return;
113
+ }
114
+ if (queueUntilReady && !isReadyRef.current) {
115
+ pendingMessagesRef.current.push(message);
116
+ return;
117
+ }
118
+ iframe.contentWindow.postMessage(message, targetOrigin);
119
+ }, [targetOrigin]);
120
+ const flushPendingMessages = React.useCallback(() => {
121
+ const pending = pendingMessagesRef.current;
122
+ if (pending.length === 0) return;
123
+ pendingMessagesRef.current = [];
124
+ for (const message_0 of pending) sendToPreview(message_0);
125
+ }, [sendToPreview]);
126
+ const requestRefresh = React.useCallback(() => {
127
+ if (!isReady) return;
128
+ const metrics = refreshMetricsRef.current;
129
+ const now = performance.now();
130
+ if (!metrics.startedAt) metrics.startedAt = now;
131
+ metrics.requested += 1;
132
+ if (isRefreshingRef.current) {
133
+ pendingRefreshRef.current = true;
134
+ metrics.queued += 1;
135
+ if (DEV_TELEMETRY && now - metrics.lastLogAt >= 5e3) {
136
+ metrics.lastLogAt = now;
137
+ const elapsedSec = Math.max(1, (now - metrics.startedAt) / 1e3);
138
+ const refreshPerMinute = metrics.completed * 60 / elapsedSec;
139
+ console.debug(`[LivePreviewTelemetry] refresh requested=${metrics.requested} completed=${metrics.completed} queued=${metrics.queued} rpm=${refreshPerMinute.toFixed(1)}`);
109
140
  }
110
- return allowedOrigins.includes(origin);
111
- };
112
- $[13] = allowedOrigins;
113
- $[14] = url;
114
- $[15] = t7;
115
- } else t7 = $[15];
116
- const isValidOrigin = t7;
117
- let t8;
118
- if ($[16] !== url) {
119
- t8 = (message) => {
120
- const iframe = iframeRef.current;
121
- if (!iframe?.contentWindow) return;
122
- try {
123
- const targetOrigin = new URL(url).origin;
124
- iframe.contentWindow.postMessage(message, targetOrigin);
125
- } catch {
126
- iframe.contentWindow.postMessage(message, "*");
127
- }
128
- };
129
- $[16] = url;
130
- $[17] = t8;
131
- } else t8 = $[17];
132
- const sendToPreview = t8;
133
- let t9;
134
- if ($[18] !== isReady || $[19] !== sendToPreview) {
135
- t9 = () => {
136
- if (!isReady) return;
137
- const metrics = refreshMetricsRef.current;
138
- const now = performance.now();
139
- if (!metrics.startedAt) metrics.startedAt = now;
140
- metrics.requested = metrics.requested + 1;
141
- if (isRefreshingRef.current) {
142
- pendingRefreshRef.current = true;
143
- metrics.queued = metrics.queued + 1;
144
- if (DEV_TELEMETRY && now - metrics.lastLogAt >= 5e3) {
145
- metrics.lastLogAt = now;
146
- const elapsedSec = Math.max(1, (now - metrics.startedAt) / 1e3);
147
- const refreshPerMinute = metrics.completed * 60 / elapsedSec;
148
- console.debug(`[LivePreviewTelemetry] refresh requested=${metrics.requested} completed=${metrics.completed} queued=${metrics.queued} rpm=${refreshPerMinute.toFixed(1)}`);
149
- }
150
- return;
151
- }
152
- isRefreshingRef.current = true;
153
- setIsRefreshing(true);
154
- sendToPreview({ type: "PREVIEW_REFRESH" });
155
- };
156
- $[18] = isReady;
157
- $[19] = sendToPreview;
158
- $[20] = t9;
159
- } else t9 = $[20];
160
- const requestRefresh = t9;
161
- let t10;
162
- let t11;
163
- if ($[21] !== isReady || $[22] !== requestRefresh || $[23] !== sendToPreview) {
164
- t10 = () => ({
165
- triggerRefresh: () => {
166
- requestRefresh();
167
- },
168
- sendFocusToPreview: (fieldPath) => {
169
- if (isReady) sendToPreview({
170
- type: "FOCUS_FIELD",
171
- fieldPath
172
- });
173
- }
174
- });
175
- t11 = [
176
- isReady,
177
- requestRefresh,
178
- sendToPreview
179
- ];
180
- $[21] = isReady;
181
- $[22] = requestRefresh;
182
- $[23] = sendToPreview;
183
- $[24] = t10;
184
- $[25] = t11;
185
- } else {
186
- t10 = $[24];
187
- t11 = $[25];
188
- }
189
- React.useImperativeHandle(ref, t10, t11);
190
- let t12;
191
- let t13;
192
- if ($[26] !== isValidOrigin || $[27] !== onBlockClick || $[28] !== onFieldClick || $[29] !== sendToPreview) {
193
- t12 = () => {
194
- const handleMessage = (event) => {
195
- if (!isValidOrigin(event.origin)) return;
196
- if (!isPreviewToAdminMessage(event.data)) return;
197
- bb98: switch (event.data.type) {
198
- case "PREVIEW_READY":
199
- isReadyRef.current = true;
200
- isRefreshingRef.current = false;
141
+ return;
142
+ }
143
+ isRefreshingRef.current = true;
144
+ setIsRefreshing(true);
145
+ sendToPreview({ type: "PREVIEW_REFRESH" });
146
+ }, [isReady, sendToPreview]);
147
+ React.useImperativeHandle(ref, () => ({
148
+ triggerRefresh: () => {
149
+ requestRefresh();
150
+ },
151
+ sendFocusToPreview: (fieldPath) => {
152
+ if (isReady) sendToPreview({
153
+ type: "FOCUS_FIELD",
154
+ fieldPath
155
+ });
156
+ },
157
+ sendInitSnapshot: (data) => {
158
+ const seq = getNextSeq();
159
+ sendToPreview({
160
+ type: "INIT_SNAPSHOT",
161
+ seq,
162
+ data
163
+ }, true);
164
+ return seq;
165
+ },
166
+ sendPatchBatch: (ops, snapshotVersion) => {
167
+ const seq_0 = getNextSeq();
168
+ sendToPreview({
169
+ type: "PATCH_BATCH",
170
+ seq: seq_0,
171
+ ops,
172
+ snapshotVersion
173
+ }, true);
174
+ return seq_0;
175
+ },
176
+ sendCommit: (data_0) => {
177
+ const seq_1 = getNextSeq();
178
+ sendToPreview({
179
+ type: "COMMIT",
180
+ seq: seq_1,
181
+ data: data_0
182
+ }, true);
183
+ return seq_1;
184
+ },
185
+ sendFullResync: (reason) => {
186
+ sendToPreview({
187
+ type: "FULL_RESYNC",
188
+ reason
189
+ }, true);
190
+ }
191
+ }), [
192
+ getNextSeq,
193
+ isReady,
194
+ requestRefresh,
195
+ sendToPreview
196
+ ]);
197
+ React.useEffect(() => {
198
+ const handleMessage = (event) => {
199
+ if (!isValidOrigin(event.origin)) return;
200
+ if (event.source !== iframeRef.current?.contentWindow) return;
201
+ if (!isPreviewToAdminMessage(event.data)) return;
202
+ switch (event.data.type) {
203
+ case "PREVIEW_READY":
204
+ isReadyRef.current = true;
205
+ isRefreshingRef.current = false;
206
+ pendingRefreshRef.current = false;
207
+ refreshMetricsRef.current = {
208
+ startedAt: 0,
209
+ requested: 0,
210
+ queued: 0,
211
+ completed: 0,
212
+ lastLogAt: 0
213
+ };
214
+ setIsReady(true);
215
+ setIframeLoading(false);
216
+ setIsRefreshing(false);
217
+ flushPendingMessages();
218
+ break;
219
+ case "REFRESH_COMPLETE":
220
+ if (refreshMetricsRef.current.startedAt) refreshMetricsRef.current.completed += 1;
221
+ if (pendingRefreshRef.current) {
201
222
  pendingRefreshRef.current = false;
202
- refreshMetricsRef.current = {
203
- startedAt: 0,
204
- requested: 0,
205
- queued: 0,
206
- completed: 0,
207
- lastLogAt: 0
208
- };
209
- setIsReady(true);
210
- setIframeLoading(false);
223
+ sendToPreview({ type: "PREVIEW_REFRESH" });
224
+ } else {
225
+ isRefreshingRef.current = false;
211
226
  setIsRefreshing(false);
212
- break bb98;
213
- case "REFRESH_COMPLETE":
214
- if (refreshMetricsRef.current.startedAt) refreshMetricsRef.current.completed = refreshMetricsRef.current.completed + 1;
215
- if (pendingRefreshRef.current) {
216
- pendingRefreshRef.current = false;
217
- sendToPreview({ type: "PREVIEW_REFRESH" });
218
- } else {
219
- isRefreshingRef.current = false;
220
- setIsRefreshing(false);
221
- if (DEV_TELEMETRY) {
222
- const metrics_0 = refreshMetricsRef.current;
223
- const now_0 = performance.now();
224
- if (now_0 - metrics_0.lastLogAt >= 5e3 && metrics_0.startedAt) {
225
- metrics_0.lastLogAt = now_0;
226
- const elapsedSec_0 = Math.max(1, (now_0 - metrics_0.startedAt) / 1e3);
227
- const refreshPerMinute_0 = metrics_0.completed * 60 / elapsedSec_0;
228
- console.debug(`[LivePreviewTelemetry] refresh requested=${metrics_0.requested} completed=${metrics_0.completed} queued=${metrics_0.queued} rpm=${refreshPerMinute_0.toFixed(1)}`);
229
- }
227
+ if (DEV_TELEMETRY) {
228
+ const metrics_0 = refreshMetricsRef.current;
229
+ const now_0 = performance.now();
230
+ if (now_0 - metrics_0.lastLogAt >= 5e3 && metrics_0.startedAt) {
231
+ metrics_0.lastLogAt = now_0;
232
+ const elapsedSec_0 = Math.max(1, (now_0 - metrics_0.startedAt) / 1e3);
233
+ const refreshPerMinute_0 = metrics_0.completed * 60 / elapsedSec_0;
234
+ console.debug(`[LivePreviewTelemetry] refresh requested=${metrics_0.requested} completed=${metrics_0.completed} queued=${metrics_0.queued} rpm=${refreshPerMinute_0.toFixed(1)}`);
230
235
  }
231
236
  }
232
- break bb98;
233
- case "FIELD_CLICKED":
234
- onFieldClick?.(event.data.fieldPath, {
235
- blockId: event.data.blockId,
236
- fieldType: event.data.fieldType
237
- });
238
- break bb98;
239
- case "BLOCK_CLICKED": onBlockClick?.(event.data.blockId);
240
- }
241
- };
242
- window.addEventListener("message", handleMessage);
243
- return () => window.removeEventListener("message", handleMessage);
244
- };
245
- t13 = [
246
- isValidOrigin,
247
- onFieldClick,
248
- onBlockClick,
249
- sendToPreview
250
- ];
251
- $[26] = isValidOrigin;
252
- $[27] = onBlockClick;
253
- $[28] = onFieldClick;
254
- $[29] = sendToPreview;
255
- $[30] = t12;
256
- $[31] = t13;
257
- } else {
258
- t12 = $[30];
259
- t13 = $[31];
260
- }
261
- React.useEffect(t12, t13);
262
- let t14;
263
- let t15;
264
- if ($[32] !== isReady || $[33] !== selectedBlockId || $[34] !== sendToPreview) {
265
- t14 = () => {
266
- if (isReady && selectedBlockId) sendToPreview({
267
- type: "SELECT_BLOCK",
268
- blockId: selectedBlockId
269
- });
270
- };
271
- t15 = [
272
- isReady,
273
- selectedBlockId,
274
- sendToPreview
275
- ];
276
- $[32] = isReady;
277
- $[33] = selectedBlockId;
278
- $[34] = sendToPreview;
279
- $[35] = t14;
280
- $[36] = t15;
281
- } else {
282
- t14 = $[35];
283
- t15 = $[36];
284
- }
285
- React.useEffect(t14, t15);
286
- let t16;
287
- if ($[37] === Symbol.for("react.memo_cache_sentinel")) {
288
- t16 = () => {
289
- setTimeout(() => {
290
- if (!isReadyRef.current) setIframeLoading(false);
291
- }, 3e3);
237
+ }
238
+ break;
239
+ case "FIELD_CLICKED":
240
+ onFieldClick?.(event.data.fieldPath, {
241
+ blockId: event.data.blockId,
242
+ fieldType: event.data.fieldType
243
+ });
244
+ break;
245
+ case "BLOCK_CLICKED":
246
+ onBlockClick?.(event.data.blockId);
247
+ break;
248
+ case "BLOCK_INSERT_REQUESTED":
249
+ onBlockInsertRequest?.(event.data);
250
+ break;
251
+ case "PATCH_APPLIED":
252
+ onPatchApplied?.(event.data.seq);
253
+ break;
254
+ case "RESYNC_REQUEST":
255
+ onResyncRequest?.(event.data.reason);
256
+ sendToPreview({
257
+ type: "FULL_RESYNC",
258
+ reason: event.data.reason
259
+ }, true);
260
+ requestRefresh();
261
+ break;
262
+ case "FIELD_VALUE_EDITED":
263
+ onFieldValueEdited?.(event.data);
264
+ break;
265
+ }
292
266
  };
293
- $[37] = t16;
294
- } else t16 = $[37];
295
- const handleLoad = t16;
296
- let t17;
297
- if ($[38] !== className) {
298
- t17 = cn("relative h-full w-full", className);
299
- $[38] = className;
300
- $[39] = t17;
301
- } else t17 = $[39];
302
- let t18;
303
- if ($[40] !== isLoading || $[41] !== t) {
304
- t18 = isLoading && /* @__PURE__ */ jsxs("div", {
305
- className: "bg-muted absolute inset-0 z-10 flex items-center justify-center",
306
- children: [/* @__PURE__ */ jsx(Icon, {
307
- icon: "ph:spinner",
308
- className: "text-muted-foreground h-6 w-6 animate-spin"
309
- }), /* @__PURE__ */ jsx("span", {
310
- className: "text-muted-foreground ml-2 text-sm",
311
- children: t("preview.loadingPreview")
312
- })]
267
+ window.addEventListener("message", handleMessage);
268
+ return () => window.removeEventListener("message", handleMessage);
269
+ }, [
270
+ flushPendingMessages,
271
+ isValidOrigin,
272
+ onFieldClick,
273
+ onBlockClick,
274
+ onBlockInsertRequest,
275
+ onFieldValueEdited,
276
+ onPatchApplied,
277
+ onResyncRequest,
278
+ requestRefresh,
279
+ sendToPreview
280
+ ]);
281
+ React.useEffect(() => {
282
+ if (isReady && selectedBlockId) sendToPreview({
283
+ type: "SELECT_BLOCK",
284
+ blockId: selectedBlockId
313
285
  });
314
- $[40] = isLoading;
315
- $[41] = t;
316
- $[42] = t18;
317
- } else t18 = $[42];
318
- let t19;
319
- if ($[43] !== t || $[44] !== tokenError) {
320
- t19 = tokenError && /* @__PURE__ */ jsx("div", {
321
- className: "bg-muted absolute inset-0 z-10 flex items-center justify-center",
322
- children: /* @__PURE__ */ jsxs("div", {
323
- className: "bg-destructive/10 border-destructive text-destructive border px-4 py-3 text-sm",
324
- children: [/* @__PURE__ */ jsx("p", {
325
- className: "font-medium",
326
- children: t("preview.previewError")
327
- }), /* @__PURE__ */ jsx("p", { children: tokenError })]
286
+ }, [
287
+ isReady,
288
+ selectedBlockId,
289
+ sendToPreview
290
+ ]);
291
+ const handleLoad = React.useCallback(() => {
292
+ setTimeout(() => {
293
+ if (!isReadyRef.current) setIframeLoading(false);
294
+ }, 3e3);
295
+ }, []);
296
+ return /* @__PURE__ */ jsxs("div", {
297
+ className: cn("relative h-full w-full", className),
298
+ children: [
299
+ isLoading && /* @__PURE__ */ jsxs("div", {
300
+ className: "bg-muted absolute inset-0 z-10 flex items-center justify-center",
301
+ children: [/* @__PURE__ */ jsx(Icon, {
302
+ icon: "ph:spinner",
303
+ className: "text-muted-foreground h-6 w-6 animate-spin"
304
+ }), /* @__PURE__ */ jsx("span", {
305
+ className: "text-muted-foreground ml-2 text-sm",
306
+ children: t("preview.loadingPreview")
307
+ })]
308
+ }),
309
+ tokenError && /* @__PURE__ */ jsx("div", {
310
+ className: "bg-muted absolute inset-0 z-10 flex items-center justify-center",
311
+ children: /* @__PURE__ */ jsxs("div", {
312
+ className: "bg-destructive/10 border-destructive text-destructive border px-4 py-3 text-sm",
313
+ children: [/* @__PURE__ */ jsx("p", {
314
+ className: "font-medium",
315
+ children: t("preview.previewError")
316
+ }), /* @__PURE__ */ jsx("p", { children: tokenError })]
317
+ })
318
+ }),
319
+ isRefreshing && !isLoading && /* @__PURE__ */ jsxs("div", {
320
+ className: "bg-background absolute top-4 right-4 z-10 flex items-center gap-2 border px-3 py-2 shadow-md",
321
+ children: [/* @__PURE__ */ jsx(Icon, {
322
+ icon: "ph:spinner",
323
+ className: "text-muted-foreground h-4 w-4 animate-spin"
324
+ }), /* @__PURE__ */ jsx("span", {
325
+ className: "text-muted-foreground text-sm",
326
+ children: t("preview.refreshing")
327
+ })]
328
+ }),
329
+ previewUrlResolved && /* @__PURE__ */ jsx("iframe", {
330
+ ref: iframeRef,
331
+ src: previewUrlResolved,
332
+ className: "h-full w-full border-0",
333
+ title: t("common.preview"),
334
+ onLoad: handleLoad,
335
+ sandbox: "allow-scripts allow-same-origin allow-forms"
328
336
  })
329
- });
330
- $[43] = t;
331
- $[44] = tokenError;
332
- $[45] = t19;
333
- } else t19 = $[45];
334
- let t20;
335
- if ($[46] !== isLoading || $[47] !== isRefreshing || $[48] !== t) {
336
- t20 = isRefreshing && !isLoading && /* @__PURE__ */ jsxs("div", {
337
- className: "bg-background absolute top-4 right-4 z-10 flex items-center gap-2 border px-3 py-2 shadow-md",
338
- children: [/* @__PURE__ */ jsx(Icon, {
339
- icon: "ph:spinner",
340
- className: "text-muted-foreground h-4 w-4 animate-spin"
341
- }), /* @__PURE__ */ jsx("span", {
342
- className: "text-muted-foreground text-sm",
343
- children: t("preview.refreshing")
344
- })]
345
- });
346
- $[46] = isLoading;
347
- $[47] = isRefreshing;
348
- $[48] = t;
349
- $[49] = t20;
350
- } else t20 = $[49];
351
- let t21;
352
- if ($[50] !== previewUrlResolved || $[51] !== t) {
353
- t21 = previewUrlResolved && /* @__PURE__ */ jsx("iframe", {
354
- ref: iframeRef,
355
- src: previewUrlResolved,
356
- className: "h-full w-full border-0",
357
- title: t("common.preview"),
358
- onLoad: handleLoad,
359
- sandbox: "allow-scripts allow-same-origin allow-forms"
360
- });
361
- $[50] = previewUrlResolved;
362
- $[51] = t;
363
- $[52] = t21;
364
- } else t21 = $[52];
365
- let t22;
366
- if ($[53] !== t17 || $[54] !== t18 || $[55] !== t19 || $[56] !== t20 || $[57] !== t21) {
367
- t22 = /* @__PURE__ */ jsxs("div", {
368
- className: t17,
369
- children: [
370
- t18,
371
- t19,
372
- t20,
373
- t21
374
- ]
375
- });
376
- $[53] = t17;
377
- $[54] = t18;
378
- $[55] = t19;
379
- $[56] = t20;
380
- $[57] = t21;
381
- $[58] = t22;
382
- } else t22 = $[58];
383
- return t22;
337
+ ]
338
+ });
384
339
  });
385
340
  PreviewPane.displayName = "PreviewPane";
386
341