@cyoda/workflow-react 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/components/WorkflowEditor.tsx
2
- import { useCallback as useCallback3, useEffect as useEffect12, useMemo as useMemo7, useRef as useRef15, useState as useState18 } from "react";
2
+ import { useCallback as useCallback3, useEffect as useEffect13, useMemo as useMemo7, useRef as useRef16, useState as useState18 } from "react";
3
3
  import {
4
4
  applyPatch as applyPatch2,
5
5
  invertPatch as invertPatch2,
@@ -102,6 +102,7 @@ var defaultMessages = {
102
102
  annotationsRevert: "Revert",
103
103
  annotationsRemove: "Remove",
104
104
  annotationsDocChanged: "Document changed underneath \u2014 Revert to reload.",
105
+ format: "Format",
105
106
  executionMode: "Execution mode",
106
107
  addProcessor: "Add processor",
107
108
  removeProcessor: "Remove",
@@ -123,7 +124,12 @@ var defaultMessages = {
123
124
  anchorBottomRight: "Bottom right",
124
125
  anchorLeftTop: "Left top",
125
126
  anchorLeft: "Left",
126
- anchorLeftBottom: "Left bottom"
127
+ anchorLeftBottom: "Left bottom",
128
+ detachPanel: "Detach panel",
129
+ dockPanel: "Dock panel",
130
+ minimize: "Minimize",
131
+ restore: "Restore",
132
+ minimizedTitle: "Inspector"
127
133
  },
128
134
  confirmDelete: {
129
135
  title: "Delete state?",
@@ -177,7 +183,9 @@ var defaultMessages = {
177
183
  noneAutomated: "No criterion. This automated transition will fire as soon as the entity reaches this state.",
178
184
  noneAutomatedWarning: "Automated transitions without criteria should usually be last in the transition order.",
179
185
  cancel: "Cancel",
180
- applyModal: "Apply"
186
+ applyModal: "Apply",
187
+ revert: "Revert",
188
+ collapse: "Collapse"
181
189
  }
182
190
  };
183
191
 
@@ -3360,7 +3368,10 @@ var smallSelectStyle = {
3360
3368
  };
3361
3369
 
3362
3370
  // src/inspector/AnnotationsField.tsx
3363
- import { useEffect as useEffect3, useRef as useRef5, useState as useState6 } from "react";
3371
+ import { useEffect as useEffect4, useRef as useRef6, useState as useState6 } from "react";
3372
+
3373
+ // src/inspector/JsonMonacoField.tsx
3374
+ import { useEffect as useEffect3, useRef as useRef5 } from "react";
3364
3375
 
3365
3376
  // src/inspector/CriterionMonacoContext.tsx
3366
3377
  import { createContext as createContext3, useContext as useContext4 } from "react";
@@ -3385,6 +3396,127 @@ function installMonacoCancellationFilter() {
3385
3396
  }
3386
3397
  installMonacoCancellationFilter();
3387
3398
 
3399
+ // src/inspector/JsonMonacoField.tsx
3400
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
3401
+ function reformat(text) {
3402
+ try {
3403
+ return JSON.stringify(JSON.parse(text), null, 2);
3404
+ } catch {
3405
+ return null;
3406
+ }
3407
+ }
3408
+ function JsonMonacoField(props) {
3409
+ const monaco = useCriterionMonaco();
3410
+ const messages = useMessages();
3411
+ const onFormat = () => {
3412
+ const next = reformat(props.buffer);
3413
+ if (next !== null && next !== props.buffer) props.onChange(next);
3414
+ };
3415
+ return /* @__PURE__ */ jsxs6("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
3416
+ /* @__PURE__ */ jsx7("div", { style: { display: "flex", justifyContent: "flex-end" }, children: /* @__PURE__ */ jsx7(
3417
+ "button",
3418
+ {
3419
+ type: "button",
3420
+ onClick: onFormat,
3421
+ disabled: props.disabled,
3422
+ "data-testid": `${props.testId}-format`,
3423
+ style: { ...ghostBtnStyle, fontSize: 11, padding: "2px 8px" },
3424
+ children: messages.inspector.format
3425
+ }
3426
+ ) }),
3427
+ monaco ? /* @__PURE__ */ jsx7(MonacoPane, { ...props, monaco }) : /* @__PURE__ */ jsx7(
3428
+ "textarea",
3429
+ {
3430
+ value: props.buffer,
3431
+ disabled: props.disabled,
3432
+ rows: 12,
3433
+ "data-testid": props.testId,
3434
+ onChange: (e) => props.onChange(e.target.value),
3435
+ style: {
3436
+ fontFamily: fonts.mono,
3437
+ fontSize: 12,
3438
+ padding: 8,
3439
+ whiteSpace: "pre-wrap",
3440
+ wordBreak: "break-word",
3441
+ border: `1px solid ${colors.border}`,
3442
+ borderRadius: radii.sm,
3443
+ background: colors.surface,
3444
+ resize: "vertical",
3445
+ minHeight: props.minHeightPx ?? 120
3446
+ }
3447
+ }
3448
+ )
3449
+ ] });
3450
+ }
3451
+ function MonacoPane({
3452
+ monaco,
3453
+ buffer,
3454
+ disabled,
3455
+ modelUri,
3456
+ onChange,
3457
+ seed,
3458
+ registerSchema,
3459
+ minHeightPx = 120,
3460
+ maxHeightPx = 480,
3461
+ testId
3462
+ }) {
3463
+ const containerRef = useRef5(null);
3464
+ const editorRef = useRef5(null);
3465
+ const modelRef = useRef5(null);
3466
+ useEffect3(() => {
3467
+ if (!containerRef.current || editorRef.current) return;
3468
+ const model = monaco.editor.createModel(buffer, "json", monaco.Uri.parse(modelUri));
3469
+ modelRef.current = model;
3470
+ const editor = monaco.editor.create(containerRef.current, {
3471
+ model,
3472
+ automaticLayout: true,
3473
+ minimap: { enabled: false },
3474
+ wordWrap: "on",
3475
+ fontSize: 13,
3476
+ tabSize: 2,
3477
+ scrollBeyondLastLine: false,
3478
+ theme: "vs",
3479
+ readOnly: disabled
3480
+ });
3481
+ editorRef.current = editor;
3482
+ installMonacoCancellationFilter();
3483
+ const schemaHandle = registerSchema?.(monaco) ?? null;
3484
+ const applyHeight = () => {
3485
+ const h = Math.min(Math.max(editor.getContentHeight?.() ?? minHeightPx, minHeightPx), maxHeightPx);
3486
+ if (containerRef.current) containerRef.current.style.height = `${h}px`;
3487
+ editor.layout?.();
3488
+ };
3489
+ applyHeight();
3490
+ const sizeSub = editor.onDidContentSizeChange?.(applyHeight) ?? { dispose() {
3491
+ } };
3492
+ const sub = model.onDidChangeContent(() => onChange(model.getValue()));
3493
+ return () => {
3494
+ sub.dispose();
3495
+ sizeSub.dispose();
3496
+ schemaHandle?.dispose();
3497
+ editor.dispose();
3498
+ editorRef.current = null;
3499
+ model.dispose();
3500
+ modelRef.current = null;
3501
+ };
3502
+ }, [monaco, modelUri]);
3503
+ useEffect3(() => {
3504
+ const model = modelRef.current;
3505
+ if (model && seed !== void 0 && model.getValue() !== seed) model.setValue(seed);
3506
+ }, [seed]);
3507
+ useEffect3(() => {
3508
+ editorRef.current?.updateOptions?.({ readOnly: disabled });
3509
+ }, [disabled]);
3510
+ return /* @__PURE__ */ jsx7(
3511
+ "div",
3512
+ {
3513
+ ref: containerRef,
3514
+ "data-testid": testId,
3515
+ style: { height: minHeightPx, border: `1px solid ${colors.border}`, borderRadius: radii.sm }
3516
+ }
3517
+ );
3518
+ }
3519
+
3388
3520
  // src/inspector/annotationsJson.ts
3389
3521
  import { ANNOTATIONS_MAX_BYTES } from "@cyoda/workflow-core";
