@questpie/admin 3.0.4 → 3.0.6

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 (90) hide show
  1. package/README.md +99 -1
  2. package/dist/client/builder/types/field-types.d.mts +11 -0
  3. package/dist/client/components/blocks/block-editor-layout.mjs +2 -2
  4. package/dist/client/components/blocks/block-library-sidebar.mjs +89 -61
  5. package/dist/client/components/brand-logo.d.mts +25 -0
  6. package/dist/client/components/brand-logo.mjs +174 -0
  7. package/dist/client/components/media/media-grid.mjs +95 -78
  8. package/dist/client/components/primitives/select-multi.mjs +388 -368
  9. package/dist/client/components/primitives/select-single.mjs +344 -331
  10. package/dist/client/components/widgets/chart-widget.mjs +78 -62
  11. package/dist/client/components/widgets/progress-widget.mjs +39 -37
  12. package/dist/client/components/widgets/quick-actions-widget.mjs +111 -90
  13. package/dist/client/components/widgets/recent-items-widget.mjs +40 -38
  14. package/dist/client/components/widgets/table-widget.mjs +4 -3
  15. package/dist/client/components/widgets/timeline-widget.mjs +92 -74
  16. package/dist/client/components/widgets/value-widget.mjs +164 -144
  17. package/dist/client/create-admin-client.d.mts +7 -0
  18. package/dist/client/create-admin-client.mjs +25 -0
  19. package/dist/client/hooks/use-brand.d.mts +22 -0
  20. package/dist/client/hooks/use-brand.mjs +52 -0
  21. package/dist/client/hooks/use-server-actions.mjs +21 -16
  22. package/dist/client/preview/block-scope-context.d.mts +2 -2
  23. package/dist/client/preview/preview-banner.d.mts +2 -2
  24. package/dist/client/preview/preview-banner.mjs +75 -46
  25. package/dist/client/runtime/index.mjs +1 -1
  26. package/dist/client/runtime/provider.d.mts +4 -0
  27. package/dist/client/runtime/provider.mjs +38 -8
  28. package/dist/client/styles/base.css +4 -0
  29. package/dist/client/types/admin-config.d.mts +24 -0
  30. package/dist/client/views/auth/auth-layout.d.mts +6 -1
  31. package/dist/client/views/auth/auth-layout.mjs +116 -102
  32. package/dist/client/views/collection/auto-form-fields.mjs +2 -0
  33. package/dist/client/views/collection/field-renderer.mjs +3 -2
  34. package/dist/client/views/collection/table-view.mjs +26 -26
  35. package/dist/client/views/globals/global-form-view.mjs +908 -863
  36. package/dist/client/views/layout/admin-layout.mjs +151 -131
  37. package/dist/client/views/layout/admin-router.mjs +297 -180
  38. package/dist/client/views/layout/admin-sidebar.mjs +178 -156
  39. package/dist/client/views/pages/accept-invite-page.mjs +122 -144
  40. package/dist/client/views/pages/forgot-password-page.mjs +22 -30
  41. package/dist/client/views/pages/invite-page.mjs +24 -33
  42. package/dist/client/views/pages/login-page.mjs +24 -32
  43. package/dist/client/views/pages/reset-password-page.mjs +77 -92
  44. package/dist/client/views/pages/setup-page.mjs +73 -65
  45. package/dist/client.d.mts +6 -2
  46. package/dist/client.mjs +5 -2
  47. package/dist/index.d.mts +6 -2
  48. package/dist/index.mjs +5 -2
  49. package/dist/server/augmentation/dashboard.d.mts +23 -5
  50. package/dist/server/augmentation/form-layout.d.mts +10 -0
  51. package/dist/server/augmentation/index.d.mts +1 -1
  52. package/dist/server/augmentation.d.mts +1 -1
  53. package/dist/server/i18n/index.mjs +13 -7
  54. package/dist/server/i18n/messages/cs.mjs +391 -1
  55. package/dist/server/i18n/messages/de.mjs +389 -1
  56. package/dist/server/i18n/messages/en.mjs +102 -0
  57. package/dist/server/i18n/messages/es.mjs +389 -1
  58. package/dist/server/i18n/messages/fr.mjs +389 -1
  59. package/dist/server/i18n/messages/pl.mjs +393 -1
  60. package/dist/server/i18n/messages/pt.mjs +386 -1
  61. package/dist/server/i18n/messages/sk.mjs +133 -1
  62. package/dist/server/modules/admin/collections/account.d.mts +50 -50
  63. package/dist/server/modules/admin/collections/admin-locks.d.mts +53 -53
  64. package/dist/server/modules/admin/collections/admin-preferences.d.mts +39 -39
  65. package/dist/server/modules/admin/collections/admin-saved-views.d.mts +47 -47
  66. package/dist/server/modules/admin/collections/apikey.d.mts +68 -68
  67. package/dist/server/modules/admin/collections/assets.d.mts +20 -20
  68. package/dist/server/modules/admin/collections/session.d.mts +42 -42
  69. package/dist/server/modules/admin/collections/user.d.mts +32 -32
  70. package/dist/server/modules/admin/collections/verification.d.mts +36 -36
  71. package/dist/server/modules/admin/dto/admin-config.dto.mjs +19 -1
  72. package/dist/server/modules/admin/routes/admin-config.d.mts +2 -2
  73. package/dist/server/modules/admin/routes/execute-action.d.mts +9 -9
  74. package/dist/server/modules/admin/routes/execute-action.mjs +34 -28
  75. package/dist/server/modules/admin/routes/i18n-helpers.mjs +34 -0
  76. package/dist/server/modules/admin/routes/locales.d.mts +2 -2
  77. package/dist/server/modules/admin/routes/preview.d.mts +11 -11
  78. package/dist/server/modules/admin/routes/preview.mjs +25 -17
  79. package/dist/server/modules/admin/routes/reactive.d.mts +9 -9
  80. package/dist/server/modules/admin/routes/route-helpers.mjs +1 -1
  81. package/dist/server/modules/admin/routes/setup.mjs +10 -7
  82. package/dist/server/modules/admin/routes/translations.d.mts +4 -4
  83. package/dist/server/modules/admin/routes/widget-data.d.mts +5 -5
  84. package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +23 -23
  85. package/dist/server.d.mts +4 -4
  86. package/dist/shared/preview-utils.d.mts +34 -1
  87. package/dist/shared/preview-utils.mjs +79 -1
  88. package/dist/shared.d.mts +2 -2
  89. package/dist/shared.mjs +2 -2
  90. package/package.json +3 -3
