@pactor-app/ui 1.42.0 → 1.43.0

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.cjs CHANGED
@@ -157,6 +157,7 @@ __export(index_exports, {
157
157
  RadioGroup: () => RadioGroup2,
158
158
  RailTooltip: () => RailTooltip,
159
159
  Rate: () => Rate,
160
+ RecordingPage: () => RecordingPage,
160
161
  Resizable: () => Resizable,
161
162
  Result: () => Result,
162
163
  RichText: () => RichText,
@@ -556,7 +557,12 @@ var ICONS = {
556
557
  "zoom-in": import_lucide_react2.ZoomIn,
557
558
  "zoom-out": import_lucide_react2.ZoomOut,
558
559
  video: import_lucide_react2.Video,
559
- music: import_lucide_react2.Music
560
+ music: import_lucide_react2.Music,
561
+ // 录音 / 音频场景(spec: chat-page 录音模板):波形、麦克风、播放控制
562
+ "audio-lines": import_lucide_react2.AudioLines,
563
+ mic: import_lucide_react2.Mic,
564
+ play: import_lucide_react2.Play,
565
+ "rotate-cw": import_lucide_react2.RotateCw
560
566
  };
561
567
  function normalizeIconName(name) {
562
568
  return name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[_\s]+/g, "-").toLowerCase();
@@ -734,7 +740,7 @@ function AlertDialogOverlay({
734
740
  {
735
741
  "data-slot": "alert-dialog-overlay",
736
742
  className: cn(
737
- "fixed inset-0 z-50 bg-(--overlay-background) data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fill-mode-forwards data-closed:fade-out-0",
743
+ "fixed inset-0 z-50 bg-(--overlay-background) duration-200 data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fill-mode-forwards data-closed:fade-out-0",
738
744
  className
739
745
  ),
740
746
  ...props
@@ -4173,7 +4179,7 @@ function DialogOverlay({
4173
4179
  {
4174
4180
  "data-slot": "dialog-overlay",
4175
4181
  className: cn(
4176
- "fixed inset-0 z-50 bg-(--overlay-background) data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0 data-closed:fill-mode-forwards",
4182
+ "fixed inset-0 z-50 bg-(--overlay-background) duration-200 data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0 data-closed:fill-mode-forwards",
4177
4183
  className
4178
4184
  ),
4179
4185
  ...props
@@ -7092,7 +7098,7 @@ function SheetOverlay({
7092
7098
  {
7093
7099
  "data-slot": "sheet-overlay",
7094
7100
  className: cn(
7095
- "fixed inset-0 z-50 bg-(--overlay-background) data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fill-mode-forwards data-closed:fade-out-0",
7101
+ "fixed inset-0 z-50 bg-(--overlay-background) duration-200 data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fill-mode-forwards data-closed:fade-out-0",
7096
7102
  className
7097
7103
  ),
7098
7104
  ...props
@@ -14959,6 +14965,7 @@ function ChatPage({
14959
14965
  artifactOpen,
14960
14966
  defaultArtifactOpen = false,
14961
14967
  onArtifactOpenChange,
14968
+ content,
14962
14969
  className,
14963
14970
  style
14964
14971
  }) {
@@ -15212,7 +15219,7 @@ function ChatPage({
15212
15219
  "div",
15213
15220
  {
15214
15221
  "data-slot": "chat-page-menu",
15215
- className: "flex h-full w-[264px] shrink-0 flex-col gap-2 overflow-hidden border-r border-border px-2 py-3",
15222
+ className: "flex h-full w-[250px] shrink-0 flex-col gap-2 overflow-hidden border-r border-border px-2 py-3",
15216
15223
  children: [
15217
15224
  brand ? /* @__PURE__ */ (0, import_jsx_runtime191.jsxs)("div", { className: "flex shrink-0 items-center justify-between px-2", children: [
15218
15225
  /* @__PURE__ */ (0, import_jsx_runtime191.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
@@ -15295,7 +15302,7 @@ function ChatPage({
15295
15302
  ]
15296
15303
  }
15297
15304
  ),
15298
- /* @__PURE__ */ (0, import_jsx_runtime191.jsx)("div", { className: "@container h-full min-w-0 flex-1", children: open || activePanelItem ? /* @__PURE__ */ (0, import_jsx_runtime191.jsxs)(PanelGroup, { orientation: "horizontal", style: { width: "100%", height: "100%" }, children: [
15305
+ /* @__PURE__ */ (0, import_jsx_runtime191.jsx)("div", { className: "@container h-full min-w-0 flex-1", children: content !== void 0 ? renderSlot(content) : open || activePanelItem ? /* @__PURE__ */ (0, import_jsx_runtime191.jsxs)(PanelGroup, { orientation: "horizontal", style: { width: "100%", height: "100%" }, children: [
15299
15306
  /* @__PURE__ */ (0, import_jsx_runtime191.jsx)(Panel, { defaultSize: "62%", children: chatArea }),
15300
15307
  /* @__PURE__ */ (0, import_jsx_runtime191.jsx)(ResizableHandle, { withHandle: true }),
15301
15308
  /* @__PURE__ */ (0, import_jsx_runtime191.jsx)(Panel, { defaultSize: "38%", minSize: "380px", maxSize: "760px", children: activePanelItem ? /* @__PURE__ */ (0, import_jsx_runtime191.jsx)(
@@ -18471,229 +18478,1889 @@ function Login({
18471
18478
  );
18472
18479
  }
18473
18480
 
18474
- // src/components/business/RuleConfig/index.tsx
18475
- var import_lucide_react43 = require("lucide-react");
18481
+ // src/components/business/RecordingPage/index.tsx
18482
+ var import_react81 = require("react");
18483
+
18484
+ // src/components/business/RecordingPage/detail.tsx
18485
+ var import_runtime54 = require("@pactor-app/runtime");
18486
+ var import_react79 = require("react");
18487
+
18488
+ // src/components/business/RecordingPage/insight.tsx
18476
18489
  var import_react76 = require("react");
18490
+
18491
+ // src/components/business/RecordingPage/perspective-dialog.tsx
18477
18492
  var import_jsx_runtime219 = require("react/jsx-runtime");
18478
- var isBlank = (v) => v == null || String(v).trim() === "";
18479
- function isValueMissing(condition) {
18480
- const { opt, value } = condition;
18481
- if (NO_VALUE_OPT.includes(opt)) return false;
18482
- if (opt === "BETWEEN") {
18483
- const [a, b] = normalizeBetweenValue(value);
18484
- return isBlank(a) || isBlank(b);
18485
- }
18486
- if (Array.isArray(value)) return value.length === 0 || value.every(isBlank);
18487
- return isBlank(value);
18488
- }
18489
- function getConditionIssue(condition) {
18490
- const missingValue = isValueMissing(condition);
18491
- const missingScore = condition.score == null || Number.isNaN(condition.score);
18492
- if (!missingValue && !missingScore) return null;
18493
- return { missingValue, missingScore };
18494
- }
18495
- var OPERATOR_VALUES = [
18496
- "GREATER",
18497
- "GREATER_EQUAL",
18498
- "LESS_EQUAL",
18499
- "LESS",
18500
- "EQUAL",
18501
- "IN",
18502
- "NOT_IN",
18503
- "UNEQUAL",
18504
- "LIKE",
18505
- "NULL",
18506
- "HASVAL",
18507
- "NOTNULL",
18508
- "BETWEEN"
18509
- ];
18510
- var NUMERIC_OPT = [
18511
- "GREATER",
18512
- "LESS",
18513
- "LESS_EQUAL",
18514
- "GREATER_EQUAL",
18515
- "UNEQUAL"
18516
- ];
18517
- var NO_VALUE_OPT = ["NULL", "HASVAL", "NOTNULL"];
18518
- var MULTI_VALUE_OPT = ["IN", "NOT_IN"];
18519
- var OPERATOR_LABELS2 = {
18520
- GREATER: "\u5927\u4E8E",
18521
- GREATER_EQUAL: "\u5927\u4E8E\u7B49\u4E8E",
18522
- LESS_EQUAL: "\u5C0F\u4E8E\u7B49\u4E8E",
18523
- LESS: "\u5C0F\u4E8E",
18524
- EQUAL: "\u7B49\u4E8E",
18525
- IN: "\u5305\u542B",
18526
- NOT_IN: "\u4E0D\u5305\u542B",
18527
- UNEQUAL: "\u4E0D\u7B49\u4E8E",
18528
- LIKE: "\u7C7B\u4F3C",
18529
- NULL: "\u4E3A\u7A7A",
18530
- HASVAL: "\u6709\u503C",
18531
- NOTNULL: "\u4E0D\u4E3A\u7A7A",
18532
- BETWEEN: "\u8303\u56F4"
18533
- };
18534
- function operatorLabel2(operator) {
18535
- return OPERATOR_LABELS2[operator] ?? operator;
18536
- }
18537
- var _key = 0;
18538
- var nextKey = () => ++_key;
18539
- var defaultCondition = () => ({ key: nextKey(), opt: "EQUAL" });
18540
- function normalizeBetweenValue(value) {
18541
- if (Array.isArray(value)) return [value[0], value[1]];
18542
- if (typeof value === "string" && value.includes(",")) {
18543
- const [a, b] = value.split(",");
18544
- return [a?.trim(), b?.trim()];
18545
- }
18546
- if (value == null || value === "") return [void 0, void 0];
18547
- return [value, void 0];
18548
- }
18549
- function formatConditionValue2(condition) {
18550
- const { opt, value } = condition;
18551
- if (value == null) return "-";
18552
- if (opt === "BETWEEN") {
18553
- const [a, b] = normalizeBetweenValue(value);
18554
- return `${a ?? "-"} ~ ${b ?? "-"}`;
18555
- }
18556
- if (Array.isArray(value)) return value.join(", ");
18557
- return String(value);
18558
- }
18559
- function RuleConfig({ value, onChange, disabled, size = "middle" }) {
18560
- const rawConditions = value?.ruleConditions;
18561
- const conditions = (0, import_react76.useMemo)(() => {
18562
- if (!rawConditions?.length) return [defaultCondition()];
18563
- const seen = /* @__PURE__ */ new Set();
18564
- return rawConditions.map((c) => {
18565
- if (c.key != null && !seen.has(c.key)) {
18566
- seen.add(c.key);
18567
- return c;
18568
- }
18569
- const key = nextKey();
18570
- seen.add(key);
18571
- return { ...c, key };
18572
- });
18573
- }, [rawConditions]);
18574
- const initScore = value?.score ?? 1;
18575
- const [scoreText, setScoreText] = (0, import_react76.useState)(String(initScore));
18576
- const lastScoreRef = (0, import_react76.useRef)(value?.score);
18577
- (0, import_react76.useEffect)(() => {
18578
- if (value?.score === lastScoreRef.current) return;
18579
- lastScoreRef.current = value?.score;
18580
- setScoreText(value?.score == null ? "" : String(value.score));
18581
- }, [value?.score]);
18582
- const commitScore = (0, import_react76.useCallback)(
18583
- (score) => {
18584
- lastScoreRef.current = score;
18585
- onChange?.({ score, ruleConditions: conditions });
18586
- },
18587
- [onChange, conditions]
18588
- );
18589
- const normalizeScore = (n) => Math.min(1e3, Math.max(1, Math.round(n)));
18590
- const handleScoreTextChange = (text) => {
18591
- setScoreText(text);
18592
- if (text === "") return;
18593
- const n = Number(text);
18594
- if (Number.isFinite(n) && n >= 1 && n <= 1e3 && Number.isInteger(n)) {
18595
- commitScore(n);
18493
+ function RecordingPerspectiveDialog({
18494
+ open,
18495
+ title,
18496
+ hint,
18497
+ value,
18498
+ placeholder,
18499
+ cancelLabel,
18500
+ confirmLabel,
18501
+ onChange,
18502
+ onCancel,
18503
+ onConfirm
18504
+ }) {
18505
+ return /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
18506
+ Dialog,
18507
+ {
18508
+ open,
18509
+ onOpenChange: (next) => {
18510
+ if (!next) onCancel();
18511
+ },
18512
+ children: /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)(
18513
+ DialogContent,
18514
+ {
18515
+ "data-slot": "recording-perspective-dialog",
18516
+ className: "gap-4 sm:max-w-xl",
18517
+ children: [
18518
+ /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(DialogTitle, { children: title }),
18519
+ hint !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(DialogDescription, { children: hint }) : null,
18520
+ /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
18521
+ Textarea2,
18522
+ {
18523
+ value,
18524
+ placeholder,
18525
+ rows: 4,
18526
+ onChange
18527
+ }
18528
+ ),
18529
+ /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("div", { className: "flex items-center justify-end gap-2", children: [
18530
+ /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(Button2, { text: cancelLabel, onClick: onCancel }),
18531
+ /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(Button2, { text: confirmLabel, variant: "primary", onClick: onConfirm })
18532
+ ] })
18533
+ ]
18534
+ }
18535
+ )
18596
18536
  }
18597
- };
18598
- const handleScoreBlur = () => {
18599
- const n = scoreText.trim() === "" ? NaN : Number(scoreText);
18600
- const next = Number.isFinite(n) ? normalizeScore(n) : 1;
18601
- setScoreText(String(next));
18602
- if (next !== lastScoreRef.current) commitScore(next);
18603
- };
18604
- const update = (0, import_react76.useCallback)(
18605
- (next, nextScore) => onChange?.({
18606
- score: nextScore ?? initScore,
18607
- ruleConditions: next
18608
- }),
18609
- [onChange, initScore]
18610
18537
  );
18611
- const handleOptChange = (key, opt) => {
18612
- update(
18613
- conditions.map(
18614
- (c) => c.key === key ? { ...c, opt, value: opt === "BETWEEN" ? [] : void 0 } : c
18615
- )
18616
- );
18617
- };
18618
- const handleValueChange = (key, val) => {
18619
- update(conditions.map((c) => c.key === key ? { ...c, value: val } : c));
18538
+ }
18539
+
18540
+ // src/components/business/RecordingPage/insight.tsx
18541
+ var import_jsx_runtime220 = require("react/jsx-runtime");
18542
+ function RecordingInsightView({
18543
+ insight,
18544
+ onPerspectiveEdit,
18545
+ onPerspectiveApply,
18546
+ onInsightAction
18547
+ }) {
18548
+ const [dialogOpen, setDialogOpen] = (0, import_react76.useState)(false);
18549
+ const inputControlled = insight.perspectiveInput !== void 0;
18550
+ const [innerInput, setInnerInput] = (0, import_react76.useState)(insight.defaultPerspectiveInput);
18551
+ const committedInput = inputControlled ? insight.perspectiveInput : innerInput;
18552
+ const [draftInput, setDraftInput] = (0, import_react76.useState)(committedInput);
18553
+ const openDialog = () => {
18554
+ setDraftInput(committedInput);
18555
+ setDialogOpen(true);
18620
18556
  };
18621
- const handleScoreChange = (key, score) => {
18622
- update(
18623
- conditions.map((c) => c.key === key ? { ...c, score } : c)
18624
- );
18557
+ const confirmDialog = () => {
18558
+ if (!inputControlled) setInnerInput(draftInput);
18559
+ onPerspectiveApply?.(draftInput ?? "");
18560
+ setDialogOpen(false);
18625
18561
  };
18626
- const handleAdd = () => update([...conditions, defaultCondition()]);
18627
- const handleDelete = (key) => update(conditions.filter((c) => c.key !== key));
18628
- if (disabled) {
18629
- return /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("div", { className: "space-y-2 text-sm", children: [
18630
- /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("div", { className: "flex items-center gap-2 pb-2 border-b", children: [
18631
- /* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { className: "text-muted-foreground", children: "\u6743\u91CD" }),
18632
- /* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { className: "font-medium", children: initScore })
18633
- ] }),
18634
- conditions.map((condition) => /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("div", { className: "flex items-center gap-2", children: [
18635
- /* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { children: operatorLabel2(condition.opt) }),
18636
- !NO_VALUE_OPT.includes(condition.opt) && /* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { className: "font-medium", children: formatConditionValue2(condition) }),
18637
- /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("span", { className: "text-muted-foreground", children: [
18638
- "\u8BC4\u5206: ",
18639
- condition.score ?? "-"
18640
- ] })
18641
- ] }, condition.key))
18642
- ] });
18643
- }
18644
- return /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("div", { className: "space-y-2", children: [
18645
- /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("div", { className: "flex items-center gap-1 pb-2 border-b gap-2", children: [
18646
- /* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { className: "text-sm shrink-0", children: "\u6743\u91CD" }),
18647
- /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
18648
- Input,
18562
+ return /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("div", { "data-slot": "recording-insight", className: "flex flex-col gap-6", children: [
18563
+ insight.perspectiveTitle !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)(
18564
+ "section",
18565
+ {
18566
+ "data-slot": "recording-insight-perspective",
18567
+ className: "flex flex-col gap-2 rounded-lg bg-success/10 p-4",
18568
+ children: [
18569
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("div", { className: "flex items-center justify-between", children: [
18570
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("div", { className: "flex min-w-0 items-center gap-2", children: [
18571
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Icon, { name: "user", size: 16, className: "shrink-0 text-muted-foreground" }),
18572
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: insight.perspectiveTitle, strong: true, className: "truncate" })
18573
+ ] }),
18574
+ insight.perspectiveActionLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(
18575
+ Button2,
18576
+ {
18577
+ text: insight.perspectiveActionLabel,
18578
+ variant: "link",
18579
+ size: "small",
18580
+ className: "text-success",
18581
+ onClick: () => {
18582
+ onPerspectiveEdit?.();
18583
+ openDialog();
18584
+ }
18585
+ }
18586
+ ) : null
18587
+ ] }),
18588
+ insight.perspectiveHint !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: insight.perspectiveHint, size: "small", type: "secondary" }) : null
18589
+ ]
18590
+ }
18591
+ ) : null,
18592
+ insight.basics !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("section", { className: "flex flex-col gap-3", children: [
18593
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: insight.basicsTitle ?? "\u57FA\u7840\u4FE1\u606F", strong: true, size: "large" }),
18594
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: insight.basics })
18595
+ ] }) : null,
18596
+ insight.chapters !== void 0 && insight.chapters.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("section", { className: "flex flex-col gap-3", children: [
18597
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: insight.chaptersTitle ?? "\u7AE0\u8282\u901F\u89C8\u4E0E\u89E3\u8BFB", strong: true, size: "large" }),
18598
+ insight.chapters.map((chapter, index) => /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)(
18599
+ "div",
18649
18600
  {
18650
- type: "number",
18651
- className: cn("w-48", CONTROL_SIZE_BOX[size]),
18652
- min: 1,
18653
- max: 1e3,
18654
- step: 1,
18655
- value: scoreText,
18656
- disabled,
18657
- placeholder: "\u8BF7\u8F93\u5165\u6743\u91CD",
18658
- onChange: (e) => handleScoreTextChange(e.target.value),
18659
- onBlur: handleScoreBlur
18660
- }
18661
- )
18662
- ] }),
18663
- conditions.map((condition) => /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
18664
- ConditionRow2,
18601
+ "data-slot": "recording-insight-chapter",
18602
+ className: "flex flex-col gap-2 rounded-lg border border-border p-4",
18603
+ children: [
18604
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("div", { className: "flex items-baseline gap-2", children: [
18605
+ chapter.time !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: chapter.time, size: "small", type: "secondary" }) : null,
18606
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: chapter.title, strong: true, size: "small" })
18607
+ ] }),
18608
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: chapter.content, size: "small" })
18609
+ ]
18610
+ },
18611
+ chapter.time ?? index
18612
+ ))
18613
+ ] }) : null,
18614
+ insight.viewpoints !== void 0 && insight.viewpoints.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("section", { className: "flex flex-col gap-3", children: [
18615
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: insight.viewpointsTitle ?? "\u89C2\u70B9\u5206\u6790", strong: true, size: "large" }),
18616
+ insight.viewpoints.map((viewpoint, index) => /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)(
18617
+ "div",
18618
+ {
18619
+ "data-slot": "recording-insight-viewpoint",
18620
+ className: "flex flex-col gap-2 rounded-lg border border-border p-4",
18621
+ children: [
18622
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("div", { className: "flex items-center justify-between", children: [
18623
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("div", { className: "flex items-center gap-2", children: [
18624
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Avatar2, { fallback: viewpoint.avatarText ?? viewpoint.speaker.charAt(0) }),
18625
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: viewpoint.speaker, strong: true, size: "small" })
18626
+ ] }),
18627
+ viewpoint.tag !== "" ? /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: viewpoint.tag ?? "\u81EA\u52A8\u8BC6\u522B", size: "small", type: "secondary" }) : null
18628
+ ] }),
18629
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("p", { className: "text-sm", children: [
18630
+ viewpoint.label !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("strong", { children: [
18631
+ viewpoint.label,
18632
+ "\uFF1A"
18633
+ ] }) : null,
18634
+ viewpoint.content
18635
+ ] })
18636
+ ]
18637
+ },
18638
+ viewpoint.speaker ?? index
18639
+ ))
18640
+ ] }) : null,
18641
+ insight.actions !== void 0 && insight.actions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsx)("div", { "data-slot": "recording-insight-actions", className: "flex items-center gap-1", children: insight.actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(
18642
+ Button2,
18665
18643
  {
18666
- condition,
18667
- issue: getConditionIssue(condition),
18668
- showDelete: conditions.length > 1,
18669
- disabled,
18670
- size,
18671
- onOptChange: (opt) => handleOptChange(condition.key, opt),
18672
- onValueChange: (val) => handleValueChange(condition.key, val),
18673
- onScoreChange: (score) => handleScoreChange(condition.key, score),
18674
- onDelete: () => handleDelete(condition.key)
18644
+ icon: action.icon,
18645
+ variant: "text",
18646
+ size: "small",
18647
+ onClick: () => onInsightAction?.(action.key)
18675
18648
  },
18676
- condition.key
18677
- )),
18678
- !disabled && /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)(
18679
- Button,
18649
+ action.key
18650
+ )) }) : null,
18651
+ /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(
18652
+ RecordingPerspectiveDialog,
18680
18653
  {
18681
- type: "button",
18682
- variant: "link",
18683
- size: "sm",
18684
- className: "h-auto p-0 text-sm mt-1",
18685
- onClick: handleAdd,
18686
- children: [
18687
- /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(import_lucide_react43.Plus, { className: "h-3.5 w-3.5" }),
18688
- "\u6DFB\u52A0\u6761\u4EF6"
18689
- ]
18654
+ open: dialogOpen,
18655
+ title: insight.perspectiveDialogTitle ?? "\u4FEE\u6539\u89E3\u8BFB\u8EAB\u4EFD",
18656
+ hint: insight.perspectiveDialogHint ?? "\u7528\u81EA\u7136\u8BED\u8A00\u8BF4\u660E\u4F60\u5728\u672C\u6B21\u4F1A\u8BAE\u4E2D\u7684\u8EAB\u4EFD\u4E0E\u5173\u6CE8\u70B9\u3002",
18657
+ value: draftInput,
18658
+ placeholder: insight.perspectivePlaceholder,
18659
+ cancelLabel: insight.perspectiveCancelLabel ?? "\u53D6\u6D88",
18660
+ confirmLabel: insight.perspectiveConfirmLabel ?? "\u5E94\u7528\u8EAB\u4EFD",
18661
+ onChange: setDraftInput,
18662
+ onCancel: () => setDialogOpen(false),
18663
+ onConfirm: confirmDialog
18690
18664
  }
18691
18665
  )
18692
18666
  ] });
18693
18667
  }
18694
- function ConditionRow2({
18695
- condition,
18696
- issue,
18668
+
18669
+ // src/components/business/RecordingPage/memory.tsx
18670
+ var import_jsx_runtime221 = require("react/jsx-runtime");
18671
+ function RecordingMemoryView({ memory, onMemoryAction }) {
18672
+ return /* @__PURE__ */ (0, import_jsx_runtime221.jsxs)("div", { "data-slot": "recording-memory", className: "flex flex-col gap-6", children: [
18673
+ (memory.groups ?? []).map((group, groupIndex) => /* @__PURE__ */ (0, import_jsx_runtime221.jsxs)("section", { className: "flex flex-col gap-3", children: [
18674
+ /* @__PURE__ */ (0, import_jsx_runtime221.jsx)(Text, { text: `${group.label} \xB7 ${group.items.length}`, strong: true, size: "large" }),
18675
+ group.items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime221.jsxs)(
18676
+ "div",
18677
+ {
18678
+ "data-slot": "recording-memory-item",
18679
+ className: "flex flex-col gap-2 rounded-lg border border-border p-4",
18680
+ children: [
18681
+ /* @__PURE__ */ (0, import_jsx_runtime221.jsx)(Text, { text: item.title, strong: true, size: "small" }),
18682
+ /* @__PURE__ */ (0, import_jsx_runtime221.jsx)(Text, { text: item.content, size: "small" })
18683
+ ]
18684
+ },
18685
+ index
18686
+ ))
18687
+ ] }, group.key ?? group.label ?? groupIndex)),
18688
+ memory.actions !== void 0 && memory.actions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime221.jsx)("div", { "data-slot": "recording-memory-actions", className: "flex items-center gap-1", children: memory.actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime221.jsx)(
18689
+ Button2,
18690
+ {
18691
+ icon: action.icon,
18692
+ variant: "text",
18693
+ size: "small",
18694
+ onClick: () => onMemoryAction?.(action.key)
18695
+ },
18696
+ action.key
18697
+ )) }) : null
18698
+ ] });
18699
+ }
18700
+
18701
+ // src/components/business/RecordingPage/share.tsx
18702
+ var import_react77 = require("react");
18703
+ var import_jsx_runtime222 = require("react/jsx-runtime");
18704
+ function copyText(text) {
18705
+ try {
18706
+ if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) {
18707
+ void navigator.clipboard.writeText(text);
18708
+ return;
18709
+ }
18710
+ const textarea = document.createElement("textarea");
18711
+ textarea.value = text;
18712
+ document.body.appendChild(textarea);
18713
+ textarea.select();
18714
+ document.execCommand?.("copy");
18715
+ textarea.remove();
18716
+ } catch {
18717
+ }
18718
+ }
18719
+ function RecordingShare({
18720
+ shareLabel,
18721
+ options,
18722
+ selectedKeys,
18723
+ popoverTitle,
18724
+ cancelLabel,
18725
+ confirmLabel,
18726
+ dialogTitle,
18727
+ link,
18728
+ copyLinkLabel,
18729
+ copiedLabel,
18730
+ mailLabel,
18731
+ systemLabel,
18732
+ onShare,
18733
+ onSelectionCommit,
18734
+ onShareConfirm,
18735
+ onShareChannel
18736
+ }) {
18737
+ const [popoverOpen, setPopoverOpen] = (0, import_react77.useState)(false);
18738
+ const [dialogOpen, setDialogOpen] = (0, import_react77.useState)(false);
18739
+ const [draftKeys, setDraftKeys] = (0, import_react77.useState)(selectedKeys);
18740
+ const [copied, setCopied] = (0, import_react77.useState)(false);
18741
+ const copyLink = () => {
18742
+ if (link !== void 0) {
18743
+ copyText(link);
18744
+ setCopied(true);
18745
+ setTimeout(() => setCopied(false), 1500);
18746
+ }
18747
+ onShareChannel?.("copyLink");
18748
+ };
18749
+ const openPopover = (next) => {
18750
+ if (next) {
18751
+ setDraftKeys(selectedKeys);
18752
+ onShare?.();
18753
+ }
18754
+ setPopoverOpen(next);
18755
+ };
18756
+ const toggleOption = (option) => {
18757
+ if (option.disabled === true) return;
18758
+ setDraftKeys(
18759
+ (prev) => prev.includes(option.key) ? prev.filter((key) => key !== option.key) : [...prev, option.key]
18760
+ );
18761
+ };
18762
+ const confirm = () => {
18763
+ const next = options.filter((option) => draftKeys.includes(option.key)).map((option) => option.key);
18764
+ onSelectionCommit(next);
18765
+ onShareConfirm?.(next);
18766
+ setPopoverOpen(false);
18767
+ setDialogOpen(true);
18768
+ };
18769
+ const trigger = /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(Button2, { text: shareLabel, size: "small" });
18770
+ return /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)(import_jsx_runtime222.Fragment, { children: [
18771
+ /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)(Popover, { open: popoverOpen, onOpenChange: openPopover, children: [
18772
+ /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(
18773
+ PopoverTrigger,
18774
+ {
18775
+ nativeButton: false,
18776
+ render: /* @__PURE__ */ (0, import_jsx_runtime222.jsx)("span", { "data-slot": "recording-share-trigger", className: "inline-flex" }),
18777
+ children: trigger
18778
+ }
18779
+ ),
18780
+ /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)(
18781
+ PopoverContent,
18782
+ {
18783
+ align: "end",
18784
+ sideOffset: 8,
18785
+ className: "w-64 p-0",
18786
+ "data-slot": "recording-share-popover",
18787
+ children: [
18788
+ /* @__PURE__ */ (0, import_jsx_runtime222.jsx)("div", { className: "px-4 pt-4 pb-2 text-sm font-semibold", children: popoverTitle }),
18789
+ /* @__PURE__ */ (0, import_jsx_runtime222.jsx)("div", { className: "flex flex-col px-2 pb-2", children: options.map((option) => {
18790
+ const checked = draftKeys.includes(option.key);
18791
+ const disabled = option.disabled === true;
18792
+ return /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)(
18793
+ "button",
18794
+ {
18795
+ type: "button",
18796
+ "data-slot": "recording-share-option",
18797
+ "aria-pressed": checked,
18798
+ disabled,
18799
+ className: cn(
18800
+ "flex w-full items-center gap-2.5 rounded-md px-2 py-2 text-left text-sm",
18801
+ disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer hover:bg-muted"
18802
+ ),
18803
+ onClick: () => toggleOption(option),
18804
+ children: [
18805
+ /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(
18806
+ "span",
18807
+ {
18808
+ className: cn(
18809
+ "flex h-5 w-5 shrink-0 items-center justify-center rounded-full",
18810
+ checked ? "bg-primary text-primary-foreground" : "border border-input"
18811
+ ),
18812
+ children: checked ? /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(Icon, { name: "check", size: 12 }) : null
18813
+ }
18814
+ ),
18815
+ option.label
18816
+ ]
18817
+ },
18818
+ option.key
18819
+ );
18820
+ }) }),
18821
+ /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)("div", { className: "flex items-center justify-end gap-2 border-t border-border px-4 py-3", children: [
18822
+ /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(Button2, { text: cancelLabel, variant: "text", onClick: () => setPopoverOpen(false) }),
18823
+ /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(Button2, { text: confirmLabel, variant: "primary", onClick: confirm })
18824
+ ] })
18825
+ ]
18826
+ }
18827
+ )
18828
+ ] }),
18829
+ /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(Dialog, { open: dialogOpen, onOpenChange: setDialogOpen, children: /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)(DialogContent, { "data-slot": "recording-share-dialog", className: "gap-4 sm:max-w-xl", children: [
18830
+ /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(DialogTitle, { children: dialogTitle }),
18831
+ link !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)("div", { className: "flex items-center justify-between gap-3 rounded-lg border border-border px-4 py-3", children: [
18832
+ /* @__PURE__ */ (0, import_jsx_runtime222.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm", children: link }),
18833
+ /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(
18834
+ Button2,
18835
+ {
18836
+ text: copied ? copiedLabel : copyLinkLabel,
18837
+ variant: "link",
18838
+ size: "small",
18839
+ onClick: copyLink
18840
+ }
18841
+ )
18842
+ ] }) : null,
18843
+ /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)("div", { className: "grid grid-cols-2 gap-3", children: [
18844
+ /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(
18845
+ Button2,
18846
+ {
18847
+ text: mailLabel,
18848
+ icon: "mail",
18849
+ className: "h-12",
18850
+ onClick: () => onShareChannel?.("mail")
18851
+ }
18852
+ ),
18853
+ /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(
18854
+ Button2,
18855
+ {
18856
+ text: systemLabel,
18857
+ icon: "share",
18858
+ className: "h-12",
18859
+ onClick: () => onShareChannel?.("system")
18860
+ }
18861
+ )
18862
+ ] })
18863
+ ] }) })
18864
+ ] });
18865
+ }
18866
+
18867
+ // src/components/business/RecordingPage/speaker-dialog.tsx
18868
+ var import_jsx_runtime223 = require("react/jsx-runtime");
18869
+ function RecordingSpeakerDialog({
18870
+ open,
18871
+ title,
18872
+ hint,
18873
+ speakers,
18874
+ selectedIndex,
18875
+ customName,
18876
+ inputPlaceholder,
18877
+ applyLabel,
18878
+ onSelect,
18879
+ onInputName,
18880
+ onCancel,
18881
+ onConfirm
18882
+ }) {
18883
+ const canApply = customName.trim() !== "" || selectedIndex >= 0;
18884
+ return /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
18885
+ Dialog,
18886
+ {
18887
+ open,
18888
+ onOpenChange: (next) => {
18889
+ if (!next) onCancel();
18890
+ },
18891
+ children: /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)(
18892
+ DialogContent,
18893
+ {
18894
+ "data-slot": "recording-speaker-dialog",
18895
+ className: "gap-4 sm:max-w-xl",
18896
+ children: [
18897
+ /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(DialogTitle, { children: title }),
18898
+ hint !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(DialogDescription, { children: hint }) : null,
18899
+ speakers.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("div", { className: "flex flex-col divide-y divide-border", children: speakers.map((speaker, index) => {
18900
+ const selected = index === selectedIndex;
18901
+ return /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)(
18902
+ "button",
18903
+ {
18904
+ type: "button",
18905
+ "data-slot": "recording-speaker-option",
18906
+ "aria-pressed": selected,
18907
+ className: cn(
18908
+ "flex w-full cursor-pointer items-center gap-3 px-3 py-3 text-left",
18909
+ selected ? "bg-primary/10" : "hover:bg-muted"
18910
+ ),
18911
+ onClick: () => onSelect(index),
18912
+ children: [
18913
+ /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(Avatar2, { fallback: speaker.avatarText ?? speaker.name.charAt(0) }),
18914
+ /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)("span", { className: "flex min-w-0 flex-1 items-baseline gap-2", children: [
18915
+ /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("span", { className: "text-sm font-medium", children: speaker.name }),
18916
+ speaker.role !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("span", { className: "truncate text-sm text-muted-foreground", children: speaker.role }) : null
18917
+ ] }),
18918
+ speaker.tag !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("span", { className: "shrink-0 text-sm text-muted-foreground", children: speaker.tag }) : null
18919
+ ]
18920
+ },
18921
+ `${speaker.name}-${index}`
18922
+ );
18923
+ }) }) : null,
18924
+ /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
18925
+ Input2,
18926
+ {
18927
+ value: customName,
18928
+ placeholder: inputPlaceholder,
18929
+ onChange: onInputName
18930
+ }
18931
+ ),
18932
+ /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("div", { className: "flex items-center justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
18933
+ Button2,
18934
+ {
18935
+ text: applyLabel,
18936
+ variant: "primary",
18937
+ disabled: !canApply,
18938
+ onClick: onConfirm
18939
+ }
18940
+ ) })
18941
+ ]
18942
+ }
18943
+ )
18944
+ }
18945
+ );
18946
+ }
18947
+
18948
+ // src/components/business/RecordingPage/summary.tsx
18949
+ var import_jsx_runtime224 = require("react/jsx-runtime");
18950
+ function MindmapPill({ label, center }) {
18951
+ return /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
18952
+ "span",
18953
+ {
18954
+ className: cn(
18955
+ "rounded-lg px-4 py-1.5 text-sm",
18956
+ center ? "bg-primary px-5 py-2.5 font-medium text-primary-foreground" : "border border-border bg-background"
18957
+ ),
18958
+ children: label
18959
+ }
18960
+ );
18961
+ }
18962
+ var mindmapLine = /* @__PURE__ */ (0, import_jsx_runtime224.jsx)("div", { className: "h-px w-10 shrink-0", style: { background: "var(--border)" } });
18963
+ function RecordingSummaryView({
18964
+ summary,
18965
+ onMindmapAction,
18966
+ onMaterialClick,
18967
+ selectedTodoIds,
18968
+ onTodoToggle,
18969
+ onSummaryAction
18970
+ }) {
18971
+ return /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("div", { "data-slot": "recording-summary", className: "flex flex-col gap-6", children: [
18972
+ summary.mindmap ? /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("section", { className: "rounded-lg border border-border", children: [
18973
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("div", { className: "flex items-center justify-between px-4 py-3", children: [
18974
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(Text, { text: summary.mindmapTitle ?? "\u601D\u7EF4\u5BFC\u56FE", strong: true }),
18975
+ summary.mindmapActionLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
18976
+ Button2,
18977
+ {
18978
+ text: summary.mindmapActionLabel,
18979
+ variant: "link",
18980
+ size: "small",
18981
+ className: "text-success",
18982
+ onClick: () => onMindmapAction?.()
18983
+ }
18984
+ ) : null
18985
+ ] }),
18986
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("div", { className: "mx-4 mb-4 flex items-center justify-center rounded-lg bg-muted p-8", children: [
18987
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)("div", { className: "flex flex-col items-start gap-2", children: (summary.mindmap.left ?? []).map((node) => /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(MindmapPill, { label: node }, node)) }),
18988
+ mindmapLine,
18989
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(MindmapPill, { label: summary.mindmap.center, center: true }),
18990
+ mindmapLine,
18991
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)("div", { className: "flex flex-col items-start gap-2", children: (summary.mindmap.right ?? []).map((node) => /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(MindmapPill, { label: node }, node)) })
18992
+ ] })
18993
+ ] }) : null,
18994
+ summary.overview !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("section", { className: "flex flex-col gap-3", children: [
18995
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
18996
+ Text,
18997
+ {
18998
+ text: summary.overviewTitle ?? "\u4F1A\u8BAE\u6982\u51B5",
18999
+ strong: true,
19000
+ size: "large"
19001
+ }
19002
+ ),
19003
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)("div", { className: "rounded-lg bg-muted p-4", children: /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(Text, { text: summary.overview }) })
19004
+ ] }) : null,
19005
+ summary.topics !== void 0 && summary.topics.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("section", { className: "flex flex-col gap-3", children: [
19006
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(Text, { text: summary.topicsTitle ?? "\u4E3B\u8981\u8BAE\u9898", strong: true, size: "large" }),
19007
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
19008
+ "div",
19009
+ {
19010
+ className: "grid gap-3",
19011
+ style: { gridTemplateColumns: "1fr 1fr" },
19012
+ children: summary.topics.map((topic, index) => /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)(
19013
+ "div",
19014
+ {
19015
+ className: "flex flex-col gap-2 rounded-lg border border-border p-4",
19016
+ children: [
19017
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(Text, { text: topic.title, strong: true, size: "small" }),
19018
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(Text, { text: topic.content, size: "small" })
19019
+ ]
19020
+ },
19021
+ index
19022
+ ))
19023
+ }
19024
+ )
19025
+ ] }) : null,
19026
+ summary.conclusions !== void 0 && summary.conclusions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("section", { className: "rounded-lg border border-border p-4", children: [
19027
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
19028
+ Text,
19029
+ {
19030
+ text: summary.conclusionsTitle ?? "\u8BC4\u5BA1\u7ED3\u8BBA\u4E0E\u540E\u7EED\u5B89\u6392",
19031
+ strong: true,
19032
+ size: "small"
19033
+ }
19034
+ ),
19035
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
19036
+ Table3,
19037
+ {
19038
+ className: "mt-3",
19039
+ columns: [
19040
+ { title: "\u4E8B\u9879", dataIndex: "item" },
19041
+ { title: "\u4F1A\u8BAE\u7ED3\u8BBA", dataIndex: "conclusion" },
19042
+ { title: "\u8D1F\u8D23\u4EBA", dataIndex: "owner" }
19043
+ ],
19044
+ dataSource: summary.conclusions.map((row, index) => ({
19045
+ id: index,
19046
+ ...row
19047
+ }))
19048
+ }
19049
+ )
19050
+ ] }) : null,
19051
+ summary.followUp !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("section", { className: "flex flex-col gap-2 rounded-lg border border-border p-4", children: [
19052
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(Text, { text: summary.followUpTitle, strong: true, size: "small" }),
19053
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(Text, { text: summary.followUp, size: "small" })
19054
+ ] }) : null,
19055
+ summary.materials !== void 0 && summary.materials.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("section", { className: "flex flex-col gap-3", children: [
19056
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
19057
+ Text,
19058
+ {
19059
+ text: summary.materialsTitle ?? "\u76F8\u5173\u6750\u6599",
19060
+ strong: true,
19061
+ size: "large"
19062
+ }
19063
+ ),
19064
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)("div", { className: "flex flex-col divide-y divide-border rounded-lg border border-border", children: summary.materials.map((material, index) => /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)(
19065
+ "button",
19066
+ {
19067
+ type: "button",
19068
+ "data-slot": "recording-material",
19069
+ className: "flex cursor-pointer items-center gap-2 px-4 py-3 text-left",
19070
+ onClick: () => onMaterialClick?.(material.id ?? index),
19071
+ children: [
19072
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
19073
+ Icon,
19074
+ {
19075
+ name: material.icon ?? "file-text",
19076
+ size: 16,
19077
+ className: "text-muted-foreground"
19078
+ }
19079
+ ),
19080
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
19081
+ Text,
19082
+ {
19083
+ text: material.title,
19084
+ size: "small",
19085
+ className: "min-w-0 flex-1 truncate"
19086
+ }
19087
+ ),
19088
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
19089
+ Text,
19090
+ {
19091
+ text: material.meta,
19092
+ size: "small",
19093
+ type: "secondary",
19094
+ className: "shrink-0"
19095
+ }
19096
+ ),
19097
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
19098
+ Icon,
19099
+ {
19100
+ name: "chevron-right",
19101
+ size: 14,
19102
+ className: "text-muted-foreground"
19103
+ }
19104
+ )
19105
+ ]
19106
+ },
19107
+ material.id ?? index
19108
+ )) })
19109
+ ] }) : null,
19110
+ summary.todos !== void 0 && summary.todos.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("section", { className: "flex flex-col gap-3", children: [
19111
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(Text, { text: summary.todosTitle ?? "\u5F85\u529E\u4E8B\u9879", strong: true, size: "large" }),
19112
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)("div", { className: "flex flex-col divide-y divide-border rounded-lg border border-border", children: summary.todos.map((todo, index) => {
19113
+ const todoId = todo.id ?? index;
19114
+ const checked = selectedTodoIds !== void 0 ? selectedTodoIds.includes(todoId) : todo.done === true;
19115
+ return /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)(
19116
+ "button",
19117
+ {
19118
+ type: "button",
19119
+ "data-slot": "recording-todo",
19120
+ "aria-pressed": checked,
19121
+ className: "flex cursor-pointer items-center gap-2 px-4 py-3 text-left",
19122
+ onClick: () => onTodoToggle?.(todoId),
19123
+ children: [
19124
+ checked ? /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
19125
+ Icon,
19126
+ {
19127
+ name: "check-circle",
19128
+ size: 16,
19129
+ className: "shrink-0 text-success"
19130
+ }
19131
+ ) : /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
19132
+ "span",
19133
+ {
19134
+ className: "shrink-0 rounded-full border border-border",
19135
+ style: { width: 16, height: 16 }
19136
+ }
19137
+ ),
19138
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
19139
+ Text,
19140
+ {
19141
+ text: todo.title,
19142
+ size: "small",
19143
+ className: "min-w-0 flex-1 truncate"
19144
+ }
19145
+ ),
19146
+ /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
19147
+ Text,
19148
+ {
19149
+ text: todo.owner,
19150
+ size: "small",
19151
+ type: "secondary",
19152
+ className: "shrink-0"
19153
+ }
19154
+ )
19155
+ ]
19156
+ },
19157
+ todoId
19158
+ );
19159
+ }) })
19160
+ ] }) : null,
19161
+ summary.actions !== void 0 && summary.actions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
19162
+ "div",
19163
+ {
19164
+ "data-slot": "recording-summary-actions",
19165
+ className: "flex items-center gap-1",
19166
+ children: summary.actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
19167
+ Button2,
19168
+ {
19169
+ icon: action.icon,
19170
+ variant: "text",
19171
+ size: "small",
19172
+ onClick: () => onSummaryAction?.(action.key)
19173
+ },
19174
+ action.key
19175
+ ))
19176
+ }
19177
+ ) : null
19178
+ ] });
19179
+ }
19180
+
19181
+ // src/components/business/RecordingPage/translation.tsx
19182
+ var import_react78 = require("react");
19183
+
19184
+ // src/components/business/RecordingPage/language-dialog.tsx
19185
+ var import_jsx_runtime225 = require("react/jsx-runtime");
19186
+ function LanguageOptionItem({
19187
+ option,
19188
+ selected,
19189
+ onSelect
19190
+ }) {
19191
+ return /* @__PURE__ */ (0, import_jsx_runtime225.jsxs)(
19192
+ "button",
19193
+ {
19194
+ type: "button",
19195
+ "data-slot": "recording-language-option",
19196
+ "aria-pressed": selected,
19197
+ className: cn(
19198
+ "flex w-full cursor-pointer items-center gap-2.5 px-3 py-2.5 text-left text-sm",
19199
+ selected ? "bg-primary/10" : "hover:bg-muted"
19200
+ ),
19201
+ onClick: () => onSelect(option.key),
19202
+ children: [
19203
+ /* @__PURE__ */ (0, import_jsx_runtime225.jsx)(
19204
+ "span",
19205
+ {
19206
+ className: cn(
19207
+ "flex h-4 w-4 shrink-0 items-center justify-center rounded-full border",
19208
+ selected ? "border-primary" : "border-input"
19209
+ ),
19210
+ children: selected ? /* @__PURE__ */ (0, import_jsx_runtime225.jsx)("span", { className: "h-2 w-2 rounded-full bg-primary" }) : null
19211
+ }
19212
+ ),
19213
+ /* @__PURE__ */ (0, import_jsx_runtime225.jsx)("span", { className: cn(selected && "font-medium"), children: option.label })
19214
+ ]
19215
+ }
19216
+ );
19217
+ }
19218
+ function RecordingLanguageDialog({
19219
+ open,
19220
+ title,
19221
+ sourceTitle,
19222
+ targetTitle,
19223
+ sourceLanguages,
19224
+ targetLanguages,
19225
+ source,
19226
+ target,
19227
+ cancelLabel,
19228
+ confirmLabel,
19229
+ onSelectSource,
19230
+ onSelectTarget,
19231
+ onCancel,
19232
+ onConfirm
19233
+ }) {
19234
+ const renderColumn = (columnTitle, options, value, onSelect) => /* @__PURE__ */ (0, import_jsx_runtime225.jsxs)("div", { className: "flex min-w-0 flex-col gap-2", children: [
19235
+ /* @__PURE__ */ (0, import_jsx_runtime225.jsx)("span", { className: "text-sm font-medium", children: columnTitle }),
19236
+ /* @__PURE__ */ (0, import_jsx_runtime225.jsx)("div", { className: "flex flex-col divide-y divide-border", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime225.jsx)(
19237
+ LanguageOptionItem,
19238
+ {
19239
+ option,
19240
+ selected: option.key === value,
19241
+ onSelect
19242
+ },
19243
+ option.key
19244
+ )) })
19245
+ ] });
19246
+ return /* @__PURE__ */ (0, import_jsx_runtime225.jsx)(
19247
+ Dialog,
19248
+ {
19249
+ open,
19250
+ onOpenChange: (next) => {
19251
+ if (!next) onCancel();
19252
+ },
19253
+ children: /* @__PURE__ */ (0, import_jsx_runtime225.jsxs)(
19254
+ DialogContent,
19255
+ {
19256
+ "data-slot": "recording-language-dialog",
19257
+ className: "gap-6 sm:max-w-xl",
19258
+ children: [
19259
+ /* @__PURE__ */ (0, import_jsx_runtime225.jsx)(DialogTitle, { children: title }),
19260
+ /* @__PURE__ */ (0, import_jsx_runtime225.jsxs)("div", { className: "grid grid-cols-2 gap-6", children: [
19261
+ renderColumn(sourceTitle, sourceLanguages, source, onSelectSource),
19262
+ renderColumn(targetTitle, targetLanguages, target, onSelectTarget)
19263
+ ] }),
19264
+ /* @__PURE__ */ (0, import_jsx_runtime225.jsxs)("div", { className: "flex items-center justify-end gap-2", children: [
19265
+ /* @__PURE__ */ (0, import_jsx_runtime225.jsx)(Button2, { text: cancelLabel, onClick: onCancel }),
19266
+ /* @__PURE__ */ (0, import_jsx_runtime225.jsx)(Button2, { text: confirmLabel, variant: "primary", onClick: onConfirm })
19267
+ ] })
19268
+ ]
19269
+ }
19270
+ )
19271
+ }
19272
+ );
19273
+ }
19274
+
19275
+ // src/components/business/RecordingPage/translation.tsx
19276
+ var import_jsx_runtime226 = require("react/jsx-runtime");
19277
+ function RecordingTranslationView({
19278
+ translation,
19279
+ onLanguageClick,
19280
+ onLanguageChange,
19281
+ onTranslationAction
19282
+ }) {
19283
+ const sourceLanguages = translation.sourceLanguages ?? [];
19284
+ const targetLanguages = translation.targetLanguages ?? [];
19285
+ const dialogEnabled = sourceLanguages.length > 0 || targetLanguages.length > 0;
19286
+ const [dialogOpen, setDialogOpen] = (0, import_react78.useState)(false);
19287
+ const sourceControlled = translation.sourceLanguage !== void 0;
19288
+ const targetControlled = translation.targetLanguage !== void 0;
19289
+ const [innerSource, setInnerSource] = (0, import_react78.useState)(
19290
+ translation.defaultSourceLanguage ?? sourceLanguages[0]?.key
19291
+ );
19292
+ const [innerTarget, setInnerTarget] = (0, import_react78.useState)(
19293
+ translation.defaultTargetLanguage ?? targetLanguages[0]?.key
19294
+ );
19295
+ const committedSource = sourceControlled ? translation.sourceLanguage : innerSource;
19296
+ const committedTarget = targetControlled ? translation.targetLanguage : innerTarget;
19297
+ const [draftSource, setDraftSource] = (0, import_react78.useState)(committedSource);
19298
+ const [draftTarget, setDraftTarget] = (0, import_react78.useState)(committedTarget);
19299
+ const openDialog = () => {
19300
+ setDraftSource(committedSource);
19301
+ setDraftTarget(committedTarget);
19302
+ setDialogOpen(true);
19303
+ };
19304
+ const confirmDialog = () => {
19305
+ if (!sourceControlled) setInnerSource(draftSource);
19306
+ if (!targetControlled) setInnerTarget(draftTarget);
19307
+ onLanguageChange?.({
19308
+ source: draftSource,
19309
+ sourceLabel: sourceLanguages.find((item) => item.key === draftSource)?.label,
19310
+ target: draftTarget,
19311
+ targetLabel: targetLanguages.find((item) => item.key === draftTarget)?.label
19312
+ });
19313
+ setDialogOpen(false);
19314
+ };
19315
+ return /* @__PURE__ */ (0, import_jsx_runtime226.jsxs)("div", { "data-slot": "recording-translation", className: "flex flex-col gap-4", children: [
19316
+ translation.languageLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime226.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime226.jsxs)(
19317
+ "button",
19318
+ {
19319
+ type: "button",
19320
+ "data-slot": "recording-translation-language",
19321
+ className: "inline-flex cursor-pointer items-center gap-1.5 rounded-full bg-primary/10 px-3 py-1.5 text-sm",
19322
+ onClick: () => {
19323
+ onLanguageClick?.();
19324
+ if (dialogEnabled) openDialog();
19325
+ },
19326
+ children: [
19327
+ /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(Icon, { name: "globe", size: 14 }),
19328
+ translation.languageLabel,
19329
+ /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(Icon, { name: "chevron-down", size: 14, className: "text-muted-foreground" })
19330
+ ]
19331
+ }
19332
+ ) }) : null,
19333
+ /* @__PURE__ */ (0, import_jsx_runtime226.jsx)("div", { className: "flex flex-col divide-y divide-border", children: (translation.segments ?? []).map((segment, index) => /* @__PURE__ */ (0, import_jsx_runtime226.jsxs)(
19334
+ "div",
19335
+ {
19336
+ "data-slot": "recording-translation-segment",
19337
+ className: "grid gap-4 py-4",
19338
+ style: { gridTemplateColumns: "1fr 1fr" },
19339
+ children: [
19340
+ /* @__PURE__ */ (0, import_jsx_runtime226.jsxs)("div", { className: "flex min-w-0 flex-col gap-3", children: [
19341
+ /* @__PURE__ */ (0, import_jsx_runtime226.jsxs)("div", { className: "flex items-center gap-2", children: [
19342
+ /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(Avatar2, { fallback: segment.avatarText ?? segment.speaker?.charAt(0) ?? "?" }),
19343
+ /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(Text, { text: segment.speaker, strong: true, size: "small" })
19344
+ ] }),
19345
+ /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(Text, { text: segment.source })
19346
+ ] }),
19347
+ /* @__PURE__ */ (0, import_jsx_runtime226.jsxs)("div", { className: "flex min-w-0 flex-col gap-3", children: [
19348
+ /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(Text, { text: translation.targetLabel ?? "\u8BD1\u6587", strong: true, size: "small" }),
19349
+ /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(Text, { text: segment.target })
19350
+ ] })
19351
+ ]
19352
+ },
19353
+ index
19354
+ )) }),
19355
+ translation.actions !== void 0 && translation.actions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime226.jsx)("div", { "data-slot": "recording-translation-actions", className: "flex items-center gap-1", children: translation.actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(
19356
+ Button2,
19357
+ {
19358
+ icon: action.icon,
19359
+ variant: "text",
19360
+ size: "small",
19361
+ onClick: () => onTranslationAction?.(action.key)
19362
+ },
19363
+ action.key
19364
+ )) }) : null,
19365
+ dialogEnabled ? /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(
19366
+ RecordingLanguageDialog,
19367
+ {
19368
+ open: dialogOpen,
19369
+ title: translation.languageDialogTitle ?? "\u9009\u62E9\u7FFB\u8BD1\u8BED\u8A00",
19370
+ sourceTitle: translation.sourceLanguagesTitle ?? "\u539F\u6587\u8BED\u8A00\u8BC6\u522B",
19371
+ targetTitle: translation.targetLanguagesTitle ?? "\u8BD1\u6587\u8BED\u8A00\u9009\u62E9",
19372
+ sourceLanguages,
19373
+ targetLanguages,
19374
+ source: draftSource,
19375
+ target: draftTarget,
19376
+ cancelLabel: translation.cancelLabel ?? "\u53D6\u6D88",
19377
+ confirmLabel: translation.confirmLabel ?? "\u786E\u5B9A",
19378
+ onSelectSource: setDraftSource,
19379
+ onSelectTarget: setDraftTarget,
19380
+ onCancel: () => setDialogOpen(false),
19381
+ onConfirm: confirmDialog
19382
+ }
19383
+ ) : null
19384
+ ] });
19385
+ }
19386
+
19387
+ // src/components/business/RecordingPage/detail.tsx
19388
+ var import_jsx_runtime227 = require("react/jsx-runtime");
19389
+ function TranscriptSegment({
19390
+ segment,
19391
+ speaker,
19392
+ onRename
19393
+ }) {
19394
+ return /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { "data-slot": "recording-segment", className: "flex flex-col gap-2", children: [
19395
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { className: "flex items-center justify-between", children: [
19396
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { className: "flex items-center gap-2", children: [
19397
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Avatar2, { fallback: segment.avatarText ?? speaker?.charAt(0) ?? "?" }),
19398
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Text, { text: speaker, strong: true, size: "small" }),
19399
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
19400
+ "button",
19401
+ {
19402
+ type: "button",
19403
+ "data-slot": "recording-speaker-edit",
19404
+ "aria-label": "\u4FEE\u6539\u53D1\u8A00\u4EBA",
19405
+ className: "cursor-pointer text-muted-foreground",
19406
+ onClick: () => onRename?.(),
19407
+ children: /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Icon, { name: "pencil", size: 14 })
19408
+ }
19409
+ )
19410
+ ] }),
19411
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { className: "flex items-center gap-2", children: [
19412
+ segment.marked ? /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Badge2, { text: "\u2691 \u5DF2\u6807\u8BB0", variant: "outline" }) : null,
19413
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Text, { text: segment.time, size: "small", type: "secondary" })
19414
+ ] })
19415
+ ] }),
19416
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Text, { text: segment.content })
19417
+ ] });
19418
+ }
19419
+ function RecordingDetail({
19420
+ title,
19421
+ meta,
19422
+ editLabel,
19423
+ shareLabel,
19424
+ shareOptions = [],
19425
+ shareSelectedKeys = [],
19426
+ sharePopoverTitle,
19427
+ shareCancelLabel,
19428
+ shareConfirmLabel,
19429
+ shareDialogTitle,
19430
+ shareLink,
19431
+ shareCopyLinkLabel,
19432
+ shareCopiedLabel,
19433
+ shareMailLabel,
19434
+ shareSystemLabel,
19435
+ onShareSelectionCommit,
19436
+ onShareConfirm,
19437
+ onShareChannel,
19438
+ onEdit,
19439
+ onShare,
19440
+ tabs,
19441
+ activeTab,
19442
+ onTabChange,
19443
+ transcriptTabKey,
19444
+ segments,
19445
+ speakers = [],
19446
+ speakerDialogTitle,
19447
+ speakerDialogHint,
19448
+ speakerInputPlaceholder,
19449
+ speakerApplyLabel,
19450
+ onSpeakerChange,
19451
+ summary,
19452
+ summaryTabKey,
19453
+ onMindmapAction,
19454
+ onMaterialClick,
19455
+ selectedTodoIds,
19456
+ onTodoToggle,
19457
+ onSummaryAction,
19458
+ insight,
19459
+ insightTabKey,
19460
+ onPerspectiveEdit,
19461
+ onPerspectiveApply,
19462
+ onInsightAction,
19463
+ memory,
19464
+ memoryTabKey,
19465
+ onMemoryAction,
19466
+ translation,
19467
+ translationTabKey,
19468
+ onLanguageClick,
19469
+ onLanguageChange,
19470
+ onTranslationAction,
19471
+ player,
19472
+ onPlay,
19473
+ onSkipBack,
19474
+ onSkipForward
19475
+ }) {
19476
+ const { renderChildren } = (0, import_runtime54.useRenderer)();
19477
+ const renderSlot = (slot) => (0, import_react79.isValidElement)(slot) || typeof slot !== "object" || slot === null ? slot : renderChildren([slot]);
19478
+ const activeTabItem = tabs.find((tab) => tab.key === activeTab);
19479
+ const [renameIndex, setRenameIndex] = (0, import_react79.useState)(null);
19480
+ const [draftSpeakerIndex, setDraftSpeakerIndex] = (0, import_react79.useState)(-1);
19481
+ const [draftSpeakerName, setDraftSpeakerName] = (0, import_react79.useState)("");
19482
+ const [speakerOverrides, setSpeakerOverrides] = (0, import_react79.useState)({});
19483
+ const speakerSignature = (0, import_react79.useRef)("");
19484
+ (0, import_react79.useEffect)(() => {
19485
+ const signature = JSON.stringify(segments.map((segment) => segment.speaker ?? ""));
19486
+ if (speakerSignature.current !== signature) {
19487
+ speakerSignature.current = signature;
19488
+ setSpeakerOverrides((prev) => Object.keys(prev).length > 0 ? {} : prev);
19489
+ }
19490
+ }, [segments]);
19491
+ const displaySpeaker = (index) => speakerOverrides[index] ?? segments[index]?.speaker;
19492
+ const openRename = (index) => {
19493
+ const current = displaySpeaker(index);
19494
+ setDraftSpeakerIndex(speakers.findIndex((item) => item.name === current));
19495
+ setDraftSpeakerName("");
19496
+ setRenameIndex(index);
19497
+ };
19498
+ const confirmRename = () => {
19499
+ if (renameIndex === null) return;
19500
+ const name = draftSpeakerName.trim() !== "" ? draftSpeakerName.trim() : speakers[draftSpeakerIndex]?.name;
19501
+ if (name === void 0 || name === "") return;
19502
+ const previous = displaySpeaker(renameIndex);
19503
+ setSpeakerOverrides((prev) => ({ ...prev, [renameIndex]: name }));
19504
+ onSpeakerChange?.({ index: renameIndex, previous, name });
19505
+ setRenameIndex(null);
19506
+ };
19507
+ return /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { "data-slot": "recording-page-detail", className: "flex h-full min-w-0 flex-1 flex-col", children: [
19508
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { className: "flex shrink-0 items-center justify-between px-6 py-4", children: [
19509
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { className: "flex min-w-0 flex-col gap-1", children: [
19510
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Text, { text: title, strong: true, size: "large", className: "truncate" }),
19511
+ meta !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Text, { text: meta, size: "small", type: "secondary" }) : null
19512
+ ] }),
19513
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { className: "flex shrink-0 items-center gap-3", children: [
19514
+ editLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Button2, { text: editLabel, variant: "link", size: "small", onClick: () => onEdit?.() }) : null,
19515
+ shareLabel !== void 0 ? shareOptions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
19516
+ RecordingShare,
19517
+ {
19518
+ shareLabel,
19519
+ options: shareOptions,
19520
+ selectedKeys: shareSelectedKeys,
19521
+ popoverTitle: sharePopoverTitle ?? "\u9009\u62E9\u5206\u4EAB\u5185\u5BB9",
19522
+ cancelLabel: shareCancelLabel ?? "\u53D6\u6D88",
19523
+ confirmLabel: shareConfirmLabel ?? "\u786E\u5B9A",
19524
+ dialogTitle: shareDialogTitle ?? "\u5206\u4EAB\u4F1A\u8BAE\u5185\u5BB9",
19525
+ link: shareLink,
19526
+ copyLinkLabel: shareCopyLinkLabel ?? "\u590D\u5236\u94FE\u63A5",
19527
+ copiedLabel: shareCopiedLabel ?? "\u5DF2\u590D\u5236",
19528
+ mailLabel: shareMailLabel ?? "\u90AE\u4EF6",
19529
+ systemLabel: shareSystemLabel ?? "\u7CFB\u7EDF\u5206\u4EAB",
19530
+ onShare,
19531
+ onSelectionCommit: (keys) => onShareSelectionCommit?.(keys),
19532
+ onShareConfirm,
19533
+ onShareChannel
19534
+ }
19535
+ ) : /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Button2, { text: shareLabel, size: "small", onClick: () => onShare?.() }) : null
19536
+ ] })
19537
+ ] }),
19538
+ tabs.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)(import_jsx_runtime227.Fragment, { children: [
19539
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)("div", { "data-slot": "recording-page-tabs", className: "flex shrink-0 px-6 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime227.jsx)("div", { className: "flex w-full items-center gap-1 rounded-lg bg-muted p-1", children: tabs.map((tab) => {
19540
+ const active = tab.key === activeTab;
19541
+ return /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
19542
+ "button",
19543
+ {
19544
+ type: "button",
19545
+ role: "tab",
19546
+ "aria-selected": active,
19547
+ className: cn(
19548
+ "flex-1 cursor-pointer rounded-md px-3 py-1 text-sm",
19549
+ active ? "bg-background shadow-sm" : "text-muted-foreground"
19550
+ ),
19551
+ onClick: () => onTabChange(tab.key),
19552
+ children: tab.label
19553
+ },
19554
+ tab.key
19555
+ );
19556
+ }) }) }),
19557
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
19558
+ "div",
19559
+ {
19560
+ "data-slot": "recording-page-tab-body",
19561
+ className: "scrollbar-subtle min-h-0 flex-1 overflow-y-auto px-6 py-4",
19562
+ children: activeTabItem?.content !== void 0 ? renderSlot(activeTabItem.content) : activeTabItem?.key === transcriptTabKey ? /* @__PURE__ */ (0, import_jsx_runtime227.jsx)("div", { className: "flex flex-col gap-6", children: segments.map((segment, index) => /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
19563
+ TranscriptSegment,
19564
+ {
19565
+ segment,
19566
+ speaker: displaySpeaker(index),
19567
+ onRename: () => openRename(index)
19568
+ },
19569
+ segment.time ?? index
19570
+ )) }) : activeTabItem?.key === summaryTabKey && summary !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
19571
+ RecordingSummaryView,
19572
+ {
19573
+ summary,
19574
+ onMindmapAction,
19575
+ onMaterialClick,
19576
+ selectedTodoIds,
19577
+ onTodoToggle,
19578
+ onSummaryAction
19579
+ }
19580
+ ) : activeTabItem?.key === insightTabKey && insight !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
19581
+ RecordingInsightView,
19582
+ {
19583
+ insight,
19584
+ onPerspectiveEdit,
19585
+ onPerspectiveApply,
19586
+ onInsightAction
19587
+ }
19588
+ ) : activeTabItem?.key === memoryTabKey && memory !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(RecordingMemoryView, { memory, onMemoryAction }) : activeTabItem?.key === translationTabKey && translation !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
19589
+ RecordingTranslationView,
19590
+ {
19591
+ translation,
19592
+ onLanguageClick,
19593
+ onLanguageChange,
19594
+ onTranslationAction
19595
+ }
19596
+ ) : null
19597
+ }
19598
+ )
19599
+ ] }) : null,
19600
+ player !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)(
19601
+ "div",
19602
+ {
19603
+ "data-slot": "recording-page-player",
19604
+ className: "flex shrink-0 items-center gap-3 border-t border-border px-6 py-3",
19605
+ children: [
19606
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Button2, { icon: "rotate-ccw", variant: "text", onClick: () => onSkipBack?.() }),
19607
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
19608
+ Button2,
19609
+ {
19610
+ icon: "play",
19611
+ style: { borderRadius: 999 },
19612
+ onClick: () => onPlay?.()
19613
+ }
19614
+ ),
19615
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Button2, { icon: "rotate-cw", variant: "text", onClick: () => onSkipForward?.() }),
19616
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Text, { text: player.currentTime, size: "small", type: "secondary" }),
19617
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Progress2, { value: player.progress, style: { flex: 1 } }),
19618
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Text, { text: player.totalTime, size: "small", type: "secondary" })
19619
+ ]
19620
+ }
19621
+ ) : null,
19622
+ /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
19623
+ RecordingSpeakerDialog,
19624
+ {
19625
+ open: renameIndex !== null,
19626
+ title: speakerDialogTitle ?? "\u4FEE\u6539\u53D1\u8A00\u4EBA",
19627
+ hint: speakerDialogHint ?? "\u9009\u62E9\u53C2\u4F1A\u4FE1\u606F\u3001\u5DF2\u8BC6\u522B\u4EBA\u5458\u6216\u4F60\u66FE\u624B\u52A8\u521B\u5EFA\u7684\u8054\u7CFB\u4EBA\u3002",
19628
+ speakers,
19629
+ selectedIndex: draftSpeakerIndex,
19630
+ customName: draftSpeakerName,
19631
+ inputPlaceholder: speakerInputPlaceholder ?? "\u8F93\u5165\u59D3\u540D",
19632
+ applyLabel: speakerApplyLabel ?? "\u5E94\u7528\u59D3\u540D",
19633
+ onSelect: setDraftSpeakerIndex,
19634
+ onInputName: setDraftSpeakerName,
19635
+ onCancel: () => setRenameIndex(null),
19636
+ onConfirm: confirmRename
19637
+ }
19638
+ )
19639
+ ] });
19640
+ }
19641
+
19642
+ // src/components/business/RecordingPage/list.tsx
19643
+ var import_react80 = require("react");
19644
+ var import_jsx_runtime228 = require("react/jsx-runtime");
19645
+ function RecordingList({
19646
+ listTitle,
19647
+ selectLabel,
19648
+ selectDoneLabel,
19649
+ selectAllLabel,
19650
+ selectedCountText,
19651
+ deleteLabel,
19652
+ deleteConfirmTitle,
19653
+ deleteConfirmText,
19654
+ deleteCancelLabel,
19655
+ deleteConfirmLabel,
19656
+ selecting = false,
19657
+ selectedRecordingIds = [],
19658
+ onEnterSelectMode,
19659
+ onExitSelectMode,
19660
+ onToggleRecordingSelect,
19661
+ onToggleSelectAll,
19662
+ onDeleteSelected,
19663
+ filters,
19664
+ activeFilter,
19665
+ onFilterChange,
19666
+ processingText,
19667
+ processingHint,
19668
+ onProcessingClick,
19669
+ newRecordingLabel,
19670
+ onNewRecording,
19671
+ groups,
19672
+ activeRecordingId,
19673
+ onSelectRecording,
19674
+ listWidth,
19675
+ emptyText
19676
+ }) {
19677
+ const [deleteConfirmOpen, setDeleteConfirmOpen] = (0, import_react80.useState)(false);
19678
+ const renderRecordingItem = (item) => {
19679
+ const active = !selecting && item.id === activeRecordingId;
19680
+ const checked = selecting && selectedRecordingIds.includes(item.id);
19681
+ return /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(
19682
+ "button",
19683
+ {
19684
+ type: "button",
19685
+ "data-slot": "recording-item",
19686
+ "data-active": active || void 0,
19687
+ "aria-pressed": selecting ? checked : void 0,
19688
+ className: cn(
19689
+ "flex w-full cursor-pointer items-start gap-2 rounded-lg p-2 text-left",
19690
+ active ? "bg-background shadow-sm" : void 0
19691
+ ),
19692
+ onClick: () => selecting ? onToggleRecordingSelect?.(item.id) : onSelectRecording(item.id),
19693
+ children: [
19694
+ selecting ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
19695
+ "span",
19696
+ {
19697
+ className: cn(
19698
+ "mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full",
19699
+ checked ? "bg-success text-background" : "border border-border bg-background"
19700
+ ),
19701
+ children: checked ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Icon, { name: "check", size: 12 }) : null
19702
+ }
19703
+ ) : /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Icon, { name: item.icon ?? "audio-lines", size: 18, className: "mt-0.5 shrink-0" }),
19704
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
19705
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
19706
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
19707
+ Text,
19708
+ {
19709
+ text: item.title,
19710
+ size: "small",
19711
+ strong: active || checked,
19712
+ className: "min-w-0 truncate"
19713
+ }
19714
+ ),
19715
+ item.status !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
19716
+ Text,
19717
+ {
19718
+ text: item.status,
19719
+ size: "small",
19720
+ type: item.statusType ?? "secondary",
19721
+ className: "shrink-0"
19722
+ }
19723
+ ) : null
19724
+ ] }),
19725
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
19726
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Text, { text: item.time, size: "small", type: "secondary" }),
19727
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Text, { text: item.duration, size: "small", type: "secondary" })
19728
+ ] })
19729
+ ] })
19730
+ ]
19731
+ },
19732
+ item.id
19733
+ );
19734
+ };
19735
+ return /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(
19736
+ "div",
19737
+ {
19738
+ "data-slot": "recording-page-list",
19739
+ className: "m-3 flex min-h-0 shrink-0 flex-col gap-3 rounded-xl bg-muted p-4",
19740
+ style: { width: listWidth },
19741
+ children: [
19742
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)("div", { className: "flex items-center justify-between", children: [
19743
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Text, { text: listTitle, strong: true, size: "large" }),
19744
+ selecting ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
19745
+ Button2,
19746
+ {
19747
+ text: selectDoneLabel ?? "\u5B8C\u6210",
19748
+ variant: "link",
19749
+ size: "small",
19750
+ onClick: () => onExitSelectMode?.()
19751
+ }
19752
+ ) : selectLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Button2, { text: selectLabel, variant: "link", size: "small", onClick: () => onEnterSelectMode?.() }) : null
19753
+ ] }),
19754
+ selecting ? /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(
19755
+ "div",
19756
+ {
19757
+ "data-slot": "recording-page-selection-bar",
19758
+ className: "flex items-center justify-between",
19759
+ children: [
19760
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
19761
+ Text,
19762
+ {
19763
+ text: (selectedCountText ?? "\u5DF2\u9009 {count} \u6761").replace(
19764
+ "{count}",
19765
+ String(selectedRecordingIds.length)
19766
+ ),
19767
+ size: "small",
19768
+ type: "secondary"
19769
+ }
19770
+ ),
19771
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
19772
+ Button2,
19773
+ {
19774
+ text: selectAllLabel ?? "\u5168\u9009",
19775
+ variant: "link",
19776
+ size: "small",
19777
+ onClick: () => onToggleSelectAll?.()
19778
+ }
19779
+ )
19780
+ ]
19781
+ }
19782
+ ) : null,
19783
+ !selecting && filters.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)("div", { "data-slot": "recording-page-filters", className: "flex gap-2", children: filters.map((filter) => {
19784
+ const active = filter.key === activeFilter;
19785
+ return /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
19786
+ "button",
19787
+ {
19788
+ type: "button",
19789
+ "data-active": active || void 0,
19790
+ className: cn(
19791
+ "cursor-pointer rounded-full px-3 py-1 text-xs",
19792
+ active ? "bg-primary text-primary-foreground" : "bg-background"
19793
+ ),
19794
+ onClick: () => onFilterChange(filter.key),
19795
+ children: filter.label
19796
+ },
19797
+ filter.key
19798
+ );
19799
+ }) }) : null,
19800
+ !selecting && processingText !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(
19801
+ "button",
19802
+ {
19803
+ type: "button",
19804
+ "data-slot": "recording-page-processing",
19805
+ className: "flex cursor-pointer items-center gap-2 rounded-lg bg-background p-3 text-left",
19806
+ onClick: () => onProcessingClick?.(),
19807
+ children: [
19808
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Icon, { name: "audio-lines", size: 18 }),
19809
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)("div", { className: "flex flex-1 flex-col", children: [
19810
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Text, { text: processingText, size: "small", strong: true }),
19811
+ processingHint !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Text, { text: processingHint, size: "small", type: "secondary" }) : null
19812
+ ] }),
19813
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Icon, { name: "chevron-right", size: 16, className: "text-muted-foreground" })
19814
+ ]
19815
+ }
19816
+ ) : null,
19817
+ !selecting && newRecordingLabel !== null && newRecordingLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
19818
+ Button2,
19819
+ {
19820
+ text: newRecordingLabel,
19821
+ icon: "mic",
19822
+ variant: "primary",
19823
+ className: "w-full",
19824
+ onClick: () => onNewRecording?.()
19825
+ }
19826
+ ) : null,
19827
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
19828
+ "div",
19829
+ {
19830
+ "data-slot": "recording-page-groups",
19831
+ className: "scrollbar-subtle flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto",
19832
+ children: groups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Empty2, { title: emptyText }) : groups.map((group, groupIndex) => /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)("div", { className: "flex flex-col gap-1", children: [
19833
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Text, { text: group.label, size: "small", type: "secondary", className: "px-1" }),
19834
+ group.items.map(renderRecordingItem)
19835
+ ] }, group.key ?? group.label ?? groupIndex))
19836
+ }
19837
+ ),
19838
+ selecting ? /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(import_jsx_runtime228.Fragment, { children: [
19839
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
19840
+ Button2,
19841
+ {
19842
+ text: deleteLabel ?? "\u5220\u9664",
19843
+ variant: "primary",
19844
+ danger: true,
19845
+ className: "w-full shrink-0",
19846
+ onClick: () => setDeleteConfirmOpen(true)
19847
+ }
19848
+ ),
19849
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(AlertDialog, { open: deleteConfirmOpen, onOpenChange: setDeleteConfirmOpen, children: /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(AlertDialogContent, { "data-slot": "recording-delete-confirm", children: [
19850
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(AlertDialogHeader, { children: [
19851
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(AlertDialogTitle, { children: deleteConfirmTitle ?? "\u5220\u9664\u5F55\u97F3" }),
19852
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(AlertDialogDescription, { children: (deleteConfirmText ?? "\u786E\u5B9A\u5220\u9664\u9009\u4E2D\u7684 {count} \u6761\u5F55\u97F3\u5417\uFF1F\u5220\u9664\u540E\u4E0D\u53EF\u6062\u590D\u3002").replace("{count}", String(selectedRecordingIds.length)) })
19853
+ ] }),
19854
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(AlertDialogFooter, { children: [
19855
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(AlertDialogCancel, { children: deleteCancelLabel ?? "\u53D6\u6D88" }),
19856
+ /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
19857
+ AlertDialogAction,
19858
+ {
19859
+ variant: "destructive",
19860
+ onClick: () => onDeleteSelected?.(),
19861
+ children: deleteConfirmLabel ?? "\u5220\u9664"
19862
+ }
19863
+ )
19864
+ ] })
19865
+ ] }) })
19866
+ ] }) : null
19867
+ ]
19868
+ }
19869
+ );
19870
+ }
19871
+
19872
+ // src/components/business/RecordingPage/index.tsx
19873
+ var import_jsx_runtime229 = require("react/jsx-runtime");
19874
+ function RecordingPage({
19875
+ listTitle = "\u5F55\u97F3\u8BB0\u5F55\u5217\u8868",
19876
+ selectLabel,
19877
+ selectDoneLabel,
19878
+ selectAllLabel,
19879
+ selectedCountText,
19880
+ deleteLabel,
19881
+ deleteConfirmTitle,
19882
+ deleteConfirmText,
19883
+ deleteCancelLabel,
19884
+ deleteConfirmLabel,
19885
+ selectedRecordingIds,
19886
+ defaultSelectedRecordingIds,
19887
+ onRecordingSelectionChange,
19888
+ onDeleteRecordings,
19889
+ onSelectClick,
19890
+ filters = [],
19891
+ activeFilterKey,
19892
+ defaultActiveFilterKey,
19893
+ onFilterChange,
19894
+ processingText,
19895
+ processingHint,
19896
+ onProcessingClick,
19897
+ newRecordingLabel = "\u5F00\u59CB\u65B0\u5F55\u97F3",
19898
+ onNewRecording,
19899
+ groups = [],
19900
+ activeRecordingId,
19901
+ defaultActiveRecordingId,
19902
+ onSelectRecording,
19903
+ listWidth = 300,
19904
+ emptyText = "\u6682\u65E0\u5F55\u97F3",
19905
+ title,
19906
+ meta,
19907
+ editLabel,
19908
+ shareLabel,
19909
+ shareOptions,
19910
+ shareSelectedKeys,
19911
+ defaultShareSelectedKeys,
19912
+ sharePopoverTitle,
19913
+ shareCancelLabel,
19914
+ shareConfirmLabel,
19915
+ shareDialogTitle,
19916
+ shareLink,
19917
+ shareCopyLinkLabel,
19918
+ shareCopiedLabel,
19919
+ shareMailLabel,
19920
+ shareSystemLabel,
19921
+ onShareConfirm,
19922
+ onShareChannel,
19923
+ onEdit,
19924
+ onShare,
19925
+ tabs = [],
19926
+ activeTabKey,
19927
+ defaultActiveTabKey,
19928
+ onTabChange,
19929
+ transcriptTabKey = "transcript",
19930
+ segments = [],
19931
+ speakers,
19932
+ speakerDialogTitle,
19933
+ speakerDialogHint,
19934
+ speakerInputPlaceholder,
19935
+ speakerApplyLabel,
19936
+ onSpeakerChange,
19937
+ summary,
19938
+ summaryTabKey = "summary",
19939
+ onMindmapAction,
19940
+ onMaterialClick,
19941
+ onTodoClick,
19942
+ selectedTodoIds,
19943
+ defaultSelectedTodoIds,
19944
+ onTodoSelectionChange,
19945
+ onSummaryAction,
19946
+ insight,
19947
+ insightTabKey = "ai",
19948
+ onPerspectiveEdit,
19949
+ onPerspectiveApply,
19950
+ onInsightAction,
19951
+ memory,
19952
+ memoryTabKey = "knowledge",
19953
+ onMemoryAction,
19954
+ translation,
19955
+ translationTabKey = "translation",
19956
+ onLanguageClick,
19957
+ onLanguageChange,
19958
+ onTranslationAction,
19959
+ player,
19960
+ onPlay,
19961
+ onSkipBack,
19962
+ onSkipForward,
19963
+ className,
19964
+ style
19965
+ }) {
19966
+ const filterControlled = activeFilterKey !== void 0;
19967
+ const [innerFilter, setInnerFilter] = (0, import_react81.useState)(
19968
+ defaultActiveFilterKey ?? filters[0]?.key
19969
+ );
19970
+ const activeFilter = filterControlled ? activeFilterKey : innerFilter;
19971
+ const setActiveFilter = (next) => {
19972
+ if (!filterControlled) setInnerFilter(next);
19973
+ onFilterChange?.(next);
19974
+ };
19975
+ const recControlled = activeRecordingId !== void 0;
19976
+ const [innerRec, setInnerRec] = (0, import_react81.useState)(defaultActiveRecordingId);
19977
+ const activeRec = recControlled ? activeRecordingId : innerRec;
19978
+ const setActiveRec = (next) => {
19979
+ if (!recControlled) setInnerRec(next);
19980
+ onSelectRecording?.(next);
19981
+ };
19982
+ const tabControlled = activeTabKey !== void 0;
19983
+ const [innerTab, setInnerTab] = (0, import_react81.useState)(defaultActiveTabKey ?? tabs[0]?.key);
19984
+ const activeTab = tabControlled ? activeTabKey : innerTab;
19985
+ const setActiveTab = (next) => {
19986
+ if (!tabControlled) setInnerTab(next);
19987
+ onTabChange?.(next);
19988
+ };
19989
+ const todoControlled = selectedTodoIds !== void 0;
19990
+ const [innerTodos, setInnerTodos] = (0, import_react81.useState)(
19991
+ () => defaultSelectedTodoIds ?? (summary?.todos ?? []).flatMap(
19992
+ (todo, index) => todo.done === true ? [todo.id ?? index] : []
19993
+ )
19994
+ );
19995
+ const selectedTodos = todoControlled ? selectedTodoIds : innerTodos;
19996
+ const toggleTodo = (id) => {
19997
+ const next = selectedTodos.includes(id) ? selectedTodos.filter((item) => item !== id) : [...selectedTodos, id];
19998
+ if (!todoControlled) setInnerTodos(next);
19999
+ onTodoClick?.(id);
20000
+ onTodoSelectionChange?.(next);
20001
+ };
20002
+ const shareControlled = shareSelectedKeys !== void 0;
20003
+ const [innerShareKeys, setInnerShareKeys] = (0, import_react81.useState)(
20004
+ () => defaultShareSelectedKeys ?? (shareOptions ?? []).map((option) => option.key)
20005
+ );
20006
+ const shareKeys = shareControlled ? shareSelectedKeys : innerShareKeys;
20007
+ const commitShareKeys = (next) => {
20008
+ if (!shareControlled) setInnerShareKeys(next);
20009
+ };
20010
+ const [selecting, setSelecting] = (0, import_react81.useState)(false);
20011
+ const recSelControlled = selectedRecordingIds !== void 0;
20012
+ const [innerSelectedRecs, setInnerSelectedRecs] = (0, import_react81.useState)(
20013
+ () => defaultSelectedRecordingIds ?? []
20014
+ );
20015
+ const selectedRecs = recSelControlled ? selectedRecordingIds : innerSelectedRecs;
20016
+ const commitSelectedRecs = (next) => {
20017
+ if (!recSelControlled) setInnerSelectedRecs(next);
20018
+ onRecordingSelectionChange?.(next);
20019
+ };
20020
+ const allRecordingIds = groups.flatMap((group) => group.items.map((item) => item.id));
20021
+ const toggleRecordingSelect = (id) => {
20022
+ commitSelectedRecs(
20023
+ selectedRecs.includes(id) ? selectedRecs.filter((item) => item !== id) : [...selectedRecs, id]
20024
+ );
20025
+ };
20026
+ const toggleSelectAll = () => {
20027
+ commitSelectedRecs(
20028
+ selectedRecs.length === allRecordingIds.length ? [] : allRecordingIds
20029
+ );
20030
+ };
20031
+ return /* @__PURE__ */ (0, import_jsx_runtime229.jsxs)(
20032
+ "div",
20033
+ {
20034
+ "data-slot": "recording-page",
20035
+ className: cn("flex h-full w-full min-h-0 items-stretch", className),
20036
+ style,
20037
+ children: [
20038
+ /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(
20039
+ RecordingList,
20040
+ {
20041
+ listTitle,
20042
+ selectLabel,
20043
+ selectDoneLabel,
20044
+ selectAllLabel,
20045
+ selectedCountText,
20046
+ deleteLabel,
20047
+ deleteConfirmTitle,
20048
+ deleteConfirmText,
20049
+ deleteCancelLabel,
20050
+ deleteConfirmLabel,
20051
+ selecting,
20052
+ selectedRecordingIds: selectedRecs,
20053
+ onEnterSelectMode: () => {
20054
+ setSelecting(true);
20055
+ onSelectClick?.();
20056
+ },
20057
+ onExitSelectMode: () => setSelecting(false),
20058
+ onToggleRecordingSelect: toggleRecordingSelect,
20059
+ onToggleSelectAll: toggleSelectAll,
20060
+ onDeleteSelected: () => onDeleteRecordings?.(selectedRecs),
20061
+ filters,
20062
+ activeFilter,
20063
+ onFilterChange: setActiveFilter,
20064
+ processingText,
20065
+ processingHint,
20066
+ onProcessingClick,
20067
+ newRecordingLabel,
20068
+ onNewRecording,
20069
+ groups,
20070
+ activeRecordingId: activeRec,
20071
+ onSelectRecording: setActiveRec,
20072
+ listWidth,
20073
+ emptyText
20074
+ }
20075
+ ),
20076
+ /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(
20077
+ RecordingDetail,
20078
+ {
20079
+ title,
20080
+ meta,
20081
+ editLabel,
20082
+ shareLabel,
20083
+ shareOptions,
20084
+ shareSelectedKeys: shareKeys,
20085
+ sharePopoverTitle,
20086
+ shareCancelLabel,
20087
+ shareConfirmLabel,
20088
+ shareDialogTitle,
20089
+ shareLink,
20090
+ shareCopyLinkLabel,
20091
+ shareCopiedLabel,
20092
+ shareMailLabel,
20093
+ shareSystemLabel,
20094
+ onShareSelectionCommit: commitShareKeys,
20095
+ onShareConfirm,
20096
+ onShareChannel,
20097
+ onEdit,
20098
+ onShare,
20099
+ tabs,
20100
+ activeTab,
20101
+ onTabChange: setActiveTab,
20102
+ transcriptTabKey,
20103
+ segments,
20104
+ speakers,
20105
+ speakerDialogTitle,
20106
+ speakerDialogHint,
20107
+ speakerInputPlaceholder,
20108
+ speakerApplyLabel,
20109
+ onSpeakerChange,
20110
+ summary,
20111
+ summaryTabKey,
20112
+ onMindmapAction,
20113
+ onMaterialClick,
20114
+ selectedTodoIds: selectedTodos,
20115
+ onTodoToggle: toggleTodo,
20116
+ onSummaryAction,
20117
+ insight,
20118
+ insightTabKey,
20119
+ onPerspectiveEdit,
20120
+ onPerspectiveApply,
20121
+ onInsightAction,
20122
+ memory,
20123
+ memoryTabKey,
20124
+ onMemoryAction,
20125
+ translation,
20126
+ translationTabKey,
20127
+ onLanguageClick,
20128
+ onLanguageChange,
20129
+ onTranslationAction,
20130
+ player,
20131
+ onPlay,
20132
+ onSkipBack,
20133
+ onSkipForward
20134
+ }
20135
+ )
20136
+ ]
20137
+ }
20138
+ );
20139
+ }
20140
+
20141
+ // src/components/business/RuleConfig/index.tsx
20142
+ var import_lucide_react43 = require("lucide-react");
20143
+ var import_react82 = require("react");
20144
+ var import_jsx_runtime230 = require("react/jsx-runtime");
20145
+ var isBlank = (v) => v == null || String(v).trim() === "";
20146
+ function isValueMissing(condition) {
20147
+ const { opt, value } = condition;
20148
+ if (NO_VALUE_OPT.includes(opt)) return false;
20149
+ if (opt === "BETWEEN") {
20150
+ const [a, b] = normalizeBetweenValue(value);
20151
+ return isBlank(a) || isBlank(b);
20152
+ }
20153
+ if (Array.isArray(value)) return value.length === 0 || value.every(isBlank);
20154
+ return isBlank(value);
20155
+ }
20156
+ function getConditionIssue(condition) {
20157
+ const missingValue = isValueMissing(condition);
20158
+ const missingScore = condition.score == null || Number.isNaN(condition.score);
20159
+ if (!missingValue && !missingScore) return null;
20160
+ return { missingValue, missingScore };
20161
+ }
20162
+ var OPERATOR_VALUES = [
20163
+ "GREATER",
20164
+ "GREATER_EQUAL",
20165
+ "LESS_EQUAL",
20166
+ "LESS",
20167
+ "EQUAL",
20168
+ "IN",
20169
+ "NOT_IN",
20170
+ "UNEQUAL",
20171
+ "LIKE",
20172
+ "NULL",
20173
+ "HASVAL",
20174
+ "NOTNULL",
20175
+ "BETWEEN"
20176
+ ];
20177
+ var NUMERIC_OPT = [
20178
+ "GREATER",
20179
+ "LESS",
20180
+ "LESS_EQUAL",
20181
+ "GREATER_EQUAL",
20182
+ "UNEQUAL"
20183
+ ];
20184
+ var NO_VALUE_OPT = ["NULL", "HASVAL", "NOTNULL"];
20185
+ var MULTI_VALUE_OPT = ["IN", "NOT_IN"];
20186
+ var OPERATOR_LABELS2 = {
20187
+ GREATER: "\u5927\u4E8E",
20188
+ GREATER_EQUAL: "\u5927\u4E8E\u7B49\u4E8E",
20189
+ LESS_EQUAL: "\u5C0F\u4E8E\u7B49\u4E8E",
20190
+ LESS: "\u5C0F\u4E8E",
20191
+ EQUAL: "\u7B49\u4E8E",
20192
+ IN: "\u5305\u542B",
20193
+ NOT_IN: "\u4E0D\u5305\u542B",
20194
+ UNEQUAL: "\u4E0D\u7B49\u4E8E",
20195
+ LIKE: "\u7C7B\u4F3C",
20196
+ NULL: "\u4E3A\u7A7A",
20197
+ HASVAL: "\u6709\u503C",
20198
+ NOTNULL: "\u4E0D\u4E3A\u7A7A",
20199
+ BETWEEN: "\u8303\u56F4"
20200
+ };
20201
+ function operatorLabel2(operator) {
20202
+ return OPERATOR_LABELS2[operator] ?? operator;
20203
+ }
20204
+ var _key = 0;
20205
+ var nextKey = () => ++_key;
20206
+ var defaultCondition = () => ({ key: nextKey(), opt: "EQUAL" });
20207
+ function normalizeBetweenValue(value) {
20208
+ if (Array.isArray(value)) return [value[0], value[1]];
20209
+ if (typeof value === "string" && value.includes(",")) {
20210
+ const [a, b] = value.split(",");
20211
+ return [a?.trim(), b?.trim()];
20212
+ }
20213
+ if (value == null || value === "") return [void 0, void 0];
20214
+ return [value, void 0];
20215
+ }
20216
+ function formatConditionValue2(condition) {
20217
+ const { opt, value } = condition;
20218
+ if (value == null) return "-";
20219
+ if (opt === "BETWEEN") {
20220
+ const [a, b] = normalizeBetweenValue(value);
20221
+ return `${a ?? "-"} ~ ${b ?? "-"}`;
20222
+ }
20223
+ if (Array.isArray(value)) return value.join(", ");
20224
+ return String(value);
20225
+ }
20226
+ function RuleConfig({ value, onChange, disabled, size = "middle" }) {
20227
+ const rawConditions = value?.ruleConditions;
20228
+ const conditions = (0, import_react82.useMemo)(() => {
20229
+ if (!rawConditions?.length) return [defaultCondition()];
20230
+ const seen = /* @__PURE__ */ new Set();
20231
+ return rawConditions.map((c) => {
20232
+ if (c.key != null && !seen.has(c.key)) {
20233
+ seen.add(c.key);
20234
+ return c;
20235
+ }
20236
+ const key = nextKey();
20237
+ seen.add(key);
20238
+ return { ...c, key };
20239
+ });
20240
+ }, [rawConditions]);
20241
+ const initScore = value?.score ?? 1;
20242
+ const [scoreText, setScoreText] = (0, import_react82.useState)(String(initScore));
20243
+ const lastScoreRef = (0, import_react82.useRef)(value?.score);
20244
+ (0, import_react82.useEffect)(() => {
20245
+ if (value?.score === lastScoreRef.current) return;
20246
+ lastScoreRef.current = value?.score;
20247
+ setScoreText(value?.score == null ? "" : String(value.score));
20248
+ }, [value?.score]);
20249
+ const commitScore = (0, import_react82.useCallback)(
20250
+ (score) => {
20251
+ lastScoreRef.current = score;
20252
+ onChange?.({ score, ruleConditions: conditions });
20253
+ },
20254
+ [onChange, conditions]
20255
+ );
20256
+ const normalizeScore = (n) => Math.min(1e3, Math.max(1, Math.round(n)));
20257
+ const handleScoreTextChange = (text) => {
20258
+ setScoreText(text);
20259
+ if (text === "") return;
20260
+ const n = Number(text);
20261
+ if (Number.isFinite(n) && n >= 1 && n <= 1e3 && Number.isInteger(n)) {
20262
+ commitScore(n);
20263
+ }
20264
+ };
20265
+ const handleScoreBlur = () => {
20266
+ const n = scoreText.trim() === "" ? NaN : Number(scoreText);
20267
+ const next = Number.isFinite(n) ? normalizeScore(n) : 1;
20268
+ setScoreText(String(next));
20269
+ if (next !== lastScoreRef.current) commitScore(next);
20270
+ };
20271
+ const update = (0, import_react82.useCallback)(
20272
+ (next, nextScore) => onChange?.({
20273
+ score: nextScore ?? initScore,
20274
+ ruleConditions: next
20275
+ }),
20276
+ [onChange, initScore]
20277
+ );
20278
+ const handleOptChange = (key, opt) => {
20279
+ update(
20280
+ conditions.map(
20281
+ (c) => c.key === key ? { ...c, opt, value: opt === "BETWEEN" ? [] : void 0 } : c
20282
+ )
20283
+ );
20284
+ };
20285
+ const handleValueChange = (key, val) => {
20286
+ update(conditions.map((c) => c.key === key ? { ...c, value: val } : c));
20287
+ };
20288
+ const handleScoreChange = (key, score) => {
20289
+ update(
20290
+ conditions.map((c) => c.key === key ? { ...c, score } : c)
20291
+ );
20292
+ };
20293
+ const handleAdd = () => update([...conditions, defaultCondition()]);
20294
+ const handleDelete = (key) => update(conditions.filter((c) => c.key !== key));
20295
+ if (disabled) {
20296
+ return /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("div", { className: "space-y-2 text-sm", children: [
20297
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("div", { className: "flex items-center gap-2 pb-2 border-b", children: [
20298
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsx)("span", { className: "text-muted-foreground", children: "\u6743\u91CD" }),
20299
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsx)("span", { className: "font-medium", children: initScore })
20300
+ ] }),
20301
+ conditions.map((condition) => /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("div", { className: "flex items-center gap-2", children: [
20302
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsx)("span", { children: operatorLabel2(condition.opt) }),
20303
+ !NO_VALUE_OPT.includes(condition.opt) && /* @__PURE__ */ (0, import_jsx_runtime230.jsx)("span", { className: "font-medium", children: formatConditionValue2(condition) }),
20304
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("span", { className: "text-muted-foreground", children: [
20305
+ "\u8BC4\u5206: ",
20306
+ condition.score ?? "-"
20307
+ ] })
20308
+ ] }, condition.key))
20309
+ ] });
20310
+ }
20311
+ return /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("div", { className: "space-y-2", children: [
20312
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("div", { className: "flex items-center gap-1 pb-2 border-b gap-2", children: [
20313
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsx)("span", { className: "text-sm shrink-0", children: "\u6743\u91CD" }),
20314
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
20315
+ Input,
20316
+ {
20317
+ type: "number",
20318
+ className: cn("w-48", CONTROL_SIZE_BOX[size]),
20319
+ min: 1,
20320
+ max: 1e3,
20321
+ step: 1,
20322
+ value: scoreText,
20323
+ disabled,
20324
+ placeholder: "\u8BF7\u8F93\u5165\u6743\u91CD",
20325
+ onChange: (e) => handleScoreTextChange(e.target.value),
20326
+ onBlur: handleScoreBlur
20327
+ }
20328
+ )
20329
+ ] }),
20330
+ conditions.map((condition) => /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
20331
+ ConditionRow2,
20332
+ {
20333
+ condition,
20334
+ issue: getConditionIssue(condition),
20335
+ showDelete: conditions.length > 1,
20336
+ disabled,
20337
+ size,
20338
+ onOptChange: (opt) => handleOptChange(condition.key, opt),
20339
+ onValueChange: (val) => handleValueChange(condition.key, val),
20340
+ onScoreChange: (score) => handleScoreChange(condition.key, score),
20341
+ onDelete: () => handleDelete(condition.key)
20342
+ },
20343
+ condition.key
20344
+ )),
20345
+ !disabled && /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)(
20346
+ Button,
20347
+ {
20348
+ type: "button",
20349
+ variant: "link",
20350
+ size: "sm",
20351
+ className: "h-auto p-0 text-sm mt-1",
20352
+ onClick: handleAdd,
20353
+ children: [
20354
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(import_lucide_react43.Plus, { className: "h-3.5 w-3.5" }),
20355
+ "\u6DFB\u52A0\u6761\u4EF6"
20356
+ ]
20357
+ }
20358
+ )
20359
+ ] });
20360
+ }
20361
+ function ConditionRow2({
20362
+ condition,
20363
+ issue,
18697
20364
  showDelete,
18698
20365
  disabled,
18699
20366
  size,
@@ -18705,9 +20372,9 @@ function ConditionRow2({
18705
20372
  const { opt, value, score } = condition;
18706
20373
  const missingValue = !disabled && !!issue?.missingValue;
18707
20374
  const missingScore = !disabled && !!issue?.missingScore;
18708
- return /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("div", { className: "space-y-1", children: [
18709
- /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("div", { className: "flex items-center gap-2", children: [
18710
- /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)(
20375
+ return /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("div", { className: "space-y-1", children: [
20376
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("div", { className: "flex items-center gap-2", children: [
20377
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)(
18711
20378
  Select,
18712
20379
  {
18713
20380
  items: OPERATOR_VALUES.map((op) => ({
@@ -18718,23 +20385,23 @@ function ConditionRow2({
18718
20385
  onValueChange: (v) => onOptChange(v),
18719
20386
  disabled,
18720
20387
  children: [
18721
- /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
20388
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
18722
20389
  SelectTrigger,
18723
20390
  {
18724
20391
  size: CONTROL_SIZE_SELECT_ATTR[size],
18725
20392
  className: cn("w-36 shrink-0", CONTROL_SIZE_TRIGGER_TEXT[size]),
18726
- children: /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(SelectValue, {})
20393
+ children: /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(SelectValue, {})
18727
20394
  }
18728
20395
  ),
18729
- /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(SelectContent, { children: OPERATOR_VALUES.map((op) => /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(SelectItem, { value: op, children: operatorLabel2(op) }, op)) })
20396
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(SelectContent, { children: OPERATOR_VALUES.map((op) => /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(SelectItem, { value: op, children: operatorLabel2(op) }, op)) })
18730
20397
  ]
18731
20398
  }
18732
20399
  ),
18733
- !NO_VALUE_OPT.includes(opt) && /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
20400
+ !NO_VALUE_OPT.includes(opt) && /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
18734
20401
  "div",
18735
20402
  {
18736
20403
  className: "w-[30%]" + (missingValue ? " [&_input]:border-destructive" : ""),
18737
- children: /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
20404
+ children: /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
18738
20405
  ValueInput,
18739
20406
  {
18740
20407
  opt,
@@ -18746,7 +20413,7 @@ function ConditionRow2({
18746
20413
  )
18747
20414
  }
18748
20415
  ),
18749
- /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
20416
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
18750
20417
  Input,
18751
20418
  {
18752
20419
  type: "number",
@@ -18764,7 +20431,7 @@ function ConditionRow2({
18764
20431
  )
18765
20432
  }
18766
20433
  ),
18767
- showDelete && !disabled && /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
20434
+ showDelete && !disabled && /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
18768
20435
  Button,
18769
20436
  {
18770
20437
  type: "button",
@@ -18772,11 +20439,11 @@ function ConditionRow2({
18772
20439
  size: "icon",
18773
20440
  className: "h-8 w-8 shrink-0 text-muted-foreground hover:text-destructive",
18774
20441
  onClick: onDelete,
18775
- children: /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(import_lucide_react43.Trash2, { className: "h-4 w-4" })
20442
+ children: /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(import_lucide_react43.Trash2, { className: "h-4 w-4" })
18776
20443
  }
18777
20444
  )
18778
20445
  ] }),
18779
- !disabled && issue && /* @__PURE__ */ (0, import_jsx_runtime219.jsx)("p", { className: "text-xs text-destructive", children: [
20446
+ !disabled && issue && /* @__PURE__ */ (0, import_jsx_runtime230.jsx)("p", { className: "text-xs text-destructive", children: [
18780
20447
  missingValue ? "\u8BF7\u586B\u5199\u53D6\u503C" : null,
18781
20448
  missingScore ? "\u8BF7\u586B\u5199\u8BC4\u5206" : null
18782
20449
  ].filter(Boolean).join("\uFF1B") })
@@ -18788,8 +20455,8 @@ function ValueInput({ opt, value, disabled, size, onChange }) {
18788
20455
  }
18789
20456
  if (opt === "BETWEEN") {
18790
20457
  const [v1, v2] = normalizeBetweenValue(value);
18791
- return /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("div", { className: "flex items-center gap-2", children: [
18792
- /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
20458
+ return /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("div", { className: "flex items-center gap-2", children: [
20459
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
18793
20460
  Input,
18794
20461
  {
18795
20462
  type: "number",
@@ -18799,8 +20466,8 @@ function ValueInput({ opt, value, disabled, size, onChange }) {
18799
20466
  onChange: (e) => onChange([e.target.valueAsNumber, v2])
18800
20467
  }
18801
20468
  ),
18802
- /* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { className: "text-muted-foreground text-sm shrink-0", children: "~" }),
18803
- /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
20469
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsx)("span", { className: "text-muted-foreground text-sm shrink-0", children: "~" }),
20470
+ /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
18804
20471
  Input,
18805
20472
  {
18806
20473
  type: "number",
@@ -18813,7 +20480,7 @@ function ValueInput({ opt, value, disabled, size, onChange }) {
18813
20480
  ] });
18814
20481
  }
18815
20482
  if (MULTI_VALUE_OPT.includes(opt)) {
18816
- return /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
20483
+ return /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
18817
20484
  TagInput,
18818
20485
  {
18819
20486
  value: value ?? [],
@@ -18824,7 +20491,7 @@ function ValueInput({ opt, value, disabled, size, onChange }) {
18824
20491
  );
18825
20492
  }
18826
20493
  if (NUMERIC_OPT.includes(opt)) {
18827
- return /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
20494
+ return /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
18828
20495
  Input,
18829
20496
  {
18830
20497
  type: "number",
@@ -18835,7 +20502,7 @@ function ValueInput({ opt, value, disabled, size, onChange }) {
18835
20502
  }
18836
20503
  );
18837
20504
  }
18838
- return /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
20505
+ return /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
18839
20506
  Input,
18840
20507
  {
18841
20508
  type: "text",
@@ -18852,7 +20519,7 @@ function TagInput({
18852
20519
  size,
18853
20520
  onChange
18854
20521
  }) {
18855
- const [input, setInput] = (0, import_react76.useState)("");
20522
+ const [input, setInput] = (0, import_react82.useState)("");
18856
20523
  const addTag = () => {
18857
20524
  const tag = input.trim();
18858
20525
  if (tag && !value.includes(tag)) {
@@ -18861,7 +20528,7 @@ function TagInput({
18861
20528
  setInput("");
18862
20529
  };
18863
20530
  const removeTag = (tag) => onChange(value.filter((t) => t !== tag));
18864
- return /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)(
20531
+ return /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)(
18865
20532
  "div",
18866
20533
  {
18867
20534
  className: cn(
@@ -18870,9 +20537,9 @@ function TagInput({
18870
20537
  ),
18871
20538
  children: [
18872
20539
  " ",
18873
- value.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)(Badge, { variant: "secondary", className: "gap-1 pr-1", children: [
20540
+ value.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)(Badge, { variant: "secondary", className: "gap-1 pr-1", children: [
18874
20541
  tag,
18875
- !disabled && /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
20542
+ !disabled && /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
18876
20543
  "button",
18877
20544
  {
18878
20545
  type: "button",
@@ -18882,7 +20549,7 @@ function TagInput({
18882
20549
  }
18883
20550
  )
18884
20551
  ] }, tag)),
18885
- !disabled && /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
20552
+ !disabled && /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
18886
20553
  "input",
18887
20554
  {
18888
20555
  className: "flex-1 min-w-16 bg-transparent outline-none placeholder:text-muted-foreground",
@@ -18903,8 +20570,8 @@ function TagInput({
18903
20570
  }
18904
20571
 
18905
20572
  // src/components/business/RuleExpression/index.tsx
18906
- var import_react77 = require("react");
18907
- var import_jsx_runtime220 = require("react/jsx-runtime");
20573
+ var import_react83 = require("react");
20574
+ var import_jsx_runtime231 = require("react/jsx-runtime");
18908
20575
  function trailingWord(text) {
18909
20576
  const m = text.match(/[\w一-龥]+$/u);
18910
20577
  return m ? m[0] : "";
@@ -19042,11 +20709,11 @@ function RuleExpression({
19042
20709
  id,
19043
20710
  className
19044
20711
  }) {
19045
- const editorRef = (0, import_react77.useRef)(null);
19046
- const [focused, setFocused] = (0, import_react77.useState)(false);
19047
- const [activeIndex, setActiveIndex] = (0, import_react77.useState)(0);
19048
- const [matchText, setMatchText] = (0, import_react77.useState)("");
19049
- const lastEmittedRef = (0, import_react77.useRef)(null);
20712
+ const editorRef = (0, import_react83.useRef)(null);
20713
+ const [focused, setFocused] = (0, import_react83.useState)(false);
20714
+ const [activeIndex, setActiveIndex] = (0, import_react83.useState)(0);
20715
+ const [matchText, setMatchText] = (0, import_react83.useState)("");
20716
+ const lastEmittedRef = (0, import_react83.useRef)(null);
19050
20717
  const matched = matchText ? options.filter((o) => o.label.toLowerCase().includes(matchText.toLowerCase())) : [];
19051
20718
  const showSuggestions = focused && !disabled && matched.length > 0;
19052
20719
  const emitTokens = (tokens) => {
@@ -19091,7 +20758,7 @@ function RuleExpression({
19091
20758
  else ed.appendChild(document.createTextNode(t.text));
19092
20759
  }
19093
20760
  };
19094
- (0, import_react77.useLayoutEffect)(() => {
20761
+ (0, import_react83.useLayoutEffect)(() => {
19095
20762
  const sig = JSON.stringify(value ?? null);
19096
20763
  if (sig !== lastEmittedRef.current) {
19097
20764
  rebuild(seedTokens(value, options));
@@ -19194,7 +20861,7 @@ function RuleExpression({
19194
20861
  e.preventDefault();
19195
20862
  }
19196
20863
  };
19197
- return /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)(
20864
+ return /* @__PURE__ */ (0, import_jsx_runtime231.jsxs)(
19198
20865
  "div",
19199
20866
  {
19200
20867
  className: cn("relative", className),
@@ -19204,7 +20871,7 @@ function RuleExpression({
19204
20871
  }
19205
20872
  },
19206
20873
  children: [
19207
- /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(
20874
+ /* @__PURE__ */ (0, import_jsx_runtime231.jsx)(
19208
20875
  "div",
19209
20876
  {
19210
20877
  ref: editorRef,
@@ -19240,13 +20907,13 @@ function RuleExpression({
19240
20907
  }
19241
20908
  }
19242
20909
  ),
19243
- showSuggestions && /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(
20910
+ showSuggestions && /* @__PURE__ */ (0, import_jsx_runtime231.jsx)(
19244
20911
  "ul",
19245
20912
  {
19246
20913
  role: "list",
19247
20914
  className: "absolute left-0 top-full z-50 mt-1 max-h-60 w-full overflow-auto rounded-md border bg-popover p-1 shadow-md",
19248
20915
  onMouseDown: (e) => e.preventDefault(),
19249
- children: matched.map((opt, index) => /* @__PURE__ */ (0, import_jsx_runtime220.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(
20916
+ children: matched.map((opt, index) => /* @__PURE__ */ (0, import_jsx_runtime231.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime231.jsx)(
19250
20917
  "button",
19251
20918
  {
19252
20919
  type: "button",
@@ -19267,8 +20934,8 @@ function RuleExpression({
19267
20934
  }
19268
20935
 
19269
20936
  // src/components/business/ScriptEditor/index.tsx
19270
- var import_react78 = require("react");
19271
- var import_jsx_runtime221 = require("react/jsx-runtime");
20937
+ var import_react84 = require("react");
20938
+ var import_jsx_runtime232 = require("react/jsx-runtime");
19272
20939
  function escapeHtml(text) {
19273
20940
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
19274
20941
  }
@@ -19335,12 +21002,12 @@ function ScriptEditor({
19335
21002
  height = 160,
19336
21003
  className
19337
21004
  }) {
19338
- const containerRef = (0, import_react78.useRef)(null);
19339
- const editorRef = (0, import_react78.useRef)(null);
19340
- const onChangeRef = (0, import_react78.useRef)(onChange);
21005
+ const containerRef = (0, import_react84.useRef)(null);
21006
+ const editorRef = (0, import_react84.useRef)(null);
21007
+ const onChangeRef = (0, import_react84.useRef)(onChange);
19341
21008
  onChangeRef.current = onChange;
19342
- const [isEmpty2, setIsEmpty] = (0, import_react78.useState)(!value);
19343
- (0, import_react78.useEffect)(() => {
21009
+ const [isEmpty2, setIsEmpty] = (0, import_react84.useState)(!value);
21010
+ (0, import_react84.useEffect)(() => {
19344
21011
  let disposed = false;
19345
21012
  (async () => {
19346
21013
  const ace = await import("ace-builds");
@@ -19378,7 +21045,7 @@ function ScriptEditor({
19378
21045
  editorRef.current = null;
19379
21046
  };
19380
21047
  }, []);
19381
- (0, import_react78.useEffect)(() => {
21048
+ (0, import_react84.useEffect)(() => {
19382
21049
  const editor = editorRef.current;
19383
21050
  if (!editor) return;
19384
21051
  const next = value ?? "";
@@ -19387,15 +21054,15 @@ function ScriptEditor({
19387
21054
  setIsEmpty(next === "");
19388
21055
  }
19389
21056
  }, [value]);
19390
- (0, import_react78.useEffect)(() => {
21057
+ (0, import_react84.useEffect)(() => {
19391
21058
  editorRef.current?.setOptions({
19392
21059
  enableBasicAutocompletion: [buildScriptCompletions(functions, variables)]
19393
21060
  });
19394
21061
  }, [functions, variables]);
19395
- (0, import_react78.useEffect)(() => {
21062
+ (0, import_react84.useEffect)(() => {
19396
21063
  editorRef.current?.setReadOnly(readonly ?? false);
19397
21064
  }, [readonly]);
19398
- return /* @__PURE__ */ (0, import_jsx_runtime221.jsxs)(
21065
+ return /* @__PURE__ */ (0, import_jsx_runtime232.jsxs)(
19399
21066
  "div",
19400
21067
  {
19401
21068
  className: cn(
@@ -19404,15 +21071,15 @@ function ScriptEditor({
19404
21071
  className
19405
21072
  ),
19406
21073
  children: [
19407
- /* @__PURE__ */ (0, import_jsx_runtime221.jsx)("div", { ref: containerRef, id, style: { height }, className: "w-full" }),
19408
- isEmpty2 && placeholder && /* @__PURE__ */ (0, import_jsx_runtime221.jsx)("div", { className: "absolute top-0 left-0 px-3 py-2 text-sm text-muted-foreground pointer-events-none z-10", children: placeholder })
21074
+ /* @__PURE__ */ (0, import_jsx_runtime232.jsx)("div", { ref: containerRef, id, style: { height }, className: "w-full" }),
21075
+ isEmpty2 && placeholder && /* @__PURE__ */ (0, import_jsx_runtime232.jsx)("div", { className: "absolute top-0 left-0 px-3 py-2 text-sm text-muted-foreground pointer-events-none z-10", children: placeholder })
19409
21076
  ]
19410
21077
  }
19411
21078
  );
19412
21079
  }
19413
21080
 
19414
21081
  // src/components/business/SiteFooter/index.tsx
19415
- var import_jsx_runtime222 = require("react/jsx-runtime");
21082
+ var import_jsx_runtime233 = require("react/jsx-runtime");
19416
21083
  function SiteFooter({
19417
21084
  brand,
19418
21085
  groups,
@@ -19424,7 +21091,7 @@ function SiteFooter({
19424
21091
  }) {
19425
21092
  const renderLink = (link) => {
19426
21093
  if (link.href) {
19427
- return /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(
21094
+ return /* @__PURE__ */ (0, import_jsx_runtime233.jsx)(
19428
21095
  Link2,
19429
21096
  {
19430
21097
  href: link.href,
@@ -19433,7 +21100,7 @@ function SiteFooter({
19433
21100
  }
19434
21101
  );
19435
21102
  }
19436
- return /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(
21103
+ return /* @__PURE__ */ (0, import_jsx_runtime233.jsx)(
19437
21104
  "button",
19438
21105
  {
19439
21106
  type: "button",
@@ -19450,22 +21117,22 @@ function SiteFooter({
19450
21117
  if (!hasBrand && !hasGroups && !hasBottom) {
19451
21118
  return null;
19452
21119
  }
19453
- return /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)(
21120
+ return /* @__PURE__ */ (0, import_jsx_runtime233.jsxs)(
19454
21121
  "footer",
19455
21122
  {
19456
21123
  "data-slot": "site-footer",
19457
21124
  className: cn("border-t bg-muted/40", className),
19458
21125
  style,
19459
21126
  children: [
19460
- hasBrand || hasGroups ? /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)(
21127
+ hasBrand || hasGroups ? /* @__PURE__ */ (0, import_jsx_runtime233.jsxs)(
19461
21128
  "div",
19462
21129
  {
19463
21130
  "data-slot": "site-footer-main",
19464
21131
  className: "mx-auto flex w-full max-w-6xl flex-col gap-8 px-6 py-10 md:flex-row md:justify-between",
19465
21132
  children: [
19466
- hasBrand ? /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)("div", { "data-slot": "site-footer-brand", className: "flex max-w-xs flex-col gap-3", children: [
19467
- brand.logo || brand.name ? /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)("div", { className: "flex items-center gap-2", children: [
19468
- brand.logo ? /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(
21133
+ hasBrand ? /* @__PURE__ */ (0, import_jsx_runtime233.jsxs)("div", { "data-slot": "site-footer-brand", className: "flex max-w-xs flex-col gap-3", children: [
21134
+ brand.logo || brand.name ? /* @__PURE__ */ (0, import_jsx_runtime233.jsxs)("div", { className: "flex items-center gap-2", children: [
21135
+ brand.logo ? /* @__PURE__ */ (0, import_jsx_runtime233.jsx)(
19469
21136
  "img",
19470
21137
  {
19471
21138
  src: brand.logo,
@@ -19473,23 +21140,23 @@ function SiteFooter({
19473
21140
  className: "size-8 rounded-md object-contain"
19474
21141
  }
19475
21142
  ) : null,
19476
- brand.name ? /* @__PURE__ */ (0, import_jsx_runtime222.jsx)("span", { className: "text-base font-semibold", children: brand.name }) : null
21143
+ brand.name ? /* @__PURE__ */ (0, import_jsx_runtime233.jsx)("span", { className: "text-base font-semibold", children: brand.name }) : null
19477
21144
  ] }) : null,
19478
- brand.description ? /* @__PURE__ */ (0, import_jsx_runtime222.jsx)("p", { className: "text-sm leading-relaxed text-muted-foreground", children: brand.description }) : null
21145
+ brand.description ? /* @__PURE__ */ (0, import_jsx_runtime233.jsx)("p", { className: "text-sm leading-relaxed text-muted-foreground", children: brand.description }) : null
19479
21146
  ] }) : null,
19480
- hasGroups ? /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(
21147
+ hasGroups ? /* @__PURE__ */ (0, import_jsx_runtime233.jsx)(
19481
21148
  "div",
19482
21149
  {
19483
21150
  "data-slot": "site-footer-groups",
19484
21151
  className: "grid flex-1 grid-cols-2 gap-8 sm:grid-cols-3 md:justify-items-end",
19485
- children: groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)(
21152
+ children: groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime233.jsxs)(
19486
21153
  "div",
19487
21154
  {
19488
21155
  "data-slot": "site-footer-group",
19489
21156
  className: "flex min-w-24 flex-col gap-3",
19490
21157
  children: [
19491
- /* @__PURE__ */ (0, import_jsx_runtime222.jsx)("span", { className: "text-sm font-medium", children: group.title }),
19492
- /* @__PURE__ */ (0, import_jsx_runtime222.jsx)("div", { className: "flex flex-col gap-2", children: group.links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime222.jsx)("div", { children: renderLink(link) }, link.text)) })
21158
+ /* @__PURE__ */ (0, import_jsx_runtime233.jsx)("span", { className: "text-sm font-medium", children: group.title }),
21159
+ /* @__PURE__ */ (0, import_jsx_runtime233.jsx)("div", { className: "flex flex-col gap-2", children: group.links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime233.jsx)("div", { children: renderLink(link) }, link.text)) })
19493
21160
  ]
19494
21161
  },
19495
21162
  group.title
@@ -19499,9 +21166,9 @@ function SiteFooter({
19499
21166
  ]
19500
21167
  }
19501
21168
  ) : null,
19502
- hasBottom ? /* @__PURE__ */ (0, import_jsx_runtime222.jsx)("div", { "data-slot": "site-footer-bottom", className: "border-t", children: /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)("div", { className: "mx-auto flex w-full max-w-6xl flex-col items-center gap-2 px-6 py-4 text-xs text-muted-foreground sm:flex-row sm:justify-between", children: [
19503
- copyright ? /* @__PURE__ */ (0, import_jsx_runtime222.jsx)("span", { children: copyright }) : /* @__PURE__ */ (0, import_jsx_runtime222.jsx)("span", {}),
19504
- bottomLinks && bottomLinks.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime222.jsx)("div", { "data-slot": "site-footer-bottom-links", className: "flex items-center gap-4", children: bottomLinks.map((link) => /* @__PURE__ */ (0, import_jsx_runtime222.jsx)("div", { children: renderLink(link) }, link.text)) }) : null
21169
+ hasBottom ? /* @__PURE__ */ (0, import_jsx_runtime233.jsx)("div", { "data-slot": "site-footer-bottom", className: "border-t", children: /* @__PURE__ */ (0, import_jsx_runtime233.jsxs)("div", { className: "mx-auto flex w-full max-w-6xl flex-col items-center gap-2 px-6 py-4 text-xs text-muted-foreground sm:flex-row sm:justify-between", children: [
21170
+ copyright ? /* @__PURE__ */ (0, import_jsx_runtime233.jsx)("span", { children: copyright }) : /* @__PURE__ */ (0, import_jsx_runtime233.jsx)("span", {}),
21171
+ bottomLinks && bottomLinks.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime233.jsx)("div", { "data-slot": "site-footer-bottom-links", className: "flex items-center gap-4", children: bottomLinks.map((link) => /* @__PURE__ */ (0, import_jsx_runtime233.jsx)("div", { children: renderLink(link) }, link.text)) }) : null
19505
21172
  ] }) }) : null
19506
21173
  ]
19507
21174
  }
@@ -19681,6 +21348,7 @@ var builtinComponents = {
19681
21348
  Login,
19682
21349
  EntityCard,
19683
21350
  CardList,
21351
+ RecordingPage,
19684
21352
  SiteFooter,
19685
21353
  // 业务表单类组件(value/onChange 受控;DSL 用 props.value + events.onChange 读写 ${event})
19686
21354
  SearchableSelect,
@@ -19748,11 +21416,11 @@ function collectDefaultOpenKeys(registry, activeMenuId) {
19748
21416
  // src/layout/admin/AdminLayout.tsx
19749
21417
  var import_permission = require("@pactor-app/permission");
19750
21418
  var import_router = require("@pactor-app/router");
19751
- var import_runtime54 = require("@pactor-app/runtime");
19752
- var import_react80 = require("react");
21419
+ var import_runtime55 = require("@pactor-app/runtime");
21420
+ var import_react86 = require("react");
19753
21421
 
19754
21422
  // src/layout/admin/use-media-query.ts
19755
- var import_react79 = require("react");
21423
+ var import_react85 = require("react");
19756
21424
  var BREAKPOINT_PX = {
19757
21425
  xs: 480,
19758
21426
  sm: 576,
@@ -19762,10 +21430,10 @@ var BREAKPOINT_PX = {
19762
21430
  xxl: 1600
19763
21431
  };
19764
21432
  function useMediaQuery(query) {
19765
- const [matches, setMatches] = (0, import_react79.useState)(
21433
+ const [matches, setMatches] = (0, import_react85.useState)(
19766
21434
  () => typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia(query).matches : false
19767
21435
  );
19768
- (0, import_react79.useEffect)(() => {
21436
+ (0, import_react85.useEffect)(() => {
19769
21437
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
19770
21438
  return;
19771
21439
  }
@@ -19785,7 +21453,7 @@ function useBreakpointBelow(breakpoint) {
19785
21453
  }
19786
21454
 
19787
21455
  // src/layout/admin/AdminLayout.tsx
19788
- var import_jsx_runtime223 = require("react/jsx-runtime");
21456
+ var import_jsx_runtime234 = require("react/jsx-runtime");
19789
21457
  function buildVisibleMenuTree(registry, permissionChecker) {
19790
21458
  const tree = registry.tree();
19791
21459
  return permissionChecker === void 0 ? [...tree] : (0, import_permission.filterMenusByPermission)(tree, permissionChecker);
@@ -19808,8 +21476,8 @@ function CollapsedGroupFlyout({
19808
21476
  activeMenuId,
19809
21477
  defaultOpenKeys
19810
21478
  }) {
19811
- const [open, setOpen] = (0, import_react80.useState)(false);
19812
- const closeTimer = (0, import_react80.useRef)(void 0);
21479
+ const [open, setOpen] = (0, import_react86.useState)(false);
21480
+ const closeTimer = (0, import_react86.useRef)(void 0);
19813
21481
  const openNow = () => {
19814
21482
  window.clearTimeout(closeTimer.current);
19815
21483
  setOpen(true);
@@ -19818,12 +21486,12 @@ function CollapsedGroupFlyout({
19818
21486
  window.clearTimeout(closeTimer.current);
19819
21487
  closeTimer.current = window.setTimeout(() => setOpen(false), 200);
19820
21488
  };
19821
- (0, import_react80.useEffect)(() => () => window.clearTimeout(closeTimer.current), []);
19822
- return /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)(Popover, { open, onOpenChange: setOpen, children: [
19823
- /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21489
+ (0, import_react86.useEffect)(() => () => window.clearTimeout(closeTimer.current), []);
21490
+ return /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)(Popover, { open, onOpenChange: setOpen, children: [
21491
+ /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
19824
21492
  PopoverTrigger,
19825
21493
  {
19826
- render: /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21494
+ render: /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
19827
21495
  "button",
19828
21496
  {
19829
21497
  type: "button",
@@ -19841,7 +21509,7 @@ function CollapsedGroupFlyout({
19841
21509
  )
19842
21510
  }
19843
21511
  ),
19844
- /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)(
21512
+ /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)(
19845
21513
  PopoverContent,
19846
21514
  {
19847
21515
  "data-slot": "menu-flyout",
@@ -19858,8 +21526,8 @@ function CollapsedGroupFlyout({
19858
21526
  }
19859
21527
  },
19860
21528
  children: [
19861
- /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("div", { className: "px-3 pt-2 pb-1 text-xs font-semibold text-muted-foreground", children: menu.title }),
19862
- /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21529
+ /* @__PURE__ */ (0, import_jsx_runtime234.jsx)("div", { className: "px-3 pt-2 pb-1 text-xs font-semibold text-muted-foreground", children: menu.title }),
21530
+ /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
19863
21531
  MenuTree,
19864
21532
  {
19865
21533
  menus: menu.children ?? [],
@@ -19883,9 +21551,9 @@ function MenuTree({
19883
21551
  collapsed = false
19884
21552
  }) {
19885
21553
  if (collapsed) {
19886
- return /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("div", { "data-slot": "menu", "data-collapsed": "true", className: "flex flex-col gap-1", children: menus.map((menu) => {
21554
+ return /* @__PURE__ */ (0, import_jsx_runtime234.jsx)("div", { "data-slot": "menu", "data-collapsed": "true", className: "flex flex-col gap-1", children: menus.map((menu) => {
19887
21555
  if (menu.type === "group") {
19888
- return /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21556
+ return /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
19889
21557
  CollapsedGroupFlyout,
19890
21558
  {
19891
21559
  menu,
@@ -19897,7 +21565,7 @@ function MenuTree({
19897
21565
  menu.id
19898
21566
  );
19899
21567
  }
19900
- return /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21568
+ return /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
19901
21569
  "button",
19902
21570
  {
19903
21571
  type: "button",
@@ -19917,7 +21585,7 @@ function MenuTree({
19917
21585
  );
19918
21586
  }) });
19919
21587
  }
19920
- return /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21588
+ return /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
19921
21589
  Accordion,
19922
21590
  {
19923
21591
  type: "multiple",
@@ -19926,27 +21594,27 @@ function MenuTree({
19926
21594
  className: "flex flex-col gap-0.5 px-2",
19927
21595
  children: menus.map((menu) => {
19928
21596
  if (menu.type === "group") {
19929
- return /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)(
21597
+ return /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)(
19930
21598
  AccordionItem,
19931
21599
  {
19932
21600
  value: menu.id,
19933
21601
  "data-slot": "menu-group",
19934
21602
  className: "border-b-0",
19935
21603
  children: [
19936
- /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21604
+ /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
19937
21605
  AccordionTrigger,
19938
21606
  {
19939
21607
  "data-slot": "menu-group-trigger",
19940
21608
  className: cn(menuItemClass2, "py-2 font-medium"),
19941
21609
  disabled: menu.disabled,
19942
21610
  title: menu.title,
19943
- children: /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)("span", { className: "inline-flex items-center gap-2", children: [
19944
- menu.icon ? /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(Icon, { name: menu.icon, size: "sm" }) : null,
21611
+ children: /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)("span", { className: "inline-flex items-center gap-2", children: [
21612
+ menu.icon ? /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(Icon, { name: menu.icon, size: "sm" }) : null,
19945
21613
  menu.title
19946
21614
  ] })
19947
21615
  }
19948
21616
  ),
19949
- /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(AccordionContent, { "data-slot": "menu-group-content", className: "pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("div", { className: "flex flex-col gap-0.5 pl-3", children: /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21617
+ /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(AccordionContent, { "data-slot": "menu-group-content", className: "pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime234.jsx)("div", { className: "flex flex-col gap-0.5 pl-3", children: /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
19950
21618
  MenuTree,
19951
21619
  {
19952
21620
  menus: menu.children ?? [],
@@ -19961,7 +21629,7 @@ function MenuTree({
19961
21629
  menu.id
19962
21630
  );
19963
21631
  }
19964
- return /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)(
21632
+ return /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)(
19965
21633
  "button",
19966
21634
  {
19967
21635
  type: "button",
@@ -19975,7 +21643,7 @@ function MenuTree({
19975
21643
  title: menu.title,
19976
21644
  onClick: () => navigateMenuItem(registry.findById(menu.id), bridge),
19977
21645
  children: [
19978
- menu.icon ? /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(Icon, { name: menu.icon, size: "sm" }) : null,
21646
+ menu.icon ? /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(Icon, { name: menu.icon, size: "sm" }) : null,
19979
21647
  menu.title
19980
21648
  ]
19981
21649
  },
@@ -19995,23 +21663,23 @@ function AdminLayout({
19995
21663
  headerExtra,
19996
21664
  children
19997
21665
  }) {
19998
- const { t } = (0, import_runtime54.useI18n)();
21666
+ const { t } = (0, import_runtime55.useI18n)();
19999
21667
  const mode = config.mode ?? "top-side";
20000
21668
  const showHeader = config.header ?? true;
20001
21669
  const showSidebar = (config.sidebar ?? true) && mode !== "top-bottom";
20002
21670
  const showTabs = config.tabs ?? false;
20003
21671
  const showBreadcrumb = config.breadcrumb ?? false;
20004
21672
  const showFooter = config.footer ?? false;
20005
- const [collapsed, setCollapsed] = (0, import_react80.useState)(config.collapsed ?? false);
21673
+ const [collapsed, setCollapsed] = (0, import_react86.useState)(config.collapsed ?? false);
20006
21674
  const broken = useBreakpointBelow(config.breakpoint);
20007
21675
  const effectiveCollapsed = collapsed || broken;
20008
- const [bridgeRoute, setBridgeRoute] = (0, import_react80.useState)(
21676
+ const [bridgeRoute, setBridgeRoute] = (0, import_react86.useState)(
20009
21677
  () => (0, import_router.resolveRoute)(registry, bridge.getLocation())
20010
21678
  );
20011
- const [tabs, setTabs] = (0, import_react80.useState)([]);
20012
- const tabsRef = (0, import_react80.useRef)(tabs);
21679
+ const [tabs, setTabs] = (0, import_react86.useState)([]);
21680
+ const tabsRef = (0, import_react86.useRef)(tabs);
20013
21681
  tabsRef.current = tabs;
20014
- (0, import_react80.useEffect)(() => {
21682
+ (0, import_react86.useEffect)(() => {
20015
21683
  const handleLocation = (location) => {
20016
21684
  const next = (0, import_router.resolveRoute)(registry, location);
20017
21685
  setBridgeRoute(next);
@@ -20032,16 +21700,16 @@ function AdminLayout({
20032
21700
  }, [registry, bridge]);
20033
21701
  const route = routeProp ?? bridgeRoute;
20034
21702
  const activeMenuId = route?.activeMenu;
20035
- const visibleMenus = (0, import_react80.useMemo)(
21703
+ const visibleMenus = (0, import_react86.useMemo)(
20036
21704
  () => buildVisibleMenuTree(registry, permissionChecker),
20037
21705
  [registry, permissionChecker]
20038
21706
  );
20039
- const defaultOpenKeysRef = (0, import_react80.useRef)(null);
21707
+ const defaultOpenKeysRef = (0, import_react86.useRef)(null);
20040
21708
  if (defaultOpenKeysRef.current === null) {
20041
21709
  defaultOpenKeysRef.current = collectDefaultOpenKeys(registry, activeMenuId);
20042
21710
  }
20043
21711
  const defaultOpenKeys = defaultOpenKeysRef.current;
20044
- const activeTopId = (0, import_react80.useMemo)(() => {
21712
+ const activeTopId = (0, import_react86.useMemo)(() => {
20045
21713
  if (activeMenuId !== void 0) {
20046
21714
  const chain = findMenuChain(registry, activeMenuId);
20047
21715
  if (chain.length > 0) {
@@ -20050,11 +21718,11 @@ function AdminLayout({
20050
21718
  }
20051
21719
  return void 0;
20052
21720
  }, [registry, activeMenuId]);
20053
- const [selectedTopId, setSelectedTopId] = (0, import_react80.useState)();
21721
+ const [selectedTopId, setSelectedTopId] = (0, import_react86.useState)();
20054
21722
  const secondaryTopId = selectedTopId ?? activeTopId ?? visibleMenus.find((m) => m.type === "group")?.id ?? visibleMenus[0]?.id;
20055
21723
  const secondaryTop = visibleMenus.find((m) => m.id === secondaryTopId);
20056
21724
  const hasSecondary = (secondaryTop?.children?.length ?? 0) > 0;
20057
- const breadcrumbItems = (0, import_react80.useMemo)(() => {
21725
+ const breadcrumbItems = (0, import_react86.useMemo)(() => {
20058
21726
  if (!showBreadcrumb || activeMenuId === void 0) {
20059
21727
  return [];
20060
21728
  }
@@ -20070,7 +21738,7 @@ function AdminLayout({
20070
21738
  };
20071
21739
  const fixedHeader = config.fixedHeader ?? true;
20072
21740
  const fixedSider = config.fixedSider ?? true;
20073
- const header = showHeader ? /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)(
21741
+ const header = showHeader ? /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)(
20074
21742
  "header",
20075
21743
  {
20076
21744
  "data-slot": "admin-header",
@@ -20079,21 +21747,21 @@ function AdminLayout({
20079
21747
  fixedHeader && "sticky top-0 z-20"
20080
21748
  ),
20081
21749
  children: [
20082
- mode !== "side-full" && /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)(import_jsx_runtime223.Fragment, { children: [
21750
+ mode !== "side-full" && /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)(import_jsx_runtime234.Fragment, { children: [
20083
21751
  brand.logo,
20084
- /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("span", { "data-slot": "admin-brand", className: "text-lg font-semibold", children: brand.title })
21752
+ /* @__PURE__ */ (0, import_jsx_runtime234.jsx)("span", { "data-slot": "admin-brand", className: "text-lg font-semibold", children: brand.title })
20085
21753
  ] }),
20086
- /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("div", { className: "flex-1" }),
21754
+ /* @__PURE__ */ (0, import_jsx_runtime234.jsx)("div", { className: "flex-1" }),
20087
21755
  headerExtra
20088
21756
  ]
20089
21757
  }
20090
21758
  ) : null;
20091
- const primaryColumn = /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21759
+ const primaryColumn = /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
20092
21760
  "div",
20093
21761
  {
20094
21762
  "data-slot": "admin-primary-col",
20095
21763
  className: "flex w-12 shrink-0 flex-col items-center gap-1 border-r border-border py-2",
20096
- children: visibleMenus.map((menu) => /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21764
+ children: visibleMenus.map((menu) => /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
20097
21765
  "button",
20098
21766
  {
20099
21767
  type: "button",
@@ -20120,7 +21788,7 @@ function AdminLayout({
20120
21788
  }
20121
21789
  );
20122
21790
  const showTrigger = config.collapsible && mode !== "two-column";
20123
- const sidebar = showSidebar ? /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)(
21791
+ const sidebar = showSidebar ? /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)(
20124
21792
  "aside",
20125
21793
  {
20126
21794
  "data-slot": "admin-sidebar",
@@ -20132,20 +21800,20 @@ function AdminLayout({
20132
21800
  ),
20133
21801
  style: mode === "two-column" && !hasSecondary ? { width: 56 } : void 0,
20134
21802
  children: [
20135
- mode === "side-full" && /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)(
21803
+ mode === "side-full" && /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)(
20136
21804
  "div",
20137
21805
  {
20138
21806
  "data-slot": "admin-sidebar-brand",
20139
21807
  className: "flex items-center gap-2 border-b border-border px-4 py-4 font-semibold",
20140
21808
  children: [
20141
21809
  brand.logo,
20142
- /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("span", { children: brand.title })
21810
+ /* @__PURE__ */ (0, import_jsx_runtime234.jsx)("span", { children: brand.title })
20143
21811
  ]
20144
21812
  }
20145
21813
  ),
20146
- mode === "two-column" ? /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)("div", { "data-slot": "admin-two-col", className: "flex h-full", children: [
21814
+ mode === "two-column" ? /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)("div", { "data-slot": "admin-two-col", className: "flex h-full", children: [
20147
21815
  primaryColumn,
20148
- hasSecondary && /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("div", { "data-slot": "admin-secondary-col", className: "min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21816
+ hasSecondary && /* @__PURE__ */ (0, import_jsx_runtime234.jsx)("div", { "data-slot": "admin-secondary-col", className: "min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
20149
21817
  MenuTree,
20150
21818
  {
20151
21819
  menus: secondaryTop?.children ?? [],
@@ -20155,7 +21823,7 @@ function AdminLayout({
20155
21823
  defaultOpenKeys
20156
21824
  }
20157
21825
  ) })
20158
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21826
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
20159
21827
  MenuTree,
20160
21828
  {
20161
21829
  menus: visibleMenus,
@@ -20166,7 +21834,7 @@ function AdminLayout({
20166
21834
  collapsed: effectiveCollapsed
20167
21835
  }
20168
21836
  ),
20169
- showTrigger && /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21837
+ showTrigger && /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
20170
21838
  "button",
20171
21839
  {
20172
21840
  type: "button",
@@ -20181,14 +21849,14 @@ function AdminLayout({
20181
21849
  ]
20182
21850
  }
20183
21851
  ) : null;
20184
- const body = /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)("div", { "data-slot": "admin-body", className: "flex min-w-0 flex-1 flex-col", children: [
20185
- showTabs && /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21852
+ const body = /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)("div", { "data-slot": "admin-body", className: "flex min-w-0 flex-1 flex-col", children: [
21853
+ showTabs && /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
20186
21854
  "div",
20187
21855
  {
20188
21856
  "data-slot": "admin-tabs",
20189
21857
  role: "tablist",
20190
21858
  className: "flex items-center gap-1 border-b border-border bg-card px-4 pt-2",
20191
- children: tabs.map((tab, index) => /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)(
21859
+ children: tabs.map((tab, index) => /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)(
20192
21860
  "div",
20193
21861
  {
20194
21862
  "data-slot": "admin-tab",
@@ -20199,7 +21867,7 @@ function AdminLayout({
20199
21867
  tab.key === currentPath ? "bg-card font-medium text-foreground" : "bg-muted text-muted-foreground"
20200
21868
  ),
20201
21869
  children: [
20202
- /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21870
+ /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
20203
21871
  "button",
20204
21872
  {
20205
21873
  type: "button",
@@ -20210,7 +21878,7 @@ function AdminLayout({
20210
21878
  children: tab.title
20211
21879
  }
20212
21880
  ),
20213
- index > 0 && /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21881
+ index > 0 && /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
20214
21882
  "button",
20215
21883
  {
20216
21884
  type: "button",
@@ -20227,21 +21895,21 @@ function AdminLayout({
20227
21895
  ))
20228
21896
  }
20229
21897
  ),
20230
- /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)(
21898
+ /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)(
20231
21899
  "main",
20232
21900
  {
20233
21901
  "data-slot": "admin-content",
20234
21902
  className: "flex-1 bg-muted/40 p-6",
20235
21903
  children: [
20236
- showBreadcrumb && breadcrumbItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21904
+ showBreadcrumb && breadcrumbItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
20237
21905
  "nav",
20238
21906
  {
20239
21907
  "data-slot": "admin-breadcrumb",
20240
21908
  "aria-label": t("pactor.layout.breadcrumb"),
20241
21909
  className: "mb-4",
20242
- children: /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("ol", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: breadcrumbItems.map((title, index) => /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)("li", { className: "flex items-center gap-2", children: [
20243
- index > 0 && /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("span", { "aria-hidden": true, children: "/" }),
20244
- /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("span", { "data-slot": "breadcrumb-link", children: title })
21910
+ children: /* @__PURE__ */ (0, import_jsx_runtime234.jsx)("ol", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: breadcrumbItems.map((title, index) => /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)("li", { className: "flex items-center gap-2", children: [
21911
+ index > 0 && /* @__PURE__ */ (0, import_jsx_runtime234.jsx)("span", { "aria-hidden": true, children: "/" }),
21912
+ /* @__PURE__ */ (0, import_jsx_runtime234.jsx)("span", { "data-slot": "breadcrumb-link", children: title })
20245
21913
  ] }, index)) })
20246
21914
  }
20247
21915
  ),
@@ -20250,7 +21918,7 @@ function AdminLayout({
20250
21918
  }
20251
21919
  )
20252
21920
  ] });
20253
- const footer = showFooter ? /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21921
+ const footer = showFooter ? /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
20254
21922
  "footer",
20255
21923
  {
20256
21924
  "data-slot": "admin-footer",
@@ -20258,7 +21926,7 @@ function AdminLayout({
20258
21926
  children: brand.title
20259
21927
  }
20260
21928
  ) : null;
20261
- return /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
21929
+ return /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(
20262
21930
  "div",
20263
21931
  {
20264
21932
  "data-slot": "admin-layout",
@@ -20266,9 +21934,9 @@ function AdminLayout({
20266
21934
  "data-fixed-header": fixedHeader || void 0,
20267
21935
  "data-fixed-sider": fixedSider || void 0,
20268
21936
  className: "flex min-h-screen flex-col bg-background text-foreground",
20269
- children: mode === "side-full" ? /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)("div", { "data-slot": "admin-side-full", className: "flex min-h-screen flex-1", children: [
21937
+ children: mode === "side-full" ? /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)("div", { "data-slot": "admin-side-full", className: "flex min-h-screen flex-1", children: [
20270
21938
  sidebar,
20271
- /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)(
21939
+ /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)(
20272
21940
  "div",
20273
21941
  {
20274
21942
  "data-slot": "admin-side-full-main",
@@ -20280,9 +21948,9 @@ function AdminLayout({
20280
21948
  ]
20281
21949
  }
20282
21950
  )
20283
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)(import_jsx_runtime223.Fragment, { children: [
21951
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)(import_jsx_runtime234.Fragment, { children: [
20284
21952
  header,
20285
- /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)("div", { "data-slot": "admin-main", className: "flex min-h-0 flex-1", children: [
21953
+ /* @__PURE__ */ (0, import_jsx_runtime234.jsxs)("div", { "data-slot": "admin-main", className: "flex min-h-0 flex-1", children: [
20286
21954
  sidebar,
20287
21955
  body
20288
21956
  ] }),
@@ -20293,9 +21961,9 @@ function AdminLayout({
20293
21961
  }
20294
21962
 
20295
21963
  // src/layout/basic/BlankLayout.tsx
20296
- var import_jsx_runtime224 = require("react/jsx-runtime");
21964
+ var import_jsx_runtime235 = require("react/jsx-runtime");
20297
21965
  function BlankLayout({ children }) {
20298
- return /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
21966
+ return /* @__PURE__ */ (0, import_jsx_runtime235.jsx)(
20299
21967
  "div",
20300
21968
  {
20301
21969
  "data-slot": "blank-layout",
@@ -20307,8 +21975,8 @@ function BlankLayout({ children }) {
20307
21975
 
20308
21976
  // src/layout/chat/ChatLayout.tsx
20309
21977
  var import_permission2 = require("@pactor-app/permission");
20310
- var import_react81 = require("react");
20311
- var import_jsx_runtime225 = require("react/jsx-runtime");
21978
+ var import_react87 = require("react");
21979
+ var import_jsx_runtime236 = require("react/jsx-runtime");
20312
21980
  function ChatLayout({
20313
21981
  brand,
20314
21982
  menu,
@@ -20323,7 +21991,7 @@ function ChatLayout({
20323
21991
  sidebarFooter,
20324
21992
  children
20325
21993
  }) {
20326
- const registryMenus = (0, import_react81.useMemo)(() => {
21994
+ const registryMenus = (0, import_react87.useMemo)(() => {
20327
21995
  if (menu !== void 0 || registry === void 0) {
20328
21996
  return [];
20329
21997
  }
@@ -20332,10 +22000,10 @@ function ChatLayout({
20332
22000
  return visible.flatMap((item) => menuItemToMenuData(item));
20333
22001
  }, [menu, registry, permissionChecker]);
20334
22002
  const menuItems = menu ?? registryMenus;
20335
- const [bridgePath, setBridgePath] = (0, import_react81.useState)(
22003
+ const [bridgePath, setBridgePath] = (0, import_react87.useState)(
20336
22004
  () => bridge?.getLocation().pathname ?? "/"
20337
22005
  );
20338
- (0, import_react81.useEffect)(() => {
22006
+ (0, import_react87.useEffect)(() => {
20339
22007
  if (bridge === void 0) {
20340
22008
  return;
20341
22009
  }
@@ -20343,7 +22011,7 @@ function ChatLayout({
20343
22011
  setBridgePath(location.pathname);
20344
22012
  });
20345
22013
  }, [bridge]);
20346
- const activeKey = (0, import_react81.useMemo)(() => {
22014
+ const activeKey = (0, import_react87.useMemo)(() => {
20347
22015
  if (activeMenuKey !== void 0) {
20348
22016
  return activeMenuKey;
20349
22017
  }
@@ -20363,7 +22031,7 @@ function ChatLayout({
20363
22031
  bridge.push(item.path);
20364
22032
  }
20365
22033
  };
20366
- const sidebarContent = sidebar !== void 0 && sidebar !== null ? sidebar : menuItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime225.jsx)(
22034
+ const sidebarContent = sidebar !== void 0 && sidebar !== null ? sidebar : menuItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime236.jsx)(
20367
22035
  Menu2,
20368
22036
  {
20369
22037
  items: menuItems.map((item) => chatMenuItemToUiMenuItem(item)),
@@ -20371,7 +22039,7 @@ function ChatLayout({
20371
22039
  onSelect: handleSelect
20372
22040
  }
20373
22041
  ) : void 0;
20374
- return /* @__PURE__ */ (0, import_jsx_runtime225.jsx)(
22042
+ return /* @__PURE__ */ (0, import_jsx_runtime236.jsx)(
20375
22043
  Sidebar,
20376
22044
  {
20377
22045
  brand,
@@ -20379,7 +22047,7 @@ function ChatLayout({
20379
22047
  sidebarFooter,
20380
22048
  collapsible,
20381
22049
  locationKey: routeProp?.path ?? bridgePath,
20382
- children: /* @__PURE__ */ (0, import_jsx_runtime225.jsx)(
22050
+ children: /* @__PURE__ */ (0, import_jsx_runtime236.jsx)(
20383
22051
  "div",
20384
22052
  {
20385
22053
  "data-slot": "chat-layout-content",
@@ -20433,26 +22101,26 @@ function menuItemToMenuData(item) {
20433
22101
  }
20434
22102
 
20435
22103
  // src/layout/basic/LoginLayout.tsx
20436
- var import_jsx_runtime226 = require("react/jsx-runtime");
22104
+ var import_jsx_runtime237 = require("react/jsx-runtime");
20437
22105
  function LoginLayout({
20438
22106
  variant = "center",
20439
22107
  brand,
20440
22108
  children
20441
22109
  }) {
20442
- const brandBlock = /* @__PURE__ */ (0, import_jsx_runtime226.jsxs)("div", { "data-slot": "login-brand", className: "flex flex-col items-center gap-2", children: [
22110
+ const brandBlock = /* @__PURE__ */ (0, import_jsx_runtime237.jsxs)("div", { "data-slot": "login-brand", className: "flex flex-col items-center gap-2", children: [
20443
22111
  brand.logo,
20444
- /* @__PURE__ */ (0, import_jsx_runtime226.jsx)("h1", { className: "text-xl font-semibold", children: brand.title }),
20445
- brand.description !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime226.jsx)("div", { className: "text-sm text-muted-foreground", children: brand.description })
22112
+ /* @__PURE__ */ (0, import_jsx_runtime237.jsx)("h1", { className: "text-xl font-semibold", children: brand.title }),
22113
+ brand.description !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime237.jsx)("div", { className: "text-sm text-muted-foreground", children: brand.description })
20446
22114
  ] });
20447
22115
  if (variant === "split") {
20448
- return /* @__PURE__ */ (0, import_jsx_runtime226.jsxs)(
22116
+ return /* @__PURE__ */ (0, import_jsx_runtime237.jsxs)(
20449
22117
  "div",
20450
22118
  {
20451
22119
  "data-slot": "login-layout",
20452
22120
  "data-variant": "split",
20453
22121
  className: "grid min-h-screen grid-cols-2 bg-background text-foreground",
20454
22122
  children: [
20455
- /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(
22123
+ /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(
20456
22124
  "div",
20457
22125
  {
20458
22126
  "data-slot": "login-brand-panel",
@@ -20460,7 +22128,7 @@ function LoginLayout({
20460
22128
  children: brandBlock
20461
22129
  }
20462
22130
  ),
20463
- /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(
22131
+ /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(
20464
22132
  "div",
20465
22133
  {
20466
22134
  "data-slot": "login-form-panel",
@@ -20472,37 +22140,37 @@ function LoginLayout({
20472
22140
  }
20473
22141
  );
20474
22142
  }
20475
- return /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(
22143
+ return /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(
20476
22144
  "div",
20477
22145
  {
20478
22146
  "data-slot": "login-layout",
20479
22147
  "data-variant": "center",
20480
22148
  className: "flex min-h-screen items-center justify-center bg-muted/40 text-foreground",
20481
- children: /* @__PURE__ */ (0, import_jsx_runtime226.jsxs)(Card, { "data-slot": "login-card", className: "w-full max-w-sm gap-4 py-6", children: [
20482
- /* @__PURE__ */ (0, import_jsx_runtime226.jsxs)(CardHeader, { className: "px-6", children: [
20483
- /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(CardTitle, { className: "sr-only", children: brand.title }),
22149
+ children: /* @__PURE__ */ (0, import_jsx_runtime237.jsxs)(Card, { "data-slot": "login-card", className: "w-full max-w-sm gap-4 py-6", children: [
22150
+ /* @__PURE__ */ (0, import_jsx_runtime237.jsxs)(CardHeader, { className: "px-6", children: [
22151
+ /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(CardTitle, { className: "sr-only", children: brand.title }),
20484
22152
  brandBlock
20485
22153
  ] }),
20486
- /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(CardContent, { className: "flex flex-col gap-4 px-6", children })
22154
+ /* @__PURE__ */ (0, import_jsx_runtime237.jsx)(CardContent, { className: "flex flex-col gap-4 px-6", children })
20487
22155
  ] })
20488
22156
  }
20489
22157
  );
20490
22158
  }
20491
22159
 
20492
22160
  // src/layout/basic/LandingLayout.tsx
20493
- var import_jsx_runtime227 = require("react/jsx-runtime");
22161
+ var import_jsx_runtime238 = require("react/jsx-runtime");
20494
22162
  function LandingLayout({
20495
22163
  navbar,
20496
22164
  footer,
20497
22165
  children
20498
22166
  }) {
20499
- return /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)(
22167
+ return /* @__PURE__ */ (0, import_jsx_runtime238.jsxs)(
20500
22168
  "div",
20501
22169
  {
20502
22170
  "data-slot": "landing-layout",
20503
22171
  className: "flex min-h-screen flex-col bg-background text-foreground",
20504
22172
  children: [
20505
- navbar !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
22173
+ navbar !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime238.jsx)(
20506
22174
  "header",
20507
22175
  {
20508
22176
  "data-slot": "landing-navbar",
@@ -20510,8 +22178,8 @@ function LandingLayout({
20510
22178
  children: navbar
20511
22179
  }
20512
22180
  ),
20513
- /* @__PURE__ */ (0, import_jsx_runtime227.jsx)("main", { "data-slot": "landing-content", className: "flex-1", children }),
20514
- footer !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
22181
+ /* @__PURE__ */ (0, import_jsx_runtime238.jsx)("main", { "data-slot": "landing-content", className: "flex-1", children }),
22182
+ footer !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime238.jsx)(
20515
22183
  "footer",
20516
22184
  {
20517
22185
  "data-slot": "landing-footer",
@@ -20638,7 +22306,7 @@ var OverlayManager = class {
20638
22306
  };
20639
22307
 
20640
22308
  // src/interaction/actions.ts
20641
- var import_runtime55 = require("@pactor-app/runtime");
22309
+ var import_runtime56 = require("@pactor-app/runtime");
20642
22310
  function createUiBridge() {
20643
22311
  return {};
20644
22312
  }
@@ -20654,7 +22322,7 @@ function registerInteractionActions(actions, manager, ui) {
20654
22322
  return failure("[pactor-interaction] overlay.open \u7F3A\u5C11 overlay \u914D\u7F6E\u53C2\u6570");
20655
22323
  }
20656
22324
  const { content, ...rest } = overlay;
20657
- const resolved = (0, import_runtime55.resolveDeep)(rest, ctx.scope);
22325
+ const resolved = (0, import_runtime56.resolveDeep)(rest, ctx.scope);
20658
22326
  const config = { ...resolved, content };
20659
22327
  const data = await manager.open(config, {
20660
22328
  parentScope: { ...ctx.scope }
@@ -20717,10 +22385,10 @@ function isRecord(value) {
20717
22385
  }
20718
22386
 
20719
22387
  // src/interaction/provider.tsx
20720
- var import_runtime56 = require("@pactor-app/runtime");
20721
- var import_react82 = require("react");
22388
+ var import_runtime57 = require("@pactor-app/runtime");
22389
+ var import_react88 = require("react");
20722
22390
  var import_react_dom2 = require("react-dom");
20723
- var import_jsx_runtime228 = require("react/jsx-runtime");
22391
+ var import_jsx_runtime239 = require("react/jsx-runtime");
20724
22392
  var TOAST_DURATION = 3e3;
20725
22393
  var toastTypeClass = {
20726
22394
  success: "border-l-4 border-l-success",
@@ -20732,11 +22400,11 @@ function InteractionProvider({
20732
22400
  bridge,
20733
22401
  children
20734
22402
  }) {
20735
- const [confirmState, setConfirmState] = (0, import_react82.useState)(null);
20736
- const [confirmOpen, setConfirmOpen] = (0, import_react82.useState)(false);
20737
- const [toasts, setToasts] = (0, import_react82.useState)([]);
20738
- const { t } = (0, import_runtime56.useI18n)();
20739
- const { modal, message } = (0, import_react82.useMemo)(() => {
22403
+ const [confirmState, setConfirmState] = (0, import_react88.useState)(null);
22404
+ const [confirmOpen, setConfirmOpen] = (0, import_react88.useState)(false);
22405
+ const [toasts, setToasts] = (0, import_react88.useState)([]);
22406
+ const { t } = (0, import_runtime57.useI18n)();
22407
+ const { modal, message } = (0, import_react88.useMemo)(() => {
20740
22408
  const pushToast = (type, content) => {
20741
22409
  const id = Date.now() + Math.random();
20742
22410
  setToasts((prev) => [...prev, { id, type, content }]);
@@ -20758,7 +22426,7 @@ function InteractionProvider({
20758
22426
  };
20759
22427
  return { modal: modalImpl, message: messageImpl };
20760
22428
  }, []);
20761
- (0, import_react82.useEffect)(() => {
22429
+ (0, import_react88.useEffect)(() => {
20762
22430
  bridge.modal = modal;
20763
22431
  bridge.message = message;
20764
22432
  return () => {
@@ -20776,11 +22444,11 @@ function InteractionProvider({
20776
22444
  setConfirmOpen(false);
20777
22445
  state?.onCancel?.();
20778
22446
  };
20779
- return /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(import_jsx_runtime228.Fragment, { children: [
22447
+ return /* @__PURE__ */ (0, import_jsx_runtime239.jsxs)(import_jsx_runtime239.Fragment, { children: [
20780
22448
  children,
20781
22449
  typeof document !== "undefined" && (0, import_react_dom2.createPortal)(
20782
- /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(import_jsx_runtime228.Fragment, { children: [
20783
- /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
22450
+ /* @__PURE__ */ (0, import_jsx_runtime239.jsxs)(import_jsx_runtime239.Fragment, { children: [
22451
+ /* @__PURE__ */ (0, import_jsx_runtime239.jsx)(
20784
22452
  Dialog,
20785
22453
  {
20786
22454
  open: confirmOpen,
@@ -20794,29 +22462,29 @@ function InteractionProvider({
20794
22462
  setConfirmState(null);
20795
22463
  }
20796
22464
  },
20797
- children: /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(DialogContent, { "data-slot": "confirm-dialog", className: "sm:max-w-sm", children: [
20798
- /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(DialogHeader, { children: [
20799
- /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(DialogTitle, { children: confirmState?.title ?? "" }),
20800
- confirmState?.content !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
22465
+ children: /* @__PURE__ */ (0, import_jsx_runtime239.jsxs)(DialogContent, { "data-slot": "confirm-dialog", className: "sm:max-w-sm", children: [
22466
+ /* @__PURE__ */ (0, import_jsx_runtime239.jsxs)(DialogHeader, { children: [
22467
+ /* @__PURE__ */ (0, import_jsx_runtime239.jsx)(DialogTitle, { children: confirmState?.title ?? "" }),
22468
+ confirmState?.content !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime239.jsx)(
20801
22469
  DialogDescription,
20802
22470
  {
20803
- render: /* @__PURE__ */ (0, import_jsx_runtime228.jsx)("div", { children: confirmState.content })
22471
+ render: /* @__PURE__ */ (0, import_jsx_runtime239.jsx)("div", { children: confirmState.content })
20804
22472
  }
20805
22473
  )
20806
22474
  ] }),
20807
- /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(DialogFooter, { children: [
20808
- /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Button, { type: "button", variant: "outline", onClick: handleCancel, children: t("pactor.alertDialog.cancel") }),
20809
- /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Button, { type: "button", onClick: handleOk, children: t("pactor.alertDialog.confirm") })
22475
+ /* @__PURE__ */ (0, import_jsx_runtime239.jsxs)(DialogFooter, { children: [
22476
+ /* @__PURE__ */ (0, import_jsx_runtime239.jsx)(Button, { type: "button", variant: "outline", onClick: handleCancel, children: t("pactor.alertDialog.cancel") }),
22477
+ /* @__PURE__ */ (0, import_jsx_runtime239.jsx)(Button, { type: "button", onClick: handleOk, children: t("pactor.alertDialog.confirm") })
20810
22478
  ] })
20811
22479
  ] })
20812
22480
  }
20813
22481
  ),
20814
- toasts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
22482
+ toasts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime239.jsx)(
20815
22483
  "div",
20816
22484
  {
20817
22485
  "data-slot": "toast-container",
20818
22486
  className: "fixed top-4 right-4 z-[100] flex w-80 flex-col gap-2",
20819
- children: toasts.map((toast2) => /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
22487
+ children: toasts.map((toast2) => /* @__PURE__ */ (0, import_jsx_runtime239.jsx)(
20820
22488
  "div",
20821
22489
  {
20822
22490
  "data-slot": "toast",
@@ -20840,9 +22508,9 @@ function InteractionProvider({
20840
22508
 
20841
22509
  // src/interaction/host.tsx
20842
22510
  var import_lucide_react44 = require("lucide-react");
20843
- var import_runtime57 = require("@pactor-app/runtime");
20844
- var import_react83 = require("react");
20845
- var import_jsx_runtime229 = require("react/jsx-runtime");
22511
+ var import_runtime58 = require("@pactor-app/runtime");
22512
+ var import_react89 = require("react");
22513
+ var import_jsx_runtime240 = require("react/jsx-runtime");
20846
22514
  function toCssWidth(width) {
20847
22515
  if (width === void 0) {
20848
22516
  return void 0;
@@ -20850,12 +22518,12 @@ function toCssWidth(width) {
20850
22518
  return typeof width === "number" ? `${width}px` : width;
20851
22519
  }
20852
22520
  function OverlayHost({ manager, resolvePage }) {
20853
- const renderer = (0, import_runtime57.useRenderer)();
20854
- const stack = (0, import_react83.useSyncExternalStore)(
22521
+ const renderer = (0, import_runtime58.useRenderer)();
22522
+ const stack = (0, import_react89.useSyncExternalStore)(
20855
22523
  (onChange) => manager.subscribe(onChange),
20856
22524
  () => manager.stack()
20857
22525
  );
20858
- (0, import_react83.useSyncExternalStore)(
22526
+ (0, import_react89.useSyncExternalStore)(
20859
22527
  (onChange) => {
20860
22528
  const offState = renderer.context.state.subscribe(onChange);
20861
22529
  const offData = renderer.context.data.subscribe(onChange);
@@ -20866,7 +22534,7 @@ function OverlayHost({ manager, resolvePage }) {
20866
22534
  },
20867
22535
  () => `${renderer.context.state.getVersion()}:${renderer.context.data.getVersion()}`
20868
22536
  );
20869
- return /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(import_jsx_runtime229.Fragment, { children: stack.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(
22537
+ return /* @__PURE__ */ (0, import_jsx_runtime240.jsx)(import_jsx_runtime240.Fragment, { children: stack.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime240.jsx)(
20870
22538
  OverlayEntryView,
20871
22539
  {
20872
22540
  entry,
@@ -20883,7 +22551,7 @@ function OverlayEntryView({
20883
22551
  renderer,
20884
22552
  resolvePage
20885
22553
  }) {
20886
- const { t } = (0, import_runtime57.useI18n)();
22554
+ const { t } = (0, import_runtime58.useI18n)();
20887
22555
  const handleCancel = () => manager.close(entry.id);
20888
22556
  let body = null;
20889
22557
  if (entry.content) {
@@ -20892,7 +22560,7 @@ function OverlayEntryView({
20892
22560
  parent: manager.parentScopeOf(entry.id)
20893
22561
  });
20894
22562
  } else if (entry.page) {
20895
- body = /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(
22563
+ body = /* @__PURE__ */ (0, import_jsx_runtime240.jsx)(
20896
22564
  PageOverlayBody,
20897
22565
  {
20898
22566
  entry,
@@ -20902,9 +22570,9 @@ function OverlayEntryView({
20902
22570
  );
20903
22571
  }
20904
22572
  if (entry.type === "drawer") {
20905
- return /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(ShadcnDrawerView, { entry, onCancel: handleCancel, children: body });
22573
+ return /* @__PURE__ */ (0, import_jsx_runtime240.jsx)(ShadcnDrawerView, { entry, onCancel: handleCancel, children: body });
20906
22574
  }
20907
- return /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(
22575
+ return /* @__PURE__ */ (0, import_jsx_runtime240.jsx)(
20908
22576
  Dialog,
20909
22577
  {
20910
22578
  open: true,
@@ -20913,7 +22581,7 @@ function OverlayEntryView({
20913
22581
  handleCancel();
20914
22582
  }
20915
22583
  },
20916
- children: /* @__PURE__ */ (0, import_jsx_runtime229.jsxs)(
22584
+ children: /* @__PURE__ */ (0, import_jsx_runtime240.jsxs)(
20917
22585
  DialogContent,
20918
22586
  {
20919
22587
  "data-slot": "overlay-modal",
@@ -20921,25 +22589,25 @@ function OverlayEntryView({
20921
22589
  style: entry.width === void 0 ? void 0 : { width: toCssWidth(entry.width) },
20922
22590
  showCloseButton: false,
20923
22591
  children: [
20924
- /* @__PURE__ */ (0, import_jsx_runtime229.jsxs)(DialogHeader, { children: [
20925
- /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(DialogTitle, { children: entry.title ?? "" }),
20926
- /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(
22592
+ /* @__PURE__ */ (0, import_jsx_runtime240.jsxs)(DialogHeader, { children: [
22593
+ /* @__PURE__ */ (0, import_jsx_runtime240.jsx)(DialogTitle, { children: entry.title ?? "" }),
22594
+ /* @__PURE__ */ (0, import_jsx_runtime240.jsx)(
20927
22595
  DialogClose,
20928
22596
  {
20929
- render: /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(
22597
+ render: /* @__PURE__ */ (0, import_jsx_runtime240.jsx)(
20930
22598
  "button",
20931
22599
  {
20932
22600
  type: "button",
20933
22601
  "data-slot": "overlay-modal-close",
20934
22602
  "aria-label": t("pactor.overlay.close"),
20935
22603
  className: "absolute top-4 right-4 cursor-pointer rounded-xs opacity-70 transition-opacity hover:opacity-100 focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-none",
20936
- children: /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(import_lucide_react44.XIcon, { className: "size-4" })
22604
+ children: /* @__PURE__ */ (0, import_jsx_runtime240.jsx)(import_lucide_react44.XIcon, { className: "size-4" })
20937
22605
  }
20938
22606
  )
20939
22607
  }
20940
22608
  )
20941
22609
  ] }),
20942
- /* @__PURE__ */ (0, import_jsx_runtime229.jsx)("div", { "data-slot": "overlay-modal-body", children: body })
22610
+ /* @__PURE__ */ (0, import_jsx_runtime240.jsx)("div", { "data-slot": "overlay-modal-body", children: body })
20943
22611
  ]
20944
22612
  }
20945
22613
  )
@@ -20951,9 +22619,9 @@ function ShadcnDrawerView({
20951
22619
  onCancel,
20952
22620
  children
20953
22621
  }) {
20954
- const { t } = (0, import_runtime57.useI18n)();
22622
+ const { t } = (0, import_runtime58.useI18n)();
20955
22623
  const panelStyle = entry.width === void 0 ? void 0 : { width: toCssWidth(entry.width), maxWidth: toCssWidth(entry.width) };
20956
- return /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(
22624
+ return /* @__PURE__ */ (0, import_jsx_runtime240.jsx)(
20957
22625
  Drawer,
20958
22626
  {
20959
22627
  direction: "right",
@@ -20964,7 +22632,7 @@ function ShadcnDrawerView({
20964
22632
  onCancel();
20965
22633
  }
20966
22634
  },
20967
- children: /* @__PURE__ */ (0, import_jsx_runtime229.jsxs)(
22635
+ children: /* @__PURE__ */ (0, import_jsx_runtime240.jsxs)(
20968
22636
  DrawerContent,
20969
22637
  {
20970
22638
  "data-slot": "drawer-panel",
@@ -20972,27 +22640,27 @@ function ShadcnDrawerView({
20972
22640
  style: panelStyle,
20973
22641
  overlayProps: { onPointerDown: onCancel },
20974
22642
  children: [
20975
- /* @__PURE__ */ (0, import_jsx_runtime229.jsxs)(
22643
+ /* @__PURE__ */ (0, import_jsx_runtime240.jsxs)(
20976
22644
  DrawerHeader,
20977
22645
  {
20978
22646
  "data-slot": "drawer-header",
20979
22647
  className: "flex flex-row items-center justify-between border-b border-border px-6 py-4",
20980
22648
  children: [
20981
- /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(DrawerTitle, { className: "text-lg", children: entry.title ?? "" }),
20982
- /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(DrawerClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(
22649
+ /* @__PURE__ */ (0, import_jsx_runtime240.jsx)(DrawerTitle, { className: "text-lg", children: entry.title ?? "" }),
22650
+ /* @__PURE__ */ (0, import_jsx_runtime240.jsx)(DrawerClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime240.jsx)(
20983
22651
  "button",
20984
22652
  {
20985
22653
  type: "button",
20986
22654
  "data-slot": "drawer-close",
20987
22655
  "aria-label": t("pactor.overlay.close"),
20988
22656
  className: "cursor-pointer rounded-xs opacity-70 transition-opacity hover:opacity-100 focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-none",
20989
- children: /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(import_lucide_react44.XIcon, { className: "size-4" })
22657
+ children: /* @__PURE__ */ (0, import_jsx_runtime240.jsx)(import_lucide_react44.XIcon, { className: "size-4" })
20990
22658
  }
20991
22659
  ) })
20992
22660
  ]
20993
22661
  }
20994
22662
  ),
20995
- /* @__PURE__ */ (0, import_jsx_runtime229.jsx)("div", { "data-slot": "drawer-body", className: "flex-1 overflow-auto p-6", children })
22663
+ /* @__PURE__ */ (0, import_jsx_runtime240.jsx)("div", { "data-slot": "drawer-body", className: "flex-1 overflow-auto p-6", children })
20996
22664
  ]
20997
22665
  }
20998
22666
  )
@@ -21004,9 +22672,9 @@ function PageOverlayBody({
21004
22672
  renderer,
21005
22673
  resolvePage
21006
22674
  }) {
21007
- const [child, setChild] = (0, import_react83.useState)(null);
21008
- const [error, setError] = (0, import_react83.useState)(null);
21009
- (0, import_react83.useEffect)(() => {
22675
+ const [child, setChild] = (0, import_react89.useState)(null);
22676
+ const [error, setError] = (0, import_react89.useState)(null);
22677
+ (0, import_react89.useEffect)(() => {
21010
22678
  if (!resolvePage) {
21011
22679
  setError(
21012
22680
  new Error(
@@ -21024,7 +22692,7 @@ function PageOverlayBody({
21024
22692
  return;
21025
22693
  }
21026
22694
  const host = renderer.context;
21027
- created = (0, import_runtime57.createPageRuntime)(pageDsl, {
22695
+ created = (0, import_runtime58.createPageRuntime)(pageDsl, {
21028
22696
  app: host.app,
21029
22697
  user: host.user,
21030
22698
  components: host.components,
@@ -21048,12 +22716,12 @@ function PageOverlayBody({
21048
22716
  };
21049
22717
  }, [entry.id]);
21050
22718
  if (error) {
21051
- return /* @__PURE__ */ (0, import_jsx_runtime229.jsx)("div", { role: "alert", children: error.message });
22719
+ return /* @__PURE__ */ (0, import_jsx_runtime240.jsx)("div", { role: "alert", children: error.message });
21052
22720
  }
21053
22721
  if (!child) {
21054
22722
  return null;
21055
22723
  }
21056
- return /* @__PURE__ */ (0, import_jsx_runtime229.jsx)(import_runtime57.PageRuntimeView, { runtime: child });
22724
+ return /* @__PURE__ */ (0, import_jsx_runtime240.jsx)(import_runtime58.PageRuntimeView, { runtime: child });
21057
22725
  }
21058
22726
  // Annotate the CommonJS export names for ESM import in node:
21059
22727
  0 && (module.exports = {
@@ -21184,6 +22852,7 @@ function PageOverlayBody({
21184
22852
  RadioGroup,
21185
22853
  RailTooltip,
21186
22854
  Rate,
22855
+ RecordingPage,
21187
22856
  Resizable,
21188
22857
  Result,
21189
22858
  RichText,