@maykonpaulo/maestro-admin 0.4.0-next.0 → 0.4.0-next.1

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/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/components/MaestroAdmin.tsx
2
- import { useCallback as useCallback5, useEffect as useEffect7, useMemo as useMemo7, useState as useState14 } from "react";
2
+ import { useCallback as useCallback5, useEffect as useEffect8, useMemo as useMemo7, useState as useState14 } from "react";
3
3
 
4
4
  // src/client/MaestroClient.ts
5
5
  var MaestroApiError = class extends Error {
@@ -431,10 +431,6 @@ var PATHS = {
431
431
  /* @__PURE__ */ jsx("rect", { x: "3.5", y: "13.5", width: "7", height: "7", rx: "1.5" }),
432
432
  /* @__PURE__ */ jsx("rect", { x: "13.5", y: "13.5", width: "7", height: "7", rx: "1.5" })
433
433
  ] }),
434
- baton: /* @__PURE__ */ jsxs(Fragment, { children: [
435
- /* @__PURE__ */ jsx("path", { d: "M4 20 14 10" }),
436
- /* @__PURE__ */ jsx("circle", { cx: "17", cy: "7", r: "3.2" })
437
- ] }),
438
434
  search: /* @__PURE__ */ jsxs(Fragment, { children: [
439
435
  /* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "6.5" }),
440
436
  /* @__PURE__ */ jsx("path", { d: "m16 16 4.5 4.5" })
@@ -593,8 +589,84 @@ function entityIcon(entity) {
593
589
  return "table";
594
590
  }
595
591
 
592
+ // src/components/brand.tsx
593
+ import { useId } from "react";
594
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
595
+ function labelProps(title) {
596
+ return title ? { role: "img" } : { "aria-hidden": true };
597
+ }
598
+ function MaestroMark({
599
+ size = 30,
600
+ className,
601
+ title
602
+ }) {
603
+ const maskId = useId();
604
+ return /* @__PURE__ */ jsxs2(
605
+ "svg",
606
+ {
607
+ viewBox: "0 0 64 64",
608
+ width: size,
609
+ height: size,
610
+ fill: "none",
611
+ className,
612
+ focusable: "false",
613
+ ...labelProps(title),
614
+ children: [
615
+ title && /* @__PURE__ */ jsx2("title", { children: title }),
616
+ /* @__PURE__ */ jsxs2("mask", { id: maskId, maskUnits: "userSpaceOnUse", x: "0", y: "0", width: "64", height: "64", children: [
617
+ /* @__PURE__ */ jsx2("rect", { width: "64", height: "64", fill: "#000" }),
618
+ /* @__PURE__ */ jsx2("rect", { y: "14", width: "64", height: "10.667", fill: "#fff" }),
619
+ /* @__PURE__ */ jsx2("rect", { y: "28.667", width: "64", height: "10.667", fill: "#fff" }),
620
+ /* @__PURE__ */ jsx2("rect", { y: "43.333", width: "64", height: "10.667", fill: "#fff" })
621
+ ] }),
622
+ /* @__PURE__ */ jsx2(
623
+ "path",
624
+ {
625
+ d: "M12 54V14l20 24 20-24v40",
626
+ stroke: "currentColor",
627
+ strokeWidth: "10",
628
+ strokeLinejoin: "round",
629
+ mask: `url(#${maskId})`
630
+ }
631
+ )
632
+ ]
633
+ }
634
+ );
635
+ }
636
+ function MaestroSeal({
637
+ size = 30,
638
+ className,
639
+ title
640
+ }) {
641
+ const maskId = useId();
642
+ return /* @__PURE__ */ jsxs2(
643
+ "svg",
644
+ {
645
+ viewBox: "0 0 64 64",
646
+ width: size,
647
+ height: size,
648
+ className,
649
+ focusable: "false",
650
+ ...labelProps(title),
651
+ children: [
652
+ title && /* @__PURE__ */ jsx2("title", { children: title }),
653
+ /* @__PURE__ */ jsxs2("mask", { id: maskId, maskUnits: "userSpaceOnUse", x: "0", y: "0", width: "64", height: "64", children: [
654
+ /* @__PURE__ */ jsx2("rect", { width: "64", height: "64", fill: "#fff" }),
655
+ /* @__PURE__ */ jsxs2("g", { transform: "scale(1.142857143) translate(-4 -4)", children: [
656
+ /* @__PURE__ */ jsx2("path", { d: "M17.3 47V17L32 35L46.7 17V47", fill: "none", stroke: "#000", strokeWidth: "8.1", strokeLinejoin: "round" }),
657
+ /* @__PURE__ */ jsx2("rect", { x: "-8", y: "-8", width: "80", height: "25", fill: "#fff" }),
658
+ /* @__PURE__ */ jsx2("rect", { x: "-8", y: "47", width: "80", height: "25", fill: "#fff" }),
659
+ /* @__PURE__ */ jsx2("rect", { x: "-8", y: "25", width: "80", height: "3", fill: "#fff" })
660
+ ] })
661
+ ] }),
662
+ /* @__PURE__ */ jsx2("rect", { width: "64", height: "64", rx: "18.3", fill: "currentColor", mask: `url(#${maskId})` })
663
+ ]
664
+ }
665
+ );
666
+ }
667
+
596
668
  // src/components/Sidebar.tsx
597
- import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
669
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
598
670
  function normalize(text) {
599
671
  return text.toLowerCase().normalize("NFD").replace(/\p{M}/gu, "");
600
672
  }
@@ -613,9 +685,9 @@ function Highlight({ label, query }) {
613
685
  if (idx === -1) return label;
614
686
  const start = originalIndex[idx];
615
687
  const end = (originalIndex[idx + foldedQuery.length - 1] ?? label.length - 1) + 1;
616
- return /* @__PURE__ */ jsxs2(Fragment2, { children: [
688
+ return /* @__PURE__ */ jsxs3(Fragment2, { children: [
617
689
  label.slice(0, start),
618
- /* @__PURE__ */ jsx2("mark", { children: label.slice(start, end) }),
690
+ /* @__PURE__ */ jsx3("mark", { children: label.slice(start, end) }),
619
691
  label.slice(end)
620
692
  ] });
621
693
  }
@@ -626,7 +698,7 @@ function EntityButton({
626
698
  subtitle,
627
699
  query
628
700
  }) {
629
- return /* @__PURE__ */ jsxs2(
701
+ return /* @__PURE__ */ jsxs3(
630
702
  "button",
631
703
  {
632
704
  type: "button",
@@ -635,10 +707,10 @@ function EntityButton({
635
707
  className: "mst-navitem",
636
708
  title: entity.label.plural,
637
709
  children: [
638
- /* @__PURE__ */ jsx2(Icon, { name: entityIcon(entity), size: 14 }),
639
- /* @__PURE__ */ jsxs2("span", { className: "mst-navitem__label", children: [
640
- query ? /* @__PURE__ */ jsx2(Highlight, { label: entity.label.plural, query }) : entity.label.plural,
641
- subtitle && /* @__PURE__ */ jsxs2("span", { className: "mst-navitem__sub", children: [
710
+ /* @__PURE__ */ jsx3(Icon, { name: entityIcon(entity), size: 14 }),
711
+ /* @__PURE__ */ jsxs3("span", { className: "mst-navitem__label", children: [
712
+ query ? /* @__PURE__ */ jsx3(Highlight, { label: entity.label.plural, query }) : entity.label.plural,
713
+ subtitle && /* @__PURE__ */ jsxs3("span", { className: "mst-navitem__sub", children: [
642
714
  " \xB7 ",
643
715
  subtitle
644
716
  ] })
@@ -677,12 +749,12 @@ function Sidebar({
677
749
  onSelect(entityId);
678
750
  };
679
751
  const isExpanded = (groupId, hasActive) => expanded[groupId] ?? hasActive;
680
- return /* @__PURE__ */ jsxs2("aside", { className: "mst-side", children: [
681
- /* @__PURE__ */ jsxs2("div", { className: "mst-side__brand", children: [
682
- /* @__PURE__ */ jsx2("span", { className: "mst-mark", children: /* @__PURE__ */ jsx2(Icon, { name: "baton", size: 15 }) }),
683
- /* @__PURE__ */ jsx2("span", { className: "mst-side__title", children: title })
752
+ return /* @__PURE__ */ jsxs3("aside", { className: "mst-side", children: [
753
+ /* @__PURE__ */ jsxs3("div", { className: "mst-side__brand", children: [
754
+ /* @__PURE__ */ jsx3(MaestroMark, { className: "mst-mark", size: 30 }),
755
+ /* @__PURE__ */ jsx3("span", { className: "mst-side__title", children: title })
684
756
  ] }),
685
- /* @__PURE__ */ jsx2("div", { className: "mst-side__search", children: /* @__PURE__ */ jsx2(
757
+ /* @__PURE__ */ jsx3("div", { className: "mst-side__search", children: /* @__PURE__ */ jsx3(
686
758
  "input",
687
759
  {
688
760
  type: "search",
@@ -696,7 +768,7 @@ function Sidebar({
696
768
  "aria-label": t.searchMenu
697
769
  }
698
770
  ) }),
699
- /* @__PURE__ */ jsx2("nav", { className: "mst-side__nav", children: query ? results.length === 0 ? /* @__PURE__ */ jsx2("p", { className: "mst-side__empty", children: t.noMenuResults }) : results.map((e) => /* @__PURE__ */ jsx2(
771
+ /* @__PURE__ */ jsx3("nav", { className: "mst-side__nav", children: query ? results.length === 0 ? /* @__PURE__ */ jsx3("p", { className: "mst-side__empty", children: t.noMenuResults }) : results.map((e) => /* @__PURE__ */ jsx3(
700
772
  EntityButton,
701
773
  {
702
774
  entity: e,
@@ -706,21 +778,21 @@ function Sidebar({
706
778
  query
707
779
  },
708
780
  e.id
709
- )) : /* @__PURE__ */ jsxs2(Fragment2, { children: [
710
- onHome && /* @__PURE__ */ jsxs2("button", { type: "button", className: "mst-navitem", "aria-current": homeActive, onClick: onHome, title: t.hub, children: [
711
- /* @__PURE__ */ jsx2(Icon, { name: "hub", size: 14 }),
712
- /* @__PURE__ */ jsx2("span", { className: "mst-navitem__label", children: t.hub })
781
+ )) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
782
+ onHome && /* @__PURE__ */ jsxs3("button", { type: "button", className: "mst-navitem", "aria-current": homeActive, onClick: onHome, title: t.hub, children: [
783
+ /* @__PURE__ */ jsx3(Icon, { name: "hub", size: 14 }),
784
+ /* @__PURE__ */ jsx3("span", { className: "mst-navitem__label", children: t.hub })
713
785
  ] }),
714
- recentEntities.length > 0 && /* @__PURE__ */ jsxs2(Fragment2, { children: [
715
- /* @__PURE__ */ jsx2("p", { className: "mst-side__section", children: t.recents }),
716
- recentEntities.map((e) => /* @__PURE__ */ jsx2(EntityButton, { entity: e, active: e.id === activeId, onSelect: select }, e.id))
786
+ recentEntities.length > 0 && /* @__PURE__ */ jsxs3(Fragment2, { children: [
787
+ /* @__PURE__ */ jsx3("p", { className: "mst-side__section", children: t.recents }),
788
+ recentEntities.map((e) => /* @__PURE__ */ jsx3(EntityButton, { entity: e, active: e.id === activeId, onSelect: select }, e.id))
717
789
  ] }),
718
- /* @__PURE__ */ jsx2("p", { className: "mst-side__section", children: t.menus }),
790
+ /* @__PURE__ */ jsx3("p", { className: "mst-side__section", children: t.menus }),
719
791
  menu.groups.map((group) => {
720
792
  const hasActive = group.entities.some((e) => e.id === activeId);
721
793
  const open = isExpanded(group.id, hasActive);
722
- return /* @__PURE__ */ jsxs2("div", { children: [
723
- /* @__PURE__ */ jsxs2(
794
+ return /* @__PURE__ */ jsxs3("div", { children: [
795
+ /* @__PURE__ */ jsxs3(
724
796
  "button",
725
797
  {
726
798
  type: "button",
@@ -728,7 +800,7 @@ function Sidebar({
728
800
  onClick: () => setExpanded((prev) => ({ ...prev, [group.id]: !open })),
729
801
  className: "mst-navitem mst-navitem--folder",
730
802
  children: [
731
- /* @__PURE__ */ jsx2(
803
+ /* @__PURE__ */ jsx3(
732
804
  Icon,
733
805
  {
734
806
  name: "chevronRight",
@@ -736,19 +808,19 @@ function Sidebar({
736
808
  className: open ? "mst-navitem__chev mst-navitem__chev--open" : "mst-navitem__chev"
737
809
  }
738
810
  ),
739
- /* @__PURE__ */ jsx2("span", { className: "mst-navitem__label", children: group.label }),
740
- /* @__PURE__ */ jsx2("span", { className: "mst-navitem__count", children: group.entities.length })
811
+ /* @__PURE__ */ jsx3("span", { className: "mst-navitem__label", children: group.label }),
812
+ /* @__PURE__ */ jsx3("span", { className: "mst-navitem__count", children: group.entities.length })
741
813
  ]
742
814
  }
743
815
  ),
744
- open && /* @__PURE__ */ jsx2("div", { className: "mst-side__children", children: group.entities.map((e) => /* @__PURE__ */ jsx2(EntityButton, { entity: e, active: e.id === activeId, onSelect: select }, e.id)) })
816
+ open && /* @__PURE__ */ jsx3("div", { className: "mst-side__children", children: group.entities.map((e) => /* @__PURE__ */ jsx3(EntityButton, { entity: e, active: e.id === activeId, onSelect: select }, e.id)) })
745
817
  ] }, group.id);
746
818
  }),
747
- menu.ungrouped.map((e) => /* @__PURE__ */ jsx2(EntityButton, { entity: e, active: e.id === activeId, onSelect: select }, e.id))
819
+ menu.ungrouped.map((e) => /* @__PURE__ */ jsx3(EntityButton, { entity: e, active: e.id === activeId, onSelect: select }, e.id))
748
820
  ] }) }),
749
- /* @__PURE__ */ jsxs2("div", { className: "mst-side__foot", children: [
750
- /* @__PURE__ */ jsx2("span", { className: "mst-pulse", "aria-hidden": true }),
751
- /* @__PURE__ */ jsx2("span", { children: t.entitiesFooter(entities.length) })
821
+ /* @__PURE__ */ jsxs3("div", { className: "mst-side__foot", children: [
822
+ /* @__PURE__ */ jsx3("span", { className: "mst-pulse", "aria-hidden": true }),
823
+ /* @__PURE__ */ jsx3("span", { children: t.entitiesFooter(entities.length) })
752
824
  ] })
753
825
  ] });
754
826
  }
@@ -757,8 +829,16 @@ function Sidebar({
757
829
  import { useState as useState5 } from "react";
758
830
 
759
831
  // src/theme.tsx
760
- import { createContext as createContext3, useCallback as useCallback2, useContext as useContext3, useMemo as useMemo2, useState as useState3 } from "react";
761
- import { jsx as jsx3 } from "react/jsx-runtime";
832
+ import {
833
+ createContext as createContext3,
834
+ useCallback as useCallback2,
835
+ useContext as useContext3,
836
+ useEffect as useEffect2,
837
+ useMemo as useMemo2,
838
+ useRef,
839
+ useState as useState3
840
+ } from "react";
841
+ import { jsx as jsx4 } from "react/jsx-runtime";
762
842
  var MAESTRO_THEMES = [
763
843
  { id: "cobalto", label: "Grafite & Cobalto", swatch: "#3557e8" },
764
844
  { id: "latao", label: "Ard\xF3sia & Lat\xE3o", swatch: "#9a6a22" },
@@ -837,7 +917,15 @@ function MaestroThemeProvider({
837
917
  }),
838
918
  [state, config.picker, update]
839
919
  );
840
- return /* @__PURE__ */ jsx3(ThemeContext.Provider, { value, children: /* @__PURE__ */ jsx3(
920
+ const faviconRef = useRef(config.favicon);
921
+ faviconRef.current = config.favicon;
922
+ useEffect2(() => {
923
+ const href = faviconRef.current?.(value.preset);
924
+ if (!href) return;
925
+ const link = globalThis.document?.querySelector('link[rel="icon"]');
926
+ if (link) link.href = href;
927
+ }, [value.preset]);
928
+ return /* @__PURE__ */ jsx4(ThemeContext.Provider, { value, children: /* @__PURE__ */ jsx4(
841
929
  "div",
842
930
  {
843
931
  ref: rootRef,
@@ -852,11 +940,11 @@ function MaestroThemeProvider({
852
940
  }
853
941
 
854
942
  // src/components/menu.tsx
855
- import { useEffect as useEffect2, useLayoutEffect, useRef, useState as useState4 } from "react";
943
+ import { useEffect as useEffect3, useLayoutEffect, useRef as useRef2, useState as useState4 } from "react";
856
944
  import { createPortal } from "react-dom";
857
- import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
945
+ import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
858
946
  function PopMenu({ anchor, items, onClose }) {
859
- const ref = useRef(null);
947
+ const ref = useRef2(null);
860
948
  const [pos, setPos] = useState4(anchor);
861
949
  const root = useAdminRoot();
862
950
  useLayoutEffect(() => {
@@ -868,7 +956,7 @@ function PopMenu({ anchor, items, onClose }) {
868
956
  y: Math.max(4, Math.min(anchor.y, window.innerHeight - rect.height - 8))
869
957
  });
870
958
  }, [anchor]);
871
- useEffect2(() => {
959
+ useEffect3(() => {
872
960
  const onDown = (e) => {
873
961
  if (ref.current && !ref.current.contains(e.target)) onClose();
874
962
  };
@@ -887,9 +975,9 @@ function PopMenu({ anchor, items, onClose }) {
887
975
  };
888
976
  }, [onClose]);
889
977
  return createPortal(
890
- /* @__PURE__ */ jsx4("div", { ref, role: "menu", style: { left: pos.x, top: pos.y }, className: "mst-menu", children: items.map((item) => /* @__PURE__ */ jsxs3("div", { children: [
891
- item.separated && /* @__PURE__ */ jsx4("div", { className: "mst-menu__sep" }),
892
- /* @__PURE__ */ jsxs3(
978
+ /* @__PURE__ */ jsx5("div", { ref, role: "menu", style: { left: pos.x, top: pos.y }, className: "mst-menu", children: items.map((item) => /* @__PURE__ */ jsxs4("div", { children: [
979
+ item.separated && /* @__PURE__ */ jsx5("div", { className: "mst-menu__sep" }),
980
+ /* @__PURE__ */ jsxs4(
893
981
  "button",
894
982
  {
895
983
  type: "button",
@@ -900,7 +988,7 @@ function PopMenu({ anchor, items, onClose }) {
900
988
  },
901
989
  className: `mst-menu__item${item.danger ? " mst-menu__item--danger" : ""}`,
902
990
  children: [
903
- item.icon && /* @__PURE__ */ jsx4(Icon, { name: item.icon, size: 14 }),
991
+ item.icon && /* @__PURE__ */ jsx5(Icon, { name: item.icon, size: 14 }),
904
992
  item.label
905
993
  ]
906
994
  }
@@ -911,8 +999,8 @@ function PopMenu({ anchor, items, onClose }) {
911
999
  }
912
1000
  function MenuButton({ items, label }) {
913
1001
  const [anchor, setAnchor] = useState4(void 0);
914
- return /* @__PURE__ */ jsxs3(Fragment3, { children: [
915
- /* @__PURE__ */ jsx4(
1002
+ return /* @__PURE__ */ jsxs4(Fragment3, { children: [
1003
+ /* @__PURE__ */ jsx5(
916
1004
  "button",
917
1005
  {
918
1006
  type: "button",
@@ -923,15 +1011,15 @@ function MenuButton({ items, label }) {
923
1011
  setAnchor({ x: rect.right - 184, y: rect.bottom + 4 });
924
1012
  },
925
1013
  className: "mst-iconbtn",
926
- children: /* @__PURE__ */ jsx4(Icon, { name: "dots", size: 14 })
1014
+ children: /* @__PURE__ */ jsx5(Icon, { name: "dots", size: 14 })
927
1015
  }
928
1016
  ),
929
- anchor && /* @__PURE__ */ jsx4(PopMenu, { anchor, items, onClose: () => setAnchor(void 0) })
1017
+ anchor && /* @__PURE__ */ jsx5(PopMenu, { anchor, items, onClose: () => setAnchor(void 0) })
930
1018
  ] });
931
1019
  }
932
1020
 
933
1021
  // src/components/Header.tsx
934
- import { Fragment as Fragment4, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1022
+ import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
935
1023
  var NEXT_SCHEME = { system: "light", light: "dark", dark: "system" };
936
1024
  var SCHEME_ICON = {
937
1025
  system: "swatch",
@@ -944,32 +1032,32 @@ function Header({ crumbs, onOpenPalette }) {
944
1032
  const [anchor, setAnchor] = useState5(void 0);
945
1033
  const themeItems = MAESTRO_THEMES.map((option) => ({
946
1034
  id: option.id,
947
- label: /* @__PURE__ */ jsxs4(Fragment4, { children: [
948
- /* @__PURE__ */ jsx5("span", { className: "mst-swatch", style: { background: option.swatch } }),
1035
+ label: /* @__PURE__ */ jsxs5(Fragment4, { children: [
1036
+ /* @__PURE__ */ jsx6("span", { className: "mst-swatch", style: { background: option.swatch } }),
949
1037
  option.label,
950
- theme.preset === option.id && /* @__PURE__ */ jsx5(Icon, { name: "check", size: 13 })
1038
+ theme.preset === option.id && /* @__PURE__ */ jsx6(Icon, { name: "check", size: 13 })
951
1039
  ] }),
952
1040
  onSelect: () => theme.setPreset(option.id)
953
1041
  }));
954
1042
  const schemeLabel = theme.scheme === "system" ? t.schemeSystem : theme.scheme === "light" ? t.schemeLight : t.schemeDark;
955
- return /* @__PURE__ */ jsxs4("header", { className: "mst-header", children: [
956
- /* @__PURE__ */ jsx5("nav", { className: "mst-crumbs", "aria-label": t.breadcrumb, children: crumbs.map((crumb, index) => /* @__PURE__ */ jsxs4("span", { className: "mst-crumbs__item", children: [
957
- index > 0 && /* @__PURE__ */ jsx5(Icon, { name: "chevronRight", size: 12, className: "mst-crumbs__sep" }),
958
- crumb.onClick ? /* @__PURE__ */ jsxs4("button", { type: "button", className: "mst-crumbs__link", onClick: crumb.onClick, children: [
959
- crumb.icon && /* @__PURE__ */ jsx5(Icon, { name: crumb.icon, size: 13 }),
1043
+ return /* @__PURE__ */ jsxs5("header", { className: "mst-header", children: [
1044
+ /* @__PURE__ */ jsx6("nav", { className: "mst-crumbs", "aria-label": t.breadcrumb, children: crumbs.map((crumb, index) => /* @__PURE__ */ jsxs5("span", { className: "mst-crumbs__item", children: [
1045
+ index > 0 && /* @__PURE__ */ jsx6(Icon, { name: "chevronRight", size: 12, className: "mst-crumbs__sep" }),
1046
+ crumb.onClick ? /* @__PURE__ */ jsxs5("button", { type: "button", className: "mst-crumbs__link", onClick: crumb.onClick, children: [
1047
+ crumb.icon && /* @__PURE__ */ jsx6(Icon, { name: crumb.icon, size: 13 }),
960
1048
  crumb.label
961
- ] }) : /* @__PURE__ */ jsxs4("span", { className: "mst-crumbs__now", children: [
962
- crumb.icon && /* @__PURE__ */ jsx5(Icon, { name: crumb.icon, size: 13 }),
1049
+ ] }) : /* @__PURE__ */ jsxs5("span", { className: "mst-crumbs__now", children: [
1050
+ crumb.icon && /* @__PURE__ */ jsx6(Icon, { name: crumb.icon, size: 13 }),
963
1051
  crumb.label
964
1052
  ] })
965
1053
  ] }, `${crumb.label}-${index}`)) }),
966
- /* @__PURE__ */ jsxs4("button", { type: "button", className: "mst-searchchip", onClick: onOpenPalette, children: [
967
- /* @__PURE__ */ jsx5(Icon, { name: "search", size: 13 }),
968
- /* @__PURE__ */ jsx5("span", { children: t.search }),
969
- /* @__PURE__ */ jsx5("kbd", { className: "mst-kbd", children: t.commandKey })
1054
+ /* @__PURE__ */ jsxs5("button", { type: "button", className: "mst-searchchip", onClick: onOpenPalette, children: [
1055
+ /* @__PURE__ */ jsx6(Icon, { name: "search", size: 13 }),
1056
+ /* @__PURE__ */ jsx6("span", { children: t.search }),
1057
+ /* @__PURE__ */ jsx6("kbd", { className: "mst-kbd", children: t.commandKey })
970
1058
  ] }),
971
- theme.picker && /* @__PURE__ */ jsxs4(Fragment4, { children: [
972
- /* @__PURE__ */ jsx5(
1059
+ theme.picker && /* @__PURE__ */ jsxs5(Fragment4, { children: [
1060
+ /* @__PURE__ */ jsx6(
973
1061
  "button",
974
1062
  {
975
1063
  type: "button",
@@ -978,10 +1066,10 @@ function Header({ crumbs, onOpenPalette }) {
978
1066
  "aria-pressed": theme.density === "compact",
979
1067
  className: "mst-iconbtn",
980
1068
  onClick: () => theme.setDensity(theme.density === "compact" ? "comfortable" : "compact"),
981
- children: /* @__PURE__ */ jsx5(Icon, { name: "rows", size: 14 })
1069
+ children: /* @__PURE__ */ jsx6(Icon, { name: "rows", size: 14 })
982
1070
  }
983
1071
  ),
984
- /* @__PURE__ */ jsx5(
1072
+ /* @__PURE__ */ jsx6(
985
1073
  "button",
986
1074
  {
987
1075
  type: "button",
@@ -992,10 +1080,10 @@ function Header({ crumbs, onOpenPalette }) {
992
1080
  const rect = e.currentTarget.getBoundingClientRect();
993
1081
  setAnchor({ x: rect.right - 200, y: rect.bottom + 6 });
994
1082
  },
995
- children: /* @__PURE__ */ jsx5(Icon, { name: "swatch", size: 14 })
1083
+ children: /* @__PURE__ */ jsx6(Icon, { name: "swatch", size: 14 })
996
1084
  }
997
1085
  ),
998
- /* @__PURE__ */ jsx5(
1086
+ /* @__PURE__ */ jsx6(
999
1087
  "button",
1000
1088
  {
1001
1089
  type: "button",
@@ -1003,11 +1091,11 @@ function Header({ crumbs, onOpenPalette }) {
1003
1091
  title: `${t.colorScheme}: ${schemeLabel}`,
1004
1092
  className: "mst-iconbtn",
1005
1093
  onClick: () => theme.setScheme(NEXT_SCHEME[theme.scheme]),
1006
- children: /* @__PURE__ */ jsx5(Icon, { name: SCHEME_ICON[theme.scheme], size: 14 })
1094
+ children: /* @__PURE__ */ jsx6(Icon, { name: SCHEME_ICON[theme.scheme], size: 14 })
1007
1095
  }
1008
1096
  )
1009
1097
  ] }),
1010
- anchor && /* @__PURE__ */ jsx5(PopMenu, { anchor, items: themeItems, onClose: () => setAnchor(void 0) })
1098
+ anchor && /* @__PURE__ */ jsx6(PopMenu, { anchor, items: themeItems, onClose: () => setAnchor(void 0) })
1011
1099
  ] });
1012
1100
  }
1013
1101
 
@@ -1015,7 +1103,7 @@ function Header({ crumbs, onOpenPalette }) {
1015
1103
  import { useMemo as useMemo3 } from "react";
1016
1104
 
1017
1105
  // src/components/ui.tsx
1018
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1106
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1019
1107
  function Button({
1020
1108
  variant = "secondary",
1021
1109
  icon,
@@ -1023,8 +1111,8 @@ function Button({
1023
1111
  children,
1024
1112
  ...props
1025
1113
  }) {
1026
- return /* @__PURE__ */ jsxs5("button", { type: "button", className: `mst-btn mst-btn--${variant} ${className}`.trim(), ...props, children: [
1027
- icon && /* @__PURE__ */ jsx6(Icon, { name: icon, size: 14 }),
1114
+ return /* @__PURE__ */ jsxs6("button", { type: "button", className: `mst-btn mst-btn--${variant} ${className}`.trim(), ...props, children: [
1115
+ icon && /* @__PURE__ */ jsx7(Icon, { name: icon, size: 14 }),
1028
1116
  children
1029
1117
  ] });
1030
1118
  }
@@ -1034,46 +1122,46 @@ function IconButton({
1034
1122
  className = "",
1035
1123
  ...props
1036
1124
  }) {
1037
- return /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": label, title: label, className: `mst-iconbtn ${className}`.trim(), ...props, children: /* @__PURE__ */ jsx6(Icon, { name: icon, size: 14 }) });
1125
+ return /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": label, title: label, className: `mst-iconbtn ${className}`.trim(), ...props, children: /* @__PURE__ */ jsx7(Icon, { name: icon, size: 14 }) });
1038
1126
  }
1039
1127
  function Badge({ children, tone = "neutral", dot = false }) {
1040
1128
  const toneClass = tone === "neutral" ? "" : ` mst-badge--${tone}`;
1041
- return /* @__PURE__ */ jsx6("span", { className: `mst-badge${toneClass}${dot ? " mst-badge--dot" : ""}`, children });
1129
+ return /* @__PURE__ */ jsx7("span", { className: `mst-badge${toneClass}${dot ? " mst-badge--dot" : ""}`, children });
1042
1130
  }
1043
1131
  function Spinner({ label }) {
1044
- return /* @__PURE__ */ jsx6("div", { className: "mst-spinner", role: "status", children: label ?? "Loading\u2026" });
1132
+ return /* @__PURE__ */ jsx7("div", { className: "mst-spinner", role: "status", children: label ?? "Loading\u2026" });
1045
1133
  }
1046
1134
  function EmptyState({ title, hint }) {
1047
- return /* @__PURE__ */ jsxs5("div", { className: "mst-empty", children: [
1048
- /* @__PURE__ */ jsx6("p", { className: "mst-empty__title", children: title }),
1049
- hint && /* @__PURE__ */ jsx6("p", { className: "mst-empty__hint", children: hint })
1135
+ return /* @__PURE__ */ jsxs6("div", { className: "mst-empty", children: [
1136
+ /* @__PURE__ */ jsx7("p", { className: "mst-empty__title", children: title }),
1137
+ hint && /* @__PURE__ */ jsx7("p", { className: "mst-empty__hint", children: hint })
1050
1138
  ] });
1051
1139
  }
1052
1140
  function ErrorBanner({ error }) {
1053
- return /* @__PURE__ */ jsxs5("div", { className: "mst-error", role: "alert", children: [
1054
- /* @__PURE__ */ jsx6(Icon, { name: "alert", size: 15 }),
1055
- /* @__PURE__ */ jsx6("span", { children: error.message })
1141
+ return /* @__PURE__ */ jsxs6("div", { className: "mst-error", role: "alert", children: [
1142
+ /* @__PURE__ */ jsx7(Icon, { name: "alert", size: 15 }),
1143
+ /* @__PURE__ */ jsx7("span", { children: error.message })
1056
1144
  ] });
1057
1145
  }
1058
1146
  function Toast({ children }) {
1059
- return /* @__PURE__ */ jsx6("div", { className: "mst-toast", role: "status", children });
1147
+ return /* @__PURE__ */ jsx7("div", { className: "mst-toast", role: "status", children });
1060
1148
  }
1061
1149
 
1062
1150
  // src/components/Hub.tsx
1063
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1151
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1064
1152
  var CAPS = ["list", "create", "update", "delete"];
1065
1153
  function EntityCard({ entity, onOpen }) {
1066
1154
  const t = useT();
1067
1155
  const capLabel = { list: t.capRead, create: t.capCreate, update: t.capUpdate, delete: t.capDelete };
1068
- return /* @__PURE__ */ jsxs6("button", { type: "button", className: "mst-ecard", onClick: () => onOpen(entity.id), children: [
1069
- /* @__PURE__ */ jsx7("span", { className: "mst-ecard__tile", children: /* @__PURE__ */ jsx7(Icon, { name: entityIcon(entity), size: 16 }) }),
1070
- /* @__PURE__ */ jsxs6("span", { className: "mst-ecard__body", children: [
1071
- /* @__PURE__ */ jsx7("span", { className: "mst-ecard__name", children: entity.label.plural }),
1072
- /* @__PURE__ */ jsx7("span", { className: "mst-ecard__desc", children: entity.description ?? t.fieldCount(entity.fields.length) }),
1073
- /* @__PURE__ */ jsx7("span", { className: "mst-caps", children: CAPS.map((cap) => /* @__PURE__ */ jsx7("span", { className: "mst-cap", "data-on": String(entity.capabilities[cap]), children: capLabel[cap] }, cap)) }),
1074
- /* @__PURE__ */ jsxs6("span", { className: "mst-source", children: [
1075
- /* @__PURE__ */ jsx7(Icon, { name: "database", size: 11 }),
1076
- /* @__PURE__ */ jsxs6("span", { children: [
1156
+ return /* @__PURE__ */ jsxs7("button", { type: "button", className: "mst-ecard", onClick: () => onOpen(entity.id), children: [
1157
+ /* @__PURE__ */ jsx8("span", { className: "mst-ecard__tile", children: /* @__PURE__ */ jsx8(Icon, { name: entityIcon(entity), size: 16 }) }),
1158
+ /* @__PURE__ */ jsxs7("span", { className: "mst-ecard__body", children: [
1159
+ /* @__PURE__ */ jsx8("span", { className: "mst-ecard__name", children: entity.label.plural }),
1160
+ /* @__PURE__ */ jsx8("span", { className: "mst-ecard__desc", children: entity.description ?? t.fieldCount(entity.fields.length) }),
1161
+ /* @__PURE__ */ jsx8("span", { className: "mst-caps", children: CAPS.map((cap) => /* @__PURE__ */ jsx8("span", { className: "mst-cap", "data-on": String(entity.capabilities[cap]), children: capLabel[cap] }, cap)) }),
1162
+ /* @__PURE__ */ jsxs7("span", { className: "mst-source", children: [
1163
+ /* @__PURE__ */ jsx8(Icon, { name: "database", size: 11 }),
1164
+ /* @__PURE__ */ jsxs7("span", { children: [
1077
1165
  entity.datasource,
1078
1166
  " \xB7 ",
1079
1167
  entity.table
@@ -1091,30 +1179,30 @@ function Hub({
1091
1179
  const menu = useMemo3(() => buildMenu(entities, labels), [entities, labels]);
1092
1180
  const sources = useMemo3(() => new Set(entities.map((e) => e.datasource)).size, [entities]);
1093
1181
  if (entities.length === 0) {
1094
- return /* @__PURE__ */ jsx7(EmptyState, { title: t.noEntities, hint: t.noEntitiesHint });
1182
+ return /* @__PURE__ */ jsx8(EmptyState, { title: t.noEntities, hint: t.noEntitiesHint });
1095
1183
  }
1096
- return /* @__PURE__ */ jsxs6("section", { className: "mst-page", children: [
1097
- /* @__PURE__ */ jsx7("div", { className: "mst-pagehead", children: /* @__PURE__ */ jsxs6("div", { children: [
1098
- /* @__PURE__ */ jsx7("h1", { className: "mst-pagehead__title", children: t.entities }),
1099
- /* @__PURE__ */ jsx7("p", { className: "mst-pagehead__meta", children: t.hubMeta(entities.length, sources) })
1184
+ return /* @__PURE__ */ jsxs7("section", { className: "mst-page", children: [
1185
+ /* @__PURE__ */ jsx8("div", { className: "mst-pagehead", children: /* @__PURE__ */ jsxs7("div", { children: [
1186
+ /* @__PURE__ */ jsx8("h1", { className: "mst-pagehead__title", children: t.entities }),
1187
+ /* @__PURE__ */ jsx8("p", { className: "mst-pagehead__meta", children: t.hubMeta(entities.length, sources) })
1100
1188
  ] }) }),
1101
- /* @__PURE__ */ jsxs6("div", { className: "mst-hub", children: [
1102
- menu.groups.map((group) => /* @__PURE__ */ jsxs6("div", { children: [
1103
- /* @__PURE__ */ jsx7("p", { className: "mst-grouplabel", children: group.label }),
1104
- /* @__PURE__ */ jsx7("div", { className: "mst-cards", children: group.entities.map((entity) => /* @__PURE__ */ jsx7(EntityCard, { entity, onOpen }, entity.id)) })
1189
+ /* @__PURE__ */ jsxs7("div", { className: "mst-hub", children: [
1190
+ menu.groups.map((group) => /* @__PURE__ */ jsxs7("div", { children: [
1191
+ /* @__PURE__ */ jsx8("p", { className: "mst-grouplabel", children: group.label }),
1192
+ /* @__PURE__ */ jsx8("div", { className: "mst-cards", children: group.entities.map((entity) => /* @__PURE__ */ jsx8(EntityCard, { entity, onOpen }, entity.id)) })
1105
1193
  ] }, group.id)),
1106
- menu.ungrouped.length > 0 && /* @__PURE__ */ jsxs6("div", { children: [
1107
- menu.groups.length > 0 && /* @__PURE__ */ jsx7("p", { className: "mst-grouplabel", children: t.otherEntities }),
1108
- /* @__PURE__ */ jsx7("div", { className: "mst-cards", children: menu.ungrouped.map((entity) => /* @__PURE__ */ jsx7(EntityCard, { entity, onOpen }, entity.id)) })
1194
+ menu.ungrouped.length > 0 && /* @__PURE__ */ jsxs7("div", { children: [
1195
+ menu.groups.length > 0 && /* @__PURE__ */ jsx8("p", { className: "mst-grouplabel", children: t.otherEntities }),
1196
+ /* @__PURE__ */ jsx8("div", { className: "mst-cards", children: menu.ungrouped.map((entity) => /* @__PURE__ */ jsx8(EntityCard, { entity, onOpen }, entity.id)) })
1109
1197
  ] })
1110
1198
  ] })
1111
1199
  ] });
1112
1200
  }
1113
1201
 
1114
1202
  // src/components/CommandPalette.tsx
1115
- import { useEffect as useEffect3, useMemo as useMemo4, useRef as useRef2, useState as useState6 } from "react";
1203
+ import { useEffect as useEffect4, useMemo as useMemo4, useRef as useRef3, useState as useState6 } from "react";
1116
1204
  import { createPortal as createPortal2 } from "react-dom";
1117
- import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1205
+ import { Fragment as Fragment5, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1118
1206
  function normalize2(text) {
1119
1207
  return text.toLowerCase().normalize("NFD").replace(/\p{M}/gu, "");
1120
1208
  }
@@ -1123,9 +1211,9 @@ function Highlight2({ label, query }) {
1123
1211
  const folded = normalize2(label);
1124
1212
  const idx = folded.indexOf(normalize2(query));
1125
1213
  if (idx === -1) return label;
1126
- return /* @__PURE__ */ jsxs7(Fragment5, { children: [
1214
+ return /* @__PURE__ */ jsxs8(Fragment5, { children: [
1127
1215
  label.slice(0, idx),
1128
- /* @__PURE__ */ jsx8("mark", { children: label.slice(idx, idx + query.length) }),
1216
+ /* @__PURE__ */ jsx9("mark", { children: label.slice(idx, idx + query.length) }),
1129
1217
  label.slice(idx + query.length)
1130
1218
  ] });
1131
1219
  }
@@ -1142,8 +1230,8 @@ function entityCommands(entities, groupOf, onSelect) {
1142
1230
  function CommandPalette({ sections, onClose }) {
1143
1231
  const t = useT();
1144
1232
  const root = useAdminRoot();
1145
- const inputRef = useRef2(null);
1146
- const listRef = useRef2(null);
1233
+ const inputRef = useRef3(null);
1234
+ const listRef = useRef3(null);
1147
1235
  const [query, setQuery] = useState6("");
1148
1236
  const [cursor, setCursor] = useState6(0);
1149
1237
  const visible = useMemo4(() => {
@@ -1156,9 +1244,9 @@ function CommandPalette({ sections, onClose }) {
1156
1244
  }, [sections, query]);
1157
1245
  const flat = useMemo4(() => visible.flatMap((section) => section.commands), [visible]);
1158
1246
  const active = flat[Math.min(cursor, flat.length - 1)];
1159
- useEffect3(() => setCursor(0), [query]);
1160
- useEffect3(() => inputRef.current?.focus(), []);
1161
- useEffect3(() => {
1247
+ useEffect4(() => setCursor(0), [query]);
1248
+ useEffect4(() => inputRef.current?.focus(), []);
1249
+ useEffect4(() => {
1162
1250
  listRef.current?.querySelector('[data-active="true"]')?.scrollIntoView({ block: "nearest" });
1163
1251
  }, [cursor, query]);
1164
1252
  const onKeyDown = (e) => {
@@ -1184,7 +1272,7 @@ function CommandPalette({ sections, onClose }) {
1184
1272
  }
1185
1273
  };
1186
1274
  return createPortal2(
1187
- /* @__PURE__ */ jsx8(
1275
+ /* @__PURE__ */ jsx9(
1188
1276
  "div",
1189
1277
  {
1190
1278
  className: "mst-overlay",
@@ -1192,10 +1280,10 @@ function CommandPalette({ sections, onClose }) {
1192
1280
  onMouseDown: (e) => {
1193
1281
  if (e.target === e.currentTarget) onClose();
1194
1282
  },
1195
- children: /* @__PURE__ */ jsxs7("div", { className: "mst-palette", role: "dialog", "aria-modal": "true", "aria-label": t.commandPalette, children: [
1196
- /* @__PURE__ */ jsxs7("div", { className: "mst-palette__input", children: [
1197
- /* @__PURE__ */ jsx8(Icon, { name: "search", size: 15 }),
1198
- /* @__PURE__ */ jsx8(
1283
+ children: /* @__PURE__ */ jsxs8("div", { className: "mst-palette", role: "dialog", "aria-modal": "true", "aria-label": t.commandPalette, children: [
1284
+ /* @__PURE__ */ jsxs8("div", { className: "mst-palette__input", children: [
1285
+ /* @__PURE__ */ jsx9(Icon, { name: "search", size: 15 }),
1286
+ /* @__PURE__ */ jsx9(
1199
1287
  "input",
1200
1288
  {
1201
1289
  ref: inputRef,
@@ -1207,11 +1295,11 @@ function CommandPalette({ sections, onClose }) {
1207
1295
  onKeyDown
1208
1296
  }
1209
1297
  ),
1210
- /* @__PURE__ */ jsx8("kbd", { className: "mst-kbd", children: "esc" })
1298
+ /* @__PURE__ */ jsx9("kbd", { className: "mst-kbd", children: "esc" })
1211
1299
  ] }),
1212
- /* @__PURE__ */ jsx8("div", { className: "mst-palette__list", ref: listRef, children: flat.length === 0 ? /* @__PURE__ */ jsx8("p", { className: "mst-palette__empty", children: t.noMenuResults }) : visible.map((section) => /* @__PURE__ */ jsxs7("div", { children: [
1213
- /* @__PURE__ */ jsx8("p", { className: "mst-palette__section", children: section.label }),
1214
- section.commands.map((command) => /* @__PURE__ */ jsxs7(
1300
+ /* @__PURE__ */ jsx9("div", { className: "mst-palette__list", ref: listRef, children: flat.length === 0 ? /* @__PURE__ */ jsx9("p", { className: "mst-palette__empty", children: t.noMenuResults }) : visible.map((section) => /* @__PURE__ */ jsxs8("div", { children: [
1301
+ /* @__PURE__ */ jsx9("p", { className: "mst-palette__section", children: section.label }),
1302
+ section.commands.map((command) => /* @__PURE__ */ jsxs8(
1215
1303
  "button",
1216
1304
  {
1217
1305
  type: "button",
@@ -1223,9 +1311,9 @@ function CommandPalette({ sections, onClose }) {
1223
1311
  command.run();
1224
1312
  },
1225
1313
  children: [
1226
- command.icon && /* @__PURE__ */ jsx8(Icon, { name: command.icon, size: 14 }),
1227
- /* @__PURE__ */ jsx8("span", { className: "mst-palette__label", children: /* @__PURE__ */ jsx8(Highlight2, { label: command.label, query }) }),
1228
- command.hint && /* @__PURE__ */ jsx8("span", { className: "mst-palette__hint", children: command.hint })
1314
+ command.icon && /* @__PURE__ */ jsx9(Icon, { name: command.icon, size: 14 }),
1315
+ /* @__PURE__ */ jsx9("span", { className: "mst-palette__label", children: /* @__PURE__ */ jsx9(Highlight2, { label: command.label, query }) }),
1316
+ command.hint && /* @__PURE__ */ jsx9("span", { className: "mst-palette__hint", children: command.hint })
1229
1317
  ]
1230
1318
  },
1231
1319
  command.id
@@ -1297,8 +1385,8 @@ function useColumnPrefs(entity, max = 6) {
1297
1385
  }
1298
1386
 
1299
1387
  // src/components/RelationValue.tsx
1300
- import { useEffect as useEffect4, useState as useState8 } from "react";
1301
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1388
+ import { useEffect as useEffect5, useState as useState8 } from "react";
1389
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1302
1390
  var displayCache = /* @__PURE__ */ new Map();
1303
1391
  function resolveDisplay(client, entityId, displayField, id) {
1304
1392
  const key = `${entityId}/${id}`;
@@ -1320,7 +1408,7 @@ function RelationValue({ field, value }) {
1320
1408
  const target = useEntity(field.relationEntity);
1321
1409
  const id = String(value);
1322
1410
  const [display, setDisplay] = useState8(void 0);
1323
- useEffect4(() => {
1411
+ useEffect5(() => {
1324
1412
  let cancelled = false;
1325
1413
  setDisplay(void 0);
1326
1414
  if (!target || target.displayField === target.primaryKey) return;
@@ -1331,17 +1419,17 @@ function RelationValue({ field, value }) {
1331
1419
  cancelled = true;
1332
1420
  };
1333
1421
  }, [client, target, id]);
1334
- return /* @__PURE__ */ jsxs8("span", { title: id, className: "mst-relation", children: [
1335
- target && /* @__PURE__ */ jsxs8("span", { className: "mst-subtle", children: [
1422
+ return /* @__PURE__ */ jsxs9("span", { title: id, className: "mst-relation", children: [
1423
+ target && /* @__PURE__ */ jsxs9("span", { className: "mst-subtle", children: [
1336
1424
  target.label.singular,
1337
1425
  ":"
1338
1426
  ] }),
1339
- /* @__PURE__ */ jsx9("span", { className: "mst-relation__label", children: display ?? shortId(id) })
1427
+ /* @__PURE__ */ jsx10("span", { className: "mst-relation__label", children: display ?? shortId(id) })
1340
1428
  ] });
1341
1429
  }
1342
1430
 
1343
1431
  // src/components/ObjectValue.tsx
1344
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1432
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
1345
1433
  var ISO_DATETIME = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/;
1346
1434
  var MAX_DEPTH = 4;
1347
1435
  function isPlainObject(value) {
@@ -1349,40 +1437,40 @@ function isPlainObject(value) {
1349
1437
  }
1350
1438
  function Primitive({ value }) {
1351
1439
  if (value === null || value === void 0) {
1352
- return /* @__PURE__ */ jsx10("span", { className: "mst-subtle", children: "\u2014" });
1440
+ return /* @__PURE__ */ jsx11("span", { className: "mst-subtle", children: "\u2014" });
1353
1441
  }
1354
1442
  if (typeof value === "boolean" || typeof value === "number") {
1355
- return /* @__PURE__ */ jsx10("code", { className: "mst-mono", style: { color: "var(--maestro-brand)" }, children: String(value) });
1443
+ return /* @__PURE__ */ jsx11("code", { className: "mst-mono", style: { color: "var(--maestro-brand)" }, children: String(value) });
1356
1444
  }
1357
1445
  const text = String(value);
1358
1446
  if (ISO_DATETIME.test(text)) {
1359
1447
  const d = new Date(text);
1360
1448
  if (!Number.isNaN(d.getTime())) {
1361
- return /* @__PURE__ */ jsx10("span", { className: "mst-nums", children: d.toLocaleString() });
1449
+ return /* @__PURE__ */ jsx11("span", { className: "mst-nums", children: d.toLocaleString() });
1362
1450
  }
1363
1451
  }
1364
- return /* @__PURE__ */ jsx10("span", { style: { overflowWrap: "anywhere" }, children: text });
1452
+ return /* @__PURE__ */ jsx11("span", { style: { overflowWrap: "anywhere" }, children: text });
1365
1453
  }
1366
1454
  function ObjectValue({ value, depth = 0 }) {
1367
1455
  const t = useT();
1368
1456
  if (!isPlainObject(value) && !Array.isArray(value)) {
1369
- return /* @__PURE__ */ jsx10(Primitive, { value });
1457
+ return /* @__PURE__ */ jsx11(Primitive, { value });
1370
1458
  }
1371
1459
  if (depth >= MAX_DEPTH) {
1372
- return /* @__PURE__ */ jsx10("code", { className: "mst-code mst-code--block", children: JSON.stringify(value) });
1460
+ return /* @__PURE__ */ jsx11("code", { className: "mst-code mst-code--block", children: JSON.stringify(value) });
1373
1461
  }
1374
1462
  const entries = Array.isArray(value) ? value.map((v, i) => [String(i), v]) : Object.entries(value);
1375
1463
  if (entries.length === 0) {
1376
- return /* @__PURE__ */ jsx10("span", { className: "mst-subtle", children: t.emptyObject });
1464
+ return /* @__PURE__ */ jsx11("span", { className: "mst-subtle", children: t.emptyObject });
1377
1465
  }
1378
- return /* @__PURE__ */ jsx10("dl", { className: depth === 0 ? "mst-objectvalue mst-objectvalue--root" : "mst-objectvalue mst-objectvalue--nested", children: entries.map(([key, entry]) => /* @__PURE__ */ jsxs9("div", { className: "mst-objectvalue__row", children: [
1379
- /* @__PURE__ */ jsx10("dt", { className: "mst-objectvalue__key", title: key, children: key }),
1380
- /* @__PURE__ */ jsx10("dd", { className: "mst-objectvalue__val", children: isPlainObject(entry) || Array.isArray(entry) ? /* @__PURE__ */ jsx10(ObjectValue, { value: entry, depth: depth + 1 }) : /* @__PURE__ */ jsx10(Primitive, { value: entry }) })
1466
+ return /* @__PURE__ */ jsx11("dl", { className: depth === 0 ? "mst-objectvalue mst-objectvalue--root" : "mst-objectvalue mst-objectvalue--nested", children: entries.map(([key, entry]) => /* @__PURE__ */ jsxs10("div", { className: "mst-objectvalue__row", children: [
1467
+ /* @__PURE__ */ jsx11("dt", { className: "mst-objectvalue__key", title: key, children: key }),
1468
+ /* @__PURE__ */ jsx11("dd", { className: "mst-objectvalue__val", children: isPlainObject(entry) || Array.isArray(entry) ? /* @__PURE__ */ jsx11(ObjectValue, { value: entry, depth: depth + 1 }) : /* @__PURE__ */ jsx11(Primitive, { value: entry }) })
1381
1469
  ] }, key)) });
1382
1470
  }
1383
1471
 
1384
1472
  // src/components/FieldValue.tsx
1385
- import { jsx as jsx11 } from "react/jsx-runtime";
1473
+ import { jsx as jsx12 } from "react/jsx-runtime";
1386
1474
  function enumLabel(field, value) {
1387
1475
  const opt = field.enumOptions?.find((o) => o.value === value);
1388
1476
  return opt ? opt.label : String(value);
@@ -1390,39 +1478,39 @@ function enumLabel(field, value) {
1390
1478
  function FieldValue({ field, value, compact = false }) {
1391
1479
  const t = useT();
1392
1480
  if (value === null || value === void 0 || value === "") {
1393
- return /* @__PURE__ */ jsx11("span", { className: "mst-subtle", children: "\u2014" });
1481
+ return /* @__PURE__ */ jsx12("span", { className: "mst-subtle", children: "\u2014" });
1394
1482
  }
1395
1483
  if (field.sensitive) {
1396
- return /* @__PURE__ */ jsx11("span", { className: "mst-subtle", children: "\u2022\u2022\u2022\u2022\u2022\u2022" });
1484
+ return /* @__PURE__ */ jsx12("span", { className: "mst-subtle", children: "\u2022\u2022\u2022\u2022\u2022\u2022" });
1397
1485
  }
1398
1486
  switch (field.type) {
1399
1487
  case "boolean":
1400
- return value ? /* @__PURE__ */ jsx11(Badge, { tone: "ok", dot: true, children: t.yes }) : /* @__PURE__ */ jsx11(Badge, { dot: true, children: t.no });
1488
+ return value ? /* @__PURE__ */ jsx12(Badge, { tone: "ok", dot: true, children: t.yes }) : /* @__PURE__ */ jsx12(Badge, { dot: true, children: t.no });
1401
1489
  case "enum":
1402
- return /* @__PURE__ */ jsx11(Badge, { tone: "brand", children: enumLabel(field, value) });
1490
+ return /* @__PURE__ */ jsx12(Badge, { tone: "brand", children: enumLabel(field, value) });
1403
1491
  case "relation":
1404
- return field.relationEntity ? /* @__PURE__ */ jsx11(RelationValue, { field, value }) : /* @__PURE__ */ jsx11("span", { children: String(value) });
1492
+ return field.relationEntity ? /* @__PURE__ */ jsx12(RelationValue, { field, value }) : /* @__PURE__ */ jsx12("span", { children: String(value) });
1405
1493
  case "date":
1406
1494
  case "datetime": {
1407
1495
  const d = new Date(String(value));
1408
- return /* @__PURE__ */ jsx11("span", { className: "mst-nums", children: Number.isNaN(d.getTime()) ? String(value) : d.toLocaleString() });
1496
+ return /* @__PURE__ */ jsx12("span", { className: "mst-nums", children: Number.isNaN(d.getTime()) ? String(value) : d.toLocaleString() });
1409
1497
  }
1410
1498
  case "integer":
1411
1499
  case "float":
1412
1500
  case "number":
1413
1501
  case "decimal":
1414
1502
  case "currency":
1415
- return /* @__PURE__ */ jsx11("span", { className: "mst-nums", children: String(value) });
1503
+ return /* @__PURE__ */ jsx12("span", { className: "mst-nums", children: String(value) });
1416
1504
  case "json":
1417
1505
  if (compact) {
1418
- return /* @__PURE__ */ jsx11("code", { className: "mst-code", children: JSON.stringify(value) });
1506
+ return /* @__PURE__ */ jsx12("code", { className: "mst-code", children: JSON.stringify(value) });
1419
1507
  }
1420
1508
  if (typeof value === "object") {
1421
- return /* @__PURE__ */ jsx11(ObjectValue, { value });
1509
+ return /* @__PURE__ */ jsx12(ObjectValue, { value });
1422
1510
  }
1423
- return /* @__PURE__ */ jsx11("code", { className: "mst-code mst-code--block", children: JSON.stringify(value) });
1511
+ return /* @__PURE__ */ jsx12("code", { className: "mst-code mst-code--block", children: JSON.stringify(value) });
1424
1512
  default:
1425
- return /* @__PURE__ */ jsx11("span", { children: String(value) });
1513
+ return /* @__PURE__ */ jsx12("span", { children: String(value) });
1426
1514
  }
1427
1515
  }
1428
1516
 
@@ -1446,7 +1534,7 @@ async function copyText(text) {
1446
1534
  }
1447
1535
 
1448
1536
  // src/components/EntityList.tsx
1449
- import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
1537
+ import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
1450
1538
  var PAGE_SIZE = 20;
1451
1539
  var ACTIONS_COLUMN_WIDTH = 44;
1452
1540
  function filterFor(field, value) {
@@ -1596,15 +1684,15 @@ function EntityList({
1596
1684
  const totalPages = data?.totalPages ?? (data ? Math.max(1, Math.ceil(data.total / PAGE_SIZE)) : 1);
1597
1685
  const firstRow = data && data.total > 0 ? (page - 1) * PAGE_SIZE + 1 : 0;
1598
1686
  const lastRow = data ? Math.min(page * PAGE_SIZE, data.total) : 0;
1599
- return /* @__PURE__ */ jsxs10("section", { className: "mst-page mst-page--fill", children: [
1600
- /* @__PURE__ */ jsxs10("div", { className: "mst-pagehead", children: [
1601
- /* @__PURE__ */ jsxs10("div", { children: [
1602
- /* @__PURE__ */ jsx12("h1", { className: "mst-pagehead__title", children: entity.label.plural }),
1603
- /* @__PURE__ */ jsxs10("p", { className: "mst-pagehead__meta", children: [
1604
- data && /* @__PURE__ */ jsx12("span", { className: "mst-nums", children: t.records(data.total) }),
1605
- /* @__PURE__ */ jsxs10("span", { className: "mst-source", children: [
1606
- /* @__PURE__ */ jsx12(Icon, { name: "database", size: 11 }),
1607
- /* @__PURE__ */ jsxs10("span", { children: [
1687
+ return /* @__PURE__ */ jsxs11("section", { className: "mst-page mst-page--fill", children: [
1688
+ /* @__PURE__ */ jsxs11("div", { className: "mst-pagehead", children: [
1689
+ /* @__PURE__ */ jsxs11("div", { children: [
1690
+ /* @__PURE__ */ jsx13("h1", { className: "mst-pagehead__title", children: entity.label.plural }),
1691
+ /* @__PURE__ */ jsxs11("p", { className: "mst-pagehead__meta", children: [
1692
+ data && /* @__PURE__ */ jsx13("span", { className: "mst-nums", children: t.records(data.total) }),
1693
+ /* @__PURE__ */ jsxs11("span", { className: "mst-source", children: [
1694
+ /* @__PURE__ */ jsx13(Icon, { name: "database", size: 11 }),
1695
+ /* @__PURE__ */ jsxs11("span", { children: [
1608
1696
  entity.datasource,
1609
1697
  " \xB7 ",
1610
1698
  entity.table
@@ -1612,8 +1700,8 @@ function EntityList({
1612
1700
  ] })
1613
1701
  ] })
1614
1702
  ] }),
1615
- /* @__PURE__ */ jsxs10("div", { className: "mst-pagehead__actions", children: [
1616
- searchFields.length > 0 && /* @__PURE__ */ jsx12(
1703
+ /* @__PURE__ */ jsxs11("div", { className: "mst-pagehead__actions", children: [
1704
+ searchFields.length > 0 && /* @__PURE__ */ jsx13(
1617
1705
  "input",
1618
1706
  {
1619
1707
  type: "search",
@@ -1626,7 +1714,7 @@ function EntityList({
1626
1714
  }
1627
1715
  }
1628
1716
  ),
1629
- /* @__PURE__ */ jsxs10(
1717
+ /* @__PURE__ */ jsxs11(
1630
1718
  Button,
1631
1719
  {
1632
1720
  icon: "columns",
@@ -1637,15 +1725,15 @@ function EntityList({
1637
1725
  children: [
1638
1726
  t.columns,
1639
1727
  " ",
1640
- /* @__PURE__ */ jsx12("span", { className: "mst-subtle mst-nums", children: t.columnsCount(columns.length, columnPrefs.available.length) })
1728
+ /* @__PURE__ */ jsx13("span", { className: "mst-subtle mst-nums", children: t.columnsCount(columns.length, columnPrefs.available.length) })
1641
1729
  ]
1642
1730
  }
1643
1731
  ),
1644
- entity.capabilities.create && /* @__PURE__ */ jsx12(Button, { variant: "primary", icon: "plus", onClick: onCreate, children: t.newRecord })
1732
+ entity.capabilities.create && /* @__PURE__ */ jsx13(Button, { variant: "primary", icon: "plus", onClick: onCreate, children: t.newRecord })
1645
1733
  ] })
1646
1734
  ] }),
1647
- filters.length > 0 && /* @__PURE__ */ jsxs10("div", { className: "mst-chips", children: [
1648
- filters.map((f) => /* @__PURE__ */ jsxs10(
1735
+ filters.length > 0 && /* @__PURE__ */ jsxs11("div", { className: "mst-chips", children: [
1736
+ filters.map((f) => /* @__PURE__ */ jsxs11(
1649
1737
  "button",
1650
1738
  {
1651
1739
  type: "button",
@@ -1657,12 +1745,12 @@ function EntityList({
1657
1745
  },
1658
1746
  children: [
1659
1747
  filterChipText(entity, f),
1660
- /* @__PURE__ */ jsx12(Icon, { name: "close", size: 11 })
1748
+ /* @__PURE__ */ jsx13(Icon, { name: "close", size: 11 })
1661
1749
  ]
1662
1750
  },
1663
1751
  f.field
1664
1752
  )),
1665
- /* @__PURE__ */ jsx12(
1753
+ /* @__PURE__ */ jsx13(
1666
1754
  "button",
1667
1755
  {
1668
1756
  type: "button",
@@ -1675,34 +1763,34 @@ function EntityList({
1675
1763
  }
1676
1764
  )
1677
1765
  ] }),
1678
- error && /* @__PURE__ */ jsx12(ErrorBanner, { error }),
1679
- loading && !data ? /* @__PURE__ */ jsx12(Spinner, { label: t.loading }) : data && data.records.length === 0 ? /* @__PURE__ */ jsx12(EmptyState, { title: t.noRecords, hint: search || filters.length ? t.tryDifferentSearch : void 0 }) : /* @__PURE__ */ jsxs10("div", { className: "mst-card mst-tablewrap", children: [
1680
- /* @__PURE__ */ jsx12("div", { className: "mst-tablescroll", children: /* @__PURE__ */ jsxs10("table", { className: "mst-table", children: [
1681
- /* @__PURE__ */ jsx12("thead", { children: /* @__PURE__ */ jsxs10("tr", { children: [
1682
- columns.map((f) => /* @__PURE__ */ jsx12(
1766
+ error && /* @__PURE__ */ jsx13(ErrorBanner, { error }),
1767
+ loading && !data ? /* @__PURE__ */ jsx13(Spinner, { label: t.loading }) : data && data.records.length === 0 ? /* @__PURE__ */ jsx13(EmptyState, { title: t.noRecords, hint: search || filters.length ? t.tryDifferentSearch : void 0 }) : /* @__PURE__ */ jsxs11("div", { className: "mst-card mst-tablewrap", children: [
1768
+ /* @__PURE__ */ jsx13("div", { className: "mst-tablescroll", children: /* @__PURE__ */ jsxs11("table", { className: "mst-table", children: [
1769
+ /* @__PURE__ */ jsx13("thead", { children: /* @__PURE__ */ jsxs11("tr", { children: [
1770
+ columns.map((f) => /* @__PURE__ */ jsx13(
1683
1771
  "th",
1684
1772
  {
1685
1773
  style: { width: f.list.width, textAlign: f.list.align },
1686
1774
  "aria-sort": sort?.field === f.name ? sort.direction === "asc" ? "ascending" : "descending" : "none",
1687
- children: f.sortable ? /* @__PURE__ */ jsxs10("button", { type: "button", className: "mst-th__button", onClick: () => toggleSort(f.name), children: [
1688
- /* @__PURE__ */ jsx12("span", { className: "mst-th__label", children: f.label }),
1689
- /* @__PURE__ */ jsx12(
1775
+ children: f.sortable ? /* @__PURE__ */ jsxs11("button", { type: "button", className: "mst-th__button", onClick: () => toggleSort(f.name), children: [
1776
+ /* @__PURE__ */ jsx13("span", { className: "mst-th__label", children: f.label }),
1777
+ /* @__PURE__ */ jsx13(
1690
1778
  Icon,
1691
1779
  {
1692
1780
  name: sort?.field === f.name ? sort.direction === "asc" ? "sortAsc" : "sortDesc" : "sort",
1693
1781
  size: 11
1694
1782
  }
1695
1783
  )
1696
- ] }) : /* @__PURE__ */ jsx12("span", { className: "mst-th__label", children: f.label })
1784
+ ] }) : /* @__PURE__ */ jsx13("span", { className: "mst-th__label", children: f.label })
1697
1785
  },
1698
1786
  f.name
1699
1787
  )),
1700
- /* @__PURE__ */ jsx12("th", { style: { width: ACTIONS_COLUMN_WIDTH }, children: /* @__PURE__ */ jsx12("span", { className: "mst-sr-only", children: t.actions }) })
1788
+ /* @__PURE__ */ jsx13("th", { style: { width: ACTIONS_COLUMN_WIDTH }, children: /* @__PURE__ */ jsx13("span", { className: "mst-sr-only", children: t.actions }) })
1701
1789
  ] }) }),
1702
- /* @__PURE__ */ jsx12("tbody", { children: data?.records.map((record, i) => {
1790
+ /* @__PURE__ */ jsx13("tbody", { children: data?.records.map((record, i) => {
1703
1791
  const id = String(record[entity.primaryKey]);
1704
- return /* @__PURE__ */ jsxs10("tr", { children: [
1705
- columns.map((f) => /* @__PURE__ */ jsx12(
1792
+ return /* @__PURE__ */ jsxs11("tr", { children: [
1793
+ columns.map((f) => /* @__PURE__ */ jsx13(
1706
1794
  "td",
1707
1795
  {
1708
1796
  className: "mst-table__cell",
@@ -1710,46 +1798,46 @@ function EntityList({
1710
1798
  title: f.label,
1711
1799
  onClick: (e) => setCellMenu({ anchor: { x: e.clientX, y: e.clientY }, field: f, record }),
1712
1800
  onDoubleClick: () => onOpen(id),
1713
- children: /* @__PURE__ */ jsx12(FieldValue, { field: f, value: record[f.name], compact: true })
1801
+ children: /* @__PURE__ */ jsx13(FieldValue, { field: f, value: record[f.name], compact: true })
1714
1802
  },
1715
1803
  f.name
1716
1804
  )),
1717
- /* @__PURE__ */ jsx12("td", { className: "mst-td--actions", children: /* @__PURE__ */ jsx12(MenuButton, { label: t.actions, items: rowMenuItems(record) }) })
1805
+ /* @__PURE__ */ jsx13("td", { className: "mst-td--actions", children: /* @__PURE__ */ jsx13(MenuButton, { label: t.actions, items: rowMenuItems(record) }) })
1718
1806
  ] }, id || i);
1719
1807
  }) })
1720
1808
  ] }) }),
1721
- data && /* @__PURE__ */ jsxs10("div", { className: "mst-pagination", children: [
1722
- /* @__PURE__ */ jsxs10("span", { className: "mst-nums", children: [
1809
+ data && /* @__PURE__ */ jsxs11("div", { className: "mst-pagination", children: [
1810
+ /* @__PURE__ */ jsxs11("span", { className: "mst-nums", children: [
1723
1811
  firstRow,
1724
1812
  "\u2013",
1725
1813
  lastRow
1726
1814
  ] }),
1727
- /* @__PURE__ */ jsx12("span", { children: t.records(data.total) }),
1728
- totalPages > 1 && /* @__PURE__ */ jsxs10("span", { className: "mst-pagination__nums", children: [
1729
- /* @__PURE__ */ jsx12("button", { type: "button", "aria-label": t.previous, disabled: page <= 1, onClick: () => setPage((p) => p - 1), children: /* @__PURE__ */ jsx12(Icon, { name: "chevronLeft", size: 13 }) }),
1730
- pageWindow(page, totalPages).map((p) => /* @__PURE__ */ jsx12("button", { type: "button", "aria-current": p === page, onClick: () => setPage(p), children: p }, p)),
1731
- /* @__PURE__ */ jsx12(
1815
+ /* @__PURE__ */ jsx13("span", { children: t.records(data.total) }),
1816
+ totalPages > 1 && /* @__PURE__ */ jsxs11("span", { className: "mst-pagination__nums", children: [
1817
+ /* @__PURE__ */ jsx13("button", { type: "button", "aria-label": t.previous, disabled: page <= 1, onClick: () => setPage((p) => p - 1), children: /* @__PURE__ */ jsx13(Icon, { name: "chevronLeft", size: 13 }) }),
1818
+ pageWindow(page, totalPages).map((p) => /* @__PURE__ */ jsx13("button", { type: "button", "aria-current": p === page, onClick: () => setPage(p), children: p }, p)),
1819
+ /* @__PURE__ */ jsx13(
1732
1820
  "button",
1733
1821
  {
1734
1822
  type: "button",
1735
1823
  "aria-label": t.next,
1736
1824
  disabled: page >= totalPages,
1737
1825
  onClick: () => setPage((p) => p + 1),
1738
- children: /* @__PURE__ */ jsx12(Icon, { name: "chevronRight", size: 13 })
1826
+ children: /* @__PURE__ */ jsx13(Icon, { name: "chevronRight", size: 13 })
1739
1827
  }
1740
1828
  )
1741
1829
  ] })
1742
1830
  ] })
1743
1831
  ] }),
1744
- cellMenu && /* @__PURE__ */ jsx12(PopMenu, { anchor: cellMenu.anchor, items: cellMenuItems(cellMenu), onClose: () => setCellMenu(void 0) }),
1745
- columnMenu && /* @__PURE__ */ jsx12(PopMenu, { anchor: columnMenu, items: columnMenuItems, onClose: () => setColumnMenu(void 0) }),
1746
- copied && /* @__PURE__ */ jsx12(Toast, { children: t.copied })
1832
+ cellMenu && /* @__PURE__ */ jsx13(PopMenu, { anchor: cellMenu.anchor, items: cellMenuItems(cellMenu), onClose: () => setCellMenu(void 0) }),
1833
+ columnMenu && /* @__PURE__ */ jsx13(PopMenu, { anchor: columnMenu, items: columnMenuItems, onClose: () => setColumnMenu(void 0) }),
1834
+ copied && /* @__PURE__ */ jsx13(Toast, { children: t.copied })
1747
1835
  ] });
1748
1836
  }
1749
1837
 
1750
1838
  // src/components/EntityDetail.tsx
1751
1839
  import { useState as useState10 } from "react";
1752
- import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
1840
+ import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
1753
1841
  function EntityDetail({
1754
1842
  entity,
1755
1843
  id,
@@ -1798,50 +1886,50 @@ function EntityDetail({
1798
1886
  onSelect: () => void onDelete()
1799
1887
  });
1800
1888
  }
1801
- return /* @__PURE__ */ jsxs11("section", { className: "mst-page", children: [
1802
- /* @__PURE__ */ jsxs11("div", { className: "mst-pagehead", children: [
1803
- /* @__PURE__ */ jsxs11("div", { children: [
1804
- /* @__PURE__ */ jsxs11("button", { type: "button", className: "mst-backlink", onClick: onBack, children: [
1805
- /* @__PURE__ */ jsx13(Icon, { name: "arrowLeft", size: 12 }),
1889
+ return /* @__PURE__ */ jsxs12("section", { className: "mst-page", children: [
1890
+ /* @__PURE__ */ jsxs12("div", { className: "mst-pagehead", children: [
1891
+ /* @__PURE__ */ jsxs12("div", { children: [
1892
+ /* @__PURE__ */ jsxs12("button", { type: "button", className: "mst-backlink", onClick: onBack, children: [
1893
+ /* @__PURE__ */ jsx14(Icon, { name: "arrowLeft", size: 12 }),
1806
1894
  entity.label.plural
1807
1895
  ] }),
1808
- /* @__PURE__ */ jsxs11("h1", { className: "mst-pagehead__title", children: [
1896
+ /* @__PURE__ */ jsxs12("h1", { className: "mst-pagehead__title", children: [
1809
1897
  entity.label.singular,
1810
1898
  " ",
1811
1899
  data ? String(data[entity.displayField] ?? id) : ""
1812
1900
  ] })
1813
1901
  ] }),
1814
- /* @__PURE__ */ jsxs11("div", { className: "mst-pagehead__actions", children: [
1815
- entity.capabilities.update && /* @__PURE__ */ jsx13(Button, { variant: "primary", icon: "pencil", onClick: onEdit, children: t.edit }),
1816
- /* @__PURE__ */ jsx13(MenuButton, { label: t.actions, items: menuItems })
1902
+ /* @__PURE__ */ jsxs12("div", { className: "mst-pagehead__actions", children: [
1903
+ entity.capabilities.update && /* @__PURE__ */ jsx14(Button, { variant: "primary", icon: "pencil", onClick: onEdit, children: t.edit }),
1904
+ /* @__PURE__ */ jsx14(MenuButton, { label: t.actions, items: menuItems })
1817
1905
  ] })
1818
1906
  ] }),
1819
- error && /* @__PURE__ */ jsx13(ErrorBanner, { error }),
1820
- loading && !data ? /* @__PURE__ */ jsx13(Spinner, {}) : data && /* @__PURE__ */ jsx13("dl", { className: "mst-fields", children: fields.map((f) => {
1907
+ error && /* @__PURE__ */ jsx14(ErrorBanner, { error }),
1908
+ loading && !data ? /* @__PURE__ */ jsx14(Spinner, {}) : data && /* @__PURE__ */ jsx14("dl", { className: "mst-fields", children: fields.map((f) => {
1821
1909
  const value = data[f.name];
1822
1910
  const isRelation = f.type === "relation" && f.relationEntity && value !== null && value !== void 0;
1823
1911
  const target = isRelation ? entities.find((e) => e.id === f.relationEntity) : void 0;
1824
- return /* @__PURE__ */ jsxs11("div", { className: "mst-fields__row", children: [
1825
- /* @__PURE__ */ jsx13("dt", { className: "mst-fields__key", children: f.label }),
1826
- /* @__PURE__ */ jsxs11("dd", { className: "mst-fields__value", children: [
1827
- /* @__PURE__ */ jsx13(FieldValue, { field: f, value }),
1828
- isRelation && /* @__PURE__ */ jsxs11("button", { type: "button", className: "mst-backlink", onClick: () => onNavigate(f.relationEntity, String(value)), children: [
1912
+ return /* @__PURE__ */ jsxs12("div", { className: "mst-fields__row", children: [
1913
+ /* @__PURE__ */ jsx14("dt", { className: "mst-fields__key", children: f.label }),
1914
+ /* @__PURE__ */ jsxs12("dd", { className: "mst-fields__value", children: [
1915
+ /* @__PURE__ */ jsx14(FieldValue, { field: f, value }),
1916
+ isRelation && /* @__PURE__ */ jsxs12("button", { type: "button", className: "mst-backlink", onClick: () => onNavigate(f.relationEntity, String(value)), children: [
1829
1917
  t.openRelated(target?.label.singular ?? f.relationEntity),
1830
- /* @__PURE__ */ jsx13(Icon, { name: "arrowUpRight", size: 11 })
1918
+ /* @__PURE__ */ jsx14(Icon, { name: "arrowUpRight", size: 11 })
1831
1919
  ] })
1832
1920
  ] })
1833
1921
  ] }, f.name);
1834
1922
  }) }),
1835
- copied && /* @__PURE__ */ jsx13(Toast, { children: t.copied })
1923
+ copied && /* @__PURE__ */ jsx14(Toast, { children: t.copied })
1836
1924
  ] });
1837
1925
  }
1838
1926
 
1839
1927
  // src/components/EntityForm.tsx
1840
- import { useEffect as useEffect6, useState as useState12 } from "react";
1928
+ import { useEffect as useEffect7, useState as useState12 } from "react";
1841
1929
 
1842
1930
  // src/components/JsonInput.tsx
1843
- import { useEffect as useEffect5, useRef as useRef3, useState as useState11 } from "react";
1844
- import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
1931
+ import { useEffect as useEffect6, useRef as useRef4, useState as useState11 } from "react";
1932
+ import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
1845
1933
  var leafInputClass = "mst-input";
1846
1934
  var MAX_DEPTH2 = 3;
1847
1935
  function RawJsonArea({
@@ -1855,8 +1943,8 @@ function RawJsonArea({
1855
1943
  const t = useT();
1856
1944
  const [text, setText] = useState11(() => value === null || value === void 0 ? "" : JSON.stringify(value, null, 2));
1857
1945
  const [invalid, setInvalid] = useState11(false);
1858
- const lastEmitted = useRef3(value);
1859
- useEffect5(() => {
1946
+ const lastEmitted = useRef4(value);
1947
+ useEffect6(() => {
1860
1948
  if (value !== lastEmitted.current) {
1861
1949
  lastEmitted.current = value;
1862
1950
  setText(value === null || value === void 0 ? "" : JSON.stringify(value, null, 2));
@@ -1880,8 +1968,8 @@ function RawJsonArea({
1880
1968
  setInvalid(true);
1881
1969
  }
1882
1970
  };
1883
- return /* @__PURE__ */ jsxs12("div", { className: "mst-field", children: [
1884
- /* @__PURE__ */ jsx14(
1971
+ return /* @__PURE__ */ jsxs13("div", { className: "mst-field", children: [
1972
+ /* @__PURE__ */ jsx15(
1885
1973
  "textarea",
1886
1974
  {
1887
1975
  id,
@@ -1894,7 +1982,7 @@ function RawJsonArea({
1894
1982
  className: `mst-textarea mst-mono${invalid ? " mst-input--invalid" : ""}`
1895
1983
  }
1896
1984
  ),
1897
- invalid && /* @__PURE__ */ jsx14("p", { role: "alert", className: "mst-help mst-help--warn", children: t.jsonInvalid })
1985
+ invalid && /* @__PURE__ */ jsx15("p", { role: "alert", className: "mst-help mst-help--warn", children: t.jsonInvalid })
1898
1986
  ] });
1899
1987
  }
1900
1988
  function LeafEditor({
@@ -1905,7 +1993,7 @@ function LeafEditor({
1905
1993
  depth
1906
1994
  }) {
1907
1995
  if (typeof value === "boolean") {
1908
- return /* @__PURE__ */ jsx14(
1996
+ return /* @__PURE__ */ jsx15(
1909
1997
  "input",
1910
1998
  {
1911
1999
  id,
@@ -1918,7 +2006,7 @@ function LeafEditor({
1918
2006
  );
1919
2007
  }
1920
2008
  if (typeof value === "number") {
1921
- return /* @__PURE__ */ jsx14(
2009
+ return /* @__PURE__ */ jsx15(
1922
2010
  "input",
1923
2011
  {
1924
2012
  id,
@@ -1932,7 +2020,7 @@ function LeafEditor({
1932
2020
  );
1933
2021
  }
1934
2022
  if (typeof value === "string") {
1935
- return /* @__PURE__ */ jsx14(
2023
+ return /* @__PURE__ */ jsx15(
1936
2024
  "input",
1937
2025
  {
1938
2026
  id,
@@ -1945,7 +2033,7 @@ function LeafEditor({
1945
2033
  );
1946
2034
  }
1947
2035
  if (value === null || value === void 0) {
1948
- return /* @__PURE__ */ jsx14(
2036
+ return /* @__PURE__ */ jsx15(
1949
2037
  "input",
1950
2038
  {
1951
2039
  id,
@@ -1959,12 +2047,12 @@ function LeafEditor({
1959
2047
  );
1960
2048
  }
1961
2049
  if (isPlainObject(value) && depth < MAX_DEPTH2) {
1962
- return /* @__PURE__ */ jsx14("div", { className: "mst-json__nest", children: /* @__PURE__ */ jsx14(ObjectEditor, { idPrefix: id, value, onChange, disabled, depth: depth + 1 }) });
2050
+ return /* @__PURE__ */ jsx15("div", { className: "mst-json__nest", children: /* @__PURE__ */ jsx15(ObjectEditor, { idPrefix: id, value, onChange, disabled, depth: depth + 1 }) });
1963
2051
  }
1964
2052
  if (Array.isArray(value) && depth < MAX_DEPTH2) {
1965
- return /* @__PURE__ */ jsx14("div", { className: "mst-json__nest", children: /* @__PURE__ */ jsx14(ArrayEditor, { idPrefix: id, value, onChange, disabled, depth: depth + 1 }) });
2053
+ return /* @__PURE__ */ jsx15("div", { className: "mst-json__nest", children: /* @__PURE__ */ jsx15(ArrayEditor, { idPrefix: id, value, onChange, disabled, depth: depth + 1 }) });
1966
2054
  }
1967
- return /* @__PURE__ */ jsx14(RawJsonArea, { id, value, onChange, disabled, rows: 3 });
2055
+ return /* @__PURE__ */ jsx15(RawJsonArea, { id, value, onChange, disabled, rows: 3 });
1968
2056
  }
1969
2057
  function ArrayEditor({
1970
2058
  idPrefix,
@@ -1981,12 +2069,12 @@ function ArrayEditor({
1981
2069
  const template = last === void 0 || last === null ? null : JSON.parse(JSON.stringify(last));
1982
2070
  onChange([...value, template]);
1983
2071
  };
1984
- return /* @__PURE__ */ jsxs12("div", { className: "mst-json__rows", children: [
2072
+ return /* @__PURE__ */ jsxs13("div", { className: "mst-json__rows", children: [
1985
2073
  value.map((item, i) => {
1986
2074
  const id = `${idPrefix}-${i}`;
1987
- return /* @__PURE__ */ jsxs12("div", { className: "mst-json__row", children: [
1988
- /* @__PURE__ */ jsx14("label", { htmlFor: id, className: "mst-json__index", children: i }),
1989
- !disabled && /* @__PURE__ */ jsx14(
2075
+ return /* @__PURE__ */ jsxs13("div", { className: "mst-json__row", children: [
2076
+ /* @__PURE__ */ jsx15("label", { htmlFor: id, className: "mst-json__index", children: i }),
2077
+ !disabled && /* @__PURE__ */ jsx15(
1990
2078
  "button",
1991
2079
  {
1992
2080
  type: "button",
@@ -1997,11 +2085,11 @@ function ArrayEditor({
1997
2085
  children: "\u2715"
1998
2086
  }
1999
2087
  ),
2000
- /* @__PURE__ */ jsx14("div", { className: "mst-json__field", children: /* @__PURE__ */ jsx14(LeafEditor, { id, value: item, onChange: (next) => setAt(i, next), disabled, depth }) })
2088
+ /* @__PURE__ */ jsx15("div", { className: "mst-json__field", children: /* @__PURE__ */ jsx15(LeafEditor, { id, value: item, onChange: (next) => setAt(i, next), disabled, depth }) })
2001
2089
  ] }, i);
2002
2090
  }),
2003
- value.length === 0 && /* @__PURE__ */ jsx14("p", { className: "mst-json__empty", children: t.emptyObject }),
2004
- !disabled && /* @__PURE__ */ jsx14("div", { className: "mst-json__addrow", children: /* @__PURE__ */ jsxs12("button", { type: "button", onClick: append, className: "mst-backlink", children: [
2091
+ value.length === 0 && /* @__PURE__ */ jsx15("p", { className: "mst-json__empty", children: t.emptyObject }),
2092
+ !disabled && /* @__PURE__ */ jsx15("div", { className: "mst-json__addrow", children: /* @__PURE__ */ jsxs13("button", { type: "button", onClick: append, className: "mst-backlink", children: [
2005
2093
  "+ ",
2006
2094
  t.addItem
2007
2095
  ] }) })
@@ -2017,16 +2105,16 @@ function ObjectEditor({
2017
2105
  const t = useT();
2018
2106
  const entries = Object.entries(value);
2019
2107
  if (entries.length === 0) {
2020
- return /* @__PURE__ */ jsx14("p", { className: "mst-json__empty", children: t.emptyObject });
2108
+ return /* @__PURE__ */ jsx15("p", { className: "mst-json__empty", children: t.emptyObject });
2021
2109
  }
2022
- return /* @__PURE__ */ jsx14("div", { className: "mst-json__rows", children: entries.map(([key, entry]) => {
2110
+ return /* @__PURE__ */ jsx15("div", { className: "mst-json__rows", children: entries.map(([key, entry]) => {
2023
2111
  const id = `${idPrefix}-${key}`;
2024
2112
  return (
2025
2113
  // flex-wrap + basis: when the label column leaves less than ~16rem for the control (deeply
2026
2114
  // nested groups), the control wraps to its own full-width line instead of squeezing.
2027
- /* @__PURE__ */ jsxs12("div", { className: "mst-json__row", children: [
2028
- /* @__PURE__ */ jsx14("label", { htmlFor: id, className: "mst-json__key", title: key, children: key }),
2029
- /* @__PURE__ */ jsx14("div", { className: "mst-json__field", children: /* @__PURE__ */ jsx14(
2115
+ /* @__PURE__ */ jsxs13("div", { className: "mst-json__row", children: [
2116
+ /* @__PURE__ */ jsx15("label", { htmlFor: id, className: "mst-json__key", title: key, children: key }),
2117
+ /* @__PURE__ */ jsx15("div", { className: "mst-json__field", children: /* @__PURE__ */ jsx15(
2030
2118
  LeafEditor,
2031
2119
  {
2032
2120
  id,
@@ -2050,7 +2138,7 @@ function JsonInput({
2050
2138
  const [mode, setMode] = useState11(() => isPlainObject(value) ? "form" : "raw");
2051
2139
  const [modeTouched, setModeTouched] = useState11(false);
2052
2140
  const structured = isPlainObject(value) || Array.isArray(value);
2053
- useEffect5(() => {
2141
+ useEffect6(() => {
2054
2142
  if (!modeTouched && structured) setMode("form");
2055
2143
  }, [structured, modeTouched]);
2056
2144
  const pick = (next) => {
@@ -2059,9 +2147,9 @@ function JsonInput({
2059
2147
  };
2060
2148
  const showForm = mode === "form" && structured;
2061
2149
  const toggleClass = (active) => `mst-json__tab${active ? " mst-json__tab--active" : ""}`;
2062
- return /* @__PURE__ */ jsxs12("div", { className: "mst-json", children: [
2063
- /* @__PURE__ */ jsxs12("div", { className: "mst-json__head", children: [
2064
- /* @__PURE__ */ jsx14(
2150
+ return /* @__PURE__ */ jsxs13("div", { className: "mst-json", children: [
2151
+ /* @__PURE__ */ jsxs13("div", { className: "mst-json__head", children: [
2152
+ /* @__PURE__ */ jsx15(
2065
2153
  "button",
2066
2154
  {
2067
2155
  type: "button",
@@ -2071,9 +2159,9 @@ function JsonInput({
2071
2159
  children: t.jsonFormMode
2072
2160
  }
2073
2161
  ),
2074
- /* @__PURE__ */ jsx14("button", { type: "button", className: toggleClass(!showForm), onClick: () => pick("raw"), children: t.jsonRawMode })
2162
+ /* @__PURE__ */ jsx15("button", { type: "button", className: toggleClass(!showForm), onClick: () => pick("raw"), children: t.jsonRawMode })
2075
2163
  ] }),
2076
- /* @__PURE__ */ jsx14("div", { className: "mst-json__body", children: showForm ? Array.isArray(value) ? /* @__PURE__ */ jsx14(ArrayEditor, { idPrefix: `field-${field.name}`, value, onChange, disabled }) : /* @__PURE__ */ jsx14(
2164
+ /* @__PURE__ */ jsx15("div", { className: "mst-json__body", children: showForm ? Array.isArray(value) ? /* @__PURE__ */ jsx15(ArrayEditor, { idPrefix: `field-${field.name}`, value, onChange, disabled }) : /* @__PURE__ */ jsx15(
2077
2165
  ObjectEditor,
2078
2166
  {
2079
2167
  idPrefix: `field-${field.name}`,
@@ -2081,7 +2169,7 @@ function JsonInput({
2081
2169
  onChange,
2082
2170
  disabled
2083
2171
  }
2084
- ) : /* @__PURE__ */ jsx14(
2172
+ ) : /* @__PURE__ */ jsx15(
2085
2173
  RawJsonArea,
2086
2174
  {
2087
2175
  id: `field-${field.name}`,
@@ -2095,7 +2183,7 @@ function JsonInput({
2095
2183
  }
2096
2184
 
2097
2185
  // src/components/FieldInput.tsx
2098
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
2186
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
2099
2187
  var inputClass = "mst-input";
2100
2188
  function FieldInput({
2101
2189
  field,
@@ -2106,7 +2194,7 @@ function FieldInput({
2106
2194
  const id = `field-${field.name}`;
2107
2195
  switch (field.type) {
2108
2196
  case "boolean":
2109
- return /* @__PURE__ */ jsx15(
2197
+ return /* @__PURE__ */ jsx16(
2110
2198
  "input",
2111
2199
  {
2112
2200
  id,
@@ -2122,7 +2210,7 @@ function FieldInput({
2122
2210
  case "float":
2123
2211
  case "decimal":
2124
2212
  case "currency":
2125
- return /* @__PURE__ */ jsx15(
2213
+ return /* @__PURE__ */ jsx16(
2126
2214
  "input",
2127
2215
  {
2128
2216
  id,
@@ -2136,7 +2224,7 @@ function FieldInput({
2136
2224
  }
2137
2225
  );
2138
2226
  case "enum":
2139
- return /* @__PURE__ */ jsxs13(
2227
+ return /* @__PURE__ */ jsxs14(
2140
2228
  "select",
2141
2229
  {
2142
2230
  id,
@@ -2145,13 +2233,13 @@ function FieldInput({
2145
2233
  onChange: (e) => onChange(e.target.value),
2146
2234
  className: "mst-select",
2147
2235
  children: [
2148
- /* @__PURE__ */ jsx15("option", { value: "", children: "\u2014" }),
2149
- field.enumOptions?.map((o) => /* @__PURE__ */ jsx15("option", { value: String(o.value), children: o.label }, String(o.value)))
2236
+ /* @__PURE__ */ jsx16("option", { value: "", children: "\u2014" }),
2237
+ field.enumOptions?.map((o) => /* @__PURE__ */ jsx16("option", { value: String(o.value), children: o.label }, String(o.value)))
2150
2238
  ]
2151
2239
  }
2152
2240
  );
2153
2241
  case "date":
2154
- return /* @__PURE__ */ jsx15(
2242
+ return /* @__PURE__ */ jsx16(
2155
2243
  "input",
2156
2244
  {
2157
2245
  id,
@@ -2163,9 +2251,9 @@ function FieldInput({
2163
2251
  }
2164
2252
  );
2165
2253
  case "json":
2166
- return /* @__PURE__ */ jsx15(JsonInput, { field, value, onChange, disabled });
2254
+ return /* @__PURE__ */ jsx16(JsonInput, { field, value, onChange, disabled });
2167
2255
  case "text":
2168
- return /* @__PURE__ */ jsx15(
2256
+ return /* @__PURE__ */ jsx16(
2169
2257
  "textarea",
2170
2258
  {
2171
2259
  id,
@@ -2178,7 +2266,7 @@ function FieldInput({
2178
2266
  }
2179
2267
  );
2180
2268
  default:
2181
- return /* @__PURE__ */ jsx15(
2269
+ return /* @__PURE__ */ jsx16(
2182
2270
  "input",
2183
2271
  {
2184
2272
  id,
@@ -2194,7 +2282,7 @@ function FieldInput({
2194
2282
  }
2195
2283
 
2196
2284
  // src/components/EntityForm.tsx
2197
- import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
2285
+ import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
2198
2286
  function EntityForm({
2199
2287
  entity,
2200
2288
  mode,
@@ -2211,7 +2299,7 @@ function EntityForm({
2211
2299
  const [values, setValues] = useState12({});
2212
2300
  const [saving, setSaving] = useState12(false);
2213
2301
  const [error, setError] = useState12(void 0);
2214
- useEffect6(() => {
2302
+ useEffect7(() => {
2215
2303
  if (!existing.data || !sourceId) return;
2216
2304
  if (mode === "edit") {
2217
2305
  setValues(existing.data);
@@ -2243,25 +2331,25 @@ function EntityForm({
2243
2331
  }
2244
2332
  };
2245
2333
  if (sourceId && existing.loading && !existing.data) {
2246
- return /* @__PURE__ */ jsx16(Spinner, {});
2334
+ return /* @__PURE__ */ jsx17(Spinner, {});
2247
2335
  }
2248
2336
  const title = mode === "edit" ? t.editTitle(entity.label.singular) : cloneFromId ? t.cloneTitle(entity.label.singular) : t.newTitle(entity.label.singular);
2249
- return /* @__PURE__ */ jsxs14("section", { className: "mst-page", children: [
2250
- /* @__PURE__ */ jsx16("div", { className: "mst-pagehead", children: /* @__PURE__ */ jsxs14("div", { children: [
2251
- /* @__PURE__ */ jsxs14("button", { type: "button", className: "mst-backlink", onClick: onCancel, children: [
2252
- /* @__PURE__ */ jsx16(Icon, { name: "arrowLeft", size: 12 }),
2337
+ return /* @__PURE__ */ jsxs15("section", { className: "mst-page", children: [
2338
+ /* @__PURE__ */ jsx17("div", { className: "mst-pagehead", children: /* @__PURE__ */ jsxs15("div", { children: [
2339
+ /* @__PURE__ */ jsxs15("button", { type: "button", className: "mst-backlink", onClick: onCancel, children: [
2340
+ /* @__PURE__ */ jsx17(Icon, { name: "arrowLeft", size: 12 }),
2253
2341
  entity.label.plural
2254
2342
  ] }),
2255
- /* @__PURE__ */ jsx16("h1", { className: "mst-pagehead__title", children: title })
2343
+ /* @__PURE__ */ jsx17("h1", { className: "mst-pagehead__title", children: title })
2256
2344
  ] }) }),
2257
- error && /* @__PURE__ */ jsx16(ErrorBanner, { error }),
2258
- /* @__PURE__ */ jsxs14("form", { onSubmit: submit, className: "mst-card mst-form", children: [
2259
- fields.map((f) => /* @__PURE__ */ jsxs14("div", { className: "mst-field", children: [
2260
- /* @__PURE__ */ jsxs14("label", { htmlFor: `field-${f.name}`, className: "mst-label", children: [
2345
+ error && /* @__PURE__ */ jsx17(ErrorBanner, { error }),
2346
+ /* @__PURE__ */ jsxs15("form", { onSubmit: submit, className: "mst-card mst-form", children: [
2347
+ fields.map((f) => /* @__PURE__ */ jsxs15("div", { className: "mst-field", children: [
2348
+ /* @__PURE__ */ jsxs15("label", { htmlFor: `field-${f.name}`, className: "mst-label", children: [
2261
2349
  f.label,
2262
- f.required && /* @__PURE__ */ jsx16("span", { className: "mst-label__req", children: "*" })
2350
+ f.required && /* @__PURE__ */ jsx17("span", { className: "mst-label__req", children: "*" })
2263
2351
  ] }),
2264
- /* @__PURE__ */ jsx16(
2352
+ /* @__PURE__ */ jsx17(
2265
2353
  FieldInput,
2266
2354
  {
2267
2355
  field: f,
@@ -2270,11 +2358,11 @@ function EntityForm({
2270
2358
  onChange: (next) => setValues((v) => ({ ...v, [f.name]: next }))
2271
2359
  }
2272
2360
  ),
2273
- f.form.helpText && /* @__PURE__ */ jsx16("p", { className: "mst-help", children: f.form.helpText })
2361
+ f.form.helpText && /* @__PURE__ */ jsx17("p", { className: "mst-help", children: f.form.helpText })
2274
2362
  ] }, f.name)),
2275
- /* @__PURE__ */ jsxs14("div", { className: "mst-form__foot", children: [
2276
- /* @__PURE__ */ jsx16(Button, { type: "button", variant: "secondary", onClick: onCancel, disabled: saving, children: t.cancel }),
2277
- /* @__PURE__ */ jsx16(Button, { type: "submit", variant: "primary", disabled: saving, children: saving ? t.saving : mode === "create" ? t.create : t.save })
2363
+ /* @__PURE__ */ jsxs15("div", { className: "mst-form__foot", children: [
2364
+ /* @__PURE__ */ jsx17(Button, { type: "button", variant: "secondary", onClick: onCancel, disabled: saving, children: t.cancel }),
2365
+ /* @__PURE__ */ jsx17(Button, { type: "submit", variant: "primary", disabled: saving, children: saving ? t.saving : mode === "create" ? t.create : t.save })
2278
2366
  ] })
2279
2367
  ] })
2280
2368
  ] });
@@ -2338,7 +2426,7 @@ function useRecents(scope) {
2338
2426
  }
2339
2427
 
2340
2428
  // src/components/MaestroAdmin.tsx
2341
- import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
2429
+ import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
2342
2430
  function AdminShell({ title, labels }) {
2343
2431
  const { data, error, loading } = useMetadata();
2344
2432
  const t = useT();
@@ -2370,7 +2458,7 @@ function AdminShell({ title, labels }) {
2370
2458
  },
2371
2459
  [pushRecent]
2372
2460
  );
2373
- useEffect7(() => {
2461
+ useEffect8(() => {
2374
2462
  const onKey = (e) => {
2375
2463
  if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "k") {
2376
2464
  e.preventDefault();
@@ -2409,10 +2497,10 @@ function AdminShell({ title, labels }) {
2409
2497
  return sections;
2410
2498
  }, [entities, groupOf, openEntity, activeEntity, t]);
2411
2499
  if (loading && !data) {
2412
- return /* @__PURE__ */ jsx17("div", { className: "mst-boot", children: /* @__PURE__ */ jsx17(Spinner, { label: t.loadingMetadata }) });
2500
+ return /* @__PURE__ */ jsx18("div", { className: "mst-boot", children: /* @__PURE__ */ jsx18(Spinner, { label: t.loadingMetadata }) });
2413
2501
  }
2414
- return /* @__PURE__ */ jsxs15(AdminEntitiesProvider, { value: entities, children: [
2415
- /* @__PURE__ */ jsx17(
2502
+ return /* @__PURE__ */ jsxs16(AdminEntitiesProvider, { value: entities, children: [
2503
+ /* @__PURE__ */ jsx18(
2416
2504
  Sidebar,
2417
2505
  {
2418
2506
  entities,
@@ -2425,12 +2513,12 @@ function AdminShell({ title, labels }) {
2425
2513
  homeActive: view.kind === "hub"
2426
2514
  }
2427
2515
  ),
2428
- /* @__PURE__ */ jsxs15("div", { className: "mst-main", children: [
2429
- /* @__PURE__ */ jsx17(Header, { crumbs, onOpenPalette: () => setPaletteOpen(true) }),
2430
- /* @__PURE__ */ jsxs15("div", { className: "mst-content", children: [
2431
- error && /* @__PURE__ */ jsx17(ErrorBanner, { error }),
2432
- view.kind === "hub" && /* @__PURE__ */ jsx17(Hub, { entities, labels, onOpen: openEntity }),
2433
- activeEntity && view.kind === "list" && /* @__PURE__ */ jsx17(
2516
+ /* @__PURE__ */ jsxs16("div", { className: "mst-main", children: [
2517
+ /* @__PURE__ */ jsx18(Header, { crumbs, onOpenPalette: () => setPaletteOpen(true) }),
2518
+ /* @__PURE__ */ jsxs16("div", { className: "mst-content", children: [
2519
+ error && /* @__PURE__ */ jsx18(ErrorBanner, { error }),
2520
+ view.kind === "hub" && /* @__PURE__ */ jsx18(Hub, { entities, labels, onOpen: openEntity }),
2521
+ activeEntity && view.kind === "list" && /* @__PURE__ */ jsx18(
2434
2522
  EntityList,
2435
2523
  {
2436
2524
  entity: activeEntity,
@@ -2441,7 +2529,7 @@ function AdminShell({ title, labels }) {
2441
2529
  onNavigate: navigateToRecord
2442
2530
  }
2443
2531
  ),
2444
- activeEntity && view.kind === "detail" && /* @__PURE__ */ jsx17(
2532
+ activeEntity && view.kind === "detail" && /* @__PURE__ */ jsx18(
2445
2533
  EntityDetail,
2446
2534
  {
2447
2535
  entity: activeEntity,
@@ -2453,7 +2541,7 @@ function AdminShell({ title, labels }) {
2453
2541
  onNavigate: navigateToRecord
2454
2542
  }
2455
2543
  ),
2456
- activeEntity && (view.kind === "create" || view.kind === "edit") && /* @__PURE__ */ jsx17(
2544
+ activeEntity && (view.kind === "create" || view.kind === "edit") && /* @__PURE__ */ jsx18(
2457
2545
  EntityForm,
2458
2546
  {
2459
2547
  entity: activeEntity,
@@ -2466,7 +2554,7 @@ function AdminShell({ title, labels }) {
2466
2554
  )
2467
2555
  ] })
2468
2556
  ] }),
2469
- paletteOpen && /* @__PURE__ */ jsx17(CommandPalette, { sections: paletteSections, onClose: () => setPaletteOpen(false) })
2557
+ paletteOpen && /* @__PURE__ */ jsx18(CommandPalette, { sections: paletteSections, onClose: () => setPaletteOpen(false) })
2470
2558
  ] });
2471
2559
  }
2472
2560
  function MaestroAdmin(props) {
@@ -2476,7 +2564,7 @@ function MaestroAdmin(props) {
2476
2564
  );
2477
2565
  const strings = useMemo7(() => stringsFor(props.locale ?? "en"), [props.locale]);
2478
2566
  const [root, setRoot] = useState14(null);
2479
- return /* @__PURE__ */ jsx17(AdminClientProvider, { value: client, children: /* @__PURE__ */ jsx17(I18nProvider, { value: strings, children: /* @__PURE__ */ jsx17(MaestroThemeProvider, { theme: props.theme, className: "mst-root", rootRef: setRoot, children: /* @__PURE__ */ jsx17(AdminRootProvider, { value: root, children: /* @__PURE__ */ jsx17(AdminShell, { title: props.title ?? "Maestro Admin", labels: props.labels }) }) }) }) });
2567
+ return /* @__PURE__ */ jsx18(AdminClientProvider, { value: client, children: /* @__PURE__ */ jsx18(I18nProvider, { value: strings, children: /* @__PURE__ */ jsx18(MaestroThemeProvider, { theme: props.theme, className: "mst-root", rootRef: setRoot, children: /* @__PURE__ */ jsx18(AdminRootProvider, { value: root, children: /* @__PURE__ */ jsx18(AdminShell, { title: props.title ?? "Maestro Admin", labels: props.labels }) }) }) }) });
2480
2568
  }
2481
2569
  export {
2482
2570
  AdminClientProvider,
@@ -2500,6 +2588,8 @@ export {
2500
2588
  MaestroAdmin,
2501
2589
  MaestroApiError,
2502
2590
  MaestroClient,
2591
+ MaestroMark,
2592
+ MaestroSeal,
2503
2593
  MaestroThemeProvider,
2504
2594
  ObjectValue,
2505
2595
  Sidebar,