@@ -1,4 +1,4 @@
1
- import { useResolveText } from "../../i18n/hooks.mjs";
1
+ import { useResolveText, useTranslation } from "../../i18n/hooks.mjs";
2
2
  import { cn } from "../../lib/utils.mjs";
3
3
  import { selectClient, useAdminStore } from "../../runtime/provider.mjs";
4
4
  import { resolveIconElement } from "../component-renderer.mjs";
@@ -45,10 +45,11 @@ function formatValue(value) {
45
45
  * ```
46
46
  */
47
47
  function ValueWidget(t0) {
48
- const $ = c(130);
48
+ const $ = c(137);
49
49
  const { config } = t0;
50
50
  const client = useAdminStore(selectClient);
51
51
  const resolveText = useResolveText();
52
+ const { t } = useTranslation();
52
53
  const useServerData = !!config.hasLoader;
53
54
  let t1;
54
55
  if ($[0] !== config.refreshInterval || $[1] !== useServerData) {
@@ -183,46 +184,65 @@ function ValueWidget(t0) {
183
184
  $[43] = resolveText;
184
185
  $[44] = t7$1;
185
186
  } else t7$1 = $[44];
186
- const t8$1 = isFetching && !isLoading;
187
- let t9$1;
187
+ const t8$1 = config.icon;
188
+ const t9$1 = config.cardVariant;
189
+ const t10$1 = isFetching && !isLoading;
190
+ let t11$1;
188
191
  if ($[45] !== refetch) {
189
- t9$1 = () => refetch();
192
+ t11$1 = () => refetch();
190
193
  $[45] = refetch;
191
- $[46] = t9$1;
192
- } else t9$1 = $[46];
193
- let t10$1;
194
- if ($[47] === Symbol.for("react.memo_cache_sentinel")) {
195
- t10$1 = /* @__PURE__ */ jsx(WidgetEmptyState, {
194
+ $[46] = t11$1;
195
+ } else t11$1 = $[46];
196
+ const t12$1 = config.actions;
197
+ const t13$1 = config.className;
198
+ let t14$1;
199
+ if ($[47] !== t) {
200
+ t14$1 = t("widget.value.emptyTitle");
201
+ $[47] = t;
202
+ $[48] = t14$1;
203
+ } else t14$1 = $[48];
204
+ let t15$1;
205
+ if ($[49] !== t) {
206
+ t15$1 = t("widget.value.emptyDescription");
207
+ $[49] = t;
208
+ $[50] = t15$1;
209
+ } else t15$1 = $[50];
210
+ let t16$1;
211
+ if ($[51] !== t14$1 || $[52] !== t15$1) {
212
+ t16$1 = /* @__PURE__ */ jsx(WidgetEmptyState, {
196
213
  iconName: "ph:gauge",
197
- title: "No value to display",
198
- description: "There is no value for this card yet."
214
+ title: t14$1,
215
+ description: t15$1
199
216
  });
200
- $[47] = t10$1;
201
- } else t10$1 = $[47];
202
- let t11$1;
203
- if ($[48] !== config.actions || $[49] !== config.cardVariant || $[50] !== config.className || $[51] !== config.icon || $[52] !== t6$1 || $[53] !== t7$1 || $[54] !== t8$1 || $[55] !== t9$1) {
204
- t11$1 = /* @__PURE__ */ jsx(WidgetCard, {
217
+ $[51] = t14$1;
218
+ $[52] = t15$1;
219
+ $[53] = t16$1;
220
+ } else t16$1 = $[53];
221
+ let t17$1;
222
+ if ($[54] !== config.actions || $[55] !== config.cardVariant || $[56] !== config.className || $[57] !== config.icon || $[58] !== t10$1 || $[59] !== t11$1 || $[60] !== t16$1 || $[61] !== t6$1 || $[62] !== t7$1) {
223
+ t17$1 = /* @__PURE__ */ jsx(WidgetCard, {
205
224
  title: t6$1,
206
225
  description: t7$1,
207
- icon: config.icon,
208
- variant: config.cardVariant,
209
- isRefreshing: t8$1,
210
- onRefresh: t9$1,
211
- actions: config.actions,
212
- className: config.className,
213
- children: t10$1
226
+ icon: t8$1,
227
+ variant: t9$1,
228
+ isRefreshing: t10$1,
229
+ onRefresh: t11$1,
230
+ actions: t12$1,
231
+ className: t13$1,
232
+ children: t16$1
214
233
  });
215
- $[48] = config.actions;
216
- $[49] = config.cardVariant;
217
- $[50] = config.className;
218
- $[51] = config.icon;
219
- $[52] = t6$1;
220
- $[53] = t7$1;
221
- $[54] = t8$1;
222
- $[55] = t9$1;
223
- $[56] = t11$1;
224
- } else t11$1 = $[56];
225
- return t11$1;
234
+ $[54] = config.actions;
235
+ $[55] = config.cardVariant;
236
+ $[56] = config.className;
237
+ $[57] = config.icon;
238
+ $[58] = t10$1;
239
+ $[59] = t11$1;
240
+ $[60] = t16$1;
241
+ $[61] = t6$1;
242
+ $[62] = t7$1;
243
+ $[63] = t17$1;
244
+ } else t17$1 = $[63];
245
+ return t17$1;
226
246
  }
227
247
  let T0;
228
248
  let cls;
@@ -239,61 +259,61 @@ function ValueWidget(t0) {
239
259
  let t7;
240
260
  let t8;
241
261
  let t9;
242
- if ($[57] !== config.actions || $[58] !== config.cardVariant || $[59] !== config.className || $[60] !== config.description || $[61] !== config.title || $[62] !== data.classNames || $[63] !== data.footer || $[64] !== data.formatted || $[65] !== data.icon || $[66] !== data.label || $[67] !== data.subtitle || $[68] !== data.trend || $[69] !== data.value || $[70] !== isFetching || $[71] !== isLoading || $[72] !== refetch || $[73] !== resolveText) {
262
+ if ($[64] !== config.actions || $[65] !== config.cardVariant || $[66] !== config.className || $[67] !== config.description || $[68] !== config.title || $[69] !== data.classNames || $[70] !== data.footer || $[71] !== data.formatted || $[72] !== data.icon || $[73] !== data.label || $[74] !== data.subtitle || $[75] !== data.trend || $[76] !== data.value || $[77] !== isFetching || $[78] !== isLoading || $[79] !== refetch || $[80] !== resolveText) {
243
263
  cls = data.classNames ?? {};
244
264
  const Icon = data.icon;
245
265
  const TrendIcon = data.trend?.icon;
246
266
  let t17$1;
247
- if ($[89] !== config.title || $[90] !== data.label || $[91] !== resolveText) {
267
+ if ($[96] !== config.title || $[97] !== data.label || $[98] !== resolveText) {
248
268
  t17$1 = data.label ? resolveText(data.label) : config.title ? resolveText(config.title) : void 0;
249
- $[89] = config.title;
250
- $[90] = data.label;
251
- $[91] = resolveText;
252
- $[92] = t17$1;
253
- } else t17$1 = $[92];
269
+ $[96] = config.title;
270
+ $[97] = data.label;
271
+ $[98] = resolveText;
272
+ $[99] = t17$1;
273
+ } else t17$1 = $[99];
254
274
  const label = t17$1;
255
275
  let t18$1;
256
- if ($[93] !== data.subtitle || $[94] !== resolveText) {
276
+ if ($[100] !== data.subtitle || $[101] !== resolveText) {
257
277
  t18$1 = data.subtitle ? resolveText(data.subtitle) : void 0;
258
- $[93] = data.subtitle;
259
- $[94] = resolveText;
260
- $[95] = t18$1;
261
- } else t18$1 = $[95];
278
+ $[100] = data.subtitle;
279
+ $[101] = resolveText;
280
+ $[102] = t18$1;
281
+ } else t18$1 = $[102];
262
282
  subtitle = t18$1;
263
283
  let t19$1;
264
- if ($[96] !== data.footer || $[97] !== resolveText) {
284
+ if ($[103] !== data.footer || $[104] !== resolveText) {
265
285
  t19$1 = data.footer ? resolveText(data.footer) : void 0;
266
- $[96] = data.footer;
267
- $[97] = resolveText;
268
- $[98] = t19$1;
269
- } else t19$1 = $[98];
286
+ $[103] = data.footer;
287
+ $[104] = resolveText;
288
+ $[105] = t19$1;
289
+ } else t19$1 = $[105];
270
290
  footer = t19$1;
271
291
  T0 = WidgetCard;
272
292
  t9 = label;
273
293
  t10 = Icon;
274
- if ($[99] !== config.description || $[100] !== resolveText) {
294
+ if ($[106] !== config.description || $[107] !== resolveText) {
275
295
  t11 = config.description ? resolveText(config.description) : void 0;
276
- $[99] = config.description;
277
- $[100] = resolveText;
278
- $[101] = t11;
279
- } else t11 = $[101];
296
+ $[106] = config.description;
297
+ $[107] = resolveText;
298
+ $[108] = t11;
299
+ } else t11 = $[108];
280
300
  t12 = config.cardVariant;
281
- if ($[102] !== refetch) {
301
+ if ($[109] !== refetch) {
282
302
  t13 = () => refetch();
283
- $[102] = refetch;
284
- $[103] = t13;
285
- } else t13 = $[103];
303
+ $[109] = refetch;
304
+ $[110] = t13;
305
+ } else t13 = $[110];
286
306
  t14 = isFetching && !isLoading;
287
307
  t15 = config.actions;
288
308
  t16 = cn(config.className, cls.root);
289
309
  t6 = cn("space-y-1", cls.content);
290
310
  let t20$1;
291
- if ($[104] !== data.formatted || $[105] !== data.value) {
311
+ if ($[111] !== data.formatted || $[112] !== data.value) {
292
312
  t20$1 = data.formatted ?? formatValue(data.value);
293
- $[104] = data.formatted;
294
- $[105] = data.value;
295
- $[106] = t20$1;
296
- } else t20$1 = $[106];
313
+ $[111] = data.formatted;
314
+ $[112] = data.value;
315
+ $[113] = t20$1;
316
+ } else t20$1 = $[113];
297
317
  t7 = /* @__PURE__ */ jsx("div", {
298
318
  className: cn("text-2xl font-bold", cls.value),
299
319
  children: t20$1
@@ -302,77 +322,77 @@ function ValueWidget(t0) {
302
322
  className: cn("flex items-center gap-1 text-sm", cls.trend),
303
323
  children: [resolveIconElement(TrendIcon, { className: cn("h-3 w-3", cls.trendIcon) }), /* @__PURE__ */ jsx("span", { children: data.trend.value })]
304
324
  });
305
- $[57] = config.actions;
306
- $[58] = config.cardVariant;
307
- $[59] = config.className;
308
- $[60] = config.description;
309
- $[61] = config.title;
310
- $[62] = data.classNames;
311
- $[63] = data.footer;
312
- $[64] = data.formatted;
313
- $[65] = data.icon;
314
- $[66] = data.label;
315
- $[67] = data.subtitle;
316
- $[68] = data.trend;
317
- $[69] = data.value;
318
- $[70] = isFetching;
319
- $[71] = isLoading;
320
- $[72] = refetch;
321
- $[73] = resolveText;
322
- $[74] = T0;
323
- $[75] = cls;
324
- $[76] = footer;
325
- $[77] = subtitle;
326
- $[78] = t10;
327
- $[79] = t11;
328
- $[80] = t12;
329
- $[81] = t13;
330
- $[82] = t14;
331
- $[83] = t15;
332
- $[84] = t16;
333
- $[85] = t6;
334
- $[86] = t7;
335
- $[87] = t8;
336
- $[88] = t9;
325
+ $[64] = config.actions;
326
+ $[65] = config.cardVariant;
327
+ $[66] = config.className;
328
+ $[67] = config.description;
329
+ $[68] = config.title;
330
+ $[69] = data.classNames;
331
+ $[70] = data.footer;
332
+ $[71] = data.formatted;
333
+ $[72] = data.icon;
334
+ $[73] = data.label;
335
+ $[74] = data.subtitle;
336
+ $[75] = data.trend;
337
+ $[76] = data.value;
338
+ $[77] = isFetching;
339
+ $[78] = isLoading;
340
+ $[79] = refetch;
341
+ $[80] = resolveText;
342
+ $[81] = T0;
343
+ $[82] = cls;
344
+ $[83] = footer;
345
+ $[84] = subtitle;
346
+ $[85] = t10;
347
+ $[86] = t11;
348
+ $[87] = t12;
349
+ $[88] = t13;
350
+ $[89] = t14;
351
+ $[90] = t15;
352
+ $[91] = t16;
353
+ $[92] = t6;
354
+ $[93] = t7;
355
+ $[94] = t8;
356
+ $[95] = t9;
337
357
  } else {
338
- T0 = $[74];
339
- cls = $[75];
340
- footer = $[76];
341
- subtitle = $[77];
342
- t10 = $[78];
343
- t11 = $[79];
344
- t12 = $[80];
345
- t13 = $[81];
346
- t14 = $[82];
347
- t15 = $[83];
348
- t16 = $[84];
349
- t6 = $[85];
350
- t7 = $[86];
351
- t8 = $[87];
352
- t9 = $[88];
358
+ T0 = $[81];
359
+ cls = $[82];
360
+ footer = $[83];
361
+ subtitle = $[84];
362
+ t10 = $[85];
363
+ t11 = $[86];
364
+ t12 = $[87];
365
+ t13 = $[88];
366
+ t14 = $[89];
367
+ t15 = $[90];
368
+ t16 = $[91];
369
+ t6 = $[92];
370
+ t7 = $[93];
371
+ t8 = $[94];
372
+ t9 = $[95];
353
373
  }
354
374
  let t17;
355
- if ($[107] !== cls || $[108] !== subtitle) {
375
+ if ($[114] !== cls || $[115] !== subtitle) {
356
376
  t17 = subtitle && /* @__PURE__ */ jsx("p", {
357
377
  className: cn("text-muted-foreground text-xs", cls.subtitle),
358
378
  children: subtitle
359
379
  });
360
- $[107] = cls;
361
- $[108] = subtitle;
362
- $[109] = t17;
363
- } else t17 = $[109];
380
+ $[114] = cls;
381
+ $[115] = subtitle;
382
+ $[116] = t17;
383
+ } else t17 = $[116];
364
384
  let t18;
365
- if ($[110] !== cls || $[111] !== footer) {
385
+ if ($[117] !== cls || $[118] !== footer) {
366
386
  t18 = footer && /* @__PURE__ */ jsx("p", {
367
387
  className: cn("text-muted-foreground pt-2 text-xs", cls.footer),
368
388
  children: footer
369
389
  });
370
- $[110] = cls;
371
- $[111] = footer;
372
- $[112] = t18;
373
- } else t18 = $[112];
390
+ $[117] = cls;
391
+ $[118] = footer;
392
+ $[119] = t18;
393
+ } else t18 = $[119];
374
394
  let t19;
375
- if ($[113] !== t17 || $[114] !== t18 || $[115] !== t6 || $[116] !== t7 || $[117] !== t8) {
395
+ if ($[120] !== t17 || $[121] !== t18 || $[122] !== t6 || $[123] !== t7 || $[124] !== t8) {
376
396
  t19 = /* @__PURE__ */ jsxs("div", {
377
397
  className: t6,
378
398
  children: [
@@ -382,15 +402,15 @@ function ValueWidget(t0) {
382
402
  t18
383
403
  ]
384
404
  });
385
- $[113] = t17;
386
- $[114] = t18;
387
- $[115] = t6;
388
- $[116] = t7;
389
- $[117] = t8;
390
- $[118] = t19;
391
- } else t19 = $[118];
405
+ $[120] = t17;
406
+ $[121] = t18;
407
+ $[122] = t6;
408
+ $[123] = t7;
409
+ $[124] = t8;
410
+ $[125] = t19;
411
+ } else t19 = $[125];
392
412
  let t20;
393
- if ($[119] !== T0 || $[120] !== t10 || $[121] !== t11 || $[122] !== t12 || $[123] !== t13 || $[124] !== t14 || $[125] !== t15 || $[126] !== t16 || $[127] !== t19 || $[128] !== t9) {
413
+ if ($[126] !== T0 || $[127] !== t10 || $[128] !== t11 || $[129] !== t12 || $[130] !== t13 || $[131] !== t14 || $[132] !== t15 || $[133] !== t16 || $[134] !== t19 || $[135] !== t9) {
394
414
  t20 = /* @__PURE__ */ jsx(T0, {
395
415
  title: t9,
396
416
  icon: t10,
@@ -402,18 +422,18 @@ function ValueWidget(t0) {
402
422
  className: t16,
403
423
  children: t19
404
424
  });
405
- $[119] = T0;
406
- $[120] = t10;
407
- $[121] = t11;
408
- $[122] = t12;
409
- $[123] = t13;
410
- $[124] = t14;
411
- $[125] = t15;
412
- $[126] = t16;
413
- $[127] = t19;
414
- $[128] = t9;
415
- $[129] = t20;
416
- } else t20 = $[129];
425
+ $[126] = T0;
426
+ $[127] = t10;
427
+ $[128] = t11;
428
+ $[129] = t12;
429
+ $[130] = t13;
430
+ $[131] = t14;
431
+ $[132] = t15;
432
+ $[133] = t16;
433
+ $[134] = t19;
434
+ $[135] = t9;
435
+ $[136] = t20;
436
+ } else t20 = $[136];
417
437
  return t20;
418
438
  }
419
439
 
@@ -0,0 +1,7 @@
1
+ import { QuestpieApp, QuestpieClient, QuestpieClientConfig } from "questpie/client";
2
+
3
+ //#region src/client/create-admin-client.d.ts
4
+
5
+ declare function createAdminClient<TApp extends QuestpieApp>(config: QuestpieClientConfig): QuestpieClient<TApp>;
6
+ //#endregion
7
+ export { createAdminClient };
@@ -0,0 +1,25 @@
1
+ import { withAdminRequestHeader } from "../shared/preview-utils.mjs";
2
+ import { createClient } from "questpie/client";
3
+
4
+ //#region src/client/create-admin-client.ts
5
+ /**
6
+ * createAdminClient — typed CMS client preconfigured for admin SPA usage.
7
+ *
8
+ * Wraps `createClient` from `questpie/client` and auto-injects the
9
+ * `X-Questpie-Admin` request header on every outbound call. Server-side
10
+ * `isAdminRequest()` (and any access rule that uses it) can then branch
11
+ * on the header instead of relying on URL prefix matching.
12
+ *
13
+ * Use this for the client passed to `<AdminLayoutProvider client={...}>`.
14
+ * Keep your public/frontend client as plain `createClient` — that one
15
+ * MUST NOT inject the admin header.
16
+ */
17
+ function createAdminClient(config) {
18
+ return createClient({
19
+ ...config,
20
+ fetch: withAdminRequestHeader(config.fetch)
21
+ });
22
+ }
23
+
24
+ //#endregion
25
+ export { createAdminClient };
@@ -0,0 +1,22 @@
1
+ import { BrandLogoConfig } from "../types/admin-config.mjs";
2
+
3
+ //#region src/client/hooks/use-brand.d.ts
4
+ interface BrandSnapshot {
5
+ name: string;
6
+ logo: BrandLogoConfig | null;
7
+ tagline: string | null;
8
+ favicon: string | null;
9
+ }
10
+ /**
11
+ * Read branding fields from the admin store. Safe to call outside of an
12
+ * `<AdminProvider>` — falls back to the default snapshot when no store is
13
+ * mounted (e.g. on a bare auth page).
14
+ */
15
+ declare function useBrand(): BrandSnapshot;
16
+ /**
17
+ * Imperative variant for code paths that cannot use hooks (callbacks,
18
+ * server-side helpers). Returns null when no provider is mounted.
19
+ */
20
+ declare function useBrandSnapshotRef(): BrandSnapshot | null;
21
+ //#endregion
22
+ export { BrandSnapshot, useBrand, useBrandSnapshotRef };
@@ -0,0 +1,52 @@
1
+ import { useAdminStoreRaw } from "../runtime/provider.mjs";
2
+ import { c } from "react/compiler-runtime";
3
+ import { createStore, useStore } from "zustand";
4
+
5
+ //#region src/client/hooks/use-brand.ts
6
+ const DEFAULT_BRAND = {
7
+ name: "Admin",
8
+ logo: null,
9
+ tagline: null,
10
+ favicon: null
11
+ };
12
+ const FALLBACK_STORE = createStore(() => ({
13
+ brandName: DEFAULT_BRAND.name,
14
+ brandLogo: DEFAULT_BRAND.logo,
15
+ brandTagline: DEFAULT_BRAND.tagline,
16
+ brandFavicon: DEFAULT_BRAND.favicon
17
+ }));
18
+ function selectBrand(state) {
19
+ return {
20
+ name: state.brandName,
21
+ logo: state.brandLogo,
22
+ tagline: state.brandTagline,
23
+ favicon: state.brandFavicon
24
+ };
25
+ }
26
+ /**
27
+ * Read branding fields from the admin store. Safe to call outside of an
28
+ * `<AdminProvider>` — falls back to the default snapshot when no store is
29
+ * mounted (e.g. on a bare auth page).
30
+ */
31
+ function useBrand() {
32
+ return useStore(useAdminStoreRaw() ?? FALLBACK_STORE, selectBrand);
33
+ }
34
+ /**
35
+ * Imperative variant for code paths that cannot use hooks (callbacks,
36
+ * server-side helpers). Returns null when no provider is mounted.
37
+ */
38
+ function useBrandSnapshotRef() {
39
+ const $ = c(2);
40
+ const store = useAdminStoreRaw();
41
+ if (!store) return null;
42
+ let t0;
43
+ if ($[0] !== store) {
44
+ t0 = selectBrand(store.getState());
45
+ $[0] = store;
46
+ $[1] = t0;
47
+ } else t0 = $[1];
48
+ return t0;
49
+ }
50
+
51
+ //#endregion
52
+ export { useBrand, useBrandSnapshotRef };
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
 
3
+ import { useTranslation } from "../i18n/hooks.mjs";
3
4
  import { selectAdmin, selectClient, useAdminStore } from "../runtime/provider.mjs";
4
5
  import { configureField } from "../builder/field/field.mjs";
5
6
  import { useCollectionSchema } from "./use-collection-schema.mjs";
@@ -13,10 +14,10 @@ import { c } from "react/compiler-runtime";
13
14
  * Server actions have their handlers stripped during serialization; this hook
14
15
  * creates client-side wrappers that execute actions via the server API.
15
16
  */
16
- function getActionErrorMessage(response) {
17
+ function getActionErrorMessage(response, t) {
17
18
  if (response.error) return response.error;
18
19
  if (response.result?.toast?.message) return response.result.toast.message;
19
- return "Action execution failed";
20
+ return t("action.executionFailed");
20
21
  }
21
22
  async function applyServerActionEffects(result, ctx) {
22
23
  if (!result) return;
@@ -54,7 +55,7 @@ function buildServerFormFields(rawFields, fieldRegistry) {
54
55
  /**
55
56
  * Map a server action definition (from collection schema) to a client ActionDefinition
56
57
  */
57
- function mapServerAction(serverAction, collection, fieldRegistry, client) {
58
+ function mapServerAction(serverAction, collection, fieldRegistry, client, locale, t) {
58
59
  const action = {
59
60
  id: serverAction.id,
60
61
  label: serverAction.label,
@@ -91,7 +92,7 @@ function mapServerAction(serverAction, collection, fieldRegistry, client) {
91
92
  width: form.width,
92
93
  onSubmit: async (data, ctx) => {
93
94
  const routes = client?.routes;
94
- if (!routes?.executeAction) throw new Error("executeAction route is not available");
95
+ if (!routes?.executeAction) throw new Error(t("error.serverActionFailed"));
95
96
  const itemId = ctx.item && !Array.isArray(ctx.item) ? ctx.item.id : void 0;
96
97
  const idsFromItems = Array.isArray(ctx.items) ? ctx.items.map((it) => it?.id).filter(Boolean) : [];
97
98
  const idsFromItemArray = Array.isArray(ctx.item) ? ctx.item.map((it) => it?.id).filter(Boolean) : [];
@@ -101,9 +102,10 @@ function mapServerAction(serverAction, collection, fieldRegistry, client) {
101
102
  actionId: serverAction.id,
102
103
  itemId,
103
104
  itemIds,
104
- data
105
+ data,
106
+ locale
105
107
  });
106
- if (!response.success || response.result?.type === "error") throw new Error(getActionErrorMessage(response));
108
+ if (!response.success || response.result?.type === "error") throw new Error(getActionErrorMessage(response, t));
107
109
  await applyServerActionEffects(response.result, ctx);
108
110
  }
109
111
  }
@@ -122,10 +124,11 @@ function mapServerAction(serverAction, collection, fieldRegistry, client) {
122
124
  * ```
123
125
  */
124
126
  function useServerActions(t0) {
125
- const $ = c(11);
127
+ const $ = c(13);
126
128
  const { collection, schema: schemaOverride } = t0;
127
129
  const admin = useAdminStore(selectAdmin);
128
130
  const client = useAdminStore(selectClient);
131
+ const { t, locale } = useTranslation();
129
132
  const t1 = !schemaOverride;
130
133
  let t2;
131
134
  if ($[0] !== t1) {
@@ -150,28 +153,30 @@ function useServerActions(t0) {
150
153
  break bb0;
151
154
  }
152
155
  let t4$1;
153
- if ($[3] !== actionsConfig.custom || $[4] !== admin || $[5] !== client || $[6] !== collection) {
156
+ if ($[3] !== actionsConfig.custom || $[4] !== admin || $[5] !== client || $[6] !== collection || $[7] !== locale || $[8] !== t) {
154
157
  const fieldRegistry = admin?.getFields?.() ?? null;
155
- t4$1 = actionsConfig.custom.map((serverAction) => mapServerAction(serverAction, collection, fieldRegistry, client));
158
+ t4$1 = actionsConfig.custom.map((serverAction) => mapServerAction(serverAction, collection, fieldRegistry, client, locale, t));
156
159
  $[3] = actionsConfig.custom;
157
160
  $[4] = admin;
158
161
  $[5] = client;
159
162
  $[6] = collection;
160
- $[7] = t4$1;
161
- } else t4$1 = $[7];
163
+ $[7] = locale;
164
+ $[8] = t;
165
+ $[9] = t4$1;
166
+ } else t4$1 = $[9];
162
167
  t3 = t4$1;
163
168
  }
164
169
  const serverActions = t3;
165
170
  let t4;
166
- if ($[8] !== isPending || $[9] !== serverActions) {
171
+ if ($[10] !== isPending || $[11] !== serverActions) {
167
172
  t4 = {
168
173
  serverActions,
169
174
  isLoading: isPending
170
175
  };
171
- $[8] = isPending;
172
- $[9] = serverActions;
173
- $[10] = t4;
174
- } else t4 = $[10];
176
+ $[10] = isPending;
177
+ $[11] = serverActions;
178
+ $[12] = t4;
179
+ } else t4 = $[12];
175
180
  return t4;
176
181
  }
177
182
  /**
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import * as react_jsx_runtime22 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime21 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): react_jsx_runtime22.JSX.Element;
38
+ }: BlockScopeProviderProps): react_jsx_runtime21.JSX.Element;
39
39
  /**
40
40
  * Get current block scope context.
41
41
  *
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime21 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime22 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): react_jsx_runtime21.JSX.Element | null;
43
+ }: PreviewBannerProps): react_jsx_runtime22.JSX.Element | null;
44
44
  //#endregion
45
45
  export { PreviewBanner, PreviewBannerProps };