@timeax/service-builder 0.0.10 → 0.0.12

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
@@ -4234,6 +4234,8 @@ import { LuTags as LuTags2 } from "react-icons/lu";
4234
4234
  import { MdOutlineRadioButtonChecked as MdOutlineRadioButtonChecked2 } from "react-icons/md";
4235
4235
  import { RxInput as RxInput2 } from "react-icons/rx";
4236
4236
  import { Fragment as Fragment5, jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
4237
+ var ACTIVE_NODE_RING_CLASS = "ring-2 ring-sky-300 shadow-lg shadow-sky-300/20 dark:ring-sky-400";
4238
+ var HIGHLIGHT_NODE_OUTLINE_CLASS = "outline-2 outline-solid outline-amber-300 dark:outline-amber-200";
4237
4239
  function NodeShell({
4238
4240
  label,
4239
4241
  icon,
@@ -4264,7 +4266,7 @@ function NodeShell({
4264
4266
  isManualHighlighted ? "manual-highlighted" : "",
4265
4267
  focusDimLevel && focusDimLevel !== "none" ? `dim-${focusDimLevel}` : ""
4266
4268
  ].filter(Boolean).join(" "),
4267
- className: "group relative min-w-44 rounded-lg bg-white p-3 ring-1 ring-slate-200 shadow-[0_4px_12px_rgba(0,0,0,0.05)] transition-all duration-200 dark:bg-slate-900 dark:ring-slate-700 " + (selected ? "ring-2 ring-blue-500 shadow-lg shadow-blue-500/20 " : "hover:shadow-lg ") + (isActiveNode ? "ring-2 ring-blue-500 shadow-lg shadow-blue-500/25 " : "") + (isCurrentTag ? "ring-2 ring-emerald-500 bg-emerald-50/70 shadow-lg shadow-emerald-500/25 dark:bg-emerald-500/10 " : "") + (isVisibleGroupField ? "ring-2 ring-emerald-300 bg-emerald-50/35 dark:bg-emerald-500/5 " : "") + (isRelatedTag ? "ring-1 ring-teal-300 bg-teal-50/25 dark:bg-teal-500/8 " : "") + (isManualHighlighted ? "outline-2 outline-amber-400 outline-solid " : "") + (draggingService && canAssignService2 ? "border border-dashed border-emerald-400 " : "") + (!canAssignService2 && draggingService ? "opacity-70 " : "") + dimClass,
4269
+ className: "group relative min-w-44 rounded-lg bg-white p-3 ring-1 ring-slate-200 shadow-[0_4px_12px_rgba(0,0,0,0.05)] transition-all duration-200 dark:bg-slate-900 dark:ring-slate-700 " + (selected ? `${ACTIVE_NODE_RING_CLASS} ` : "hover:shadow-lg ") + (isActiveNode ? `${ACTIVE_NODE_RING_CLASS} ` : "") + (isCurrentTag ? "ring-2 ring-emerald-500 bg-emerald-50/70 shadow-lg shadow-emerald-500/25 dark:bg-emerald-500/10 " : "") + (isVisibleGroupField ? "ring-2 ring-emerald-300 bg-emerald-50/35 dark:bg-emerald-500/5 " : "") + (isRelatedTag ? "ring-1 ring-teal-300 bg-teal-50/25 dark:bg-teal-500/8 " : "") + (isManualHighlighted ? `${HIGHLIGHT_NODE_OUTLINE_CLASS} ` : "") + (draggingService && canAssignService2 ? "border border-dashed border-emerald-400 " : "") + (!canAssignService2 && draggingService ? "opacity-70 " : "") + dimClass,
4268
4270
  onDragOver: (event) => {
4269
4271
  if (!canAcceptDropPayload?.(event.dataTransfer)) return;
4270
4272
  event.preventDefault();
@@ -4361,7 +4363,7 @@ function OptionNode(props) {
4361
4363
  props.data.isManualHighlighted ? "manual-highlighted" : "",
4362
4364
  props.data.focusDimLevel && props.data.focusDimLevel !== "none" ? `dim-${props.data.focusDimLevel}` : ""
4363
4365
  ].filter(Boolean).join(" "),
4364
- className: "relative rounded-full border px-4 py-1.5 text-sm bg-white text-slate-800 transition dark:bg-slate-900 dark:text-slate-200 " + (props.selected ? "border-blue-500 bg-blue-50 text-blue-700 dark:bg-blue-500/15 " : "border-slate-300 dark:border-slate-700 ") + (props.data.isActiveNode ? "ring-2 ring-blue-500 shadow-lg shadow-blue-500/25 " : "") + (props.data.isCurrentTag ? "ring-2 ring-emerald-500 bg-emerald-50/70 dark:bg-emerald-500/10 " : "") + (props.data.isVisibleGroupField ? "ring-2 ring-emerald-300 bg-emerald-50/35 dark:bg-emerald-500/5 " : "") + (props.data.isRelatedTag ? "ring-1 ring-teal-300 bg-teal-50/25 dark:bg-teal-500/8 " : "") + (props.data.isManualHighlighted ? "outline-2 outline-solid outline-amber-400 " : "") + (props.data.focusDimLevel === "soft" ? "opacity-80 " : props.data.focusDimLevel === "medium" ? "opacity-[0.55] " : props.data.focusDimLevel === "strong" ? "opacity-35 " : ""),
4366
+ className: "relative rounded-full border px-4 py-1.5 text-sm bg-white text-slate-800 transition dark:bg-slate-900 dark:text-slate-200 " + (props.selected ? "border-sky-300 bg-sky-50 text-sky-700 dark:bg-sky-500/15 dark:border-sky-400 " : "border-slate-300 dark:border-slate-700 ") + (props.data.isActiveNode ? `${ACTIVE_NODE_RING_CLASS} ` : "") + (props.data.isCurrentTag ? "ring-2 ring-emerald-500 bg-emerald-50/70 dark:bg-emerald-500/10 " : "") + (props.data.isVisibleGroupField ? "ring-2 ring-emerald-300 bg-emerald-50/35 dark:bg-emerald-500/5 " : "") + (props.data.isRelatedTag ? "ring-1 ring-teal-300 bg-teal-50/25 dark:bg-teal-500/8 " : "") + (props.data.isManualHighlighted ? `${HIGHLIGHT_NODE_OUTLINE_CLASS} ` : "") + (props.data.focusDimLevel === "soft" ? "opacity-80 " : props.data.focusDimLevel === "medium" ? "opacity-[0.55] " : props.data.focusDimLevel === "strong" ? "opacity-35 " : ""),
4365
4367
  onDragOver: (event) => {
4366
4368
  if (!props.data.canAcceptDropPayload?.(event.dataTransfer)) return;
4367
4369
  event.preventDefault();
@@ -4388,14 +4390,20 @@ function OptionNode(props) {
4388
4390
  function CommentNode(props) {
4389
4391
  const thread = props.data.thread;
4390
4392
  const main = thread?.messages?.find((message) => message.isMain) ?? thread?.messages?.[0];
4391
- return /* @__PURE__ */ jsxs11("div", { className: "h-48 w-64 rounded-lg border border-[#E0E0E0] bg-[#FEFBEA] shadow-md transition-all hover:shadow-lg dark:border-[#555] dark:bg-[#4a4a38]", children: [
4392
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 border-b border-[#E0E0E0]/70 px-3 py-2 text-xs font-medium text-slate-600 dark:border-[#555] dark:text-slate-300", children: [
4393
- /* @__PURE__ */ jsx15(BsChatSquareQuote2, {}),
4394
- /* @__PURE__ */ jsx15("span", { children: main?.authorName ?? "Comment" })
4395
- ] }),
4396
- /* @__PURE__ */ jsx15("div", { className: "px-3 py-2 text-sm leading-5 text-slate-700 dark:text-slate-200", children: main?.body ?? "" }),
4397
- /* @__PURE__ */ jsx15("div", { className: "absolute bottom-2 right-2 text-[10px] uppercase tracking-[0.14em] text-slate-400", children: thread?.resolved ? "Resolved" : "Open" })
4398
- ] });
4393
+ return /* @__PURE__ */ jsxs11(
4394
+ "div",
4395
+ {
4396
+ className: "h-48 w-64 rounded-lg border border-[#E0E0E0] bg-[#FEFBEA] shadow-md transition-all hover:shadow-lg dark:border-[#555] dark:bg-[#4a4a38] " + (props.selected ? `${ACTIVE_NODE_RING_CLASS} ` : ""),
4397
+ children: [
4398
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 border-b border-[#E0E0E0]/70 px-3 py-2 text-xs font-medium text-slate-600 dark:border-[#555] dark:text-slate-300", children: [
4399
+ /* @__PURE__ */ jsx15(BsChatSquareQuote2, {}),
4400
+ /* @__PURE__ */ jsx15("span", { children: main?.authorName ?? "Comment" })
4401
+ ] }),
4402
+ /* @__PURE__ */ jsx15("div", { className: "px-3 py-2 text-sm leading-5 text-slate-700 dark:text-slate-200", children: main?.body ?? "" }),
4403
+ /* @__PURE__ */ jsx15("div", { className: "absolute bottom-2 right-2 text-[10px] uppercase tracking-[0.14em] text-slate-400", children: thread?.resolved ? "Resolved" : "Open" })
4404
+ ]
4405
+ }
4406
+ );
4399
4407
  }
4400
4408
  var nodeTypes = {
4401
4409
  tag: TagNode,
@@ -5275,7 +5283,6 @@ function CanvasPanel({
5275
5283
  }, [canvas.api]);
5276
5284
  function setSnapshot(event) {
5277
5285
  const nextSnapshot = event?.snapshot;
5278
- console.log("this is the changed...");
5279
5286
  if (!nextSnapshot) return;
5280
5287
  const nextHash = hashSnapshot(nextSnapshot);
5281
5288
  setCurrentSnapshotHash((current) => current === nextHash ? current : nextHash);
@@ -5287,7 +5294,6 @@ function CanvasPanel({
5287
5294
  useEffect8(() => {
5288
5295
  const catalogChange = canvas.api.on("catalog:change", setSnapshot);
5289
5296
  const offEditorChange = canvas.api.on("editor:change", (event) => {
5290
- console.log("this snapshot changed via the editor...");
5291
5297
  setSnapshot(event);
5292
5298
  if (event?.reason === "mutation" || event?.reason === "transaction") {
5293
5299
  setHistoryState({ canUndo: true, canRedo: false });
@@ -6912,27 +6918,62 @@ var Header = ({ menu = [] }) => {
6912
6918
  var header_default = Header;
6913
6919
 
6914
6920
  // src/components/ui/scroll-area.tsx
6915
- import * as React11 from "react";
6916
- import { jsx as jsx27 } from "react/jsx-runtime";
6917
- var ScrollArea = React11.forwardRef(function ScrollArea2({ className, children, ...props }, ref) {
6918
- return /* @__PURE__ */ jsx27("div", { "data-slot": "scroll-area", ref, className: cn("relative size-full overflow-auto", className), ...props, children });
6919
- });
6920
- var ScrollBar = React11.forwardRef(function ScrollBar2({ className, orientation = "vertical", ...props }, ref) {
6921
+ import "react";
6922
+ import { ScrollArea as ScrollAreaPrimitive } from "radix-ui";
6923
+ import { jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
6924
+ function ScrollArea({
6925
+ className,
6926
+ children,
6927
+ ...props
6928
+ }) {
6929
+ return /* @__PURE__ */ jsxs20(
6930
+ ScrollAreaPrimitive.Root,
6931
+ {
6932
+ "data-slot": "scroll-area",
6933
+ className: cn("relative", className),
6934
+ ...props,
6935
+ children: [
6936
+ /* @__PURE__ */ jsx27(
6937
+ ScrollAreaPrimitive.Viewport,
6938
+ {
6939
+ "data-slot": "scroll-area-viewport",
6940
+ className: "size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1",
6941
+ children
6942
+ }
6943
+ ),
6944
+ /* @__PURE__ */ jsx27(ScrollBar, {}),
6945
+ /* @__PURE__ */ jsx27(ScrollAreaPrimitive.Corner, {})
6946
+ ]
6947
+ }
6948
+ );
6949
+ }
6950
+ function ScrollBar({
6951
+ className,
6952
+ orientation = "vertical",
6953
+ ...props
6954
+ }) {
6921
6955
  return /* @__PURE__ */ jsx27(
6922
- "div",
6956
+ ScrollAreaPrimitive.ScrollAreaScrollbar,
6923
6957
  {
6924
6958
  "data-slot": "scroll-area-scrollbar",
6925
- ref,
6926
- "aria-hidden": "true",
6959
+ orientation,
6927
6960
  className: cn(
6928
- "pointer-events-none absolute opacity-0",
6929
- orientation === "vertical" ? "right-0 top-0 h-full w-0" : "bottom-0 left-0 h-0 w-full",
6961
+ "flex touch-none p-px transition-colors select-none",
6962
+ orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent",
6963
+ orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent",
6930
6964
  className
6931
6965
  ),
6932
- ...props
6966
+ ...props,
6967
+ children: /* @__PURE__ */ jsx27(
6968
+ ScrollAreaPrimitive.ScrollAreaThumb,
6969
+ {
6970
+ "data-slot": "scroll-area-thumb",
6971
+ className: "relative flex-1 rounded-full bg-border"
6972
+ }
6973
+ )
6933
6974
  }
6934
6975
  );
6935
- });
6976
+ }
6936
6977
 
6937
6978
  // src/panels/left/assets/index.tsx
6938
6979
  import { useInputs } from "@timeax/digital-service-engine/react";
@@ -6940,7 +6981,7 @@ import { useWorkspace as useWorkspace8 } from "@timeax/digital-service-engine/wo
6940
6981
  import { useMemo as useMemo11, useState as useState12 } from "react";
6941
6982
  import { CiSearch } from "react-icons/ci";
6942
6983
  import { LuBox, LuShapes } from "react-icons/lu";
6943
- import { jsx as jsx28, jsxs as jsxs20 } from "react/jsx-runtime";
6984
+ import { jsx as jsx28, jsxs as jsxs21 } from "react/jsx-runtime";
6944
6985
  function toTitle(value) {
6945
6986
  return value.split(/[-_:]/g).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
6946
6987
  }
@@ -6972,8 +7013,8 @@ function AssetsPanel() {
6972
7013
  const filteredTemplates = lower ? templates2.filter(
6973
7014
  (item) => item.name.toLowerCase().includes(lower) || String(item.kind ?? "").toLowerCase().includes(lower)
6974
7015
  ) : templates2;
6975
- return /* @__PURE__ */ jsxs20("div", { className: "flex h-full min-h-0 flex-col rounded-2xl border border-slate-200/80 bg-white/90 p-3 shadow-sm dark:border-slate-800 dark:bg-slate-950/80", children: [
6976
- /* @__PURE__ */ jsxs20("label", { className: "relative", children: [
7016
+ return /* @__PURE__ */ jsxs21("div", { className: "flex h-full min-h-0 flex-col rounded-2xl border border-slate-200/80 bg-white/90 p-3 shadow-sm dark:border-slate-800 dark:bg-slate-950/80", children: [
7017
+ /* @__PURE__ */ jsxs21("label", { className: "relative", children: [
6977
7018
  /* @__PURE__ */ jsx28(CiSearch, { className: "pointer-events-none absolute top-1/2 left-3 -translate-y-1/2 text-slate-400" }),
6978
7019
  /* @__PURE__ */ jsx28(
6979
7020
  "input",
@@ -6985,13 +7026,13 @@ function AssetsPanel() {
6985
7026
  }
6986
7027
  )
6987
7028
  ] }),
6988
- /* @__PURE__ */ jsxs20(ScrollArea, { className: "mt-3 min-h-0 flex-1 pr-1", children: [
6989
- /* @__PURE__ */ jsxs20("section", { children: [
6990
- /* @__PURE__ */ jsxs20("h4", { className: "mb-2 flex items-center gap-2 text-xs font-semibold tracking-wide text-slate-500 uppercase dark:text-slate-400", children: [
7029
+ /* @__PURE__ */ jsxs21(ScrollArea, { className: "mt-3 min-h-0 flex-1 pr-1", children: [
7030
+ /* @__PURE__ */ jsxs21("section", { children: [
7031
+ /* @__PURE__ */ jsxs21("h4", { className: "mb-2 flex items-center gap-2 text-xs font-semibold tracking-wide text-slate-500 uppercase dark:text-slate-400", children: [
6991
7032
  /* @__PURE__ */ jsx28(LuShapes, {}),
6992
7033
  "Built-in Inputs"
6993
7034
  ] }),
6994
- /* @__PURE__ */ jsx28("div", { className: "grid grid-cols-2 gap-2", children: filteredBuiltins.length ? filteredBuiltins.map((item) => /* @__PURE__ */ jsxs20(
7035
+ /* @__PURE__ */ jsx28("div", { className: "grid grid-cols-2 gap-2", children: filteredBuiltins.length ? filteredBuiltins.map((item) => /* @__PURE__ */ jsxs21(
6995
7036
  "button",
6996
7037
  {
6997
7038
  type: "button",
@@ -7016,13 +7057,13 @@ function AssetsPanel() {
7016
7057
  item.key
7017
7058
  )) : /* @__PURE__ */ jsx28(EmptyState, { title: "No built-ins", description: "No registry input entries matched your search.", className: "min-h-36" }) })
7018
7059
  ] }),
7019
- /* @__PURE__ */ jsxs20("section", { className: "mt-5", children: [
7020
- /* @__PURE__ */ jsxs20("h4", { className: "mb-2 flex items-center gap-2 text-xs font-semibold tracking-wide text-slate-500 uppercase dark:text-slate-400", children: [
7060
+ /* @__PURE__ */ jsxs21("section", { className: "mt-5", children: [
7061
+ /* @__PURE__ */ jsxs21("h4", { className: "mb-2 flex items-center gap-2 text-xs font-semibold tracking-wide text-slate-500 uppercase dark:text-slate-400", children: [
7021
7062
  /* @__PURE__ */ jsx28(LuBox, {}),
7022
7063
  "Saved Templates"
7023
7064
  ] }),
7024
7065
  /* @__PURE__ */ jsx28(WorkspaceBootInlineNotice, { boot: ws.boot, sections: ["templates"], className: "mb-3" }),
7025
- /* @__PURE__ */ jsx28("div", { className: "grid grid-cols-2 gap-2", children: filteredTemplates.length ? filteredTemplates.map((item) => /* @__PURE__ */ jsxs20(
7066
+ /* @__PURE__ */ jsx28("div", { className: "grid grid-cols-2 gap-2", children: filteredTemplates.length ? filteredTemplates.map((item) => /* @__PURE__ */ jsxs21(
7026
7067
  "button",
7027
7068
  {
7028
7069
  type: "button",
@@ -8232,7 +8273,7 @@ import { VscChevronRight } from "react-icons/vsc";
8232
8273
 
8233
8274
  // src/components/sort-tree/node.tsx
8234
8275
  import * as React21 from "react";
8235
- import { jsx as jsx32, jsxs as jsxs21 } from "react/jsx-runtime";
8276
+ import { jsx as jsx32, jsxs as jsxs22 } from "react/jsx-runtime";
8236
8277
  function Node({ node, matched, isEditing, onCommit, onCancel }) {
8237
8278
  const spanRef = React21.useRef(null);
8238
8279
  React21.useEffect(() => {
@@ -8263,7 +8304,7 @@ function Node({ node, matched, isEditing, onCommit, onCancel }) {
8263
8304
  onCancel?.();
8264
8305
  }
8265
8306
  };
8266
- return /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-2 truncate " + (matched ? "rounded bg-yellow-200/50 px-1" : ""), children: [
8307
+ return /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2 truncate " + (matched ? "rounded bg-yellow-200/50 px-1" : ""), children: [
8267
8308
  node.icon ? /* @__PURE__ */ jsx32("span", { className: "inline-flex items-center", children: node.icon }) : null,
8268
8309
  /* @__PURE__ */ jsx32(
8269
8310
  "span",
@@ -8281,7 +8322,7 @@ function Node({ node, matched, isEditing, onCommit, onCancel }) {
8281
8322
  }
8282
8323
 
8283
8324
  // src/components/sort-tree/node-row.tsx
8284
- import { jsx as jsx33, jsxs as jsxs22 } from "react/jsx-runtime";
8325
+ import { jsx as jsx33, jsxs as jsxs23 } from "react/jsx-runtime";
8285
8326
  function NodeRow({
8286
8327
  node,
8287
8328
  path,
@@ -8312,7 +8353,7 @@ function NodeRow({
8312
8353
  e.stopPropagation();
8313
8354
  callback?.(e);
8314
8355
  };
8315
- return /* @__PURE__ */ jsxs22(
8356
+ return /* @__PURE__ */ jsxs23(
8316
8357
  "div",
8317
8358
  {
8318
8359
  className: ["tree-row", rowClassName || "", isDragging ? "is-dragging" : ""].join(" "),
@@ -8326,7 +8367,7 @@ function NodeRow({
8326
8367
  children: [
8327
8368
  showBinding ? /* @__PURE__ */ jsx33("div", { className: "tree-rail", style: { width: pad }, children: binding.guides.map((g, i) => /* @__PURE__ */ jsx33("span", { className: "tree-col", "data-show": g ? "1" : "0", style: { width: indent } }, i)) }) : /* @__PURE__ */ jsx33("div", { style: { width: pad } }),
8328
8369
  showBinding && /* @__PURE__ */ jsx33("div", { className: "tree-elbow", style: { width: indent } }),
8329
- /* @__PURE__ */ jsx33("div", { className: "min-w-0 flex-1", children: isDragging ? /* @__PURE__ */ jsxs22(
8370
+ /* @__PURE__ */ jsx33("div", { className: "min-w-0 flex-1", children: isDragging ? /* @__PURE__ */ jsxs23(
8330
8371
  "div",
8331
8372
  {
8332
8373
  "aria-hidden": "true",
@@ -8398,7 +8439,7 @@ function NodeRow({
8398
8439
  }
8399
8440
 
8400
8441
  // src/components/sort-tree/internal/render-row.tsx
8401
- import { jsx as jsx34, jsxs as jsxs23 } from "react/jsx-runtime";
8442
+ import { jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
8402
8443
  var ZONE_HEIGHT = 6;
8403
8444
  function useRenderRow(args) {
8404
8445
  const {
@@ -8489,7 +8530,7 @@ function useRenderRow(args) {
8489
8530
  // fallback
8490
8531
  },
8491
8532
  onMouseDown: (e) => onRowPointerDown(e, rIndex, r.node),
8492
- children: /* @__PURE__ */ jsxs23("div", { className: cn(skinClass, activeClassString), style: { borderRadius: "inherit" }, children: [
8533
+ children: /* @__PURE__ */ jsxs24("div", { className: cn(skinClass, activeClassString), style: { borderRadius: "inherit" }, children: [
8493
8534
  /* @__PURE__ */ jsx34(DropZone, { id: zoneId(r.path, "before"), height: ZONE_HEIGHT, onNativeDrop: handleExternalDrop, disabled: disableZones }),
8494
8535
  /* @__PURE__ */ jsx34(OnDroppableWrap, { id: zoneId(r.path, "on"), onNativeDrop: handleExternalDrop, disabled: disableZones, children: /* @__PURE__ */ jsx34(DraggableRow, { id: draggableId, disabled: disabledDrag, children: /* @__PURE__ */ jsx34(
8495
8536
  NodeRow,
@@ -8597,7 +8638,7 @@ function useRenderRow(args) {
8597
8638
  }
8598
8639
 
8599
8640
  // src/components/sort-tree/sort-tree.tsx
8600
- import { jsx as jsx35, jsxs as jsxs24 } from "react/jsx-runtime";
8641
+ import { jsx as jsx35, jsxs as jsxs25 } from "react/jsx-runtime";
8601
8642
  function SortTreeInner(props, ref) {
8602
8643
  const {
8603
8644
  data,
@@ -8890,7 +8931,7 @@ function SortTreeInner(props, ref) {
8890
8931
  loadChildren
8891
8932
  ]
8892
8933
  );
8893
- return /* @__PURE__ */ jsxs24(DndContext, { sensors, onDragStart: handleDragStart, onDragEnd: handleDragEnd, collisionDetection, children: [
8934
+ return /* @__PURE__ */ jsxs25(DndContext, { sensors, onDragStart: handleDragStart, onDragEnd: handleDragEnd, collisionDetection, children: [
8894
8935
  /* @__PURE__ */ jsx35("div", { className, style, tabIndex: 0, onKeyDown, children: height ? /* @__PURE__ */ jsx35(
8895
8936
  List,
8896
8937
  {
@@ -9184,7 +9225,69 @@ import { LuTags as LuTags3 } from "react-icons/lu";
9184
9225
  import { MdOutlineAdd } from "react-icons/md";
9185
9226
  import { RxInput as RxInput3 } from "react-icons/rx";
9186
9227
  import { VscNewFolder } from "react-icons/vsc";
9187
- import { jsx as jsx38, jsxs as jsxs25 } from "react/jsx-runtime";
9228
+
9229
+ // src/panels/left/layers/reorder.ts
9230
+ function isOptionId(id) {
9231
+ return id.startsWith("o:");
9232
+ }
9233
+ function parentPathKey(path) {
9234
+ if (!path?.length) return "";
9235
+ return path.map(String).join("/");
9236
+ }
9237
+ function canDropSameParentOnly(args) {
9238
+ if (!args.from) return true;
9239
+ return parentPathKey(args.from.parentPath) === parentPathKey(args.to.parentPath);
9240
+ }
9241
+ function canDropFieldsSameParentOnly(args) {
9242
+ if (!canDropSameParentOnly(args)) return false;
9243
+ if (!args.dragged) return true;
9244
+ const draggedId = String(args.dragged.id);
9245
+ const parentId = args.to.parent ? String(args.to.parent.id) : "";
9246
+ if (isOptionId(draggedId)) {
9247
+ return parentId.startsWith("f:");
9248
+ }
9249
+ return parentId === "";
9250
+ }
9251
+ function isReorderLike(detail) {
9252
+ return detail.type === "move" || detail.type === "reorder";
9253
+ }
9254
+ function applyTagTreeReorder(detail, editor) {
9255
+ if (!isReorderLike(detail)) return false;
9256
+ detail.preventDefault();
9257
+ editor.placeNode(String(detail.node.id), { index: detail.to.index });
9258
+ return true;
9259
+ }
9260
+ function applyFieldTreeReorder(detail, args) {
9261
+ if (!isReorderLike(detail)) return false;
9262
+ detail.preventDefault();
9263
+ const nodeId = String(detail.node.id);
9264
+ if (isOptionId(nodeId)) {
9265
+ args.editor.placeOption(nodeId, { index: detail.to.index });
9266
+ return true;
9267
+ }
9268
+ const writeAndPlace = () => {
9269
+ args.editor.patchProps?.((props) => {
9270
+ const map = props.order_for_tags ??= {};
9271
+ map[args.currentTagId] = [...args.contextFieldOrder];
9272
+ });
9273
+ args.editor.placeNode(nodeId, {
9274
+ scopeTagId: args.currentTagId,
9275
+ index: detail.to.index
9276
+ });
9277
+ };
9278
+ if (typeof args.editor.transact === "function" && typeof args.editor.patchProps === "function") {
9279
+ args.editor.transact("Reorder field in context", writeAndPlace);
9280
+ return true;
9281
+ }
9282
+ args.editor.placeNode(nodeId, {
9283
+ scopeTagId: args.currentTagId,
9284
+ index: detail.to.index
9285
+ });
9286
+ return true;
9287
+ }
9288
+
9289
+ // src/panels/left/layers/index.tsx
9290
+ import { jsx as jsx38, jsxs as jsxs26 } from "react/jsx-runtime";
9188
9291
  function filterTree(nodes, query) {
9189
9292
  if (!query.trim()) return nodes;
9190
9293
  const lower = query.toLowerCase();
@@ -9223,6 +9326,7 @@ var Layers = () => {
9223
9326
  canvas.api.addToSelection(ids);
9224
9327
  };
9225
9328
  const handleTagChange = (_next, detail) => {
9329
+ if (applyTagTreeReorder(detail, canvas.api.editor)) return;
9226
9330
  detail.preventDefault?.();
9227
9331
  if (detail.type === "update") {
9228
9332
  canvas.api.editor.editLabel(detail.node.id, detail.node.title);
@@ -9234,6 +9338,13 @@ var Layers = () => {
9234
9338
  }
9235
9339
  };
9236
9340
  const handleFieldChange = (_next, detail) => {
9341
+ if (applyFieldTreeReorder(detail, {
9342
+ editor: canvas.api.editor,
9343
+ currentTagId: canvas.api.selection.currentTag?.() ?? "t:root",
9344
+ contextFieldOrder: canvas.layers.fields.map((node) => String(node.id)).filter((id) => !id.startsWith("o:"))
9345
+ })) {
9346
+ return;
9347
+ }
9237
9348
  if (detail.type === "update") {
9238
9349
  detail.preventDefault();
9239
9350
  canvas.api.editor.editLabel(detail.node.id, detail.node.title);
@@ -9262,7 +9373,7 @@ var Layers = () => {
9262
9373
  const handleFieldSearchBlur = () => {
9263
9374
  if (!fieldSearch.trim()) setIsFieldSearchOpen(false);
9264
9375
  };
9265
- return /* @__PURE__ */ jsxs25("div", { className: "flex h-full min-h-0 flex-1 flex-col overflow-hidden rounded-2xl border border-slate-200/80 bg-white/90 shadow-sm dark:border-slate-800 dark:bg-slate-950/80", children: [
9376
+ return /* @__PURE__ */ jsxs26("div", { className: "flex h-full min-h-0 flex-1 flex-col overflow-hidden rounded-2xl border border-slate-200/80 bg-white/90 shadow-sm dark:border-slate-800 dark:bg-slate-950/80", children: [
9266
9377
  /* @__PURE__ */ jsx38(
9267
9378
  Panel,
9268
9379
  {
@@ -9271,13 +9382,13 @@ var Layers = () => {
9271
9382
  minHeight: 180,
9272
9383
  maxHeight: 520,
9273
9384
  className: "flex min-h-45 flex-col rounded-none! border-b border-slate-200/80 bg-transparent dark:border-slate-800",
9274
- children: /* @__PURE__ */ jsxs25("section", { className: "flex min-h-0 flex-1 flex-col px-4 pt-4 pb-3", children: [
9275
- /* @__PURE__ */ jsxs25("div", { className: "flex items-start justify-between gap-3", children: [
9276
- /* @__PURE__ */ jsxs25("div", { className: "min-w-0", children: [
9385
+ children: /* @__PURE__ */ jsxs26("section", { className: "flex min-h-0 flex-1 flex-col px-4 pt-4 pb-3", children: [
9386
+ /* @__PURE__ */ jsxs26("div", { className: "flex items-start justify-between gap-3", children: [
9387
+ /* @__PURE__ */ jsxs26("div", { className: "min-w-0", children: [
9277
9388
  /* @__PURE__ */ jsx38("h3", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: "Tag hierarchy" }),
9278
9389
  /* @__PURE__ */ jsx38("p", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: "Structure the visible groups and inheritance tree." })
9279
9390
  ] }),
9280
- /* @__PURE__ */ jsxs25("div", { className: "flex items-center gap-1", children: [
9391
+ /* @__PURE__ */ jsxs26("div", { className: "flex items-center gap-1", children: [
9281
9392
  /* @__PURE__ */ jsx38(
9282
9393
  "button",
9283
9394
  {
@@ -9298,7 +9409,7 @@ var Layers = () => {
9298
9409
  )
9299
9410
  ] })
9300
9411
  ] }),
9301
- /* @__PURE__ */ jsxs25("div", { className: "mt-3 flex min-h-0 flex-1 flex-col gap-3", children: [
9412
+ /* @__PURE__ */ jsxs26("div", { className: "mt-3 flex min-h-0 flex-1 flex-col gap-3", children: [
9302
9413
  isTagSearchOpen || hasTagSearch ? /* @__PURE__ */ jsx38(
9303
9414
  PanelSearch,
9304
9415
  {
@@ -9328,6 +9439,7 @@ var Layers = () => {
9328
9439
  value: canvas.selectionInfo.tagIds,
9329
9440
  rowClassName: "mb-1 rounded-xl border border-transparent px-1 hover:border-slate-200 hover:bg-slate-50 dark:hover:border-slate-800 dark:hover:bg-slate-900/70",
9330
9441
  data: tags,
9442
+ canDrop: canDropSameParentOnly,
9331
9443
  activeClassName: (e) => e.node.id === canvas.activeId ? "border-blue-300! bg-blue-50/80 dark:border-blue-500/40! dark:bg-blue-500/10!" : "",
9332
9444
  onChange: handleTagChange,
9333
9445
  onContextMenu: (detail) => {
@@ -9356,13 +9468,13 @@ var Layers = () => {
9356
9468
  ] })
9357
9469
  }
9358
9470
  ),
9359
- /* @__PURE__ */ jsxs25("section", { className: "flex min-h-0 flex-1 flex-col px-4 pt-3 pb-4", children: [
9360
- /* @__PURE__ */ jsxs25("div", { className: "flex items-start justify-between gap-3", children: [
9361
- /* @__PURE__ */ jsxs25("div", { className: "min-w-0", children: [
9471
+ /* @__PURE__ */ jsxs26("section", { className: "flex min-h-0 flex-1 flex-col px-4 pt-3 pb-4", children: [
9472
+ /* @__PURE__ */ jsxs26("div", { className: "flex items-start justify-between gap-3", children: [
9473
+ /* @__PURE__ */ jsxs26("div", { className: "min-w-0", children: [
9362
9474
  /* @__PURE__ */ jsx38("h3", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: "Fields in view" }),
9363
9475
  /* @__PURE__ */ jsx38("p", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: `Under ${activeTagLabel}` })
9364
9476
  ] }),
9365
- /* @__PURE__ */ jsxs25("div", { className: "flex items-center gap-1", children: [
9477
+ /* @__PURE__ */ jsxs26("div", { className: "flex items-center gap-1", children: [
9366
9478
  /* @__PURE__ */ jsx38(
9367
9479
  "button",
9368
9480
  {
@@ -9404,7 +9516,7 @@ var Layers = () => {
9404
9516
  )
9405
9517
  ] })
9406
9518
  ] }),
9407
- /* @__PURE__ */ jsxs25("div", { className: "mt-3 flex min-h-0 flex-1 flex-col gap-3", children: [
9519
+ /* @__PURE__ */ jsxs26("div", { className: "mt-3 flex min-h-0 flex-1 flex-col gap-3", children: [
9408
9520
  isFieldSearchOpen || hasFieldSearch ? /* @__PURE__ */ jsx38(
9409
9521
  PanelSearch,
9410
9522
  {
@@ -9448,6 +9560,7 @@ var Layers = () => {
9448
9560
  value: [...canvas.selectionInfo.fieldIds, ...canvas.selectionInfo.optionIds],
9449
9561
  rowClassName: "mb-1 rounded-xl border border-transparent px-1 hover:border-slate-200 hover:bg-slate-50 dark:hover:border-slate-800 dark:hover:bg-slate-900/70",
9450
9562
  data: fields,
9563
+ canDrop: canDropFieldsSameParentOnly,
9451
9564
  onChange: handleFieldChange,
9452
9565
  onContextMenu: (detail) => {
9453
9566
  const nodeId = String(detail.node.id);
@@ -9547,7 +9660,7 @@ function TabsContent({
9547
9660
  // src/panels/left/index.tsx
9548
9661
  import { CiGrid32 } from "react-icons/ci";
9549
9662
  import { MdOutlineLayers } from "react-icons/md";
9550
- import { jsx as jsx40, jsxs as jsxs26 } from "react/jsx-runtime";
9663
+ import { jsx as jsx40, jsxs as jsxs27 } from "react/jsx-runtime";
9551
9664
  var Left = ({ menu }) => {
9552
9665
  const tabClassName = cn(
9553
9666
  "rounded-xl! py-2! shadow-none!",
@@ -9561,15 +9674,15 @@ var Left = ({ menu }) => {
9561
9674
  edges: ["right"],
9562
9675
  maxWidth: 420,
9563
9676
  minWidth: 320,
9564
- children: /* @__PURE__ */ jsxs26("div", { className: "flex h-full flex-col", children: [
9677
+ children: /* @__PURE__ */ jsxs27("div", { className: "flex h-full flex-col", children: [
9565
9678
  /* @__PURE__ */ jsx40(header_default, { menu }),
9566
- /* @__PURE__ */ jsx40("div", { className: "flex min-h-0 flex-1 flex-col gap-2 py-2", children: /* @__PURE__ */ jsxs26(Tabs, { defaultValue: "layers", className: "flex min-h-0 flex-1 flex-col px-3", children: [
9567
- /* @__PURE__ */ jsxs26(TabsList, { className: "grid h-auto grid-cols-2 rounded-2xl bg-slate-100 p-1 dark:bg-slate-900", children: [
9568
- /* @__PURE__ */ jsx40(TabsTrigger, { className: tabClassName, value: "layers", children: /* @__PURE__ */ jsxs26("span", { className: "flex items-center gap-2", children: [
9679
+ /* @__PURE__ */ jsx40("div", { className: "flex min-h-0 flex-1 flex-col gap-2 py-2", children: /* @__PURE__ */ jsxs27(Tabs, { defaultValue: "layers", className: "flex min-h-0 flex-1 flex-col px-3", children: [
9680
+ /* @__PURE__ */ jsxs27(TabsList, { className: "grid h-auto grid-cols-2 rounded-2xl bg-slate-100 p-1 dark:bg-slate-900", children: [
9681
+ /* @__PURE__ */ jsx40(TabsTrigger, { className: tabClassName, value: "layers", children: /* @__PURE__ */ jsxs27("span", { className: "flex items-center gap-2", children: [
9569
9682
  /* @__PURE__ */ jsx40(MdOutlineLayers, {}),
9570
9683
  /* @__PURE__ */ jsx40("span", { children: "Layers" })
9571
9684
  ] }) }),
9572
- /* @__PURE__ */ jsx40(TabsTrigger, { className: tabClassName, value: "assets", children: /* @__PURE__ */ jsxs26("span", { className: "flex items-center gap-2", children: [
9685
+ /* @__PURE__ */ jsx40(TabsTrigger, { className: tabClassName, value: "assets", children: /* @__PURE__ */ jsxs27("span", { className: "flex items-center gap-2", children: [
9573
9686
  /* @__PURE__ */ jsx40(CiGrid32, {}),
9574
9687
  /* @__PURE__ */ jsx40("span", { children: "Assets" })
9575
9688
  ] }) })
@@ -9589,7 +9702,7 @@ import { useMemo as useMemo18 } from "react";
9589
9702
  import { GoChevronDown } from "react-icons/go";
9590
9703
  import { HiOutlineDotsHorizontal } from "react-icons/hi";
9591
9704
  import { PiUserPlusThin } from "react-icons/pi";
9592
- import { jsx as jsx41, jsxs as jsxs27 } from "react/jsx-runtime";
9705
+ import { jsx as jsx41, jsxs as jsxs28 } from "react/jsx-runtime";
9593
9706
  function getInitials(name) {
9594
9707
  const parts = name.trim().split(/\s+/).filter(Boolean);
9595
9708
  if (!parts.length) return "?";
@@ -9651,22 +9764,22 @@ var Users = ({ users, onViewUser, onSetMain, onToggleAdmin, onRemoveUser, onInvi
9651
9764
  return bScore - aScore || a.name.localeCompare(b.name);
9652
9765
  });
9653
9766
  }, [users]);
9654
- return /* @__PURE__ */ jsxs27(Popover, { children: [
9655
- /* @__PURE__ */ jsx41(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs27(
9767
+ return /* @__PURE__ */ jsxs28(Popover, { children: [
9768
+ /* @__PURE__ */ jsx41(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs28(
9656
9769
  "button",
9657
9770
  {
9658
9771
  type: "button",
9659
9772
  className: "flex items-center gap-2 rounded-xl border border-transparent px-1 py-1 transition hover:border-slate-200 hover:bg-white dark:hover:border-slate-800 dark:hover:bg-slate-950",
9660
9773
  children: [
9661
- /* @__PURE__ */ jsxs27("div", { className: "flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-white dark:*:data-[slot=avatar]:ring-slate-950", children: [
9662
- visibleUsers.map((user) => /* @__PURE__ */ jsxs27("div", { className: "relative", children: [
9663
- /* @__PURE__ */ jsxs27(Avatar, { className: "h-8 w-8", children: [
9774
+ /* @__PURE__ */ jsxs28("div", { className: "flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-white dark:*:data-[slot=avatar]:ring-slate-950", children: [
9775
+ visibleUsers.map((user) => /* @__PURE__ */ jsxs28("div", { className: "relative", children: [
9776
+ /* @__PURE__ */ jsxs28(Avatar, { className: "h-8 w-8", children: [
9664
9777
  /* @__PURE__ */ jsx41(AvatarImage, { src: user.avatar, alt: user.name }),
9665
9778
  /* @__PURE__ */ jsx41(AvatarFallback, { children: getInitials(user.name) })
9666
9779
  ] }),
9667
9780
  user.isOnline ? /* @__PURE__ */ jsx41("span", { className: "absolute right-0 bottom-0 h-2 w-2 rounded-full bg-emerald-500 ring-2 ring-white dark:ring-slate-950" }) : null
9668
9781
  ] }, user.id)),
9669
- extra > 0 ? /* @__PURE__ */ jsxs27("div", { className: "flex h-8 w-8 items-center justify-center rounded-full border border-dashed border-slate-300 bg-slate-100 text-xs font-medium text-slate-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-300", children: [
9782
+ extra > 0 ? /* @__PURE__ */ jsxs28("div", { className: "flex h-8 w-8 items-center justify-center rounded-full border border-dashed border-slate-300 bg-slate-100 text-xs font-medium text-slate-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-300", children: [
9670
9783
  "+",
9671
9784
  extra
9672
9785
  ] }) : null
@@ -9675,14 +9788,14 @@ var Users = ({ users, onViewUser, onSetMain, onToggleAdmin, onRemoveUser, onInvi
9675
9788
  ]
9676
9789
  }
9677
9790
  ) }),
9678
- /* @__PURE__ */ jsxs27(PopoverContent, { align: "start", className: "w-[380px] rounded-3xl border-slate-200 bg-white/98 p-0 shadow-2xl dark:border-slate-800 dark:bg-slate-950/98", children: [
9679
- /* @__PURE__ */ jsx41("div", { className: "border-b border-slate-200 px-4 py-4 dark:border-slate-800", children: /* @__PURE__ */ jsxs27("div", { className: "flex items-start justify-between gap-3", children: [
9680
- /* @__PURE__ */ jsxs27("div", { children: [
9791
+ /* @__PURE__ */ jsxs28(PopoverContent, { align: "start", className: "w-[380px] rounded-3xl border-slate-200 bg-white/98 p-0 shadow-2xl dark:border-slate-800 dark:bg-slate-950/98", children: [
9792
+ /* @__PURE__ */ jsx41("div", { className: "border-b border-slate-200 px-4 py-4 dark:border-slate-800", children: /* @__PURE__ */ jsxs28("div", { className: "flex items-start justify-between gap-3", children: [
9793
+ /* @__PURE__ */ jsxs28("div", { children: [
9681
9794
  /* @__PURE__ */ jsx41("div", { className: "text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-400 dark:text-slate-500", children: "Collaborators" }),
9682
9795
  /* @__PURE__ */ jsx41("h3", { className: "mt-1 text-base font-semibold text-slate-900 dark:text-slate-100", children: "Branch authors" }),
9683
9796
  /* @__PURE__ */ jsx41("p", { className: "mt-1 text-sm text-slate-500 dark:text-slate-400", children: "Presence, roles, and access for the active branch." })
9684
9797
  ] }),
9685
- /* @__PURE__ */ jsxs27(
9798
+ /* @__PURE__ */ jsxs28(
9686
9799
  Button,
9687
9800
  {
9688
9801
  type: "button",
@@ -9704,9 +9817,9 @@ var Users = ({ users, onViewUser, onSetMain, onToggleAdmin, onRemoveUser, onInvi
9704
9817
  "div",
9705
9818
  {
9706
9819
  className: "rounded-2xl border border-slate-200/80 bg-slate-50/80 p-3 shadow-sm dark:border-slate-800 dark:bg-slate-900/70",
9707
- children: /* @__PURE__ */ jsxs27("div", { className: "flex items-start gap-3", children: [
9708
- /* @__PURE__ */ jsxs27("div", { className: "relative", children: [
9709
- /* @__PURE__ */ jsxs27(Avatar, { className: "h-11 w-11 border border-white shadow-sm dark:border-slate-950", children: [
9820
+ children: /* @__PURE__ */ jsxs28("div", { className: "flex items-start gap-3", children: [
9821
+ /* @__PURE__ */ jsxs28("div", { className: "relative", children: [
9822
+ /* @__PURE__ */ jsxs28(Avatar, { className: "h-11 w-11 border border-white shadow-sm dark:border-slate-950", children: [
9710
9823
  /* @__PURE__ */ jsx41(AvatarImage, { src: user.avatar, alt: user.name }),
9711
9824
  /* @__PURE__ */ jsx41(AvatarFallback, { children: getInitials(user.name) })
9712
9825
  ] }),
@@ -9720,9 +9833,9 @@ var Users = ({ users, onViewUser, onSetMain, onToggleAdmin, onRemoveUser, onInvi
9720
9833
  }
9721
9834
  )
9722
9835
  ] }),
9723
- /* @__PURE__ */ jsxs27("div", { className: "min-w-0 flex-1", children: [
9724
- /* @__PURE__ */ jsxs27("div", { className: "flex items-start justify-between gap-3", children: [
9725
- /* @__PURE__ */ jsxs27("div", { className: "min-w-0", children: [
9836
+ /* @__PURE__ */ jsxs28("div", { className: "min-w-0 flex-1", children: [
9837
+ /* @__PURE__ */ jsxs28("div", { className: "flex items-start justify-between gap-3", children: [
9838
+ /* @__PURE__ */ jsxs28("div", { className: "min-w-0", children: [
9726
9839
  /* @__PURE__ */ jsx41("div", { className: "truncate text-sm font-semibold text-slate-900 dark:text-slate-100", children: user.name }),
9727
9840
  /* @__PURE__ */ jsx41("div", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: statusLabel })
9728
9841
  ] }),
@@ -9748,7 +9861,7 @@ var Users = ({ users, onViewUser, onSetMain, onToggleAdmin, onRemoveUser, onInvi
9748
9861
  }
9749
9862
  )
9750
9863
  ] }),
9751
- /* @__PURE__ */ jsxs27("div", { className: "mt-3 flex flex-wrap gap-2", children: [
9864
+ /* @__PURE__ */ jsxs28("div", { className: "mt-3 flex flex-wrap gap-2", children: [
9752
9865
  (user.roles?.length ? user.roles : ["viewer"]).map((role) => /* @__PURE__ */ jsx41("span", { className: cn("rounded-full border px-2.5 py-1 text-[11px] font-semibold capitalize", roleClass(role)), children: formatRole(role) }, `${user.id}-${role}`)),
9753
9866
  /* @__PURE__ */ jsx41("span", { className: "rounded-full border border-slate-200 bg-white px-2.5 py-1 text-[11px] font-medium text-slate-500 dark:border-slate-700 dark:bg-slate-950 dark:text-slate-300", children: permissionsLabel })
9754
9867
  ] })
@@ -9768,7 +9881,7 @@ import { useCanvas as useCanvas6, useWorkspace as useWorkspace9 } from "@timeax/
9768
9881
  import { useMemo as useMemo19 } from "react";
9769
9882
  import { MdOutlinePlayArrow } from "react-icons/md";
9770
9883
  import { PiShareFatThin } from "react-icons/pi";
9771
- import { jsx as jsx42, jsxs as jsxs28 } from "react/jsx-runtime";
9884
+ import { jsx as jsx42, jsxs as jsxs29 } from "react/jsx-runtime";
9772
9885
  var Header2 = ({ onShare, onPlay }) => {
9773
9886
  const ws = useWorkspace9();
9774
9887
  const canvas = useCanvas6();
@@ -9803,8 +9916,8 @@ var Header2 = ({ onShare, onPlay }) => {
9803
9916
  const onShareClick = () => {
9804
9917
  onShare?.(ws.snapshot.data);
9805
9918
  };
9806
- return /* @__PURE__ */ jsxs28("div", { className: "flex items-center justify-between gap-3 border-b border-slate-200 px-3 py-3 dark:border-slate-800", children: [
9807
- /* @__PURE__ */ jsxs28("div", { className: "min-w-0 flex items-center gap-3", children: [
9919
+ return /* @__PURE__ */ jsxs29("div", { className: "flex items-center justify-between gap-3 border-b border-slate-200 px-3 py-3 dark:border-slate-800", children: [
9920
+ /* @__PURE__ */ jsxs29("div", { className: "min-w-0 flex items-center gap-3", children: [
9808
9921
  /* @__PURE__ */ jsx42(users_default, { users }),
9809
9922
  /* @__PURE__ */ jsx42(
9810
9923
  BuilderIconButton,
@@ -9866,7 +9979,7 @@ function CollapsibleContent2({
9866
9979
  import { InputField as InputField3 } from "@timeax/form-palette";
9867
9980
  import * as React28 from "react";
9868
9981
  import { createCache as createCache2, createIndexedDBDriver as createIndexedDBDriver2, createMemoryDriver as createMemoryDriver2 } from "@timeax/cache-store";
9869
- import { jsx as jsx44, jsxs as jsxs29 } from "react/jsx-runtime";
9982
+ import { jsx as jsx44, jsxs as jsxs30 } from "react/jsx-runtime";
9870
9983
  var OPEN_DB_NAME = "dgp-cache";
9871
9984
  var OPEN_STORE_NAME = "kv";
9872
9985
  var OPEN_NS = "comment-thread-open";
@@ -9949,7 +10062,7 @@ function PersonAvatar({
9949
10062
  sizeClass = "h-8 w-8",
9950
10063
  fallback
9951
10064
  }) {
9952
- return /* @__PURE__ */ jsxs29(Avatar, { className: sizeClass, children: [
10065
+ return /* @__PURE__ */ jsxs30(Avatar, { className: sizeClass, children: [
9953
10066
  person.avatar?.src ? /* @__PURE__ */ jsx44(AvatarImage, { src: person.avatar.src, alt: person.avatar.alt ?? `Avatar of ${person.name}` }) : null,
9954
10067
  /* @__PURE__ */ jsx44(AvatarFallback, { children: fallback ?? initials(person.name) })
9955
10068
  ] });
@@ -9961,7 +10074,7 @@ function ReplyInputRow({
9961
10074
  onSubmit,
9962
10075
  className
9963
10076
  }) {
9964
- return /* @__PURE__ */ jsxs29("div", { className: cx("flex items-center gap-3", className), children: [
10077
+ return /* @__PURE__ */ jsxs30("div", { className: cx("flex items-center gap-3", className), children: [
9965
10078
  /* @__PURE__ */ jsx44(PersonAvatar, { person: { name: you.name, avatar: you.avatar }, fallback: initials(you.name) }),
9966
10079
  /* @__PURE__ */ jsx44(
9967
10080
  InputField3,
@@ -9982,10 +10095,10 @@ function ReplyInputRow({
9982
10095
  }
9983
10096
  function CommentItem({ msg, identities, formatTime }) {
9984
10097
  const author = resolveAuthor(msg, identities);
9985
- return /* @__PURE__ */ jsxs29("div", { className: "flex items-start gap-3", children: [
10098
+ return /* @__PURE__ */ jsxs30("div", { className: "flex items-start gap-3", children: [
9986
10099
  /* @__PURE__ */ jsx44(PersonAvatar, { person: author }),
9987
- /* @__PURE__ */ jsxs29("div", { className: "flex-1", children: [
9988
- /* @__PURE__ */ jsxs29("div", { className: "flex items-center justify-between", children: [
10100
+ /* @__PURE__ */ jsxs30("div", { className: "flex-1", children: [
10101
+ /* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-between", children: [
9989
10102
  /* @__PURE__ */ jsx44("p", { className: "text-sm font-semibold text-gray-800 dark:text-white", children: author.name }),
9990
10103
  /* @__PURE__ */ jsx44("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: formatTime(msg.createdAt) })
9991
10104
  ] }),
@@ -10007,7 +10120,7 @@ function CommentThreadView({ thread, identities, you, highlight, formatTime, onR
10007
10120
  };
10008
10121
  if (!main) return null;
10009
10122
  const [open, setOpen] = useThreadOpenState(thread.id, true);
10010
- return /* @__PURE__ */ jsxs29(
10123
+ return /* @__PURE__ */ jsxs30(
10011
10124
  "div",
10012
10125
  {
10013
10126
  className: cx(
@@ -10015,11 +10128,11 @@ function CommentThreadView({ thread, identities, you, highlight, formatTime, onR
10015
10128
  ),
10016
10129
  children: [
10017
10130
  isHighlighted ? /* @__PURE__ */ jsx44(ActiveDot, {}) : null,
10018
- /* @__PURE__ */ jsxs29(Collapsible, { open, onOpenChange: setOpen, children: [
10131
+ /* @__PURE__ */ jsxs30(Collapsible, { open, onOpenChange: setOpen, children: [
10019
10132
  /* @__PURE__ */ jsx44(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsx44("div", { className: "px-3 py-4", children: /* @__PURE__ */ jsx44(CommentItem, { msg: main, identities, formatTime: fmt }) }) }),
10020
- /* @__PURE__ */ jsx44(CollapsibleContent2, { children: /* @__PURE__ */ jsx44("div", { className: "border-t border-gray-200 bg-gray-50 p-4 pl-6 dark:border-gray-700 dark:bg-gray-800/50", children: /* @__PURE__ */ jsxs29("div", { className: "flex items-start gap-4", children: [
10133
+ /* @__PURE__ */ jsx44(CollapsibleContent2, { children: /* @__PURE__ */ jsx44("div", { className: "border-t border-gray-200 bg-gray-50 p-4 pl-6 dark:border-gray-700 dark:bg-gray-800/50", children: /* @__PURE__ */ jsxs30("div", { className: "flex items-start gap-4", children: [
10021
10134
  /* @__PURE__ */ jsx44("div", { className: "ml-1 w-px shrink-0 self-stretch bg-gray-300 dark:bg-gray-600" }),
10022
- /* @__PURE__ */ jsxs29("div", { className: "flex-1 space-y-4", children: [
10135
+ /* @__PURE__ */ jsxs30("div", { className: "flex-1 space-y-4", children: [
10023
10136
  replies.map((r) => /* @__PURE__ */ jsx44(CommentItem, { msg: r, identities, formatTime: fmt }, r.id)),
10024
10137
  /* @__PURE__ */ jsx44(ReplyInputRow, { id: thread.id, you, value, setValue, onSubmit: submit })
10025
10138
  ] })
@@ -10030,7 +10143,7 @@ function CommentThreadView({ thread, identities, you, highlight, formatTime, onR
10030
10143
  );
10031
10144
  }
10032
10145
  function ActiveDot() {
10033
- return /* @__PURE__ */ jsxs29("span", { className: "absolute -top-1.5 -left-1.5 flex h-3 w-3", children: [
10146
+ return /* @__PURE__ */ jsxs30("span", { className: "absolute -top-1.5 -left-1.5 flex h-3 w-3", children: [
10034
10147
  /* @__PURE__ */ jsx44("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-primary opacity-75" }),
10035
10148
  /* @__PURE__ */ jsx44("span", { className: "relative inline-flex h-3 w-3 rounded-full bg-primary" })
10036
10149
  ] });
@@ -10041,7 +10154,7 @@ import { useWorkspace as useWorkspace10 } from "@timeax/digital-service-engine/w
10041
10154
  import { InputField as InputField4 } from "@timeax/form-palette";
10042
10155
  import { useMemo as useMemo21, useState as useState22 } from "react";
10043
10156
  import { MdOutlineSend } from "react-icons/md";
10044
- import { jsx as jsx45, jsxs as jsxs30 } from "react/jsx-runtime";
10157
+ import { jsx as jsx45, jsxs as jsxs31 } from "react/jsx-runtime";
10045
10158
  var Comments = () => {
10046
10159
  const ws = useWorkspace10();
10047
10160
  const [value, setValue] = useState22("");
@@ -10054,12 +10167,12 @@ var Comments = () => {
10054
10167
  (thread) => thread.messages.some((message) => `${message.authorName ?? ""} ${message.body}`.toLowerCase().includes(lower))
10055
10168
  );
10056
10169
  }, [ws.comments.threads.data, query]);
10057
- return /* @__PURE__ */ jsxs30("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
10058
- /* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-between px-4 pt-4", children: [
10170
+ return /* @__PURE__ */ jsxs31("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
10171
+ /* @__PURE__ */ jsxs31("div", { className: "flex items-center justify-between px-4 pt-4", children: [
10059
10172
  /* @__PURE__ */ jsx45("div", { children: /* @__PURE__ */ jsx45("h3", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: "All comments" }) }),
10060
10173
  /* @__PURE__ */ jsx45("button", { className: "text-xs font-semibold text-blue-600 hover:underline dark:text-blue-300", children: "Mark as read" })
10061
10174
  ] }),
10062
- /* @__PURE__ */ jsxs30("div", { className: "px-4 pt-3", children: [
10175
+ /* @__PURE__ */ jsxs31("div", { className: "px-4 pt-3", children: [
10063
10176
  /* @__PURE__ */ jsx45(PanelSearch, { value: query, onChange: setQuery, placeholder: "Search comments or authors" }),
10064
10177
  /* @__PURE__ */ jsx45(WorkspaceBootInlineNotice, { boot: ws.boot, sections: ["comments"], className: "mt-3" })
10065
10178
  ] }),
@@ -10098,7 +10211,7 @@ var Comments = () => {
10098
10211
  branchId: ws.branches.currentId
10099
10212
  }).finally(() => setValue(""));
10100
10213
  },
10101
- className: "cursor-pointer rounded-xl bg-blue-600 px-3 py-2 text-white transition hover:bg-blue-700",
10214
+ className: "cursor-pointer rounded-full bg-blue-600 px-2 py-2 text-white transition hover:bg-blue-700",
10102
10215
  disabled: !ws.boot.isReady,
10103
10216
  children: /* @__PURE__ */ jsx45(MdOutlineSend, {})
10104
10217
  }
@@ -10167,7 +10280,7 @@ function FieldLabel(props) {
10167
10280
  import * as React31 from "react";
10168
10281
  import { MdOutlineOpenInNew, MdOutlineRemoveCircleOutline } from "react-icons/md";
10169
10282
  import { TiWarning } from "react-icons/ti";
10170
- import { jsx as jsx48, jsxs as jsxs31 } from "react/jsx-runtime";
10283
+ import { jsx as jsx48, jsxs as jsxs32 } from "react/jsx-runtime";
10171
10284
  var SectionCtx = React31.createContext(null);
10172
10285
  function useSectionCtx() {
10173
10286
  const ctx = React31.useContext(SectionCtx);
@@ -10223,7 +10336,7 @@ var Section = Object.assign(SectionRoot, {
10223
10336
  });
10224
10337
  function buildSectionActionButton({ className, icon, tooltip, iconOnly = false, badge, children, ...props }, ref) {
10225
10338
  const derivedAriaLabel = props["aria-label"] ?? (typeof tooltip === "string" ? tooltip : typeof children === "string" ? children : typeof props.title === "string" ? props.title : void 0);
10226
- const button = /* @__PURE__ */ jsxs31(
10339
+ const button = /* @__PURE__ */ jsxs32(
10227
10340
  "button",
10228
10341
  {
10229
10342
  ref,
@@ -10245,7 +10358,7 @@ function buildSectionActionButton({ className, icon, tooltip, iconOnly = false,
10245
10358
  }
10246
10359
  );
10247
10360
  if (!tooltip) return button;
10248
- return /* @__PURE__ */ jsxs31(Tooltip, { children: [
10361
+ return /* @__PURE__ */ jsxs32(Tooltip, { children: [
10249
10362
  /* @__PURE__ */ jsx48(TooltipTrigger, { asChild: true, children: button }),
10250
10363
  /* @__PURE__ */ jsx48(TooltipContent, { side: "bottom", children: tooltip })
10251
10364
  ] });
@@ -10260,8 +10373,8 @@ function IncludesList({ className, children }) {
10260
10373
  return /* @__PURE__ */ jsx48("div", { className: cn("space-y-2", className), children });
10261
10374
  }
10262
10375
  function IncludesItem({ title, badge, actions, className }) {
10263
- return /* @__PURE__ */ jsxs31("div", { className: cn("flex items-center justify-between rounded-md p-2", "bg-gray-50 dark:bg-gray-800/50", className), children: [
10264
- /* @__PURE__ */ jsxs31("div", { className: "flex min-w-0 items-center gap-2", children: [
10376
+ return /* @__PURE__ */ jsxs32("div", { className: cn("flex items-center justify-between rounded-md p-2", "bg-gray-50 dark:bg-gray-800/50", className), children: [
10377
+ /* @__PURE__ */ jsxs32("div", { className: "flex min-w-0 items-center gap-2", children: [
10265
10378
  /* @__PURE__ */ jsx48("span", { className: "truncate text-sm text-gray-800 dark:text-gray-200", children: title }),
10266
10379
  badge
10267
10380
  ] }),
@@ -10274,8 +10387,8 @@ function IncludesItemMissing({
10274
10387
  className,
10275
10388
  icon
10276
10389
  }) {
10277
- return /* @__PURE__ */ jsxs31("div", { className: cn("flex items-center justify-between rounded-md p-2", "bg-red-50 dark:bg-red-900/20", className), children: [
10278
- /* @__PURE__ */ jsxs31("div", { className: "flex min-w-0 items-center gap-2", children: [
10390
+ return /* @__PURE__ */ jsxs32("div", { className: cn("flex items-center justify-between rounded-md p-2", "bg-red-50 dark:bg-red-900/20", className), children: [
10391
+ /* @__PURE__ */ jsxs32("div", { className: "flex min-w-0 items-center gap-2", children: [
10279
10392
  /* @__PURE__ */ jsx48("span", { className: "shrink-0 text-base text-red-500 dark:text-red-400", children: icon ?? /* @__PURE__ */ jsx48("span", { className: "material-symbols-outlined", children: /* @__PURE__ */ jsx48(TiWarning, {}) }) }),
10280
10393
  /* @__PURE__ */ jsx48("span", { className: "truncate text-sm text-red-700 dark:text-red-300", children: message })
10281
10394
  ] }),
@@ -10310,6 +10423,161 @@ function IncludesIconAction({ kind, onClick, disabled, title, icon, className })
10310
10423
  );
10311
10424
  }
10312
10425
 
10426
+ // src/builder/service-context.ts
10427
+ import { createBuilder } from "@timeax/digital-service-engine/core";
10428
+ function createDefaultServiceContext(props, preferredTagId) {
10429
+ const tagIds = (props?.filters ?? []).map((tag) => tag.id);
10430
+ return {
10431
+ selectedTagId: preferredTagId && tagIds.includes(preferredTagId) ? preferredTagId : tagIds[0] ?? null,
10432
+ selectedButtons: [],
10433
+ strictSafety: true,
10434
+ enforcePolicies: true
10435
+ };
10436
+ }
10437
+ function sanitizeServiceContext(snapshot, state) {
10438
+ const allowed = new Set(snapshot.buttonGroups.flatMap((group) => group.options.map((option) => option.id)));
10439
+ const selectedButtons = state.selectedButtons.filter((id) => allowed.has(id));
10440
+ if (selectedButtons.length === state.selectedButtons.length) return state;
10441
+ return { ...state, selectedButtons };
10442
+ }
10443
+ function buildServiceContextSnapshot(args) {
10444
+ const props = args.props ?? void 0;
10445
+ const serviceMap = args.services ?? {};
10446
+ const tags = (props?.filters ?? []).map((tag) => ({
10447
+ id: tag.id,
10448
+ label: tag.label,
10449
+ description: describeTag(tag)
10450
+ }));
10451
+ const selectedTag = (props?.filters ?? []).find((tag) => tag.id === args.state.selectedTagId) ?? null;
10452
+ if (!props || !selectedTag) {
10453
+ return {
10454
+ state: args.state,
10455
+ tags,
10456
+ selectedTag,
10457
+ buttonGroups: [],
10458
+ visibleFieldIds: [],
10459
+ usedServiceIds: []
10460
+ };
10461
+ }
10462
+ const sandbox = createBuilder({ serviceMap });
10463
+ sandbox.load(props);
10464
+ const visibleFieldIds = sandbox.visibleFields(selectedTag.id, args.state.selectedButtons);
10465
+ const buttonGroups = buildButtonGroups(props.fields ?? [], visibleFieldIds);
10466
+ const usedServiceIds = collectUsedServiceIds({
10467
+ props,
10468
+ tagId: selectedTag.id,
10469
+ visibleFieldIds,
10470
+ selectedButtons: args.state.selectedButtons
10471
+ });
10472
+ return {
10473
+ state: args.state,
10474
+ tags,
10475
+ selectedTag,
10476
+ buttonGroups,
10477
+ visibleFieldIds,
10478
+ usedServiceIds
10479
+ };
10480
+ }
10481
+ function buildServiceRowVM(args) {
10482
+ const service = args.services?.[args.summary.id] ?? null;
10483
+ const check = args.check;
10484
+ const searchText = [args.summary.name, args.summary.category, args.summary.platformId, String(args.summary.id)].filter(Boolean).join(" ").toLowerCase();
10485
+ const search = args.search?.trim().toLowerCase() ?? "";
10486
+ const matchesSearch = !search || searchText.includes(search);
10487
+ const isCompatible = !check || servicePassesCurrentFilter(check, args.state);
10488
+ const status = describeCheck(check, args.state);
10489
+ return {
10490
+ id: String(args.summary.id),
10491
+ summary: args.summary,
10492
+ service,
10493
+ check,
10494
+ matchesSearch,
10495
+ isCompatible,
10496
+ passesCurrentFilter: matchesSearch,
10497
+ statusTone: status.tone,
10498
+ statusLabel: status.label,
10499
+ reasonLabels: status.reasons,
10500
+ searchText
10501
+ };
10502
+ }
10503
+ function buildButtonGroups(fields, visibleFieldIds) {
10504
+ const visibleSet = new Set(visibleFieldIds);
10505
+ return fields.filter((field) => visibleSet.has(field.id)).map((field) => {
10506
+ const options = field.options?.length ? field.options.filter((option) => option.id).map((option) => ({
10507
+ id: String(option.id),
10508
+ label: option.label,
10509
+ description: `Option in ${field.label}`,
10510
+ fieldId: field.id,
10511
+ fieldLabel: field.label
10512
+ })) : field.button ? [
10513
+ {
10514
+ id: field.id,
10515
+ label: field.label,
10516
+ description: "Button field",
10517
+ fieldId: field.id,
10518
+ fieldLabel: field.label
10519
+ }
10520
+ ] : [];
10521
+ return {
10522
+ id: field.id,
10523
+ label: field.label,
10524
+ options
10525
+ };
10526
+ }).filter((group) => group.options.length > 0);
10527
+ }
10528
+ function collectUsedServiceIds(args) {
10529
+ const visibleSet = new Set(args.visibleFieldIds);
10530
+ const used = /* @__PURE__ */ new Set();
10531
+ const tag = args.props.filters?.find((item) => item.id === args.tagId);
10532
+ if (tag?.service_id != null) used.add(String(tag.service_id));
10533
+ for (const field of args.props.fields ?? []) {
10534
+ if (!visibleSet.has(field.id)) continue;
10535
+ if (field.service_id != null) {
10536
+ used.add(String(field.service_id));
10537
+ }
10538
+ for (const option of field.options ?? []) {
10539
+ if (option.service_id != null) {
10540
+ used.add(String(option.service_id));
10541
+ }
10542
+ }
10543
+ }
10544
+ return Array.from(used);
10545
+ }
10546
+ function describeTag(tag) {
10547
+ const constraints = Object.entries(tag.constraints ?? {}).filter(([, enabled]) => enabled).map(([key]) => key);
10548
+ return constraints.length ? constraints.join(", ") : "All visible services";
10549
+ }
10550
+ function servicePassesCurrentFilter(check, state) {
10551
+ const passesPolicies = state?.enforcePolicies === false ? true : check.passesPolicies;
10552
+ const safetyPass = check.fitsConstraints && check.passesRate && passesPolicies;
10553
+ return state?.strictSafety === false ? true : safetyPass;
10554
+ }
10555
+ function describeCheck(check, state) {
10556
+ if (!check) {
10557
+ return {
10558
+ tone: "default",
10559
+ label: "No context",
10560
+ reasons: []
10561
+ };
10562
+ }
10563
+ const reasons = [
10564
+ !check.fitsConstraints ? "Constraint mismatch" : null,
10565
+ !check.passesRate ? "Rate policy mismatch" : null,
10566
+ state?.enforcePolicies !== false && !check.passesPolicies ? "Policy blocked" : null,
10567
+ check.reasons.includes("missing_capability") ? "Missing capability" : null
10568
+ ].filter(Boolean);
10569
+ if (servicePassesCurrentFilter(check, state) && check.ok) {
10570
+ return { tone: "success", label: "Safe fit", reasons };
10571
+ }
10572
+ if (servicePassesCurrentFilter(check, state)) {
10573
+ return { tone: "warning", label: state?.enforcePolicies === false ? "Policy checks relaxed" : "Usable", reasons };
10574
+ }
10575
+ if (reasons.length) {
10576
+ return { tone: "danger", label: "Hidden by context", reasons };
10577
+ }
10578
+ return { tone: "default", label: "Available", reasons };
10579
+ }
10580
+
10313
10581
  // src/panels/right/components/renderif.tsx
10314
10582
  import "react";
10315
10583
  import { Fragment as Fragment8, jsx as jsx49 } from "react/jsx-runtime";
@@ -10338,29 +10606,32 @@ function RenderIf({ data, emptyMessage = null, children, when }) {
10338
10606
  // src/panels/right/partials/global/add-service.tsx
10339
10607
  import { useCanvas as useCanvas7, useWorkspace as useWorkspace11 } from "@timeax/digital-service-engine/workspace";
10340
10608
  import { InputField as InputField5 } from "@timeax/form-palette";
10341
- import { useMemo as useMemo23, useState as useState24 } from "react";
10609
+ import { useCallback as useCallback16, useEffect as useEffect17, useMemo as useMemo23, useState as useState24 } from "react";
10342
10610
  import { BsPlus } from "react-icons/bs";
10343
- import { Fragment as Fragment9, jsx as jsx50, jsxs as jsxs32 } from "react/jsx-runtime";
10611
+ import { FaFolderOpen } from "react-icons/fa";
10612
+ import { FiFilter } from "react-icons/fi";
10613
+ import { Fragment as Fragment9, jsx as jsx50, jsxs as jsxs33 } from "react/jsx-runtime";
10614
+ var UNGROUPED_TREE_VALUE = "__catalog_ungrouped__";
10344
10615
  function AddService({ className, data, disabled, disabledMessage, readOnly, readOnlyMessage, emptyMessage }) {
10345
10616
  const ws = useWorkspace11();
10346
10617
  const canvas = useCanvas7();
10347
- const services2 = useMemo23(() => ws.services.data ?? {}, [ws.services.data]);
10348
- const connectedService = data.raw.service_id != null ? services2[data.raw.service_id] : void 0;
10618
+ const servicesMap = useMemo23(() => ws.services.data ?? {}, [ws.services.data]);
10619
+ const connectedService = data.raw.service_id != null ? servicesMap[data.raw.service_id] : void 0;
10349
10620
  const isReadOnly = Boolean(disabled || readOnly);
10350
10621
  const helperMessage = readOnlyMessage ?? disabledMessage;
10351
- return /* @__PURE__ */ jsxs32(Section, { className, children: [
10352
- /* @__PURE__ */ jsxs32(Section.Header, { children: [
10622
+ return /* @__PURE__ */ jsxs33(Section, { className, children: [
10623
+ /* @__PURE__ */ jsxs33(Section.Header, { children: [
10353
10624
  /* @__PURE__ */ jsx50(Section.Title, { children: "Service" }),
10354
- /* @__PURE__ */ jsx50(Section.Actions, { children: !isReadOnly ? /* @__PURE__ */ jsx50(AddServicePopover, { data, services: Object.values(services2) }) : null })
10625
+ /* @__PURE__ */ jsx50(Section.Actions, { children: !isReadOnly ? /* @__PURE__ */ jsx50(AddServicePopover, { data, services: Object.values(servicesMap), servicesMap }) : null })
10355
10626
  ] }),
10356
- /* @__PURE__ */ jsxs32(Section.Content, { children: [
10627
+ /* @__PURE__ */ jsxs33(Section.Content, { children: [
10357
10628
  helperMessage ? /* @__PURE__ */ jsx50("p", { className: "mb-3 text-xs text-slate-500 dark:text-slate-400", children: helperMessage }) : null,
10358
10629
  /* @__PURE__ */ jsx50(RenderIf, { data: connectedService, emptyMessage: isReadOnly ? emptyMessage ?? null : emptyMessage ?? "None", children: (service) => /* @__PURE__ */ jsx50(Fragment9, { children: /* @__PURE__ */ jsx50(
10359
10630
  IncludesItem,
10360
10631
  {
10361
10632
  title: service.name ?? `Service ${service.id}`,
10362
10633
  className: "items-start!",
10363
- badge: /* @__PURE__ */ jsxs32("span", { className: "rounded-full bg-slate-200 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.16em] text-slate-600 dark:bg-slate-800 dark:text-slate-300", children: [
10634
+ badge: /* @__PURE__ */ jsxs33("span", { className: "rounded-full bg-slate-200 px-2 py-0.5 text-[10px] font-semibold tracking-[0.16em] text-slate-600 uppercase dark:bg-slate-800 dark:text-slate-300", children: [
10364
10635
  "#",
10365
10636
  service.id
10366
10637
  ] }),
@@ -10379,19 +10650,19 @@ function AddService({ className, data, disabled, disabledMessage, readOnly, read
10379
10650
  }
10380
10651
  function ServiceSummary({ service, nodeId, disabled }) {
10381
10652
  const canvas = useCanvas7();
10382
- return /* @__PURE__ */ jsxs32("div", { className: "mt-2 rounded-md bg-gray-50 p-3 text-sm dark:bg-gray-800/50", children: [
10383
- /* @__PURE__ */ jsxs32("div", { className: "space-y-1 text-xs text-gray-600 dark:text-gray-300", children: [
10384
- /* @__PURE__ */ jsxs32("p", { children: [
10653
+ return /* @__PURE__ */ jsxs33("div", { className: "mt-2 rounded-md bg-gray-50 p-3 text-sm dark:bg-gray-800/50", children: [
10654
+ /* @__PURE__ */ jsxs33("div", { className: "space-y-1 text-xs text-gray-600 dark:text-gray-300", children: [
10655
+ /* @__PURE__ */ jsxs33("p", { children: [
10385
10656
  /* @__PURE__ */ jsx50("span", { className: "font-medium text-gray-800 dark:text-gray-200", children: "Category:" }),
10386
10657
  " ",
10387
10658
  service.category ?? "Uncategorised"
10388
10659
  ] }),
10389
- /* @__PURE__ */ jsxs32("p", { children: [
10660
+ /* @__PURE__ */ jsxs33("p", { children: [
10390
10661
  /* @__PURE__ */ jsx50("span", { className: "font-medium text-gray-800 dark:text-gray-200", children: "Rate:" }),
10391
10662
  " ",
10392
10663
  service.rate
10393
10664
  ] }),
10394
- /* @__PURE__ */ jsxs32("p", { children: [
10665
+ /* @__PURE__ */ jsxs33("p", { children: [
10395
10666
  /* @__PURE__ */ jsx50("span", { className: "font-medium text-gray-800 dark:text-gray-200", children: "Range:" }),
10396
10667
  " ",
10397
10668
  service.min ?? 0,
@@ -10410,55 +10681,256 @@ function ServiceSummary({ service, nodeId, disabled }) {
10410
10681
  ) }) : null
10411
10682
  ] });
10412
10683
  }
10413
- function AddServicePopover({ data, services: services2 }) {
10684
+ function AddServicePopover({
10685
+ data,
10686
+ services: services2,
10687
+ servicesMap
10688
+ }) {
10689
+ const ws = useWorkspace11();
10414
10690
  const canvas = useCanvas7();
10415
10691
  const [open, setOpen] = useState24(false);
10692
+ const [filterOpen, setFilterOpen] = useState24(false);
10416
10693
  const [query, setQuery] = useState24("");
10417
10694
  const [selected, setSelected] = useState24("");
10418
- const options = useMemo23(() => {
10419
- const lower = query.trim().toLowerCase();
10420
- return services2.filter((service) => {
10421
- if (!lower) return true;
10422
- return `${service.name ?? ""} ${service.category ?? ""} ${String(service.id)}`.toLowerCase().includes(lower);
10423
- }).map((service) => ({
10424
- label: service.name ?? `Service ${service.id}`,
10425
- value: String(service.id),
10426
- description: service.category,
10427
- service
10428
- }));
10429
- }, [services2, query]);
10430
- return /* @__PURE__ */ jsxs32(Popover, { open, onOpenChange: setOpen, children: [
10431
- /* @__PURE__ */ jsx50(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx50(SectionActionTriggerButton, { icon: /* @__PURE__ */ jsx50(BsPlus, {}), children: "Add" }) }),
10432
- /* @__PURE__ */ jsx50(PopoverContent, { className: "w-96", children: /* @__PURE__ */ jsxs32("div", { className: "flex flex-col gap-3", children: [
10433
- /* @__PURE__ */ jsx50(InputField5, { variant: "text", value: query, onChange: (e) => setQuery(e.value ?? ""), placeholder: "Search services..." }),
10434
- /* @__PURE__ */ jsx50(ScrollArea, { className: "h-72 pr-1", children: /* @__PURE__ */ jsx50("div", { className: "space-y-2 pr-2", children: options.length ? options.map((option) => /* @__PURE__ */ jsxs32(
10435
- "button",
10436
- {
10437
- type: "button",
10438
- onClick: () => setSelected(option.value),
10439
- className: `w-full rounded-md border px-3 py-2 text-left transition ${selected === option.value ? "border-blue-300 bg-blue-50 dark:border-blue-500/40 dark:bg-blue-500/10" : "border-slate-200 hover:border-slate-300 hover:bg-slate-50 dark:border-slate-700 dark:hover:border-slate-600 dark:hover:bg-slate-900"}`,
10440
- children: [
10441
- /* @__PURE__ */ jsx50("div", { className: "text-sm font-medium text-slate-900 dark:text-slate-100", children: option.label }),
10442
- /* @__PURE__ */ jsxs32("div", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: [
10443
- option.description ?? "Uncategorised",
10444
- " \u2022 Rate ",
10445
- option.service.rate
10446
- ] })
10447
- ]
10448
- },
10449
- option.value
10450
- )) : /* @__PURE__ */ jsx50("div", { className: "rounded-md border border-dashed border-slate-300 px-3 py-6 text-center text-sm text-slate-500 dark:border-slate-700 dark:text-slate-400", children: "No services found." }) }) }),
10451
- /* @__PURE__ */ jsx50(
10452
- Button,
10453
- {
10454
- onClick: () => {
10455
- if (!selected) return;
10456
- canvas.api.editor.setService(data.id, { service_id: Number(selected) });
10457
- setOpen(false);
10458
- setSelected("");
10459
- setQuery("");
10460
- },
10461
- type: "button",
10695
+ const [contextFilterEnabled, setContextFilterEnabled] = useState24(false);
10696
+ const [catalogState, setCatalogState] = useState24(null);
10697
+ const policies2 = ws.policies.policies.data ?? [];
10698
+ const currentTagId = canvas.api.selection.currentTag?.();
10699
+ const preferredTagId = currentTagId != null ? String(currentTagId) : canvas.layers.tags[0]?.id != null ? String(canvas.layers.tags[0]?.id) : null;
10700
+ const selectedButtons = useMemo23(
10701
+ () => (canvas.api.selection.selectedButtons?.() ?? []).map((value) => String(value)),
10702
+ [canvas.api.selection, canvas.selectionInfo.ids, canvas.selectionInfo.optionIds]
10703
+ );
10704
+ const liveSelectionContext = useMemo23(
10705
+ () => ({
10706
+ selectedTagId: preferredTagId,
10707
+ selectedButtons,
10708
+ strictSafety: true,
10709
+ enforcePolicies: true
10710
+ }),
10711
+ [preferredTagId, selectedButtons]
10712
+ );
10713
+ const liveSnapshot = useMemo23(
10714
+ () => buildServiceContextSnapshot({ props: canvas.props, services: servicesMap, state: liveSelectionContext }),
10715
+ [canvas.props, liveSelectionContext, servicesMap]
10716
+ );
10717
+ useEffect17(() => {
10718
+ const editor = canvas.api.editor;
10719
+ const ensured = editor.getCatalog?.() ?? editor.ensureCatalog?.();
10720
+ if (ensured) setCatalogState(ensured);
10721
+ const offCatalogChange = canvas.api.on("catalog:change", ({ catalog }) => {
10722
+ const next = catalog ?? editor.getCatalog?.() ?? editor.ensureCatalog?.();
10723
+ setCatalogState(next ?? null);
10724
+ });
10725
+ const offCatalogActiveChange = canvas.api.on("catalog:active-change", () => {
10726
+ const next = editor.getCatalog?.() ?? editor.ensureCatalog?.();
10727
+ setCatalogState(next ?? null);
10728
+ });
10729
+ return () => {
10730
+ offCatalogChange?.();
10731
+ offCatalogActiveChange?.();
10732
+ };
10733
+ }, [canvas.api]);
10734
+ const catalogMode = catalogState?.viewMode === "grouped" ? "catalog" : "all";
10735
+ const catalogGroups = useMemo23(
10736
+ () => (catalogState?.nodes ?? []).filter((node) => node.kind === "group").sort((a, b) => (a.order ?? 0) - (b.order ?? 0) || a.label.localeCompare(b.label)),
10737
+ [catalogState]
10738
+ );
10739
+ const selectedCatalogGroupId = catalogGroups.some((node) => node.id === catalogState?.activeNodeId) ? String(catalogState?.activeNodeId) : null;
10740
+ const groupedServiceIds = useMemo23(() => {
10741
+ const ids = /* @__PURE__ */ new Set();
10742
+ for (const group of catalogGroups) {
10743
+ for (const serviceId of group.serviceIds) ids.add(String(serviceId));
10744
+ }
10745
+ return ids;
10746
+ }, [catalogGroups]);
10747
+ const allowedCatalogIds = useMemo23(() => {
10748
+ if (catalogMode !== "catalog") return null;
10749
+ if (!selectedCatalogGroupId) {
10750
+ const ids = /* @__PURE__ */ new Set();
10751
+ for (const service of services2) {
10752
+ const id = String(service.id);
10753
+ if (!groupedServiceIds.has(id)) ids.add(id);
10754
+ }
10755
+ return ids;
10756
+ }
10757
+ const selectedGroup = catalogGroups.find((group) => group.id === selectedCatalogGroupId);
10758
+ if (!selectedGroup) {
10759
+ const ids = /* @__PURE__ */ new Set();
10760
+ for (const service of services2) {
10761
+ const id = String(service.id);
10762
+ if (!groupedServiceIds.has(id)) ids.add(id);
10763
+ }
10764
+ return ids;
10765
+ }
10766
+ return new Set(selectedGroup.serviceIds.map((id) => String(id)));
10767
+ }, [catalogGroups, catalogMode, groupedServiceIds, selectedCatalogGroupId, services2]);
10768
+ const compatibleIds = useMemo23(() => {
10769
+ if (!contextFilterEnabled) return null;
10770
+ if (!liveSnapshot.selectedTag) return null;
10771
+ const checks = canvas.api.editor.filterServicesForVisibleGroup?.(
10772
+ services2.map((service) => service.id),
10773
+ {
10774
+ tagId: liveSnapshot.selectedTag.id,
10775
+ selectedButtons: liveSnapshot.state.selectedButtons,
10776
+ usedServiceIds: liveSnapshot.usedServiceIds,
10777
+ effectiveConstraints: liveSnapshot.selectedTag.constraints,
10778
+ policies: policies2
10779
+ }
10780
+ );
10781
+ if (!Array.isArray(checks)) return null;
10782
+ const ids = /* @__PURE__ */ new Set();
10783
+ for (const check of checks) {
10784
+ if (check?.fitsConstraints && check?.passesRate && check?.passesPolicies) {
10785
+ ids.add(String(check.id));
10786
+ }
10787
+ }
10788
+ return ids;
10789
+ }, [canvas.api.editor, contextFilterEnabled, liveSnapshot, policies2, services2]);
10790
+ const setCatalogMode = useCallback16(
10791
+ (mode) => {
10792
+ const editor = canvas.api.editor;
10793
+ editor.ensureCatalog?.();
10794
+ editor.setCatalogViewMode?.(mode === "catalog" ? "grouped" : "all");
10795
+ },
10796
+ [canvas.api.editor]
10797
+ );
10798
+ const filterActive = contextFilterEnabled || catalogMode === "catalog";
10799
+ const options = useMemo23(() => {
10800
+ const lower = query.trim().toLowerCase();
10801
+ return services2.filter((service) => {
10802
+ if (!lower) return true;
10803
+ return `${service.name ?? ""} ${service.category ?? ""} ${String(service.id)}`.toLowerCase().includes(lower);
10804
+ }).filter((service) => allowedCatalogIds ? allowedCatalogIds.has(String(service.id)) : true).filter((service) => compatibleIds ? compatibleIds.has(String(service.id)) : true).map((service) => ({
10805
+ label: service.name ?? `Service ${service.id}`,
10806
+ value: String(service.id),
10807
+ description: service.category,
10808
+ service
10809
+ }));
10810
+ }, [allowedCatalogIds, compatibleIds, services2, query]);
10811
+ useEffect17(() => {
10812
+ if (selected && !options.some((option) => option.value === selected)) {
10813
+ setSelected("");
10814
+ }
10815
+ }, [options, selected]);
10816
+ const treeValue = selectedCatalogGroupId ?? (catalogMode === "catalog" ? UNGROUPED_TREE_VALUE : void 0);
10817
+ const treeOptions = buildCatalogGroupTreeOptions(catalogGroups);
10818
+ const selectedCatalogGroup = catalogGroups.find((group) => group.id === selectedCatalogGroupId) ?? null;
10819
+ return /* @__PURE__ */ jsxs33(Popover, { open, onOpenChange: setOpen, children: [
10820
+ /* @__PURE__ */ jsx50(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx50(SectionActionTriggerButton, { icon: /* @__PURE__ */ jsx50(BsPlus, {}), children: "Add" }) }),
10821
+ /* @__PURE__ */ jsx50(PopoverContent, { className: "w-96", children: /* @__PURE__ */ jsxs33("div", { className: "flex flex-col gap-3", children: [
10822
+ /* @__PURE__ */ jsx50(
10823
+ InputField5,
10824
+ {
10825
+ variant: "text",
10826
+ value: query,
10827
+ onChange: (e) => setQuery(e.value ?? ""),
10828
+ placeholder: "Search services...",
10829
+ extendBoxToControls: true,
10830
+ joinControls: true,
10831
+ trailingControl: /* @__PURE__ */ jsxs33(Popover, { open: filterOpen, onOpenChange: setFilterOpen, children: [
10832
+ /* @__PURE__ */ jsx50(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx50(
10833
+ "button",
10834
+ {
10835
+ type: "button",
10836
+ "aria-label": "Service list filter",
10837
+ className: `flex h-full w-8 cursor-pointer items-center justify-center text-sm transition ${filterActive ? "text-blue-700 dark:text-blue-200" : "text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-900"}`,
10838
+ children: /* @__PURE__ */ jsx50(FiFilter, {})
10839
+ }
10840
+ ) }),
10841
+ /* @__PURE__ */ jsxs33(PopoverContent, { align: "end", sideOffset: 8, collisionPadding: 12, className: "w-80 space-y-3 rounded-xl", children: [
10842
+ /* @__PURE__ */ jsxs33("div", { children: [
10843
+ /* @__PURE__ */ jsx50("div", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: "Service filters" }),
10844
+ /* @__PURE__ */ jsx50("p", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: "Combine catalog grouping with current context compatibility." })
10845
+ ] }),
10846
+ /* @__PURE__ */ jsxs33("div", { className: "space-y-2 rounded-lg border border-slate-200 p-3 dark:border-slate-800", children: [
10847
+ /* @__PURE__ */ jsx50("div", { className: "text-xs font-semibold tracking-[0.16em] text-slate-500 uppercase dark:text-slate-400", children: "Catalog scope" }),
10848
+ /* @__PURE__ */ jsx50(
10849
+ InputField5,
10850
+ {
10851
+ variant: "radio",
10852
+ value: catalogMode,
10853
+ options: [
10854
+ { key: "all", label: "All services" },
10855
+ { key: "catalog", label: "Catalog group" }
10856
+ ],
10857
+ onChange: (event) => setCatalogMode(event.value)
10858
+ }
10859
+ ),
10860
+ /* @__PURE__ */ jsx50(
10861
+ InputField5,
10862
+ {
10863
+ variant: "treeselect",
10864
+ mode: "button",
10865
+ label: "Select group",
10866
+ className: "w-fit!",
10867
+ disabled: catalogMode !== "catalog",
10868
+ multiple: false,
10869
+ value: treeValue,
10870
+ options: [{ key: UNGROUPED_TREE_VALUE, label: "Ungrouped" }, ...treeOptions],
10871
+ searchable: true,
10872
+ clearable: true,
10873
+ onChange: (event) => {
10874
+ const next = event.value == null ? null : String(event.value);
10875
+ canvas.api.editor.setActiveCatalogNode?.(
10876
+ next === UNGROUPED_TREE_VALUE || next == null ? void 0 : next
10877
+ );
10878
+ },
10879
+ button: /* @__PURE__ */ jsx50(FaFolderOpen, {})
10880
+ }
10881
+ ),
10882
+ catalogMode === "catalog" ? /* @__PURE__ */ jsxs33("div", { className: "text-xs text-slate-500 dark:text-slate-400", children: [
10883
+ "Showing ",
10884
+ selectedCatalogGroup?.label ?? "Ungrouped",
10885
+ " services."
10886
+ ] }) : null
10887
+ ] }),
10888
+ /* @__PURE__ */ jsxs33("label", { className: "flex items-start justify-between gap-3 rounded-lg border border-slate-200 p-3 text-sm text-slate-900 dark:border-slate-800 dark:text-slate-100", children: [
10889
+ /* @__PURE__ */ jsxs33("span", { className: "min-w-0", children: [
10890
+ /* @__PURE__ */ jsx50("span", { className: "block font-medium", children: "Current context" }),
10891
+ /* @__PURE__ */ jsx50("span", { className: "mt-1 block text-xs text-slate-500 dark:text-slate-400", children: "Filter services based on the current visible-group context." })
10892
+ ] }),
10893
+ /* @__PURE__ */ jsx50(
10894
+ "input",
10895
+ {
10896
+ "aria-label": "Current context",
10897
+ type: "checkbox",
10898
+ checked: contextFilterEnabled,
10899
+ onChange: (event) => setContextFilterEnabled(event.target.checked)
10900
+ }
10901
+ )
10902
+ ] })
10903
+ ] })
10904
+ ] })
10905
+ }
10906
+ ),
10907
+ /* @__PURE__ */ jsx50(ScrollArea, { className: "h-72 pr-1", children: /* @__PURE__ */ jsx50("div", { className: "space-y-2 pr-2", children: options.length ? options.map((option) => /* @__PURE__ */ jsxs33(
10908
+ "button",
10909
+ {
10910
+ type: "button",
10911
+ onClick: () => setSelected(option.value),
10912
+ className: `w-full rounded-md border px-3 py-2 text-left transition ${selected === option.value ? "border-blue-300 bg-blue-50 dark:border-blue-500/40 dark:bg-blue-500/10" : "border-slate-200 hover:border-slate-300 hover:bg-slate-50 dark:border-slate-700 dark:hover:border-slate-600 dark:hover:bg-slate-900"}`,
10913
+ children: [
10914
+ /* @__PURE__ */ jsx50("div", { className: "text-sm font-medium text-slate-900 dark:text-slate-100", children: option.label }),
10915
+ /* @__PURE__ */ jsxs33("div", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: [
10916
+ option.description ?? "Uncategorised",
10917
+ " \u2022 Rate ",
10918
+ option.service.rate
10919
+ ] })
10920
+ ]
10921
+ },
10922
+ option.value
10923
+ )) : /* @__PURE__ */ jsx50("div", { className: "rounded-md border border-dashed border-slate-300 px-3 py-6 text-center text-sm text-slate-500 dark:border-slate-700 dark:text-slate-400", children: "No services found." }) }) }),
10924
+ /* @__PURE__ */ jsx50(
10925
+ Button,
10926
+ {
10927
+ onClick: () => {
10928
+ if (!selected) return;
10929
+ canvas.api.editor.setService(data.id, { service_id: Number(selected) });
10930
+ setOpen(false);
10931
+ setSelected("");
10932
+ },
10933
+ type: "button",
10462
10934
  size: "sm",
10463
10935
  children: "Save"
10464
10936
  }
@@ -10466,13 +10938,24 @@ function AddServicePopover({ data, services: services2 }) {
10466
10938
  ] }) })
10467
10939
  ] });
10468
10940
  }
10941
+ function buildCatalogGroupTreeOptions(groups, parentId = null) {
10942
+ return groups.filter((group) => (group.parentId ?? null) === parentId).sort((a, b) => (a.order ?? 0) - (b.order ?? 0) || a.label.localeCompare(b.label)).map((group) => {
10943
+ const children = buildCatalogGroupTreeOptions(groups, group.id);
10944
+ return {
10945
+ key: group.id,
10946
+ label: group.label,
10947
+ description: `${group.serviceIds.length} service${group.serviceIds.length === 1 ? "" : "s"}`,
10948
+ children: children.length ? children : void 0
10949
+ };
10950
+ });
10951
+ }
10469
10952
  var add_service_default = AddService;
10470
10953
 
10471
10954
  // src/panels/right/partials/properties/field-properties.tsx
10472
10955
  import { resolveInputDescriptor, useInputs as useInputs2 } from "@timeax/digital-service-engine/react";
10473
10956
  import { useCanvas as useCanvas12 } from "@timeax/digital-service-engine/workspace";
10474
10957
  import { InputField as InputField11 } from "@timeax/form-palette";
10475
- import { useEffect as useEffect17, useMemo as useMemo28, useState as useState28 } from "react";
10958
+ import { useEffect as useEffect18, useMemo as useMemo28, useState as useState28 } from "react";
10476
10959
 
10477
10960
  // src/panels/right/partials/properties/components/descriptor-settings.tsx
10478
10961
  import { InputField as InputField6 } from "@timeax/form-palette";
@@ -10521,7 +11004,7 @@ function buildQuantityRule(valueBy, base = {}) {
10521
11004
  }
10522
11005
 
10523
11006
  // src/panels/right/partials/properties/components/descriptor-settings.tsx
10524
- import { jsx as jsx51, jsxs as jsxs33 } from "react/jsx-runtime";
11007
+ import { jsx as jsx51, jsxs as jsxs34 } from "react/jsx-runtime";
10525
11008
  var RESERVED_DESCRIPTOR_KEYS = /* @__PURE__ */ new Set([
10526
11009
  "options",
10527
11010
  "label",
@@ -10673,7 +11156,7 @@ function FieldDescription({
10673
11156
  onReset
10674
11157
  }) {
10675
11158
  if (!description && !canReset) return null;
10676
- return /* @__PURE__ */ jsxs33("div", { className: "flex items-start justify-between gap-3", children: [
11159
+ return /* @__PURE__ */ jsxs34("div", { className: "flex items-start justify-between gap-3", children: [
10677
11160
  /* @__PURE__ */ jsx51("p", { className: "text-xs text-slate-500 dark:text-slate-400", children: description }),
10678
11161
  canReset ? /* @__PURE__ */ jsx51(Button, { type: "button", variant: "ghost", size: "sm", className: "h-7 px-2 text-xs", onClick: onReset, children: "Reset" }) : null
10679
11162
  ] });
@@ -10682,7 +11165,7 @@ function DescriptorPrimitiveField({ schema, value, hasOverride, onSet, onClear,
10682
11165
  switch (schema.type) {
10683
11166
  case "string": {
10684
11167
  const options = schema.enum?.map((item) => ({ label: item, value: item }));
10685
- return /* @__PURE__ */ jsxs33("div", { className: "space-y-2", children: [
11168
+ return /* @__PURE__ */ jsxs34("div", { className: "space-y-2", children: [
10686
11169
  /* @__PURE__ */ jsx51(FieldDescription, { description: schema.description, canReset: hasOverride, onReset: () => onClear(path) }),
10687
11170
  /* @__PURE__ */ jsx51(
10688
11171
  InputField6,
@@ -10705,7 +11188,7 @@ function DescriptorPrimitiveField({ schema, value, hasOverride, onSet, onClear,
10705
11188
  ] });
10706
11189
  }
10707
11190
  case "number":
10708
- return /* @__PURE__ */ jsxs33("div", { className: "space-y-2", children: [
11191
+ return /* @__PURE__ */ jsxs34("div", { className: "space-y-2", children: [
10709
11192
  /* @__PURE__ */ jsx51(FieldDescription, { description: schema.description, canReset: hasOverride, onReset: () => onClear(path) }),
10710
11193
  /* @__PURE__ */ jsx51(
10711
11194
  InputField6,
@@ -10726,7 +11209,7 @@ function DescriptorPrimitiveField({ schema, value, hasOverride, onSet, onClear,
10726
11209
  )
10727
11210
  ] });
10728
11211
  case "boolean":
10729
- return /* @__PURE__ */ jsxs33("div", { className: "space-y-2", children: [
11212
+ return /* @__PURE__ */ jsxs34("div", { className: "space-y-2", children: [
10730
11213
  /* @__PURE__ */ jsx51(FieldDescription, { description: schema.description, canReset: hasOverride, onReset: () => onClear(path) }),
10731
11214
  /* @__PURE__ */ jsx51(
10732
11215
  InputField6,
@@ -10744,7 +11227,7 @@ function DescriptorPrimitiveField({ schema, value, hasOverride, onSet, onClear,
10744
11227
  value: item.value,
10745
11228
  description: item.description
10746
11229
  }));
10747
- return /* @__PURE__ */ jsxs33("div", { className: "space-y-2", children: [
11230
+ return /* @__PURE__ */ jsxs34("div", { className: "space-y-2", children: [
10748
11231
  /* @__PURE__ */ jsx51(FieldDescription, { description: schema.description, canReset: hasOverride, onReset: () => onClear(path) }),
10749
11232
  /* @__PURE__ */ jsx51(
10750
11233
  InputField6,
@@ -10813,15 +11296,15 @@ function DescriptorObjectField({ schema, value, hasOverride, onSet, onClear, pat
10813
11296
  setActiveShapes((current) => ({ ...current, [nextKey]: draftShape }));
10814
11297
  setDraftKey("");
10815
11298
  };
10816
- return /* @__PURE__ */ jsx51("div", { className: "rounded-xl border border-slate-200/80 p-3 dark:border-slate-800", children: /* @__PURE__ */ jsxs33("div", { className: "space-y-2", children: [
10817
- /* @__PURE__ */ jsxs33("div", { className: "flex items-start justify-between gap-3", children: [
10818
- /* @__PURE__ */ jsxs33("div", { children: [
11299
+ return /* @__PURE__ */ jsx51("div", { className: "rounded-xl border border-slate-200/80 p-3 dark:border-slate-800", children: /* @__PURE__ */ jsxs34("div", { className: "space-y-2", children: [
11300
+ /* @__PURE__ */ jsxs34("div", { className: "flex items-start justify-between gap-3", children: [
11301
+ /* @__PURE__ */ jsxs34("div", { children: [
10819
11302
  /* @__PURE__ */ jsx51("h4", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: schema.label }),
10820
11303
  /* @__PURE__ */ jsx51("p", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: schema.description })
10821
11304
  ] }),
10822
11305
  allowClear && hasOverride ? /* @__PURE__ */ jsx51(Button, { type: "button", variant: "ghost", size: "sm", className: "h-7 px-2 text-xs", onClick: () => onClear(path), children: "Reset" }) : null
10823
11306
  ] }),
10824
- /* @__PURE__ */ jsxs33("div", { className: "space-y-4", children: [
11307
+ /* @__PURE__ */ jsxs34("div", { className: "space-y-4", children: [
10825
11308
  orderedEntries.map(([key, childSchema]) => /* @__PURE__ */ jsx51(
10826
11309
  DescriptorNodeField,
10827
11310
  {
@@ -10838,8 +11321,8 @@ function DescriptorObjectField({ schema, value, hasOverride, onSet, onClear, pat
10838
11321
  const shapeKey = activeShapes[key] ?? inferShapeKey(schema.shape, objectValue[key]);
10839
11322
  const shapeSchema = (shapeKey && schema.shape?.[shapeKey]) ?? shapeEntries[0]?.[1];
10840
11323
  if (!shapeSchema) return null;
10841
- return /* @__PURE__ */ jsxs33("div", { className: "space-y-3 rounded-lg border border-dashed border-slate-200 p-3 dark:border-slate-700", children: [
10842
- /* @__PURE__ */ jsxs33("div", { className: "grid gap-3 md:grid-cols-[minmax(0,1fr)_180px_auto]", children: [
11324
+ return /* @__PURE__ */ jsxs34("div", { className: "space-y-3 rounded-lg border border-dashed border-slate-200 p-3 dark:border-slate-700", children: [
11325
+ /* @__PURE__ */ jsxs34("div", { className: "grid gap-3 md:grid-cols-[minmax(0,1fr)_180px_auto]", children: [
10843
11326
  /* @__PURE__ */ jsx51(
10844
11327
  InputField6,
10845
11328
  {
@@ -10871,7 +11354,7 @@ function DescriptorObjectField({ schema, value, hasOverride, onSet, onClear, pat
10871
11354
  });
10872
11355
  }
10873
11356
  }
10874
- ) : /* @__PURE__ */ jsxs33("div", { className: "flex items-end text-xs text-slate-500 dark:text-slate-400", children: [
11357
+ ) : /* @__PURE__ */ jsxs34("div", { className: "flex items-end text-xs text-slate-500 dark:text-slate-400", children: [
10875
11358
  "Shape: ",
10876
11359
  shapeKey ?? shapeEntries[0]?.[0] ?? "Custom"
10877
11360
  ] }),
@@ -10905,7 +11388,7 @@ function DescriptorObjectField({ schema, value, hasOverride, onSet, onClear, pat
10905
11388
  )
10906
11389
  ] }, key);
10907
11390
  }),
10908
- schema.editable && shapeEntries.length ? /* @__PURE__ */ jsxs33("div", { className: "grid gap-3 rounded-lg border border-dashed border-slate-200 p-3 md:grid-cols-[minmax(0,1fr)_180px_auto] dark:border-slate-700", children: [
11391
+ schema.editable && shapeEntries.length ? /* @__PURE__ */ jsxs34("div", { className: "grid gap-3 rounded-lg border border-dashed border-slate-200 p-3 md:grid-cols-[minmax(0,1fr)_180px_auto] dark:border-slate-700", children: [
10909
11392
  /* @__PURE__ */ jsx51(
10910
11393
  InputField6,
10911
11394
  {
@@ -10953,15 +11436,15 @@ function DescriptorArrayField({ schema, value, hasOverride, onSet, onClear, path
10953
11436
  setActiveShapes((current) => ({ ...current, [nextIndex]: draftShape }));
10954
11437
  }
10955
11438
  };
10956
- return /* @__PURE__ */ jsx51("div", { className: "rounded-xl border border-slate-200/80 p-3 dark:border-slate-800", children: /* @__PURE__ */ jsxs33("div", { className: "space-y-2", children: [
10957
- /* @__PURE__ */ jsxs33("div", { className: "flex items-start justify-between gap-3", children: [
10958
- /* @__PURE__ */ jsxs33("div", { children: [
11439
+ return /* @__PURE__ */ jsx51("div", { className: "rounded-xl border border-slate-200/80 p-3 dark:border-slate-800", children: /* @__PURE__ */ jsxs34("div", { className: "space-y-2", children: [
11440
+ /* @__PURE__ */ jsxs34("div", { className: "flex items-start justify-between gap-3", children: [
11441
+ /* @__PURE__ */ jsxs34("div", { children: [
10959
11442
  /* @__PURE__ */ jsx51("h4", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: schema.label }),
10960
11443
  /* @__PURE__ */ jsx51("p", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: schema.description })
10961
11444
  ] }),
10962
11445
  allowClear && hasOverride ? /* @__PURE__ */ jsx51(Button, { type: "button", variant: "ghost", size: "sm", className: "h-7 px-2 text-xs", onClick: () => onClear(path), children: "Reset" }) : null
10963
11446
  ] }),
10964
- /* @__PURE__ */ jsxs33("div", { className: "space-y-4", children: [
11447
+ /* @__PURE__ */ jsxs34("div", { className: "space-y-4", children: [
10965
11448
  schema.items ? schema.items.map((childSchema, index) => /* @__PURE__ */ jsx51(
10966
11449
  DescriptorNodeField,
10967
11450
  {
@@ -10978,9 +11461,9 @@ function DescriptorArrayField({ schema, value, hasOverride, onSet, onClear, path
10978
11461
  const shapeKey = activeShapes[index] ?? inferShapeKey(schema.shape, item);
10979
11462
  const itemSchema = schema.item ?? (shapeKey ? schema.shape?.[shapeKey] : void 0) ?? shapeEntries[0]?.[1];
10980
11463
  if (!itemSchema) return null;
10981
- return /* @__PURE__ */ jsxs33("div", { className: "space-y-3 rounded-lg border border-dashed border-slate-200 p-3 dark:border-slate-700", children: [
10982
- /* @__PURE__ */ jsxs33("div", { className: "grid gap-3 md:grid-cols-[minmax(0,1fr)_180px_auto]", children: [
10983
- /* @__PURE__ */ jsxs33("div", { className: "flex items-end text-xs text-slate-500 dark:text-slate-400", children: [
11464
+ return /* @__PURE__ */ jsxs34("div", { className: "space-y-3 rounded-lg border border-dashed border-slate-200 p-3 dark:border-slate-700", children: [
11465
+ /* @__PURE__ */ jsxs34("div", { className: "grid gap-3 md:grid-cols-[minmax(0,1fr)_180px_auto]", children: [
11466
+ /* @__PURE__ */ jsxs34("div", { className: "flex items-end text-xs text-slate-500 dark:text-slate-400", children: [
10984
11467
  formatLabel(schema.label),
10985
11468
  " item ",
10986
11469
  index + 1
@@ -11034,8 +11517,8 @@ function DescriptorArrayField({ schema, value, hasOverride, onSet, onClear, path
11034
11517
  )
11035
11518
  ] }, `${path.join(".")}:${index}`);
11036
11519
  }),
11037
- !schema.items && (schema.editable ?? true) ? /* @__PURE__ */ jsxs33("div", { className: "grid gap-3 rounded-lg border border-dashed border-slate-200 p-3 md:grid-cols-[minmax(0,1fr)_180px_auto] dark:border-slate-700", children: [
11038
- /* @__PURE__ */ jsxs33("div", { className: "flex items-end text-xs text-slate-500 dark:text-slate-400", children: [
11520
+ !schema.items && (schema.editable ?? true) ? /* @__PURE__ */ jsxs34("div", { className: "grid gap-3 rounded-lg border border-dashed border-slate-200 p-3 md:grid-cols-[minmax(0,1fr)_180px_auto] dark:border-slate-700", children: [
11521
+ /* @__PURE__ */ jsxs34("div", { className: "flex items-end text-xs text-slate-500 dark:text-slate-400", children: [
11039
11522
  "Add another ",
11040
11523
  schema.label.toLowerCase()
11041
11524
  ] }),
@@ -11110,7 +11593,7 @@ import { InputField as InputField7 } from "@timeax/form-palette";
11110
11593
  import { useMemo as useMemo25 } from "react";
11111
11594
  import { BsPlus as BsPlus2 } from "react-icons/bs";
11112
11595
  import { MdDeleteOutline } from "react-icons/md";
11113
- import { jsx as jsx52, jsxs as jsxs34 } from "react/jsx-runtime";
11596
+ import { jsx as jsx52, jsxs as jsxs35 } from "react/jsx-runtime";
11114
11597
  var ruleOptions = [
11115
11598
  { label: "Value", value: "value" },
11116
11599
  { label: "Length", value: "length" },
@@ -11170,10 +11653,10 @@ function QuantitySection({ node }) {
11170
11653
  const hasQuantityDefault = capabilities.quantity.canEditDefault && quantityDefault !== void 0;
11171
11654
  const canAddRule = capabilities.quantity.canEditRule && !hasFieldRule;
11172
11655
  const canAddDefault = capabilities.quantity.canEditDefault && !hasQuantityDefault;
11173
- return /* @__PURE__ */ jsxs34(Section, { children: [
11174
- /* @__PURE__ */ jsxs34(Section.Header, { children: [
11656
+ return /* @__PURE__ */ jsxs35(Section, { children: [
11657
+ /* @__PURE__ */ jsxs35(Section.Header, { children: [
11175
11658
  /* @__PURE__ */ jsx52(Section.Title, { children: "Quantity" }),
11176
- canAddRule || canAddDefault || hasFieldRule || hasQuantityDefault ? /* @__PURE__ */ jsxs34(Section.Actions, { children: [
11659
+ canAddRule || canAddDefault || hasFieldRule || hasQuantityDefault ? /* @__PURE__ */ jsxs35(Section.Actions, { children: [
11177
11660
  canAddRule ? /* @__PURE__ */ jsx52(
11178
11661
  SectionActionButton,
11179
11662
  {
@@ -11219,9 +11702,9 @@ function QuantitySection({ node }) {
11219
11702
  ) : null
11220
11703
  ] }) : null
11221
11704
  ] }),
11222
- /* @__PURE__ */ jsx52(Section.Content, { children: node.kind === "field" ? /* @__PURE__ */ jsxs34("div", { className: "space-y-4", children: [
11223
- hasFieldRule ? /* @__PURE__ */ jsxs34("div", { className: "space-y-3 rounded-xl border border-slate-200 p-3 dark:border-slate-800", children: [
11224
- /* @__PURE__ */ jsxs34("div", { className: "space-y-2", children: [
11705
+ /* @__PURE__ */ jsx52(Section.Content, { children: node.kind === "field" ? /* @__PURE__ */ jsxs35("div", { className: "space-y-4", children: [
11706
+ hasFieldRule ? /* @__PURE__ */ jsxs35("div", { className: "space-y-3 rounded-xl border border-slate-200 p-3 dark:border-slate-800", children: [
11707
+ /* @__PURE__ */ jsxs35("div", { className: "space-y-2", children: [
11225
11708
  /* @__PURE__ */ jsx52("div", { className: "grid grid-cols-3 gap-2 rounded-lg bg-slate-100 p-1 dark:bg-slate-900", children: ruleOptions.map((option) => {
11226
11709
  const active = fieldRule?.valueBy === option.value;
11227
11710
  return /* @__PURE__ */ jsx52(
@@ -11250,7 +11733,7 @@ function QuantitySection({ node }) {
11250
11733
  onChange: (e) => updateRule({ code: String(e.value ?? "") })
11251
11734
  }
11252
11735
  ) : null,
11253
- /* @__PURE__ */ jsxs34("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: [
11736
+ /* @__PURE__ */ jsxs35("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: [
11254
11737
  /* @__PURE__ */ jsx52(
11255
11738
  InputField7,
11256
11739
  {
@@ -11303,7 +11786,7 @@ function QuantitySection({ node }) {
11303
11786
  )
11304
11787
  ] })
11305
11788
  ] }) : null,
11306
- capabilities.quantity.canEditDefault ? hasQuantityDefault ? /* @__PURE__ */ jsxs34("div", { className: "space-y-2 rounded-xl border border-slate-200 p-3 dark:border-slate-800", children: [
11789
+ capabilities.quantity.canEditDefault ? hasQuantityDefault ? /* @__PURE__ */ jsxs35("div", { className: "space-y-2 rounded-xl border border-slate-200 p-3 dark:border-slate-800", children: [
11307
11790
  /* @__PURE__ */ jsx52(
11308
11791
  InputField7,
11309
11792
  {
@@ -11316,7 +11799,7 @@ function QuantitySection({ node }) {
11316
11799
  ),
11317
11800
  capabilities.quantity.defaultHelp ? /* @__PURE__ */ jsx52("p", { className: "text-xs text-slate-500 dark:text-slate-400", children: capabilities.quantity.defaultHelp }) : null
11318
11801
  ] }) : null : null
11319
- ] }) : hasQuantityDefault ? /* @__PURE__ */ jsxs34("div", { className: "space-y-2", children: [
11802
+ ] }) : hasQuantityDefault ? /* @__PURE__ */ jsxs35("div", { className: "space-y-2", children: [
11320
11803
  /* @__PURE__ */ jsx52(
11321
11804
  InputField7,
11322
11805
  {
@@ -11338,7 +11821,7 @@ import { useCanvas as useCanvas9 } from "@timeax/digital-service-engine/workspac
11338
11821
  import { InputField as InputField8 } from "@timeax/form-palette";
11339
11822
  import { BsPencil, BsPlus as BsPlus3 } from "react-icons/bs";
11340
11823
  import { MdDeleteOutline as MdDeleteOutline2 } from "react-icons/md";
11341
- import { Fragment as Fragment10, jsx as jsx53, jsxs as jsxs35 } from "react/jsx-runtime";
11824
+ import { Fragment as Fragment10, jsx as jsx53, jsxs as jsxs36 } from "react/jsx-runtime";
11342
11825
  var utilityModes = [
11343
11826
  { label: "Flat", value: "flat" },
11344
11827
  { label: "Per quantity", value: "per_quantity" },
@@ -11390,10 +11873,10 @@ function UtilitySection({ node }) {
11390
11873
  canvas.api.editor.updateOption(node.id, { meta: nextMeta });
11391
11874
  });
11392
11875
  };
11393
- return /* @__PURE__ */ jsxs35(Section, { children: [
11394
- /* @__PURE__ */ jsxs35(Section.Header, { children: [
11876
+ return /* @__PURE__ */ jsxs36(Section, { children: [
11877
+ /* @__PURE__ */ jsxs36(Section.Header, { children: [
11395
11878
  /* @__PURE__ */ jsx53(Section.Title, { children: "Utility" }),
11396
- /* @__PURE__ */ jsxs35(Section.Actions, { children: [
11879
+ /* @__PURE__ */ jsxs36(Section.Actions, { children: [
11397
11880
  !hasStoredUtility && !isActiveUtility ? /* @__PURE__ */ jsx53(
11398
11881
  SectionActionButton,
11399
11882
  {
@@ -11426,10 +11909,10 @@ function UtilitySection({ node }) {
11426
11909
  ) : null
11427
11910
  ] })
11428
11911
  ] }),
11429
- /* @__PURE__ */ jsx53(Section.Content, { children: hasUtilityConfiguration ? /* @__PURE__ */ jsxs35("div", { className: "space-y-3", children: [
11912
+ /* @__PURE__ */ jsx53(Section.Content, { children: hasUtilityConfiguration ? /* @__PURE__ */ jsxs36("div", { className: "space-y-3", children: [
11430
11913
  !hasStoredUtility ? /* @__PURE__ */ jsx53("p", { className: "text-xs text-slate-500 dark:text-slate-400", children: "This node is marked as utility-priced, but its utility marker is missing. Fill in the values below to repair it." }) : null,
11431
11914
  hasStoredUtility && !isActiveUtility ? /* @__PURE__ */ jsx53("p", { className: "text-xs text-slate-500 dark:text-slate-400", children: "This node still has utility marker values stored, but its pricing role is base. Activate utility to apply these charges, or clear the marker." }) : null,
11432
- /* @__PURE__ */ jsxs35(Fragment10, { children: [
11915
+ /* @__PURE__ */ jsxs36(Fragment10, { children: [
11433
11916
  /* @__PURE__ */ jsx53(
11434
11917
  InputField8,
11435
11918
  {
@@ -11508,7 +11991,7 @@ import { InputField as InputField9 } from "@timeax/form-palette";
11508
11991
  import { useMemo as useMemo26 } from "react";
11509
11992
  import { BsPlus as BsPlus4 } from "react-icons/bs";
11510
11993
  import { MdDeleteOutline as MdDeleteOutline3 } from "react-icons/md";
11511
- import { jsx as jsx54, jsxs as jsxs36 } from "react/jsx-runtime";
11994
+ import { jsx as jsx54, jsxs as jsxs37 } from "react/jsx-runtime";
11512
11995
  var opOptions = [
11513
11996
  { label: "Equals", value: "eq" },
11514
11997
  { label: "Not equal", value: "neq" },
@@ -11581,7 +12064,7 @@ function TypedScalarEditor({
11581
12064
  onChange
11582
12065
  }) {
11583
12066
  const scalarType = inferScalarType(value);
11584
- return /* @__PURE__ */ jsx54("div", { className: "space-y-3 rounded-lg border border-slate-200/80 p-3 dark:border-slate-800", children: /* @__PURE__ */ jsxs36("div", { className: "grid gap-3 md:grid-cols-[160px_minmax(0,1fr)]", children: [
12067
+ return /* @__PURE__ */ jsx54("div", { className: "space-y-3 rounded-lg border border-slate-200/80 p-3 dark:border-slate-800", children: /* @__PURE__ */ jsxs37("div", { className: "grid gap-3 md:grid-cols-[160px_minmax(0,1fr)]", children: [
11585
12068
  /* @__PURE__ */ jsx54(
11586
12069
  InputField9,
11587
12070
  {
@@ -11627,17 +12110,17 @@ function TypedScalarListEditor({
11627
12110
  onChange
11628
12111
  }) {
11629
12112
  const items = (values ?? []).filter((value) => ["string", "number", "boolean"].includes(typeof value));
11630
- return /* @__PURE__ */ jsxs36("div", { className: "space-y-3 rounded-lg border border-slate-200/80 p-3 dark:border-slate-800", children: [
11631
- /* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between gap-3", children: [
11632
- /* @__PURE__ */ jsxs36("div", { children: [
12113
+ return /* @__PURE__ */ jsxs37("div", { className: "space-y-3 rounded-lg border border-slate-200/80 p-3 dark:border-slate-800", children: [
12114
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-center justify-between gap-3", children: [
12115
+ /* @__PURE__ */ jsxs37("div", { children: [
11633
12116
  /* @__PURE__ */ jsx54("h4", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: "Allowed values" }),
11634
12117
  /* @__PURE__ */ jsx54("p", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: "Rule values are checked in the order shown here." })
11635
12118
  ] }),
11636
12119
  /* @__PURE__ */ jsx54(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onChange([...items, ""]), children: "Add value" })
11637
12120
  ] }),
11638
- items.length ? /* @__PURE__ */ jsx54("div", { className: "space-y-3", children: items.map((item, index) => /* @__PURE__ */ jsxs36("div", { className: "space-y-3 rounded-lg border border-dashed border-slate-200 p-3 dark:border-slate-700", children: [
11639
- /* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between gap-3", children: [
11640
- /* @__PURE__ */ jsxs36("div", { className: "text-xs font-medium tracking-[0.16em] text-slate-500 uppercase dark:text-slate-400", children: [
12121
+ items.length ? /* @__PURE__ */ jsx54("div", { className: "space-y-3", children: items.map((item, index) => /* @__PURE__ */ jsxs37("div", { className: "space-y-3 rounded-lg border border-dashed border-slate-200 p-3 dark:border-slate-700", children: [
12122
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-center justify-between gap-3", children: [
12123
+ /* @__PURE__ */ jsxs37("div", { className: "text-xs font-medium tracking-[0.16em] text-slate-500 uppercase dark:text-slate-400", children: [
11641
12124
  "Value ",
11642
12125
  index + 1
11643
12126
  ] }),
@@ -11671,10 +12154,10 @@ function ValidationRuleCard({
11671
12154
  onRemove
11672
12155
  }) {
11673
12156
  const valueBy = rule.valueBy ?? "value";
11674
- return /* @__PURE__ */ jsxs36("div", { className: "space-y-4 rounded-xl border border-slate-200 p-4 dark:border-slate-800", children: [
11675
- /* @__PURE__ */ jsxs36("div", { className: "flex items-start justify-between gap-3", children: [
11676
- /* @__PURE__ */ jsxs36("div", { children: [
11677
- /* @__PURE__ */ jsxs36("div", { className: "text-xs font-medium tracking-[0.16em] text-slate-500 uppercase dark:text-slate-400", children: [
12157
+ return /* @__PURE__ */ jsxs37("div", { className: "space-y-4 rounded-xl border border-slate-200 p-4 dark:border-slate-800", children: [
12158
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-start justify-between gap-3", children: [
12159
+ /* @__PURE__ */ jsxs37("div", { children: [
12160
+ /* @__PURE__ */ jsxs37("div", { className: "text-xs font-medium tracking-[0.16em] text-slate-500 uppercase dark:text-slate-400", children: [
11678
12161
  "Rule ",
11679
12162
  index + 1
11680
12163
  ] }),
@@ -11691,7 +12174,7 @@ function ValidationRuleCard({
11691
12174
  }
11692
12175
  )
11693
12176
  ] }),
11694
- /* @__PURE__ */ jsxs36("div", { className: "grid gap-3 md:grid-cols-2", children: [
12177
+ /* @__PURE__ */ jsxs37("div", { className: "grid gap-3 md:grid-cols-2", children: [
11695
12178
  /* @__PURE__ */ jsx54(
11696
12179
  InputField9,
11697
12180
  {
@@ -11751,7 +12234,7 @@ function ValidationRuleCard({
11751
12234
  )
11752
12235
  }
11753
12236
  ) : null,
11754
- rule.op === "between" ? /* @__PURE__ */ jsxs36("div", { className: "grid gap-3 md:grid-cols-2", children: [
12237
+ rule.op === "between" ? /* @__PURE__ */ jsxs37("div", { className: "grid gap-3 md:grid-cols-2", children: [
11755
12238
  /* @__PURE__ */ jsx54(
11756
12239
  InputField9,
11757
12240
  {
@@ -11795,7 +12278,7 @@ function ValidationRuleCard({
11795
12278
  )
11796
12279
  }
11797
12280
  ) : null,
11798
- rule.op === "match" ? /* @__PURE__ */ jsxs36("div", { className: "grid gap-3 md:grid-cols-2", children: [
12281
+ rule.op === "match" ? /* @__PURE__ */ jsxs37("div", { className: "grid gap-3 md:grid-cols-2", children: [
11799
12282
  /* @__PURE__ */ jsx54(
11800
12283
  InputField9,
11801
12284
  {
@@ -11869,10 +12352,10 @@ function ValidationSection({ node }) {
11869
12352
  const removeRuleAt = (index) => {
11870
12353
  persistRules(rules.filter((_, ruleIndex) => ruleIndex !== index));
11871
12354
  };
11872
- return /* @__PURE__ */ jsxs36(Section, { children: [
11873
- /* @__PURE__ */ jsxs36(Section.Header, { children: [
12355
+ return /* @__PURE__ */ jsxs37(Section, { children: [
12356
+ /* @__PURE__ */ jsxs37(Section.Header, { children: [
11874
12357
  /* @__PURE__ */ jsx54(Section.Title, { children: "Validation" }),
11875
- /* @__PURE__ */ jsxs36(Section.Actions, { children: [
12358
+ /* @__PURE__ */ jsxs37(Section.Actions, { children: [
11876
12359
  !rules.length ? /* @__PURE__ */ jsx54(SectionActionButton, { icon: /* @__PURE__ */ jsx54(BsPlus4, {}), iconOnly: true, tooltip: "Add validation", "aria-label": "Add validation", onClick: addRule }) : null,
11877
12360
  rules.length ? /* @__PURE__ */ jsx54(
11878
12361
  SectionActionButton,
@@ -11886,7 +12369,7 @@ function ValidationSection({ node }) {
11886
12369
  ) : null
11887
12370
  ] })
11888
12371
  ] }),
11889
- /* @__PURE__ */ jsx54(Section.Content, { children: rules.length ? /* @__PURE__ */ jsxs36("div", { className: "space-y-4", children: [
12372
+ /* @__PURE__ */ jsx54(Section.Content, { children: rules.length ? /* @__PURE__ */ jsxs37("div", { className: "space-y-4", children: [
11890
12373
  rules.map((rule, index) => /* @__PURE__ */ jsx54(
11891
12374
  ValidationRuleCard,
11892
12375
  {
@@ -11898,7 +12381,7 @@ function ValidationSection({ node }) {
11898
12381
  `${index}-${rule.op}-${rule.valueBy ?? "value"}`
11899
12382
  )),
11900
12383
  /* @__PURE__ */ jsx54(Button, { type: "button", variant: "outline", size: "sm", onClick: addRule, children: "Add another rule" })
11901
- ] }) : /* @__PURE__ */ jsxs36("div", { className: "space-y-3 rounded-xl border border-dashed border-slate-200 p-4 dark:border-slate-800", children: [
12384
+ ] }) : /* @__PURE__ */ jsxs37("div", { className: "space-y-3 rounded-xl border border-dashed border-slate-200 p-4 dark:border-slate-800", children: [
11902
12385
  /* @__PURE__ */ jsx54("p", { className: "text-sm font-medium text-slate-900 dark:text-slate-100", children: "No validation rules yet" }),
11903
12386
  /* @__PURE__ */ jsx54("p", { className: "text-xs text-slate-500 dark:text-slate-400", children: "Add ordered rules to validate this field value, its length, or an eval-derived subject. The first failing rule supplies the field message." }),
11904
12387
  /* @__PURE__ */ jsx54(Button, { type: "button", variant: "outline", size: "sm", onClick: addRule, children: "Add validation" })
@@ -11916,12 +12399,12 @@ import { useMemo as useMemo27, useState as useState27 } from "react";
11916
12399
  import { InputField as InputField10 } from "@timeax/form-palette";
11917
12400
  import { useState as useState26 } from "react";
11918
12401
  import { BsPlus as BsPlus5 } from "react-icons/bs";
11919
- import { jsx as jsx55, jsxs as jsxs37 } from "react/jsx-runtime";
12402
+ import { jsx as jsx55, jsxs as jsxs38 } from "react/jsx-runtime";
11920
12403
  function AddIncludesPopover({ open, onOpenChange, onSelect, options }) {
11921
12404
  const [value, setValue] = useState26();
11922
- return /* @__PURE__ */ jsxs37(Popover, { open, onOpenChange, children: [
12405
+ return /* @__PURE__ */ jsxs38(Popover, { open, onOpenChange, children: [
11923
12406
  /* @__PURE__ */ jsx55(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx55(SectionActionTriggerButton, { icon: /* @__PURE__ */ jsx55(BsPlus5, {}), children: "Add" }) }),
11924
- /* @__PURE__ */ jsx55(PopoverContent, { children: /* @__PURE__ */ jsxs37("div", { className: "flex flex-col gap-2", children: [
12407
+ /* @__PURE__ */ jsx55(PopoverContent, { children: /* @__PURE__ */ jsxs38("div", { className: "flex flex-col gap-2", children: [
11925
12408
  /* @__PURE__ */ jsx55(
11926
12409
  InputField10,
11927
12410
  {
@@ -11952,7 +12435,7 @@ function AddIncludesPopover({ open, onOpenChange, onSelect, options }) {
11952
12435
  }
11953
12436
 
11954
12437
  // src/panels/right/partials/properties/components/Union.tsx
11955
- import { jsx as jsx56, jsxs as jsxs38 } from "react/jsx-runtime";
12438
+ import { jsx as jsx56, jsxs as jsxs39 } from "react/jsx-runtime";
11956
12439
  function IncExcludeSection({ node, mode, capability }) {
11957
12440
  const canvas = useCanvas11();
11958
12441
  const [open, setOpen] = useState27(false);
@@ -11988,8 +12471,8 @@ function IncExcludeSection({ node, mode, capability }) {
11988
12471
  }));
11989
12472
  }, [canvas.props.fields, node]);
11990
12473
  const name = mode.slice(0, -1);
11991
- return /* @__PURE__ */ jsxs38(Section, { children: [
11992
- /* @__PURE__ */ jsxs38(Section.Header, { children: [
12474
+ return /* @__PURE__ */ jsxs39(Section, { children: [
12475
+ /* @__PURE__ */ jsxs39(Section.Header, { children: [
11993
12476
  /* @__PURE__ */ jsx56(Section.Title, { children: mode == "includes" ? "Includes" : "Excludes" }),
11994
12477
  /* @__PURE__ */ jsx56(Section.Actions, { children: canEdit ? /* @__PURE__ */ jsx56(
11995
12478
  AddIncludesPopover,
@@ -12001,7 +12484,7 @@ function IncExcludeSection({ node, mode, capability }) {
12001
12484
  }
12002
12485
  ) : null })
12003
12486
  ] }),
12004
- /* @__PURE__ */ jsxs38(Section.Content, { children: [
12487
+ /* @__PURE__ */ jsxs39(Section.Content, { children: [
12005
12488
  helperMessage ? /* @__PURE__ */ jsx56("p", { className: "mb-3 text-xs text-slate-500 dark:text-slate-400", children: helperMessage }) : null,
12006
12489
  /* @__PURE__ */ jsx56(RenderIf, { data: (node[mode]?.size ?? 0) > 0, emptyMessage: "None", children: /* @__PURE__ */ jsx56(IncludesList, { children: Array.from(node[mode] ?? []).map((id) => {
12007
12490
  const field = fields[id];
@@ -12033,7 +12516,7 @@ function IncExcludeSection({ node, mode, capability }) {
12033
12516
  }
12034
12517
 
12035
12518
  // src/panels/right/partials/properties/field-properties.tsx
12036
- import { Fragment as Fragment11, jsx as jsx57, jsxs as jsxs39 } from "react/jsx-runtime";
12519
+ import { Fragment as Fragment11, jsx as jsx57, jsxs as jsxs40 } from "react/jsx-runtime";
12037
12520
  var getVariant = (node) => {
12038
12521
  const variant = node.raw.meta?.variant;
12039
12522
  return typeof variant === "string" && variant.trim() ? variant.trim() : void 0;
@@ -12062,13 +12545,13 @@ function FieldProperties({ className, node }) {
12062
12545
  const descriptor = useMemo28(() => resolveInputDescriptor(registry, currentType, currentVariant), [currentType, currentVariant, registry]);
12063
12546
  const descriptorUi = descriptor?.ui ?? {};
12064
12547
  const descriptorKeySet = useMemo28(() => new Set(getDescriptorUiKeys(descriptorUi)), [descriptorUi]);
12065
- useEffect17(() => {
12548
+ useEffect18(() => {
12066
12549
  setNameDraft(nameValue);
12067
12550
  }, [node.id, nameValue]);
12068
- useEffect17(() => {
12551
+ useEffect18(() => {
12069
12552
  setPlaceholderDraft(placeholderValue);
12070
12553
  }, [node.id, placeholderValue]);
12071
- useEffect17(() => {
12554
+ useEffect18(() => {
12072
12555
  setHelpTextDraft(helpTextValue);
12073
12556
  }, [node.id, helpTextValue]);
12074
12557
  const fieldTypeOptions = useMemo28(() => {
@@ -12125,12 +12608,12 @@ function FieldProperties({ className, node }) {
12125
12608
  const nextVariant = String(rawVariant ?? "default");
12126
12609
  applyDescriptorTransition(currentType, nextVariant === "default" ? void 0 : nextVariant);
12127
12610
  };
12128
- return /* @__PURE__ */ jsx57("div", { className, children: /* @__PURE__ */ jsxs39("div", { className: "space-y-4", children: [
12129
- /* @__PURE__ */ jsxs39(Section, { children: [
12611
+ return /* @__PURE__ */ jsx57("div", { className, children: /* @__PURE__ */ jsxs40("div", { className: "space-y-4", children: [
12612
+ /* @__PURE__ */ jsxs40(Section, { children: [
12130
12613
  /* @__PURE__ */ jsx57(Section.Header, { children: /* @__PURE__ */ jsx57(Section.Title, { children: "Field identity" }) }),
12131
- /* @__PURE__ */ jsxs39(Section.Content, { children: [
12614
+ /* @__PURE__ */ jsxs40(Section.Content, { children: [
12132
12615
  /* @__PURE__ */ jsx57("p", { className: "mb-3 text-xs text-slate-500 dark:text-slate-400", children: "Core field metadata used by the service engine and preview form." }),
12133
- /* @__PURE__ */ jsxs39("div", { className: "space-y-3", children: [
12616
+ /* @__PURE__ */ jsxs40("div", { className: "space-y-3", children: [
12134
12617
  /* @__PURE__ */ jsx57(
12135
12618
  InputField11,
12136
12619
  {
@@ -12186,11 +12669,11 @@ function FieldProperties({ className, node }) {
12186
12669
  ] })
12187
12670
  ] }),
12188
12671
  /* @__PURE__ */ jsx57(Separator2, {}),
12189
- /* @__PURE__ */ jsxs39(Section, { children: [
12672
+ /* @__PURE__ */ jsxs40(Section, { children: [
12190
12673
  /* @__PURE__ */ jsx57(Section.Header, { children: /* @__PURE__ */ jsx57(Section.Title, { children: "Defaults and help" }) }),
12191
- /* @__PURE__ */ jsxs39(Section.Content, { children: [
12674
+ /* @__PURE__ */ jsxs40(Section.Content, { children: [
12192
12675
  /* @__PURE__ */ jsx57("p", { className: "mb-3 text-xs text-slate-500 dark:text-slate-400", children: "Preview-oriented defaults passed to the form palette." }),
12193
- /* @__PURE__ */ jsxs39("div", { className: "space-y-3", children: [
12676
+ /* @__PURE__ */ jsxs40("div", { className: "space-y-3", children: [
12194
12677
  /* @__PURE__ */ jsx57(
12195
12678
  InputField11,
12196
12679
  {
@@ -12215,11 +12698,11 @@ function FieldProperties({ className, node }) {
12215
12698
  ] })
12216
12699
  ] }),
12217
12700
  /* @__PURE__ */ jsx57(Separator2, {}),
12218
- /* @__PURE__ */ jsxs39(Section, { defaultOpen: false, children: [
12701
+ /* @__PURE__ */ jsxs40(Section, { defaultOpen: false, children: [
12219
12702
  /* @__PURE__ */ jsx57(Section.Header, { children: /* @__PURE__ */ jsx57(Section.Title, { children: "Input appearance and behavior" }) }),
12220
- /* @__PURE__ */ jsxs39(Section.Content, { children: [
12703
+ /* @__PURE__ */ jsxs40(Section.Content, { children: [
12221
12704
  /* @__PURE__ */ jsx57("p", { className: "mb-3 text-xs text-slate-500 dark:text-slate-400", children: "Descriptor-owned runtime props. The schema comes from the input registry and overrides are stored in field defaults." }),
12222
- descriptor ? /* @__PURE__ */ jsx57(DescriptorSettings, { schema: descriptorUi, defaults, onChange: updateDefaults }) : /* @__PURE__ */ jsxs39("p", { className: "text-xs text-slate-500 dark:text-slate-400", children: [
12705
+ descriptor ? /* @__PURE__ */ jsx57(DescriptorSettings, { schema: descriptorUi, defaults, onChange: updateDefaults }) : /* @__PURE__ */ jsxs40("p", { className: "text-xs text-slate-500 dark:text-slate-400", children: [
12223
12706
  "No input descriptor was found for this field type",
12224
12707
  currentVariant ? ` / ${currentVariant}` : "",
12225
12708
  "."
@@ -12233,9 +12716,9 @@ function FieldProperties({ className, node }) {
12233
12716
  /* @__PURE__ */ jsx57(Separator2, {}),
12234
12717
  /* @__PURE__ */ jsx57(utility_section_default, { node }),
12235
12718
  /* @__PURE__ */ jsx57(Separator2, {}),
12236
- /* @__PURE__ */ jsxs39(Section, { children: [
12719
+ /* @__PURE__ */ jsxs40(Section, { children: [
12237
12720
  /* @__PURE__ */ jsx57(Section.Header, { children: /* @__PURE__ */ jsx57(Section.Title, { children: "Binding summary" }) }),
12238
- /* @__PURE__ */ jsxs39(Section.Content, { children: [
12721
+ /* @__PURE__ */ jsxs40(Section.Content, { children: [
12239
12722
  /* @__PURE__ */ jsx57("p", { className: "mb-3 text-xs text-slate-500 dark:text-slate-400", children: "Where this field appears and how it behaves in the active branch." }),
12240
12723
  /* @__PURE__ */ jsx57(
12241
12724
  PropertyList,
@@ -12250,12 +12733,12 @@ function FieldProperties({ className, node }) {
12250
12733
  ] })
12251
12734
  ] }),
12252
12735
  /* @__PURE__ */ jsx57(Separator2, {}),
12253
- options.length ? /* @__PURE__ */ jsxs39(Fragment11, { children: [
12254
- /* @__PURE__ */ jsxs39(Section, { children: [
12736
+ options.length ? /* @__PURE__ */ jsxs40(Fragment11, { children: [
12737
+ /* @__PURE__ */ jsxs40(Section, { children: [
12255
12738
  /* @__PURE__ */ jsx57(Section.Header, { children: /* @__PURE__ */ jsx57(Section.Title, { children: "Options" }) }),
12256
- /* @__PURE__ */ jsxs39(Section.Content, { children: [
12739
+ /* @__PURE__ */ jsxs40(Section.Content, { children: [
12257
12740
  /* @__PURE__ */ jsx57("p", { className: "mb-3 text-xs text-slate-500 dark:text-slate-400", children: "Current option labels available on this field." }),
12258
- /* @__PURE__ */ jsx57("div", { className: "space-y-2", children: options.map((option) => /* @__PURE__ */ jsxs39(
12741
+ /* @__PURE__ */ jsx57("div", { className: "space-y-2", children: options.map((option) => /* @__PURE__ */ jsxs40(
12259
12742
  "div",
12260
12743
  {
12261
12744
  className: "flex items-center justify-between rounded-xl bg-slate-50 px-3 py-2 text-sm dark:bg-slate-900",
@@ -12278,11 +12761,11 @@ function FieldProperties({ className, node }) {
12278
12761
  ] }),
12279
12762
  /* @__PURE__ */ jsx57(Separator2, {})
12280
12763
  ] }) : null,
12281
- capabilities.triggerMappings.canEdit ? /* @__PURE__ */ jsxs39(Fragment11, { children: [
12764
+ capabilities.triggerMappings.canEdit ? /* @__PURE__ */ jsxs40(Fragment11, { children: [
12282
12765
  /* @__PURE__ */ jsx57(IncExcludeSection, { node, mode: "includes", capability: capabilities.triggerMappings }),
12283
12766
  /* @__PURE__ */ jsx57(Separator2, {}),
12284
12767
  /* @__PURE__ */ jsx57(IncExcludeSection, { node, mode: "excludes", capability: capabilities.triggerMappings })
12285
- ] }) : /* @__PURE__ */ jsxs39(Section, { children: [
12768
+ ] }) : /* @__PURE__ */ jsxs40(Section, { children: [
12286
12769
  /* @__PURE__ */ jsx57(Section.Header, { children: /* @__PURE__ */ jsx57(Section.Title, { children: "Trigger mappings" }) }),
12287
12770
  /* @__PURE__ */ jsx57(Section.Content, { children: /* @__PURE__ */ jsx57("p", { className: "text-xs text-slate-500 dark:text-slate-400", children: capabilities.triggerMappings.message }) })
12288
12771
  ] }),
@@ -12295,18 +12778,18 @@ var field_properties_default = FieldProperties;
12295
12778
  // src/panels/right/partials/properties/option-properties.tsx
12296
12779
  import { useCanvas as useCanvas13 } from "@timeax/digital-service-engine/workspace";
12297
12780
  import { InputField as InputField12 } from "@timeax/form-palette";
12298
- import { jsx as jsx58, jsxs as jsxs40 } from "react/jsx-runtime";
12781
+ import { jsx as jsx58, jsxs as jsxs41 } from "react/jsx-runtime";
12299
12782
  function OptionProperties({ className, node }) {
12300
12783
  const canvas = useCanvas13();
12301
12784
  const capabilities = getOptionPropertyCapabilities(node);
12302
12785
  const field = node.field();
12303
12786
  const options = field.raw.options ?? [];
12304
- return /* @__PURE__ */ jsx58("div", { className, children: /* @__PURE__ */ jsxs40("div", { className: "space-y-4", children: [
12305
- /* @__PURE__ */ jsxs40(Section, { children: [
12787
+ return /* @__PURE__ */ jsx58("div", { className, children: /* @__PURE__ */ jsxs41("div", { className: "space-y-4", children: [
12788
+ /* @__PURE__ */ jsxs41(Section, { children: [
12306
12789
  /* @__PURE__ */ jsx58(Section.Header, { children: /* @__PURE__ */ jsx58(Section.Title, { children: "Option identity" }) }),
12307
- /* @__PURE__ */ jsxs40(Section.Content, { children: [
12790
+ /* @__PURE__ */ jsxs41(Section.Content, { children: [
12308
12791
  /* @__PURE__ */ jsx58("p", { className: "mb-3 text-xs text-slate-500 dark:text-slate-400", children: "Edit the currently focused option node." }),
12309
- /* @__PURE__ */ jsxs40("div", { className: "space-y-3", children: [
12792
+ /* @__PURE__ */ jsxs41("div", { className: "space-y-3", children: [
12310
12793
  /* @__PURE__ */ jsx58(
12311
12794
  InputField12,
12312
12795
  {
@@ -12344,9 +12827,9 @@ function OptionProperties({ className, node }) {
12344
12827
  /* @__PURE__ */ jsx58(Separator2, {}),
12345
12828
  /* @__PURE__ */ jsx58(utility_section_default, { node }),
12346
12829
  /* @__PURE__ */ jsx58(Separator2, {}),
12347
- /* @__PURE__ */ jsxs40(Section, { children: [
12830
+ /* @__PURE__ */ jsxs41(Section, { children: [
12348
12831
  /* @__PURE__ */ jsx58(Section.Header, { children: /* @__PURE__ */ jsx58(Section.Title, { children: "Option mapping" }) }),
12349
- /* @__PURE__ */ jsxs40(Section.Content, { children: [
12832
+ /* @__PURE__ */ jsxs41(Section.Content, { children: [
12350
12833
  /* @__PURE__ */ jsx58("p", { className: "mb-3 text-xs text-slate-500 dark:text-slate-400", children: "How this option participates in visible field mappings." }),
12351
12834
  /* @__PURE__ */ jsx58(
12352
12835
  PropertyList,
@@ -12385,11 +12868,11 @@ import { TiDelete } from "react-icons/ti";
12385
12868
  import { Form, InputField as InputField13 } from "@timeax/form-palette";
12386
12869
  import "react";
12387
12870
  import { BsPlus as BsPlus6 } from "react-icons/bs";
12388
- import { jsx as jsx59, jsxs as jsxs41 } from "react/jsx-runtime";
12871
+ import { jsx as jsx59, jsxs as jsxs42 } from "react/jsx-runtime";
12389
12872
  function AddConstraintsPopover({ open, onOpenChange, constraints, allConstraints, onSubmit }) {
12390
- return /* @__PURE__ */ jsxs41(Popover, { open, onOpenChange, children: [
12873
+ return /* @__PURE__ */ jsxs42(Popover, { open, onOpenChange, children: [
12391
12874
  /* @__PURE__ */ jsx59(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx59(SectionActionTriggerButton, { icon: /* @__PURE__ */ jsx59(BsPlus6, {}), children: "Add" }) }),
12392
- /* @__PURE__ */ jsx59(PopoverContent, { children: /* @__PURE__ */ jsx59(RenderIf, { data: allConstraints, children: /* @__PURE__ */ jsxs41(
12875
+ /* @__PURE__ */ jsx59(PopoverContent, { children: /* @__PURE__ */ jsx59(RenderIf, { data: allConstraints, children: /* @__PURE__ */ jsxs42(
12393
12876
  Form,
12394
12877
  {
12395
12878
  wrapped: true,
@@ -12420,20 +12903,20 @@ function AddConstraintsPopover({ open, onOpenChange, constraints, allConstraints
12420
12903
 
12421
12904
  // src/panels/right/partials/properties/tag/ConstraintOriginPopover.tsx
12422
12905
  import "react";
12423
- import { jsx as jsx60, jsxs as jsxs42 } from "react/jsx-runtime";
12906
+ import { jsx as jsx60, jsxs as jsxs43 } from "react/jsx-runtime";
12424
12907
  function ConstraintOriginPopover({ constraint, onClearSelf, onClearSubtree }) {
12425
- return /* @__PURE__ */ jsxs42(Popover, { children: [
12908
+ return /* @__PURE__ */ jsxs43(Popover, { children: [
12426
12909
  /* @__PURE__ */ jsx60(PopoverTrigger, { className: "flex items-center gap-1", children: "Owner" }),
12427
- /* @__PURE__ */ jsx60(PopoverContent, { className: "w-fit p-0", children: /* @__PURE__ */ jsxs42("div", { className: "max-w-[320px] p-3 text-sm", children: [
12910
+ /* @__PURE__ */ jsx60(PopoverContent, { className: "w-fit p-0", children: /* @__PURE__ */ jsxs43("div", { className: "max-w-[320px] p-3 text-sm", children: [
12428
12911
  /* @__PURE__ */ jsx60("div", { className: "font-medium", children: "Clear constraint?" }),
12429
- /* @__PURE__ */ jsxs42("div", { className: "mt-1 text-muted-foreground", children: [
12912
+ /* @__PURE__ */ jsxs43("div", { className: "mt-1 text-muted-foreground", children: [
12430
12913
  "You're about to clear ",
12431
12914
  /* @__PURE__ */ jsx60("span", { className: "font-medium", children: constraint }),
12432
12915
  " on this tag. Descendants may inherit a different value (or none) after this change."
12433
12916
  ] }),
12434
- /* @__PURE__ */ jsxs42("div", { className: "mt-3 space-y-2", children: [
12917
+ /* @__PURE__ */ jsxs43("div", { className: "mt-3 space-y-2", children: [
12435
12918
  /* @__PURE__ */ jsx60("div", { className: "text-muted-foreground", children: "Do you want to also clear it for the whole subtree (\xE2\u20AC\u0153shake the tree\xE2\u20AC\x9D)?" }),
12436
- /* @__PURE__ */ jsxs42("div", { className: "flex items-center justify-end gap-2", children: [
12919
+ /* @__PURE__ */ jsxs43("div", { className: "flex items-center justify-end gap-2", children: [
12437
12920
  /* @__PURE__ */ jsx60(
12438
12921
  "button",
12439
12922
  {
@@ -12461,24 +12944,24 @@ function ConstraintOriginPopover({ constraint, onClearSelf, onClearSubtree }) {
12461
12944
  // src/panels/right/partials/properties/tag/ConstraintOverridePopover.tsx
12462
12945
  import { AlertTriangle } from "lucide-react";
12463
12946
  import "react";
12464
- import { jsx as jsx61, jsxs as jsxs43 } from "react/jsx-runtime";
12947
+ import { jsx as jsx61, jsxs as jsxs44 } from "react/jsx-runtime";
12465
12948
  function ConstraintOverridePopover({ constraint, onClear }) {
12466
- return /* @__PURE__ */ jsxs43(Popover, { children: [
12467
- /* @__PURE__ */ jsxs43(PopoverTrigger, { className: "flex items-center gap-1", children: [
12949
+ return /* @__PURE__ */ jsxs44(Popover, { children: [
12950
+ /* @__PURE__ */ jsxs44(PopoverTrigger, { className: "flex items-center gap-1", children: [
12468
12951
  /* @__PURE__ */ jsx61(AlertTriangle, { className: "size-3 text-yellow-400" }),
12469
12952
  "Overridden"
12470
12953
  ] }),
12471
- /* @__PURE__ */ jsx61(PopoverContent, { className: "w-fit p-0", children: /* @__PURE__ */ jsxs43("div", { className: "max-w-[320px] p-3 text-sm", children: [
12954
+ /* @__PURE__ */ jsx61(PopoverContent, { className: "w-fit p-0", children: /* @__PURE__ */ jsxs44("div", { className: "max-w-[320px] p-3 text-sm", children: [
12472
12955
  /* @__PURE__ */ jsx61("div", { className: "font-medium", children: "Constraint override detected" }),
12473
- /* @__PURE__ */ jsxs43("div", { className: "mt-1 text-muted-foreground", children: [
12956
+ /* @__PURE__ */ jsxs44("div", { className: "mt-1 text-muted-foreground", children: [
12474
12957
  "This tag tries to set ",
12475
12958
  /* @__PURE__ */ jsx61("span", { className: "font-medium", children: constraint }),
12476
12959
  ", but an ancestor tag already decided it. Overrides don't apply \xE2\u20AC\u201D the ancestor value wins."
12477
12960
  ] }),
12478
- /* @__PURE__ */ jsxs43("div", { className: "mt-3 space-y-1", children: [
12961
+ /* @__PURE__ */ jsxs44("div", { className: "mt-3 space-y-1", children: [
12479
12962
  /* @__PURE__ */ jsx61("div", { className: "font-medium", children: "How to fix" }),
12480
- /* @__PURE__ */ jsxs43("ul", { className: "list-disc pl-4 text-muted-foreground", children: [
12481
- /* @__PURE__ */ jsxs43("li", { children: [
12963
+ /* @__PURE__ */ jsxs44("ul", { className: "list-disc pl-4 text-muted-foreground", children: [
12964
+ /* @__PURE__ */ jsxs44("li", { children: [
12482
12965
  "Click ",
12483
12966
  /* @__PURE__ */ jsx61("span", { className: "font-medium", children: "Origin" }),
12484
12967
  " to jump to the ancestor that set the rule, then make the value match there (or remove it)."
@@ -12500,14 +12983,14 @@ function ConstraintOverridePopover({ constraint, onClear }) {
12500
12983
  }
12501
12984
 
12502
12985
  // src/panels/right/partials/properties/tag/TagConstraintsSection.tsx
12503
- import { Fragment as Fragment12, jsx as jsx62, jsxs as jsxs44 } from "react/jsx-runtime";
12986
+ import { Fragment as Fragment12, jsx as jsx62, jsxs as jsxs45 } from "react/jsx-runtime";
12504
12987
  function TagConstraintsSection({ node }) {
12505
12988
  const constraints = Object.keys(node.raw.constraints ?? {});
12506
12989
  const canvas = useCanvas14();
12507
12990
  const [open, setOpen] = useState29(false);
12508
12991
  const allConstraints = useMemo29(() => canvas.api.getConstraints() ?? [], [canvas.props]);
12509
- return /* @__PURE__ */ jsx62(Fragment12, { children: /* @__PURE__ */ jsxs44(Section, { children: [
12510
- /* @__PURE__ */ jsxs44(Section.Header, { children: [
12992
+ return /* @__PURE__ */ jsx62(Fragment12, { children: /* @__PURE__ */ jsxs45(Section, { children: [
12993
+ /* @__PURE__ */ jsxs45(Section.Header, { children: [
12511
12994
  /* @__PURE__ */ jsx62(Section.Title, { children: "Constraints" }),
12512
12995
  /* @__PURE__ */ jsx62(Section.Actions, { children: /* @__PURE__ */ jsx62(
12513
12996
  AddConstraintsPopover,
@@ -12602,10 +13085,10 @@ function TagExcludesSection({ node }) {
12602
13085
  }
12603
13086
 
12604
13087
  // src/panels/right/partials/properties/tag.tsx
12605
- import { Fragment as Fragment13, jsx as jsx65, jsxs as jsxs45 } from "react/jsx-runtime";
13088
+ import { Fragment as Fragment13, jsx as jsx65, jsxs as jsxs46 } from "react/jsx-runtime";
12606
13089
  function TagProperties({ node }) {
12607
13090
  const capabilities = getTagPropertyCapabilities();
12608
- return /* @__PURE__ */ jsxs45(Fragment13, { children: [
13091
+ return /* @__PURE__ */ jsxs46(Fragment13, { children: [
12609
13092
  /* @__PURE__ */ jsx65(TagConstraintsSection, { node }),
12610
13093
  /* @__PURE__ */ jsx65(Separator2, {}),
12611
13094
  /* @__PURE__ */ jsx65(quantity_section_default, { node }),
@@ -12624,7 +13107,7 @@ import { InputField as InputField15 } from "@timeax/form-palette";
12624
13107
  import { useMemo as useMemo30, useState as useState30 } from "react";
12625
13108
  import { AiOutlineLoading3Quarters } from "react-icons/ai";
12626
13109
  import { MdOutlineContentCopy } from "react-icons/md";
12627
- import { jsx as jsx66, jsxs as jsxs46 } from "react/jsx-runtime";
13110
+ import { jsx as jsx66, jsxs as jsxs47 } from "react/jsx-runtime";
12628
13111
  var kinds = {
12629
13112
  tag: TagProperties,
12630
13113
  option: option_properties_default,
@@ -12642,20 +13125,20 @@ var Properties = () => {
12642
13125
  if (!Kind) {
12643
13126
  return /* @__PURE__ */ jsx66("div", { className: "p-4", children: /* @__PURE__ */ jsx66(EmptyState, { title: "No active node selected", description: "Pick a tag, field, or option from the layers panel or canvas to inspect its core settings." }) });
12644
13127
  }
12645
- return /* @__PURE__ */ jsx66("div", { className: "flex h-full flex-col overflow-hidden", children: /* @__PURE__ */ jsx66(ScrollArea, { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsxs46("div", { className: "flex flex-col gap-4 px-4 py-4", children: [
13128
+ return /* @__PURE__ */ jsx66("div", { className: "flex h-full flex-col overflow-hidden", children: /* @__PURE__ */ jsx66(ScrollArea, { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsxs47("div", { className: "flex flex-col gap-4 px-4 py-4", children: [
12646
13129
  /* @__PURE__ */ jsx66(WorkspaceBootInlineNotice, { boot: ws.boot, sections: ["snapshotBody", "policies"] }),
12647
- /* @__PURE__ */ jsxs46(Section, { children: [
13130
+ /* @__PURE__ */ jsxs47(Section, { children: [
12648
13131
  /* @__PURE__ */ jsx66(Section.Header, { children: /* @__PURE__ */ jsx66(Section.Title, { children: "Selection overview" }) }),
12649
- /* @__PURE__ */ jsxs46(Section.Content, { children: [
13132
+ /* @__PURE__ */ jsxs47(Section.Content, { children: [
12650
13133
  /* @__PURE__ */ jsx66("p", { className: "mb-3 text-xs text-slate-500 dark:text-slate-400", children: "The inspector stays synced with the active canvas and layers selection." }),
12651
- /* @__PURE__ */ jsxs46("div", { className: "flex items-start justify-between gap-3", children: [
12652
- /* @__PURE__ */ jsxs46("div", { children: [
13134
+ /* @__PURE__ */ jsxs47("div", { className: "flex items-start justify-between gap-3", children: [
13135
+ /* @__PURE__ */ jsxs47("div", { children: [
12653
13136
  /* @__PURE__ */ jsx66("div", { className: "text-sm font-semibold capitalize text-slate-900 dark:text-slate-100", children: node.kind }),
12654
13137
  /* @__PURE__ */ jsx66("p", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: getNodeSummary(node) })
12655
13138
  ] }),
12656
13139
  /* @__PURE__ */ jsx66(SelectionBadge, { active: true, selected: true })
12657
13140
  ] }),
12658
- /* @__PURE__ */ jsxs46("div", { className: "mt-3 space-y-3", children: [
13141
+ /* @__PURE__ */ jsxs47("div", { className: "mt-3 space-y-3", children: [
12659
13142
  /* @__PURE__ */ jsx66(
12660
13143
  InputField15,
12661
13144
  {
@@ -12712,7 +13195,7 @@ var Properties = () => {
12712
13195
 
12713
13196
  // src/panels/right/components/wireframe-tags-widget.tsx
12714
13197
  import { IoClose } from "react-icons/io5";
12715
- import { Fragment as Fragment14, jsx as jsx67, jsxs as jsxs47 } from "react/jsx-runtime";
13198
+ import { Fragment as Fragment14, jsx as jsx67, jsxs as jsxs48 } from "react/jsx-runtime";
12716
13199
  function noticeToneClass(notice) {
12717
13200
  const color = (notice.color ?? "").toLowerCase();
12718
13201
  if (color.includes("red") || color.includes("rose") || color.includes("danger")) {
@@ -12745,7 +13228,7 @@ function WireframeTagsWidget({
12745
13228
  onTagDragOver,
12746
13229
  onTagDrop
12747
13230
  }) {
12748
- return /* @__PURE__ */ jsxs47("div", { className: "flex flex-wrap items-center gap-2", children: [
13231
+ return /* @__PURE__ */ jsxs48("div", { className: "flex flex-wrap items-center gap-2", children: [
12749
13232
  /* @__PURE__ */ jsx67(
12750
13233
  "small",
12751
13234
  {
@@ -12755,8 +13238,8 @@ function WireframeTagsWidget({
12755
13238
  children: "Tags:"
12756
13239
  }
12757
13240
  ),
12758
- /* @__PURE__ */ jsx67("div", { className: "flex flex-wrap items-center gap-1.5", children: visibleTag ? /* @__PURE__ */ jsxs47(Fragment14, { children: [
12759
- parents.map((item) => /* @__PURE__ */ jsxs47(
13241
+ /* @__PURE__ */ jsx67("div", { className: "flex flex-wrap items-center gap-1.5", children: visibleTag ? /* @__PURE__ */ jsxs48(Fragment14, { children: [
13242
+ parents.map((item) => /* @__PURE__ */ jsxs48(
12760
13243
  "button",
12761
13244
  {
12762
13245
  type: "button",
@@ -12780,7 +13263,7 @@ function WireframeTagsWidget({
12780
13263
  },
12781
13264
  item.id
12782
13265
  )),
12783
- /* @__PURE__ */ jsxs47(
13266
+ /* @__PURE__ */ jsxs48(
12784
13267
  "button",
12785
13268
  {
12786
13269
  type: "button",
@@ -12803,7 +13286,7 @@ function WireframeTagsWidget({
12803
13286
  }
12804
13287
  ),
12805
13288
  children.map((item) => {
12806
- return /* @__PURE__ */ jsxs47(
13289
+ return /* @__PURE__ */ jsxs48(
12807
13290
  "button",
12808
13291
  {
12809
13292
  type: "button",
@@ -12828,7 +13311,7 @@ function WireframeTagsWidget({
12828
13311
  );
12829
13312
  })
12830
13313
  ] }) : children.length ? children.map((item) => {
12831
- return /* @__PURE__ */ jsxs47(
13314
+ return /* @__PURE__ */ jsxs48(
12832
13315
  "button",
12833
13316
  {
12834
13317
  type: "button",
@@ -12852,8 +13335,8 @@ var wireframe_tags_widget_default = WireframeTagsWidget;
12852
13335
  // src/panels/right/tabs/wireframe.tsx
12853
13336
  import { useOrderFlow, Wrapper } from "@timeax/digital-service-engine/react";
12854
13337
  import { useCanvas as useCanvas16, useWorkspace as useWorkspace13 } from "@timeax/digital-service-engine/workspace";
12855
- import { useCallback as useCallback16, useMemo as useMemo31 } from "react";
12856
- import { jsx as jsx68, jsxs as jsxs48 } from "react/jsx-runtime";
13338
+ import { useCallback as useCallback17, useMemo as useMemo31 } from "react";
13339
+ import { jsx as jsx68, jsxs as jsxs49 } from "react/jsx-runtime";
12857
13340
  var CHECKBOX_SINGLE_EXTRA_PROPS = Object.freeze({ single: true });
12858
13341
  function Wireframe() {
12859
13342
  const canvas = useCanvas16();
@@ -12913,15 +13396,15 @@ function Wireframe() {
12913
13396
  }
12914
13397
  return map;
12915
13398
  }, [canvas.props, canvas.selectionInfo, canvas.activeId]);
12916
- const select = useCallback16(
13399
+ const select = useCallback17(
12917
13400
  (id) => {
12918
13401
  canvas.setActive(id);
12919
13402
  canvas.api.select([id]);
12920
13403
  },
12921
13404
  [canvas.api, canvas.setActive]
12922
13405
  );
12923
- return /* @__PURE__ */ jsxs48("div", { className: "flex h-full min-h-0 flex-col", children: [
12924
- /* @__PURE__ */ jsx68("div", { className: "min-h-0 flex-1 overflow-auto p-4", children: /* @__PURE__ */ jsx68("div", { className: "mx-auto max-w-md", children: /* @__PURE__ */ jsxs48("div", { className: "flex flex-col gap-4", children: [
13406
+ return /* @__PURE__ */ jsxs49("div", { className: "flex h-full min-h-0 flex-col", children: [
13407
+ /* @__PURE__ */ jsx68("div", { className: "min-h-0 flex-1 overflow-auto p-4", children: /* @__PURE__ */ jsx68("div", { className: "mx-auto max-w-md", children: /* @__PURE__ */ jsxs49("div", { className: "flex flex-col gap-4", children: [
12925
13408
  /* @__PURE__ */ jsx68(WorkspaceBootInlineNotice, { boot: ws.boot, sections: ["snapshotBody", "policies"] }),
12926
13409
  /* @__PURE__ */ jsx68(
12927
13410
  wireframe_tags_widget_default,
@@ -13017,7 +13500,7 @@ var wireframe_default = Wireframe;
13017
13500
  // src/panels/right/index.tsx
13018
13501
  import { OrderFlowProvider, useInputs as useInputs3 } from "@timeax/digital-service-engine/react";
13019
13502
  import { useCanvas as useCanvas17 } from "@timeax/digital-service-engine/workspace";
13020
- import { jsx as jsx69, jsxs as jsxs49 } from "react/jsx-runtime";
13503
+ import { jsx as jsx69, jsxs as jsxs50 } from "react/jsx-runtime";
13021
13504
  var RightPanel = ({ onShare, onPlay }) => {
13022
13505
  const tabClassName = cn(
13023
13506
  "m-0! rounded-none! border-t-0! border-r-0! border-b-2! border-l-0! border-transparent! py-2.5! shadow-none!",
@@ -13034,10 +13517,10 @@ var RightPanel = ({ onShare, onPlay }) => {
13034
13517
  maxWidth: 420,
13035
13518
  minWidth: 320,
13036
13519
  className: "flex h-dvh max-h-dvh w-100 flex-col rounded-none! border-l border-slate-200 bg-[linear-gradient(180deg,rgba(255,255,255,0.98),rgba(248,250,252,0.98))] dark:border-slate-800 dark:bg-[linear-gradient(180deg,rgba(2,6,23,0.98),rgba(15,23,42,0.98))]",
13037
- children: /* @__PURE__ */ jsxs49("div", { className: "flex h-full flex-col", children: [
13520
+ children: /* @__PURE__ */ jsxs50("div", { className: "flex h-full flex-col", children: [
13038
13521
  /* @__PURE__ */ jsx69(header_default2, { onShare, onPlay }),
13039
- /* @__PURE__ */ jsxs49(Tabs, { className: "grow gap-0 overflow-hidden", defaultValue: "wireframe", children: [
13040
- /* @__PURE__ */ jsxs49(TabsList, { className: "grid h-fit w-full grid-cols-3 rounded-none! border-b border-slate-200 bg-transparent p-0 dark:border-slate-800", children: [
13522
+ /* @__PURE__ */ jsxs50(Tabs, { className: "grow gap-0 overflow-hidden", defaultValue: "wireframe", children: [
13523
+ /* @__PURE__ */ jsxs50(TabsList, { className: "grid h-fit w-full grid-cols-3 rounded-none! border-b border-slate-200 bg-transparent p-0 dark:border-slate-800", children: [
13041
13524
  /* @__PURE__ */ jsx69(TabsTrigger, { className: tabClassName, value: "comments", children: "Comments" }),
13042
13525
  /* @__PURE__ */ jsx69(TabsTrigger, { className: tabClassName, value: "properties", children: "Properties" }),
13043
13526
  /* @__PURE__ */ jsx69(TabsTrigger, { className: tabClassName, value: "wireframe", children: "Wireframe" })
@@ -13052,168 +13535,13 @@ var RightPanel = ({ onShare, onPlay }) => {
13052
13535
  };
13053
13536
  var right_default = RightPanel;
13054
13537
 
13055
- // src/builder/service-context.ts
13056
- import { createBuilder } from "@timeax/digital-service-engine/core";
13057
- function createDefaultServiceContext(props, preferredTagId) {
13058
- const tagIds = (props?.filters ?? []).map((tag) => tag.id);
13059
- return {
13060
- selectedTagId: preferredTagId && tagIds.includes(preferredTagId) ? preferredTagId : tagIds[0] ?? null,
13061
- selectedButtons: [],
13062
- strictSafety: true,
13063
- enforcePolicies: true
13064
- };
13065
- }
13066
- function sanitizeServiceContext(snapshot, state) {
13067
- const allowed = new Set(snapshot.buttonGroups.flatMap((group) => group.options.map((option) => option.id)));
13068
- const selectedButtons = state.selectedButtons.filter((id) => allowed.has(id));
13069
- if (selectedButtons.length === state.selectedButtons.length) return state;
13070
- return { ...state, selectedButtons };
13071
- }
13072
- function buildServiceContextSnapshot(args) {
13073
- const props = args.props ?? void 0;
13074
- const serviceMap = args.services ?? {};
13075
- const tags = (props?.filters ?? []).map((tag) => ({
13076
- id: tag.id,
13077
- label: tag.label,
13078
- description: describeTag(tag)
13079
- }));
13080
- const selectedTag = (props?.filters ?? []).find((tag) => tag.id === args.state.selectedTagId) ?? null;
13081
- if (!props || !selectedTag) {
13082
- return {
13083
- state: args.state,
13084
- tags,
13085
- selectedTag,
13086
- buttonGroups: [],
13087
- visibleFieldIds: [],
13088
- usedServiceIds: []
13089
- };
13090
- }
13091
- const sandbox = createBuilder({ serviceMap });
13092
- sandbox.load(props);
13093
- const visibleFieldIds = sandbox.visibleFields(selectedTag.id, args.state.selectedButtons);
13094
- const buttonGroups = buildButtonGroups(props.fields ?? [], visibleFieldIds);
13095
- const usedServiceIds = collectUsedServiceIds({
13096
- props,
13097
- tagId: selectedTag.id,
13098
- visibleFieldIds,
13099
- selectedButtons: args.state.selectedButtons
13100
- });
13101
- return {
13102
- state: args.state,
13103
- tags,
13104
- selectedTag,
13105
- buttonGroups,
13106
- visibleFieldIds,
13107
- usedServiceIds
13108
- };
13109
- }
13110
- function buildServiceRowVM(args) {
13111
- const service = args.services?.[args.summary.id] ?? null;
13112
- const check = args.check;
13113
- const searchText = [args.summary.name, args.summary.category, args.summary.platformId, String(args.summary.id)].filter(Boolean).join(" ").toLowerCase();
13114
- const search = args.search?.trim().toLowerCase() ?? "";
13115
- const matchesSearch = !search || searchText.includes(search);
13116
- const isCompatible = !check || servicePassesCurrentFilter(check, args.state);
13117
- const status = describeCheck(check, args.state);
13118
- return {
13119
- id: String(args.summary.id),
13120
- summary: args.summary,
13121
- service,
13122
- check,
13123
- matchesSearch,
13124
- isCompatible,
13125
- passesCurrentFilter: matchesSearch,
13126
- statusTone: status.tone,
13127
- statusLabel: status.label,
13128
- reasonLabels: status.reasons,
13129
- searchText
13130
- };
13131
- }
13132
- function buildButtonGroups(fields, visibleFieldIds) {
13133
- const visibleSet = new Set(visibleFieldIds);
13134
- return fields.filter((field) => visibleSet.has(field.id)).map((field) => {
13135
- const options = field.options?.length ? field.options.filter((option) => option.id).map((option) => ({
13136
- id: String(option.id),
13137
- label: option.label,
13138
- description: `Option in ${field.label}`,
13139
- fieldId: field.id,
13140
- fieldLabel: field.label
13141
- })) : field.button ? [
13142
- {
13143
- id: field.id,
13144
- label: field.label,
13145
- description: "Button field",
13146
- fieldId: field.id,
13147
- fieldLabel: field.label
13148
- }
13149
- ] : [];
13150
- return {
13151
- id: field.id,
13152
- label: field.label,
13153
- options
13154
- };
13155
- }).filter((group) => group.options.length > 0);
13156
- }
13157
- function collectUsedServiceIds(args) {
13158
- const visibleSet = new Set(args.visibleFieldIds);
13159
- const used = /* @__PURE__ */ new Set();
13160
- const tag = args.props.filters?.find((item) => item.id === args.tagId);
13161
- if (tag?.service_id != null) used.add(String(tag.service_id));
13162
- for (const field of args.props.fields ?? []) {
13163
- if (!visibleSet.has(field.id)) continue;
13164
- if (field.service_id != null) {
13165
- used.add(String(field.service_id));
13166
- }
13167
- for (const option of field.options ?? []) {
13168
- if (option.service_id != null) {
13169
- used.add(String(option.service_id));
13170
- }
13171
- }
13172
- }
13173
- return Array.from(used);
13174
- }
13175
- function describeTag(tag) {
13176
- const constraints = Object.entries(tag.constraints ?? {}).filter(([, enabled]) => enabled).map(([key]) => key);
13177
- return constraints.length ? constraints.join(", ") : "All visible services";
13178
- }
13179
- function servicePassesCurrentFilter(check, state) {
13180
- const passesPolicies = state?.enforcePolicies === false ? true : check.passesPolicies;
13181
- const safetyPass = check.fitsConstraints && check.passesRate && passesPolicies;
13182
- return state?.strictSafety === false ? true : safetyPass;
13183
- }
13184
- function describeCheck(check, state) {
13185
- if (!check) {
13186
- return {
13187
- tone: "default",
13188
- label: "No context",
13189
- reasons: []
13190
- };
13191
- }
13192
- const reasons = [
13193
- !check.fitsConstraints ? "Constraint mismatch" : null,
13194
- !check.passesRate ? "Rate policy mismatch" : null,
13195
- state?.enforcePolicies !== false && !check.passesPolicies ? "Policy blocked" : null,
13196
- check.reasons.includes("missing_capability") ? "Missing capability" : null
13197
- ].filter(Boolean);
13198
- if (servicePassesCurrentFilter(check, state) && check.ok) {
13199
- return { tone: "success", label: "Safe fit", reasons };
13200
- }
13201
- if (servicePassesCurrentFilter(check, state)) {
13202
- return { tone: "warning", label: state?.enforcePolicies === false ? "Policy checks relaxed" : "Usable", reasons };
13203
- }
13204
- if (reasons.length) {
13205
- return { tone: "danger", label: "Hidden by context", reasons };
13206
- }
13207
- return { tone: "default", label: "Available", reasons };
13208
- }
13209
-
13210
13538
  // src/workspace/fallback-editor-modal.tsx
13211
13539
  import { useCanvas as useCanvas18, useWorkspace as useWorkspace14 } from "@timeax/digital-service-engine/workspace";
13212
13540
  import cloneDeep2 from "lodash/cloneDeep";
13213
- import { Suspense, lazy, createContext as createContext4, useCallback as useCallback17, useContext as useContext4, useEffect as useEffect18, useMemo as useMemo32, useState as useState31 } from "react";
13541
+ import { Suspense, lazy, createContext as createContext4, useCallback as useCallback18, useContext as useContext4, useEffect as useEffect19, useMemo as useMemo32, useState as useState31 } from "react";
13214
13542
  import { createPortal as createPortal3 } from "react-dom";
13215
13543
  import { FiX as FiX3 } from "react-icons/fi";
13216
- import { jsx as jsx70, jsxs as jsxs50 } from "react/jsx-runtime";
13544
+ import { jsx as jsx70, jsxs as jsxs51 } from "react/jsx-runtime";
13217
13545
  var LazyFallbackEditor = lazy(async () => {
13218
13546
  const mod = await import("@timeax/digital-service-engine/react");
13219
13547
  return { default: mod.FallbackEditor };
@@ -13233,11 +13561,11 @@ function FallbackEditorModalProvider({ children }) {
13233
13561
  const [launch, setLaunch] = useState31(null);
13234
13562
  const [sessionId, setSessionId] = useState31(0);
13235
13563
  const [surfaceError, setSurfaceError] = useState31(null);
13236
- const close = useCallback17(() => {
13564
+ const close = useCallback18(() => {
13237
13565
  setLaunch(null);
13238
13566
  setSurfaceError(null);
13239
13567
  }, []);
13240
- const openForNode = useCallback17((input) => {
13568
+ const openForNode = useCallback18((input) => {
13241
13569
  setSurfaceError(null);
13242
13570
  setSessionId((current) => current + 1);
13243
13571
  setLaunch({
@@ -13248,7 +13576,7 @@ function FallbackEditorModalProvider({ children }) {
13248
13576
  nodeLabel: input.nodeLabel ?? input.nodeId
13249
13577
  });
13250
13578
  }, []);
13251
- const openForService = useCallback17((input) => {
13579
+ const openForService = useCallback18((input) => {
13252
13580
  setSurfaceError(null);
13253
13581
  setSessionId((current) => current + 1);
13254
13582
  setLaunch({
@@ -13257,7 +13585,7 @@ function FallbackEditorModalProvider({ children }) {
13257
13585
  serviceName: input.serviceName
13258
13586
  });
13259
13587
  }, []);
13260
- const persistProps = useCallback17(
13588
+ const persistProps = useCallback18(
13261
13589
  (label, mutate) => {
13262
13590
  const editorAny = canvas.api.editor;
13263
13591
  if (typeof editorAny.transact !== "function" || typeof editorAny.replaceProps !== "function") {
@@ -13271,7 +13599,7 @@ function FallbackEditorModalProvider({ children }) {
13271
13599
  },
13272
13600
  [canvas.api.builder, canvas.api.editor, canvas.props]
13273
13601
  );
13274
- const handleSave = useCallback17(
13602
+ const handleSave = useCallback18(
13275
13603
  async (nextFallbacks) => {
13276
13604
  setSurfaceError(null);
13277
13605
  try {
@@ -13288,7 +13616,7 @@ function FallbackEditorModalProvider({ children }) {
13288
13616
  },
13289
13617
  [close, persistProps]
13290
13618
  );
13291
- const handleSettingsChange = useCallback17(
13619
+ const handleSettingsChange = useCallback18(
13292
13620
  async (nextSettings) => {
13293
13621
  setSurfaceError(null);
13294
13622
  try {
@@ -13323,7 +13651,7 @@ function FallbackEditorModalProvider({ children }) {
13323
13651
  () => canvas.props?.fallbackSettings ?? {},
13324
13652
  [canvas.props]
13325
13653
  );
13326
- useEffect18(() => {
13654
+ useEffect19(() => {
13327
13655
  if (!launch) return;
13328
13656
  const onKeyDown = (event) => {
13329
13657
  if (event.key === "Escape") close();
@@ -13340,7 +13668,7 @@ function FallbackEditorModalProvider({ children }) {
13340
13668
  }),
13341
13669
  [close, launch, openForNode, openForService]
13342
13670
  );
13343
- return /* @__PURE__ */ jsxs50(FallbackEditorModalContext.Provider, { value, children: [
13671
+ return /* @__PURE__ */ jsxs51(FallbackEditorModalContext.Provider, { value, children: [
13344
13672
  children,
13345
13673
  typeof document !== "undefined" && launch ? createPortal3(
13346
13674
  /* @__PURE__ */ jsx70(
@@ -13350,15 +13678,15 @@ function FallbackEditorModalProvider({ children }) {
13350
13678
  onMouseDown: (event) => {
13351
13679
  if (event.target === event.currentTarget) close();
13352
13680
  },
13353
- children: /* @__PURE__ */ jsxs50(
13681
+ children: /* @__PURE__ */ jsxs51(
13354
13682
  "div",
13355
13683
  {
13356
13684
  className: cn(
13357
13685
  "flex h-[min(90vh,56rem)] w-[min(96vw,88rem)] flex-col overflow-hidden rounded-[28px] border border-slate-200 bg-white shadow-2xl dark:border-slate-800 dark:bg-slate-950"
13358
13686
  ),
13359
13687
  children: [
13360
- /* @__PURE__ */ jsxs50("div", { className: "flex items-start justify-between gap-4 border-b border-slate-200 px-6 py-4 dark:border-slate-800", children: [
13361
- /* @__PURE__ */ jsxs50("div", { className: "min-w-0", children: [
13688
+ /* @__PURE__ */ jsxs51("div", { className: "flex items-start justify-between gap-4 border-b border-slate-200 px-6 py-4 dark:border-slate-800", children: [
13689
+ /* @__PURE__ */ jsxs51("div", { className: "min-w-0", children: [
13362
13690
  /* @__PURE__ */ jsx70("h2", { className: "text-lg font-semibold text-slate-900 dark:text-slate-100", children: launchTitle }),
13363
13691
  /* @__PURE__ */ jsx70("p", { className: "mt-1 text-sm text-slate-500 dark:text-slate-400", children: launchDescription })
13364
13692
  ] }),
@@ -13401,7 +13729,7 @@ function useFallbackEditorModal() {
13401
13729
 
13402
13730
  // src/workspace/bottom-panel/index.tsx
13403
13731
  import { useCanvas as useCanvas21, useWorkspace as useWorkspace15 } from "@timeax/digital-service-engine/workspace";
13404
- import { useCallback as useCallback18, useEffect as useEffect21, useMemo as useMemo34, useRef as useRef11, useState as useState34 } from "react";
13732
+ import { useCallback as useCallback19, useEffect as useEffect22, useMemo as useMemo34, useRef as useRef11, useState as useState34 } from "react";
13405
13733
  import { FiEye as FiEye3, FiEyeOff as FiEyeOff2, FiSearch, FiTerminal as FiTerminal2, FiX as FiX5 } from "react-icons/fi";
13406
13734
  import { LuGripHorizontal, LuLayers3 } from "react-icons/lu";
13407
13735
  import { MdOutlineSync } from "react-icons/md";
@@ -13612,7 +13940,7 @@ function toNodeChip(canvas, id) {
13612
13940
  }
13613
13941
 
13614
13942
  // src/workspace/bottom-panel/console-tab.tsx
13615
- import { Fragment as Fragment15, jsx as jsx72, jsxs as jsxs51 } from "react/jsx-runtime";
13943
+ import { Fragment as Fragment15, jsx as jsx72, jsxs as jsxs52 } from "react/jsx-runtime";
13616
13944
  function ConsoleTab({
13617
13945
  errors,
13618
13946
  notices,
@@ -13641,20 +13969,20 @@ function ConsoleTab({
13641
13969
  ];
13642
13970
  const activeIntro = introState[subTab];
13643
13971
  const introCopy = getConsoleIntroCopy(subTab);
13644
- return /* @__PURE__ */ jsxs51("div", { className: "space-y-4", children: [
13645
- !activeIntro.closed ? /* @__PURE__ */ jsx72("div", { className: "rounded-2xl border border-sky-200/80 bg-sky-50/70 p-3 dark:border-sky-500/20 dark:bg-sky-500/10", children: /* @__PURE__ */ jsxs51("div", { className: "flex items-start justify-between gap-3", children: [
13646
- /* @__PURE__ */ jsxs51("div", { className: "min-w-0", children: [
13972
+ return /* @__PURE__ */ jsxs52("div", { className: "space-y-4", children: [
13973
+ !activeIntro.closed ? /* @__PURE__ */ jsx72("div", { className: "rounded-2xl border border-sky-200/80 bg-sky-50/70 p-3 dark:border-sky-500/20 dark:bg-sky-500/10", children: /* @__PURE__ */ jsxs52("div", { className: "flex items-start justify-between gap-3", children: [
13974
+ /* @__PURE__ */ jsxs52("div", { className: "min-w-0", children: [
13647
13975
  /* @__PURE__ */ jsx72("p", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: introCopy.title }),
13648
- !activeIntro.minimized ? /* @__PURE__ */ jsxs51(Fragment15, { children: [
13976
+ !activeIntro.minimized ? /* @__PURE__ */ jsxs52(Fragment15, { children: [
13649
13977
  /* @__PURE__ */ jsx72("p", { className: "mt-1 text-xs text-slate-600 dark:text-slate-300", children: introCopy.description }),
13650
- /* @__PURE__ */ jsxs51("div", { className: "mt-2 flex flex-wrap items-center gap-2 text-[11px] text-slate-500 dark:text-slate-400", children: [
13978
+ /* @__PURE__ */ jsxs52("div", { className: "mt-2 flex flex-wrap items-center gap-2 text-[11px] text-slate-500 dark:text-slate-400", children: [
13651
13979
  /* @__PURE__ */ jsx72("span", { className: "rounded-full bg-white/80 px-2 py-0.5 dark:bg-slate-900/70", children: validating ? "Validating..." : "Console idle" }),
13652
13980
  /* @__PURE__ */ jsx72("span", { className: "rounded-full bg-white/80 px-2 py-0.5 dark:bg-slate-900/70", children: shortcutLabel }),
13653
13981
  /* @__PURE__ */ jsx72("span", { className: "rounded-full bg-white/80 px-2 py-0.5 dark:bg-slate-900/70", children: "Press Escape to close" })
13654
13982
  ] })
13655
13983
  ] }) : null
13656
13984
  ] }),
13657
- /* @__PURE__ */ jsxs51("div", { className: "flex items-center gap-2 text-xs", children: [
13985
+ /* @__PURE__ */ jsxs52("div", { className: "flex items-center gap-2 text-xs", children: [
13658
13986
  /* @__PURE__ */ jsx72(
13659
13987
  "button",
13660
13988
  {
@@ -13675,9 +14003,9 @@ function ConsoleTab({
13675
14003
  )
13676
14004
  ] })
13677
14005
  ] }) }) : null,
13678
- /* @__PURE__ */ jsxs51("div", { className: "rounded-2xl border border-slate-200 bg-white/70 p-3 dark:border-slate-800 dark:bg-slate-950/40", children: [
13679
- /* @__PURE__ */ jsxs51("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
13680
- /* @__PURE__ */ jsx72("div", { className: "flex flex-wrap items-center gap-2", children: subTabs.map((tab) => /* @__PURE__ */ jsxs51(
14006
+ /* @__PURE__ */ jsxs52("div", { className: "rounded-2xl border border-slate-200 bg-white/70 p-3 dark:border-slate-800 dark:bg-slate-950/40", children: [
14007
+ /* @__PURE__ */ jsxs52("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
14008
+ /* @__PURE__ */ jsx72("div", { className: "flex flex-wrap items-center gap-2", children: subTabs.map((tab) => /* @__PURE__ */ jsxs52(
13681
14009
  "button",
13682
14010
  {
13683
14011
  type: "button",
@@ -13693,12 +14021,12 @@ function ConsoleTab({
13693
14021
  },
13694
14022
  tab.id
13695
14023
  )) }),
13696
- subTab === "logs" && logRows.length ? /* @__PURE__ */ jsxs51(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => errors.clear("logs"), className: "h-8 rounded-xl px-3 text-xs", children: [
14024
+ subTab === "logs" && logRows.length ? /* @__PURE__ */ jsxs52(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => errors.clear("logs"), className: "h-8 rounded-xl px-3 text-xs", children: [
13697
14025
  /* @__PURE__ */ jsx72(FiTrash2, {}),
13698
14026
  "Clear logs"
13699
14027
  ] }) : null
13700
14028
  ] }),
13701
- /* @__PURE__ */ jsxs51("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [
14029
+ /* @__PURE__ */ jsxs52("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [
13702
14030
  /* @__PURE__ */ jsx72("span", { className: "text-[11px] font-semibold tracking-[0.16em] text-slate-500 uppercase dark:text-slate-400", children: "Scope" }),
13703
14031
  /* @__PURE__ */ jsx72(
13704
14032
  "button",
@@ -13724,7 +14052,7 @@ function ConsoleTab({
13724
14052
  children: "Active node"
13725
14053
  }
13726
14054
  ),
13727
- subTab !== "logs" ? /* @__PURE__ */ jsxs51(Fragment15, { children: [
14055
+ subTab !== "logs" ? /* @__PURE__ */ jsxs52(Fragment15, { children: [
13728
14056
  /* @__PURE__ */ jsx72("span", { className: "ml-2 text-[11px] font-semibold tracking-[0.16em] text-slate-500 uppercase dark:text-slate-400", children: "Severity" }),
13729
14057
  ["all", "error", "warning", "info"].map((option) => /* @__PURE__ */ jsx72(
13730
14058
  "button",
@@ -13770,20 +14098,20 @@ function NoticeCard({ notice, onNodeClick }) {
13770
14098
  const canvas = useCanvas20();
13771
14099
  const targetNodeId = notice.target.scope === "node" ? notice.target.node_id : null;
13772
14100
  const targetChip = notice.target.scope === "node" ? toNodeChip(canvas, notice.target.node_id) : "Global notice";
13773
- return /* @__PURE__ */ jsx72("div", { className: "rounded-2xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-950/90", children: /* @__PURE__ */ jsxs51("div", { className: "flex items-start gap-3", children: [
14101
+ return /* @__PURE__ */ jsx72("div", { className: "rounded-2xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-950/90", children: /* @__PURE__ */ jsxs52("div", { className: "flex items-start gap-3", children: [
13774
14102
  /* @__PURE__ */ jsx72("div", { className: "mt-0.5", children: iconForSeverity(notice.severity) }),
13775
- /* @__PURE__ */ jsxs51("div", { className: "min-w-0 flex-1 space-y-2", children: [
13776
- /* @__PURE__ */ jsxs51("div", { className: "flex flex-wrap items-center gap-2", children: [
14103
+ /* @__PURE__ */ jsxs52("div", { className: "min-w-0 flex-1 space-y-2", children: [
14104
+ /* @__PURE__ */ jsxs52("div", { className: "flex flex-wrap items-center gap-2", children: [
13777
14105
  /* @__PURE__ */ jsx72("span", { className: severityBadgeClassName(notice.severity), children: notice.kind }),
13778
14106
  /* @__PURE__ */ jsx72("span", { className: "rounded-full bg-slate-100 px-2.5 py-1 text-[10px] font-semibold tracking-[0.16em] text-slate-600 uppercase dark:bg-slate-900 dark:text-slate-300", children: notice.type }),
13779
14107
  /* @__PURE__ */ jsx72("span", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: notice.title })
13780
14108
  ] }),
13781
14109
  notice.description ? /* @__PURE__ */ jsx72("p", { className: "text-sm text-slate-600 dark:text-slate-300", children: notice.description }) : null,
13782
- notice.reason ? /* @__PURE__ */ jsxs51("p", { className: "text-xs text-slate-500 dark:text-slate-400", children: [
14110
+ notice.reason ? /* @__PURE__ */ jsxs52("p", { className: "text-xs text-slate-500 dark:text-slate-400", children: [
13783
14111
  "Reason: ",
13784
14112
  notice.reason
13785
14113
  ] }) : null,
13786
- /* @__PURE__ */ jsxs51("div", { className: "flex flex-wrap items-center gap-2 text-xs text-slate-500 dark:text-slate-400", children: [
14114
+ /* @__PURE__ */ jsxs52("div", { className: "flex flex-wrap items-center gap-2 text-xs text-slate-500 dark:text-slate-400", children: [
13787
14115
  notice.target.scope === "node" ? /* @__PURE__ */ jsx72(
13788
14116
  "button",
13789
14117
  {
@@ -13794,11 +14122,11 @@ function NoticeCard({ notice, onNodeClick }) {
13794
14122
  }
13795
14123
  ) : /* @__PURE__ */ jsx72("span", { className: "rounded-full bg-slate-100 px-2.5 py-1 text-xs text-slate-700 dark:bg-slate-900 dark:text-slate-300", children: targetChip }),
13796
14124
  notice.marked_at ? /* @__PURE__ */ jsx72("span", { children: new Date(notice.marked_at).toLocaleString() }) : null,
13797
- notice.icon ? /* @__PURE__ */ jsxs51("span", { children: [
14125
+ notice.icon ? /* @__PURE__ */ jsxs52("span", { children: [
13798
14126
  "Icon: ",
13799
14127
  notice.icon
13800
14128
  ] }) : null,
13801
- notice.color ? /* @__PURE__ */ jsxs51("span", { children: [
14129
+ notice.color ? /* @__PURE__ */ jsxs52("span", { children: [
13802
14130
  "Color: ",
13803
14131
  notice.color
13804
14132
  ] }) : null
@@ -13814,10 +14142,10 @@ function ValidationCard({ row, onNodeClick }) {
13814
14142
  {
13815
14143
  className: "rounded-2xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-950/90",
13816
14144
  onClick: () => scope.length && canvas.api.setHighlighted(scope),
13817
- children: /* @__PURE__ */ jsxs51("div", { className: "flex items-start gap-3", children: [
14145
+ children: /* @__PURE__ */ jsxs52("div", { className: "flex items-start gap-3", children: [
13818
14146
  /* @__PURE__ */ jsx72("div", { className: "mt-0.5", children: iconForSeverity(row.severity) }),
13819
- /* @__PURE__ */ jsxs51("div", { className: "min-w-0 flex-1", children: [
13820
- /* @__PURE__ */ jsxs51("div", { className: "flex flex-wrap items-center gap-2", children: [
14147
+ /* @__PURE__ */ jsxs52("div", { className: "min-w-0 flex-1", children: [
14148
+ /* @__PURE__ */ jsxs52("div", { className: "flex flex-wrap items-center gap-2", children: [
13821
14149
  /* @__PURE__ */ jsx72("span", { className: severityBadgeClassName(row.severity), children: row.code.replaceAll("_", " ") }),
13822
14150
  /* @__PURE__ */ jsx72("span", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: row.message })
13823
14151
  ] }),
@@ -13836,16 +14164,16 @@ function ValidationCard({ row, onNodeClick }) {
13836
14164
  );
13837
14165
  }
13838
14166
  function LogCard({ row, onRemove }) {
13839
- return /* @__PURE__ */ jsx72("div", { className: "rounded-2xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-950/90", children: /* @__PURE__ */ jsxs51("div", { className: "flex items-start gap-3", children: [
14167
+ return /* @__PURE__ */ jsx72("div", { className: "rounded-2xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-950/90", children: /* @__PURE__ */ jsxs52("div", { className: "flex items-start gap-3", children: [
13840
14168
  /* @__PURE__ */ jsx72("div", { className: "mt-0.5", children: /* @__PURE__ */ jsx72(FiInfo2, { className: "text-lg text-sky-500" }) }),
13841
- /* @__PURE__ */ jsxs51("div", { className: "min-w-0 flex-1", children: [
13842
- /* @__PURE__ */ jsxs51("div", { className: "flex flex-wrap items-center gap-2", children: [
14169
+ /* @__PURE__ */ jsxs52("div", { className: "min-w-0 flex-1", children: [
14170
+ /* @__PURE__ */ jsxs52("div", { className: "flex flex-wrap items-center gap-2", children: [
13843
14171
  /* @__PURE__ */ jsx72("span", { className: "rounded-full bg-sky-100 px-2.5 py-1 text-[10px] font-semibold tracking-[0.16em] text-sky-700 uppercase dark:bg-sky-500/15 dark:text-sky-200", children: row.code ?? "log" }),
13844
14172
  /* @__PURE__ */ jsx72("span", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: row.message })
13845
14173
  ] }),
13846
- /* @__PURE__ */ jsxs51("div", { className: "mt-3 flex items-center justify-between gap-3 text-xs text-slate-500 dark:text-slate-400", children: [
14174
+ /* @__PURE__ */ jsxs52("div", { className: "mt-3 flex items-center justify-between gap-3 text-xs text-slate-500 dark:text-slate-400", children: [
13847
14175
  /* @__PURE__ */ jsx72("span", { children: new Date(row.createdAt).toLocaleTimeString() }),
13848
- /* @__PURE__ */ jsxs51(Button, { type: "button", variant: "ghost", size: "sm", onClick: onRemove, className: "h-7 rounded-xl px-2 text-xs", children: [
14176
+ /* @__PURE__ */ jsxs52(Button, { type: "button", variant: "ghost", size: "sm", onClick: onRemove, className: "h-7 rounded-xl px-2 text-xs", children: [
13849
14177
  /* @__PURE__ */ jsx72(FiX4, {}),
13850
14178
  "Dismiss"
13851
14179
  ] })
@@ -13856,7 +14184,7 @@ function LogCard({ row, onRemove }) {
13856
14184
 
13857
14185
  // src/workspace/bottom-panel/service-picker-dialog.tsx
13858
14186
  import { InputField as InputField16 } from "@timeax/form-palette";
13859
- import { useEffect as useEffect19, useMemo as useMemo33, useState as useState32 } from "react";
14187
+ import { useEffect as useEffect20, useMemo as useMemo33, useState as useState32 } from "react";
13860
14188
  import { createPortal as createPortal4 } from "react-dom";
13861
14189
 
13862
14190
  // src/workspace/bottom-panel/service-picker.ts
@@ -13974,7 +14302,7 @@ function isScalar(value) {
13974
14302
  }
13975
14303
 
13976
14304
  // src/workspace/bottom-panel/service-picker-dialog.tsx
13977
- import { jsx as jsx73, jsxs as jsxs52 } from "react/jsx-runtime";
14305
+ import { jsx as jsx73, jsxs as jsxs53 } from "react/jsx-runtime";
13978
14306
  function ServicePickerDialog({
13979
14307
  open,
13980
14308
  groupLabel,
@@ -13987,12 +14315,12 @@ function ServicePickerDialog({
13987
14315
  }) {
13988
14316
  const [filters, setFilters] = useState32(() => createDefaultServicePickerFilters());
13989
14317
  const [selectedIds, setSelectedIds] = useState32(/* @__PURE__ */ new Set());
13990
- useEffect19(() => {
14318
+ useEffect20(() => {
13991
14319
  if (!open) return;
13992
14320
  setFilters(createDefaultServicePickerFilters());
13993
14321
  setSelectedIds(/* @__PURE__ */ new Set());
13994
14322
  }, [open]);
13995
- useEffect19(() => {
14323
+ useEffect20(() => {
13996
14324
  if (!open) return;
13997
14325
  const onKeyDown = (event) => {
13998
14326
  if (event.key === "Escape") onOpenChange(false);
@@ -14020,7 +14348,7 @@ function ServicePickerDialog({
14020
14348
  const selectedCount = selectedIds.size;
14021
14349
  const canConfirm = selectedCount > 0;
14022
14350
  return createPortal4(
14023
- /* @__PURE__ */ jsx73("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-slate-950/45 p-4", children: /* @__PURE__ */ jsxs52(
14351
+ /* @__PURE__ */ jsx73("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-slate-950/45 p-4", children: /* @__PURE__ */ jsxs53(
14024
14352
  "div",
14025
14353
  {
14026
14354
  role: "dialog",
@@ -14028,15 +14356,15 @@ function ServicePickerDialog({
14028
14356
  "aria-label": "Service picker",
14029
14357
  className: "flex h-[min(80vh,42rem)] w-[min(72rem,calc(100vw-2rem))] flex-col overflow-hidden rounded-3xl border border-slate-200 bg-white shadow-2xl dark:border-slate-800 dark:bg-slate-950",
14030
14358
  children: [
14031
- /* @__PURE__ */ jsx73("div", { className: "border-b border-slate-200 px-5 py-4 dark:border-slate-800", children: /* @__PURE__ */ jsxs52("div", { className: "flex items-start justify-between gap-4", children: [
14032
- /* @__PURE__ */ jsxs52("div", { children: [
14359
+ /* @__PURE__ */ jsx73("div", { className: "border-b border-slate-200 px-5 py-4 dark:border-slate-800", children: /* @__PURE__ */ jsxs53("div", { className: "flex items-start justify-between gap-4", children: [
14360
+ /* @__PURE__ */ jsxs53("div", { children: [
14033
14361
  /* @__PURE__ */ jsx73("h3", { className: "text-lg font-semibold text-slate-900 dark:text-slate-100", children: "Assign services to group" }),
14034
14362
  /* @__PURE__ */ jsx73("p", { className: "mt-1 text-sm text-slate-500 dark:text-slate-400", children: groupLabel ? `Pick one or more services to append into ${groupLabel}.` : "Pick one or more services to append into the selected catalog group." })
14035
14363
  ] }),
14036
14364
  /* @__PURE__ */ jsx73(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => onOpenChange(false), className: "rounded-xl", children: "Close" })
14037
14365
  ] }) }),
14038
- /* @__PURE__ */ jsxs52("div", { className: "grid h-full min-h-0 flex-1 overflow-hidden md:grid-cols-[18rem_minmax(0,1fr)]", children: [
14039
- /* @__PURE__ */ jsx73("div", { className: "min-h-0 border-r border-slate-200 dark:border-slate-800", children: /* @__PURE__ */ jsx73(ScrollArea, { className: "h-full min-h-0", children: /* @__PURE__ */ jsxs52("div", { className: "space-y-4 p-4", children: [
14366
+ /* @__PURE__ */ jsxs53("div", { className: "grid h-full min-h-0 flex-1 overflow-hidden md:grid-cols-[18rem_minmax(0,1fr)]", children: [
14367
+ /* @__PURE__ */ jsx73("div", { className: "min-h-0 border-r border-slate-200 dark:border-slate-800", children: /* @__PURE__ */ jsx73(ScrollArea, { className: "h-full min-h-0", children: /* @__PURE__ */ jsxs53("div", { className: "space-y-4 p-4", children: [
14040
14368
  /* @__PURE__ */ jsx73(FilterField, { label: "Search", children: /* @__PURE__ */ jsx73(
14041
14369
  InputField16,
14042
14370
  {
@@ -14087,7 +14415,7 @@ function ServicePickerDialog({
14087
14415
  }))
14088
14416
  }
14089
14417
  ) }),
14090
- /* @__PURE__ */ jsxs52("div", { className: "grid grid-cols-2 gap-2", children: [
14418
+ /* @__PURE__ */ jsxs53("div", { className: "grid grid-cols-2 gap-2", children: [
14091
14419
  /* @__PURE__ */ jsx73(FilterField, { label: "Min rate", children: /* @__PURE__ */ jsx73(
14092
14420
  InputField16,
14093
14421
  {
@@ -14111,7 +14439,7 @@ function ServicePickerDialog({
14111
14439
  }
14112
14440
  ) })
14113
14441
  ] }),
14114
- /* @__PURE__ */ jsx73(FilterField, { label: "Name keyword", children: /* @__PURE__ */ jsxs52("div", { className: "space-y-2", children: [
14442
+ /* @__PURE__ */ jsx73(FilterField, { label: "Name keyword", children: /* @__PURE__ */ jsxs53("div", { className: "space-y-2", children: [
14115
14443
  /* @__PURE__ */ jsx73(
14116
14444
  InputField16,
14117
14445
  {
@@ -14182,8 +14510,8 @@ function ServicePickerDialog({
14182
14510
  }
14183
14511
  ) })
14184
14512
  ] }) }) }),
14185
- /* @__PURE__ */ jsxs52("div", { className: "flex min-h-0 flex-col overflow-hidden", children: [
14186
- /* @__PURE__ */ jsxs52("div", { className: "border-b border-slate-200 px-4 py-3 text-sm text-slate-500 dark:border-slate-800 dark:text-slate-400", children: [
14513
+ /* @__PURE__ */ jsxs53("div", { className: "flex min-h-0 flex-col overflow-hidden", children: [
14514
+ /* @__PURE__ */ jsxs53("div", { className: "border-b border-slate-200 px-4 py-3 text-sm text-slate-500 dark:border-slate-800 dark:text-slate-400", children: [
14187
14515
  filteredServices.length,
14188
14516
  " service",
14189
14517
  filteredServices.length === 1 ? "" : "s",
@@ -14193,7 +14521,7 @@ function ServicePickerDialog({
14193
14521
  const id = String(service.id);
14194
14522
  const selected = selectedIds.has(id);
14195
14523
  const alreadyAssigned = existingGroupServiceIds.has(id);
14196
- return /* @__PURE__ */ jsxs52(
14524
+ return /* @__PURE__ */ jsxs53(
14197
14525
  "label",
14198
14526
  {
14199
14527
  className: cn(
@@ -14215,12 +14543,12 @@ function ServicePickerDialog({
14215
14543
  })
14216
14544
  }
14217
14545
  ),
14218
- /* @__PURE__ */ jsxs52("div", { className: "min-w-0 flex-1", children: [
14219
- /* @__PURE__ */ jsxs52("div", { className: "flex items-center justify-between gap-3", children: [
14220
- /* @__PURE__ */ jsxs52("div", { className: "min-w-0", children: [
14546
+ /* @__PURE__ */ jsxs53("div", { className: "min-w-0 flex-1", children: [
14547
+ /* @__PURE__ */ jsxs53("div", { className: "flex items-center justify-between gap-3", children: [
14548
+ /* @__PURE__ */ jsxs53("div", { className: "min-w-0", children: [
14221
14549
  /* @__PURE__ */ jsx73("div", { className: "truncate text-sm font-semibold text-slate-900 dark:text-slate-100", children: service.name }),
14222
- /* @__PURE__ */ jsxs52("div", { className: "mt-1 flex flex-wrap gap-2 text-xs text-slate-500 dark:text-slate-400", children: [
14223
- /* @__PURE__ */ jsxs52("span", { children: [
14550
+ /* @__PURE__ */ jsxs53("div", { className: "mt-1 flex flex-wrap gap-2 text-xs text-slate-500 dark:text-slate-400", children: [
14551
+ /* @__PURE__ */ jsxs53("span", { children: [
14224
14552
  "#",
14225
14553
  service.id
14226
14554
  ] }),
@@ -14230,8 +14558,8 @@ function ServicePickerDialog({
14230
14558
  ] }),
14231
14559
  alreadyAssigned ? /* @__PURE__ */ jsx73("span", { className: "rounded-full bg-emerald-50 px-2.5 py-1 text-[11px] text-emerald-700 dark:bg-emerald-500/10 dark:text-emerald-200", children: "Already in group" }) : null
14232
14560
  ] }),
14233
- /* @__PURE__ */ jsxs52("div", { className: "mt-3 flex flex-wrap gap-2", children: [
14234
- service.rate != null ? /* @__PURE__ */ jsxs52("span", { className: "rounded-full bg-slate-100 px-2.5 py-1 text-[11px] text-slate-600 dark:bg-slate-900 dark:text-slate-300", children: [
14561
+ /* @__PURE__ */ jsxs53("div", { className: "mt-3 flex flex-wrap gap-2", children: [
14562
+ service.rate != null ? /* @__PURE__ */ jsxs53("span", { className: "rounded-full bg-slate-100 px-2.5 py-1 text-[11px] text-slate-600 dark:bg-slate-900 dark:text-slate-300", children: [
14235
14563
  "Rate ",
14236
14564
  service.rate
14237
14565
  ] }) : null,
@@ -14245,14 +14573,14 @@ function ServicePickerDialog({
14245
14573
  }) : /* @__PURE__ */ jsx73("div", { className: "rounded-2xl border border-dashed border-slate-300 px-4 py-10 text-center text-sm text-slate-500 dark:border-slate-700 dark:text-slate-400", children: "No services match the current filters." }) }) })
14246
14574
  ] })
14247
14575
  ] }),
14248
- /* @__PURE__ */ jsxs52("div", { className: "flex items-center justify-between gap-3 border-t border-slate-200 px-5 py-4 dark:border-slate-800", children: [
14249
- /* @__PURE__ */ jsxs52("div", { className: "text-sm text-slate-500 dark:text-slate-400", children: [
14576
+ /* @__PURE__ */ jsxs53("div", { className: "flex items-center justify-between gap-3 border-t border-slate-200 px-5 py-4 dark:border-slate-800", children: [
14577
+ /* @__PURE__ */ jsxs53("div", { className: "text-sm text-slate-500 dark:text-slate-400", children: [
14250
14578
  selectedCount,
14251
14579
  " service",
14252
14580
  selectedCount === 1 ? "" : "s",
14253
14581
  " selected"
14254
14582
  ] }),
14255
- /* @__PURE__ */ jsxs52("div", { className: "flex items-center gap-2", children: [
14583
+ /* @__PURE__ */ jsxs53("div", { className: "flex items-center gap-2", children: [
14256
14584
  /* @__PURE__ */ jsx73(Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), className: "rounded-xl", children: "Cancel" }),
14257
14585
  /* @__PURE__ */ jsx73(
14258
14586
  Button,
@@ -14276,7 +14604,7 @@ function ServicePickerDialog({
14276
14604
  );
14277
14605
  }
14278
14606
  function FilterField({ label, children }) {
14279
- return /* @__PURE__ */ jsxs52("label", { className: "block space-y-1.5", children: [
14607
+ return /* @__PURE__ */ jsxs53("label", { className: "block space-y-1.5", children: [
14280
14608
  /* @__PURE__ */ jsx73("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500 dark:text-slate-400", children: label }),
14281
14609
  children
14282
14610
  ] });
@@ -14327,12 +14655,12 @@ function ResizableHandle({
14327
14655
 
14328
14656
  // src/workspace/bottom-panel/services-split-pane.tsx
14329
14657
  import { InputField as InputField17 } from "@timeax/form-palette";
14330
- import { useEffect as useEffect20, useState as useState33 } from "react";
14331
- import { FaFolderOpen } from "react-icons/fa";
14332
- import { FiEdit2, FiFilter, FiFolderPlus, FiPlus as FiPlus2, FiTrash2 as FiTrash22 } from "react-icons/fi";
14658
+ import { useEffect as useEffect21, useState as useState33 } from "react";
14659
+ import { FaFolderOpen as FaFolderOpen2 } from "react-icons/fa";
14660
+ import { FiEdit2, FiFilter as FiFilter2, FiFolderPlus, FiPlus as FiPlus2, FiTrash2 as FiTrash22 } from "react-icons/fi";
14333
14661
 
14334
14662
  // src/workspace/bottom-panel/service-detail-card.tsx
14335
- import { jsx as jsx75, jsxs as jsxs53 } from "react/jsx-runtime";
14663
+ import { jsx as jsx75, jsxs as jsxs54 } from "react/jsx-runtime";
14336
14664
  function ServiceDetailCard({
14337
14665
  mode,
14338
14666
  row,
@@ -14343,16 +14671,16 @@ function ServiceDetailCard({
14343
14671
  }) {
14344
14672
  const summary = row.summary;
14345
14673
  const service = row.service;
14346
- return /* @__PURE__ */ jsxs53("div", { className: "space-y-5", children: [
14347
- /* @__PURE__ */ jsxs53("div", { className: "rounded-3xl border border-slate-200 bg-slate-50/80 p-5 dark:border-slate-800 dark:bg-slate-900/40", children: [
14348
- /* @__PURE__ */ jsxs53("div", { className: "flex flex-wrap items-start justify-between gap-4", children: [
14349
- /* @__PURE__ */ jsxs53("div", { className: "min-w-0", children: [
14350
- /* @__PURE__ */ jsxs53("div", { className: "flex items-center gap-2", children: [
14674
+ return /* @__PURE__ */ jsxs54("div", { className: "space-y-5", children: [
14675
+ /* @__PURE__ */ jsxs54("div", { className: "rounded-3xl border border-slate-200 bg-slate-50/80 p-5 dark:border-slate-800 dark:bg-slate-900/40", children: [
14676
+ /* @__PURE__ */ jsxs54("div", { className: "flex flex-wrap items-start justify-between gap-4", children: [
14677
+ /* @__PURE__ */ jsxs54("div", { className: "min-w-0", children: [
14678
+ /* @__PURE__ */ jsxs54("div", { className: "flex items-center gap-2", children: [
14351
14679
  /* @__PURE__ */ jsx75(StatusDot, { tone: row.statusTone, className: "mt-0.5" }),
14352
14680
  /* @__PURE__ */ jsx75("h5", { className: "truncate text-lg font-semibold text-slate-900 dark:text-slate-100", children: summary.name })
14353
14681
  ] }),
14354
- /* @__PURE__ */ jsxs53("div", { className: "mt-2 flex flex-wrap gap-2 text-xs text-slate-500 dark:text-slate-400", children: [
14355
- /* @__PURE__ */ jsxs53("span", { children: [
14682
+ /* @__PURE__ */ jsxs54("div", { className: "mt-2 flex flex-wrap gap-2 text-xs text-slate-500 dark:text-slate-400", children: [
14683
+ /* @__PURE__ */ jsxs54("span", { children: [
14356
14684
  "#",
14357
14685
  summary.id
14358
14686
  ] }),
@@ -14360,7 +14688,7 @@ function ServiceDetailCard({
14360
14688
  summary.platformId ? /* @__PURE__ */ jsx75("span", { children: summary.platformId }) : null
14361
14689
  ] })
14362
14690
  ] }),
14363
- /* @__PURE__ */ jsxs53("div", { className: "flex items-center gap-2", children: [
14691
+ /* @__PURE__ */ jsxs54("div", { className: "flex items-center gap-2", children: [
14364
14692
  mode === "active" && onOpenFallbackQuickAdd ? /* @__PURE__ */ jsx75(
14365
14693
  "button",
14366
14694
  {
@@ -14382,14 +14710,14 @@ function ServiceDetailCard({
14382
14710
  /* @__PURE__ */ jsx75("span", { className: statusBadgeClassName(row.statusTone), children: row.statusLabel })
14383
14711
  ] })
14384
14712
  ] }),
14385
- /* @__PURE__ */ jsxs53("div", { className: "mt-4 grid gap-3 sm:grid-cols-2", children: [
14713
+ /* @__PURE__ */ jsxs54("div", { className: "mt-4 grid gap-3 sm:grid-cols-2", children: [
14386
14714
  /* @__PURE__ */ jsx75(DetailMetric, { label: "Rate", value: summary.rate != null ? String(summary.rate) : "Not set" }),
14387
14715
  /* @__PURE__ */ jsx75(DetailMetric, { label: "Estimate", value: summary.estimate ?? "No estimate" }),
14388
14716
  /* @__PURE__ */ jsx75(DetailMetric, { label: "Min", value: summary.min != null ? String(summary.min) : "0" }),
14389
14717
  /* @__PURE__ */ jsx75(DetailMetric, { label: "Max", value: summary.max != null ? String(summary.max) : "Unlimited" })
14390
14718
  ] })
14391
14719
  ] }),
14392
- mode !== "active" ? /* @__PURE__ */ jsxs53("section", { className: "space-y-3", children: [
14720
+ mode !== "active" ? /* @__PURE__ */ jsxs54("section", { className: "space-y-3", children: [
14393
14721
  /* @__PURE__ */ jsx75(
14394
14722
  SectionTitle2,
14395
14723
  {
@@ -14397,8 +14725,8 @@ function ServiceDetailCard({
14397
14725
  description: mode === "catalog" ? "This summary shows how the service fits the current visible-group context while browsing catalog groups." : "This summary shows how the service fits the current visible-group context."
14398
14726
  }
14399
14727
  ),
14400
- /* @__PURE__ */ jsxs53("div", { className: "rounded-2xl border border-slate-200 bg-white p-4 dark:border-slate-800 dark:bg-slate-950/80", children: [
14401
- /* @__PURE__ */ jsxs53("div", { className: "flex flex-wrap gap-2", children: [
14728
+ /* @__PURE__ */ jsxs54("div", { className: "rounded-2xl border border-slate-200 bg-white p-4 dark:border-slate-800 dark:bg-slate-950/80", children: [
14729
+ /* @__PURE__ */ jsxs54("div", { className: "flex flex-wrap gap-2", children: [
14402
14730
  /* @__PURE__ */ jsx75(FilterChip, { label: row.check?.fitsConstraints ? "Constraints fit" : "Constraint mismatch", tone: row.check?.fitsConstraints ? "success" : "danger" }),
14403
14731
  /* @__PURE__ */ jsx75(FilterChip, { label: row.check?.passesRate ? "Rate ok" : "Rate blocked", tone: row.check?.passesRate ? "success" : "warning" }),
14404
14732
  /* @__PURE__ */ jsx75(
@@ -14412,14 +14740,14 @@ function ServiceDetailCard({
14412
14740
  row.reasonLabels.length ? /* @__PURE__ */ jsx75("div", { className: "mt-3 flex flex-wrap gap-2", children: row.reasonLabels.map((reason) => /* @__PURE__ */ jsx75("span", { className: "rounded-full bg-amber-50 px-2.5 py-1 text-xs text-amber-700 dark:bg-amber-500/10 dark:text-amber-200", children: reason }, `${row.id}:${reason}`)) }) : /* @__PURE__ */ jsx75("p", { className: "mt-3 text-sm text-slate-500 dark:text-slate-400", children: "This service is a clean fit for the current visible-group and selected-trigger context." })
14413
14741
  ] })
14414
14742
  ] }) : null,
14415
- /* @__PURE__ */ jsxs53("section", { className: "space-y-3", children: [
14743
+ /* @__PURE__ */ jsxs54("section", { className: "space-y-3", children: [
14416
14744
  /* @__PURE__ */ jsx75(SectionTitle2, { title: "Capabilities", description: "Flags and pricing hints attached to this service." }),
14417
- /* @__PURE__ */ jsx75("div", { className: "rounded-2xl border border-slate-200 bg-white p-4 dark:border-slate-800 dark:bg-slate-950/80", children: summary.flags.length || service?.meta ? /* @__PURE__ */ jsxs53("div", { className: "flex flex-wrap gap-2", children: [
14745
+ /* @__PURE__ */ jsx75("div", { className: "rounded-2xl border border-slate-200 bg-white p-4 dark:border-slate-800 dark:bg-slate-950/80", children: summary.flags.length || service?.meta ? /* @__PURE__ */ jsxs54("div", { className: "flex flex-wrap gap-2", children: [
14418
14746
  summary.flags.map((flag) => /* @__PURE__ */ jsx75("span", { className: "rounded-full bg-emerald-50 px-2.5 py-1 text-xs text-emerald-700 dark:bg-emerald-500/10 dark:text-emerald-200", children: flag }, flag)),
14419
14747
  Object.keys(service?.meta ?? {}).slice(0, 3).map((key) => /* @__PURE__ */ jsx75("span", { className: "rounded-full bg-slate-100 px-2.5 py-1 text-xs text-slate-600 dark:bg-slate-900 dark:text-slate-300", children: key }, key))
14420
14748
  ] }) : /* @__PURE__ */ jsx75("p", { className: "text-sm text-slate-500 dark:text-slate-400", children: "No capability flags were published for this service." }) })
14421
14749
  ] }),
14422
- /* @__PURE__ */ jsxs53("section", { className: "space-y-3", children: [
14750
+ /* @__PURE__ */ jsxs54("section", { className: "space-y-3", children: [
14423
14751
  /* @__PURE__ */ jsx75(SectionTitle2, { title: "Bindings", description: "Nodes currently connected to this service. Click any node to jump back into the canvas." }),
14424
14752
  /* @__PURE__ */ jsx75("div", { className: "rounded-2xl border border-slate-200 bg-white p-4 dark:border-slate-800 dark:bg-slate-950/80", children: summary.attachedNodeIds.length ? /* @__PURE__ */ jsx75("div", { className: "flex flex-wrap gap-2", children: summary.attachedNodeIds.map((nodeId, index) => /* @__PURE__ */ jsx75(
14425
14753
  "button",
@@ -14435,13 +14763,13 @@ function ServiceDetailCard({
14435
14763
  ] });
14436
14764
  }
14437
14765
  function SectionTitle2({ title, description }) {
14438
- return /* @__PURE__ */ jsxs53("div", { children: [
14766
+ return /* @__PURE__ */ jsxs54("div", { children: [
14439
14767
  /* @__PURE__ */ jsx75("p", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: title }),
14440
14768
  /* @__PURE__ */ jsx75("p", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: description })
14441
14769
  ] });
14442
14770
  }
14443
14771
  function DetailMetric({ label, value }) {
14444
- return /* @__PURE__ */ jsxs53("div", { className: "rounded-2xl bg-white px-4 py-3 dark:bg-slate-950", children: [
14772
+ return /* @__PURE__ */ jsxs54("div", { className: "rounded-2xl bg-white px-4 py-3 dark:bg-slate-950", children: [
14445
14773
  /* @__PURE__ */ jsx75("p", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-400 dark:text-slate-500", children: label }),
14446
14774
  /* @__PURE__ */ jsx75("p", { className: "mt-2 text-sm font-semibold text-slate-900 dark:text-slate-100", children: value })
14447
14775
  ] });
@@ -14451,22 +14779,22 @@ function FilterChip({ label, tone = "default" }) {
14451
14779
  }
14452
14780
 
14453
14781
  // src/workspace/bottom-panel/services-split-pane.tsx
14454
- import { jsx as jsx76, jsxs as jsxs54 } from "react/jsx-runtime";
14455
- var UNGROUPED_TREE_VALUE = "__catalog_ungrouped__";
14782
+ import { jsx as jsx76, jsxs as jsxs55 } from "react/jsx-runtime";
14783
+ var UNGROUPED_TREE_VALUE2 = "__catalog_ungrouped__";
14456
14784
  function ServicesSplitPane(props) {
14457
14785
  const emptyTitle = props.mode === "active" ? "No active services yet" : "No services match this view";
14458
14786
  const emptyDescription = props.mode === "active" ? "Connect a service to a tag, field, or option and it will appear here with its bindings." : props.mode === "catalog" ? "Select a catalog group or create one to organize source services for faster assignment." : "Try changing the search or toggles to bring more services into view.";
14459
- return /* @__PURE__ */ jsx76("div", { className: "min-h-90 p-4", children: /* @__PURE__ */ jsxs54(ResizablePanelGroup, { direction: "horizontal", className: "min-h-90", children: [
14460
- /* @__PURE__ */ jsx76(ResizablePanel, { defaultSize: 44, minSize: 30, children: /* @__PURE__ */ jsxs54("section", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
14461
- /* @__PURE__ */ jsxs54("div", { className: "space-y-3 border-b border-slate-100 pr-4 dark:border-slate-800", children: [
14462
- /* @__PURE__ */ jsxs54("div", { className: "flex items-center justify-between gap-3", children: [
14787
+ return /* @__PURE__ */ jsx76("div", { className: "min-h-90 p-4", children: /* @__PURE__ */ jsxs55(ResizablePanelGroup, { direction: "horizontal", className: "min-h-90", children: [
14788
+ /* @__PURE__ */ jsx76(ResizablePanel, { defaultSize: 44, minSize: 30, children: /* @__PURE__ */ jsxs55("section", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
14789
+ /* @__PURE__ */ jsxs55("div", { className: "space-y-3 border-b border-slate-100 pr-4 dark:border-slate-800", children: [
14790
+ /* @__PURE__ */ jsxs55("div", { className: "flex items-center justify-between gap-3", children: [
14463
14791
  /* @__PURE__ */ jsx76("div", { children: /* @__PURE__ */ jsx76("h4", { className: "mt-1 text-base font-semibold text-slate-900 dark:text-slate-100", children: props.mode === "active" ? "Attached services" : props.mode === "catalog" ? "Catalog workspace" : "All services" }) }),
14464
- /* @__PURE__ */ jsxs54("div", { className: "flex items-center gap-2", children: [
14792
+ /* @__PURE__ */ jsxs55("div", { className: "flex items-center gap-2", children: [
14465
14793
  props.mode === "catalog" ? /* @__PURE__ */ jsx76("span", { className: "rounded-full bg-blue-50 px-2.5 py-1 text-[10px] font-semibold tracking-[0.16em] text-blue-700 uppercase dark:bg-blue-500/10 dark:text-blue-200", children: props.selectedCatalogGroupLabel ?? "Ungrouped" }) : null,
14466
14794
  /* @__PURE__ */ jsx76("span", { className: "rounded-full bg-slate-100 px-2.5 py-1 text-[10px] font-semibold tracking-[0.16em] text-slate-600 uppercase dark:bg-slate-900 dark:text-slate-300", children: props.rows.length })
14467
14795
  ] })
14468
14796
  ] }),
14469
- props.mode === "all" && props.appliedSnapshot?.selectedTag ? /* @__PURE__ */ jsxs54("div", { className: "flex flex-wrap gap-2 pb-3", children: [
14797
+ props.mode === "all" && props.appliedSnapshot?.selectedTag ? /* @__PURE__ */ jsxs55("div", { className: "flex flex-wrap gap-2 pb-3", children: [
14470
14798
  /* @__PURE__ */ jsx76(FilterChip2, { label: `Context tag: ${props.appliedSnapshot.selectedTag.label}` }),
14471
14799
  /* @__PURE__ */ jsx76(
14472
14800
  FilterChip2,
@@ -14503,7 +14831,7 @@ function ServicesSplitPane(props) {
14503
14831
  }
14504
14832
  ) }) : null
14505
14833
  ] }),
14506
- /* @__PURE__ */ jsx76(ScrollArea, { className: "h-[calc(var(--bottom-panel-height)-15rem)] max-h-[calc(var(--bottom-panel-height)-15rem)] min-h-0 flex-1", children: /* @__PURE__ */ jsx76("div", { className: "space-y-2 p-3 pl-0", children: props.rows.length === 0 ? /* @__PURE__ */ jsx76(EmptyState, { title: emptyTitle, description: emptyDescription }) : props.rows.map((row) => /* @__PURE__ */ jsxs54(
14834
+ /* @__PURE__ */ jsx76(ScrollArea, { className: "h-[calc(var(--bottom-panel-height)-14.5rem)] max-h-[calc(var(--bottom-panel-height)-14.5rem)] min-h-0 flex-1", children: /* @__PURE__ */ jsx76("div", { className: "space-y-2 p-3 pl-0", children: props.rows.length === 0 ? /* @__PURE__ */ jsx76(EmptyState, { title: emptyTitle, description: emptyDescription }) : props.rows.map((row) => /* @__PURE__ */ jsxs55(
14507
14835
  "button",
14508
14836
  {
14509
14837
  type: "button",
@@ -14516,14 +14844,14 @@ function ServicesSplitPane(props) {
14516
14844
  props.selectedRowId === row.id ? "border-blue-300 bg-blue-50 shadow-sm dark:border-blue-500/40 dark:bg-blue-500/10" : "border-slate-200 bg-white hover:border-slate-300 hover:bg-slate-50 dark:border-slate-800 dark:bg-slate-950/60 dark:hover:border-slate-700"
14517
14845
  ),
14518
14846
  children: [
14519
- /* @__PURE__ */ jsxs54("div", { className: "flex items-start justify-between gap-3", children: [
14520
- /* @__PURE__ */ jsxs54("div", { className: "min-w-0", children: [
14521
- /* @__PURE__ */ jsxs54("div", { className: "flex items-center gap-2", children: [
14847
+ /* @__PURE__ */ jsxs55("div", { className: "flex items-start justify-between gap-3", children: [
14848
+ /* @__PURE__ */ jsxs55("div", { className: "min-w-0", children: [
14849
+ /* @__PURE__ */ jsxs55("div", { className: "flex items-center gap-2", children: [
14522
14850
  /* @__PURE__ */ jsx76(StatusDot, { tone: row.statusTone }),
14523
14851
  /* @__PURE__ */ jsx76("span", { className: "truncate text-sm font-semibold text-slate-900 dark:text-slate-100", children: row.summary.name })
14524
14852
  ] }),
14525
- /* @__PURE__ */ jsxs54("div", { className: "mt-1 flex flex-wrap items-center gap-2 text-xs text-slate-500 dark:text-slate-400", children: [
14526
- /* @__PURE__ */ jsxs54("span", { children: [
14853
+ /* @__PURE__ */ jsxs55("div", { className: "mt-1 flex flex-wrap items-center gap-2 text-xs text-slate-500 dark:text-slate-400", children: [
14854
+ /* @__PURE__ */ jsxs55("span", { children: [
14527
14855
  "#",
14528
14856
  row.summary.id
14529
14857
  ] }),
@@ -14533,13 +14861,13 @@ function ServicesSplitPane(props) {
14533
14861
  ] }),
14534
14862
  /* @__PURE__ */ jsx76("span", { className: statusBadgeClassName(row.statusTone), children: row.statusLabel })
14535
14863
  ] }),
14536
- /* @__PURE__ */ jsxs54("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [
14537
- /* @__PURE__ */ jsxs54("span", { className: "rounded-full bg-slate-100 px-2.5 py-1 text-[11px] text-slate-600 dark:bg-slate-900 dark:text-slate-300", children: [
14864
+ /* @__PURE__ */ jsxs55("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [
14865
+ /* @__PURE__ */ jsxs55("span", { className: "rounded-full bg-slate-100 px-2.5 py-1 text-[11px] text-slate-600 dark:bg-slate-900 dark:text-slate-300", children: [
14538
14866
  row.summary.attachmentCount,
14539
14867
  " node",
14540
14868
  row.summary.attachmentCount === 1 ? "" : "s"
14541
14869
  ] }),
14542
- row.summary.rate != null ? /* @__PURE__ */ jsxs54("span", { className: "rounded-full bg-slate-100 px-2.5 py-1 text-[11px] text-slate-600 dark:bg-slate-900 dark:text-slate-300", children: [
14870
+ row.summary.rate != null ? /* @__PURE__ */ jsxs55("span", { className: "rounded-full bg-slate-100 px-2.5 py-1 text-[11px] text-slate-600 dark:bg-slate-900 dark:text-slate-300", children: [
14543
14871
  "Rate ",
14544
14872
  row.summary.rate
14545
14873
  ] }) : null,
@@ -14558,13 +14886,13 @@ function ServicesSplitPane(props) {
14558
14886
  )) }) })
14559
14887
  ] }) }),
14560
14888
  /* @__PURE__ */ jsx76(ResizableHandle, { withHandle: true }),
14561
- /* @__PURE__ */ jsx76(ResizablePanel, { defaultSize: 56, minSize: 36, children: /* @__PURE__ */ jsxs54("section", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
14562
- /* @__PURE__ */ jsxs54("div", { className: "border-b border-slate-100 px-4 dark:border-slate-800", children: [
14889
+ /* @__PURE__ */ jsx76(ResizablePanel, { defaultSize: 56, minSize: 36, children: /* @__PURE__ */ jsxs55("section", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
14890
+ /* @__PURE__ */ jsxs55("div", { className: "border-b border-slate-100 px-4 dark:border-slate-800", children: [
14563
14891
  /* @__PURE__ */ jsx76("p", { className: "text-xs font-semibold tracking-[0.18em] text-slate-400 uppercase dark:text-slate-500", children: "Service detail" }),
14564
14892
  /* @__PURE__ */ jsx76("h4", { className: "mt-1 text-base font-semibold text-slate-900 dark:text-slate-100", children: props.detailRow ? props.detailRow.summary.name : "Select a service" }),
14565
14893
  /* @__PURE__ */ jsx76("p", { className: "mt-1 text-sm text-slate-500 dark:text-slate-400", children: props.mode === "active" ? "Highlight connected nodes, inspect usage, and jump back into the canvas." : props.mode === "catalog" ? "Inspect compatibility, pricing, and bindings while browsing manual catalog groups." : "Inspect compatibility, pricing, and bindings before assigning the service to a node." })
14566
14894
  ] }),
14567
- /* @__PURE__ */ jsx76(ScrollArea, { className: "h-[calc(var(--bottom-panel-height)-15rem)] min-h-0 flex-1", children: /* @__PURE__ */ jsx76("div", { className: "p-5", children: props.detailRow ? /* @__PURE__ */ jsx76(
14895
+ /* @__PURE__ */ jsx76(ScrollArea, { className: "h-[calc(var(--bottom-panel-height)-14.5rem)] max-h-[calc(var(--bottom-panel-height)-14.5rem)] min-h-0 flex-1", children: /* @__PURE__ */ jsx76("div", { className: "p-5", children: props.detailRow ? /* @__PURE__ */ jsx76(
14568
14896
  ServiceDetailCard,
14569
14897
  {
14570
14898
  mode: props.mode,
@@ -14596,7 +14924,7 @@ function CatalogContextPopover({
14596
14924
  onDraftContextChange
14597
14925
  }) {
14598
14926
  const context = draftContext;
14599
- return /* @__PURE__ */ jsxs54(Popover, { open, onOpenChange, children: [
14927
+ return /* @__PURE__ */ jsxs55(Popover, { open, onOpenChange, children: [
14600
14928
  /* @__PURE__ */ jsx76(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx76(
14601
14929
  "button",
14602
14930
  {
@@ -14606,10 +14934,10 @@ function CatalogContextPopover({
14606
14934
  "inline-flex h-9 w-9 items-center justify-center rounded-xl border text-sm transition",
14607
14935
  compatibleOnly ? "border-blue-200 bg-blue-50 text-blue-700 dark:border-blue-500/30 dark:bg-blue-500/10 dark:text-blue-200" : "border-slate-200 bg-white text-slate-600 hover:bg-slate-100 dark:border-slate-800 dark:bg-slate-950 dark:text-slate-300 dark:hover:bg-slate-900"
14608
14936
  ),
14609
- children: /* @__PURE__ */ jsx76(FiFilter, {})
14937
+ children: /* @__PURE__ */ jsx76(FiFilter2, {})
14610
14938
  }
14611
14939
  ) }),
14612
- /* @__PURE__ */ jsxs54(
14940
+ /* @__PURE__ */ jsxs55(
14613
14941
  PopoverContent,
14614
14942
  {
14615
14943
  align: "end",
@@ -14617,30 +14945,30 @@ function CatalogContextPopover({
14617
14945
  collisionPadding: 16,
14618
14946
  className: "max-h-[min(32rem,var(--radix-popover-content-available-height))] w-[min(24rem,calc(100vw-2rem))] overflow-hidden rounded-2xl p-0",
14619
14947
  children: [
14620
- /* @__PURE__ */ jsxs54("div", { className: "border-b border-slate-200 px-4 py-3 dark:border-slate-800", children: [
14948
+ /* @__PURE__ */ jsxs55("div", { className: "border-b border-slate-200 px-4 py-3 dark:border-slate-800", children: [
14621
14949
  /* @__PURE__ */ jsx76("div", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: "Catalog context" }),
14622
14950
  /* @__PURE__ */ jsx76("p", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: "Control compatibility checks here, or link them to the current workspace context." })
14623
14951
  ] }),
14624
- /* @__PURE__ */ jsx76(ScrollArea, { className: "h-[calc(var(--radix-popover-content-available-height)-4.5rem)] max-h-[calc(var(--radix-popover-content-available-height)-4.5rem)]", children: /* @__PURE__ */ jsxs54("div", { className: "space-y-4 p-4", children: [
14625
- /* @__PURE__ */ jsxs54("label", { className: "flex items-start justify-between gap-3 text-sm text-slate-900 dark:text-slate-100", children: [
14626
- /* @__PURE__ */ jsxs54("span", { className: "min-w-0", children: [
14952
+ /* @__PURE__ */ jsx76(ScrollArea, { className: "h-[calc(var(--radix-popover-content-available-height)-4.5rem)] max-h-[calc(var(--radix-popover-content-available-height)-4.5rem)]", children: /* @__PURE__ */ jsxs55("div", { className: "space-y-4 p-4", children: [
14953
+ /* @__PURE__ */ jsxs55("label", { className: "flex items-start justify-between gap-3 text-sm text-slate-900 dark:text-slate-100", children: [
14954
+ /* @__PURE__ */ jsxs55("span", { className: "min-w-0", children: [
14627
14955
  /* @__PURE__ */ jsx76("span", { className: "block font-medium", children: "Compatible only" }),
14628
14956
  /* @__PURE__ */ jsx76("span", { className: "mt-1 block text-xs text-slate-500 dark:text-slate-400", children: "Show only services that fit this catalog context safely." })
14629
14957
  ] }),
14630
14958
  /* @__PURE__ */ jsx76("input", { type: "checkbox", checked: compatibleOnly, onChange: (event) => onCompatibleOnlyChange(event.target.checked) })
14631
14959
  ] }),
14632
- /* @__PURE__ */ jsxs54("label", { className: "flex items-start justify-between gap-3 text-sm text-slate-900 dark:text-slate-100", children: [
14633
- /* @__PURE__ */ jsxs54("span", { className: "min-w-0", children: [
14960
+ /* @__PURE__ */ jsxs55("label", { className: "flex items-start justify-between gap-3 text-sm text-slate-900 dark:text-slate-100", children: [
14961
+ /* @__PURE__ */ jsxs55("span", { className: "min-w-0", children: [
14634
14962
  /* @__PURE__ */ jsx76("span", { className: "block font-medium", children: "Link to current context" }),
14635
14963
  /* @__PURE__ */ jsx76("span", { className: "mt-1 block text-xs text-slate-500 dark:text-slate-400", children: "Mirror the current canvas tag and selected buttons while linked." })
14636
14964
  ] }),
14637
14965
  /* @__PURE__ */ jsx76("input", { type: "checkbox", checked: contextLinked, onChange: (event) => onContextLinkedChange(event.target.checked) })
14638
14966
  ] }),
14639
- /* @__PURE__ */ jsxs54("div", { className: "space-y-2 rounded-2xl border border-slate-200 bg-slate-50/70 p-3 dark:border-slate-800 dark:bg-slate-900/40", children: [
14967
+ /* @__PURE__ */ jsxs55("div", { className: "space-y-2 rounded-2xl border border-slate-200 bg-slate-50/70 p-3 dark:border-slate-800 dark:bg-slate-900/40", children: [
14640
14968
  /* @__PURE__ */ jsx76("div", { className: "text-xs font-semibold tracking-[0.16em] text-slate-500 uppercase dark:text-slate-400", children: "Tags" }),
14641
14969
  /* @__PURE__ */ jsx76("div", { className: "space-y-2", children: (draftSnapshot?.tags ?? []).map((tag) => {
14642
14970
  const selected = context?.selectedTagId === tag.id;
14643
- return /* @__PURE__ */ jsxs54("label", { className: "flex items-start gap-3 text-sm text-slate-900 dark:text-slate-100", children: [
14971
+ return /* @__PURE__ */ jsxs55("label", { className: "flex items-start gap-3 text-sm text-slate-900 dark:text-slate-100", children: [
14644
14972
  /* @__PURE__ */ jsx76(
14645
14973
  "input",
14646
14974
  {
@@ -14659,20 +14987,20 @@ function CatalogContextPopover({
14659
14987
  })
14660
14988
  }
14661
14989
  ),
14662
- /* @__PURE__ */ jsxs54("span", { className: "min-w-0", children: [
14990
+ /* @__PURE__ */ jsxs55("span", { className: "min-w-0", children: [
14663
14991
  /* @__PURE__ */ jsx76("span", { className: "block font-medium", children: tag.label }),
14664
14992
  tag.description ? /* @__PURE__ */ jsx76("span", { className: "block text-xs text-slate-500 dark:text-slate-400", children: tag.description }) : null
14665
14993
  ] })
14666
14994
  ] }, tag.id);
14667
14995
  }) })
14668
14996
  ] }),
14669
- /* @__PURE__ */ jsxs54("div", { className: "space-y-2 rounded-2xl border border-slate-200 bg-slate-50/70 p-3 dark:border-slate-800 dark:bg-slate-900/40", children: [
14997
+ /* @__PURE__ */ jsxs55("div", { className: "space-y-2 rounded-2xl border border-slate-200 bg-slate-50/70 p-3 dark:border-slate-800 dark:bg-slate-900/40", children: [
14670
14998
  /* @__PURE__ */ jsx76("div", { className: "text-xs font-semibold tracking-[0.16em] text-slate-500 uppercase dark:text-slate-400", children: "Selected buttons" }),
14671
- draftSnapshot?.buttonGroups?.length ? /* @__PURE__ */ jsx76("div", { className: "space-y-3", children: draftSnapshot.buttonGroups.map((group) => /* @__PURE__ */ jsxs54("div", { className: "space-y-2", children: [
14999
+ draftSnapshot?.buttonGroups?.length ? /* @__PURE__ */ jsx76("div", { className: "space-y-3", children: draftSnapshot.buttonGroups.map((group) => /* @__PURE__ */ jsxs55("div", { className: "space-y-2", children: [
14672
15000
  /* @__PURE__ */ jsx76("div", { className: "text-sm font-medium text-slate-900 dark:text-slate-100", children: group.label }),
14673
15001
  /* @__PURE__ */ jsx76("div", { className: "space-y-1", children: group.options.map((option) => {
14674
15002
  const checked = context?.selectedButtons.includes(option.id) ?? false;
14675
- return /* @__PURE__ */ jsxs54(
15003
+ return /* @__PURE__ */ jsxs55(
14676
15004
  "label",
14677
15005
  {
14678
15006
  className: "flex items-start gap-3 text-sm text-slate-900 dark:text-slate-100",
@@ -14694,7 +15022,7 @@ function CatalogContextPopover({
14694
15022
  })
14695
15023
  }
14696
15024
  ),
14697
- /* @__PURE__ */ jsxs54("span", { className: "min-w-0", children: [
15025
+ /* @__PURE__ */ jsxs55("span", { className: "min-w-0", children: [
14698
15026
  /* @__PURE__ */ jsx76("span", { className: "block", children: option.label }),
14699
15027
  option.description ? /* @__PURE__ */ jsx76("span", { className: "block text-xs text-slate-500 dark:text-slate-400", children: option.description }) : null
14700
15028
  ] })
@@ -14705,9 +15033,9 @@ function CatalogContextPopover({
14705
15033
  }) })
14706
15034
  ] }, group.id)) }) : /* @__PURE__ */ jsx76("div", { className: "text-sm text-slate-500 dark:text-slate-400", children: "No visible trigger options for the selected tag." })
14707
15035
  ] }),
14708
- /* @__PURE__ */ jsxs54("div", { className: "space-y-2 rounded-2xl border border-slate-200 bg-slate-50/70 p-3 dark:border-slate-800 dark:bg-slate-900/40", children: [
15036
+ /* @__PURE__ */ jsxs55("div", { className: "space-y-2 rounded-2xl border border-slate-200 bg-slate-50/70 p-3 dark:border-slate-800 dark:bg-slate-900/40", children: [
14709
15037
  /* @__PURE__ */ jsx76("div", { className: "text-xs font-semibold tracking-[0.16em] text-slate-500 uppercase dark:text-slate-400", children: "Safety" }),
14710
- /* @__PURE__ */ jsxs54("label", { className: "flex items-center justify-between gap-3 text-sm text-slate-900 dark:text-slate-100", children: [
15038
+ /* @__PURE__ */ jsxs55("label", { className: "flex items-center justify-between gap-3 text-sm text-slate-900 dark:text-slate-100", children: [
14711
15039
  /* @__PURE__ */ jsx76("span", { children: "Strict safety" }),
14712
15040
  /* @__PURE__ */ jsx76(
14713
15041
  "input",
@@ -14722,7 +15050,7 @@ function CatalogContextPopover({
14722
15050
  }
14723
15051
  )
14724
15052
  ] }),
14725
- /* @__PURE__ */ jsxs54("label", { className: "flex items-center justify-between gap-3 text-sm text-slate-900 dark:text-slate-100", children: [
15053
+ /* @__PURE__ */ jsxs55("label", { className: "flex items-center justify-between gap-3 text-sm text-slate-900 dark:text-slate-100", children: [
14726
15054
  /* @__PURE__ */ jsx76("span", { children: "Enforce policies" }),
14727
15055
  /* @__PURE__ */ jsx76(
14728
15056
  "input",
@@ -14756,10 +15084,10 @@ function CatalogToolbar({
14756
15084
  onDeleteGroup,
14757
15085
  onAssignServices
14758
15086
  }) {
14759
- const treeValue = selectedGroupId ?? (ungroupedSelected ? UNGROUPED_TREE_VALUE : void 0);
14760
- const treeOptions = buildCatalogGroupTreeOptions(groups);
14761
- return /* @__PURE__ */ jsxs54("div", { className: "flex items-center justify-between gap-3", children: [
14762
- /* @__PURE__ */ jsxs54("div", { className: "flex flex-wrap items-center gap-2", children: [
15087
+ const treeValue = selectedGroupId ?? (ungroupedSelected ? UNGROUPED_TREE_VALUE2 : void 0);
15088
+ const treeOptions = buildCatalogGroupTreeOptions2(groups);
15089
+ return /* @__PURE__ */ jsxs55("div", { className: "flex items-center justify-between gap-3", children: [
15090
+ /* @__PURE__ */ jsxs55("div", { className: "flex flex-wrap items-center gap-2", children: [
14763
15091
  /* @__PURE__ */ jsx76(
14764
15092
  GroupInputPopoverButton,
14765
15093
  {
@@ -14815,14 +15143,14 @@ function CatalogToolbar({
14815
15143
  className: "w-fit!",
14816
15144
  multiple: false,
14817
15145
  value: treeValue,
14818
- options: [{ key: UNGROUPED_TREE_VALUE, label: "Ungrouped" }, ...treeOptions],
15146
+ options: [{ key: UNGROUPED_TREE_VALUE2, label: "Ungrouped" }, ...treeOptions],
14819
15147
  searchable: true,
14820
15148
  clearable: true,
14821
15149
  onChange: (event) => {
14822
15150
  const next = event.value == null ? null : String(event.value);
14823
- onSelectGroup(next === UNGROUPED_TREE_VALUE ? null : next);
15151
+ onSelectGroup(next === UNGROUPED_TREE_VALUE2 ? null : next);
14824
15152
  },
14825
- button: /* @__PURE__ */ jsx76(FaFolderOpen, {})
15153
+ button: /* @__PURE__ */ jsx76(FaFolderOpen2, {})
14826
15154
  }
14827
15155
  )
14828
15156
  ] });
@@ -14838,10 +15166,10 @@ function GroupInputPopoverButton({
14838
15166
  }) {
14839
15167
  const [open, setOpen] = useState33(false);
14840
15168
  const [value, setValue] = useState33(initialValue);
14841
- useEffect20(() => {
15169
+ useEffect21(() => {
14842
15170
  if (open) setValue(initialValue);
14843
15171
  }, [initialValue, open]);
14844
- return /* @__PURE__ */ jsxs54(Popover, { open, onOpenChange: setOpen, children: [
15172
+ return /* @__PURE__ */ jsxs55(Popover, { open, onOpenChange: setOpen, children: [
14845
15173
  /* @__PURE__ */ jsx76(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx76(
14846
15174
  "button",
14847
15175
  {
@@ -14856,8 +15184,8 @@ function GroupInputPopoverButton({
14856
15184
  children: icon
14857
15185
  }
14858
15186
  ) }),
14859
- /* @__PURE__ */ jsx76(PopoverContent, { align: "start", side: "bottom", sideOffset: 8, collisionPadding: 16, className: "w-80 rounded-2xl", children: /* @__PURE__ */ jsxs54("div", { className: "space-y-3", children: [
14860
- /* @__PURE__ */ jsxs54("div", { children: [
15187
+ /* @__PURE__ */ jsx76(PopoverContent, { align: "start", side: "bottom", sideOffset: 8, collisionPadding: 16, className: "w-80 rounded-2xl", children: /* @__PURE__ */ jsxs55("div", { className: "space-y-3", children: [
15188
+ /* @__PURE__ */ jsxs55("div", { children: [
14861
15189
  /* @__PURE__ */ jsx76("div", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: title }),
14862
15190
  /* @__PURE__ */ jsx76("p", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: "Names are editor-side catalog labels only." })
14863
15191
  ] }),
@@ -14872,7 +15200,7 @@ function GroupInputPopoverButton({
14872
15200
  autoComplete: "off"
14873
15201
  }
14874
15202
  ),
14875
- /* @__PURE__ */ jsxs54("div", { className: "flex justify-end gap-2", children: [
15203
+ /* @__PURE__ */ jsxs55("div", { className: "flex justify-end gap-2", children: [
14876
15204
  /* @__PURE__ */ jsx76(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setOpen(false), className: "rounded-xl", children: "Cancel" }),
14877
15205
  /* @__PURE__ */ jsx76(
14878
15206
  Button,
@@ -14904,7 +15232,7 @@ function ConfirmPopoverButton({
14904
15232
  onConfirm
14905
15233
  }) {
14906
15234
  const [open, setOpen] = useState33(false);
14907
- return /* @__PURE__ */ jsxs54(Popover, { open, onOpenChange: setOpen, children: [
15235
+ return /* @__PURE__ */ jsxs55(Popover, { open, onOpenChange: setOpen, children: [
14908
15236
  /* @__PURE__ */ jsx76(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx76(
14909
15237
  "button",
14910
15238
  {
@@ -14919,12 +15247,12 @@ function ConfirmPopoverButton({
14919
15247
  children: icon
14920
15248
  }
14921
15249
  ) }),
14922
- /* @__PURE__ */ jsx76(PopoverContent, { align: "start", side: "bottom", sideOffset: 8, collisionPadding: 16, className: "w-80 rounded-2xl", children: /* @__PURE__ */ jsxs54("div", { className: "space-y-3", children: [
14923
- /* @__PURE__ */ jsxs54("div", { children: [
15250
+ /* @__PURE__ */ jsx76(PopoverContent, { align: "start", side: "bottom", sideOffset: 8, collisionPadding: 16, className: "w-80 rounded-2xl", children: /* @__PURE__ */ jsxs55("div", { className: "space-y-3", children: [
15251
+ /* @__PURE__ */ jsxs55("div", { children: [
14924
15252
  /* @__PURE__ */ jsx76("div", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: title }),
14925
15253
  /* @__PURE__ */ jsx76("p", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: description })
14926
15254
  ] }),
14927
- /* @__PURE__ */ jsxs54("div", { className: "flex justify-end gap-2", children: [
15255
+ /* @__PURE__ */ jsxs55("div", { className: "flex justify-end gap-2", children: [
14928
15256
  /* @__PURE__ */ jsx76(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setOpen(false), className: "rounded-xl", children: "Cancel" }),
14929
15257
  /* @__PURE__ */ jsx76(
14930
15258
  Button,
@@ -14949,7 +15277,7 @@ function ToolbarIconButton({
14949
15277
  disabled = false,
14950
15278
  onClick
14951
15279
  }) {
14952
- return /* @__PURE__ */ jsxs54(Tooltip, { children: [
15280
+ return /* @__PURE__ */ jsxs55(Tooltip, { children: [
14953
15281
  /* @__PURE__ */ jsx76(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx76(
14954
15282
  "button",
14955
15283
  {
@@ -14970,9 +15298,9 @@ function ToolbarIconButton({
14970
15298
  function FilterChip2({ label, tone = "default" }) {
14971
15299
  return /* @__PURE__ */ jsx76("span", { className: cn("rounded-full px-2.5 py-1 text-[11px] font-medium", filterChipClassName(tone)), children: label });
14972
15300
  }
14973
- function buildCatalogGroupTreeOptions(groups, parentId = null) {
15301
+ function buildCatalogGroupTreeOptions2(groups, parentId = null) {
14974
15302
  return groups.filter((group) => (group.parentId ?? null) === parentId).sort((a, b) => (a.order ?? 0) - (b.order ?? 0) || a.label.localeCompare(b.label)).map((group) => {
14975
- const children = buildCatalogGroupTreeOptions(groups, group.id);
15303
+ const children = buildCatalogGroupTreeOptions2(groups, group.id);
14976
15304
  return {
14977
15305
  key: group.id,
14978
15306
  label: group.label,
@@ -14983,7 +15311,7 @@ function buildCatalogGroupTreeOptions(groups, parentId = null) {
14983
15311
  }
14984
15312
 
14985
15313
  // src/workspace/bottom-panel/index.tsx
14986
- import { Fragment as Fragment16, jsx as jsx77, jsxs as jsxs55 } from "react/jsx-runtime";
15314
+ import { Fragment as Fragment16, jsx as jsx77, jsxs as jsxs56 } from "react/jsx-runtime";
14987
15315
  var DRAG_MIME = "application/x-service-builder-service";
14988
15316
  function BottomConsolePanel({ controller, errors, activeServices, allServices, onServiceDragStateChange }) {
14989
15317
  const canvas = useCanvas21();
@@ -15078,25 +15406,25 @@ function BottomConsolePanel({ controller, errors, activeServices, allServices, o
15078
15406
  ).filter((row) => row.matchesSearch).filter((row) => !compatibleOnly || row.isCompatible).filter((row) => !hideActiveServices || !hiddenServiceIds.has(row.id)),
15079
15407
  [allChecksById, allSearch, allServices, compatibleOnly, effectiveCatalogContext, hiddenServiceIds, hideActiveServices, servicesMap]
15080
15408
  );
15081
- useEffect21(() => {
15409
+ useEffect22(() => {
15082
15410
  const next = createDefaultServiceContext(canvas.props, preferredTagId);
15083
15411
  setCatalogContextDraft((current) => {
15084
15412
  if (contextLinked) return current;
15085
15413
  return current.selectedTagId ? current : next;
15086
15414
  });
15087
15415
  }, [canvas.props, contextLinked, preferredTagId]);
15088
- useEffect21(() => {
15416
+ useEffect22(() => {
15089
15417
  if (!contextLinked) return;
15090
15418
  setCatalogContextDraft(liveSelectionContext);
15091
15419
  }, [contextLinked, liveSelectionContext]);
15092
- useEffect21(() => {
15420
+ useEffect22(() => {
15093
15421
  if (contextLinked) return;
15094
15422
  const next = sanitizeServiceContext(draftSnapshot, catalogContextDraft);
15095
15423
  if (JSON.stringify(next) !== JSON.stringify(catalogContextDraft)) {
15096
15424
  setCatalogContextDraft(next);
15097
15425
  }
15098
15426
  }, [catalogContextDraft, contextLinked, draftSnapshot]);
15099
- useEffect21(() => {
15427
+ useEffect22(() => {
15100
15428
  const editor = canvas.api.editor;
15101
15429
  const ensured = editor.getCatalog?.() ?? editor.ensureCatalog?.();
15102
15430
  console.log(ensured);
@@ -15143,24 +15471,24 @@ function BottomConsolePanel({ controller, errors, activeServices, allServices, o
15143
15471
  return ids;
15144
15472
  }, [canvas.activeId, canvas.selectionInfo.ids]);
15145
15473
  const consoleIssueCount = errors.validation.length + errors.logs.length + notices.length;
15146
- useEffect21(() => {
15474
+ useEffect22(() => {
15147
15475
  setSelectedActiveServiceId((current) => ensureSelectedRow(current, activeRows));
15148
15476
  }, [activeRows]);
15149
- useEffect21(() => {
15477
+ useEffect22(() => {
15150
15478
  if (catalogState?.selectedServiceId == null) return;
15151
15479
  setSelectedAllServiceId(String(catalogState.selectedServiceId));
15152
15480
  }, [catalogState?.selectedServiceId]);
15153
- useEffect21(() => {
15481
+ useEffect22(() => {
15154
15482
  setSelectedAllServiceId((current) => ensureSelectedRow(current, visibleAllRows));
15155
15483
  }, [visibleAllRows]);
15156
- useEffect21(() => {
15484
+ useEffect22(() => {
15157
15485
  const desiredIds = controller.isOpen && controller.activeTab === "activeServices" && selectedActiveServiceId ? activeRows.find((row) => row.id === selectedActiveServiceId)?.summary.attachedNodeIds ?? [] : [];
15158
15486
  if (!sameIds(lastHighlightedIdsRef.current, desiredIds)) {
15159
15487
  canvas.api.setHighlighted(desiredIds);
15160
15488
  lastHighlightedIdsRef.current = [...desiredIds];
15161
15489
  }
15162
15490
  }, [activeRows, canvas.api, controller.activeTab, controller.isOpen, selectedActiveServiceId]);
15163
- useEffect21(() => {
15491
+ useEffect22(() => {
15164
15492
  return () => {
15165
15493
  if (lastHighlightedIdsRef.current.length) {
15166
15494
  canvas.api.setHighlighted([]);
@@ -15168,10 +15496,10 @@ function BottomConsolePanel({ controller, errors, activeServices, allServices, o
15168
15496
  }
15169
15497
  };
15170
15498
  }, [canvas.api]);
15171
- useEffect21(() => {
15499
+ useEffect22(() => {
15172
15500
  if (searchOpen) searchInputRef.current?.focus();
15173
15501
  }, [searchOpen]);
15174
- useEffect21(() => {
15502
+ useEffect22(() => {
15175
15503
  setPanelPosition((current) => {
15176
15504
  const resolved = resolvePanelPosition(current, panelRef.current, panelContainerRef.current);
15177
15505
  persistPanelPosition(resolved);
@@ -15193,7 +15521,7 @@ function BottomConsolePanel({ controller, errors, activeServices, allServices, o
15193
15521
  }
15194
15522
  event.preventDefault();
15195
15523
  };
15196
- useEffect21(() => {
15524
+ useEffect22(() => {
15197
15525
  if (!draggingPanel) return;
15198
15526
  const onPointerMove = (event) => {
15199
15527
  const start = dragStartRef.current;
@@ -15221,7 +15549,7 @@ function BottomConsolePanel({ controller, errors, activeServices, allServices, o
15221
15549
  window.removeEventListener("pointercancel", onPointerUp);
15222
15550
  };
15223
15551
  }, [draggingPanel, panelPosition]);
15224
- const setCatalogMode = useCallback18(
15552
+ const setCatalogMode = useCallback19(
15225
15553
  (mode) => {
15226
15554
  const editor = canvas.api.editor;
15227
15555
  editor.ensureCatalog?.();
@@ -15229,27 +15557,27 @@ function BottomConsolePanel({ controller, errors, activeServices, allServices, o
15229
15557
  },
15230
15558
  [canvas.api.editor]
15231
15559
  );
15232
- const handleSelectCatalogService = useCallback18(
15560
+ const handleSelectCatalogService = useCallback19(
15233
15561
  (id) => {
15234
15562
  setSelectedAllServiceId(id);
15235
15563
  canvas.api.editor.setSelectedCatalogService?.(id ?? void 0);
15236
15564
  },
15237
15565
  [canvas.api.editor]
15238
15566
  );
15239
- const handleSelectCatalogGroup = useCallback18(
15567
+ const handleSelectCatalogGroup = useCallback19(
15240
15568
  (groupId) => {
15241
15569
  canvas.api.editor.setActiveCatalogNode?.(groupId ?? void 0);
15242
15570
  },
15243
15571
  [canvas.api.editor]
15244
15572
  );
15245
- const handleCreateRootGroup = useCallback18(
15573
+ const handleCreateRootGroup = useCallback19(
15246
15574
  (label) => {
15247
15575
  if (!label.trim()) return;
15248
15576
  canvas.api.editor.createCatalogGroup?.({ label: label.trim() });
15249
15577
  },
15250
15578
  [canvas.api.editor]
15251
15579
  );
15252
- const handleCreateChildGroup = useCallback18(
15580
+ const handleCreateChildGroup = useCallback19(
15253
15581
  (label) => {
15254
15582
  if (!selectedCatalogGroupId) return;
15255
15583
  const editor = canvas.api.editor;
@@ -15258,7 +15586,7 @@ function BottomConsolePanel({ controller, errors, activeServices, allServices, o
15258
15586
  },
15259
15587
  [canvas.api.editor, selectedCatalogGroupId]
15260
15588
  );
15261
- const handleRenameGroup = useCallback18(
15589
+ const handleRenameGroup = useCallback19(
15262
15590
  (label) => {
15263
15591
  if (!selectedCatalogGroupId) return;
15264
15592
  const group = catalogGroups.find((item) => item.id === selectedCatalogGroupId);
@@ -15268,15 +15596,15 @@ function BottomConsolePanel({ controller, errors, activeServices, allServices, o
15268
15596
  },
15269
15597
  [canvas.api.editor, catalogGroups, selectedCatalogGroupId]
15270
15598
  );
15271
- const handleDeleteGroup = useCallback18(() => {
15599
+ const handleDeleteGroup = useCallback19(() => {
15272
15600
  if (!selectedCatalogGroupId) return;
15273
15601
  canvas.api.editor.removeCatalogNode?.(selectedCatalogGroupId, { cascade: true });
15274
15602
  }, [canvas.api.editor, selectedCatalogGroupId]);
15275
- const handleAssignServices = useCallback18(() => {
15603
+ const handleAssignServices = useCallback19(() => {
15276
15604
  if (!selectedCatalogGroupId) return;
15277
15605
  setServicePickerOpen(true);
15278
15606
  }, [selectedCatalogGroupId]);
15279
- const handleConfirmAssignServices = useCallback18(
15607
+ const handleConfirmAssignServices = useCallback19(
15280
15608
  (serviceIds) => {
15281
15609
  if (!selectedCatalogGroupId || !serviceIds.length) return;
15282
15610
  canvas.api.editor.assignServicesToCatalogGroup?.(selectedCatalogGroupId, serviceIds, "append");
@@ -15317,7 +15645,7 @@ function BottomConsolePanel({ controller, errors, activeServices, allServices, o
15317
15645
  }
15318
15646
  ) });
15319
15647
  }, [controller.activeTab, activeSearch, allSearch, setActiveSearch, setAllSearch]);
15320
- return /* @__PURE__ */ jsxs55("div", { ref: panelContainerRef, className: "pointer-events-none absolute inset-0", children: [
15648
+ return /* @__PURE__ */ jsxs56("div", { ref: panelContainerRef, className: "pointer-events-none absolute inset-0", children: [
15321
15649
  /* @__PURE__ */ jsx77(
15322
15650
  ServicePickerDialog,
15323
15651
  {
@@ -15331,7 +15659,7 @@ function BottomConsolePanel({ controller, errors, activeServices, allServices, o
15331
15659
  onConfirm: handleConfirmAssignServices
15332
15660
  }
15333
15661
  ),
15334
- /* @__PURE__ */ jsxs55(
15662
+ /* @__PURE__ */ jsxs56(
15335
15663
  Panel,
15336
15664
  {
15337
15665
  ref: panelRef,
@@ -15362,8 +15690,8 @@ function BottomConsolePanel({ controller, errors, activeServices, allServices, o
15362
15690
  ["--bottom-panel-height"]: controller.height + "px"
15363
15691
  },
15364
15692
  children: [
15365
- /* @__PURE__ */ jsxs55("div", { className: "flex items-center justify-between gap-3 border-b border-slate-200/80 px-3 py-2 dark:border-slate-800/80", children: [
15366
- /* @__PURE__ */ jsx77("div", { className: "flex min-w-0 items-center gap-1", children: tabs.map((tab) => /* @__PURE__ */ jsxs55(
15693
+ /* @__PURE__ */ jsxs56("div", { className: "flex items-center justify-between gap-3 border-b border-slate-200/80 px-3 py-2 dark:border-slate-800/80", children: [
15694
+ /* @__PURE__ */ jsx77("div", { className: "flex min-w-0 items-center gap-1", children: tabs.map((tab) => /* @__PURE__ */ jsxs56(
15367
15695
  "button",
15368
15696
  {
15369
15697
  type: "button",
@@ -15389,8 +15717,8 @@ function BottomConsolePanel({ controller, errors, activeServices, allServices, o
15389
15717
  },
15390
15718
  tab.id
15391
15719
  )) }),
15392
- /* @__PURE__ */ jsxs55("div", { className: "flex items-center gap-1", children: [
15393
- /* @__PURE__ */ jsxs55(
15720
+ /* @__PURE__ */ jsxs56("div", { className: "flex items-center gap-1", children: [
15721
+ /* @__PURE__ */ jsxs56(
15394
15722
  "button",
15395
15723
  {
15396
15724
  type: "button",
@@ -15405,7 +15733,7 @@ function BottomConsolePanel({ controller, errors, activeServices, allServices, o
15405
15733
  ]
15406
15734
  }
15407
15735
  ),
15408
- /* @__PURE__ */ jsxs55("div", { className: "hidden items-center gap-2 rounded-xl border border-slate-200/80 px-2 py-1 text-xs text-slate-500 md:flex dark:border-slate-800 dark:text-slate-400", children: [
15736
+ /* @__PURE__ */ jsxs56("div", { className: "hidden items-center gap-2 rounded-xl border border-slate-200/80 px-2 py-1 text-xs text-slate-500 md:flex dark:border-slate-800 dark:text-slate-400", children: [
15409
15737
  /* @__PURE__ */ jsx77(LuGripHorizontal, {}),
15410
15738
  /* @__PURE__ */ jsx77("span", { children: "Resize from top or side edges" })
15411
15739
  ] }),
@@ -15422,13 +15750,13 @@ function BottomConsolePanel({ controller, errors, activeServices, allServices, o
15422
15750
  )
15423
15751
  ] })
15424
15752
  ] }),
15425
- /* @__PURE__ */ jsxs55("div", { className: "flex min-h-0 flex-1 flex-col bg-slate-50/70 dark:bg-slate-950/40", children: [
15426
- controller.activeTab !== "console" ? /* @__PURE__ */ jsxs55("div", { className: "flex items-center justify-between gap-3 border-b border-slate-200/70 px-4 py-3 dark:border-slate-800/70", children: [
15427
- /* @__PURE__ */ jsxs55("div", { className: "min-w-0", children: [
15753
+ /* @__PURE__ */ jsxs56("div", { className: "flex min-h-0 flex-1 flex-col bg-slate-50/70 dark:bg-slate-950/40", children: [
15754
+ controller.activeTab !== "console" ? /* @__PURE__ */ jsxs56("div", { className: "flex items-center justify-between gap-3 border-b border-slate-200/70 px-4 py-3 dark:border-slate-800/70", children: [
15755
+ /* @__PURE__ */ jsxs56("div", { className: "min-w-0", children: [
15428
15756
  /* @__PURE__ */ jsx77("p", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: controller.activeTab === "activeServices" ? "Connected services" : "Service catalog" }),
15429
15757
  /* @__PURE__ */ jsx77("p", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: controller.activeTab === "activeServices" ? "Bound services can be highlighted back onto the canvas from here." : catalogPanelMode === "catalog" ? "Browse source services through manual editor-side catalog groups while keeping detail and compatibility visible." : "Browse every source service, filter by current visible-group compatibility, and drag it onto nodes." })
15430
15758
  ] }),
15431
- /* @__PURE__ */ jsx77("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs55("div", { className: "relative flex items-center gap-2", children: [
15759
+ /* @__PURE__ */ jsx77("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs56("div", { className: "relative flex items-center gap-2", children: [
15432
15760
  searchOpen ? Search : null,
15433
15761
  /* @__PURE__ */ jsx77(
15434
15762
  HeaderIconButton,
@@ -15439,7 +15767,7 @@ function BottomConsolePanel({ controller, errors, activeServices, allServices, o
15439
15767
  children: /* @__PURE__ */ jsx77(FiSearch, {})
15440
15768
  }
15441
15769
  ),
15442
- controller.activeTab === "allServices" ? /* @__PURE__ */ jsxs55(Fragment16, { children: [
15770
+ controller.activeTab === "allServices" ? /* @__PURE__ */ jsxs56(Fragment16, { children: [
15443
15771
  /* @__PURE__ */ jsx77(
15444
15772
  CatalogContextPopover,
15445
15773
  {
@@ -15567,7 +15895,7 @@ function HeaderIconButton({
15567
15895
  active = false,
15568
15896
  onClick
15569
15897
  }) {
15570
- return /* @__PURE__ */ jsxs55(Tooltip, { children: [
15898
+ return /* @__PURE__ */ jsxs56(Tooltip, { children: [
15571
15899
  /* @__PURE__ */ jsx77(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx77(
15572
15900
  "button",
15573
15901
  {
@@ -15585,7 +15913,7 @@ function HeaderIconButton({
15585
15913
  ] });
15586
15914
  }
15587
15915
  function CatalogModeSwitch({ mode, onChange }) {
15588
- return /* @__PURE__ */ jsxs55("div", { className: "inline-flex items-center rounded-xl border border-slate-200 bg-white p-1 dark:border-slate-800 dark:bg-slate-950", children: [
15916
+ return /* @__PURE__ */ jsxs56("div", { className: "inline-flex items-center rounded-xl border border-slate-200 bg-white p-1 dark:border-slate-800 dark:bg-slate-950", children: [
15589
15917
  /* @__PURE__ */ jsx77(
15590
15918
  "button",
15591
15919
  {
@@ -16241,7 +16569,7 @@ var workspaceBackend = createMemoryWorkspaceBackend({
16241
16569
  });
16242
16570
 
16243
16571
  // src/index.tsx
16244
- import { Fragment as Fragment17, jsx as jsx78, jsxs as jsxs56 } from "react/jsx-runtime";
16572
+ import { Fragment as Fragment17, jsx as jsx78, jsxs as jsxs57 } from "react/jsx-runtime";
16245
16573
  var inputRegistry = createInputRegistry();
16246
16574
  registerEntries(inputRegistry);
16247
16575
  function WorkspaceLayout({ onShare, onPlay, menu }) {
@@ -16251,9 +16579,9 @@ function WorkspaceLayout({ onShare, onPlay, menu }) {
16251
16579
  const bottomPanel = useBottomConsolePanel();
16252
16580
  const [draggingServiceId, setDraggingServiceId] = useState35(null);
16253
16581
  const serviceSummary = useMemo35(() => buildServiceSummaries(canvas, ws), [canvas.props, canvas.selectionInfo, canvas.activeId, ws.services.data]);
16254
- return /* @__PURE__ */ jsx78(FallbackQuickAddProvider, { children: /* @__PURE__ */ jsx78(NodeContextMenuProvider, { children: /* @__PURE__ */ jsx78(FallbackEditorModalProvider, { children: /* @__PURE__ */ jsxs56("div", { className: "relative flex h-screen flex-col overflow-hidden *:font-display", children: [
16582
+ return /* @__PURE__ */ jsx78(FallbackQuickAddProvider, { children: /* @__PURE__ */ jsx78(NodeContextMenuProvider, { children: /* @__PURE__ */ jsx78(FallbackEditorModalProvider, { children: /* @__PURE__ */ jsxs57("div", { className: "relative flex h-screen flex-col overflow-hidden *:font-display", children: [
16255
16583
  /* @__PURE__ */ jsx78("div", { className: "pointer-events-none absolute top-4 left-1/2 z-30 w-full max-w-2xl -translate-x-1/2 px-4", children: /* @__PURE__ */ jsx78("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx78(WorkspaceBootStatusSurface, { boot: ws.boot }) }) }),
16256
- /* @__PURE__ */ jsxs56("div", { className: "flex grow overflow-hidden", children: [
16584
+ /* @__PURE__ */ jsxs57("div", { className: "flex grow overflow-hidden", children: [
16257
16585
  /* @__PURE__ */ jsx78(left_default, { menu }),
16258
16586
  /* @__PURE__ */ jsx78(
16259
16587
  CanvasPanel,
@@ -16354,7 +16682,7 @@ var Styles = `
16354
16682
 
16355
16683
  `;
16356
16684
  function ServiceBuilder({ backend, actor, onShare, onPlay, menu }) {
16357
- return /* @__PURE__ */ jsxs56(Fragment17, { children: [
16685
+ return /* @__PURE__ */ jsxs57(Fragment17, { children: [
16358
16686
  /* @__PURE__ */ jsx78("style", { children: Styles }),
16359
16687
  /* @__PURE__ */ jsx78(InputsProvider, { initialRegistry: inputRegistry, children: /* @__PURE__ */ jsx78(Workspace, { backend, actor, children: () => /* @__PURE__ */ jsx78(WorkspaceLayout, { onShare, onPlay, menu }) }) })
16360
16688
  ] });