@octaviaflow/core 3.1.0-beta.102 → 3.1.0-beta.104
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/components/ExpressionField/ExpressionField.d.ts +18 -7
- package/dist/components/ExpressionField/ExpressionField.d.ts.map +1 -1
- package/dist/components/ExpressionField/parseExpression.d.ts +52 -0
- package/dist/components/ExpressionField/parseExpression.d.ts.map +1 -0
- package/dist/index.cjs +569 -80
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +612 -122
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -34425,13 +34425,176 @@ import {
|
|
|
34425
34425
|
useCallback as useCallback50,
|
|
34426
34426
|
useEffect as useEffect56,
|
|
34427
34427
|
useId as useId61,
|
|
34428
|
-
useRef as useRef50
|
|
34428
|
+
useRef as useRef50,
|
|
34429
|
+
useState as useState71
|
|
34429
34430
|
} from "react";
|
|
34431
|
+
|
|
34432
|
+
// src/components/ExpressionField/parseExpression.ts
|
|
34433
|
+
var CALL_NAME_SOURCE = "(?:[A-Z_][A-Z0-9_]*|user\\.[A-Za-z_][A-Za-z0-9_]*)";
|
|
34434
|
+
var CALL_HEAD = new RegExp(`^(${CALL_NAME_SOURCE})\\s*\\(`);
|
|
34435
|
+
function wrappedRegions(value) {
|
|
34436
|
+
const out = [];
|
|
34437
|
+
let i = 0;
|
|
34438
|
+
while (i < value.length) {
|
|
34439
|
+
const open = value.indexOf("{{", i);
|
|
34440
|
+
if (open === -1) break;
|
|
34441
|
+
let depth = 0;
|
|
34442
|
+
let quote = null;
|
|
34443
|
+
let close = -1;
|
|
34444
|
+
for (let j = open; j < value.length; j++) {
|
|
34445
|
+
const ch = value[j];
|
|
34446
|
+
if (quote) {
|
|
34447
|
+
if (ch === quote) quote = null;
|
|
34448
|
+
continue;
|
|
34449
|
+
}
|
|
34450
|
+
if (ch === '"' || ch === "'") {
|
|
34451
|
+
quote = ch;
|
|
34452
|
+
continue;
|
|
34453
|
+
}
|
|
34454
|
+
if (ch === "{" && value[j + 1] === "{") {
|
|
34455
|
+
depth++;
|
|
34456
|
+
j++;
|
|
34457
|
+
continue;
|
|
34458
|
+
}
|
|
34459
|
+
if (ch === "}" && value[j + 1] === "}") {
|
|
34460
|
+
depth--;
|
|
34461
|
+
j++;
|
|
34462
|
+
if (depth === 0) {
|
|
34463
|
+
close = j;
|
|
34464
|
+
break;
|
|
34465
|
+
}
|
|
34466
|
+
}
|
|
34467
|
+
}
|
|
34468
|
+
if (close === -1) break;
|
|
34469
|
+
out.push({ start: open, end: close });
|
|
34470
|
+
i = close + 1;
|
|
34471
|
+
}
|
|
34472
|
+
return out;
|
|
34473
|
+
}
|
|
34474
|
+
function splitArguments(argsText) {
|
|
34475
|
+
const trimmed = argsText.trim();
|
|
34476
|
+
if (!trimmed) return [];
|
|
34477
|
+
const args = [];
|
|
34478
|
+
let current = "";
|
|
34479
|
+
let depth = 0;
|
|
34480
|
+
let braces = 0;
|
|
34481
|
+
let quote = null;
|
|
34482
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
34483
|
+
const ch = trimmed[i];
|
|
34484
|
+
if (quote) {
|
|
34485
|
+
current += ch;
|
|
34486
|
+
if (ch === quote) quote = null;
|
|
34487
|
+
continue;
|
|
34488
|
+
}
|
|
34489
|
+
if (ch === '"' || ch === "'") {
|
|
34490
|
+
quote = ch;
|
|
34491
|
+
current += ch;
|
|
34492
|
+
continue;
|
|
34493
|
+
}
|
|
34494
|
+
if (ch === "{" && trimmed[i + 1] === "{") {
|
|
34495
|
+
braces++;
|
|
34496
|
+
current += "{{";
|
|
34497
|
+
i++;
|
|
34498
|
+
continue;
|
|
34499
|
+
}
|
|
34500
|
+
if (ch === "}" && trimmed[i + 1] === "}") {
|
|
34501
|
+
braces--;
|
|
34502
|
+
current += "}}";
|
|
34503
|
+
i++;
|
|
34504
|
+
continue;
|
|
34505
|
+
}
|
|
34506
|
+
if (ch === "(") depth++;
|
|
34507
|
+
if (ch === ")") depth--;
|
|
34508
|
+
if (ch === "," && depth === 0 && braces === 0) {
|
|
34509
|
+
args.push(current.trim());
|
|
34510
|
+
current = "";
|
|
34511
|
+
continue;
|
|
34512
|
+
}
|
|
34513
|
+
current += ch;
|
|
34514
|
+
}
|
|
34515
|
+
if (current.trim()) args.push(current.trim());
|
|
34516
|
+
return args;
|
|
34517
|
+
}
|
|
34518
|
+
function parseCall(raw) {
|
|
34519
|
+
const inner = raw.startsWith("{{") && raw.endsWith("}}") ? raw.slice(2, -2).trim() : raw.trim();
|
|
34520
|
+
const head = CALL_HEAD.exec(inner);
|
|
34521
|
+
if (!head) return void 0;
|
|
34522
|
+
const open = inner.indexOf("(");
|
|
34523
|
+
const close = inner.lastIndexOf(")");
|
|
34524
|
+
if (open === -1 || close < open) return void 0;
|
|
34525
|
+
return { name: head[1], args: splitArguments(inner.slice(open + 1, close)) };
|
|
34526
|
+
}
|
|
34527
|
+
function formatCall(name, args) {
|
|
34528
|
+
return `{{${name}(${args.filter((a) => a.trim() !== "").join(", ")})}}`;
|
|
34529
|
+
}
|
|
34530
|
+
function parseExpression(value, pillEveryToken = false) {
|
|
34531
|
+
const segments = [];
|
|
34532
|
+
let cursor = 0;
|
|
34533
|
+
const pushText = (raw) => {
|
|
34534
|
+
if (raw) segments.push({ kind: "text", raw });
|
|
34535
|
+
};
|
|
34536
|
+
for (const { start, end } of wrappedRegions(value)) {
|
|
34537
|
+
pushText(value.slice(cursor, start));
|
|
34538
|
+
const raw = value.slice(start, end + 1);
|
|
34539
|
+
const call = parseCall(raw);
|
|
34540
|
+
if (call) {
|
|
34541
|
+
segments.push({ kind: "call", raw, name: call.name, args: call.args });
|
|
34542
|
+
} else if (raw.startsWith("{{ods://") || pillEveryToken) {
|
|
34543
|
+
segments.push({ kind: "ref", raw });
|
|
34544
|
+
} else {
|
|
34545
|
+
pushText(raw);
|
|
34546
|
+
}
|
|
34547
|
+
cursor = end + 1;
|
|
34548
|
+
}
|
|
34549
|
+
const tail = value.slice(cursor);
|
|
34550
|
+
let last = 0;
|
|
34551
|
+
for (const m of tail.matchAll(/\$\{[^}]+\}/g)) {
|
|
34552
|
+
pushText(tail.slice(last, m.index));
|
|
34553
|
+
segments.push({ kind: "ref", raw: m[0] });
|
|
34554
|
+
last = (m.index ?? 0) + m[0].length;
|
|
34555
|
+
}
|
|
34556
|
+
pushText(tail.slice(last));
|
|
34557
|
+
return segments;
|
|
34558
|
+
}
|
|
34559
|
+
function callAt(raw, path) {
|
|
34560
|
+
let current = parseCall(raw);
|
|
34561
|
+
for (const index of path) {
|
|
34562
|
+
if (!current) return void 0;
|
|
34563
|
+
const arg = current.args[index];
|
|
34564
|
+
if (arg === void 0) return void 0;
|
|
34565
|
+
current = parseCall(arg);
|
|
34566
|
+
}
|
|
34567
|
+
return current;
|
|
34568
|
+
}
|
|
34569
|
+
function formatNestedCall(name, args) {
|
|
34570
|
+
return `${name}(${args.filter((a) => a.trim() !== "").join(", ")})`;
|
|
34571
|
+
}
|
|
34572
|
+
function replaceArgument(raw, path, next) {
|
|
34573
|
+
if (path.length === 0) return next;
|
|
34574
|
+
const [index, ...rest] = path;
|
|
34575
|
+
const call = parseCall(raw);
|
|
34576
|
+
if (!call || index === void 0 || index > call.args.length) return raw;
|
|
34577
|
+
const args = [...call.args];
|
|
34578
|
+
if (args[index] === void 0) args[index] = "";
|
|
34579
|
+
args[index] = rest.length === 0 ? next : replaceArgument(args[index], rest, next);
|
|
34580
|
+
const wrapped = raw.trim().startsWith("{{");
|
|
34581
|
+
return wrapped ? formatCall(call.name, args) : formatNestedCall(call.name, args);
|
|
34582
|
+
}
|
|
34583
|
+
function argumentKind(arg) {
|
|
34584
|
+
const trimmed = arg.trim();
|
|
34585
|
+
if (!trimmed) return "literal";
|
|
34586
|
+
if (parseCall(trimmed)) return "call";
|
|
34587
|
+
if (trimmed.startsWith("{{") || trimmed.startsWith("ods://") || trimmed.startsWith("${")) {
|
|
34588
|
+
return "reference";
|
|
34589
|
+
}
|
|
34590
|
+
return "literal";
|
|
34591
|
+
}
|
|
34592
|
+
|
|
34593
|
+
// src/components/ExpressionField/ExpressionField.tsx
|
|
34430
34594
|
import { jsx as jsx147, jsxs as jsxs141 } from "react/jsx-runtime";
|
|
34431
|
-
var REF_TOKEN = /(\{\{ods:\/\/[^}]+\}\}|\$\{[^}]+\})/g;
|
|
34432
|
-
var ANY_TOKEN = /(\{\{[^}]+\}\}|\$\{[^}]+\})/g;
|
|
34433
|
-
var CALL_TOKEN = /^\{\{\s*(?:[A-Z_][A-Z0-9_]*|user\.[A-Za-z_][A-Za-z0-9_]*)\s*\(/;
|
|
34434
34595
|
var ZERO_WIDTH = "\u200B";
|
|
34596
|
+
var PILL = "ods-expression-field__pill";
|
|
34597
|
+
var CHIP = "ods-expression-field__chip";
|
|
34435
34598
|
function shortReferenceLabel(token) {
|
|
34436
34599
|
if (token.startsWith("{{ods://")) {
|
|
34437
34600
|
const path = token.slice(8, -2);
|
|
@@ -34453,7 +34616,7 @@ function serialize(el) {
|
|
|
34453
34616
|
}
|
|
34454
34617
|
if (node.nodeType !== Node.ELEMENT_NODE) return;
|
|
34455
34618
|
const elem = node;
|
|
34456
|
-
if (elem.classList.contains(
|
|
34619
|
+
if (elem.classList.contains(PILL) || elem.classList.contains(CHIP)) {
|
|
34457
34620
|
out += elem.getAttribute("data-value") || "";
|
|
34458
34621
|
} else if (elem.tagName === "BR") {
|
|
34459
34622
|
out += "\n";
|
|
@@ -34484,6 +34647,19 @@ function insideCallArguments(textBeforeCaret) {
|
|
|
34484
34647
|
}
|
|
34485
34648
|
return depth > 0;
|
|
34486
34649
|
}
|
|
34650
|
+
function argSummary(arg, nameOf, depth = 2) {
|
|
34651
|
+
const trimmed = arg.trim();
|
|
34652
|
+
const call = parseCall(trimmed);
|
|
34653
|
+
if (call) {
|
|
34654
|
+
if (depth <= 0) return `${nameOf(call.name)}(\u2026)`;
|
|
34655
|
+
const inner = call.args.map((a) => argSummary(a, nameOf, depth - 1)).filter(Boolean).join(", ");
|
|
34656
|
+
return `${nameOf(call.name)}(${inner})`;
|
|
34657
|
+
}
|
|
34658
|
+
if (trimmed.startsWith("{{") || trimmed.startsWith("ods://") || trimmed.startsWith("${")) {
|
|
34659
|
+
return shortReferenceLabel(trimmed.startsWith("ods://") ? `{{${trimmed}}}` : trimmed);
|
|
34660
|
+
}
|
|
34661
|
+
return trimmed;
|
|
34662
|
+
}
|
|
34487
34663
|
function ExpressionField({
|
|
34488
34664
|
value,
|
|
34489
34665
|
onChange,
|
|
@@ -34496,6 +34672,7 @@ function ExpressionField({
|
|
|
34496
34672
|
className,
|
|
34497
34673
|
style,
|
|
34498
34674
|
resolveLabel,
|
|
34675
|
+
resolveCall,
|
|
34499
34676
|
pillEveryToken = false,
|
|
34500
34677
|
"aria-label": ariaLabel
|
|
34501
34678
|
}) {
|
|
@@ -34504,28 +34681,42 @@ function ExpressionField({
|
|
|
34504
34681
|
const generatedId = useId61();
|
|
34505
34682
|
const fieldId = id ?? generatedId;
|
|
34506
34683
|
const helperId = `${fieldId}-helper`;
|
|
34507
|
-
const
|
|
34508
|
-
const isPillToken = useCallback50(
|
|
34509
|
-
(part) => {
|
|
34510
|
-
if (CALL_TOKEN.test(part)) return false;
|
|
34511
|
-
return pillEveryToken ? /^(\{\{[^}]+\}\}|\$\{[^}]+\})$/.test(part) : /^(\{\{ods:\/\/[^}]+\}\}|\$\{[^}]+\})$/.test(part);
|
|
34512
|
-
},
|
|
34513
|
-
[pillEveryToken]
|
|
34514
|
-
);
|
|
34684
|
+
const [editing, setEditing] = useState71(null);
|
|
34515
34685
|
const labelFor = useCallback50(
|
|
34516
34686
|
(token) => resolveLabel?.(token) ?? shortReferenceLabel(token),
|
|
34517
34687
|
[resolveLabel]
|
|
34518
34688
|
);
|
|
34519
|
-
const
|
|
34520
|
-
(
|
|
34521
|
-
|
|
34522
|
-
|
|
34523
|
-
|
|
34524
|
-
|
|
34525
|
-
|
|
34526
|
-
return
|
|
34689
|
+
const callLabel = useCallback50(
|
|
34690
|
+
(name) => resolveCall?.(name)?.label ?? (name.startsWith("user.") ? name.slice(5) : name),
|
|
34691
|
+
[resolveCall]
|
|
34692
|
+
);
|
|
34693
|
+
const chipText = useCallback50(
|
|
34694
|
+
(name, args) => {
|
|
34695
|
+
const summary = args.map((a) => argSummary(a, callLabel)).filter(Boolean).join(", ");
|
|
34696
|
+
return `${callLabel(name)}(${summary})`;
|
|
34527
34697
|
},
|
|
34528
|
-
[
|
|
34698
|
+
[callLabel]
|
|
34699
|
+
);
|
|
34700
|
+
const makeToken = useCallback50(
|
|
34701
|
+
(segment) => {
|
|
34702
|
+
if (segment.kind === "text") return null;
|
|
34703
|
+
const el = document.createElement("span");
|
|
34704
|
+
el.contentEditable = "false";
|
|
34705
|
+
el.setAttribute("data-value", segment.raw);
|
|
34706
|
+
el.tabIndex = -1;
|
|
34707
|
+
if (segment.kind === "ref") {
|
|
34708
|
+
el.className = PILL;
|
|
34709
|
+
el.textContent = labelFor(segment.raw);
|
|
34710
|
+
el.title = segment.raw;
|
|
34711
|
+
} else {
|
|
34712
|
+
el.className = CHIP;
|
|
34713
|
+
el.setAttribute("data-call", segment.name);
|
|
34714
|
+
el.textContent = chipText(segment.name, segment.args);
|
|
34715
|
+
el.title = segment.raw;
|
|
34716
|
+
}
|
|
34717
|
+
return el;
|
|
34718
|
+
},
|
|
34719
|
+
[labelFor, chipText]
|
|
34529
34720
|
);
|
|
34530
34721
|
const render = useCallback50(
|
|
34531
34722
|
(raw) => {
|
|
@@ -34533,17 +34724,19 @@ function ExpressionField({
|
|
|
34533
34724
|
if (!el) return;
|
|
34534
34725
|
el.innerHTML = "";
|
|
34535
34726
|
if (!raw) return;
|
|
34536
|
-
|
|
34537
|
-
if (
|
|
34538
|
-
|
|
34539
|
-
|
|
34727
|
+
for (const segment of parseExpression(raw, pillEveryToken)) {
|
|
34728
|
+
if (segment.kind === "text") {
|
|
34729
|
+
el.appendChild(document.createTextNode(segment.raw));
|
|
34730
|
+
continue;
|
|
34731
|
+
}
|
|
34732
|
+
const token = makeToken(segment);
|
|
34733
|
+
if (token) {
|
|
34734
|
+
el.appendChild(token);
|
|
34540
34735
|
el.appendChild(document.createTextNode(ZERO_WIDTH));
|
|
34541
|
-
} else {
|
|
34542
|
-
el.appendChild(document.createTextNode(part));
|
|
34543
34736
|
}
|
|
34544
|
-
}
|
|
34737
|
+
}
|
|
34545
34738
|
},
|
|
34546
|
-
[
|
|
34739
|
+
[pillEveryToken, makeToken]
|
|
34547
34740
|
);
|
|
34548
34741
|
useEffect56(() => {
|
|
34549
34742
|
if (fromSelf.current) {
|
|
@@ -34564,9 +34757,8 @@ function ExpressionField({
|
|
|
34564
34757
|
if (!el || !sel || sel.rangeCount === 0 || !el.contains(sel.anchorNode)) return "";
|
|
34565
34758
|
const range = sel.getRangeAt(0).cloneRange();
|
|
34566
34759
|
range.setStart(el, 0);
|
|
34567
|
-
const fragment = range.cloneContents();
|
|
34568
34760
|
const holder = document.createElement("div");
|
|
34569
|
-
holder.appendChild(
|
|
34761
|
+
holder.appendChild(range.cloneContents());
|
|
34570
34762
|
return serialize(holder);
|
|
34571
34763
|
}, []);
|
|
34572
34764
|
const insert = useCallback50(
|
|
@@ -34576,9 +34768,19 @@ function ExpressionField({
|
|
|
34576
34768
|
const sel = window.getSelection();
|
|
34577
34769
|
const hasCaret = !!sel && sel.rangeCount > 0 && el.contains(sel.anchorNode);
|
|
34578
34770
|
const asArgument = hasCaret && insideCallArguments(textBeforeCaret());
|
|
34579
|
-
const
|
|
34580
|
-
const
|
|
34581
|
-
const
|
|
34771
|
+
const call = parseCall(raw);
|
|
34772
|
+
const isCall = kind === "function" || !!call;
|
|
34773
|
+
const text = isCall || asArgument ? raw : raw.startsWith("ods://") ? `{{${raw}}}` : raw;
|
|
34774
|
+
let node;
|
|
34775
|
+
if (asArgument) {
|
|
34776
|
+
node = document.createTextNode(text);
|
|
34777
|
+
} else if (isCall && call) {
|
|
34778
|
+
node = makeToken({ kind: "call", raw: text, name: call.name, args: call.args });
|
|
34779
|
+
} else if (text.startsWith("{{") || text.startsWith("${")) {
|
|
34780
|
+
node = makeToken({ kind: "ref", raw: text });
|
|
34781
|
+
} else {
|
|
34782
|
+
node = document.createTextNode(text);
|
|
34783
|
+
}
|
|
34582
34784
|
const range = hasCaret && sel ? sel.getRangeAt(0) : (() => {
|
|
34583
34785
|
const r = document.createRange();
|
|
34584
34786
|
r.selectNodeContents(el);
|
|
@@ -34590,27 +34792,113 @@ function ExpressionField({
|
|
|
34590
34792
|
const after = document.createTextNode(ZERO_WIDTH);
|
|
34591
34793
|
range.setStartAfter(node);
|
|
34592
34794
|
range.insertNode(after);
|
|
34593
|
-
|
|
34594
|
-
|
|
34595
|
-
const close = text.lastIndexOf(")");
|
|
34596
|
-
if (open !== -1 && close === open + 1) {
|
|
34597
|
-
range.setStart(node, open + 1);
|
|
34598
|
-
range.collapse(true);
|
|
34599
|
-
} else {
|
|
34600
|
-
range.setStartAfter(after);
|
|
34601
|
-
range.collapse(true);
|
|
34602
|
-
}
|
|
34603
|
-
} else {
|
|
34604
|
-
range.setStartAfter(after);
|
|
34605
|
-
range.collapse(true);
|
|
34606
|
-
}
|
|
34795
|
+
range.setStartAfter(after);
|
|
34796
|
+
range.collapse(true);
|
|
34607
34797
|
el.focus();
|
|
34608
34798
|
const selection = window.getSelection();
|
|
34609
34799
|
selection?.removeAllRanges();
|
|
34610
34800
|
selection?.addRange(range);
|
|
34611
34801
|
commit();
|
|
34802
|
+
if (isCall && call && node instanceof HTMLElement && call.args.length === 0) {
|
|
34803
|
+
openEditor(node);
|
|
34804
|
+
}
|
|
34805
|
+
},
|
|
34806
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34807
|
+
[commit, disabled, makeToken, textBeforeCaret]
|
|
34808
|
+
);
|
|
34809
|
+
const selected = useRef50(null);
|
|
34810
|
+
const selectToken = useCallback50((token) => {
|
|
34811
|
+
selected.current = token;
|
|
34812
|
+
const range = document.createRange();
|
|
34813
|
+
range.selectNode(token);
|
|
34814
|
+
const sel = window.getSelection();
|
|
34815
|
+
sel?.removeAllRanges();
|
|
34816
|
+
sel?.addRange(range);
|
|
34817
|
+
fieldRef.current?.focus();
|
|
34818
|
+
}, []);
|
|
34819
|
+
const openEditor = useCallback50((chip) => {
|
|
34820
|
+
const raw = chip.getAttribute("data-value") ?? "";
|
|
34821
|
+
if (!parseCall(raw)) return;
|
|
34822
|
+
const box = chip.getBoundingClientRect();
|
|
34823
|
+
const host = fieldRef.current?.getBoundingClientRect();
|
|
34824
|
+
setEditing({
|
|
34825
|
+
el: chip,
|
|
34826
|
+
raw,
|
|
34827
|
+
rect: {
|
|
34828
|
+
top: box.bottom - (host?.top ?? 0) + 4,
|
|
34829
|
+
left: Math.max(0, box.left - (host?.left ?? 0)),
|
|
34830
|
+
width: Math.max(300, box.width)
|
|
34831
|
+
}
|
|
34832
|
+
});
|
|
34833
|
+
}, []);
|
|
34834
|
+
const applyEditor = useCallback50(
|
|
34835
|
+
(raw) => {
|
|
34836
|
+
if (!editing) return;
|
|
34837
|
+
const call = parseCall(raw);
|
|
34838
|
+
if (!call) return;
|
|
34839
|
+
editing.el.setAttribute("data-value", raw);
|
|
34840
|
+
editing.el.textContent = chipText(call.name, call.args);
|
|
34841
|
+
editing.el.title = raw;
|
|
34842
|
+
setEditing(null);
|
|
34843
|
+
commit();
|
|
34844
|
+
fieldRef.current?.focus();
|
|
34845
|
+
},
|
|
34846
|
+
[editing, chipText, commit]
|
|
34847
|
+
);
|
|
34848
|
+
const handleClick = useCallback50(
|
|
34849
|
+
(e) => {
|
|
34850
|
+
const target = e.target.closest(`.${PILL}, .${CHIP}`);
|
|
34851
|
+
if (!target) return;
|
|
34852
|
+
selectToken(target);
|
|
34853
|
+
if (!disabled && target.classList.contains(CHIP) && e.detail >= 2) {
|
|
34854
|
+
openEditor(target);
|
|
34855
|
+
}
|
|
34856
|
+
},
|
|
34857
|
+
[disabled, openEditor, selectToken]
|
|
34858
|
+
);
|
|
34859
|
+
const handleCopy = useCallback50(
|
|
34860
|
+
(e, cut = false) => {
|
|
34861
|
+
const sel = window.getSelection();
|
|
34862
|
+
if (!sel || sel.rangeCount === 0) return;
|
|
34863
|
+
const holder = document.createElement("div");
|
|
34864
|
+
holder.appendChild(sel.getRangeAt(0).cloneContents());
|
|
34865
|
+
const token = selected.current;
|
|
34866
|
+
const text = serialize(holder) || (token && fieldRef.current?.contains(token) && sel.containsNode(token, true) ? token.getAttribute("data-value") ?? "" : "");
|
|
34867
|
+
if (!text) return;
|
|
34868
|
+
e.preventDefault();
|
|
34869
|
+
e.clipboardData.setData("text/plain", text);
|
|
34870
|
+
if (cut && !disabled) {
|
|
34871
|
+
if (serialize(holder)) sel.getRangeAt(0).deleteContents();
|
|
34872
|
+
else token?.remove();
|
|
34873
|
+
commit();
|
|
34874
|
+
}
|
|
34875
|
+
},
|
|
34876
|
+
[commit, disabled]
|
|
34877
|
+
);
|
|
34878
|
+
const handlePaste = useCallback50(
|
|
34879
|
+
(e) => {
|
|
34880
|
+
e.preventDefault();
|
|
34881
|
+
const text = e.clipboardData.getData("text/plain");
|
|
34882
|
+
if (!text) return;
|
|
34883
|
+
document.execCommand("insertText", false, text);
|
|
34884
|
+
const next = serialize(fieldRef.current);
|
|
34885
|
+
fromSelf.current = false;
|
|
34886
|
+
onChange(next);
|
|
34887
|
+
},
|
|
34888
|
+
[onChange]
|
|
34889
|
+
);
|
|
34890
|
+
const handleKeyDown = useCallback50(
|
|
34891
|
+
(e) => {
|
|
34892
|
+
if (e.key !== "Enter" || !e.metaKey) return;
|
|
34893
|
+
const sel = window.getSelection();
|
|
34894
|
+
const node = sel?.anchorNode;
|
|
34895
|
+
const chip = node instanceof HTMLElement ? node.closest(`.${CHIP}`) : node?.parentElement?.closest(`.${CHIP}`) ?? null;
|
|
34896
|
+
if (chip) {
|
|
34897
|
+
e.preventDefault();
|
|
34898
|
+
openEditor(chip);
|
|
34899
|
+
}
|
|
34612
34900
|
},
|
|
34613
|
-
[
|
|
34901
|
+
[openEditor]
|
|
34614
34902
|
);
|
|
34615
34903
|
const handleDragOver = useCallback50(
|
|
34616
34904
|
(e) => {
|
|
@@ -34637,42 +34925,244 @@ function ExpressionField({
|
|
|
34637
34925
|
},
|
|
34638
34926
|
[disabled, insert]
|
|
34639
34927
|
);
|
|
34640
|
-
const
|
|
34641
|
-
|
|
34642
|
-
|
|
34643
|
-
|
|
34644
|
-
|
|
34928
|
+
const handleBlur = useCallback50(() => {
|
|
34929
|
+
const el = fieldRef.current;
|
|
34930
|
+
if (!el) return;
|
|
34931
|
+
const next = serialize(el);
|
|
34932
|
+
if (next !== value) {
|
|
34933
|
+
fromSelf.current = true;
|
|
34934
|
+
onChange(next);
|
|
34935
|
+
}
|
|
34936
|
+
if (!editing) render(next);
|
|
34937
|
+
}, [editing, onChange, render, value]);
|
|
34645
34938
|
return /* @__PURE__ */ jsxs141("div", { className: cn("ods-expression-field", className), style, children: [
|
|
34646
34939
|
label && /* @__PURE__ */ jsx147("label", { className: "ods-expression-field__label", htmlFor: fieldId, children: label }),
|
|
34647
|
-
/* @__PURE__ */
|
|
34648
|
-
|
|
34649
|
-
|
|
34650
|
-
|
|
34651
|
-
|
|
34652
|
-
|
|
34653
|
-
|
|
34654
|
-
|
|
34655
|
-
|
|
34656
|
-
|
|
34657
|
-
|
|
34658
|
-
|
|
34659
|
-
|
|
34660
|
-
|
|
34661
|
-
|
|
34662
|
-
|
|
34663
|
-
|
|
34664
|
-
|
|
34665
|
-
|
|
34666
|
-
|
|
34667
|
-
|
|
34668
|
-
|
|
34669
|
-
|
|
34670
|
-
|
|
34671
|
-
|
|
34672
|
-
|
|
34940
|
+
/* @__PURE__ */ jsxs141("div", { className: "ods-expression-field__body", children: [
|
|
34941
|
+
/* @__PURE__ */ jsx147(
|
|
34942
|
+
"div",
|
|
34943
|
+
{
|
|
34944
|
+
id: fieldId,
|
|
34945
|
+
ref: fieldRef,
|
|
34946
|
+
role: "textbox",
|
|
34947
|
+
"aria-multiline": "true",
|
|
34948
|
+
"aria-label": ariaLabel ?? (typeof label === "string" ? label : void 0),
|
|
34949
|
+
"aria-describedby": helperText ? helperId : void 0,
|
|
34950
|
+
"aria-disabled": disabled || void 0,
|
|
34951
|
+
contentEditable: !disabled,
|
|
34952
|
+
suppressContentEditableWarning: true,
|
|
34953
|
+
"data-placeholder": placeholder,
|
|
34954
|
+
className: cn(
|
|
34955
|
+
"ods-expression-field__input",
|
|
34956
|
+
disabled && "ods-expression-field__input--disabled"
|
|
34957
|
+
),
|
|
34958
|
+
style: { minHeight: `${Math.max(1, rows) * 1.5 + 1}rem` },
|
|
34959
|
+
onInput: commit,
|
|
34960
|
+
onBlur: handleBlur,
|
|
34961
|
+
onClick: handleClick,
|
|
34962
|
+
onKeyDown: handleKeyDown,
|
|
34963
|
+
onCopy: handleCopy,
|
|
34964
|
+
onCut: (e) => handleCopy(e, true),
|
|
34965
|
+
onPaste: handlePaste,
|
|
34966
|
+
onDragOver: handleDragOver,
|
|
34967
|
+
onDragLeave: handleDragLeave,
|
|
34968
|
+
onDrop: handleDrop
|
|
34969
|
+
}
|
|
34970
|
+
),
|
|
34971
|
+
editing && /* @__PURE__ */ jsx147(
|
|
34972
|
+
CallEditor,
|
|
34973
|
+
{
|
|
34974
|
+
raw: editing.raw,
|
|
34975
|
+
rect: editing.rect,
|
|
34976
|
+
nameOf: callLabel,
|
|
34977
|
+
labelFor,
|
|
34978
|
+
resolveCall,
|
|
34979
|
+
onCancel: () => setEditing(null),
|
|
34980
|
+
onApply: applyEditor
|
|
34981
|
+
}
|
|
34982
|
+
)
|
|
34983
|
+
] }),
|
|
34673
34984
|
helperText && /* @__PURE__ */ jsx147("span", { id: helperId, className: "ods-expression-field__helper", children: helperText })
|
|
34674
34985
|
] });
|
|
34675
34986
|
}
|
|
34987
|
+
function CallEditor({
|
|
34988
|
+
raw,
|
|
34989
|
+
rect,
|
|
34990
|
+
nameOf,
|
|
34991
|
+
labelFor,
|
|
34992
|
+
resolveCall,
|
|
34993
|
+
onApply,
|
|
34994
|
+
onCancel
|
|
34995
|
+
}) {
|
|
34996
|
+
const [draft, setDraft] = useState71(raw);
|
|
34997
|
+
const [path, setPath] = useState71([]);
|
|
34998
|
+
const [rawMode, setRawMode] = useState71(false);
|
|
34999
|
+
const panelRef = useRef50(null);
|
|
35000
|
+
useEffect56(() => {
|
|
35001
|
+
const onKey = (e) => {
|
|
35002
|
+
if (e.key === "Escape") onCancel();
|
|
35003
|
+
};
|
|
35004
|
+
document.addEventListener("keydown", onKey);
|
|
35005
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
35006
|
+
}, [onCancel]);
|
|
35007
|
+
const current = callAt(draft, path);
|
|
35008
|
+
const signature = current ? resolveCall?.(current.name) : void 0;
|
|
35009
|
+
const names = signature?.args ?? [];
|
|
35010
|
+
const args = current ? current.args.length ? current.args : [""] : [];
|
|
35011
|
+
const crumbs = [];
|
|
35012
|
+
for (let i = 0; i <= path.length; i++) {
|
|
35013
|
+
const at = callAt(draft, path.slice(0, i));
|
|
35014
|
+
if (at) crumbs.push({ label: nameOf(at.name), path: path.slice(0, i) });
|
|
35015
|
+
}
|
|
35016
|
+
const setArg = (index, next) => setDraft((d) => replaceArgument(d, [...path, index], next));
|
|
35017
|
+
const dropInto = (index) => (e) => {
|
|
35018
|
+
const dropped = e.dataTransfer.getData("application/x-fx-insert");
|
|
35019
|
+
if (!dropped) return;
|
|
35020
|
+
e.preventDefault();
|
|
35021
|
+
e.stopPropagation();
|
|
35022
|
+
const kind = e.dataTransfer.getData("application/x-fx-type");
|
|
35023
|
+
const bare = dropped.startsWith("{{") && dropped.endsWith("}}") ? dropped.slice(2, -2).trim() : dropped;
|
|
35024
|
+
setDraft((d) => replaceArgument(d, [...path, index], bare));
|
|
35025
|
+
if (kind === "function" || parseCall(bare)) setPath((pth) => [...pth, index]);
|
|
35026
|
+
};
|
|
35027
|
+
return /* @__PURE__ */ jsxs141(
|
|
35028
|
+
"div",
|
|
35029
|
+
{
|
|
35030
|
+
ref: panelRef,
|
|
35031
|
+
className: "ods-expression-field__editor",
|
|
35032
|
+
style: { top: rect.top, left: rect.left, width: rect.width },
|
|
35033
|
+
role: "dialog",
|
|
35034
|
+
"aria-label": `Edit ${crumbs[0]?.label ?? "function"}`,
|
|
35035
|
+
children: [
|
|
35036
|
+
/* @__PURE__ */ jsxs141("div", { className: "ods-expression-field__editor-head", children: [
|
|
35037
|
+
/* @__PURE__ */ jsx147("nav", { className: "ods-expression-field__editor-crumbs", "aria-label": "Nested functions", children: crumbs.map((crumb, i) => /* @__PURE__ */ jsxs141("span", { children: [
|
|
35038
|
+
i > 0 && /* @__PURE__ */ jsx147("span", { "aria-hidden": "true", children: " \u203A " }),
|
|
35039
|
+
/* @__PURE__ */ jsx147(
|
|
35040
|
+
"button",
|
|
35041
|
+
{
|
|
35042
|
+
type: "button",
|
|
35043
|
+
disabled: i === crumbs.length - 1,
|
|
35044
|
+
onClick: () => setPath(crumb.path),
|
|
35045
|
+
children: crumb.label
|
|
35046
|
+
}
|
|
35047
|
+
)
|
|
35048
|
+
] }, crumb.path.join(".") || "root")) }),
|
|
35049
|
+
/* @__PURE__ */ jsx147(
|
|
35050
|
+
"button",
|
|
35051
|
+
{
|
|
35052
|
+
type: "button",
|
|
35053
|
+
className: "ods-expression-field__editor-link",
|
|
35054
|
+
onClick: () => setRawMode((r) => !r),
|
|
35055
|
+
children: rawMode ? "Back to fields" : "Edit as text"
|
|
35056
|
+
}
|
|
35057
|
+
)
|
|
35058
|
+
] }),
|
|
35059
|
+
rawMode ? /* @__PURE__ */ jsx147(
|
|
35060
|
+
"textarea",
|
|
35061
|
+
{
|
|
35062
|
+
className: "ods-expression-field__editor-raw",
|
|
35063
|
+
value: draft,
|
|
35064
|
+
rows: 3,
|
|
35065
|
+
"aria-label": "Expression",
|
|
35066
|
+
onChange: (e) => setDraft(e.target.value)
|
|
35067
|
+
}
|
|
35068
|
+
) : /* @__PURE__ */ jsxs141("div", { className: "ods-expression-field__editor-rows", children: [
|
|
35069
|
+
args.map((arg, index) => {
|
|
35070
|
+
const kind = argumentKind(arg);
|
|
35071
|
+
const rowLabel = names[index] ?? `argument ${index + 1}`;
|
|
35072
|
+
const nested = kind === "call" ? parseCall(arg) : void 0;
|
|
35073
|
+
return (
|
|
35074
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
35075
|
+
/* @__PURE__ */ jsxs141("div", { className: "ods-expression-field__editor-row", children: [
|
|
35076
|
+
/* @__PURE__ */ jsx147("span", { id: `arg-${index}-label`, children: rowLabel }),
|
|
35077
|
+
nested ? /* @__PURE__ */ jsxs141(
|
|
35078
|
+
"div",
|
|
35079
|
+
{
|
|
35080
|
+
className: "ods-expression-field__editor-nested",
|
|
35081
|
+
onDragOver: (e) => {
|
|
35082
|
+
if (e.dataTransfer.types.includes("application/x-fx-insert")) e.preventDefault();
|
|
35083
|
+
},
|
|
35084
|
+
onDrop: dropInto(index),
|
|
35085
|
+
children: [
|
|
35086
|
+
/* @__PURE__ */ jsx147("code", { children: argSummary(arg, nameOf) }),
|
|
35087
|
+
/* @__PURE__ */ jsxs141("span", { children: [
|
|
35088
|
+
/* @__PURE__ */ jsx147("button", { type: "button", onClick: () => setPath([...path, index]), children: "Open" }),
|
|
35089
|
+
/* @__PURE__ */ jsx147("button", { type: "button", onClick: () => setArg(index, ""), "aria-label": `Clear ${rowLabel}`, children: "Clear" })
|
|
35090
|
+
] })
|
|
35091
|
+
]
|
|
35092
|
+
}
|
|
35093
|
+
) : kind === "reference" ? (
|
|
35094
|
+
// A reference is a value from somewhere else — named, never
|
|
35095
|
+
// its raw `ods://…` path, here as much as in the field.
|
|
35096
|
+
/* @__PURE__ */ jsxs141(
|
|
35097
|
+
"div",
|
|
35098
|
+
{
|
|
35099
|
+
className: "ods-expression-field__editor-ref",
|
|
35100
|
+
onDragOver: (e) => {
|
|
35101
|
+
if (e.dataTransfer.types.includes("application/x-fx-insert")) e.preventDefault();
|
|
35102
|
+
},
|
|
35103
|
+
onDrop: dropInto(index),
|
|
35104
|
+
children: [
|
|
35105
|
+
/* @__PURE__ */ jsx147(
|
|
35106
|
+
"span",
|
|
35107
|
+
{
|
|
35108
|
+
className: "ods-expression-field__pill",
|
|
35109
|
+
title: arg,
|
|
35110
|
+
"aria-labelledby": `arg-${index}-label`,
|
|
35111
|
+
children: labelFor(arg.startsWith("ods://") ? `{{${arg}}}` : arg)
|
|
35112
|
+
}
|
|
35113
|
+
),
|
|
35114
|
+
/* @__PURE__ */ jsx147("button", { type: "button", onClick: () => setArg(index, ""), "aria-label": `Clear ${rowLabel}`, children: "Clear" })
|
|
35115
|
+
]
|
|
35116
|
+
}
|
|
35117
|
+
)
|
|
35118
|
+
) : /* @__PURE__ */ jsx147(
|
|
35119
|
+
"input",
|
|
35120
|
+
{
|
|
35121
|
+
"aria-labelledby": `arg-${index}-label`,
|
|
35122
|
+
value: arg,
|
|
35123
|
+
placeholder: 'a value, "text", or drag one in',
|
|
35124
|
+
"data-kind": kind,
|
|
35125
|
+
onChange: (e) => setArg(index, e.target.value),
|
|
35126
|
+
onDragOver: (e) => {
|
|
35127
|
+
if (e.dataTransfer.types.includes("application/x-fx-insert")) e.preventDefault();
|
|
35128
|
+
},
|
|
35129
|
+
onDrop: dropInto(index)
|
|
35130
|
+
}
|
|
35131
|
+
)
|
|
35132
|
+
] }, index)
|
|
35133
|
+
);
|
|
35134
|
+
}),
|
|
35135
|
+
/* @__PURE__ */ jsx147(
|
|
35136
|
+
"button",
|
|
35137
|
+
{
|
|
35138
|
+
type: "button",
|
|
35139
|
+
className: "ods-expression-field__editor-link",
|
|
35140
|
+
onClick: () => setDraft((d) => {
|
|
35141
|
+
const at = callAt(d, path);
|
|
35142
|
+
if (!at) return d;
|
|
35143
|
+
const next = [...at.args, '""'];
|
|
35144
|
+
return path.length === 0 ? formatCall(at.name, next) : replaceArgument(d, path, `${at.name}(${next.join(", ")})`);
|
|
35145
|
+
}),
|
|
35146
|
+
children: "+ argument"
|
|
35147
|
+
}
|
|
35148
|
+
)
|
|
35149
|
+
] }),
|
|
35150
|
+
/* @__PURE__ */ jsxs141("div", { className: "ods-expression-field__editor-foot", children: [
|
|
35151
|
+
/* @__PURE__ */ jsx147("button", { type: "button", onClick: onCancel, children: "Cancel" }),
|
|
35152
|
+
/* @__PURE__ */ jsx147(
|
|
35153
|
+
"button",
|
|
35154
|
+
{
|
|
35155
|
+
type: "button",
|
|
35156
|
+
className: "ods-expression-field__editor-primary",
|
|
35157
|
+
onClick: () => onApply(draft),
|
|
35158
|
+
children: "Apply"
|
|
35159
|
+
}
|
|
35160
|
+
)
|
|
35161
|
+
] })
|
|
35162
|
+
]
|
|
35163
|
+
}
|
|
35164
|
+
);
|
|
35165
|
+
}
|
|
34676
35166
|
|
|
34677
35167
|
// src/components/TopBar/TopBar.tsx
|
|
34678
35168
|
import { jsx as jsx148, jsxs as jsxs142 } from "react/jsx-runtime";
|
|
@@ -34761,7 +35251,7 @@ import {
|
|
|
34761
35251
|
forwardRef as forwardRef97,
|
|
34762
35252
|
useCallback as useCallback51,
|
|
34763
35253
|
useId as useId62,
|
|
34764
|
-
useState as
|
|
35254
|
+
useState as useState72
|
|
34765
35255
|
} from "react";
|
|
34766
35256
|
import {
|
|
34767
35257
|
BuildToolIcon,
|
|
@@ -34807,7 +35297,7 @@ var TraceStep = forwardRef97(
|
|
|
34807
35297
|
const baseId = providedId ?? `ods-trace-step-${reactId}`;
|
|
34808
35298
|
const headId = `${baseId}-head`;
|
|
34809
35299
|
const contentId = `${baseId}-content`;
|
|
34810
|
-
const [uncontrolledOpen, setUncontrolledOpen] =
|
|
35300
|
+
const [uncontrolledOpen, setUncontrolledOpen] = useState72(defaultOpen);
|
|
34811
35301
|
const isControlled = controlledOpen !== void 0;
|
|
34812
35302
|
const open = isControlled ? controlledOpen : uncontrolledOpen;
|
|
34813
35303
|
const canExpand = !!children;
|
|
@@ -35166,7 +35656,7 @@ var UserCard = forwardRef99(function UserCard2({
|
|
|
35166
35656
|
UserCard.displayName = "UserCard";
|
|
35167
35657
|
|
|
35168
35658
|
// src/components/WorkflowEditor/WorkflowEditor.tsx
|
|
35169
|
-
import { useCallback as useCallback53, useMemo as useMemo39, useState as
|
|
35659
|
+
import { useCallback as useCallback53, useMemo as useMemo39, useState as useState73 } from "react";
|
|
35170
35660
|
|
|
35171
35661
|
// src/hooks/useWorkflow.ts
|
|
35172
35662
|
import { useCallback as useCallback52, useMemo as useMemo38, useReducer } from "react";
|
|
@@ -35934,10 +36424,10 @@ function WorkflowEditor({
|
|
|
35934
36424
|
}) {
|
|
35935
36425
|
const wf = useWorkflow(options2);
|
|
35936
36426
|
const { workflow, dispatch, canUndo, canRedo, undo, redo } = wf;
|
|
35937
|
-
const [uncontrolledLock, setUncontrolledLock] =
|
|
35938
|
-
const [uncontrolledDrawer, setUncontrolledDrawer] =
|
|
35939
|
-
const [uncontrolledHistory, setUncontrolledHistory] =
|
|
35940
|
-
const [uncontrolledDebug, setUncontrolledDebug] =
|
|
36427
|
+
const [uncontrolledLock, setUncontrolledLock] = useState73(false);
|
|
36428
|
+
const [uncontrolledDrawer, setUncontrolledDrawer] = useState73(!!drawer);
|
|
36429
|
+
const [uncontrolledHistory, setUncontrolledHistory] = useState73(false);
|
|
36430
|
+
const [uncontrolledDebug, setUncontrolledDebug] = useState73(false);
|
|
35941
36431
|
const isLockMode = controlledLockMode ?? uncontrolledLock;
|
|
35942
36432
|
const isDrawerOpen = controlledDrawerOpen ?? uncontrolledDrawer;
|
|
35943
36433
|
const isHistoryOpen = controlledHistoryOpen ?? uncontrolledHistory;
|
|
@@ -36028,7 +36518,7 @@ function WorkflowEditor({
|
|
|
36028
36518
|
},
|
|
36029
36519
|
[wf]
|
|
36030
36520
|
);
|
|
36031
|
-
const [canvasSize, setCanvasSize] =
|
|
36521
|
+
const [canvasSize, setCanvasSize] = useState73({ w: 0, h: 0 });
|
|
36032
36522
|
const handleCanvasRef = useCallback53((node) => {
|
|
36033
36523
|
if (!node) return;
|
|
36034
36524
|
setCanvasSize({ w: node.clientWidth, h: node.clientHeight });
|
|
@@ -36278,7 +36768,7 @@ import {
|
|
|
36278
36768
|
} from "@octaviaflow/icons";
|
|
36279
36769
|
|
|
36280
36770
|
// src/hooks/useWorkflowRuntime.ts
|
|
36281
|
-
import { useEffect as useEffect57, useState as
|
|
36771
|
+
import { useEffect as useEffect57, useState as useState74 } from "react";
|
|
36282
36772
|
function toMs2(t) {
|
|
36283
36773
|
if (t == null) return null;
|
|
36284
36774
|
return typeof t === "number" ? t : t.getTime();
|
|
@@ -36292,7 +36782,7 @@ function formatWorkflowRuntime(ms) {
|
|
|
36292
36782
|
return h > 0 ? `${h}:${pad2(m)}:${pad2(sec)}` : `${pad2(m)}:${pad2(sec)}`;
|
|
36293
36783
|
}
|
|
36294
36784
|
function useWorkflowRuntime(startedAt, active) {
|
|
36295
|
-
const [, force] =
|
|
36785
|
+
const [, force] = useState74(0);
|
|
36296
36786
|
useEffect57(() => {
|
|
36297
36787
|
if (!active || startedAt == null) return;
|
|
36298
36788
|
if (typeof window === "undefined") return;
|
|
@@ -36673,10 +37163,10 @@ function WorkflowHeaderExpanded({
|
|
|
36673
37163
|
}
|
|
36674
37164
|
|
|
36675
37165
|
// src/hooks/useBanner.ts
|
|
36676
|
-
import { useCallback as useCallback54, useEffect as useEffect58, useRef as useRef51, useState as
|
|
37166
|
+
import { useCallback as useCallback54, useEffect as useEffect58, useRef as useRef51, useState as useState75 } from "react";
|
|
36677
37167
|
function useBanner(options2 = {}) {
|
|
36678
37168
|
const { defaultOpen = false, autoDismissAfter, onDismiss } = options2;
|
|
36679
|
-
const [open, setOpen] =
|
|
37169
|
+
const [open, setOpen] = useState75(defaultOpen);
|
|
36680
37170
|
const timerRef = useRef51(null);
|
|
36681
37171
|
const onDismissRef = useRef51(onDismiss);
|
|
36682
37172
|
useEffect58(() => {
|
|
@@ -36721,7 +37211,7 @@ function useBanner(options2 = {}) {
|
|
|
36721
37211
|
}
|
|
36722
37212
|
|
|
36723
37213
|
// src/hooks/useCallout.ts
|
|
36724
|
-
import { useCallback as useCallback55, useEffect as useEffect59, useState as
|
|
37214
|
+
import { useCallback as useCallback55, useEffect as useEffect59, useState as useState76 } from "react";
|
|
36725
37215
|
var STORAGE_PREFIX = "ods:callout:dismissed:";
|
|
36726
37216
|
function readPersisted(key) {
|
|
36727
37217
|
if (!key || typeof window === "undefined") return false;
|
|
@@ -36744,7 +37234,7 @@ function writePersisted(key, value) {
|
|
|
36744
37234
|
}
|
|
36745
37235
|
function useCallout(options2 = {}) {
|
|
36746
37236
|
const { defaultOpen = true, persistKey, onDismiss } = options2;
|
|
36747
|
-
const [open, setOpen] =
|
|
37237
|
+
const [open, setOpen] = useState76(defaultOpen);
|
|
36748
37238
|
useEffect59(() => {
|
|
36749
37239
|
if (persistKey && readPersisted(persistKey)) {
|
|
36750
37240
|
setOpen(false);
|
|
@@ -36845,7 +37335,7 @@ function breakpointMinWidth(name) {
|
|
|
36845
37335
|
}
|
|
36846
37336
|
|
|
36847
37337
|
// src/hooks/useRating.ts
|
|
36848
|
-
import { useCallback as useCallback56, useState as
|
|
37338
|
+
import { useCallback as useCallback56, useState as useState77 } from "react";
|
|
36849
37339
|
function useRating({
|
|
36850
37340
|
value: controlled,
|
|
36851
37341
|
defaultValue = 0,
|
|
@@ -36853,7 +37343,7 @@ function useRating({
|
|
|
36853
37343
|
step = 1,
|
|
36854
37344
|
onChange
|
|
36855
37345
|
} = {}) {
|
|
36856
|
-
const [internal, setInternal] =
|
|
37346
|
+
const [internal, setInternal] = useState77(defaultValue);
|
|
36857
37347
|
const value = controlled ?? internal;
|
|
36858
37348
|
const isControlled = controlled !== void 0;
|
|
36859
37349
|
const clamp2 = useCallback56(
|
|
@@ -36882,7 +37372,7 @@ function useBinaryRating({
|
|
|
36882
37372
|
defaultValue = null,
|
|
36883
37373
|
onChange
|
|
36884
37374
|
} = {}) {
|
|
36885
|
-
const [internal, setInternal] =
|
|
37375
|
+
const [internal, setInternal] = useState77(defaultValue);
|
|
36886
37376
|
const value = controlled ?? internal;
|
|
36887
37377
|
const isControlled = controlled !== void 0;
|
|
36888
37378
|
const set = useCallback56(
|
|
@@ -36904,13 +37394,13 @@ function useBinaryRating({
|
|
|
36904
37394
|
}
|
|
36905
37395
|
|
|
36906
37396
|
// src/hooks/useTimeline.ts
|
|
36907
|
-
import { useCallback as useCallback57, useState as
|
|
37397
|
+
import { useCallback as useCallback57, useState as useState78 } from "react";
|
|
36908
37398
|
function useTimeline({
|
|
36909
37399
|
items: controlled,
|
|
36910
37400
|
defaultItems = [],
|
|
36911
37401
|
onChange
|
|
36912
37402
|
} = {}) {
|
|
36913
|
-
const [internal, setInternal] =
|
|
37403
|
+
const [internal, setInternal] = useState78(defaultItems);
|
|
36914
37404
|
const items = controlled ?? internal;
|
|
36915
37405
|
const isControlled = controlled !== void 0;
|
|
36916
37406
|
const commit = useCallback57(
|
|
@@ -36970,7 +37460,7 @@ function useTimeline({
|
|
|
36970
37460
|
}
|
|
36971
37461
|
|
|
36972
37462
|
// src/hooks/useTraceTimeline.ts
|
|
36973
|
-
import { useCallback as useCallback58, useRef as useRef52, useState as
|
|
37463
|
+
import { useCallback as useCallback58, useRef as useRef52, useState as useState79 } from "react";
|
|
36974
37464
|
var GLOBAL_SEQ = 0;
|
|
36975
37465
|
var generateId = () => `ods-trace-${Date.now().toString(36)}-${(GLOBAL_SEQ++).toString(36)}`;
|
|
36976
37466
|
function useTraceTimeline({
|
|
@@ -36978,7 +37468,7 @@ function useTraceTimeline({
|
|
|
36978
37468
|
defaultSteps = [],
|
|
36979
37469
|
onChange
|
|
36980
37470
|
} = {}) {
|
|
36981
|
-
const [internal, setInternal] =
|
|
37471
|
+
const [internal, setInternal] = useState79(defaultSteps);
|
|
36982
37472
|
const steps = controlled ?? internal;
|
|
36983
37473
|
const isControlled = controlled !== void 0;
|
|
36984
37474
|
const stepsRef = useRef52(steps);
|
|
@@ -38141,7 +38631,7 @@ DeliveryFrequencyControl.displayName = "DeliveryFrequencyControl";
|
|
|
38141
38631
|
|
|
38142
38632
|
// src/notifications/components/EventCatalogPicker/EventCatalogPicker.tsx
|
|
38143
38633
|
import { SearchIcon as SearchIcon16 } from "@octaviaflow/icons";
|
|
38144
|
-
import { useId as useId67, useMemo as useMemo41, useState as
|
|
38634
|
+
import { useId as useId67, useMemo as useMemo41, useState as useState80 } from "react";
|
|
38145
38635
|
|
|
38146
38636
|
// src/notifications/components/meta.tsx
|
|
38147
38637
|
import {
|
|
@@ -38247,8 +38737,8 @@ function EventCatalogPicker({
|
|
|
38247
38737
|
}) {
|
|
38248
38738
|
const reactId = useId67();
|
|
38249
38739
|
const baseId = id ?? `${reactId}-events`;
|
|
38250
|
-
const [query, setQuery] =
|
|
38251
|
-
const [collapsed, setCollapsed] =
|
|
38740
|
+
const [query, setQuery] = useState80("");
|
|
38741
|
+
const [collapsed, setCollapsed] = useState80({});
|
|
38252
38742
|
const selected = useMemo41(() => new Set(value), [value]);
|
|
38253
38743
|
const filtered = useMemo41(() => {
|
|
38254
38744
|
const q2 = query.trim().toLowerCase();
|
|
@@ -38394,7 +38884,7 @@ EventCatalogPicker.displayName = "EventCatalogPicker";
|
|
|
38394
38884
|
|
|
38395
38885
|
// src/notifications/components/NotificationBell/NotificationBell.tsx
|
|
38396
38886
|
import { NotificationIcon as NotificationIcon2 } from "@octaviaflow/icons";
|
|
38397
|
-
import { useCallback as useCallback59, useState as
|
|
38887
|
+
import { useCallback as useCallback59, useState as useState82 } from "react";
|
|
38398
38888
|
|
|
38399
38889
|
// src/notifications/engine/inbox.ts
|
|
38400
38890
|
function resolveInboxAction(item, catalog) {
|
|
@@ -38549,7 +39039,7 @@ NotificationDetailDialog.displayName = "NotificationDetailDialog";
|
|
|
38549
39039
|
|
|
38550
39040
|
// src/notifications/components/NotificationInbox/NotificationInbox.tsx
|
|
38551
39041
|
import { ArchiveIcon as ArchiveIcon3, CheckmarkIcon as CheckmarkIcon16, NotificationOffIcon } from "@octaviaflow/icons";
|
|
38552
|
-
import { useMemo as useMemo42, useState as
|
|
39042
|
+
import { useMemo as useMemo42, useState as useState81 } from "react";
|
|
38553
39043
|
import { Fragment as Fragment66, jsx as jsx161, jsxs as jsxs153 } from "react/jsx-runtime";
|
|
38554
39044
|
var FILTER_OPTIONS = [
|
|
38555
39045
|
{ value: "all", label: "All" },
|
|
@@ -38576,13 +39066,13 @@ function NotificationInbox({
|
|
|
38576
39066
|
now: now2,
|
|
38577
39067
|
className
|
|
38578
39068
|
}) {
|
|
38579
|
-
const [internalFilter, setInternalFilter] =
|
|
39069
|
+
const [internalFilter, setInternalFilter] = useState81(defaultFilter2);
|
|
38580
39070
|
const activeFilter = filter ?? internalFilter;
|
|
38581
39071
|
const setFilter = (f) => {
|
|
38582
39072
|
if (filter === void 0) setInternalFilter(f);
|
|
38583
39073
|
onFilterChange?.(f);
|
|
38584
39074
|
};
|
|
38585
|
-
const [detailItem, setDetailItem] =
|
|
39075
|
+
const [detailItem, setDetailItem] = useState81(null);
|
|
38586
39076
|
const unread = countUnread(items);
|
|
38587
39077
|
const visible = useMemo42(() => {
|
|
38588
39078
|
const list = filterInbox(items, activeFilter);
|
|
@@ -38749,7 +39239,7 @@ function NotificationBell({
|
|
|
38749
39239
|
const unread = unreadCount ?? countUnread(items);
|
|
38750
39240
|
const hasUnread = unread > 0;
|
|
38751
39241
|
const countLabel = unread > 99 ? "99+" : String(unread);
|
|
38752
|
-
const [internalOpen, setInternalOpen] =
|
|
39242
|
+
const [internalOpen, setInternalOpen] = useState82(false);
|
|
38753
39243
|
const isOpen = open ?? internalOpen;
|
|
38754
39244
|
const setOpen = useCallback59(
|
|
38755
39245
|
(next) => {
|
|
@@ -38758,7 +39248,7 @@ function NotificationBell({
|
|
|
38758
39248
|
},
|
|
38759
39249
|
[open, onOpenChange]
|
|
38760
39250
|
);
|
|
38761
|
-
const [detailItem, setDetailItem] =
|
|
39251
|
+
const [detailItem, setDetailItem] = useState82(null);
|
|
38762
39252
|
const handleOpenItem = (item, action) => {
|
|
38763
39253
|
setOpen(false);
|
|
38764
39254
|
if (action.kind === "modal") setDetailItem(item);
|
|
@@ -38958,7 +39448,7 @@ NotificationChannelCard.displayName = "NotificationChannelCard";
|
|
|
38958
39448
|
|
|
38959
39449
|
// src/notifications/components/NotificationChannelDialog/NotificationChannelDialog.tsx
|
|
38960
39450
|
import { SendIcon as SendIcon2 } from "@octaviaflow/icons";
|
|
38961
|
-
import { useEffect as useEffect61, useMemo as useMemo43, useState as
|
|
39451
|
+
import { useEffect as useEffect61, useMemo as useMemo43, useState as useState84 } from "react";
|
|
38962
39452
|
|
|
38963
39453
|
// src/notifications/engine/channels.ts
|
|
38964
39454
|
var CONNECTED_CHANNEL_TYPES = [
|
|
@@ -39064,7 +39554,7 @@ function draftFromChannel(channel, fallbackType = "slack") {
|
|
|
39064
39554
|
|
|
39065
39555
|
// src/notifications/components/NotificationChannelForm/NotificationChannelForm.tsx
|
|
39066
39556
|
import { AddIcon as AddIcon6, CheckmarkFilledIcon as CheckmarkFilledIcon3, LaunchIcon as LaunchIcon2 } from "@octaviaflow/icons";
|
|
39067
|
-
import { useId as useId68, useState as
|
|
39557
|
+
import { useId as useId68, useState as useState83 } from "react";
|
|
39068
39558
|
import { jsx as jsx164, jsxs as jsxs156 } from "react/jsx-runtime";
|
|
39069
39559
|
var DEFAULT_TYPES = [
|
|
39070
39560
|
"slack",
|
|
@@ -39108,7 +39598,7 @@ function NotificationChannelForm({
|
|
|
39108
39598
|
const baseId = id ?? `${reactId}-channel`;
|
|
39109
39599
|
const typeMeta = CHANNEL_TYPE_META[value.type];
|
|
39110
39600
|
const patch = (next) => onChange({ ...value, ...next });
|
|
39111
|
-
const [touched, setTouched] =
|
|
39601
|
+
const [touched, setTouched] = useState83({});
|
|
39112
39602
|
const touch = (field) => setTouched((t) => t[field] ? t : { ...t, [field]: true });
|
|
39113
39603
|
const errorFor = (field) => errors?.[field] && (showAllErrors || touched[field]) ? errors[field] : void 0;
|
|
39114
39604
|
const errorText = (field) => {
|
|
@@ -39124,7 +39614,7 @@ function NotificationChannelForm({
|
|
|
39124
39614
|
const targetLabel = targetOptions?.find((o) => o.value === value.target)?.label;
|
|
39125
39615
|
const summary = describeChannelDraft(value, instances, targetLabel);
|
|
39126
39616
|
const suggestedLabel = suggestChannelLabel(value, instances, targetLabel);
|
|
39127
|
-
const [recipientDraft, setRecipientDraft] =
|
|
39617
|
+
const [recipientDraft, setRecipientDraft] = useState83("");
|
|
39128
39618
|
const recipients = value.recipients ?? [];
|
|
39129
39619
|
const commitRecipient = () => {
|
|
39130
39620
|
const parts = recipientDraft.split(/[,\s;]+/).map((s) => s.trim()).filter(Boolean);
|
|
@@ -39409,13 +39899,13 @@ function NotificationChannelDialog({
|
|
|
39409
39899
|
className
|
|
39410
39900
|
}) {
|
|
39411
39901
|
const editing = Boolean(channel?.id);
|
|
39412
|
-
const [draft, setDraft] =
|
|
39902
|
+
const [draft, setDraft] = useState84(
|
|
39413
39903
|
() => draftFromChannel(channel, initialType)
|
|
39414
39904
|
);
|
|
39415
|
-
const [submitted, setSubmitted] =
|
|
39416
|
-
const [testing, setTesting] =
|
|
39417
|
-
const [testResult, setTestResult] =
|
|
39418
|
-
const [submitError, setSubmitError] =
|
|
39905
|
+
const [submitted, setSubmitted] = useState84(false);
|
|
39906
|
+
const [testing, setTesting] = useState84(false);
|
|
39907
|
+
const [testResult, setTestResult] = useState84(null);
|
|
39908
|
+
const [submitError, setSubmitError] = useState84(null);
|
|
39419
39909
|
useEffect61(() => {
|
|
39420
39910
|
if (!open) return;
|
|
39421
39911
|
setDraft(draftFromChannel(channel, initialType));
|
|
@@ -39598,7 +40088,7 @@ NotificationChannelList.displayName = "NotificationChannelList";
|
|
|
39598
40088
|
|
|
39599
40089
|
// src/notifications/components/NotificationPreferenceMatrix/NotificationPreferenceMatrix.tsx
|
|
39600
40090
|
import { LockedIcon as LockedIcon2 } from "@octaviaflow/icons";
|
|
39601
|
-
import { useId as useId69, useMemo as useMemo44, useState as
|
|
40091
|
+
import { useId as useId69, useMemo as useMemo44, useState as useState85 } from "react";
|
|
39602
40092
|
|
|
39603
40093
|
// src/notifications/engine/preferences.ts
|
|
39604
40094
|
var CRITICAL_CHANNELS = ["in_app", "email"];
|
|
@@ -39692,7 +40182,7 @@ function NotificationPreferenceMatrix({
|
|
|
39692
40182
|
() => filterCatalog(catalog, personalAudiences(isAdmin)),
|
|
39693
40183
|
[catalog, isAdmin]
|
|
39694
40184
|
);
|
|
39695
|
-
const [notice, setNotice] =
|
|
40185
|
+
const [notice, setNotice] = useState85(null);
|
|
39696
40186
|
const toggle = (eventKey, channel, on) => {
|
|
39697
40187
|
const r = setPreference(value, catalog, eventKey, channel, on);
|
|
39698
40188
|
if (r.blocked) {
|