3390
3522
  function annotationsModelUri(key) {
@@ -3417,14 +3549,14 @@ function parseAnnotationsJson(text) {
3417
3549
  }
3418
3550
 
3419
3551
  // src/inspector/AnnotationsField.tsx
3420
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
3552
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
3421
3553
  var pretty = (v) => JSON.stringify(v, null, 2);
3422
3554
  function AnnotationsField(props) {
3423
3555
  const messages = useMessages();
3424
3556
  if (props.value === void 0) {
3425
- return /* @__PURE__ */ jsxs6("div", { style: sectionStyle, children: [
3426
- props.showLabel !== false && /* @__PURE__ */ jsx7(SectionLabel, {}),
3427
- !props.disabled && /* @__PURE__ */ jsx7(
3557
+ return /* @__PURE__ */ jsxs7("div", { style: sectionStyle, children: [
3558
+ props.showLabel !== false && /* @__PURE__ */ jsx8(SectionLabel, {}),
3559
+ !props.disabled && /* @__PURE__ */ jsx8(
3428
3560
  "button",
3429
3561
  {
3430
3562
  type: "button",
@@ -3436,7 +3568,7 @@ function AnnotationsField(props) {
3436
3568
  )
3437
3569
  ] });
3438
3570
  }
3439
- return /* @__PURE__ */ jsx7(AnnotationsEditor, { ...props, value: props.value }, props.modelKey);
3571
+ return /* @__PURE__ */ jsx8(AnnotationsEditor, { ...props, value: props.value }, props.modelKey);
3440
3572
  }
3441
3573
  function AnnotationsEditor({
3442
3574
  value,
@@ -3447,11 +3579,10 @@ function AnnotationsEditor({
3447
3579
  showLabel
3448
3580
  }) {
3449
3581
  const messages = useMessages();
3450
- const monaco = useCriterionMonaco();
3451
3582
  const [buffer, setBuffer] = useState6(() => pretty(value));
3452
3583
  const [docChanged, setDocChanged] = useState6(false);
3453
- const prevValueRef = useRef5(value);
3454
- useEffect3(() => {
3584
+ const prevValueRef = useRef6(value);
3585
+ useEffect4(() => {
3455
3586
  if (sameJson(prevValueRef.current, value)) return;
3456
3587
  const parsed = parseAnnotationsJson(buffer).annotations;
3457
3588
  if (parsed !== null && sameJson(parsed, value)) {
@@ -3467,6 +3598,7 @@ function AnnotationsEditor({
3467
3598
  const result = parseAnnotationsJson(buffer);
3468
3599
  const dirty = result.annotations !== null && !sameJson(result.annotations, value);
3469
3600
  const applyEnabled = !disabled && result.annotations !== null && dirty;
3601
+ const canRevert = buffer !== pretty(value);
3470
3602
  const apply = () => {
3471
3603
  if (!applyEnabled || result.annotations === null) return;
3472
3604
  onCommit(result.annotations);
@@ -3476,32 +3608,23 @@ function AnnotationsEditor({
3476
3608
  setBuffer(pretty(value));
3477
3609
  setDocChanged(false);
3478
3610
  };
3479
- return /* @__PURE__ */ jsxs6("div", { style: sectionStyle, children: [
3480
- showLabel !== false && /* @__PURE__ */ jsx7(SectionLabel, {}),
3481
- monaco ? /* @__PURE__ */ jsx7(
3482
- MonacoJsonPane,
3611
+ return /* @__PURE__ */ jsxs7("div", { style: sectionStyle, children: [
3612
+ showLabel !== false && /* @__PURE__ */ jsx8(SectionLabel, {}),
3613
+ /* @__PURE__ */ jsx8(
3614
+ JsonMonacoField,
3483
3615
  {
3484
- monaco,
3485
3616
  buffer,
3486
3617
  disabled,
3487
3618
  modelUri: annotationsModelUri(modelKey),
3488
- onChange: setBuffer
3489
- }
3490
- ) : /* @__PURE__ */ jsx7(
3491
- "textarea",
3492
- {
3493
- value: buffer,
3494
- disabled,
3495
- rows: 12,
3496
- "data-testid": "annotations-json-editor",
3497
- style: textareaStyle,
3498
- onChange: (e) => setBuffer(e.target.value)
3619
+ onChange: setBuffer,
3620
+ seed: buffer,
3621
+ testId: "annotations-json-editor"
3499
3622
  }
3500
3623
  ),
3501
- result.error && /* @__PURE__ */ jsx7("div", { role: "alert", "data-testid": "annotations-error", style: errorStyle, children: result.error }),
3502
- docChanged && /* @__PURE__ */ jsx7("div", { role: "alert", "data-testid": "annotations-doc-changed", style: warnStyle, children: messages.inspector.annotationsDocChanged }),
3503
- !disabled && /* @__PURE__ */ jsxs6("div", { style: { display: "flex", gap: 6, flexWrap: "wrap" }, children: [
3504
- /* @__PURE__ */ jsx7(
3624
+ result.error && /* @__PURE__ */ jsx8("div", { role: "alert", "data-testid": "annotations-error", style: errorStyle, children: result.error }),
3625
+ docChanged && /* @__PURE__ */ jsx8("div", { role: "alert", "data-testid": "annotations-doc-changed", style: warnStyle, children: messages.inspector.annotationsDocChanged }),
3626
+ !disabled && /* @__PURE__ */ jsxs7("div", { style: { display: "flex", gap: 6, flexWrap: "wrap" }, children: [
3627
+ /* @__PURE__ */ jsx8(
3505
3628
  "button",
3506
3629
  {
3507
3630
  type: "button",
@@ -3512,77 +3635,16 @@ function AnnotationsEditor({
3512
3635
  children: messages.inspector.annotationsApply
3513
3636
  }
3514
3637
  ),
3515
- /* @__PURE__ */ jsx7("button", { type: "button", onClick: revert, disabled: !dirty, style: ghostBtn, "data-testid": "inspector-annotations-revert", children: messages.inspector.annotationsRevert }),
3516
- /* @__PURE__ */ jsx7("button", { type: "button", onClick: onRemove, style: dangerBtn, "data-testid": "inspector-annotations-remove", children: messages.inspector.annotationsRemove })
3638
+ /* @__PURE__ */ jsx8("button", { type: "button", onClick: revert, disabled: !canRevert, style: ghostBtn, "data-testid": "inspector-annotations-revert", children: messages.inspector.annotationsRevert }),
3639
+ /* @__PURE__ */ jsx8("button", { type: "button", onClick: onRemove, style: dangerBtn, "data-testid": "inspector-annotations-remove", children: messages.inspector.annotationsRemove })
3517
3640
  ] })
3518
3641
  ] });
3519
3642
  }
3520
- function MonacoJsonPane({
3521
- monaco,
3522
- buffer,
3523
- disabled,
3524
- modelUri,
3525
- onChange
3526
- }) {
3527
- const containerRef = useRef5(null);
3528
- const editorRef = useRef5(null);
3529
- const modelRef = useRef5(null);
3530
- useEffect3(() => {
3531
- if (!containerRef.current || editorRef.current) return;
3532
- const model = monaco.editor.createModel(buffer, "json", monaco.Uri.parse(modelUri));
3533
- modelRef.current = model;
3534
- const editor = monaco.editor.create(containerRef.current, {
3535
- model,
3536
- automaticLayout: true,
3537
- minimap: { enabled: false },
3538
- fontSize: 13,
3539
- tabSize: 2,
3540
- scrollBeyondLastLine: false,
3541
- theme: "vs",
3542
- readOnly: disabled
3543
- });
3544
- editorRef.current = editor;
3545
- installMonacoCancellationFilter();
3546
- const sub = model.onDidChangeContent(() => onChange(model.getValue()));
3547
- return () => {
3548
- sub.dispose();
3549
- editor.dispose();
3550
- editorRef.current = null;
3551
- model.dispose();
3552
- modelRef.current = null;
3553
- };
3554
- }, [monaco, modelUri]);
3555
- useEffect3(() => {
3556
- const model = modelRef.current;
3557
- if (model && model.getValue() !== buffer) model.setValue(buffer);
3558
- }, [buffer]);
3559
- useEffect3(() => {
3560
- editorRef.current?.updateOptions?.({ readOnly: disabled });
3561
- }, [disabled]);
3562
- return /* @__PURE__ */ jsx7(
3563
- "div",
3564
- {
3565
- ref: containerRef,
3566
- "data-testid": "annotations-json-editor",
3567
- style: { height: 220, border: `1px solid ${colors.border}`, borderRadius: radii.sm }
3568
- }
3569
- );
3570
- }
3571
3643
  function SectionLabel() {
3572
3644
  const messages = useMessages();
3573
- return /* @__PURE__ */ jsx7("span", { style: { fontSize: 11, fontWeight: 600, letterSpacing: "0.08em", textTransform: "uppercase", color: colors.textSecondary }, children: messages.inspector.annotations });
3645
+ return /* @__PURE__ */ jsx8("span", { style: { fontSize: 11, fontWeight: 600, letterSpacing: "0.08em", textTransform: "uppercase", color: colors.textSecondary }, children: messages.inspector.annotations });
3574
3646
  }
3575
3647
  var sectionStyle = { display: "flex", flexDirection: "column", gap: 8 };
3576
- var textareaStyle = {
3577
- fontFamily: fonts.mono,
3578
- fontSize: 12,
3579
- padding: 8,
3580
- minHeight: 180,
3581
- border: `1px solid ${colors.border}`,
3582
- borderRadius: radii.sm,
3583
- background: "white",
3584
- resize: "vertical"
3585
- };
3586
3648
  var ghostBtn = { padding: "6px 10px", background: "white", border: `1px solid ${colors.border}`, borderRadius: radii.sm, fontSize: 12, cursor: "pointer" };
3587
3649
  var primaryBtn = { ...ghostBtn, background: colors.primary, color: "white", borderColor: colors.primary };
3588
3650
  var disabledBtn = { ...primaryBtn, opacity: 0.5, cursor: "not-allowed" };
@@ -3591,15 +3653,15 @@ var errorStyle = { color: colors.danger, fontSize: 11 };
3591
3653
  var warnStyle = { color: colors.warning, fontSize: 11 };
3592
3654
 
3593
3655
  // src/inspector/WorkflowForm.tsx
3594
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
3656
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
3595
3657
  function WorkflowForm({
3596
3658
  workflow,
3597
3659
  disabled,
3598
3660
  onDispatch
3599
3661
  }) {
3600
3662
  const messages = useMessages();
3601
- return /* @__PURE__ */ jsxs7(FieldGroup, { title: messages.inspector.properties, children: [
3602
- /* @__PURE__ */ jsx8(
3663
+ return /* @__PURE__ */ jsxs8(FieldGroup, { title: messages.inspector.properties, children: [
3664
+ /* @__PURE__ */ jsx9(
3603
3665
  TextField,
3604
3666
  {
3605
3667
  label: messages.inspector.name,
@@ -3609,7 +3671,7 @@ function WorkflowForm({
3609
3671
  testId: "inspector-workflow-name"
3610
3672
  }
3611
3673
  ),
3612
- /* @__PURE__ */ jsx8(
3674
+ /* @__PURE__ */ jsx9(
3613
3675
  TextField,
3614
3676
  {
3615
3677
  label: messages.inspector.version,
@@ -3624,7 +3686,7 @@ function WorkflowForm({
3624
3686
  testId: "inspector-workflow-version"
3625
3687
  }
3626
3688
  ),
3627
- /* @__PURE__ */ jsx8(
3689
+ /* @__PURE__ */ jsx9(
3628
3690
  TextField,
3629
3691
  {
3630
3692
  label: messages.inspector.description,
@@ -3640,7 +3702,7 @@ function WorkflowForm({
3640
3702
  testId: "inspector-workflow-desc"
3641
3703
  }
3642
3704
  ),
3643
- /* @__PURE__ */ jsx8(
3705
+ /* @__PURE__ */ jsx9(
3644
3706
  CheckboxField,
3645
3707
  {
3646
3708
  label: messages.inspector.active,
@@ -3654,7 +3716,7 @@ function WorkflowForm({
3654
3716
  testId: "inspector-workflow-active"
3655
3717
  }
3656
3718
  ),
3657
- /* @__PURE__ */ jsx8(
3719
+ /* @__PURE__ */ jsx9(
3658
3720
  TextField,
3659
3721
  {
3660
3722
  label: messages.inspector.initialState,
@@ -3669,7 +3731,7 @@ function WorkflowForm({
3669
3731
  testId: "inspector-workflow-initial"
3670
3732
  }
3671
3733
  ),
3672
- /* @__PURE__ */ jsx8(
3734
+ /* @__PURE__ */ jsx9(
3673
3735
  AnnotationsField,
3674
3736
  {
3675
3737
  value: workflow.annotations,
@@ -3685,7 +3747,7 @@ function WorkflowForm({
3685
3747
  // src/inspector/StateForm.tsx
3686
3748
  import { useState as useState7 } from "react";
3687
3749
  import { NAME_REGEX } from "@cyoda/workflow-core";
3688
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
3750
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
3689
3751
  function StateForm({
3690
3752
  workflow,
3691
3753
  stateCode,
@@ -3719,8 +3781,8 @@ function StateForm({
3719
3781
  }
3720
3782
  onDispatch({ op: "renameState", workflow: workflow.name, from: stateCode, to: next });
3721
3783
  };
3722
- return /* @__PURE__ */ jsxs8(FieldGroup, { title: messages.inspector.properties, children: [
3723
- /* @__PURE__ */ jsx9(
3784
+ return /* @__PURE__ */ jsxs9(FieldGroup, { title: messages.inspector.properties, children: [
3785
+ /* @__PURE__ */ jsx10(
3724
3786
  TextField,
3725
3787
  {
3726
3788
  label: messages.inspector.name,
@@ -3731,19 +3793,19 @@ function StateForm({
3731
3793
  testId: "inspector-state-name"
3732
3794
  }
3733
3795
  ),
3734
- renameError && /* @__PURE__ */ jsx9("div", { role: "alert", style: { color: colors.danger, fontSize: 12 }, children: renameError }),
3735
- (isInitial || isTerminal || isUnreachable) && /* @__PURE__ */ jsxs8("div", { style: { display: "flex", gap: 6, flexWrap: "wrap" }, children: [
3736
- isInitial && /* @__PURE__ */ jsx9(StateBadge, { color: "#15803d", bg: "#f0fdf4", label: "Initial" }),
3737
- isTerminal && /* @__PURE__ */ jsx9(StateBadge, { color: "#0369a1", bg: "#eff6ff", label: "Terminal" }),
3738
- isUnreachable && /* @__PURE__ */ jsx9(StateBadge, { color: colors.warning, bg: colors.warningBg, label: "Unreachable" })
3796
+ renameError && /* @__PURE__ */ jsx10("div", { role: "alert", style: { color: colors.danger, fontSize: 12 }, children: renameError }),
3797
+ (isInitial || isTerminal || isUnreachable) && /* @__PURE__ */ jsxs9("div", { style: { display: "flex", gap: 6, flexWrap: "wrap" }, children: [
3798
+ isInitial && /* @__PURE__ */ jsx10(StateBadge, { color: "#15803d", bg: "#f0fdf4", label: "Initial" }),
3799
+ isTerminal && /* @__PURE__ */ jsx10(StateBadge, { color: "#0369a1", bg: "#eff6ff", label: "Terminal" }),
3800
+ isUnreachable && /* @__PURE__ */ jsx10(StateBadge, { color: colors.warning, bg: colors.warningBg, label: "Unreachable" })
3739
3801
  ] }),
3740
- /* @__PURE__ */ jsxs8("div", { style: { fontSize: 12, color: colors.textSecondary }, children: [
3802
+ /* @__PURE__ */ jsxs9("div", { style: { fontSize: 12, color: colors.textSecondary }, children: [
3741
3803
  outgoing,
3742
3804
  " outgoing \xB7 ",
3743
3805
  incoming,
3744
3806
  " incoming"
3745
3807
  ] }),
3746
- !isInitial && !disabled && /* @__PURE__ */ jsx9(
3808
+ !isInitial && !disabled && /* @__PURE__ */ jsx10(
3747
3809
  "button",
3748
3810
  {
3749
3811
  type: "button",
@@ -3753,7 +3815,7 @@ function StateForm({
3753
3815
  children: "Set as Initial State"
3754
3816
  }
3755
3817
  ),
3756
- issues && issues.length > 0 && /* @__PURE__ */ jsx9("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: issues.map((issue, i) => /* @__PURE__ */ jsx9(
3818
+ issues && issues.length > 0 && /* @__PURE__ */ jsx10("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: issues.map((issue, i) => /* @__PURE__ */ jsx10(
3757
3819
  "div",
3758
3820
  {
3759
3821
  role: "alert",
@@ -3769,7 +3831,7 @@ function StateForm({
3769
3831
  },
3770
3832
  `${issue.code}-${i}`
3771
3833
  )) }),
3772
- /* @__PURE__ */ jsx9(
3834
+ /* @__PURE__ */ jsx10(
3773
3835
  AnnotationsField,
3774
3836
  {
3775
3837
  value: state.annotations,
@@ -3779,7 +3841,7 @@ function StateForm({
3779
3841
  onRemove: () => onDispatch({ op: "setAnnotations", target: { kind: "state", workflow: workflow.name, stateCode } })
3780
3842
  }
3781
3843
  ),
3782
- /* @__PURE__ */ jsx9(
3844
+ /* @__PURE__ */ jsx10(
3783
3845
  "button",
3784
3846
  {
3785
3847
  type: "button",
@@ -3793,7 +3855,7 @@ function StateForm({
3793
3855
  ] });
3794
3856
  }
3795
3857
  function StateBadge({ color, bg, label }) {
3796
- return /* @__PURE__ */ jsx9(
3858
+ return /* @__PURE__ */ jsx10(
3797
3859
  "span",
3798
3860
  {
3799
3861
  style: {
@@ -3846,143 +3908,12 @@ var dangerBtn2 = {
3846
3908
  };
3847
3909
 
3848
3910
  // src/inspector/TransitionForm.tsx
3849
- import { useRef as useRef8, useState as useState10 } from "react";
3911
+ import { useRef as useRef9, useState as useState10 } from "react";
3850
3912
  import { NAME_REGEX as NAME_REGEX3 } from "@cyoda/workflow-core";
3851
3913
 
3852
- // src/inspector/CriterionForm.tsx
3853
- import { useState as useState8 } from "react";
3854
-
3855
- // src/modals/DeleteStateModal.tsx
3856
- import { useEffect as useEffect4, useMemo as useMemo3, useRef as useRef6 } from "react";
3857
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
3858
- function countAffected(doc, workflow, stateCode) {
3859
- let outgoing = 0;
3860
- let incoming = 0;
3861
- const wf = doc.session.workflows.find((w) => w.name === workflow);
3862
- if (!wf) return { outgoing, incoming };
3863
- for (const [code, state] of Object.entries(wf.states)) {
3864
- for (const t of state.transitions) {
3865
- if (code === stateCode) outgoing++;
3866
- if (t.next === stateCode && code !== stateCode) incoming++;
3867
- }
3868
- }
3869
- return { outgoing, incoming };
3870
- }
3871
- function DeleteStateModal({
3872
- document: doc,
3873
- workflow,
3874
- stateCode,
3875
- onConfirm,
3876
- onCancel
3877
- }) {
3878
- const messages = useMessages();
3879
- const counts = useMemo3(
3880
- () => countAffected(doc, workflow, stateCode),
3881
- [doc, workflow, stateCode]
3882
- );
3883
- return /* @__PURE__ */ jsxs9(ModalFrame, { onCancel, children: [
3884
- /* @__PURE__ */ jsx10("h2", { style: { margin: 0, fontSize: 16 }, children: messages.confirmDelete.title }),
3885
- /* @__PURE__ */ jsx10("p", { style: { margin: "12px 0", fontSize: 13, color: colors.textSecondary }, children: messages.confirmDelete.message }),
3886
- /* @__PURE__ */ jsxs9("div", { style: { padding: 8, background: colors.surfaceMuted, border: `1px solid ${colors.borderSubtle}`, borderRadius: radii.sm, fontSize: 13 }, children: [
3887
- /* @__PURE__ */ jsx10("strong", { children: stateCode }),
3888
- /* @__PURE__ */ jsxs9("div", { style: { color: colors.textSecondary }, children: [
3889
- messages.confirmDelete.transitionsAffected,
3890
- ": ",
3891
- counts.outgoing + counts.incoming
3892
- ] })
3893
- ] }),
3894
- /* @__PURE__ */ jsxs9("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 16 }, children: [
3895
- /* @__PURE__ */ jsx10("button", { type: "button", onClick: onCancel, style: ghostBtn3, "data-testid": "modal-delete-cancel", children: messages.confirmDelete.cancel }),
3896
- /* @__PURE__ */ jsx10("button", { type: "button", onClick: onConfirm, style: dangerBtn3, "data-testid": "modal-delete-confirm", children: messages.confirmDelete.confirm })
3897
- ] })
3898
- ] });
3899
- }
3900
- function ModalFrame({
3901
- children,
3902
- onCancel,
3903
- labelledBy
3904
- }) {
3905
- const frameRef = useRef6(null);
3906
- const previousFocusRef = useRef6(null);
3907
- useEffect4(() => {
3908
- previousFocusRef.current = document.activeElement ?? null;
3909
- const node = frameRef.current;
3910
- if (node) {
3911
- const focusable = node.querySelector(
3912
- 'input, select, textarea, button, [tabindex]:not([tabindex="-1"])'
3913
- );
3914
- (focusable ?? node).focus();
3915
- }
3916
- return () => {
3917
- previousFocusRef.current?.focus?.();
3918
- };
3919
- }, []);
3920
- return /* @__PURE__ */ jsx10(
3921
- "div",
3922
- {
3923
- onClick: onCancel,
3924
- onKeyDown: (e) => {
3925
- if (e.key === "Escape") {
3926
- e.stopPropagation();
3927
- onCancel();
3928
- }
3929
- },
3930
- style: {
3931
- position: "fixed",
3932
- inset: 0,
3933
- background: "rgba(15,23,42,0.4)",
3934
- display: "flex",
3935
- alignItems: "center",
3936
- justifyContent: "center",
3937
- zIndex: 1e3
3938
- },
3939
- "data-testid": "modal-backdrop",
3940
- children: /* @__PURE__ */ jsx10(
3941
- "div",
3942
- {
3943
- ref: frameRef,
3944
- role: "dialog",
3945
- "aria-modal": "true",
3946
- "aria-labelledby": labelledBy,
3947
- tabIndex: -1,
3948
- onClick: (e) => e.stopPropagation(),
3949
- style: {
3950
- background: "white",
3951
- borderRadius: radii.md,
3952
- padding: 20,
3953
- minWidth: 340,
3954
- boxShadow: "0 10px 30px rgba(15,23,42,0.25)",
3955
- outline: "none",
3956
- fontFamily: fonts.sans,
3957
- color: colors.textPrimary
3958
- },
3959
- "data-testid": "modal-frame",
3960
- children
3961
- }
3962
- )
3963
- }
3964
- );
3965
- }
3966
- var ghostBtn3 = {
3967
- padding: "6px 12px",
3968
- background: "white",
3969
- border: `1px solid ${colors.border}`,
3970
- borderRadius: radii.sm,
3971
- fontSize: 13,
3972
- cursor: "pointer"
3973
- };
3974
- var dangerBtn3 = {
3975
- ...ghostBtn3,
3976
- background: colors.danger,
3977
- color: "white",
3978
- borderColor: colors.danger
3979
- };
3980
-
3981
- // src/inspector/CriterionJsonEditor.tsx
3982
- import { useEffect as useEffect5, useRef as useRef7 } from "react";
3983
- import {
3984
- registerCriterionSchema
3985
- } from "@cyoda/workflow-monaco";
3914
+ // src/inspector/CriterionField.tsx
3915
+ import { useEffect as useEffect5, useRef as useRef7, useState as useState8 } from "react";
3916
+ import { registerCriterionSchema } from "@cyoda/workflow-monaco";
3986
3917
 
3987
3918
  // src/inspector/criterionJson.ts
3988
3919
  import { CriterionSchema, criterionBlockingError } from "@cyoda/workflow-core";
@@ -4012,396 +3943,269 @@ function parseCriterionJson(text) {
4012
3943
  if (typeof raw === "object" && raw !== null && typeof raw.type === "string") {
4013
3944
  try {
4014
3945
  friendly = criterionBlockingError(raw);
4015
- } catch {
4016
- friendly = null;
4017
- }
4018
- }
4019
- return { criterion: null, error: friendly ?? zodMessage(res.error) };
4020
- }
4021
-
4022
- // src/inspector/CriterionJsonEditor.tsx
4023
- import { jsx as jsx11 } from "react/jsx-runtime";
4024
- function CriterionJsonEditor({ value, disabled, modelKey, onChange }) {
4025
- const monaco = useCriterionMonaco();
4026
- const onChangeRef = useRef7(onChange);
4027
- onChangeRef.current = onChange;
4028
- const initialText = useRef7(JSON.stringify(value, null, 2)).current;
4029
- if (monaco) {
4030
- return /* @__PURE__ */ jsx11(
4031
- MonacoCriterionEditor,
4032
- {
4033
- monaco,
4034
- initialText,
4035
- disabled,
4036
- modelKey,
4037
- onChangeRef
4038
- }
4039
- );
4040
- }
4041
- return /* @__PURE__ */ jsx11(
4042
- TextareaCriterionEditor,
4043
- {
4044
- initialText,
4045
- disabled,
4046
- onChangeRef
4047
- }
4048
- );
4049
- }
4050
- function TextareaCriterionEditor({
4051
- initialText,
4052
- disabled,
4053
- onChangeRef
4054
- }) {
4055
- useEffect5(() => {
4056
- onChangeRef.current(parseCriterionJson(initialText));
4057
- }, [initialText, onChangeRef]);
4058
- return /* @__PURE__ */ jsx11(
4059
- "textarea",
4060
- {
4061
- defaultValue: initialText,
4062
- disabled,
4063
- rows: 16,
4064
- "data-testid": "criterion-json-editor",
4065
- style: jsonTextAreaStyle,
4066
- onChange: (e) => onChangeRef.current(parseCriterionJson(e.target.value))
4067
- }
4068
- );
4069
- }
4070
- function MonacoCriterionEditor({
4071
- monaco,
4072
- initialText,
4073
- disabled,
4074
- modelKey,
4075
- onChangeRef
4076
- }) {
4077
- const containerRef = useRef7(null);
4078
- const editorRef = useRef7(null);
4079
- useEffect5(() => {
4080
- if (!containerRef.current || editorRef.current) return;
4081
- const model = monaco.editor.createModel(
4082
- initialText,
4083
- "json",
4084
- monaco.Uri.parse(criterionModelUri(modelKey))
4085
- );
4086
- const editor = monaco.editor.create(containerRef.current, {
4087
- model,
4088
- automaticLayout: true,
4089
- minimap: { enabled: false },
4090
- fontSize: 13,
4091
- tabSize: 2,
4092
- scrollBeyondLastLine: false,
4093
- theme: "vs",
4094
- readOnly: disabled
4095
- });
4096
- editorRef.current = editor;
4097
- installMonacoCancellationFilter();
4098
- const schemaHandle = registerCriterionSchema(monaco);
4099
- const report = () => onChangeRef.current(parseCriterionJson(model.getValue()));
4100
- report();
4101
- const sub = model.onDidChangeContent(report);
4102
- return () => {
4103
- sub.dispose();
4104
- schemaHandle.dispose();
4105
- editor.dispose();
4106
- editorRef.current = null;
4107
- model.dispose();
4108
- };
4109
- }, [monaco, modelKey]);
4110
- useEffect5(() => {
4111
- editorRef.current?.updateOptions?.({ readOnly: disabled });
4112
- }, [disabled]);
4113
- return /* @__PURE__ */ jsx11(
4114
- "div",
4115
- {
4116
- ref: containerRef,
4117
- "data-testid": "criterion-json-editor",
4118
- style: { height: 320, border: `1px solid ${colors.border}`, borderRadius: radii.sm }
4119
- }
4120
- );
4121
- }
4122
- var jsonTextAreaStyle = {
4123
- fontFamily: fonts.mono,
4124
- fontSize: 12,
4125
- padding: 8,
4126
- borderWidth: 1,
4127
- borderStyle: "solid",
4128
- borderColor: colors.border,
4129
- borderRadius: radii.sm,
4130
- background: "white",
4131
- resize: "vertical"
4132
- };
4133
-
4134
- // src/inspector/CriterionForm.tsx
4135
- import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
4136
- function defaultCriterion(type) {
4137
- switch (type) {
4138
- case "simple":
4139
- return { type: "simple", jsonPath: "", operation: "EQUALS" };
4140
- case "group":
4141
- return { type: "group", operator: "AND", conditions: [] };
4142
- case "function":
4143
- return { type: "function", function: { name: "" } };
4144
- case "lifecycle":
4145
- return { type: "lifecycle", field: "state", operation: "EQUALS" };
4146
- case "array":
4147
- return { type: "array", jsonPath: "", operation: "EQUALS", value: [] };
4148
- }
4149
- }
4150
- function CriterionSection({
4151
- host,
4152
- stateCode,
4153
- transitionName,
4154
- targetState,
4155
- manual,
4156
- criterion,
4157
- disabled,
4158
- onDispatch,
4159
- onSelectionChange
4160
- }) {
4161
- const messages = useMessages();
4162
- const [modalOpen, setModalOpen] = useState8(false);
4163
- const path = ["criterion"];
4164
- const removeCriterion = () => {
4165
- onDispatch({ op: "setCriterion", host, path, criterion: void 0 });
4166
- if (host.kind === "transition") {
4167
- onSelectionChange?.({ kind: "transition", transitionUuid: host.transitionUuid });
4168
- }
4169
- };
4170
- return /* @__PURE__ */ jsxs10(Fragment4, { children: [
4171
- /* @__PURE__ */ jsx12(
4172
- CriterionSummaryCard,
4173
- {
4174
- criterion,
4175
- disabled,
4176
- manual,
4177
- onAdd: () => setModalOpen(true),
4178
- onEdit: () => setModalOpen(true),
4179
- onRemove: removeCriterion
4180
- }
4181
- ),
4182
- modalOpen && /* @__PURE__ */ jsx12(
4183
- CriterionEditorModal,
4184
- {
4185
- title: criterion ? messages.criterion.editTitle : messages.criterion.addTitle,
4186
- context: `${stateCode ?? host.workflow} \u2192 ${transitionName ?? "transition"} \u2192 ${targetState ?? ""}`,
4187
- host,
4188
- path,
4189
- initialCriterion: criterion,
4190
- disabled,
4191
- onDispatch,
4192
- onCancel: () => setModalOpen(false),
4193
- onApplied: () => {
4194
- setModalOpen(false);
4195
- if (host.kind === "transition") {
4196
- const selection = {
4197
- kind: "transition",
4198
- transitionUuid: host.transitionUuid
4199
- };
4200
- onSelectionChange?.(selection);
4201
- window.setTimeout(() => onSelectionChange?.(selection), 100);
4202
- }
4203
- }
4204
- }
4205
- )
4206
- ] });
3946
+ } catch {
3947
+ friendly = null;
3948
+ }
3949
+ }
3950
+ return { criterion: null, error: friendly ?? zodMessage(res.error) };
4207
3951
  }
4208
- function CriterionSummaryCard({
4209
- criterion,
4210
- disabled,
4211
- manual,
4212
- onAdd,
4213
- onEdit,
4214
- onRemove
4215
- }) {
4216
- const messages = useMessages();
4217
- const m = messages.criterion;
4218
- if (!criterion) {
3952
+
3953
+ // src/inspector/CriterionField.tsx
3954
+ import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
3955
+ function defaultSimpleCriterion() {
3956
+ return { type: "simple", jsonPath: "", operation: "EQUALS" };
3957
+ }
3958
+ var pretty2 = (c) => JSON.stringify(c, null, 2);
3959
+ function CriterionField(props) {
3960
+ const m = useMessages().criterion;
3961
+ if (props.value === void 0) {
4219
3962
  return /* @__PURE__ */ jsxs10("div", { style: cardStyle, "data-testid": "criterion-summary-card", children: [
4220
- /* @__PURE__ */ jsx12(SectionHeader, { label: m.heading, badge: "none" }),
4221
- /* @__PURE__ */ jsx12("p", { style: summaryTextStyle, children: manual ? m.noneManual : m.noneAutomated }),
4222
- !manual && /* @__PURE__ */ jsx12("p", { style: warningCardStyle, "data-testid": "criterion-automated-warning", children: m.noneAutomatedWarning }),
4223
- !disabled && /* @__PURE__ */ jsx12(
4224
- "button",
4225
- {
4226
- type: "button",
4227
- onClick: onAdd,
4228
- style: primaryBtn2,
4229
- "data-testid": "inspector-criterion-add",
4230
- children: m.add
4231
- }
4232
- )
3963
+ /* @__PURE__ */ jsx11("p", { style: summaryTextStyle, children: props.manual ? m.noneManual : m.noneAutomated }),
3964
+ !props.manual && /* @__PURE__ */ jsx11("p", { style: warnStyle2, "data-testid": "criterion-automated-warning", children: m.noneAutomatedWarning }),
3965
+ !props.disabled && /* @__PURE__ */ jsx11("button", { type: "button", style: primaryBtnStyle, "data-testid": "inspector-criterion-add", onClick: () => props.onCommit(defaultSimpleCriterion()), children: m.add })
4233
3966
  ] });
4234
3967
  }
3968
+ return /* @__PURE__ */ jsx11(CriterionEditor, { ...props, value: props.value }, props.modelKey);
3969
+ }
3970
+ function CriterionEditor({ value, disabled, modelKey, onCommit, onRemove }) {
3971
+ const messages = useMessages();
3972
+ const m = messages.criterion;
3973
+ const [expanded, setExpanded] = useState8(false);
3974
+ const [buffer, setBuffer] = useState8(() => pretty2(value));
3975
+ const [docChanged, setDocChanged] = useState8(false);
3976
+ const prevValueRef = useRef7(value);
3977
+ useEffect5(() => {
3978
+ if (sameJson(prevValueRef.current, value)) return;
3979
+ const parsed = parseCriterionJson(buffer).criterion;
3980
+ if (parsed !== null && sameJson(parsed, value)) {
3981
+ setDocChanged(false);
3982
+ } else if (parsed !== null && sameJson(parsed, prevValueRef.current)) {
3983
+ setBuffer(pretty2(value));
3984
+ setDocChanged(false);
3985
+ } else {
3986
+ setDocChanged(true);
3987
+ }
3988
+ prevValueRef.current = value;
3989
+ }, [value, buffer]);
3990
+ const result = parseCriterionJson(buffer);
3991
+ const dirty = result.criterion !== null && !sameJson(result.criterion, value);
3992
+ const applyEnabled = !disabled && result.criterion !== null && dirty;
3993
+ const canRevert = buffer !== pretty2(value);
3994
+ const apply = () => {
3995
+ if (!applyEnabled || result.criterion === null) return;
3996
+ onCommit(result.criterion);
3997
+ setDocChanged(false);
3998
+ setExpanded(false);
3999
+ };
4000
+ const revert = () => {
4001
+ setBuffer(pretty2(value));
4002
+ setDocChanged(false);
4003
+ };
4235
4004
  return /* @__PURE__ */ jsxs10("div", { style: cardStyle, "data-testid": "criterion-summary-card", children: [
4236
- /* @__PURE__ */ jsx12(SectionHeader, { label: m.heading, badge: criterion.type }),
4237
- /* @__PURE__ */ jsx12(CriterionCompactJson, { criterion }),
4238
- !disabled && /* @__PURE__ */ jsxs10("div", { style: { display: "flex", flexWrap: "wrap", gap: 6 }, children: [
4239
- /* @__PURE__ */ jsx12(
4240
- "button",
4005
+ /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
4006
+ /* @__PURE__ */ jsx11("span", { style: metaChipStyle, children: value.type }),
4007
+ /* @__PURE__ */ jsx11("span", { style: { flex: 1 } }),
4008
+ !disabled && !expanded && /* @__PURE__ */ jsx11("button", { type: "button", style: ghostBtnStyle, "data-testid": "inspector-criterion-edit", onClick: () => setExpanded(true), children: m.edit }),
4009
+ !disabled && /* @__PURE__ */ jsx11("button", { type: "button", style: destructiveBtnStyle, "data-testid": "inspector-criterion-remove", onClick: onRemove, children: m.remove })
4010
+ ] }),
4011
+ !expanded && /* @__PURE__ */ jsx11(CompactJson, { criterion: value }),
4012
+ expanded && /* @__PURE__ */ jsxs10(Fragment4, { children: [
4013
+ /* @__PURE__ */ jsx11(
4014
+ JsonMonacoField,
4241
4015
  {
4242
- type: "button",
4243
- onClick: onEdit,
4244
- style: ghostBtn4,
4245
- "data-testid": "inspector-criterion-edit",
4246
- children: m.edit
4016
+ buffer,
4017
+ disabled,
4018
+ modelUri: criterionModelUri(modelKey),
4019
+ onChange: setBuffer,
4020
+ seed: buffer,
4021
+ registerSchema: registerCriterionSchema,
4022
+ testId: "criterion-json-editor"
4247
4023
  }
4248
4024
  ),
4249
- /* @__PURE__ */ jsx12(
4250
- "button",
4251
- {
4252
- type: "button",
4253
- onClick: onRemove,
4254
- style: dangerBtn4,
4255
- "data-testid": "inspector-criterion-remove",
4256
- children: m.remove
4257
- }
4258
- )
4025
+ result.error && /* @__PURE__ */ jsx11("div", { role: "alert", "data-testid": "criterion-error", style: errorStyle2, children: result.error }),
4026
+ docChanged && /* @__PURE__ */ jsx11("div", { role: "alert", "data-testid": "criterion-doc-changed", style: warnLineStyle, children: messages.inspector.annotationsDocChanged }),
4027
+ !disabled && /* @__PURE__ */ jsxs10("div", { style: { display: "flex", gap: 6, flexWrap: "wrap" }, children: [
4028
+ /* @__PURE__ */ jsx11("button", { type: "button", onClick: apply, disabled: !applyEnabled, style: applyEnabled ? primaryBtnStyle : { ...primaryBtnStyle, opacity: 0.5, cursor: "not-allowed" }, "data-testid": "inspector-criterion-apply", children: m.applyModal }),
4029
+ /* @__PURE__ */ jsx11("button", { type: "button", onClick: revert, disabled: !canRevert, style: ghostBtnStyle, "data-testid": "inspector-criterion-revert", children: m.revert }),
4030
+ /* @__PURE__ */ jsx11("button", { type: "button", onClick: () => setExpanded(false), style: ghostBtnStyle, "data-testid": "inspector-criterion-collapse", children: m.collapse })
4031
+ ] })
4259
4032
  ] })
4260
4033
  ] });
4261
4034
  }
4262
- function CriterionCompactJson({ criterion }) {
4035
+ function CompactJson({ criterion }) {
4263
4036
  const text = JSON.stringify(criterion);
4264
4037
  const display = text.length > 140 ? `${text.slice(0, 137)}\u2026` : text;
4265
- return /* @__PURE__ */ jsx12(
4266
- "code",
4267
- {
4268
- "data-testid": "criterion-compact-json",
4269
- style: {
4270
- display: "block",
4271
- fontFamily: fonts.mono,
4272
- fontSize: 11,
4273
- color: colors.textSecondary,
4274
- background: colors.surfaceMuted,
4275
- padding: "6px 8px",
4276
- borderRadius: radii.sm,
4277
- whiteSpace: "pre-wrap",
4278
- wordBreak: "break-word"
4279
- },
4280
- children: display
4281
- }
4282
- );
4038
+ return /* @__PURE__ */ jsx11("code", { "data-testid": "criterion-compact-json", style: { display: "block", fontFamily: fonts.mono, fontSize: 11, color: colors.textSecondary, background: colors.surfaceMuted, padding: "6px 8px", borderRadius: radii.sm, whiteSpace: "pre-wrap", wordBreak: "break-word" }, children: display });
4283
4039
  }
4040
+ var cardStyle = { display: "flex", flexDirection: "column", gap: 8, padding: 10, border: `1px solid ${colors.border}`, borderRadius: radii.md, background: colors.surface };
4041
+ var summaryTextStyle = { margin: 0, fontSize: 12, color: colors.textSecondary, lineHeight: 1.45 };
4042
+ var warnStyle2 = { margin: 0, padding: "6px 8px", background: colors.warningBg, border: `1px solid ${colors.warningBorder}`, borderRadius: radii.sm, color: colors.warning, fontSize: 11 };
4043
+ var errorStyle2 = { color: colors.danger, fontSize: 11 };
4044
+ var warnLineStyle = { color: colors.warning, fontSize: 11 };
4045
+
4046
+ // src/inspector/CriterionForm.tsx
4047
+ import { jsx as jsx12 } from "react/jsx-runtime";
4284
4048
  function criterionModelKey(host) {
4285
4049
  if (host.kind === "transition") return `transition-${host.transitionUuid}`;
4286
4050
  if (host.kind === "processorConfig") return `processor-${host.processorUuid}`;
4287
4051
  return `host-${host.workflow}`;
4288
4052
  }
4289
- function CriterionEditorModal({
4290
- title,
4291
- context,
4053
+ function CriterionSection({
4292
4054
  host,
4293
- path,
4294
- initialCriterion,
4055
+ manual,
4056
+ criterion,
4295
4057
  disabled,
4296
4058
  onDispatch,
4297
- onCancel,
4298
- onApplied
4059
+ onSelectionChange: _onSelectionChange
4060
+ }) {
4061
+ const path = ["criterion"];
4062
+ return /* @__PURE__ */ jsx12(
4063
+ CriterionField,
4064
+ {
4065
+ value: criterion,
4066
+ manual,
4067
+ disabled,
4068
+ modelKey: criterionModelKey(host),
4069
+ onCommit: (next) => onDispatch({ op: "setCriterion", host, path, criterion: next }),
4070
+ onRemove: () => onDispatch({ op: "setCriterion", host, path, criterion: void 0 })
4071
+ }
4072
+ );
4073
+ }
4074
+
4075
+ // src/inspector/ProcessorForm.tsx
4076
+ import { useEffect as useEffect7, useState as useState9 } from "react";
4077
+ import {
4078
+ NAME_REGEX as NAME_REGEX2
4079
+ } from "@cyoda/workflow-core";
4080
+
4081
+ // src/modals/DeleteStateModal.tsx
4082
+ import { useEffect as useEffect6, useMemo as useMemo3, useRef as useRef8 } from "react";
4083
+ import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
4084
+ function countAffected(doc, workflow, stateCode) {
4085
+ let outgoing = 0;
4086
+ let incoming = 0;
4087
+ const wf = doc.session.workflows.find((w) => w.name === workflow);
4088
+ if (!wf) return { outgoing, incoming };
4089
+ for (const [code, state] of Object.entries(wf.states)) {
4090
+ for (const t of state.transitions) {
4091
+ if (code === stateCode) outgoing++;
4092
+ if (t.next === stateCode && code !== stateCode) incoming++;
4093
+ }
4094
+ }
4095
+ return { outgoing, incoming };
4096
+ }
4097
+ function DeleteStateModal({
4098
+ document: doc,
4099
+ workflow,
4100
+ stateCode,
4101
+ onConfirm,
4102
+ onCancel
4299
4103
  }) {
4300
4104
  const messages = useMessages();
4301
- const seed = initialCriterion ?? defaultCriterion("simple");
4302
- const [result, setResult] = useState8(
4303
- () => parseCriterionJson(JSON.stringify(seed))
4105
+ const counts = useMemo3(
4106
+ () => countAffected(doc, workflow, stateCode),
4107
+ [doc, workflow, stateCode]
4304
4108
  );
4305
- const modelKey = criterionModelKey(host);
4306
- const applyDisabled = disabled || result.criterion === null;
4307
- const apply = () => {
4308
- if (applyDisabled || !result.criterion) return;
4309
- onDispatch({ op: "setCriterion", host, path, criterion: result.criterion });
4310
- onApplied();
4311
- };
4312
- return /* @__PURE__ */ jsx12(ModalFrame, { onCancel, labelledBy: "criterion-modal-title", children: /* @__PURE__ */ jsxs10("div", { style: modalStyle, "data-testid": "criterion-editor-modal", children: [
4313
- /* @__PURE__ */ jsxs10("header", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
4314
- /* @__PURE__ */ jsx12("h2", { id: "criterion-modal-title", style: { margin: 0, fontSize: 18 }, children: title }),
4315
- /* @__PURE__ */ jsx12("p", { style: { margin: 0, fontSize: 12, color: colors.textTertiary }, children: context })
4109
+ return /* @__PURE__ */ jsxs11(ModalFrame, { onCancel, children: [
4110
+ /* @__PURE__ */ jsx13("h2", { style: { margin: 0, fontSize: 16 }, children: messages.confirmDelete.title }),
4111
+ /* @__PURE__ */ jsx13("p", { style: { margin: "12px 0", fontSize: 13, color: colors.textSecondary }, children: messages.confirmDelete.message }),
4112
+ /* @__PURE__ */ jsxs11("div", { style: { padding: 8, background: colors.surfaceMuted, border: `1px solid ${colors.borderSubtle}`, borderRadius: radii.sm, fontSize: 13 }, children: [
4113
+ /* @__PURE__ */ jsx13("strong", { children: stateCode }),
4114
+ /* @__PURE__ */ jsxs11("div", { style: { color: colors.textSecondary }, children: [
4115
+ messages.confirmDelete.transitionsAffected,
4116
+ ": ",
4117
+ counts.outgoing + counts.incoming
4118
+ ] })
4316
4119
  ] }),
4317
- /* @__PURE__ */ jsx12("div", { style: modalBodyStyle, children: /* @__PURE__ */ jsx12(
4318
- CriterionJsonEditor,
4319
- {
4320
- value: seed,
4321
- disabled,
4322
- modelKey,
4323
- onChange: setResult
4324
- }
4325
- ) }),
4326
- result.error && /* @__PURE__ */ jsx12("div", { role: "alert", style: errorStyle2, "data-testid": "criterion-modal-blocking-error", children: result.error }),
4327
- /* @__PURE__ */ jsxs10("footer", { style: modalFooterStyle, children: [
4328
- /* @__PURE__ */ jsx12("div", { style: { flex: 1 } }),
4329
- /* @__PURE__ */ jsx12("button", { type: "button", onClick: onCancel, style: ghostBtn4, "data-testid": "criterion-modal-cancel", children: messages.criterion.cancel }),
4330
- /* @__PURE__ */ jsx12(
4331
- "button",
4120
+ /* @__PURE__ */ jsxs11("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 16 }, children: [
4121
+ /* @__PURE__ */ jsx13("button", { type: "button", onClick: onCancel, style: ghostBtn3, "data-testid": "modal-delete-cancel", children: messages.confirmDelete.cancel }),
4122
+ /* @__PURE__ */ jsx13("button", { type: "button", onClick: onConfirm, style: dangerBtn3, "data-testid": "modal-delete-confirm", children: messages.confirmDelete.confirm })
4123
+ ] })
4124
+ ] });
4125
+ }
4126
+ function ModalFrame({
4127
+ children,
4128
+ onCancel,
4129
+ labelledBy
4130
+ }) {
4131
+ const frameRef = useRef8(null);
4132
+ const previousFocusRef = useRef8(null);
4133
+ useEffect6(() => {
4134
+ previousFocusRef.current = document.activeElement ?? null;
4135
+ const node = frameRef.current;
4136
+ if (node) {
4137
+ const focusable = node.querySelector(
4138
+ 'input, select, textarea, button, [tabindex]:not([tabindex="-1"])'
4139
+ );
4140
+ (focusable ?? node).focus();
4141
+ }
4142
+ return () => {
4143
+ previousFocusRef.current?.focus?.();
4144
+ };
4145
+ }, []);
4146
+ return /* @__PURE__ */ jsx13(
4147
+ "div",
4148
+ {
4149
+ onClick: onCancel,
4150
+ onKeyDown: (e) => {
4151
+ if (e.key === "Escape") {
4152
+ e.stopPropagation();
4153
+ onCancel();
4154
+ }
4155
+ },
4156
+ style: {
4157
+ position: "fixed",
4158
+ inset: 0,
4159
+ background: "rgba(15,23,42,0.4)",
4160
+ display: "flex",
4161
+ alignItems: "center",
4162
+ justifyContent: "center",
4163
+ zIndex: 1e3
4164
+ },
4165
+ "data-testid": "modal-backdrop",
4166
+ children: /* @__PURE__ */ jsx13(
4167
+ "div",
4332
4168
  {
4333
- type: "button",
4334
- onClick: apply,
4335
- disabled: applyDisabled,
4336
- style: applyDisabled ? disabledPrimaryBtn : primaryBtn2,
4337
- "data-testid": "criterion-modal-apply",
4338
- children: messages.criterion.applyModal
4169
+ ref: frameRef,
4170
+ role: "dialog",
4171
+ "aria-modal": "true",
4172
+ "aria-labelledby": labelledBy,
4173
+ tabIndex: -1,
4174
+ onClick: (e) => e.stopPropagation(),
4175
+ style: {
4176
+ background: "white",
4177
+ borderRadius: radii.md,
4178
+ padding: 20,
4179
+ minWidth: 340,
4180
+ boxShadow: "0 10px 30px rgba(15,23,42,0.25)",
4181
+ outline: "none",
4182
+ fontFamily: fonts.sans,
4183
+ color: colors.textPrimary
4184
+ },
4185
+ "data-testid": "modal-frame",
4186
+ children
4339
4187
  }
4340
4188
  )
4341
- ] })
4342
- ] }) });
4343
- }
4344
- function SectionHeader({ label, badge }) {
4345
- return /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
4346
- /* @__PURE__ */ jsx12("span", { style: { fontSize: 11, fontWeight: 600, letterSpacing: "0.08em", textTransform: "uppercase", color: colors.textSecondary }, children: label }),
4347
- /* @__PURE__ */ jsx12("span", { style: { fontSize: 11, padding: "1px 6px", background: colors.surfaceMuted, borderRadius: radii.pill, color: colors.textTertiary }, children: badge })
4348
- ] });
4189
+ }
4190
+ );
4349
4191
  }
4350
- var cardStyle = {
4351
- display: "flex",
4352
- flexDirection: "column",
4353
- gap: 8,
4354
- padding: 10,
4192
+ var ghostBtn3 = {
4193
+ padding: "6px 12px",
4194
+ background: "white",
4355
4195
  border: `1px solid ${colors.border}`,
4356
- borderRadius: radii.md,
4357
- background: "white"
4358
- };
4359
- var summaryTextStyle = { margin: 0, fontSize: 12, color: colors.textSecondary, lineHeight: 1.45 };
4360
- var warningCardStyle = {
4361
- margin: 0,
4362
- padding: "6px 8px",
4363
- background: colors.warningBg,
4364
- border: `1px solid ${colors.warningBorder}`,
4365
4196
  borderRadius: radii.sm,
4366
- color: colors.warning,
4367
- fontSize: 11
4368
- };
4369
- var modalStyle = {
4370
- width: "min(760px, calc(100vw - 48px))",
4371
- maxHeight: "min(760px, calc(100vh - 72px))",
4372
- display: "flex",
4373
- flexDirection: "column",
4374
- gap: 14
4375
- };
4376
- var modalBodyStyle = {
4377
- overflow: "auto",
4378
- padding: 12,
4379
- border: `1px solid ${colors.borderSubtle}`,
4380
- borderRadius: radii.md,
4381
- background: colors.surfaceMuted
4197
+ fontSize: 13,
4198
+ cursor: "pointer"
4382
4199
  };
4383
- var modalFooterStyle = {
4384
- display: "flex",
4385
- alignItems: "center",
4386
- gap: 8,
4387
- position: "sticky",
4388
- bottom: 0,
4389
- paddingTop: 10,
4390
- borderTop: `1px solid ${colors.borderSubtle}`,
4391
- background: "white"
4200
+ var dangerBtn3 = {
4201
+ ...ghostBtn3,
4202
+ background: colors.danger,
4203
+ color: "white",
4204
+ borderColor: colors.danger
4392
4205
  };
4393
- var ghostBtn4 = { padding: "6px 10px", background: "white", border: `1px solid ${colors.border}`, borderRadius: radii.sm, fontSize: 12, cursor: "pointer" };
4394
- var primaryBtn2 = { ...ghostBtn4, background: colors.primary, color: "white", borderColor: colors.primary };
4395
- var disabledPrimaryBtn = { ...primaryBtn2, opacity: 0.5, cursor: "not-allowed" };
4396
- var dangerBtn4 = { ...ghostBtn4, background: colors.dangerBg, borderColor: colors.dangerBorder, color: colors.danger };
4397
- var errorStyle2 = { color: colors.danger, fontSize: 11 };
4398
4206
 
4399
4207
  // src/inspector/ProcessorForm.tsx
4400
- import { useEffect as useEffect6, useState as useState9 } from "react";
4401
- import {
4402
- NAME_REGEX as NAME_REGEX2
4403
- } from "@cyoda/workflow-core";
4404
- import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
4208
+ import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
4405
4209
  var EXECUTION_MODES = [
4406
4210
  "ASYNC_NEW_TX",
4407
4211
  "ASYNC_SAME_TX",
@@ -4499,7 +4303,7 @@ function ProcessorEditorModal({
4499
4303
  onApply
4500
4304
  }) {
4501
4305
  const [draft, setDraft] = useState9(() => toDraft(initialProcessor));
4502
- useEffect6(() => {
4306
+ useEffect7(() => {
4503
4307
  setDraft(toDraft(initialProcessor));
4504
4308
  }, [initialProcessor]);
4505
4309
  const error = validateDraft(draft, existingNames, initialProcessor?.name);
@@ -4507,13 +4311,13 @@ function ProcessorEditorModal({
4507
4311
  if (disabled || error) return;
4508
4312
  onApply(toProcessor(draft));
4509
4313
  };
4510
- return /* @__PURE__ */ jsx13(ModalFrame, { onCancel, labelledBy: "processor-modal-title", children: /* @__PURE__ */ jsxs11("div", { style: modalStyle2, "data-testid": "processor-editor-modal", children: [
4511
- /* @__PURE__ */ jsxs11("header", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
4512
- /* @__PURE__ */ jsx13("h2", { id: "processor-modal-title", style: { margin: 0, fontSize: 18 }, children: title }),
4513
- /* @__PURE__ */ jsx13("p", { style: { margin: 0, fontSize: 12, color: colors.textTertiary }, children: "Processor changes stay local until Apply." })
4314
+ return /* @__PURE__ */ jsx14(ModalFrame, { onCancel, labelledBy: "processor-modal-title", children: /* @__PURE__ */ jsxs12("div", { style: modalStyle, "data-testid": "processor-editor-modal", children: [
4315
+ /* @__PURE__ */ jsxs12("header", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
4316
+ /* @__PURE__ */ jsx14("h2", { id: "processor-modal-title", style: { margin: 0, fontSize: 18 }, children: title }),
4317
+ /* @__PURE__ */ jsx14("p", { style: { margin: 0, fontSize: 12, color: colors.textTertiary }, children: "Processor changes stay local until Apply." })
4514
4318
  ] }),
4515
- /* @__PURE__ */ jsxs11("div", { style: modalBodyStyle2, children: [
4516
- /* @__PURE__ */ jsx13(FormField, { label: "Name", children: /* @__PURE__ */ jsx13(
4319
+ /* @__PURE__ */ jsxs12("div", { style: modalBodyStyle, children: [
4320
+ /* @__PURE__ */ jsx14(FormField, { label: "Name", children: /* @__PURE__ */ jsx14(
4517
4321
  "input",
4518
4322
  {
4519
4323
  type: "text",
@@ -4523,7 +4327,7 @@ function ProcessorEditorModal({
4523
4327
  style: inputStyle2
4524
4328
  }
4525
4329
  ) }),
4526
- /* @__PURE__ */ jsx13(FormField, { label: "Execution mode", children: /* @__PURE__ */ jsx13(
4330
+ /* @__PURE__ */ jsx14(FormField, { label: "Execution mode", children: /* @__PURE__ */ jsx14(
4527
4331
  CustomSelectInput,
4528
4332
  {
4529
4333
  value: draft.executionMode,
@@ -4532,8 +4336,8 @@ function ProcessorEditorModal({
4532
4336
  testId: "processor-execution-mode"
4533
4337
  }
4534
4338
  ) }),
4535
- /* @__PURE__ */ jsxs11("label", { style: checkboxRowStyle, children: [
4536
- /* @__PURE__ */ jsx13(
4339
+ /* @__PURE__ */ jsxs12("label", { style: checkboxRowStyle, children: [
4340
+ /* @__PURE__ */ jsx14(
4537
4341
  "input",
4538
4342
  {
4539
4343
  type: "checkbox",
@@ -4541,9 +4345,9 @@ function ProcessorEditorModal({
4541
4345
  onChange: (event) => setDraft((current) => ({ ...current, attachEntity: event.target.checked }))
4542
4346
  }
4543
4347
  ),
4544
- /* @__PURE__ */ jsx13("span", { children: "Attach entity" })
4348
+ /* @__PURE__ */ jsx14("span", { children: "Attach entity" })
4545
4349
  ] }),
4546
- /* @__PURE__ */ jsx13(FormField, { label: "Calculation node tags", children: /* @__PURE__ */ jsx13(
4350
+ /* @__PURE__ */ jsx14(FormField, { label: "Calculation node tags", children: /* @__PURE__ */ jsx14(
4547
4351
  "input",
4548
4352
  {
4549
4353
  type: "text",
@@ -4556,7 +4360,7 @@ function ProcessorEditorModal({
4556
4360
  style: inputStyle2
4557
4361
  }
4558
4362
  ) }),
4559
- /* @__PURE__ */ jsx13(FormField, { label: "Response timeout ms", children: /* @__PURE__ */ jsx13(
4363
+ /* @__PURE__ */ jsx14(FormField, { label: "Response timeout ms", children: /* @__PURE__ */ jsx14(
4560
4364
  "input",
4561
4365
  {
4562
4366
  type: "text",
@@ -4568,7 +4372,7 @@ function ProcessorEditorModal({
4568
4372
  style: inputStyle2
4569
4373
  }
4570
4374
  ) }),
4571
- /* @__PURE__ */ jsx13(FormField, { label: "Retry policy", children: /* @__PURE__ */ jsx13(
4375
+ /* @__PURE__ */ jsx14(FormField, { label: "Retry policy", children: /* @__PURE__ */ jsx14(
4572
4376
  "input",
4573
4377
  {
4574
4378
  type: "text",
@@ -4577,8 +4381,8 @@ function ProcessorEditorModal({
4577
4381
  style: inputStyle2
4578
4382
  }
4579
4383
  ) }),
4580
- /* @__PURE__ */ jsxs11("label", { style: checkboxRowStyle, children: [
4581
- /* @__PURE__ */ jsx13(
4384
+ /* @__PURE__ */ jsxs12("label", { style: checkboxRowStyle, children: [
4385
+ /* @__PURE__ */ jsx14(
4582
4386
  "input",
4583
4387
  {
4584
4388
  type: "checkbox",
@@ -4591,9 +4395,9 @@ function ProcessorEditorModal({
4591
4395
  "data-testid": "processor-async-result"
4592
4396
  }
4593
4397
  ),
4594
- /* @__PURE__ */ jsx13("span", { children: "Async result" })
4398
+ /* @__PURE__ */ jsx14("span", { children: "Async result" })
4595
4399
  ] }),
4596
- /* @__PURE__ */ jsx13(FormField, { label: "Crossover to async ms", children: /* @__PURE__ */ jsx13(
4400
+ /* @__PURE__ */ jsx14(FormField, { label: "Crossover to async ms", children: /* @__PURE__ */ jsx14(
4597
4401
  "input",
4598
4402
  {
4599
4403
  type: "text",
@@ -4608,16 +4412,16 @@ function ProcessorEditorModal({
4608
4412
  }
4609
4413
  ) })
4610
4414
  ] }),
4611
- error && /* @__PURE__ */ jsx13("div", { role: "alert", style: errorStyle3, "data-testid": "processor-modal-error", children: error }),
4612
- /* @__PURE__ */ jsxs11("footer", { style: modalFooterStyle2, children: [
4613
- /* @__PURE__ */ jsx13("button", { type: "button", onClick: onCancel, style: ghostBtn5, "data-testid": "processor-modal-cancel", children: "Cancel" }),
4614
- /* @__PURE__ */ jsx13(
4415
+ error && /* @__PURE__ */ jsx14("div", { role: "alert", style: errorStyle3, "data-testid": "processor-modal-error", children: error }),
4416
+ /* @__PURE__ */ jsxs12("footer", { style: modalFooterStyle, children: [
4417
+ /* @__PURE__ */ jsx14("button", { type: "button", onClick: onCancel, style: ghostBtn4, "data-testid": "processor-modal-cancel", children: "Cancel" }),
4418
+ /* @__PURE__ */ jsx14(
4615
4419
  "button",
4616
4420
  {
4617
4421
  type: "button",
4618
4422
  onClick: apply,
4619
4423
  disabled: disabled || !!error,
4620
- style: disabled || error ? disabledPrimaryBtn2 : primaryBtn3,
4424
+ style: disabled || error ? disabledPrimaryBtn : primaryBtn2,
4621
4425
  "data-testid": "processor-modal-apply",
4622
4426
  children: "Apply processor"
4623
4427
  }
@@ -4629,8 +4433,8 @@ function FormField({
4629
4433
  label,
4630
4434
  children
4631
4435
  }) {
4632
- return /* @__PURE__ */ jsxs11("label", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
4633
- /* @__PURE__ */ jsx13("span", { style: labelStyle2, children: label }),
4436
+ return /* @__PURE__ */ jsxs12("label", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
4437
+ /* @__PURE__ */ jsx14("span", { style: labelStyle2, children: label }),
4634
4438
  children
4635
4439
  ] });
4636
4440
  }
@@ -4645,17 +4449,17 @@ function ProcessorForm({
4645
4449
  }) {
4646
4450
  const messages = useMessages();
4647
4451
  const [modalOpen, setModalOpen] = useState9(false);
4648
- return /* @__PURE__ */ jsxs11("div", { style: summaryCardStyle, children: [
4649
- /* @__PURE__ */ jsxs11("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", gap: 8 }, children: [
4650
- /* @__PURE__ */ jsxs11("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
4651
- /* @__PURE__ */ jsx13("strong", { style: { fontSize: 13 }, children: processor.name }),
4652
- /* @__PURE__ */ jsx13("span", { style: { fontSize: 12, color: colors.textSecondary }, children: summarizeProcessor(processor) })
4452
+ return /* @__PURE__ */ jsxs12("div", { style: summaryCardStyle, children: [
4453
+ /* @__PURE__ */ jsxs12("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", gap: 8 }, children: [
4454
+ /* @__PURE__ */ jsxs12("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
4455
+ /* @__PURE__ */ jsx14("strong", { style: { fontSize: 13 }, children: processor.name }),
4456
+ /* @__PURE__ */ jsx14("span", { style: { fontSize: 12, color: colors.textSecondary }, children: summarizeProcessor(processor) })
4653
4457
  ] }),
4654
- /* @__PURE__ */ jsx13("span", { style: chipStyle, children: processor.type })
4458
+ /* @__PURE__ */ jsx14("span", { style: chipStyle, children: processor.type })
4655
4459
  ] }),
4656
- /* @__PURE__ */ jsxs11("div", { style: { display: "flex", gap: 6, flexWrap: "wrap" }, children: [
4657
- /* @__PURE__ */ jsx13("button", { type: "button", onClick: () => setModalOpen(true), style: ghostBtn5, children: "Edit" }),
4658
- /* @__PURE__ */ jsx13(
4460
+ /* @__PURE__ */ jsxs12("div", { style: { display: "flex", gap: 6, flexWrap: "wrap" }, children: [
4461
+ /* @__PURE__ */ jsx14("button", { type: "button", onClick: () => setModalOpen(true), style: ghostBtn4, children: "Edit" }),
4462
+ /* @__PURE__ */ jsx14(
4659
4463
  "button",
4660
4464
  {
4661
4465
  type: "button",
@@ -4666,11 +4470,11 @@ function ProcessorForm({
4666
4470
  processorUuid,
4667
4471
  toIndex: processorIndex - 1
4668
4472
  }),
4669
- style: ghostBtn5,
4473
+ style: ghostBtn4,
4670
4474
  children: messages.inspector.moveUp
4671
4475
  }
4672
4476
  ),
4673
- /* @__PURE__ */ jsx13(
4477
+ /* @__PURE__ */ jsx14(
4674
4478
  "button",
4675
4479
  {
4676
4480
  type: "button",
@@ -4681,23 +4485,23 @@ function ProcessorForm({
4681
4485
  processorUuid,
4682
4486
  toIndex: processorIndex + 1
4683
4487
  }),
4684
- style: ghostBtn5,
4488
+ style: ghostBtn4,
4685
4489
  children: messages.inspector.moveDown
4686
4490
  }
4687
4491
  ),
4688
- /* @__PURE__ */ jsx13(
4492
+ /* @__PURE__ */ jsx14(
4689
4493
  "button",
4690
4494
  {
4691
4495
  type: "button",
4692
4496
  disabled,
4693
4497
  onClick: () => onDispatch({ op: "removeProcessor", processorUuid }),
4694
- style: dangerBtn5,
4498
+ style: dangerBtn4,
4695
4499
  "data-testid": "inspector-processor-delete",
4696
4500
  children: messages.inspector.removeProcessor
4697
4501
  }
4698
4502
  )
4699
4503
  ] }),
4700
- modalOpen && /* @__PURE__ */ jsx13(
4504
+ modalOpen && /* @__PURE__ */ jsx14(
4701
4505
  ProcessorEditorModal,
4702
4506
  {
4703
4507
  title: `Edit ${processor.name}`,
@@ -4734,18 +4538,18 @@ var disabledInputStyle = {
4734
4538
  background: colors.surfaceMuted,
4735
4539
  color: colors.textTertiary
4736
4540
  };
4737
- var modalStyle2 = {
4541
+ var modalStyle = {
4738
4542
  width: "min(760px, calc(100vw - 48px))",
4739
4543
  display: "flex",
4740
4544
  flexDirection: "column",
4741
4545
  gap: 16
4742
4546
  };
4743
- var modalBodyStyle2 = {
4547
+ var modalBodyStyle = {
4744
4548
  display: "grid",
4745
4549
  gridTemplateColumns: "1fr 1fr",
4746
4550
  gap: 12
4747
4551
  };
4748
- var modalFooterStyle2 = {
4552
+ var modalFooterStyle = {
4749
4553
  display: "flex",
4750
4554
  justifyContent: "flex-end",
4751
4555
  gap: 8
@@ -4767,7 +4571,7 @@ var errorStyle3 = {
4767
4571
  color: colors.danger,
4768
4572
  fontSize: 12
4769
4573
  };
4770
- var ghostBtn5 = {
4574
+ var ghostBtn4 = {
4771
4575
  padding: "6px 10px",
4772
4576
  background: "white",
4773
4577
  border: `1px solid ${colors.border}`,
@@ -4775,19 +4579,19 @@ var ghostBtn5 = {
4775
4579
  fontSize: 12,
4776
4580
  cursor: "pointer"
4777
4581
  };
4778
- var primaryBtn3 = {
4779
- ...ghostBtn5,
4582
+ var primaryBtn2 = {
4583
+ ...ghostBtn4,
4780
4584
  background: colors.primary,
4781
4585
  color: "white",
4782
4586
  borderColor: colors.primary
4783
4587
  };
4784
- var disabledPrimaryBtn2 = {
4785
- ...primaryBtn3,
4588
+ var disabledPrimaryBtn = {
4589
+ ...primaryBtn2,
4786
4590
  opacity: 0.5,
4787
4591
  cursor: "not-allowed"
4788
4592
  };
4789
- var dangerBtn5 = {
4790
- ...ghostBtn5,
4593
+ var dangerBtn4 = {
4594
+ ...ghostBtn4,
4791
4595
  background: colors.dangerBg,
4792
4596
  borderColor: colors.dangerBorder,
4793
4597
  color: colors.danger
@@ -4811,7 +4615,7 @@ var summaryCardStyle = {
4811
4615
  };
4812
4616
 
4813
4617
  // src/inspector/TransitionForm.tsx
4814
- import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
4618
+ import { Fragment as Fragment5, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
4815
4619
  function TransitionForm({
4816
4620
  workflow,
4817
4621
  stateCode,
@@ -4834,7 +4638,7 @@ function TransitionForm({
4834
4638
  const [scheduleTimeoutDraft, setScheduleTimeoutDraft] = useState10(
4835
4639
  transition.schedule?.timeoutMs !== void 0 ? String(transition.schedule.timeoutMs) : ""
4836
4640
  );
4837
- const prevTransitionUuidRef = useRef8(transitionUuid);
4641
+ const prevTransitionUuidRef = useRef9(transitionUuid);
4838
4642
  if (prevTransitionUuidRef.current !== transitionUuid) {
4839
4643
  prevTransitionUuidRef.current = transitionUuid;
4840
4644
  setScheduleDelayDraft(
@@ -4932,9 +4736,9 @@ function TransitionForm({
4932
4736
  index: index + 1
4933
4737
  });
4934
4738
  };
4935
- return /* @__PURE__ */ jsxs12("div", { style: transitionFormStyle, children: [
4936
- /* @__PURE__ */ jsxs12(FieldGroup, { title: messages.inspector.properties, children: [
4937
- /* @__PURE__ */ jsx14(
4739
+ return /* @__PURE__ */ jsxs13("div", { style: transitionFormStyle, children: [
4740
+ /* @__PURE__ */ jsxs13(FieldGroup, { title: messages.inspector.properties, children: [
4741
+ /* @__PURE__ */ jsx15(
4938
4742
  TextField,
4939
4743
  {
4940
4744
  label: messages.inspector.name,
@@ -4945,8 +4749,8 @@ function TransitionForm({
4945
4749
  testId: "inspector-transition-name"
4946
4750
  }
4947
4751
  ),
4948
- renameError && /* @__PURE__ */ jsx14("div", { role: "alert", style: { color: colors.danger, fontSize: 12 }, children: renameError }),
4949
- !disabled && /* @__PURE__ */ jsx14(
4752
+ renameError && /* @__PURE__ */ jsx15("div", { role: "alert", style: { color: colors.danger, fontSize: 12 }, children: renameError }),
4753
+ !disabled && /* @__PURE__ */ jsx15(
4950
4754
  SelectField,
4951
4755
  {
4952
4756
  label: "Source state",
@@ -4966,7 +4770,7 @@ function TransitionForm({
4966
4770
  testId: "inspector-transition-source-state"
4967
4771
  }
4968
4772
  ),
4969
- /* @__PURE__ */ jsx14(
4773
+ /* @__PURE__ */ jsx15(
4970
4774
  SelectField,
4971
4775
  {
4972
4776
  label: "Target state",
@@ -4977,7 +4781,7 @@ function TransitionForm({
4977
4781
  testId: "inspector-transition-next"
4978
4782
  }
4979
4783
  ),
4980
- /* @__PURE__ */ jsx14(
4784
+ /* @__PURE__ */ jsx15(
4981
4785
  SelectField,
4982
4786
  {
4983
4787
  label: messages.inspector.transitionType,
@@ -4991,7 +4795,7 @@ function TransitionForm({
4991
4795
  testId: "inspector-transition-manual"
4992
4796
  }
4993
4797
  ),
4994
- /* @__PURE__ */ jsx14(
4798
+ /* @__PURE__ */ jsx15(
4995
4799
  CheckboxField,
4996
4800
  {
4997
4801
  label: messages.inspector.disabled,
@@ -5001,7 +4805,7 @@ function TransitionForm({
5001
4805
  testId: "inspector-transition-disabled"
5002
4806
  }
5003
4807
  ),
5004
- /* @__PURE__ */ jsx14(
4808
+ /* @__PURE__ */ jsx15(
5005
4809
  AnchorSelect,
5006
4810
  {
5007
4811
  label: messages.inspector.sourceAnchor,
@@ -5012,7 +4816,7 @@ function TransitionForm({
5012
4816
  testId: "inspector-transition-source-anchor"
5013
4817
  }
5014
4818
  ),
5015
- /* @__PURE__ */ jsx14(
4819
+ /* @__PURE__ */ jsx15(
5016
4820
  AnchorSelect,
5017
4821
  {
5018
4822
  label: messages.inspector.targetAnchor,
@@ -5023,12 +4827,12 @@ function TransitionForm({
5023
4827
  testId: "inspector-transition-target-anchor"
5024
4828
  }
5025
4829
  ),
5026
- /* @__PURE__ */ jsxs12("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
5027
- /* @__PURE__ */ jsxs12("div", { style: { display: "flex", gap: 6 }, children: [
5028
- /* @__PURE__ */ jsx14("button", { type: "button", disabled, onClick: () => reorder(-1), style: ghostBtn6, children: messages.inspector.moveUp }),
5029
- /* @__PURE__ */ jsx14("button", { type: "button", disabled, onClick: () => reorder(1), style: ghostBtn6, children: messages.inspector.moveDown })
4830
+ /* @__PURE__ */ jsxs13("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
4831
+ /* @__PURE__ */ jsxs13("div", { style: { display: "flex", gap: 6 }, children: [
4832
+ /* @__PURE__ */ jsx15("button", { type: "button", disabled, onClick: () => reorder(-1), style: ghostBtn5, children: messages.inspector.moveUp }),
4833
+ /* @__PURE__ */ jsx15("button", { type: "button", disabled, onClick: () => reorder(1), style: ghostBtn5, children: messages.inspector.moveDown })
5030
4834
  ] }),
5031
- /* @__PURE__ */ jsx14(
4835
+ /* @__PURE__ */ jsx15(
5032
4836
  "p",
5033
4837
  {
5034
4838
  style: {
@@ -5042,20 +4846,20 @@ function TransitionForm({
5042
4846
  }
5043
4847
  )
5044
4848
  ] }),
5045
- /* @__PURE__ */ jsx14("hr", { style: { border: "none", borderTop: `1px solid ${colors.borderSubtle}`, margin: 0 } }),
5046
- /* @__PURE__ */ jsx14(
4849
+ /* @__PURE__ */ jsx15("hr", { style: { border: "none", borderTop: `1px solid ${colors.borderSubtle}`, margin: 0 } }),
4850
+ /* @__PURE__ */ jsx15(
5047
4851
  "button",
5048
4852
  {
5049
4853
  type: "button",
5050
4854
  disabled,
5051
4855
  onClick: removeTransition,
5052
- style: dangerBtn6,
4856
+ style: dangerBtn5,
5053
4857
  "data-testid": "inspector-transition-delete",
5054
4858
  children: "Delete transition"
5055
4859
  }
5056
4860
  ),
5057
- /* @__PURE__ */ jsx14("hr", { style: { border: "none", borderTop: `1px solid ${colors.borderSubtle}`, margin: 0 } }),
5058
- issues && issues.length > 0 && /* @__PURE__ */ jsx14("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: issues.map((issue, i) => /* @__PURE__ */ jsx14(
4861
+ /* @__PURE__ */ jsx15("hr", { style: { border: "none", borderTop: `1px solid ${colors.borderSubtle}`, margin: 0 } }),
4862
+ issues && issues.length > 0 && /* @__PURE__ */ jsx15("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: issues.map((issue, i) => /* @__PURE__ */ jsx15(
5059
4863
  "div",
5060
4864
  {
5061
4865
  role: "alert",
@@ -5072,12 +4876,12 @@ function TransitionForm({
5072
4876
  `${issue.code}-${i}`
5073
4877
  )) })
5074
4878
  ] }),
5075
- /* @__PURE__ */ jsx14(
4879
+ /* @__PURE__ */ jsx15(
5076
4880
  TransitionSection,
5077
4881
  {
5078
4882
  title: messages.inspector.criteria,
5079
4883
  testId: "inspector-transition-criteria-section",
5080
- children: /* @__PURE__ */ jsx14(
4884
+ children: /* @__PURE__ */ jsx15(
5081
4885
  CriterionSection,
5082
4886
  {
5083
4887
  host,
@@ -5093,18 +4897,18 @@ function TransitionForm({
5093
4897
  )
5094
4898
  }
5095
4899
  ),
5096
- /* @__PURE__ */ jsxs12(
4900
+ /* @__PURE__ */ jsxs13(
5097
4901
  TransitionSection,
5098
4902
  {
5099
4903
  title: "Scheduled transition",
5100
4904
  testId: "inspector-transition-schedule-section",
5101
4905
  children: [
5102
- /* @__PURE__ */ jsxs12(
4906
+ /* @__PURE__ */ jsxs13(
5103
4907
  "label",
5104
4908
  {
5105
4909
  style: { display: "flex", flexDirection: "row", alignItems: "center", gap: 8, fontSize: 12, color: colors.textSecondary, cursor: "pointer" },
5106
4910
  children: [
5107
- /* @__PURE__ */ jsx14(
4911
+ /* @__PURE__ */ jsx15(
5108
4912
  "input",
5109
4913
  {
5110
4914
  type: "checkbox",
@@ -5124,14 +4928,14 @@ function TransitionForm({
5124
4928
  }
5125
4929
  }
5126
4930
  ),
5127
- /* @__PURE__ */ jsx14("span", { children: "Enable schedule" })
4931
+ /* @__PURE__ */ jsx15("span", { children: "Enable schedule" })
5128
4932
  ]
5129
4933
  }
5130
4934
  ),
5131
- transition.schedule !== void 0 && /* @__PURE__ */ jsxs12(Fragment5, { children: [
5132
- /* @__PURE__ */ jsxs12("label", { style: { display: "flex", flexDirection: "column", gap: 4, fontSize: 12, color: colors.textSecondary }, children: [
5133
- /* @__PURE__ */ jsx14("span", { style: { fontWeight: 500 }, children: "Delay (ms)" }),
5134
- /* @__PURE__ */ jsx14(
4935
+ transition.schedule !== void 0 && /* @__PURE__ */ jsxs13(Fragment5, { children: [
4936
+ /* @__PURE__ */ jsxs13("label", { style: { display: "flex", flexDirection: "column", gap: 4, fontSize: 12, color: colors.textSecondary }, children: [
4937
+ /* @__PURE__ */ jsx15("span", { style: { fontWeight: 500 }, children: "Delay (ms)" }),
4938
+ /* @__PURE__ */ jsx15(
5135
4939
  "input",
5136
4940
  {
5137
4941
  type: "text",
@@ -5147,9 +4951,9 @@ function TransitionForm({
5147
4951
  }
5148
4952
  )
5149
4953
  ] }),
5150
- /* @__PURE__ */ jsxs12("label", { style: { display: "flex", flexDirection: "column", gap: 4, fontSize: 12, color: colors.textSecondary }, children: [
5151
- /* @__PURE__ */ jsx14("span", { style: { fontWeight: 500 }, children: "Timeout (ms)" }),
5152
- /* @__PURE__ */ jsx14(
4954
+ /* @__PURE__ */ jsxs13("label", { style: { display: "flex", flexDirection: "column", gap: 4, fontSize: 12, color: colors.textSecondary }, children: [
4955
+ /* @__PURE__ */ jsx15("span", { style: { fontWeight: 500 }, children: "Timeout (ms)" }),
4956
+ /* @__PURE__ */ jsx15(
5153
4957
  "input",
5154
4958
  {
5155
4959
  type: "text",
@@ -5166,7 +4970,7 @@ function TransitionForm({
5166
4970
  )
5167
4971
  ] })
5168
4972
  ] }),
5169
- /* @__PURE__ */ jsx14(
4973
+ /* @__PURE__ */ jsx15(
5170
4974
  "p",
5171
4975
  {
5172
4976
  style: {
@@ -5186,28 +4990,28 @@ function TransitionForm({
5186
4990
  ]
5187
4991
  }
5188
4992
  ),
5189
- /* @__PURE__ */ jsxs12(
4993
+ /* @__PURE__ */ jsxs13(
5190
4994
  TransitionSection,
5191
4995
  {
5192
4996
  title: messages.inspector.processors,
5193
4997
  testId: "inspector-transition-processes-section",
5194
4998
  children: [
5195
- processorCount === 0 ? /* @__PURE__ */ jsx14("div", { style: emptyProcessorStateStyle, children: /* @__PURE__ */ jsx14("p", { style: summaryTextStyle2, children: "No processors run on this transition." }) }) : /* @__PURE__ */ jsxs12(Fragment5, { children: [
5196
- /* @__PURE__ */ jsx14("p", { style: processorHelperStyle, children: "Processors run sequentially in the order shown." }),
5197
- processors.map((processor, index) => /* @__PURE__ */ jsxs12("div", { style: processorRowStyle, children: [
5198
- /* @__PURE__ */ jsxs12("div", { style: { display: "flex", gap: 10, alignItems: "center" }, children: [
5199
- /* @__PURE__ */ jsxs12("span", { style: processorOrderStyle, children: [
4999
+ processorCount === 0 ? /* @__PURE__ */ jsx15("div", { style: emptyProcessorStateStyle, children: /* @__PURE__ */ jsx15("p", { style: summaryTextStyle2, children: "No processors run on this transition." }) }) : /* @__PURE__ */ jsxs13(Fragment5, { children: [
5000
+ /* @__PURE__ */ jsx15("p", { style: processorHelperStyle, children: "Processors run sequentially in the order shown." }),
5001
+ processors.map((processor, index) => /* @__PURE__ */ jsxs13("div", { style: processorRowStyle, children: [
5002
+ /* @__PURE__ */ jsxs13("div", { style: { display: "flex", gap: 10, alignItems: "center" }, children: [
5003
+ /* @__PURE__ */ jsxs13("span", { style: processorOrderStyle, children: [
5200
5004
  index + 1,
5201
5005
  "."
5202
5006
  ] }),
5203
- /* @__PURE__ */ jsx14("span", { style: processorTypeChipStyle, children: processor.type }),
5204
- /* @__PURE__ */ jsxs12("div", { style: { display: "flex", flexDirection: "column", gap: 2, minWidth: 0 }, children: [
5205
- /* @__PURE__ */ jsx14("strong", { style: { fontSize: 13 }, children: processor.name }),
5206
- /* @__PURE__ */ jsx14("span", { style: summaryTextStyle2, children: summarizeProcessor(processor) })
5007
+ /* @__PURE__ */ jsx15("span", { style: processorTypeChipStyle, children: processor.type }),
5008
+ /* @__PURE__ */ jsxs13("div", { style: { display: "flex", flexDirection: "column", gap: 2, minWidth: 0 }, children: [
5009
+ /* @__PURE__ */ jsx15("strong", { style: { fontSize: 13 }, children: processor.name }),
5010
+ /* @__PURE__ */ jsx15("span", { style: summaryTextStyle2, children: summarizeProcessor(processor) })
5207
5011
  ] })
5208
5012
  ] }),
5209
- /* @__PURE__ */ jsxs12("div", { style: { display: "flex", gap: 6, flexWrap: "wrap" }, children: [
5210
- /* @__PURE__ */ jsx14(
5013
+ /* @__PURE__ */ jsxs13("div", { style: { display: "flex", gap: 6, flexWrap: "wrap" }, children: [
5014
+ /* @__PURE__ */ jsx15(
5211
5015
  "button",
5212
5016
  {
5213
5017
  type: "button",
@@ -5217,23 +5021,23 @@ function TransitionForm({
5217
5021
  processorUuid: processorUuids[index],
5218
5022
  processorIndex: index
5219
5023
  }),
5220
- style: ghostBtn6,
5024
+ style: ghostBtn5,
5221
5025
  "data-testid": `processor-edit-${index}`,
5222
5026
  children: "Edit"
5223
5027
  }
5224
5028
  ),
5225
- /* @__PURE__ */ jsx14(
5029
+ /* @__PURE__ */ jsx15(
5226
5030
  "button",
5227
5031
  {
5228
5032
  type: "button",
5229
5033
  disabled,
5230
5034
  onClick: () => duplicateProcessor(processor, index),
5231
- style: ghostBtn6,
5035
+ style: ghostBtn5,
5232
5036
  "data-testid": `processor-duplicate-${index}`,
5233
5037
  children: "Duplicate"
5234
5038
  }
5235
5039
  ),
5236
- /* @__PURE__ */ jsx14(
5040
+ /* @__PURE__ */ jsx15(
5237
5041
  "button",
5238
5042
  {
5239
5043
  type: "button",
@@ -5244,12 +5048,12 @@ function TransitionForm({
5244
5048
  processorUuid: processorUuids[index],
5245
5049
  toIndex: index - 1
5246
5050
  }),
5247
- style: ghostBtn6,
5051
+ style: ghostBtn5,
5248
5052
  "data-testid": `processor-move-up-${index}`,
5249
5053
  children: "Move up"
5250
5054
  }
5251
5055
  ),
5252
- /* @__PURE__ */ jsx14(
5056
+ /* @__PURE__ */ jsx15(
5253
5057
  "button",
5254
5058
  {
5255
5059
  type: "button",
@@ -5260,18 +5064,18 @@ function TransitionForm({
5260
5064
  processorUuid: processorUuids[index],
5261
5065
  toIndex: index + 1
5262
5066
  }),
5263
- style: ghostBtn6,
5067
+ style: ghostBtn5,
5264
5068
  "data-testid": `processor-move-down-${index}`,
5265
5069
  children: "Move down"
5266
5070
  }
5267
5071
  ),
5268
- /* @__PURE__ */ jsx14(
5072
+ /* @__PURE__ */ jsx15(
5269
5073
  "button",
5270
5074
  {
5271
5075
  type: "button",
5272
5076
  disabled: disabled || !processorUuids[index],
5273
5077
  onClick: () => processorUuids[index] && onDispatch({ op: "removeProcessor", processorUuid: processorUuids[index] }),
5274
- style: dangerBtn6,
5078
+ style: dangerBtn5,
5275
5079
  "data-testid": `processor-delete-${index}`,
5276
5080
  children: "Delete"
5277
5081
  }
@@ -5279,13 +5083,13 @@ function TransitionForm({
5279
5083
  ] })
5280
5084
  ] }, processorUuids[index] ?? `${processor.name}-${index}`))
5281
5085
  ] }),
5282
- /* @__PURE__ */ jsx14(
5086
+ /* @__PURE__ */ jsx15(
5283
5087
  "button",
5284
5088
  {
5285
5089
  type: "button",
5286
5090
  disabled,
5287
5091
  onClick: () => setProcessorModal({ mode: "add" }),
5288
- style: ghostBtn6,
5092
+ style: ghostBtn5,
5289
5093
  "data-testid": "inspector-add-processor",
5290
5094
  children: messages.inspector.addProcessor
5291
5095
  }
@@ -5293,7 +5097,7 @@ function TransitionForm({
5293
5097
  ]
5294
5098
  }
5295
5099
  ),
5296
- /* @__PURE__ */ jsx14(TransitionSection, { title: "Annotations", testId: "inspector-transition-annotations-section", children: /* @__PURE__ */ jsx14(
5100
+ /* @__PURE__ */ jsx15(TransitionSection, { title: "Annotations", testId: "inspector-transition-annotations-section", children: /* @__PURE__ */ jsx15(
5297
5101
  AnnotationsField,
5298
5102
  {
5299
5103
  value: transition.annotations,
@@ -5304,7 +5108,7 @@ function TransitionForm({
5304
5108
  onRemove: () => onDispatch({ op: "setAnnotations", target: { kind: "transition", transitionUuid } })
5305
5109
  }
5306
5110
  ) }),
5307
- processorModal && /* @__PURE__ */ jsx14(
5111
+ processorModal && /* @__PURE__ */ jsx15(
5308
5112
  ProcessorEditorModal,
5309
5113
  {
5310
5114
  title: processorModal.mode === "add" ? "Add processor" : "Edit processor",
@@ -5324,8 +5128,8 @@ function TransitionSection({
5324
5128
  testId,
5325
5129
  children
5326
5130
  }) {
5327
- return /* @__PURE__ */ jsxs12("section", { style: transitionSectionStyle, "data-testid": testId, children: [
5328
- /* @__PURE__ */ jsx14("header", { style: sectionHeaderStyle, children: title }),
5131
+ return /* @__PURE__ */ jsxs13("section", { style: transitionSectionStyle, "data-testid": testId, children: [
5132
+ /* @__PURE__ */ jsx15("header", { style: sectionHeaderStyle, children: title }),
5329
5133
  children
5330
5134
  ] });
5331
5135
  }
@@ -5348,7 +5152,7 @@ var sectionHeaderStyle = {
5348
5152
  textTransform: "uppercase",
5349
5153
  color: colors.textSecondary
5350
5154
  };
5351
- var ghostBtn6 = {
5155
+ var ghostBtn5 = {
5352
5156
  padding: "4px 8px",
5353
5157
  background: "white",
5354
5158
  border: `1px solid ${colors.border}`,
@@ -5356,8 +5160,8 @@ var ghostBtn6 = {
5356
5160
  fontSize: 12,
5357
5161
  cursor: "pointer"
5358
5162
  };
5359
- var dangerBtn6 = {
5360
- ...ghostBtn6,
5163
+ var dangerBtn5 = {
5164
+ ...ghostBtn5,
5361
5165
  background: colors.dangerBg,
5362
5166
  borderColor: colors.dangerBorder,
5363
5167
  color: colors.danger
@@ -5432,9 +5236,9 @@ function AnchorSelect({
5432
5236
  { value: "left", label: messages.inspector.anchorLeft },
5433
5237
  { value: "left-bottom", label: messages.inspector.anchorLeftBottom }
5434
5238
  ];
5435
- return /* @__PURE__ */ jsxs12("label", { style: { display: "flex", flexDirection: "column", gap: 4, fontSize: 12, color: colors.textSecondary }, children: [
5436
- /* @__PURE__ */ jsx14("span", { style: { fontWeight: 500 }, children: label }),
5437
- /* @__PURE__ */ jsx14(
5239
+ return /* @__PURE__ */ jsxs13("label", { style: { display: "flex", flexDirection: "column", gap: 4, fontSize: 12, color: colors.textSecondary }, children: [
5240
+ /* @__PURE__ */ jsx15("span", { style: { fontWeight: 500 }, children: label }),
5241
+ /* @__PURE__ */ jsx15(
5438
5242
  CustomSelectInput,
5439
5243
  {
5440
5244
  value: value ?? "",
@@ -5449,7 +5253,7 @@ function AnchorSelect({
5449
5253
  }
5450
5254
 
5451
5255
  // src/inspector/Inspector.tsx
5452
- import { Fragment as Fragment6, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
5256
+ import { Fragment as Fragment6, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
5453
5257
  function issueKeyForSelection(selection) {
5454
5258
  if (!selection) return null;
5455
5259
  switch (selection.kind) {
@@ -5474,7 +5278,9 @@ function Inspector({
5474
5278
  onSelectionChange,
5475
5279
  onClose,
5476
5280
  onRequestDeleteState,
5477
- width = 384
5281
+ docked,
5282
+ onToggleDock,
5283
+ onMinimize
5478
5284
  }) {
5479
5285
  const messages = useMessages();
5480
5286
  const { developerMode } = useEditorConfig();
@@ -5487,7 +5293,7 @@ function Inspector({
5487
5293
  return issues.filter((i) => i.targetId === selectionIssueKey);
5488
5294
  }, [issues, selectionIssueKey]);
5489
5295
  const breadcrumb = renderBreadcrumb(resolved);
5490
- return /* @__PURE__ */ jsxs13(
5296
+ return /* @__PURE__ */ jsxs14(
5491
5297
  "aside",
5492
5298
  {
5493
5299
  style: {
@@ -5496,16 +5302,17 @@ function Inspector({
5496
5302
  flexDirection: "column",
5497
5303
  background: colors.surfaceMuted,
5498
5304
  borderLeft: `1px solid ${colors.borderSubtle}`,
5499
- flex: `0 0 ${width}px`,
5500
- width,
5501
- minWidth: 360,
5305
+ flex: "1 1 auto",
5306
+ width: "100%",
5307
+ minWidth: 0,
5502
5308
  fontFamily: fonts.sans
5503
5309
  },
5504
5310
  "data-testid": "inspector",
5505
5311
  children: [
5506
- /* @__PURE__ */ jsxs13(
5312
+ /* @__PURE__ */ jsxs14(
5507
5313
  "header",
5508
5314
  {
5315
+ "data-inspector-drag-handle": true,
5509
5316
  style: {
5510
5317
  padding: "10px 12px",
5511
5318
  borderBottom: `1px solid ${colors.borderSubtle}`,
@@ -5516,8 +5323,59 @@ function Inspector({
5516
5323
  gap: 8
5517
5324
  },
5518
5325
  children: [
5519
- /* @__PURE__ */ jsx15("span", { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: breadcrumb }),
5520
- onClose && /* @__PURE__ */ jsx15(
5326
+ /* @__PURE__ */ jsx16("span", { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: breadcrumb }),
5327
+ onToggleDock && /* @__PURE__ */ jsx16(
5328
+ "button",
5329
+ {
5330
+ type: "button",
5331
+ "aria-label": docked ? messages.inspector.detachPanel : messages.inspector.dockPanel,
5332
+ title: docked ? messages.inspector.detachPanel : messages.inspector.dockPanel,
5333
+ "data-testid": "inspector-dock-toggle",
5334
+ onClick: onToggleDock,
5335
+ style: {
5336
+ width: 24,
5337
+ height: 24,
5338
+ border: `1px solid ${colors.border}`,
5339
+ borderRadius: radii.sm,
5340
+ background: "white",
5341
+ color: colors.textSecondary,
5342
+ cursor: "pointer",
5343
+ display: "inline-flex",
5344
+ alignItems: "center",
5345
+ justifyContent: "center",
5346
+ padding: 0,
5347
+ fontSize: 13
5348
+ },
5349
+ children: docked ? "\u2922" : "\u2921"
5350
+ }
5351
+ ),
5352
+ onMinimize && /* @__PURE__ */ jsx16(
5353
+ "button",
5354
+ {
5355
+ type: "button",
5356
+ "aria-label": messages.inspector.minimize,
5357
+ title: messages.inspector.minimize,
5358
+ "data-testid": "inspector-minimize",
5359
+ onClick: onMinimize,
5360
+ style: {
5361
+ width: 24,
5362
+ height: 24,
5363
+ border: `1px solid ${colors.border}`,
5364
+ borderRadius: radii.sm,
5365
+ background: "white",
5366
+ color: colors.textSecondary,
5367
+ cursor: "pointer",
5368
+ display: "inline-flex",
5369
+ alignItems: "flex-end",
5370
+ justifyContent: "center",
5371
+ padding: "0 0 5px",
5372
+ fontSize: 18,
5373
+ lineHeight: "10px"
5374
+ },
5375
+ children: "\u2013"
5376
+ }
5377
+ ),
5378
+ onClose && /* @__PURE__ */ jsx16(
5521
5379
  "button",
5522
5380
  {
5523
5381
  type: "button",
@@ -5545,8 +5403,8 @@ function Inspector({
5545
5403
  ]
5546
5404
  }
5547
5405
  ),
5548
- developerMode && /* @__PURE__ */ jsxs13("div", { style: { display: "flex", borderBottom: `1px solid ${colors.borderSubtle}` }, children: [
5549
- /* @__PURE__ */ jsx15(
5406
+ developerMode && /* @__PURE__ */ jsxs14("div", { style: { display: "flex", borderBottom: `1px solid ${colors.borderSubtle}` }, children: [
5407
+ /* @__PURE__ */ jsx16(
5550
5408
  TabButton,
5551
5409
  {
5552
5410
  active: effectiveTab === "properties",
@@ -5555,7 +5413,7 @@ function Inspector({
5555
5413
  children: messages.inspector.properties
5556
5414
  }
5557
5415
  ),
5558
- /* @__PURE__ */ jsx15(
5416
+ /* @__PURE__ */ jsx16(
5559
5417
  TabButton,
5560
5418
  {
5561
5419
  active: effectiveTab === "json",
@@ -5565,11 +5423,11 @@ function Inspector({
5565
5423
  }
5566
5424
  )
5567
5425
  ] }),
5568
- /* @__PURE__ */ jsxs13("div", { style: { padding: 12, overflowY: "auto", flex: 1, display: "flex", flexDirection: "column", gap: 16 }, children: [
5569
- effectiveTab === "properties" && /* @__PURE__ */ jsxs13(Fragment6, { children: [
5570
- !resolved && /* @__PURE__ */ jsx15(EmptyState, { message: messages.inspector.empty }),
5571
- resolved?.kind === "workflow" && /* @__PURE__ */ jsx15(WorkflowForm, { workflow: resolved.workflow, disabled: readOnly, onDispatch }, resolved.workflow.name),
5572
- resolved?.kind === "state" && /* @__PURE__ */ jsx15(
5426
+ /* @__PURE__ */ jsxs14("div", { style: { padding: 12, overflowY: "auto", flex: 1, display: "flex", flexDirection: "column", gap: 16 }, children: [
5427
+ effectiveTab === "properties" && /* @__PURE__ */ jsxs14(Fragment6, { children: [
5428
+ !resolved && /* @__PURE__ */ jsx16(EmptyState, { message: messages.inspector.empty }),
5429
+ resolved?.kind === "workflow" && /* @__PURE__ */ jsx16(WorkflowForm, { workflow: resolved.workflow, disabled: readOnly, onDispatch }, resolved.workflow.name),
5430
+ resolved?.kind === "state" && /* @__PURE__ */ jsx16(
5573
5431
  StateForm,
5574
5432
  {
5575
5433
  workflow: resolved.workflow,
@@ -5582,7 +5440,7 @@ function Inspector({
5582
5440
  },
5583
5441
  `${resolved.workflow.name}:${resolved.stateCode}`
5584
5442
  ),
5585
- resolved?.kind === "transition" && /* @__PURE__ */ jsx15(
5443
+ resolved?.kind === "transition" && /* @__PURE__ */ jsx16(
5586
5444
  TransitionForm,
5587
5445
  {
5588
5446
  workflow: resolved.workflow,
@@ -5599,7 +5457,7 @@ function Inspector({
5599
5457
  },
5600
5458
  resolved.transitionUuid
5601
5459
  ),
5602
- resolved?.kind === "processor" && /* @__PURE__ */ jsx15(
5460
+ resolved?.kind === "processor" && /* @__PURE__ */ jsx16(
5603
5461
  ProcessorForm,
5604
5462
  {
5605
5463
  processor: resolved.processor,
@@ -5613,8 +5471,8 @@ function Inspector({
5613
5471
  resolved.processorUuid
5614
5472
  )
5615
5473
  ] }),
5616
- developerMode && effectiveTab === "json" && /* @__PURE__ */ jsx15(JsonPreview, { document: doc, resolved }),
5617
- selectionIssues.length > 0 && /* @__PURE__ */ jsx15(IssuesList, { issues: selectionIssues, title: messages.inspector.issues })
5474
+ developerMode && effectiveTab === "json" && /* @__PURE__ */ jsx16(JsonPreview, { document: doc, resolved }),
5475
+ selectionIssues.length > 0 && /* @__PURE__ */ jsx16(IssuesList, { issues: selectionIssues, title: messages.inspector.issues })
5618
5476
  ] })
5619
5477
  ]
5620
5478
  }
@@ -5637,7 +5495,7 @@ function TabButton({
5637
5495
  children,
5638
5496
  testId
5639
5497
  }) {
5640
- return /* @__PURE__ */ jsx15(
5498
+ return /* @__PURE__ */ jsx16(
5641
5499
  "button",
5642
5500
  {
5643
5501
  type: "button",
@@ -5658,17 +5516,17 @@ function TabButton({
5658
5516
  );
5659
5517
  }
5660
5518
  function EmptyState({ message }) {
5661
- return /* @__PURE__ */ jsx15("p", { style: { color: colors.textTertiary, fontSize: 13 }, children: message });
5519
+ return /* @__PURE__ */ jsx16("p", { style: { color: colors.textTertiary, fontSize: 13 }, children: message });
5662
5520
  }
5663
5521
  function IssuesList({
5664
5522
  issues,
5665
5523
  title
5666
5524
  }) {
5667
- return /* @__PURE__ */ jsxs13("section", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
5668
- /* @__PURE__ */ jsx15("header", { style: { fontSize: 11, fontWeight: 600, letterSpacing: "0.08em", textTransform: "uppercase", color: colors.textSecondary }, children: title }),
5525
+ return /* @__PURE__ */ jsxs14("section", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
5526
+ /* @__PURE__ */ jsx16("header", { style: { fontSize: 11, fontWeight: 600, letterSpacing: "0.08em", textTransform: "uppercase", color: colors.textSecondary }, children: title }),
5669
5527
  issues.map((issue, i) => {
5670
5528
  const tone = severityTone(issue.severity);
5671
- return /* @__PURE__ */ jsxs13(
5529
+ return /* @__PURE__ */ jsxs14(
5672
5530
  "div",
5673
5531
  {
5674
5532
  style: {
@@ -5679,8 +5537,8 @@ function IssuesList({
5679
5537
  fontSize: 12
5680
5538
  },
5681
5539
  children: [
5682
- /* @__PURE__ */ jsx15("strong", { children: issue.code }),
5683
- /* @__PURE__ */ jsx15("div", { children: issue.message })
5540
+ /* @__PURE__ */ jsx16("strong", { children: issue.code }),
5541
+ /* @__PURE__ */ jsx16("div", { children: issue.message })
5684
5542
  ]
5685
5543
  },
5686
5544
  `${issue.code}-${i}`
@@ -5700,7 +5558,7 @@ function JsonPreview({
5700
5558
  if (resolved.kind === "processor") return JSON.stringify(resolved.processor, null, 2);
5701
5559
  return "";
5702
5560
  }, [doc, resolved]);
5703
- return /* @__PURE__ */ jsx15(
5561
+ return /* @__PURE__ */ jsx16(
5704
5562
  "pre",
5705
5563
  {
5706
5564
  style: {
@@ -5722,8 +5580,221 @@ function JsonPreview({
5722
5580
  );
5723
5581
  }
5724
5582
 
5583
+ // src/inspector/inspectorPlacement.ts
5584
+ var MIN_FLOAT_W = 340;
5585
+ var MIN_FLOAT_H = 260;
5586
+ function clampRect(rect, viewport) {
5587
+ const width = Math.min(Math.max(rect.width, MIN_FLOAT_W), viewport.w);
5588
+ const height = Math.min(Math.max(rect.height, MIN_FLOAT_H), viewport.h);
5589
+ const left = Math.min(Math.max(rect.left, 0), Math.max(0, viewport.w - width));
5590
+ const top = Math.min(Math.max(rect.top, 0), Math.max(0, viewport.h - height));
5591
+ return { left, top, width, height };
5592
+ }
5593
+ function placementStorageKey(base) {
5594
+ return `${base}:inspector`;
5595
+ }
5596
+ function loadPlacement(base) {
5597
+ if (base === null) return null;
5598
+ try {
5599
+ const raw = localStorage.getItem(placementStorageKey(base));
5600
+ if (!raw) return null;
5601
+ const p = JSON.parse(raw);
5602
+ if (p && (p.mode === "docked" || p.mode === "floating" || p.mode === "minimized") && p.rect && typeof p.rect.left === "number" && typeof p.rect.top === "number" && typeof p.rect.width === "number" && typeof p.rect.height === "number") {
5603
+ return p;
5604
+ }
5605
+ return null;
5606
+ } catch {
5607
+ return null;
5608
+ }
5609
+ }
5610
+ function savePlacement(base, p) {
5611
+ if (base === null) return;
5612
+ try {
5613
+ localStorage.setItem(placementStorageKey(base), JSON.stringify(p));
5614
+ } catch {
5615
+ }
5616
+ }
5617
+
5618
+ // src/inspector/InspectorFrame.tsx
5619
+ import { Fragment as Fragment7, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
5620
+ var FLOATING_Z = 40;
5621
+ var MIN_BAR_Z = 50;
5622
+ function InspectorFrame({
5623
+ mode,
5624
+ rect,
5625
+ dockedWidth,
5626
+ onRectChange,
5627
+ onDockedWidthChange,
5628
+ onRestore,
5629
+ onClose,
5630
+ children
5631
+ }) {
5632
+ const messages = useMessages();
5633
+ const startWidthDrag = (e) => {
5634
+ e.preventDefault();
5635
+ const startX = e.clientX;
5636
+ const startW = dockedWidth;
5637
+ const onMove = (ev) => onDockedWidthChange(Math.max(360, startW + (startX - ev.clientX)));
5638
+ const onUp = () => {
5639
+ document.removeEventListener("mousemove", onMove);
5640
+ document.removeEventListener("mouseup", onUp);
5641
+ };
5642
+ document.addEventListener("mousemove", onMove);
5643
+ document.addEventListener("mouseup", onUp);
5644
+ };
5645
+ const viewport = () => ({ w: window.innerWidth, h: window.innerHeight });
5646
+ const startMove = (e) => {
5647
+ const target = e.target;
5648
+ if (target.closest("button")) return;
5649
+ if (!target.closest("[data-inspector-drag-handle]")) return;
5650
+ e.preventDefault();
5651
+ const dx = e.clientX - rect.left;
5652
+ const dy = e.clientY - rect.top;
5653
+ const onMove = (ev) => onRectChange(clampRect({ ...rect, left: ev.clientX - dx, top: ev.clientY - dy }, viewport()));
5654
+ const onUp = () => {
5655
+ document.removeEventListener("mousemove", onMove);
5656
+ document.removeEventListener("mouseup", onUp);
5657
+ };
5658
+ document.addEventListener("mousemove", onMove);
5659
+ document.addEventListener("mouseup", onUp);
5660
+ };
5661
+ const startResize = (e) => {
5662
+ e.preventDefault();
5663
+ e.stopPropagation();
5664
+ const sx = e.clientX, sy = e.clientY, sw = rect.width, sh = rect.height;
5665
+ const onMove = (ev) => onRectChange(clampRect({ ...rect, width: Math.max(MIN_FLOAT_W, sw + (ev.clientX - sx)), height: Math.max(MIN_FLOAT_H, sh + (ev.clientY - sy)) }, viewport()));
5666
+ const onUp = () => {
5667
+ document.removeEventListener("mousemove", onMove);
5668
+ document.removeEventListener("mouseup", onUp);
5669
+ };
5670
+ document.addEventListener("mousemove", onMove);
5671
+ document.addEventListener("mouseup", onUp);
5672
+ };
5673
+ const floating = mode === "floating";
5674
+ const minimized = mode === "minimized";
5675
+ const style = floating || minimized ? {
5676
+ position: "fixed",
5677
+ left: rect.left,
5678
+ top: rect.top,
5679
+ width: rect.width,
5680
+ height: rect.height,
5681
+ zIndex: FLOATING_Z,
5682
+ boxShadow: "0 24px 50px -12px rgba(15,23,42,0.45)",
5683
+ borderRadius: 12,
5684
+ overflow: "hidden",
5685
+ display: minimized ? "none" : "flex"
5686
+ } : { position: "relative", flex: `0 0 ${dockedWidth}px`, width: dockedWidth, height: "100%", display: "flex" };
5687
+ return /* @__PURE__ */ jsxs15(Fragment7, { children: [
5688
+ mode === "docked" && /* @__PURE__ */ jsx17(
5689
+ "div",
5690
+ {
5691
+ "data-testid": "inspector-resize-handle",
5692
+ onMouseDown: startWidthDrag,
5693
+ style: { width: 3, flexShrink: 0, cursor: "col-resize", background: "transparent", borderLeft: `1px solid ${colors.borderSubtle}`, zIndex: 10 },
5694
+ onMouseEnter: (e) => e.currentTarget.style.background = colors.border,
5695
+ onMouseLeave: (e) => e.currentTarget.style.background = "transparent"
5696
+ }
5697
+ ),
5698
+ /* @__PURE__ */ jsxs15(
5699
+ "div",
5700
+ {
5701
+ "data-testid": "inspector-frame",
5702
+ onMouseDownCapture: floating ? startMove : void 0,
5703
+ style,
5704
+ children: [
5705
+ children,
5706
+ floating && /* @__PURE__ */ jsx17(
5707
+ "div",
5708
+ {
5709
+ "data-testid": "inspector-resize-grip",
5710
+ onMouseDown: startResize,
5711
+ style: { position: "absolute", right: 2, bottom: 2, width: 16, height: 16, cursor: "nwse-resize", zIndex: 5 }
5712
+ }
5713
+ )
5714
+ ]
5715
+ }
5716
+ ),
5717
+ minimized && /* @__PURE__ */ jsxs15(
5718
+ "div",
5719
+ {
5720
+ "data-testid": "inspector-min-bar",
5721
+ onClick: onRestore,
5722
+ title: messages.inspector.restore,
5723
+ style: minBarStyle,
5724
+ children: [
5725
+ /* @__PURE__ */ jsx17("span", { style: { width: 8, height: 8, borderRadius: "50%", background: colors.primary, flex: "0 0 auto" } }),
5726
+ /* @__PURE__ */ jsx17("span", { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", fontSize: 12, color: colors.textSecondary }, children: messages.inspector.minimizedTitle }),
5727
+ /* @__PURE__ */ jsx17(
5728
+ "button",
5729
+ {
5730
+ type: "button",
5731
+ "data-testid": "inspector-restore",
5732
+ "aria-label": messages.inspector.restore,
5733
+ title: messages.inspector.restore,
5734
+ onClick: (e) => {
5735
+ e.stopPropagation();
5736
+ onRestore();
5737
+ },
5738
+ style: barBtnStyle,
5739
+ children: "\u2922"
5740
+ }
5741
+ ),
5742
+ onClose && /* @__PURE__ */ jsx17(
5743
+ "button",
5744
+ {
5745
+ type: "button",
5746
+ "data-testid": "inspector-min-close",
5747
+ "aria-label": "Close inspector",
5748
+ title: "Close inspector",
5749
+ onClick: (e) => {
5750
+ e.stopPropagation();
5751
+ onClose();
5752
+ },
5753
+ style: { ...barBtnStyle, fontSize: 16 },
5754
+ children: "\xD7"
5755
+ }
5756
+ )
5757
+ ]
5758
+ }
5759
+ )
5760
+ ] });
5761
+ }
5762
+ var minBarStyle = {
5763
+ position: "fixed",
5764
+ right: 16,
5765
+ bottom: 16,
5766
+ zIndex: MIN_BAR_Z,
5767
+ display: "flex",
5768
+ alignItems: "center",
5769
+ gap: 8,
5770
+ width: 260,
5771
+ height: 40,
5772
+ padding: "0 6px 0 12px",
5773
+ borderRadius: 10,
5774
+ background: "white",
5775
+ border: `1px solid ${colors.border}`,
5776
+ boxShadow: "0 12px 28px -10px rgba(15,23,42,0.4)",
5777
+ cursor: "pointer",
5778
+ userSelect: "none"
5779
+ };
5780
+ var barBtnStyle = {
5781
+ width: 24,
5782
+ height: 24,
5783
+ flex: "0 0 auto",
5784
+ border: `1px solid ${colors.border}`,
5785
+ borderRadius: radii.sm,
5786
+ background: "white",
5787
+ color: colors.textSecondary,
5788
+ cursor: "pointer",
5789
+ display: "inline-flex",
5790
+ alignItems: "center",
5791
+ justifyContent: "center",
5792
+ padding: 0,
5793
+ fontSize: 13
5794
+ };
5795
+
5725
5796
  // src/toolbar/Toolbar.tsx
5726
- import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
5797
+ import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
5727
5798
  function Toolbar({
5728
5799
  derived,
5729
5800
  readOnly,
@@ -5737,7 +5808,7 @@ function Toolbar({
5737
5808
  toolbarEnd
5738
5809
  }) {
5739
5810
  const messages = useMessages();
5740
- return /* @__PURE__ */ jsxs14(
5811
+ return /* @__PURE__ */ jsxs16(
5741
5812
  "footer",
5742
5813
  {
5743
5814
  style: {
@@ -5752,11 +5823,11 @@ function Toolbar({
5752
5823
  },
5753
5824
  "data-testid": "toolbar",
5754
5825
  children: [
5755
- toolbarStart && /* @__PURE__ */ jsx16("div", { style: slotStyle, "data-testid": "toolbar-start", children: toolbarStart }),
5756
- toolbarCenter && /* @__PURE__ */ jsx16("div", { style: { ...slotStyle, flex: 1, justifyContent: "center" }, "data-testid": "toolbar-center", children: toolbarCenter }),
5757
- !toolbarCenter && /* @__PURE__ */ jsx16("div", { style: { flex: 1 } }),
5758
- /* @__PURE__ */ jsxs14("span", { role: "status", "aria-live": "polite", style: { display: "inline-flex", gap: 6 }, children: [
5759
- /* @__PURE__ */ jsx16(
5826
+ toolbarStart && /* @__PURE__ */ jsx18("div", { style: slotStyle, "data-testid": "toolbar-start", children: toolbarStart }),
5827
+ toolbarCenter && /* @__PURE__ */ jsx18("div", { style: { ...slotStyle, flex: 1, justifyContent: "center" }, "data-testid": "toolbar-center", children: toolbarCenter }),
5828
+ !toolbarCenter && /* @__PURE__ */ jsx18("div", { style: { flex: 1 } }),
5829
+ /* @__PURE__ */ jsxs16("span", { role: "status", "aria-live": "polite", style: { display: "inline-flex", gap: 6 }, children: [
5830
+ /* @__PURE__ */ jsx18(
5760
5831
  ValidationPill,
5761
5832
  {
5762
5833
  severity: "error",
@@ -5768,7 +5839,7 @@ function Toolbar({
5768
5839
  testId: "toolbar-errors"
5769
5840
  }
5770
5841
  ),
5771
- /* @__PURE__ */ jsx16(
5842
+ /* @__PURE__ */ jsx18(
5772
5843
  ValidationPill,
5773
5844
  {
5774
5845
  severity: "warning",
@@ -5780,7 +5851,7 @@ function Toolbar({
5780
5851
  testId: "toolbar-warnings"
5781
5852
  }
5782
5853
  ),
5783
- /* @__PURE__ */ jsx16(
5854
+ /* @__PURE__ */ jsx18(
5784
5855
  ValidationPill,
5785
5856
  {
5786
5857
  severity: "info",
@@ -5793,7 +5864,7 @@ function Toolbar({
5793
5864
  }
5794
5865
  )
5795
5866
  ] }),
5796
- onSave && showSaveButton && /* @__PURE__ */ jsx16(
5867
+ onSave && showSaveButton && /* @__PURE__ */ jsx18(
5797
5868
  "button",
5798
5869
  {
5799
5870
  type: "button",
@@ -5804,7 +5875,7 @@ function Toolbar({
5804
5875
  children: messages.toolbar.save
5805
5876
  }
5806
5877
  ),
5807
- toolbarEnd && /* @__PURE__ */ jsx16("div", { style: slotStyle, "data-testid": "toolbar-end", children: toolbarEnd })
5878
+ toolbarEnd && /* @__PURE__ */ jsx18("div", { style: slotStyle, "data-testid": "toolbar-end", children: toolbarEnd })
5808
5879
  ]
5809
5880
  }
5810
5881
  );
@@ -5826,7 +5897,7 @@ function ValidationPill({
5826
5897
  const tone = severityTone(severity);
5827
5898
  const interactive = count > 0 && !!onClick;
5828
5899
  const hasIssues = count > 0;
5829
- return /* @__PURE__ */ jsxs14(
5900
+ return /* @__PURE__ */ jsxs16(
5830
5901
  "button",
5831
5902
  {
5832
5903
  type: "button",
@@ -5853,7 +5924,7 @@ function ValidationPill({
5853
5924
  height: 20
5854
5925
  },
5855
5926
  children: [
5856
- /* @__PURE__ */ jsx16("span", { style: { fontSize: severity === "info" ? 14 : 10, lineHeight: 1 }, children: SEVERITY_ICON[severity] }),
5927
+ /* @__PURE__ */ jsx18("span", { style: { fontSize: severity === "info" ? 14 : 10, lineHeight: 1 }, children: SEVERITY_ICON[severity] }),
5857
5928
  count
5858
5929
  ]
5859
5930
  }
@@ -5877,8 +5948,8 @@ var slotStyle = {
5877
5948
  };
5878
5949
 
5879
5950
  // src/toolbar/IssuesDrawer.tsx
5880
- import { useEffect as useEffect7, useMemo as useMemo5, useRef as useRef9 } from "react";
5881
- import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
5951
+ import { useEffect as useEffect8, useMemo as useMemo5, useRef as useRef10 } from "react";
5952
+ import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
5882
5953
  function resolveTarget(doc, targetId) {
5883
5954
  if (!targetId) return null;
5884
5955
  const ids = doc.meta.ids;
@@ -5931,8 +6002,8 @@ function IssuesDrawer({
5931
6002
  onJumpTo
5932
6003
  }) {
5933
6004
  const messages = useMessages();
5934
- const ref = useRef9(null);
5935
- useEffect7(() => {
6005
+ const ref = useRef10(null);
6006
+ useEffect8(() => {
5936
6007
  if (!open) return;
5937
6008
  function onKey(e) {
5938
6009
  if (e.key === "Escape") {
@@ -5967,7 +6038,7 @@ function IssuesDrawer({
5967
6038
  }, [severity, messages]);
5968
6039
  const tone = severityTone(severity);
5969
6040
  if (!open) return null;
5970
- return /* @__PURE__ */ jsxs15(
6041
+ return /* @__PURE__ */ jsxs17(
5971
6042
  "div",
5972
6043
  {
5973
6044
  ref,
@@ -5991,7 +6062,7 @@ function IssuesDrawer({
5991
6062
  flexDirection: "column"
5992
6063
  },
5993
6064
  children: [
5994
- /* @__PURE__ */ jsxs15(
6065
+ /* @__PURE__ */ jsxs17(
5995
6066
  "header",
5996
6067
  {
5997
6068
  style: {
@@ -6002,7 +6073,7 @@ function IssuesDrawer({
6002
6073
  gap: 8
6003
6074
  },
6004
6075
  children: [
6005
- /* @__PURE__ */ jsx17(
6076
+ /* @__PURE__ */ jsx19(
6006
6077
  "span",
6007
6078
  {
6008
6079
  style: {
@@ -6015,12 +6086,12 @@ function IssuesDrawer({
6015
6086
  "aria-hidden": true
6016
6087
  }
6017
6088
  ),
6018
- /* @__PURE__ */ jsxs15("strong", { style: { flex: 1, fontSize: 13, color: colors.textPrimary }, children: [
6089
+ /* @__PURE__ */ jsxs17("strong", { style: { flex: 1, fontSize: 13, color: colors.textPrimary }, children: [
6019
6090
  title,
6020
6091
  " \xB7 ",
6021
6092
  filtered.length
6022
6093
  ] }),
6023
- /* @__PURE__ */ jsx17(
6094
+ /* @__PURE__ */ jsx19(
6024
6095
  "button",
6025
6096
  {
6026
6097
  type: "button",
@@ -6043,14 +6114,14 @@ function IssuesDrawer({
6043
6114
  ]
6044
6115
  }
6045
6116
  ),
6046
- filtered.length === 0 ? /* @__PURE__ */ jsx17(
6117
+ filtered.length === 0 ? /* @__PURE__ */ jsx19(
6047
6118
  "p",
6048
6119
  {
6049
6120
  style: { padding: 12, color: colors.textTertiary, fontSize: 12, margin: 0 },
6050
6121
  "data-testid": "issues-drawer-empty",
6051
6122
  children: messages.issues.none
6052
6123
  }
6053
- ) : /* @__PURE__ */ jsx17(
6124
+ ) : /* @__PURE__ */ jsx19(
6054
6125
  "ul",
6055
6126
  {
6056
6127
  style: {
@@ -6064,7 +6135,7 @@ function IssuesDrawer({
6064
6135
  children: filtered.map((issue, idx) => {
6065
6136
  const target = resolveTarget(doc, issue.targetId);
6066
6137
  const targetLabel = target ? target.kind === "transition" ? `${messages.issues.relatedTransition}: ${target.label}` : target.kind === "state" ? `${messages.issues.relatedState}: ${target.label}` : target.label : null;
6067
- return /* @__PURE__ */ jsxs15(
6138
+ return /* @__PURE__ */ jsxs17(
6068
6139
  "li",
6069
6140
  {
6070
6141
  style: {
@@ -6078,10 +6149,10 @@ function IssuesDrawer({
6078
6149
  },
6079
6150
  "data-testid": `issues-drawer-item-${idx}`,
6080
6151
  children: [
6081
- /* @__PURE__ */ jsx17("div", { style: { fontSize: 11, fontWeight: 700, color: tone.fg }, children: issue.code }),
6082
- /* @__PURE__ */ jsx17("div", { style: { fontSize: 12, color: colors.textPrimary }, children: issue.message }),
6083
- targetLabel && /* @__PURE__ */ jsx17("div", { style: { fontSize: 11, color: colors.textSecondary }, children: targetLabel }),
6084
- target && /* @__PURE__ */ jsx17("div", { children: /* @__PURE__ */ jsx17(
6152
+ /* @__PURE__ */ jsx19("div", { style: { fontSize: 11, fontWeight: 700, color: tone.fg }, children: issue.code }),
6153
+ /* @__PURE__ */ jsx19("div", { style: { fontSize: 12, color: colors.textPrimary }, children: issue.message }),
6154
+ targetLabel && /* @__PURE__ */ jsx19("div", { style: { fontSize: 11, color: colors.textSecondary }, children: targetLabel }),
6155
+ target && /* @__PURE__ */ jsx19("div", { children: /* @__PURE__ */ jsx19(
6085
6156
  "button",
6086
6157
  {
6087
6158
  type: "button",
@@ -6116,12 +6187,12 @@ function IssuesDrawer({
6116
6187
  }
6117
6188
 
6118
6189
  // src/toolbar/WorkflowTabs.tsx
6119
- import { useEffect as useEffect9, useRef as useRef11, useState as useState13 } from "react";
6190
+ import { useEffect as useEffect10, useRef as useRef12, useState as useState13 } from "react";
6120
6191
 
6121
6192
  // src/toolbar/VersionBadge.tsx
6122
- import { useEffect as useEffect8, useRef as useRef10, useState as useState12 } from "react";
6193
+ import { useEffect as useEffect9, useRef as useRef11, useState as useState12 } from "react";
6123
6194
  import { createPortal as createPortal2 } from "react-dom";
6124
- import { Fragment as Fragment7, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
6195
+ import { Fragment as Fragment8, jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
6125
6196
  function VersionBadge({
6126
6197
  version,
6127
6198
  supportedVersions,
@@ -6130,9 +6201,9 @@ function VersionBadge({
6130
6201
  }) {
6131
6202
  const [open, setOpen] = useState12(false);
6132
6203
  const [dropdownPos, setDropdownPos] = useState12(null);
6133
- const buttonRef = useRef10(null);
6134
- const dropdownRef = useRef10(null);
6135
- useEffect8(() => {
6204
+ const buttonRef = useRef11(null);
6205
+ const dropdownRef = useRef11(null);
6206
+ useEffect9(() => {
6136
6207
  if (!open) return;
6137
6208
  const handler = (e) => {
6138
6209
  const target = e.target;
@@ -6154,7 +6225,7 @@ function VersionBadge({
6154
6225
  setOpen((o) => !o);
6155
6226
  };
6156
6227
  if (readOnly) {
6157
- return /* @__PURE__ */ jsx18(
6228
+ return /* @__PURE__ */ jsx20(
6158
6229
  "div",
6159
6230
  {
6160
6231
  "data-testid": "version-badge",
@@ -6173,7 +6244,7 @@ function VersionBadge({
6173
6244
  );
6174
6245
  }
6175
6246
  const dropdown = open && dropdownPos ? createPortal2(
6176
- /* @__PURE__ */ jsxs16(
6247
+ /* @__PURE__ */ jsxs18(
6177
6248
  "div",
6178
6249
  {
6179
6250
  ref: dropdownRef,
@@ -6192,7 +6263,7 @@ function VersionBadge({
6192
6263
  zIndex: 9999
6193
6264
  },
6194
6265
  children: [
6195
- /* @__PURE__ */ jsx18(
6266
+ /* @__PURE__ */ jsx20(
6196
6267
  "div",
6197
6268
  {
6198
6269
  style: {
@@ -6209,7 +6280,7 @@ function VersionBadge({
6209
6280
  ),
6210
6281
  [...supportedVersions].reverse().map((v) => {
6211
6282
  const isCurrent = v === version.replace(/^v/, "");
6212
- return /* @__PURE__ */ jsxs16(
6283
+ return /* @__PURE__ */ jsxs18(
6213
6284
  "button",
6214
6285
  {
6215
6286
  type: "button",
@@ -6232,16 +6303,16 @@ function VersionBadge({
6232
6303
  textAlign: "left"
6233
6304
  },
6234
6305
  children: [
6235
- /* @__PURE__ */ jsxs16("span", { children: [
6306
+ /* @__PURE__ */ jsxs18("span", { children: [
6236
6307
  v,
6237
6308
  " ",
6238
- /* @__PURE__ */ jsxs16("span", { style: { fontSize: 11, color: isCurrent ? "#93C5FD" : "#94A3B8" }, children: [
6309
+ /* @__PURE__ */ jsxs18("span", { style: { fontSize: 11, color: isCurrent ? "#93C5FD" : "#94A3B8" }, children: [
6239
6310
  "cyoda-go ",
6240
6311
  v,
6241
6312
  ".x"
6242
6313
  ] })
6243
6314
  ] }),
6244
- isCurrent && /* @__PURE__ */ jsx18(
6315
+ isCurrent && /* @__PURE__ */ jsx20(
6245
6316
  "span",
6246
6317
  {
6247
6318
  style: {
@@ -6265,8 +6336,8 @@ function VersionBadge({
6265
6336
  ),
6266
6337
  document.body
6267
6338
  ) : null;
6268
- return /* @__PURE__ */ jsxs16(Fragment7, { children: [
6269
- /* @__PURE__ */ jsxs16(
6339
+ return /* @__PURE__ */ jsxs18(Fragment8, { children: [
6340
+ /* @__PURE__ */ jsxs18(
6270
6341
  "button",
6271
6342
  {
6272
6343
  ref: buttonRef,
@@ -6289,7 +6360,7 @@ function VersionBadge({
6289
6360
  },
6290
6361
  children: [
6291
6362
  version,
6292
- /* @__PURE__ */ jsx18("span", { style: { fontSize: 10, opacity: 0.7 }, children: open ? "\u25B4" : "\u25BE" })
6363
+ /* @__PURE__ */ jsx20("span", { style: { fontSize: 10, opacity: 0.7 }, children: open ? "\u25B4" : "\u25BE" })
6293
6364
  ]
6294
6365
  }
6295
6366
  ),
@@ -6298,7 +6369,7 @@ function VersionBadge({
6298
6369
  }
6299
6370
 
6300
6371
  // src/toolbar/WorkflowTabs.tsx
6301
- import { Fragment as Fragment8, jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
6372
+ import { Fragment as Fragment9, jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
6302
6373
  function WorkflowTabs({
6303
6374
  workflows,
6304
6375
  activeWorkflow,
@@ -6314,8 +6385,8 @@ function WorkflowTabs({
6314
6385
  const messages = useMessages();
6315
6386
  const [editingTab, setEditingTab] = useState13(null);
6316
6387
  const [draftName, setDraftName] = useState13("");
6317
- const inputRef = useRef11(null);
6318
- useEffect9(() => {
6388
+ const inputRef = useRef12(null);
6389
+ useEffect10(() => {
6319
6390
  if (editingTab !== null) inputRef.current?.select();
6320
6391
  }, [editingTab]);
6321
6392
  const startEditing = (name) => {
@@ -6335,7 +6406,7 @@ function WorkflowTabs({
6335
6406
  setEditingTab(null);
6336
6407
  };
6337
6408
  const cancelEdit = () => setEditingTab(null);
6338
- return /* @__PURE__ */ jsxs17(
6409
+ return /* @__PURE__ */ jsxs19(
6339
6410
  "nav",
6340
6411
  {
6341
6412
  style: {
@@ -6353,7 +6424,7 @@ function WorkflowTabs({
6353
6424
  workflows.map((w) => {
6354
6425
  const active = w.name === activeWorkflow;
6355
6426
  const isEditing = editingTab === w.name;
6356
- return /* @__PURE__ */ jsxs17(
6427
+ return /* @__PURE__ */ jsxs19(
6357
6428
  "div",
6358
6429
  {
6359
6430
  style: {
@@ -6364,7 +6435,7 @@ function WorkflowTabs({
6364
6435
  background: active ? "white" : "transparent"
6365
6436
  },
6366
6437
  children: [
6367
- isEditing ? /* @__PURE__ */ jsx19(
6438
+ isEditing ? /* @__PURE__ */ jsx21(
6368
6439
  "input",
6369
6440
  {
6370
6441
  ref: inputRef,
@@ -6395,7 +6466,7 @@ function WorkflowTabs({
6395
6466
  width: Math.max(60, draftName.length * 8)
6396
6467
  }
6397
6468
  }
6398
- ) : /* @__PURE__ */ jsx19(
6469
+ ) : /* @__PURE__ */ jsx21(
6399
6470
  "button",
6400
6471
  {
6401
6472
  type: "button",
@@ -6414,7 +6485,7 @@ function WorkflowTabs({
6414
6485
  children: w.name || messages.tabs.untitled
6415
6486
  }
6416
6487
  ),
6417
- onClose && !readOnly && workflows.length > 1 && !isEditing && /* @__PURE__ */ jsx19(
6488
+ onClose && !readOnly && workflows.length > 1 && !isEditing && /* @__PURE__ */ jsx21(
6418
6489
  "button",
6419
6490
  {
6420
6491
  type: "button",
@@ -6437,7 +6508,7 @@ function WorkflowTabs({
6437
6508
  w.name
6438
6509
  );
6439
6510
  }),
6440
- onAdd && !readOnly && /* @__PURE__ */ jsxs17(
6511
+ onAdd && !readOnly && /* @__PURE__ */ jsxs19(
6441
6512
  "button",
6442
6513
  {
6443
6514
  type: "button",
@@ -6462,9 +6533,9 @@ function WorkflowTabs({
6462
6533
  ]
6463
6534
  }
6464
6535
  ),
6465
- dialectVersion && /* @__PURE__ */ jsxs17(Fragment8, { children: [
6466
- /* @__PURE__ */ jsx19("div", { style: { flex: 1 } }),
6467
- /* @__PURE__ */ jsx19(
6536
+ dialectVersion && /* @__PURE__ */ jsxs19(Fragment9, { children: [
6537
+ /* @__PURE__ */ jsx21("div", { style: { flex: 1 } }),
6538
+ /* @__PURE__ */ jsx21(
6468
6539
  VersionBadge,
6469
6540
  {
6470
6541
  version: dialectVersion,
@@ -6482,7 +6553,7 @@ function WorkflowTabs({
6482
6553
  // src/modals/DragConnectModal.tsx
6483
6554
  import { useState as useState14 } from "react";
6484
6555
  import { NAME_REGEX as NAME_REGEX4 } from "@cyoda/workflow-core";
6485
- import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
6556
+ import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
6486
6557
  function generateDefault(toState, existing) {
6487
6558
  const base = `to_${toState}`;
6488
6559
  if (!existing.has(base)) return base;
@@ -6503,16 +6574,16 @@ function DragConnectModal({
6503
6574
  const invalidFormat = !!name && !NAME_REGEX4.test(name);
6504
6575
  const duplicate = existing.has(name);
6505
6576
  const blocked = name.length === 0 || invalidFormat || duplicate;
6506
- return /* @__PURE__ */ jsxs18(ModalFrame, { onCancel, children: [
6507
- /* @__PURE__ */ jsx20("h2", { style: { margin: 0, fontSize: 16 }, children: messages.dragConnect.title }),
6508
- /* @__PURE__ */ jsxs18("p", { style: { margin: "6px 0 14px", fontSize: 12, color: colors.textSecondary }, children: [
6577
+ return /* @__PURE__ */ jsxs20(ModalFrame, { onCancel, children: [
6578
+ /* @__PURE__ */ jsx22("h2", { style: { margin: 0, fontSize: 16 }, children: messages.dragConnect.title }),
6579
+ /* @__PURE__ */ jsxs20("p", { style: { margin: "6px 0 14px", fontSize: 12, color: colors.textSecondary }, children: [
6509
6580
  fromState,
6510
6581
  " \u2192 ",
6511
6582
  toState
6512
6583
  ] }),
6513
- /* @__PURE__ */ jsxs18("label", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
6514
- /* @__PURE__ */ jsx20("span", { style: { fontSize: 12, color: colors.textSecondary }, children: messages.dragConnect.transitionName }),
6515
- /* @__PURE__ */ jsx20(
6584
+ /* @__PURE__ */ jsxs20("label", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
6585
+ /* @__PURE__ */ jsx22("span", { style: { fontSize: 12, color: colors.textSecondary }, children: messages.dragConnect.transitionName }),
6586
+ /* @__PURE__ */ jsx22(
6516
6587
  "input",
6517
6588
  {
6518
6589
  type: "text",
@@ -6532,17 +6603,17 @@ function DragConnectModal({
6532
6603
  }
6533
6604
  )
6534
6605
  ] }),
6535
- invalidFormat && /* @__PURE__ */ jsx20("div", { style: errorMsg, "data-testid": "dragconnect-error-format", children: messages.dragConnect.invalidName }),
6536
- duplicate && /* @__PURE__ */ jsx20("div", { style: errorMsg, "data-testid": "dragconnect-error-duplicate", children: messages.dragConnect.duplicateName }),
6537
- /* @__PURE__ */ jsxs18("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 16 }, children: [
6538
- /* @__PURE__ */ jsx20("button", { type: "button", onClick: onCancel, style: ghostBtn7, "data-testid": "dragconnect-cancel", children: messages.dragConnect.cancel }),
6539
- /* @__PURE__ */ jsx20(
6606
+ invalidFormat && /* @__PURE__ */ jsx22("div", { style: errorMsg, "data-testid": "dragconnect-error-format", children: messages.dragConnect.invalidName }),
6607
+ duplicate && /* @__PURE__ */ jsx22("div", { style: errorMsg, "data-testid": "dragconnect-error-duplicate", children: messages.dragConnect.duplicateName }),
6608
+ /* @__PURE__ */ jsxs20("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 16 }, children: [
6609
+ /* @__PURE__ */ jsx22("button", { type: "button", onClick: onCancel, style: ghostBtn6, "data-testid": "dragconnect-cancel", children: messages.dragConnect.cancel }),
6610
+ /* @__PURE__ */ jsx22(
6540
6611
  "button",
6541
6612
  {
6542
6613
  type: "button",
6543
6614
  onClick: () => !blocked && onCreate(name),
6544
6615
  disabled: blocked,
6545
- style: primaryBtn4,
6616
+ style: primaryBtn3,
6546
6617
  "data-testid": "dragconnect-create",
6547
6618
  children: messages.dragConnect.create
6548
6619
  }
@@ -6555,7 +6626,7 @@ var errorMsg = {
6555
6626
  fontSize: 12,
6556
6627
  color: colors.danger
6557
6628
  };
6558
- var ghostBtn7 = {
6629
+ var ghostBtn6 = {
6559
6630
  padding: "6px 12px",
6560
6631
  background: "white",
6561
6632
  border: `1px solid ${colors.border}`,
@@ -6563,17 +6634,17 @@ var ghostBtn7 = {
6563
6634
  fontSize: 13,
6564
6635
  cursor: "pointer"
6565
6636
  };
6566
- var primaryBtn4 = {
6567
- ...ghostBtn7,
6637
+ var primaryBtn3 = {
6638
+ ...ghostBtn6,
6568
6639
  background: colors.primary,
6569
6640
  color: "white",
6570
6641
  borderColor: colors.primary
6571
6642
  };
6572
6643
 
6573
6644
  // src/modals/AddStateModal.tsx
6574
- import { useEffect as useEffect10, useRef as useRef12, useState as useState15 } from "react";
6645
+ import { useEffect as useEffect11, useRef as useRef13, useState as useState15 } from "react";
6575
6646
  import { NAME_REGEX as NAME_REGEX5 } from "@cyoda/workflow-core";
6576
- import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
6647
+ import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
6577
6648
  function generateName(existing) {
6578
6649
  let n = 1;
6579
6650
  while (existing.includes(`state${n}`)) n++;
@@ -6582,8 +6653,8 @@ function generateName(existing) {
6582
6653
  function AddStateModal({ existingNames, onCreate, onCancel }) {
6583
6654
  const [name, setName] = useState15(() => generateName(existingNames));
6584
6655
  const [error, setError] = useState15(null);
6585
- const inputRef = useRef12(null);
6586
- useEffect10(() => {
6656
+ const inputRef = useRef13(null);
6657
+ useEffect11(() => {
6587
6658
  inputRef.current?.select();
6588
6659
  }, []);
6589
6660
  const validate = (v) => {
@@ -6601,11 +6672,11 @@ function AddStateModal({ existingNames, onCreate, onCancel }) {
6601
6672
  }
6602
6673
  onCreate(name.trim());
6603
6674
  };
6604
- return /* @__PURE__ */ jsxs19(ModalFrame, { onCancel, labelledBy: "add-state-title", children: [
6605
- /* @__PURE__ */ jsx21("h2", { id: "add-state-title", style: { margin: 0, fontSize: 16 }, children: "Add State" }),
6606
- /* @__PURE__ */ jsxs19("div", { style: { marginTop: 16, display: "flex", flexDirection: "column", gap: 6 }, children: [
6607
- /* @__PURE__ */ jsx21("label", { htmlFor: "add-state-name-input", style: { fontSize: 12, color: colors.textSecondary }, children: "State name" }),
6608
- /* @__PURE__ */ jsx21(
6675
+ return /* @__PURE__ */ jsxs21(ModalFrame, { onCancel, labelledBy: "add-state-title", children: [
6676
+ /* @__PURE__ */ jsx23("h2", { id: "add-state-title", style: { margin: 0, fontSize: 16 }, children: "Add State" }),
6677
+ /* @__PURE__ */ jsxs21("div", { style: { marginTop: 16, display: "flex", flexDirection: "column", gap: 6 }, children: [
6678
+ /* @__PURE__ */ jsx23("label", { htmlFor: "add-state-name-input", style: { fontSize: 12, color: colors.textSecondary }, children: "State name" }),
6679
+ /* @__PURE__ */ jsx23(
6609
6680
  "input",
6610
6681
  {
6611
6682
  ref: inputRef,
@@ -6631,7 +6702,7 @@ function AddStateModal({ existingNames, onCreate, onCancel }) {
6631
6702
  }
6632
6703
  }
6633
6704
  ),
6634
- error && /* @__PURE__ */ jsx21(
6705
+ error && /* @__PURE__ */ jsx23(
6635
6706
  "div",
6636
6707
  {
6637
6708
  id: "add-state-error",
@@ -6641,23 +6712,23 @@ function AddStateModal({ existingNames, onCreate, onCancel }) {
6641
6712
  }
6642
6713
  )
6643
6714
  ] }),
6644
- /* @__PURE__ */ jsxs19("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 20 }, children: [
6645
- /* @__PURE__ */ jsx21(
6715
+ /* @__PURE__ */ jsxs21("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 20 }, children: [
6716
+ /* @__PURE__ */ jsx23(
6646
6717
  "button",
6647
6718
  {
6648
6719
  type: "button",
6649
6720
  onClick: onCancel,
6650
- style: ghostBtn8,
6721
+ style: ghostBtn7,
6651
6722
  "data-testid": "add-state-cancel",
6652
6723
  children: "Cancel"
6653
6724
  }
6654
6725
  ),
6655
- /* @__PURE__ */ jsx21(
6726
+ /* @__PURE__ */ jsx23(
6656
6727
  "button",
6657
6728
  {
6658
6729
  type: "button",
6659
6730
  onClick: handleSubmit,
6660
- style: primaryBtn5,
6731
+ style: primaryBtn4,
6661
6732
  "data-testid": "add-state-confirm",
6662
6733
  children: "Add State"
6663
6734
  }
@@ -6665,7 +6736,7 @@ function AddStateModal({ existingNames, onCreate, onCancel }) {
6665
6736
  ] })
6666
6737
  ] });
6667
6738
  }
6668
- var ghostBtn8 = {
6739
+ var ghostBtn7 = {
6669
6740
  padding: "6px 12px",
6670
6741
  background: "white",
6671
6742
  border: `1px solid ${colors.border}`,
@@ -6673,8 +6744,8 @@ var ghostBtn8 = {
6673
6744
  fontSize: 13,
6674
6745
  cursor: "pointer"
6675
6746
  };
6676
- var primaryBtn5 = {
6677
- ...ghostBtn8,
6747
+ var primaryBtn4 = {
6748
+ ...ghostBtn7,
6678
6749
  background: colors.primary,
6679
6750
  color: "white",
6680
6751
  borderColor: colors.primary
@@ -6682,15 +6753,15 @@ var primaryBtn5 = {
6682
6753
 
6683
6754
  // src/modals/HelpModal.tsx
6684
6755
  import { workflowPalette as workflowPalette5 } from "@cyoda/workflow-viewer/theme";
6685
- import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
6756
+ import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
6686
6757
  function HelpModal({ onCancel }) {
6687
6758
  const messages = useMessages();
6688
6759
  const h = messages.help;
6689
6760
  const node = workflowPalette5.node;
6690
6761
  const edge = workflowPalette5.edge;
6691
- return /* @__PURE__ */ jsx22(ModalFrame, { onCancel, labelledBy: "workflow-help-title", children: /* @__PURE__ */ jsxs20("div", { style: { width: 480, maxWidth: "85vw" }, children: [
6692
- /* @__PURE__ */ jsx22("h2", { id: "workflow-help-title", style: { margin: 0, fontSize: 16 }, children: h.title }),
6693
- /* @__PURE__ */ jsxs20(
6762
+ return /* @__PURE__ */ jsx24(ModalFrame, { onCancel, labelledBy: "workflow-help-title", children: /* @__PURE__ */ jsxs22("div", { style: { width: 480, maxWidth: "85vw" }, children: [
6763
+ /* @__PURE__ */ jsx24("h2", { id: "workflow-help-title", style: { margin: 0, fontSize: 16 }, children: h.title }),
6764
+ /* @__PURE__ */ jsxs22(
6694
6765
  "div",
6695
6766
  {
6696
6767
  style: {
@@ -6703,48 +6774,48 @@ function HelpModal({ onCancel }) {
6703
6774
  gap: 16
6704
6775
  },
6705
6776
  children: [
6706
- /* @__PURE__ */ jsxs20(Section, { title: h.statesTitle, children: [
6707
- /* @__PURE__ */ jsx22(ColorRow, { fill: node.initial.fill, border: node.initial.border, label: h.stateInitial }),
6708
- /* @__PURE__ */ jsx22(ColorRow, { fill: node.default.fill, border: node.default.border, label: h.stateDefault }),
6709
- /* @__PURE__ */ jsx22(ColorRow, { fill: node.processing.fill, border: node.processing.border, label: h.stateProcessing }),
6710
- /* @__PURE__ */ jsx22(ColorRow, { fill: node.manualReview.fill, border: node.manualReview.border, label: h.stateManualReview }),
6711
- /* @__PURE__ */ jsx22(ColorRow, { fill: node.terminal.fill, border: node.terminal.border, label: h.stateTerminal }),
6712
- /* @__PURE__ */ jsx22(ColorRow, { fill: "#FFFFFF", border: colors.danger, label: h.stateError }),
6713
- /* @__PURE__ */ jsx22(ColorRow, { fill: "#FFFFFF", border: colors.warning, label: h.stateWarning })
6777
+ /* @__PURE__ */ jsxs22(Section, { title: h.statesTitle, children: [
6778
+ /* @__PURE__ */ jsx24(ColorRow, { fill: node.initial.fill, border: node.initial.border, label: h.stateInitial }),
6779
+ /* @__PURE__ */ jsx24(ColorRow, { fill: node.default.fill, border: node.default.border, label: h.stateDefault }),
6780
+ /* @__PURE__ */ jsx24(ColorRow, { fill: node.processing.fill, border: node.processing.border, label: h.stateProcessing }),
6781
+ /* @__PURE__ */ jsx24(ColorRow, { fill: node.manualReview.fill, border: node.manualReview.border, label: h.stateManualReview }),
6782
+ /* @__PURE__ */ jsx24(ColorRow, { fill: node.terminal.fill, border: node.terminal.border, label: h.stateTerminal }),
6783
+ /* @__PURE__ */ jsx24(ColorRow, { fill: "#FFFFFF", border: colors.danger, label: h.stateError }),
6784
+ /* @__PURE__ */ jsx24(ColorRow, { fill: "#FFFFFF", border: colors.warning, label: h.stateWarning })
6714
6785
  ] }),
6715
- /* @__PURE__ */ jsxs20(Section, { title: h.transitionsTitle, children: [
6716
- /* @__PURE__ */ jsx22(LineRow, { color: edge.automated, label: h.transitionAutomated }),
6717
- /* @__PURE__ */ jsx22(LineRow, { color: edge.manual, dashed: true, label: h.transitionManual }),
6718
- /* @__PURE__ */ jsx22(LineRow, { color: edge.conditional, label: h.transitionConditional }),
6719
- /* @__PURE__ */ jsx22(LineRow, { color: edge.processing, label: h.transitionProcessing }),
6720
- /* @__PURE__ */ jsx22(LineRow, { color: edge.terminal, label: h.transitionTerminal }),
6721
- /* @__PURE__ */ jsx22(LineRow, { color: edge.loop, label: h.transitionLoop }),
6722
- /* @__PURE__ */ jsx22(LineRow, { color: edge.disabled, label: h.transitionDisabled })
6786
+ /* @__PURE__ */ jsxs22(Section, { title: h.transitionsTitle, children: [
6787
+ /* @__PURE__ */ jsx24(LineRow, { color: edge.automated, label: h.transitionAutomated }),
6788
+ /* @__PURE__ */ jsx24(LineRow, { color: edge.manual, dashed: true, label: h.transitionManual }),
6789
+ /* @__PURE__ */ jsx24(LineRow, { color: edge.conditional, label: h.transitionConditional }),
6790
+ /* @__PURE__ */ jsx24(LineRow, { color: edge.processing, label: h.transitionProcessing }),
6791
+ /* @__PURE__ */ jsx24(LineRow, { color: edge.terminal, label: h.transitionTerminal }),
6792
+ /* @__PURE__ */ jsx24(LineRow, { color: edge.loop, label: h.transitionLoop }),
6793
+ /* @__PURE__ */ jsx24(LineRow, { color: edge.disabled, label: h.transitionDisabled })
6723
6794
  ] }),
6724
- /* @__PURE__ */ jsxs20(Section, { title: h.controlsTitle, children: [
6725
- /* @__PURE__ */ jsx22(ShortcutRow, { keys: "A", label: h.shortcutAddState }),
6726
- /* @__PURE__ */ jsx22(ShortcutRow, { keys: "L", label: h.shortcutAutoLayout }),
6727
- /* @__PURE__ */ jsx22(ShortcutRow, { keys: "Ctrl/\u2318 Z", label: h.shortcutUndo }),
6728
- /* @__PURE__ */ jsx22(ShortcutRow, { keys: "Ctrl/\u2318 \u21E7 Z", label: h.shortcutRedo }),
6729
- /* @__PURE__ */ jsx22(ShortcutRow, { keys: "Ctrl/\u2318 S", label: h.shortcutSave }),
6730
- /* @__PURE__ */ jsx22(ShortcutRow, { keys: "Delete", label: h.shortcutDelete }),
6731
- /* @__PURE__ */ jsx22(ShortcutRow, { keys: "Esc", label: h.shortcutEscape })
6795
+ /* @__PURE__ */ jsxs22(Section, { title: h.controlsTitle, children: [
6796
+ /* @__PURE__ */ jsx24(ShortcutRow, { keys: "A", label: h.shortcutAddState }),
6797
+ /* @__PURE__ */ jsx24(ShortcutRow, { keys: "L", label: h.shortcutAutoLayout }),
6798
+ /* @__PURE__ */ jsx24(ShortcutRow, { keys: "Ctrl/\u2318 Z", label: h.shortcutUndo }),
6799
+ /* @__PURE__ */ jsx24(ShortcutRow, { keys: "Ctrl/\u2318 \u21E7 Z", label: h.shortcutRedo }),
6800
+ /* @__PURE__ */ jsx24(ShortcutRow, { keys: "Ctrl/\u2318 S", label: h.shortcutSave }),
6801
+ /* @__PURE__ */ jsx24(ShortcutRow, { keys: "Delete", label: h.shortcutDelete }),
6802
+ /* @__PURE__ */ jsx24(ShortcutRow, { keys: "Esc", label: h.shortcutEscape })
6732
6803
  ] }),
6733
- /* @__PURE__ */ jsx22(Section, { title: h.tipsTitle, children: /* @__PURE__ */ jsxs20("ul", { style: { margin: 0, paddingLeft: 18, fontSize: 13, color: colors.textSecondary, display: "flex", flexDirection: "column", gap: 6 }, children: [
6734
- /* @__PURE__ */ jsx22("li", { children: h.tipDoubleClick }),
6735
- /* @__PURE__ */ jsx22("li", { children: h.tipConnect }),
6736
- /* @__PURE__ */ jsx22("li", { children: h.tipSelect }),
6737
- /* @__PURE__ */ jsx22("li", { children: h.tipMove })
6804
+ /* @__PURE__ */ jsx24(Section, { title: h.tipsTitle, children: /* @__PURE__ */ jsxs22("ul", { style: { margin: 0, paddingLeft: 18, fontSize: 13, color: colors.textSecondary, display: "flex", flexDirection: "column", gap: 6 }, children: [
6805
+ /* @__PURE__ */ jsx24("li", { children: h.tipDoubleClick }),
6806
+ /* @__PURE__ */ jsx24("li", { children: h.tipConnect }),
6807
+ /* @__PURE__ */ jsx24("li", { children: h.tipSelect }),
6808
+ /* @__PURE__ */ jsx24("li", { children: h.tipMove })
6738
6809
  ] }) })
6739
6810
  ]
6740
6811
  }
6741
6812
  ),
6742
- /* @__PURE__ */ jsx22("div", { style: { display: "flex", justifyContent: "flex-end", marginTop: 16 }, children: /* @__PURE__ */ jsx22("button", { type: "button", onClick: onCancel, style: ghostBtnStyle, "data-testid": "help-modal-close", children: h.close }) })
6813
+ /* @__PURE__ */ jsx24("div", { style: { display: "flex", justifyContent: "flex-end", marginTop: 16 }, children: /* @__PURE__ */ jsx24("button", { type: "button", onClick: onCancel, style: ghostBtnStyle, "data-testid": "help-modal-close", children: h.close }) })
6743
6814
  ] }) });
6744
6815
  }
6745
6816
  function Section({ title, children }) {
6746
- return /* @__PURE__ */ jsxs20("div", { children: [
6747
- /* @__PURE__ */ jsx22(
6817
+ return /* @__PURE__ */ jsxs22("div", { children: [
6818
+ /* @__PURE__ */ jsx24(
6748
6819
  "h3",
6749
6820
  {
6750
6821
  style: {
@@ -6758,12 +6829,12 @@ function Section({ title, children }) {
6758
6829
  children: title
6759
6830
  }
6760
6831
  ),
6761
- /* @__PURE__ */ jsx22("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children })
6832
+ /* @__PURE__ */ jsx24("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children })
6762
6833
  ] });
6763
6834
  }
6764
6835
  function ColorRow({ fill, border, label }) {
6765
- return /* @__PURE__ */ jsxs20("div", { style: { display: "flex", alignItems: "center", gap: 10, fontSize: 13, color: colors.textPrimary }, children: [
6766
- /* @__PURE__ */ jsx22(
6836
+ return /* @__PURE__ */ jsxs22("div", { style: { display: "flex", alignItems: "center", gap: 10, fontSize: 13, color: colors.textPrimary }, children: [
6837
+ /* @__PURE__ */ jsx24(
6767
6838
  "span",
6768
6839
  {
6769
6840
  style: {
@@ -6776,12 +6847,12 @@ function ColorRow({ fill, border, label }) {
6776
6847
  }
6777
6848
  }
6778
6849
  ),
6779
- /* @__PURE__ */ jsx22("span", { children: label })
6850
+ /* @__PURE__ */ jsx24("span", { children: label })
6780
6851
  ] });
6781
6852
  }
6782
6853
  function LineRow({ color, label, dashed }) {
6783
- return /* @__PURE__ */ jsxs20("div", { style: { display: "flex", alignItems: "center", gap: 10, fontSize: 13, color: colors.textPrimary }, children: [
6784
- /* @__PURE__ */ jsx22("svg", { width: "28", height: "14", style: { flexShrink: 0 }, "aria-hidden": "true", children: /* @__PURE__ */ jsx22(
6854
+ return /* @__PURE__ */ jsxs22("div", { style: { display: "flex", alignItems: "center", gap: 10, fontSize: 13, color: colors.textPrimary }, children: [
6855
+ /* @__PURE__ */ jsx24("svg", { width: "28", height: "14", style: { flexShrink: 0 }, "aria-hidden": "true", children: /* @__PURE__ */ jsx24(
6785
6856
  "line",
6786
6857
  {
6787
6858
  x1: "2",
@@ -6794,12 +6865,12 @@ function LineRow({ color, label, dashed }) {
6794
6865
  ...dashed ? { strokeDasharray: "3 3" } : {}
6795
6866
  }
6796
6867
  ) }),
6797
- /* @__PURE__ */ jsx22("span", { children: label })
6868
+ /* @__PURE__ */ jsx24("span", { children: label })
6798
6869
  ] });
6799
6870
  }
6800
6871
  function ShortcutRow({ keys, label }) {
6801
- return /* @__PURE__ */ jsxs20("div", { style: { display: "flex", alignItems: "center", gap: 10, fontSize: 13, color: colors.textPrimary }, children: [
6802
- /* @__PURE__ */ jsx22(
6872
+ return /* @__PURE__ */ jsxs22("div", { style: { display: "flex", alignItems: "center", gap: 10, fontSize: 13, color: colors.textPrimary }, children: [
6873
+ /* @__PURE__ */ jsx24(
6803
6874
  "kbd",
6804
6875
  {
6805
6876
  style: {
@@ -6819,12 +6890,12 @@ function ShortcutRow({ keys, label }) {
6819
6890
  children: keys
6820
6891
  }
6821
6892
  ),
6822
- /* @__PURE__ */ jsx22("span", { children: label })
6893
+ /* @__PURE__ */ jsx24("span", { children: label })
6823
6894
  ] });
6824
6895
  }
6825
6896
 
6826
6897
  // src/modals/VersionSwitchModal.tsx
6827
- import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
6898
+ import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
6828
6899
  function VersionSwitchModal({
6829
6900
  fromVersion,
6830
6901
  toVersion,
@@ -6832,7 +6903,7 @@ function VersionSwitchModal({
6832
6903
  onConfirm,
6833
6904
  onCancel
6834
6905
  }) {
6835
- return /* @__PURE__ */ jsx23(
6906
+ return /* @__PURE__ */ jsx25(
6836
6907
  "div",
6837
6908
  {
6838
6909
  style: {
@@ -6844,7 +6915,7 @@ function VersionSwitchModal({
6844
6915
  justifyContent: "center",
6845
6916
  zIndex: 1e3
6846
6917
  },
6847
- children: /* @__PURE__ */ jsxs21(
6918
+ children: /* @__PURE__ */ jsxs23(
6848
6919
  "div",
6849
6920
  {
6850
6921
  "data-testid": "version-switch-modal",
@@ -6858,8 +6929,8 @@ function VersionSwitchModal({
6858
6929
  fontFamily: "inherit"
6859
6930
  },
6860
6931
  children: [
6861
- /* @__PURE__ */ jsxs21("div", { style: { padding: "16px 20px 0", display: "flex", alignItems: "flex-start", gap: 12 }, children: [
6862
- /* @__PURE__ */ jsx23(
6932
+ /* @__PURE__ */ jsxs23("div", { style: { padding: "16px 20px 0", display: "flex", alignItems: "flex-start", gap: 12 }, children: [
6933
+ /* @__PURE__ */ jsx25(
6863
6934
  "div",
6864
6935
  {
6865
6936
  style: {
@@ -6876,20 +6947,20 @@ function VersionSwitchModal({
6876
6947
  children: "\u26A0\uFE0F"
6877
6948
  }
6878
6949
  ),
6879
- /* @__PURE__ */ jsxs21("div", { children: [
6880
- /* @__PURE__ */ jsxs21("div", { style: { fontWeight: 600, fontSize: 14, color: "#0F172A", marginBottom: 4 }, children: [
6950
+ /* @__PURE__ */ jsxs23("div", { children: [
6951
+ /* @__PURE__ */ jsxs23("div", { style: { fontWeight: 600, fontSize: 14, color: "#0F172A", marginBottom: 4 }, children: [
6881
6952
  "Switch to ",
6882
6953
  toVersion,
6883
6954
  "?"
6884
6955
  ] }),
6885
- /* @__PURE__ */ jsxs21("div", { style: { color: "#475569", lineHeight: 1.5, fontSize: 13 }, children: [
6956
+ /* @__PURE__ */ jsxs23("div", { style: { color: "#475569", lineHeight: 1.5, fontSize: 13 }, children: [
6886
6957
  "Switching to ",
6887
6958
  toVersion,
6888
6959
  " will remove data not supported in that dialect:"
6889
6960
  ] })
6890
6961
  ] })
6891
6962
  ] }),
6892
- /* @__PURE__ */ jsxs21(
6963
+ /* @__PURE__ */ jsxs23(
6893
6964
  "div",
6894
6965
  {
6895
6966
  style: {
@@ -6902,17 +6973,17 @@ function VersionSwitchModal({
6902
6973
  fontSize: 12
6903
6974
  },
6904
6975
  children: [
6905
- /* @__PURE__ */ jsx23("div", { style: { fontWeight: 600, marginBottom: 6 }, children: "Will be removed:" }),
6906
- /* @__PURE__ */ jsx23("ul", { style: { margin: 0, paddingLeft: 16, lineHeight: 1.8 }, children: warnings.map((w, i) => /* @__PURE__ */ jsx23("li", { children: w }, i)) })
6976
+ /* @__PURE__ */ jsx25("div", { style: { fontWeight: 600, marginBottom: 6 }, children: "Will be removed:" }),
6977
+ /* @__PURE__ */ jsx25("ul", { style: { margin: 0, paddingLeft: 16, lineHeight: 1.8 }, children: warnings.map((w, i) => /* @__PURE__ */ jsx25("li", { children: w }, i)) })
6907
6978
  ]
6908
6979
  }
6909
6980
  ),
6910
- /* @__PURE__ */ jsxs21("div", { style: { padding: "10px 20px 0 64px", color: "#64748B", fontSize: 12, lineHeight: 1.5 }, children: [
6981
+ /* @__PURE__ */ jsxs23("div", { style: { padding: "10px 20px 0 64px", color: "#64748B", fontSize: 12, lineHeight: 1.5 }, children: [
6911
6982
  "This cannot be undone. You can switch back to ",
6912
6983
  fromVersion,
6913
6984
  " any time, but the removed data will not be restored."
6914
6985
  ] }),
6915
- /* @__PURE__ */ jsxs21(
6986
+ /* @__PURE__ */ jsxs23(
6916
6987
  "div",
6917
6988
  {
6918
6989
  style: {
@@ -6924,7 +6995,7 @@ function VersionSwitchModal({
6924
6995
  marginTop: 16
6925
6996
  },
6926
6997
  children: [
6927
- /* @__PURE__ */ jsx23(
6998
+ /* @__PURE__ */ jsx25(
6928
6999
  "button",
6929
7000
  {
6930
7001
  type: "button",
@@ -6942,7 +7013,7 @@ function VersionSwitchModal({
6942
7013
  children: "Cancel"
6943
7014
  }
6944
7015
  ),
6945
- /* @__PURE__ */ jsxs21(
7016
+ /* @__PURE__ */ jsxs23(
6946
7017
  "button",
6947
7018
  {
6948
7019
  type: "button",
@@ -6976,17 +7047,17 @@ function VersionSwitchModal({
6976
7047
  }
6977
7048
 
6978
7049
  // src/components/CommentNode.tsx
6979
- import { useRef as useRef13, useState as useState16 } from "react";
6980
- import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
7050
+ import { useRef as useRef14, useState as useState16 } from "react";
7051
+ import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
6981
7052
  function CommentNode({ comment, disabled, onUpdate, onRemove }) {
6982
7053
  const [editing, setEditing] = useState16(false);
6983
7054
  const [draft, setDraft] = useState16(comment.text);
6984
- const textareaRef = useRef13(null);
7055
+ const textareaRef = useRef14(null);
6985
7056
  const commitEdit = () => {
6986
7057
  setEditing(false);
6987
7058
  if (draft !== comment.text) onUpdate({ text: draft });
6988
7059
  };
6989
- return /* @__PURE__ */ jsxs22(
7060
+ return /* @__PURE__ */ jsxs24(
6990
7061
  "div",
6991
7062
  {
6992
7063
  "data-testid": `comment-${comment.id}`,
@@ -7007,8 +7078,8 @@ function CommentNode({ comment, disabled, onUpdate, onRemove }) {
7007
7078
  userSelect: "none"
7008
7079
  },
7009
7080
  children: [
7010
- /* @__PURE__ */ jsxs22("div", { style: { display: "flex", justifyContent: "flex-end", gap: 4, marginBottom: 4 }, children: [
7011
- !disabled && !editing && /* @__PURE__ */ jsx24(
7081
+ /* @__PURE__ */ jsxs24("div", { style: { display: "flex", justifyContent: "flex-end", gap: 4, marginBottom: 4 }, children: [
7082
+ !disabled && !editing && /* @__PURE__ */ jsx26(
7012
7083
  "button",
7013
7084
  {
7014
7085
  type: "button",
@@ -7023,7 +7094,7 @@ function CommentNode({ comment, disabled, onUpdate, onRemove }) {
7023
7094
  children: "\u270F\uFE0F"
7024
7095
  }
7025
7096
  ),
7026
- !disabled && /* @__PURE__ */ jsx24(
7097
+ !disabled && /* @__PURE__ */ jsx26(
7027
7098
  "button",
7028
7099
  {
7029
7100
  type: "button",
@@ -7035,7 +7106,7 @@ function CommentNode({ comment, disabled, onUpdate, onRemove }) {
7035
7106
  }
7036
7107
  )
7037
7108
  ] }),
7038
- editing ? /* @__PURE__ */ jsx24(
7109
+ editing ? /* @__PURE__ */ jsx26(
7039
7110
  "textarea",
7040
7111
  {
7041
7112
  ref: textareaRef,
@@ -7061,7 +7132,7 @@ function CommentNode({ comment, disabled, onUpdate, onRemove }) {
7061
7132
  },
7062
7133
  "data-testid": `comment-textarea-${comment.id}`
7063
7134
  }
7064
- ) : /* @__PURE__ */ jsx24(
7135
+ ) : /* @__PURE__ */ jsx26(
7065
7136
  "div",
7066
7137
  {
7067
7138
  onDoubleClick: () => {
@@ -7071,7 +7142,7 @@ function CommentNode({ comment, disabled, onUpdate, onRemove }) {
7071
7142
  }
7072
7143
  },
7073
7144
  style: { whiteSpace: "pre-wrap", wordBreak: "break-word", minHeight: 20 },
7074
- children: comment.text || /* @__PURE__ */ jsx24("em", { style: { color: "#94a3b8" }, children: "empty note" })
7145
+ children: comment.text || /* @__PURE__ */ jsx26("em", { style: { color: "#94a3b8" }, children: "empty note" })
7075
7146
  }
7076
7147
  )
7077
7148
  ]
@@ -7089,14 +7160,14 @@ var iconBtn = {
7089
7160
  };
7090
7161
 
7091
7162
  // src/components/WorkflowJsonEditor.tsx
7092
- import { useEffect as useEffect11, useMemo as useMemo6, useRef as useRef14, useState as useState17 } from "react";
7163
+ import { useEffect as useEffect12, useMemo as useMemo6, useRef as useRef15, useState as useState17 } from "react";
7093
7164
  import {
7094
7165
  attachCursorSelectionBridge,
7095
7166
  attachWorkflowJsonController,
7096
7167
  registerWorkflowSchema,
7097
7168
  revealIdInEditor
7098
7169
  } from "@cyoda/workflow-monaco";
7099
- import { Fragment as Fragment9, jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
7170
+ import { Fragment as Fragment10, jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
7100
7171
  function WorkflowJsonEditor({
7101
7172
  document: document2,
7102
7173
  issues,
@@ -7108,19 +7179,19 @@ function WorkflowJsonEditor({
7108
7179
  onSelectionChange,
7109
7180
  onStatusChange
7110
7181
  }) {
7111
- const containerRef = useRef14(null);
7112
- const documentRef = useRef14(document2);
7113
- const issuesRef = useRef14(issues);
7114
- const readOnlyRef = useRef14(readOnly);
7115
- const onPatchRef = useRef14(onPatch);
7116
- const onSelectionChangeRef = useRef14(onSelectionChange);
7117
- const onStatusChangeRef = useRef14(onStatusChange);
7118
- const editorRef = useRef14(null);
7119
- const controllerRef = useRef14(null);
7120
- const schemaHandleRef = useRef14(null);
7121
- const cursorBridgeRef = useRef14(null);
7122
- const applyingGraphSelectionRef = useRef14(false);
7123
- const visibleRef = useRef14(visible);
7182
+ const containerRef = useRef15(null);
7183
+ const documentRef = useRef15(document2);
7184
+ const issuesRef = useRef15(issues);
7185
+ const readOnlyRef = useRef15(readOnly);
7186
+ const onPatchRef = useRef15(onPatch);
7187
+ const onSelectionChangeRef = useRef15(onSelectionChange);
7188
+ const onStatusChangeRef = useRef15(onStatusChange);
7189
+ const editorRef = useRef15(null);
7190
+ const controllerRef = useRef15(null);
7191
+ const schemaHandleRef = useRef15(null);
7192
+ const cursorBridgeRef = useRef15(null);
7193
+ const applyingGraphSelectionRef = useRef15(false);
7194
+ const visibleRef = useRef15(visible);
7124
7195
  const [status, setStatus] = useState17({ status: "idle" });
7125
7196
  documentRef.current = document2;
7126
7197
  issuesRef.current = issues;
@@ -7137,7 +7208,7 @@ function WorkflowJsonEditor({
7137
7208
  const modelUri = config?.modelUri;
7138
7209
  const editorOptions = config?.editorOptions;
7139
7210
  const debounceMs = config?.debounceMs;
7140
- useEffect11(() => {
7211
+ useEffect12(() => {
7141
7212
  if (!monaco || !containerRef.current || editorRef.current) return;
7142
7213
  const model = monaco.editor.createModel(
7143
7214
  "",
@@ -7192,7 +7263,7 @@ function WorkflowJsonEditor({
7192
7263
  model.dispose();
7193
7264
  };
7194
7265
  }, [monaco, modelUri]);
7195
- useEffect11(() => {
7266
+ useEffect12(() => {
7196
7267
  const editor = editorRef.current;
7197
7268
  const controller = controllerRef.current;
7198
7269
  if (!editor || !controller || !config) return;
@@ -7200,17 +7271,17 @@ function WorkflowJsonEditor({
7200
7271
  controller.syncFromDocument(document2);
7201
7272
  controller.renderIssues(issues, document2);
7202
7273
  }, [config, document2, issues, readOnly]);
7203
- useEffect11(() => {
7274
+ useEffect12(() => {
7204
7275
  if (!visible) return;
7205
7276
  editorRef.current?.layout?.();
7206
7277
  }, [visible]);
7207
- useEffect11(() => {
7278
+ useEffect12(() => {
7208
7279
  if (!config) {
7209
7280
  setStatus({ status: "idle" });
7210
7281
  onStatusChangeRef.current?.({ status: "idle" });
7211
7282
  }
7212
7283
  }, [config]);
7213
- useEffect11(() => {
7284
+ useEffect12(() => {
7214
7285
  const editor = editorRef.current;
7215
7286
  if (!editor || !visible || !selectedId) return;
7216
7287
  applyingGraphSelectionRef.current = true;
@@ -7221,7 +7292,7 @@ function WorkflowJsonEditor({
7221
7292
  return () => window.clearTimeout(timeout);
7222
7293
  }, [document2, selectedId, visible]);
7223
7294
  if (!config) {
7224
- return /* @__PURE__ */ jsx25(
7295
+ return /* @__PURE__ */ jsx27(
7225
7296
  "div",
7226
7297
  {
7227
7298
  "data-testid": "workflow-json-unavailable",
@@ -7236,11 +7307,11 @@ function WorkflowJsonEditor({
7236
7307
  textAlign: "center",
7237
7308
  background: "#F8FAFC"
7238
7309
  },
7239
- children: /* @__PURE__ */ jsx25(UnavailableMessage, {})
7310
+ children: /* @__PURE__ */ jsx27(UnavailableMessage, {})
7240
7311
  }
7241
7312
  );
7242
7313
  }
7243
- return /* @__PURE__ */ jsxs23(
7314
+ return /* @__PURE__ */ jsxs25(
7244
7315
  "div",
7245
7316
  {
7246
7317
  "data-testid": "workflow-json-editor",
@@ -7252,8 +7323,8 @@ function WorkflowJsonEditor({
7252
7323
  minHeight: 0
7253
7324
  },
7254
7325
  children: [
7255
- /* @__PURE__ */ jsx25(JsonStatusBanner, { status }),
7256
- /* @__PURE__ */ jsx25(
7326
+ /* @__PURE__ */ jsx27(JsonStatusBanner, { status }),
7327
+ /* @__PURE__ */ jsx27(
7257
7328
  "div",
7258
7329
  {
7259
7330
  ref: containerRef,
@@ -7266,7 +7337,7 @@ function WorkflowJsonEditor({
7266
7337
  }
7267
7338
  function UnavailableMessage() {
7268
7339
  const messages = useMessages();
7269
- return /* @__PURE__ */ jsx25(Fragment9, { children: messages.editorView.unavailable });
7340
+ return /* @__PURE__ */ jsx27(Fragment10, { children: messages.editorView.unavailable });
7270
7341
  }
7271
7342
  function JsonStatusBanner({ status }) {
7272
7343
  const messages = useMessages();
@@ -7275,7 +7346,7 @@ function JsonStatusBanner({ status }) {
7275
7346
  }
7276
7347
  const tone = status.status === "semantic-errors" ? { border: "#FCD34D", bg: "#FFFBEB", text: "#92400E" } : { border: "#FCA5A5", bg: "#FEF2F2", text: "#991B1B" };
7277
7348
  const body = status.status === "semantic-errors" ? messages.editorView.semanticErrors : status.status === "invalid-schema" ? messages.editorView.invalidSchema : `${messages.editorView.invalidJson}${status.message ? ` ${status.message}` : ""}`;
7278
- return /* @__PURE__ */ jsx25(
7349
+ return /* @__PURE__ */ jsx27(
7279
7350
  "div",
7280
7351
  {
7281
7352
  role: "status",
@@ -7319,7 +7390,7 @@ function selectionFromJsonId(doc, id) {
7319
7390
  }
7320
7391
 
7321
7392
  // src/components/WorkflowEditor.tsx
7322
- import { Fragment as Fragment10, jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
7393
+ import { Fragment as Fragment11, jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
7323
7394
  function hasPersistedWorkflowUi(meta) {
7324
7395
  return !!meta && Object.values(meta).some((value) => value !== void 0);
7325
7396
  }
@@ -7388,7 +7459,7 @@ function WorkflowEditor({
7388
7459
  const [state, actions] = useEditorStore(initialDocumentWithLayout, mode);
7389
7460
  const [isFullscreen, setIsFullscreen] = useState18(false);
7390
7461
  const [inspectorWidth, setInspectorWidth] = useState18(384);
7391
- const editorContainerRef = useRef15(null);
7462
+ const editorContainerRef = useRef16(null);
7392
7463
  const [pendingDelete, setPendingDelete] = useState18(null);
7393
7464
  const [pendingConnect, setPendingConnect] = useState18(null);
7394
7465
  const [pendingAddState, setPendingAddState] = useState18(null);
@@ -7399,23 +7470,33 @@ function WorkflowEditor({
7399
7470
  const [jsonStatus, setJsonStatus] = useState18({ status: "idle" });
7400
7471
  const [openIssueSeverity, setOpenIssueSeverity] = useState18(null);
7401
7472
  const [inspectorOpen, setInspectorOpen] = useState18(false);
7473
+ const [placement, setPlacement] = useState18(() => {
7474
+ const loaded = loadPlacement(localStorageKey);
7475
+ if (loaded) {
7476
+ return {
7477
+ ...loaded,
7478
+ rect: clampRect(loaded.rect, { w: window.innerWidth, h: window.innerHeight })
7479
+ };
7480
+ }
7481
+ return { mode: "docked", rect: { left: 120, top: 96, width: 460, height: 560 } };
7482
+ });
7402
7483
  const [pendingVersionSwitch, setPendingVersionSwitch] = useState18(null);
7403
- const selectionRef = useRef15(state.selection);
7404
- const documentStateRef = useRef15(state.document);
7405
- const activeWorkflowRef = useRef15(state.activeWorkflow);
7406
- const pendingSelectionRestoreRef = useRef15(null);
7407
- const newStatePositionRef = useRef15(null);
7408
- useEffect12(() => {
7484
+ const selectionRef = useRef16(state.selection);
7485
+ const documentStateRef = useRef16(state.document);
7486
+ const activeWorkflowRef = useRef16(state.activeWorkflow);
7487
+ const pendingSelectionRestoreRef = useRef16(null);
7488
+ const newStatePositionRef = useRef16(null);
7489
+ useEffect13(() => {
7409
7490
  selectionRef.current = state.selection;
7410
7491
  }, [state.selection]);
7411
- useEffect12(() => {
7492
+ useEffect13(() => {
7412
7493
  documentStateRef.current = state.document;
7413
7494
  activeWorkflowRef.current = state.activeWorkflow;
7414
7495
  }, [state.document, state.activeWorkflow]);
7415
- useEffect12(() => {
7496
+ useEffect13(() => {
7416
7497
  onChange?.(state.document);
7417
7498
  }, [state.document, onChange]);
7418
- useEffect12(() => {
7499
+ useEffect13(() => {
7419
7500
  try {
7420
7501
  const toStore = {};
7421
7502
  for (const [wfName, ui] of Object.entries(state.document.meta.workflowUi)) {
@@ -7434,26 +7515,38 @@ function WorkflowEditor({
7434
7515
  } catch {
7435
7516
  }
7436
7517
  }, [state.document.meta.workflowUi, localStorageKey, onWorkflowUiChange]);
7437
- useEffect12(() => {
7518
+ useEffect13(() => {
7438
7519
  if (!onLayoutMetadataChange || !state.activeWorkflow) return;
7439
7520
  const ui = state.document.meta.workflowUi[state.activeWorkflow];
7440
7521
  if (ui) onLayoutMetadataChange(ui);
7441
7522
  }, [state.document.meta.workflowUi, state.activeWorkflow, onLayoutMetadataChange]);
7442
- const handleInspectorResizeStart = useCallback3((e) => {
7443
- e.preventDefault();
7444
- const startX = e.clientX;
7445
- const startWidth = inspectorWidth;
7446
- const onMove = (ev) => {
7447
- const delta = startX - ev.clientX;
7448
- setInspectorWidth(Math.max(360, startWidth + delta));
7449
- };
7450
- const onUp = () => {
7451
- document.removeEventListener("mousemove", onMove);
7452
- document.removeEventListener("mouseup", onUp);
7453
- };
7454
- document.addEventListener("mousemove", onMove);
7455
- document.addEventListener("mouseup", onUp);
7456
- }, [inspectorWidth]);
7523
+ useEffect13(() => {
7524
+ savePlacement(localStorageKey, placement);
7525
+ }, [placement, localStorageKey]);
7526
+ const toggleDock = useCallback3(() => {
7527
+ setPlacement((p) => {
7528
+ const viewport = { w: window.innerWidth, h: window.innerHeight };
7529
+ if (p.mode === "docked") {
7530
+ return { mode: "floating", rect: clampRect(p.rect, viewport) };
7531
+ }
7532
+ return { ...p, mode: "docked" };
7533
+ });
7534
+ }, []);
7535
+ const minimizeInspector = useCallback3(() => {
7536
+ setPlacement(
7537
+ (p) => p.mode === "minimized" ? p : { mode: "minimized", rect: p.rect, restoreMode: p.mode }
7538
+ );
7539
+ }, []);
7540
+ const restoreInspector = useCallback3(() => {
7541
+ setPlacement((p) => {
7542
+ if (p.mode !== "minimized") return p;
7543
+ const back = p.restoreMode ?? "docked";
7544
+ if (back === "floating") {
7545
+ return { mode: "floating", rect: clampRect(p.rect, { w: window.innerWidth, h: window.innerHeight }) };
7546
+ }
7547
+ return { mode: "docked", rect: p.rect };
7548
+ });
7549
+ }, []);
7457
7550
  const handleToggleFullscreen = useCallback3(() => {
7458
7551
  setIsFullscreen((v) => !v);
7459
7552
  }, []);
@@ -7469,13 +7562,6 @@ function WorkflowEditor({
7469
7562
  kind: "transition",
7470
7563
  transitionUuid: patch.host.transitionUuid
7471
7564
  };
7472
- pendingSelectionRestoreRef.current = restoreSelection;
7473
- window.setTimeout(() => {
7474
- if (sameSelection(pendingSelectionRestoreRef.current, restoreSelection)) {
7475
- actions.setSelection(restoreSelection);
7476
- pendingSelectionRestoreRef.current = null;
7477
- }
7478
- }, 50);
7479
7565
  actions.dispatchTransaction({
7480
7566
  summary: patch.criterion ? "Set criterion" : "Clear criterion",
7481
7567
  patches: [patch],
@@ -7812,7 +7898,7 @@ function WorkflowEditor({
7812
7898
  },
7813
7899
  [anyModalOpen, readOnly, state.selection]
7814
7900
  );
7815
- useEffect12(() => {
7901
+ useEffect13(() => {
7816
7902
  const handleDocumentDeleteKeyDown = (event) => {
7817
7903
  if (anyModalOpen || readOnly || isTypingTarget(event.target)) return;
7818
7904
  if (event.ctrlKey || event.metaKey || event.altKey) return;
@@ -7849,7 +7935,7 @@ function WorkflowEditor({
7849
7935
  [layoutOptions, pinnedNodes]
7850
7936
  );
7851
7937
  const savedViewport = state.activeWorkflow ? state.document.meta.workflowUi[state.activeWorkflow]?.viewports?.[orientation] : void 0;
7852
- useEffect12(() => {
7938
+ useEffect13(() => {
7853
7939
  if (enableJsonEditor) return;
7854
7940
  setJsonStatus({ status: "idle" });
7855
7941
  onJsonStatusChange?.({ status: "idle" });
@@ -7888,13 +7974,13 @@ function WorkflowEditor({
7888
7974
  if (readOnly || anyModalOpen) return;
7889
7975
  openAddStateModal({ x, y });
7890
7976
  }, [anyModalOpen, openAddStateModal, readOnly]);
7891
- const graphPane = /* @__PURE__ */ jsxs24(
7977
+ const graphPane = /* @__PURE__ */ jsxs26(
7892
7978
  "div",
7893
7979
  {
7894
7980
  "data-testid": "workflow-editor-graph-pane",
7895
7981
  style: { flex: 1, minWidth: 0, minHeight: 0, height: "100%", position: "relative" },
7896
7982
  children: [
7897
- /* @__PURE__ */ jsx26(
7983
+ /* @__PURE__ */ jsx28(
7898
7984
  Canvas,
7899
7985
  {
7900
7986
  graph: derived.graph,
@@ -7939,7 +8025,7 @@ function WorkflowEditor({
7939
8025
  helpLabel: mergedMessages.toolbar.help
7940
8026
  }
7941
8027
  ),
7942
- reconnectError && /* @__PURE__ */ jsx26(
8028
+ reconnectError && /* @__PURE__ */ jsx28(
7943
8029
  "div",
7944
8030
  {
7945
8031
  role: "alert",
@@ -7964,7 +8050,7 @@ function WorkflowEditor({
7964
8050
  state.activeWorkflow && (() => {
7965
8051
  const comments = state.document.meta.workflowUi[state.activeWorkflow]?.comments;
7966
8052
  if (!comments) return null;
7967
- return Object.values(comments).map((c) => /* @__PURE__ */ jsx26(
8053
+ return Object.values(comments).map((c) => /* @__PURE__ */ jsx28(
7968
8054
  CommentNode,
7969
8055
  {
7970
8056
  comment: c,
@@ -7987,12 +8073,12 @@ function WorkflowEditor({
7987
8073
  ]
7988
8074
  }
7989
8075
  );
7990
- const jsonPane = enableJsonEditor ? /* @__PURE__ */ jsx26(
8076
+ const jsonPane = enableJsonEditor ? /* @__PURE__ */ jsx28(
7991
8077
  "div",
7992
8078
  {
7993
8079
  "data-testid": "workflow-editor-json-pane",
7994
8080
  style: { flex: 1, minWidth: 0, minHeight: 0, height: "100%" },
7995
- children: /* @__PURE__ */ jsx26(
8081
+ children: /* @__PURE__ */ jsx28(
7996
8082
  WorkflowJsonEditor,
7997
8083
  {
7998
8084
  document: state.document,
@@ -8008,7 +8094,7 @@ function WorkflowEditor({
8008
8094
  )
8009
8095
  }
8010
8096
  ) : null;
8011
- return /* @__PURE__ */ jsx26(CriterionMonacoProvider, { value: jsonEditor?.monaco ?? null, children: /* @__PURE__ */ jsx26(I18nContext.Provider, { value: mergedMessages, children: /* @__PURE__ */ jsx26(EditorConfigContext.Provider, { value: editorConfig, children: /* @__PURE__ */ jsxs24(
8097
+ return /* @__PURE__ */ jsx28(CriterionMonacoProvider, { value: jsonEditor?.monaco ?? null, children: /* @__PURE__ */ jsx28(I18nContext.Provider, { value: mergedMessages, children: /* @__PURE__ */ jsx28(EditorConfigContext.Provider, { value: editorConfig, children: /* @__PURE__ */ jsxs26(
8012
8098
  "div",
8013
8099
  {
8014
8100
  ref: editorContainerRef,
@@ -8029,7 +8115,7 @@ function WorkflowEditor({
8029
8115
  onKeyDown: handleKeyDown,
8030
8116
  tabIndex: -1,
8031
8117
  children: [
8032
- chrome?.tabs !== false && showTabs && /* @__PURE__ */ jsx26(
8118
+ chrome?.tabs !== false && showTabs && /* @__PURE__ */ jsx28(
8033
8119
  WorkflowTabs,
8034
8120
  {
8035
8121
  workflows,
@@ -8056,9 +8142,9 @@ function WorkflowEditor({
8056
8142
  onVersionChange: handleVersionChange
8057
8143
  }
8058
8144
  ),
8059
- /* @__PURE__ */ jsxs24("div", { style: { flex: 1, display: "flex", minHeight: 0 }, children: [
8060
- /* @__PURE__ */ jsxs24("div", { style: { flex: 1, minWidth: 0, minHeight: 0, display: "flex", flexDirection: "column" }, children: [
8061
- (enableJsonEditor && jsonEditorPlacement === "tab" || !readOnly && graphVisible) && /* @__PURE__ */ jsxs24(
8145
+ /* @__PURE__ */ jsxs26("div", { style: { flex: 1, display: "flex", minHeight: 0 }, children: [
8146
+ /* @__PURE__ */ jsxs26("div", { style: { flex: 1, minWidth: 0, minHeight: 0, display: "flex", flexDirection: "column" }, children: [
8147
+ (enableJsonEditor && jsonEditorPlacement === "tab" || !readOnly && graphVisible) && /* @__PURE__ */ jsxs26(
8062
8148
  "div",
8063
8149
  {
8064
8150
  style: {
@@ -8072,8 +8158,8 @@ function WorkflowEditor({
8072
8158
  },
8073
8159
  "data-testid": "workflow-editor-surface-tabs",
8074
8160
  children: [
8075
- enableJsonEditor && jsonEditorPlacement === "tab" && /* @__PURE__ */ jsxs24(Fragment10, { children: [
8076
- /* @__PURE__ */ jsx26(
8161
+ enableJsonEditor && jsonEditorPlacement === "tab" && /* @__PURE__ */ jsxs26(Fragment11, { children: [
8162
+ /* @__PURE__ */ jsx28(
8077
8163
  SurfaceTab,
8078
8164
  {
8079
8165
  active: activeSurface === "graph",
@@ -8081,7 +8167,7 @@ function WorkflowEditor({
8081
8167
  children: mergedMessages.editorView.graph
8082
8168
  }
8083
8169
  ),
8084
- /* @__PURE__ */ jsx26(
8170
+ /* @__PURE__ */ jsx28(
8085
8171
  SurfaceTab,
8086
8172
  {
8087
8173
  active: activeSurface === "json",
@@ -8090,8 +8176,8 @@ function WorkflowEditor({
8090
8176
  }
8091
8177
  )
8092
8178
  ] }),
8093
- /* @__PURE__ */ jsx26("div", { style: { flex: 1 } }),
8094
- !readOnly && activeSurface === "graph" && /* @__PURE__ */ jsxs24(
8179
+ /* @__PURE__ */ jsx28("div", { style: { flex: 1 } }),
8180
+ !readOnly && activeSurface === "graph" && /* @__PURE__ */ jsxs26(
8095
8181
  "button",
8096
8182
  {
8097
8183
  type: "button",
@@ -8112,7 +8198,7 @@ function WorkflowEditor({
8112
8198
  cursor: "pointer"
8113
8199
  },
8114
8200
  children: [
8115
- /* @__PURE__ */ jsx26("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", children: /* @__PURE__ */ jsx26("path", { d: "M12 5v14M5 12h14" }) }),
8201
+ /* @__PURE__ */ jsx28("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", children: /* @__PURE__ */ jsx28("path", { d: "M12 5v14M5 12h14" }) }),
8116
8202
  mergedMessages.toolbar.addStateButton
8117
8203
  ]
8118
8204
  }
@@ -8120,7 +8206,7 @@ function WorkflowEditor({
8120
8206
  ]
8121
8207
  }
8122
8208
  ),
8123
- enableJsonEditor && jsonEditorPlacement === "split" ? /* @__PURE__ */ jsxs24(
8209
+ enableJsonEditor && jsonEditorPlacement === "split" ? /* @__PURE__ */ jsxs26(
8124
8210
  "div",
8125
8211
  {
8126
8212
  style: {
@@ -8133,10 +8219,10 @@ function WorkflowEditor({
8133
8219
  "data-testid": "workflow-editor-split-view",
8134
8220
  children: [
8135
8221
  graphPane,
8136
- /* @__PURE__ */ jsx26("div", { style: { borderLeft: "1px solid #E2E8F0", minWidth: 0 }, children: jsonPane })
8222
+ /* @__PURE__ */ jsx28("div", { style: { borderLeft: "1px solid #E2E8F0", minWidth: 0 }, children: jsonPane })
8137
8223
  ]
8138
8224
  }
8139
- ) : /* @__PURE__ */ jsxs24(
8225
+ ) : /* @__PURE__ */ jsxs26(
8140
8226
  "div",
8141
8227
  {
8142
8228
  style: {
@@ -8148,8 +8234,8 @@ function WorkflowEditor({
8148
8234
  flexDirection: "column"
8149
8235
  },
8150
8236
  children: [
8151
- graphVisible ? /* @__PURE__ */ jsx26("div", { style: { flex: 1, minHeight: 0, minWidth: 0 }, children: graphPane }) : null,
8152
- enableJsonEditor ? /* @__PURE__ */ jsx26(
8237
+ graphVisible ? /* @__PURE__ */ jsx28("div", { style: { flex: 1, minHeight: 0, minWidth: 0 }, children: graphPane }) : null,
8238
+ enableJsonEditor ? /* @__PURE__ */ jsx28(
8153
8239
  "div",
8154
8240
  {
8155
8241
  style: {
@@ -8166,41 +8252,36 @@ function WorkflowEditor({
8166
8252
  }
8167
8253
  )
8168
8254
  ] }),
8169
- inspectorVisible && /* @__PURE__ */ jsxs24(Fragment10, { children: [
8170
- /* @__PURE__ */ jsx26(
8171
- "div",
8172
- {
8173
- onMouseDown: handleInspectorResizeStart,
8174
- style: {
8175
- width: 3,
8176
- flexShrink: 0,
8177
- cursor: "col-resize",
8178
- background: "transparent",
8179
- borderLeft: "1px solid #E2E8F0",
8180
- transition: "background 0.15s",
8181
- zIndex: 10
8182
- },
8183
- onMouseEnter: (e) => e.currentTarget.style.background = "#CBD5E1",
8184
- onMouseLeave: (e) => e.currentTarget.style.background = "transparent"
8185
- }
8186
- ),
8187
- /* @__PURE__ */ jsx26(
8188
- Inspector,
8189
- {
8190
- document: state.document,
8191
- selection: state.selection,
8192
- issues: derived.issues,
8193
- readOnly,
8194
- onDispatch: dispatch,
8195
- onSelectionChange: handleSelectionChange,
8196
- onClose: () => handleSelectionChange(null),
8197
- onRequestDeleteState: requestDeleteState,
8198
- width: inspectorWidth
8199
- }
8200
- )
8201
- ] })
8255
+ inspectorVisible && /* @__PURE__ */ jsx28(
8256
+ InspectorFrame,
8257
+ {
8258
+ mode: placement.mode,
8259
+ rect: placement.rect,
8260
+ dockedWidth: inspectorWidth,
8261
+ onRectChange: (rect) => setPlacement((p) => ({ ...p, rect })),
8262
+ onDockedWidthChange: setInspectorWidth,
8263
+ onRestore: restoreInspector,
8264
+ onClose: () => handleSelectionChange(null),
8265
+ children: /* @__PURE__ */ jsx28(
8266
+ Inspector,
8267
+ {
8268
+ document: state.document,
8269
+ selection: state.selection,
8270
+ issues: derived.issues,
8271
+ readOnly,
8272
+ onDispatch: dispatch,
8273
+ onSelectionChange: handleSelectionChange,
8274
+ onClose: () => handleSelectionChange(null),
8275
+ onRequestDeleteState: requestDeleteState,
8276
+ docked: placement.mode === "docked",
8277
+ onToggleDock: toggleDock,
8278
+ onMinimize: minimizeInspector
8279
+ }
8280
+ )
8281
+ }
8282
+ )
8202
8283
  ] }),
8203
- pendingAddState !== null && state.activeWorkflow && /* @__PURE__ */ jsx26(
8284
+ pendingAddState !== null && state.activeWorkflow && /* @__PURE__ */ jsx28(
8204
8285
  AddStateModal,
8205
8286
  {
8206
8287
  existingNames: Object.keys(
@@ -8212,7 +8293,7 @@ function WorkflowEditor({
8212
8293
  onCancel: () => setPendingAddState(null)
8213
8294
  }
8214
8295
  ),
8215
- pendingDelete && /* @__PURE__ */ jsx26(
8296
+ pendingDelete && /* @__PURE__ */ jsx28(
8216
8297
  DeleteStateModal,
8217
8298
  {
8218
8299
  document: state.document,
@@ -8222,7 +8303,7 @@ function WorkflowEditor({
8222
8303
  onCancel: () => setPendingDelete(null)
8223
8304
  }
8224
8305
  ),
8225
- pendingConnect && pendingConnectState && /* @__PURE__ */ jsx26(
8306
+ pendingConnect && pendingConnectState && /* @__PURE__ */ jsx28(
8226
8307
  DragConnectModal,
8227
8308
  {
8228
8309
  source: pendingConnectState,
@@ -8232,8 +8313,8 @@ function WorkflowEditor({
8232
8313
  onCancel: () => setPendingConnect(null)
8233
8314
  }
8234
8315
  ),
8235
- helpOpen && /* @__PURE__ */ jsx26(HelpModal, { onCancel: () => setHelpOpen(false) }),
8236
- pendingVersionSwitch && /* @__PURE__ */ jsx26(
8316
+ helpOpen && /* @__PURE__ */ jsx28(HelpModal, { onCancel: () => setHelpOpen(false) }),
8317
+ pendingVersionSwitch && /* @__PURE__ */ jsx28(
8237
8318
  VersionSwitchModal,
8238
8319
  {
8239
8320
  fromVersion: `v${state.document.meta.cyodaVersion ?? LATEST_CYODA_VERSION}`,
@@ -8246,8 +8327,8 @@ function WorkflowEditor({
8246
8327
  onCancel: () => setPendingVersionSwitch(null)
8247
8328
  }
8248
8329
  ),
8249
- chrome?.toolbar !== false && /* @__PURE__ */ jsxs24("div", { style: { position: "relative" }, children: [
8250
- /* @__PURE__ */ jsx26(
8330
+ chrome?.toolbar !== false && /* @__PURE__ */ jsxs26("div", { style: { position: "relative" }, children: [
8331
+ /* @__PURE__ */ jsx28(
8251
8332
  Toolbar,
8252
8333
  {
8253
8334
  derived,
@@ -8262,7 +8343,7 @@ function WorkflowEditor({
8262
8343
  toolbarEnd
8263
8344
  }
8264
8345
  ),
8265
- /* @__PURE__ */ jsx26(
8346
+ /* @__PURE__ */ jsx28(
8266
8347
  IssuesDrawer,
8267
8348
  {
8268
8349
  open: openIssueSeverity !== null,
@@ -8420,22 +8501,6 @@ function normalizeAnchorPair(anchors) {
8420
8501
  function sameAnchors(a, b) {
8421
8502
  return a?.source === b?.source && a?.target === b?.target;
8422
8503
  }
8423
- function sameSelection(a, b) {
8424
- if (a === b) return true;
8425
- if (!a || !b || a.kind !== b.kind) return false;
8426
- switch (a.kind) {
8427
- case "workflow":
8428
- return b.kind === "workflow" && a.workflow === b.workflow;
8429
- case "state":
8430
- return b.kind === "state" && a.workflow === b.workflow && a.stateCode === b.stateCode && a.nodeId === b.nodeId;
8431
- case "transition":
8432
- return b.kind === "transition" && a.transitionUuid === b.transitionUuid;
8433
- case "processor":
8434
- return b.kind === "processor" && a.processorUuid === b.processorUuid;
8435
- case "criterion":
8436
- return b.kind === "criterion" && a.hostKind === b.hostKind && a.hostId === b.hostId && a.path.length === b.path.length && a.path.every((part, index) => part === b.path[index]);
8437
- }
8438
- }
8439
8504
  function workflowForSelection(doc, selection) {
8440
8505
  if (!selection) return null;
8441
8506
  if (selection.kind === "workflow" || selection.kind === "state") return selection.workflow;
@@ -8458,7 +8523,7 @@ function SurfaceTab({
8458
8523
  onClick,
8459
8524
  children
8460
8525
  }) {
8461
- return /* @__PURE__ */ jsx26(
8526
+ return /* @__PURE__ */ jsx28(
8462
8527
  "button",
8463
8528
  {
8464
8529
  type: "button",
@@ -8513,18 +8578,18 @@ function snapToGrid(value, grid = 16) {
8513
8578
  }
8514
8579
 
8515
8580
  // src/save/useSaveFlow.ts
8516
- import { useCallback as useCallback4, useRef as useRef16, useState as useState19 } from "react";
8581
+ import { useCallback as useCallback4, useRef as useRef17, useState as useState19 } from "react";
8517
8582
  import {
8518
8583
  WorkflowApiConflictError
8519
8584
  } from "@cyoda/workflow-core";
8520
8585
  function useSaveFlow(args) {
8521
8586
  const { api, document: doc, concurrencyToken, onSaved, onReload } = args;
8522
8587
  const [status, setStatus] = useState19({ kind: "idle" });
8523
- const tokenRef = useRef16(concurrencyToken);
8588
+ const tokenRef = useRef17(concurrencyToken);
8524
8589
  tokenRef.current = concurrencyToken;
8525
- const entityRef = useRef16(doc.session.entity);
8590
+ const entityRef = useRef17(doc.session.entity);
8526
8591
  entityRef.current = doc.session.entity;
8527
- const payloadRef = useRef16({
8592
+ const payloadRef = useRef17({
8528
8593
  importMode: doc.session.importMode,
8529
8594
  workflows: doc.session.workflows
8530
8595
  });
@@ -8532,7 +8597,7 @@ function useSaveFlow(args) {
8532
8597
  importMode: doc.session.importMode,
8533
8598
  workflows: doc.session.workflows
8534
8599
  };
8535
- const savingRef = useRef16(false);
8600
+ const savingRef = useRef17(false);
8536
8601
  const performImport = useCallback4(
8537
8602
  async (token) => {
8538
8603
  if (savingRef.current) return;
@@ -8591,7 +8656,7 @@ function useSaveFlow(args) {
8591
8656
 
8592
8657
  // src/save/SaveConfirmModal.tsx
8593
8658
  import { useState as useState20 } from "react";
8594
- import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
8659
+ import { jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
8595
8660
  function SaveConfirmModal({
8596
8661
  mode,
8597
8662
  requiresExplicitConfirm,
@@ -8604,14 +8669,14 @@ function SaveConfirmModal({
8604
8669
  const [ackMode, setAckMode] = useState20(!requiresExplicitConfirm);
8605
8670
  const [ackWarnings, setAckWarnings] = useState20(warningCount === 0);
8606
8671
  const blocked = !ackMode || !ackWarnings;
8607
- return /* @__PURE__ */ jsxs25(ModalFrame, { onCancel, children: [
8608
- /* @__PURE__ */ jsx27("h2", { style: { margin: 0, fontSize: 16 }, children: messages.saveConfirm.title }),
8609
- /* @__PURE__ */ jsxs25("p", { style: { margin: "12px 0", fontSize: 13, color: colors.textSecondary }, children: [
8672
+ return /* @__PURE__ */ jsxs27(ModalFrame, { onCancel, children: [
8673
+ /* @__PURE__ */ jsx29("h2", { style: { margin: 0, fontSize: 16 }, children: messages.saveConfirm.title }),
8674
+ /* @__PURE__ */ jsxs27("p", { style: { margin: "12px 0", fontSize: 13, color: colors.textSecondary }, children: [
8610
8675
  messages.saveConfirm.modeLabel,
8611
8676
  ": ",
8612
- /* @__PURE__ */ jsx27("strong", { children: mode })
8677
+ /* @__PURE__ */ jsx29("strong", { children: mode })
8613
8678
  ] }),
8614
- diffSummary2 && /* @__PURE__ */ jsx27(
8679
+ diffSummary2 && /* @__PURE__ */ jsx29(
8615
8680
  "pre",
8616
8681
  {
8617
8682
  style: {
@@ -8630,8 +8695,8 @@ function SaveConfirmModal({
8630
8695
  children: diffSummary2
8631
8696
  }
8632
8697
  ),
8633
- requiresExplicitConfirm && /* @__PURE__ */ jsxs25("label", { style: checkRow, "data-testid": "save-ack-mode", children: [
8634
- /* @__PURE__ */ jsx27(
8698
+ requiresExplicitConfirm && /* @__PURE__ */ jsxs27("label", { style: checkRow, "data-testid": "save-ack-mode", children: [
8699
+ /* @__PURE__ */ jsx29(
8635
8700
  "input",
8636
8701
  {
8637
8702
  type: "checkbox",
@@ -8639,10 +8704,10 @@ function SaveConfirmModal({
8639
8704
  onChange: (e) => setAckMode(e.target.checked)
8640
8705
  }
8641
8706
  ),
8642
- /* @__PURE__ */ jsx27("span", { children: mode === "REPLACE" ? messages.saveConfirm.ackReplace : messages.saveConfirm.ackActivate })
8707
+ /* @__PURE__ */ jsx29("span", { children: mode === "REPLACE" ? messages.saveConfirm.ackReplace : messages.saveConfirm.ackActivate })
8643
8708
  ] }),
8644
- warningCount > 0 && /* @__PURE__ */ jsxs25("label", { style: checkRow, "data-testid": "save-ack-warnings", children: [
8645
- /* @__PURE__ */ jsx27(
8709
+ warningCount > 0 && /* @__PURE__ */ jsxs27("label", { style: checkRow, "data-testid": "save-ack-warnings", children: [
8710
+ /* @__PURE__ */ jsx29(
8646
8711
  "input",
8647
8712
  {
8648
8713
  type: "checkbox",
@@ -8650,17 +8715,17 @@ function SaveConfirmModal({
8650
8715
  onChange: (e) => setAckWarnings(e.target.checked)
8651
8716
  }
8652
8717
  ),
8653
- /* @__PURE__ */ jsx27("span", { children: messages.saveConfirm.ackWarnings.replace("{count}", String(warningCount)) })
8718
+ /* @__PURE__ */ jsx29("span", { children: messages.saveConfirm.ackWarnings.replace("{count}", String(warningCount)) })
8654
8719
  ] }),
8655
- /* @__PURE__ */ jsxs25("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 16 }, children: [
8656
- /* @__PURE__ */ jsx27("button", { type: "button", onClick: onCancel, style: ghostBtn9, "data-testid": "save-cancel", children: messages.saveConfirm.cancel }),
8657
- /* @__PURE__ */ jsx27(
8720
+ /* @__PURE__ */ jsxs27("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 16 }, children: [
8721
+ /* @__PURE__ */ jsx29("button", { type: "button", onClick: onCancel, style: ghostBtn8, "data-testid": "save-cancel", children: messages.saveConfirm.cancel }),
8722
+ /* @__PURE__ */ jsx29(
8658
8723
  "button",
8659
8724
  {
8660
8725
  type: "button",
8661
8726
  disabled: blocked,
8662
8727
  onClick: onConfirm,
8663
- style: primaryBtn6,
8728
+ style: primaryBtn5,
8664
8729
  "data-testid": "save-confirm",
8665
8730
  children: messages.saveConfirm.confirm
8666
8731
  }
@@ -8676,7 +8741,7 @@ var checkRow = {
8676
8741
  color: colors.textPrimary,
8677
8742
  margin: "8px 0"
8678
8743
  };
8679
- var ghostBtn9 = {
8744
+ var ghostBtn8 = {
8680
8745
  padding: "6px 12px",
8681
8746
  background: "white",
8682
8747
  border: `1px solid ${colors.border}`,
@@ -8684,18 +8749,18 @@ var ghostBtn9 = {
8684
8749
  fontSize: 13,
8685
8750
  cursor: "pointer"
8686
8751
  };
8687
- var primaryBtn6 = {
8688
- ...ghostBtn9,
8752
+ var primaryBtn5 = {
8753
+ ...ghostBtn8,
8689
8754
  background: colors.primary,
8690
8755
  color: "white",
8691
8756
  borderColor: colors.primary
8692
8757
  };
8693
8758
 
8694
8759
  // src/save/ConflictBanner.tsx
8695
- import { jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
8760
+ import { jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
8696
8761
  function ConflictBanner({ onReload, onForceOverwrite }) {
8697
8762
  const messages = useMessages();
8698
- return /* @__PURE__ */ jsxs26(
8763
+ return /* @__PURE__ */ jsxs28(
8699
8764
  "div",
8700
8765
  {
8701
8766
  style: {
@@ -8711,8 +8776,8 @@ function ConflictBanner({ onReload, onForceOverwrite }) {
8711
8776
  role: "alert",
8712
8777
  "data-testid": "conflict-banner",
8713
8778
  children: [
8714
- /* @__PURE__ */ jsx28("span", { style: { flex: 1 }, children: messages.conflict.message }),
8715
- /* @__PURE__ */ jsx28(
8779
+ /* @__PURE__ */ jsx30("span", { style: { flex: 1 }, children: messages.conflict.message }),
8780
+ /* @__PURE__ */ jsx30(
8716
8781
  "button",
8717
8782
  {
8718
8783
  type: "button",
@@ -8722,7 +8787,7 @@ function ConflictBanner({ onReload, onForceOverwrite }) {
8722
8787
  children: messages.conflict.reload
8723
8788
  }
8724
8789
  ),
8725
- /* @__PURE__ */ jsx28(
8790
+ /* @__PURE__ */ jsx30(
8726
8791
  "button",
8727
8792
  {
8728
8793
  type: "button",