@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/{chunk-IBMIQXOM.js → chunk-7OBUSV5S.js} +1 -1
- package/dist/{chunk-XRPL536L.js → chunk-H6E53JL2.js} +2 -2
- package/dist/{chunk-ZUXZRBCR.js → chunk-HKQMSEQB.js} +1910 -247
- package/dist/{chunk-F5JY3PBE.js → chunk-HU2RFIWH.js} +1 -1
- package/dist/{chunk-PWXXEJ4J.js → chunk-QIOYKSN4.js} +11 -2
- package/dist/{chunk-XMWIT53K.js → chunk-T3TGKYAB.js} +2 -2
- package/dist/{chunk-HAOAXDTW.js → chunk-YVHPJHW3.js} +1 -1
- package/dist/components/index.cjs +1917 -248
- package/dist/components/index.d.cts +533 -2
- package/dist/components/index.d.ts +533 -2
- package/dist/components/index.js +7 -5
- package/dist/index.cjs +2100 -431
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -7
- package/dist/interaction/index.cjs +1 -1
- package/dist/interaction/index.js +2 -2
- package/dist/layout/index.cjs +7 -2
- package/dist/layout/index.js +3 -3
- package/dist/ui/index.cjs +3 -3
- package/dist/ui/index.js +3 -3
- package/package.json +6 -6
- package/styles.css +17 -2
|
@@ -148,6 +148,7 @@ __export(components_exports, {
|
|
|
148
148
|
RadioGroup: () => RadioGroup2,
|
|
149
149
|
RailTooltip: () => RailTooltip,
|
|
150
150
|
Rate: () => Rate,
|
|
151
|
+
RecordingPage: () => RecordingPage,
|
|
151
152
|
Resizable: () => Resizable,
|
|
152
153
|
Result: () => Result,
|
|
153
154
|
RichText: () => RichText,
|
|
@@ -540,7 +541,12 @@ var ICONS = {
|
|
|
540
541
|
"zoom-in": import_lucide_react2.ZoomIn,
|
|
541
542
|
"zoom-out": import_lucide_react2.ZoomOut,
|
|
542
543
|
video: import_lucide_react2.Video,
|
|
543
|
-
music: import_lucide_react2.Music
|
|
544
|
+
music: import_lucide_react2.Music,
|
|
545
|
+
// 录音 / 音频场景(spec: chat-page 录音模板):波形、麦克风、播放控制
|
|
546
|
+
"audio-lines": import_lucide_react2.AudioLines,
|
|
547
|
+
mic: import_lucide_react2.Mic,
|
|
548
|
+
play: import_lucide_react2.Play,
|
|
549
|
+
"rotate-cw": import_lucide_react2.RotateCw
|
|
544
550
|
};
|
|
545
551
|
function normalizeIconName(name) {
|
|
546
552
|
return name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[_\s]+/g, "-").toLowerCase();
|
|
@@ -718,7 +724,7 @@ function AlertDialogOverlay({
|
|
|
718
724
|
{
|
|
719
725
|
"data-slot": "alert-dialog-overlay",
|
|
720
726
|
className: cn(
|
|
721
|
-
"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",
|
|
727
|
+
"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",
|
|
722
728
|
className
|
|
723
729
|
),
|
|
724
730
|
...props
|
|
@@ -4152,7 +4158,7 @@ function DialogOverlay({
|
|
|
4152
4158
|
{
|
|
4153
4159
|
"data-slot": "dialog-overlay",
|
|
4154
4160
|
className: cn(
|
|
4155
|
-
"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",
|
|
4161
|
+
"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",
|
|
4156
4162
|
className
|
|
4157
4163
|
),
|
|
4158
4164
|
...props
|
|
@@ -7053,7 +7059,7 @@ function SheetOverlay({
|
|
|
7053
7059
|
{
|
|
7054
7060
|
"data-slot": "sheet-overlay",
|
|
7055
7061
|
className: cn(
|
|
7056
|
-
"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",
|
|
7062
|
+
"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",
|
|
7057
7063
|
className
|
|
7058
7064
|
),
|
|
7059
7065
|
...props
|
|
@@ -14920,6 +14926,7 @@ function ChatPage({
|
|
|
14920
14926
|
artifactOpen,
|
|
14921
14927
|
defaultArtifactOpen = false,
|
|
14922
14928
|
onArtifactOpenChange,
|
|
14929
|
+
content,
|
|
14923
14930
|
className,
|
|
14924
14931
|
style
|
|
14925
14932
|
}) {
|
|
@@ -15173,7 +15180,7 @@ function ChatPage({
|
|
|
15173
15180
|
"div",
|
|
15174
15181
|
{
|
|
15175
15182
|
"data-slot": "chat-page-menu",
|
|
15176
|
-
className: "flex h-full w-[
|
|
15183
|
+
className: "flex h-full w-[250px] shrink-0 flex-col gap-2 overflow-hidden border-r border-border px-2 py-3",
|
|
15177
15184
|
children: [
|
|
15178
15185
|
brand ? /* @__PURE__ */ (0, import_jsx_runtime191.jsxs)("div", { className: "flex shrink-0 items-center justify-between px-2", children: [
|
|
15179
15186
|
/* @__PURE__ */ (0, import_jsx_runtime191.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
|
|
@@ -15256,7 +15263,7 @@ function ChatPage({
|
|
|
15256
15263
|
]
|
|
15257
15264
|
}
|
|
15258
15265
|
),
|
|
15259
|
-
/* @__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: [
|
|
15266
|
+
/* @__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: [
|
|
15260
15267
|
/* @__PURE__ */ (0, import_jsx_runtime191.jsx)(Panel, { defaultSize: "62%", children: chatArea }),
|
|
15261
15268
|
/* @__PURE__ */ (0, import_jsx_runtime191.jsx)(ResizableHandle, { withHandle: true }),
|
|
15262
15269
|
/* @__PURE__ */ (0, import_jsx_runtime191.jsx)(Panel, { defaultSize: "38%", minSize: "380px", maxSize: "760px", children: activePanelItem ? /* @__PURE__ */ (0, import_jsx_runtime191.jsx)(
|
|
@@ -18432,196 +18439,1856 @@ function Login({
|
|
|
18432
18439
|
);
|
|
18433
18440
|
}
|
|
18434
18441
|
|
|
18435
|
-
// src/components/business/
|
|
18436
|
-
var
|
|
18442
|
+
// src/components/business/RecordingPage/index.tsx
|
|
18443
|
+
var import_react81 = require("react");
|
|
18444
|
+
|
|
18445
|
+
// src/components/business/RecordingPage/detail.tsx
|
|
18446
|
+
var import_runtime54 = require("@pactor-app/runtime");
|
|
18447
|
+
var import_react79 = require("react");
|
|
18448
|
+
|
|
18449
|
+
// src/components/business/RecordingPage/insight.tsx
|
|
18437
18450
|
var import_react76 = require("react");
|
|
18451
|
+
|
|
18452
|
+
// src/components/business/RecordingPage/perspective-dialog.tsx
|
|
18438
18453
|
var import_jsx_runtime219 = require("react/jsx-runtime");
|
|
18439
|
-
|
|
18440
|
-
|
|
18441
|
-
|
|
18442
|
-
|
|
18443
|
-
|
|
18444
|
-
|
|
18445
|
-
|
|
18446
|
-
|
|
18447
|
-
|
|
18448
|
-
|
|
18449
|
-
|
|
18450
|
-
|
|
18451
|
-
|
|
18452
|
-
|
|
18453
|
-
|
|
18454
|
-
|
|
18454
|
+
function RecordingPerspectiveDialog({
|
|
18455
|
+
open,
|
|
18456
|
+
title,
|
|
18457
|
+
hint,
|
|
18458
|
+
value,
|
|
18459
|
+
placeholder,
|
|
18460
|
+
cancelLabel,
|
|
18461
|
+
confirmLabel,
|
|
18462
|
+
onChange,
|
|
18463
|
+
onCancel,
|
|
18464
|
+
onConfirm
|
|
18465
|
+
}) {
|
|
18466
|
+
return /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
|
|
18467
|
+
Dialog,
|
|
18468
|
+
{
|
|
18469
|
+
open,
|
|
18470
|
+
onOpenChange: (next) => {
|
|
18471
|
+
if (!next) onCancel();
|
|
18472
|
+
},
|
|
18473
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)(
|
|
18474
|
+
DialogContent,
|
|
18475
|
+
{
|
|
18476
|
+
"data-slot": "recording-perspective-dialog",
|
|
18477
|
+
className: "gap-4 sm:max-w-xl",
|
|
18478
|
+
children: [
|
|
18479
|
+
/* @__PURE__ */ (0, import_jsx_runtime219.jsx)(DialogTitle, { children: title }),
|
|
18480
|
+
hint !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime219.jsx)(DialogDescription, { children: hint }) : null,
|
|
18481
|
+
/* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
|
|
18482
|
+
Textarea2,
|
|
18483
|
+
{
|
|
18484
|
+
value,
|
|
18485
|
+
placeholder,
|
|
18486
|
+
rows: 4,
|
|
18487
|
+
onChange
|
|
18488
|
+
}
|
|
18489
|
+
),
|
|
18490
|
+
/* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("div", { className: "flex items-center justify-end gap-2", children: [
|
|
18491
|
+
/* @__PURE__ */ (0, import_jsx_runtime219.jsx)(Button2, { text: cancelLabel, onClick: onCancel }),
|
|
18492
|
+
/* @__PURE__ */ (0, import_jsx_runtime219.jsx)(Button2, { text: confirmLabel, variant: "primary", onClick: onConfirm })
|
|
18493
|
+
] })
|
|
18494
|
+
]
|
|
18495
|
+
}
|
|
18496
|
+
)
|
|
18497
|
+
}
|
|
18498
|
+
);
|
|
18455
18499
|
}
|
|
18456
|
-
|
|
18457
|
-
|
|
18458
|
-
|
|
18459
|
-
|
|
18460
|
-
|
|
18461
|
-
|
|
18462
|
-
|
|
18463
|
-
|
|
18464
|
-
|
|
18465
|
-
|
|
18466
|
-
|
|
18467
|
-
|
|
18468
|
-
|
|
18469
|
-
|
|
18470
|
-
|
|
18471
|
-
|
|
18472
|
-
|
|
18473
|
-
|
|
18474
|
-
|
|
18475
|
-
|
|
18476
|
-
|
|
18477
|
-
|
|
18478
|
-
|
|
18479
|
-
|
|
18480
|
-
|
|
18481
|
-
|
|
18482
|
-
|
|
18483
|
-
|
|
18484
|
-
|
|
18485
|
-
|
|
18486
|
-
|
|
18487
|
-
|
|
18488
|
-
|
|
18489
|
-
|
|
18490
|
-
|
|
18491
|
-
|
|
18492
|
-
|
|
18493
|
-
|
|
18494
|
-
|
|
18495
|
-
|
|
18496
|
-
|
|
18500
|
+
|
|
18501
|
+
// src/components/business/RecordingPage/insight.tsx
|
|
18502
|
+
var import_jsx_runtime220 = require("react/jsx-runtime");
|
|
18503
|
+
function RecordingInsightView({
|
|
18504
|
+
insight,
|
|
18505
|
+
onPerspectiveEdit,
|
|
18506
|
+
onPerspectiveApply,
|
|
18507
|
+
onInsightAction
|
|
18508
|
+
}) {
|
|
18509
|
+
const [dialogOpen, setDialogOpen] = (0, import_react76.useState)(false);
|
|
18510
|
+
const inputControlled = insight.perspectiveInput !== void 0;
|
|
18511
|
+
const [innerInput, setInnerInput] = (0, import_react76.useState)(insight.defaultPerspectiveInput);
|
|
18512
|
+
const committedInput = inputControlled ? insight.perspectiveInput : innerInput;
|
|
18513
|
+
const [draftInput, setDraftInput] = (0, import_react76.useState)(committedInput);
|
|
18514
|
+
const openDialog = () => {
|
|
18515
|
+
setDraftInput(committedInput);
|
|
18516
|
+
setDialogOpen(true);
|
|
18517
|
+
};
|
|
18518
|
+
const confirmDialog = () => {
|
|
18519
|
+
if (!inputControlled) setInnerInput(draftInput);
|
|
18520
|
+
onPerspectiveApply?.(draftInput ?? "");
|
|
18521
|
+
setDialogOpen(false);
|
|
18522
|
+
};
|
|
18523
|
+
return /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("div", { "data-slot": "recording-insight", className: "flex flex-col gap-6", children: [
|
|
18524
|
+
insight.perspectiveTitle !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)(
|
|
18525
|
+
"section",
|
|
18526
|
+
{
|
|
18527
|
+
"data-slot": "recording-insight-perspective",
|
|
18528
|
+
className: "flex flex-col gap-2 rounded-lg bg-success/10 p-4",
|
|
18529
|
+
children: [
|
|
18530
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
18531
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
18532
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Icon, { name: "user", size: 16, className: "shrink-0 text-muted-foreground" }),
|
|
18533
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: insight.perspectiveTitle, strong: true, className: "truncate" })
|
|
18534
|
+
] }),
|
|
18535
|
+
insight.perspectiveActionLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(
|
|
18536
|
+
Button2,
|
|
18537
|
+
{
|
|
18538
|
+
text: insight.perspectiveActionLabel,
|
|
18539
|
+
variant: "link",
|
|
18540
|
+
size: "small",
|
|
18541
|
+
className: "text-success",
|
|
18542
|
+
onClick: () => {
|
|
18543
|
+
onPerspectiveEdit?.();
|
|
18544
|
+
openDialog();
|
|
18545
|
+
}
|
|
18546
|
+
}
|
|
18547
|
+
) : null
|
|
18548
|
+
] }),
|
|
18549
|
+
insight.perspectiveHint !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: insight.perspectiveHint, size: "small", type: "secondary" }) : null
|
|
18550
|
+
]
|
|
18551
|
+
}
|
|
18552
|
+
) : null,
|
|
18553
|
+
insight.basics !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("section", { className: "flex flex-col gap-3", children: [
|
|
18554
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: insight.basicsTitle ?? "\u57FA\u7840\u4FE1\u606F", strong: true, size: "large" }),
|
|
18555
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: insight.basics })
|
|
18556
|
+
] }) : null,
|
|
18557
|
+
insight.chapters !== void 0 && insight.chapters.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("section", { className: "flex flex-col gap-3", children: [
|
|
18558
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: insight.chaptersTitle ?? "\u7AE0\u8282\u901F\u89C8\u4E0E\u89E3\u8BFB", strong: true, size: "large" }),
|
|
18559
|
+
insight.chapters.map((chapter, index) => /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)(
|
|
18560
|
+
"div",
|
|
18561
|
+
{
|
|
18562
|
+
"data-slot": "recording-insight-chapter",
|
|
18563
|
+
className: "flex flex-col gap-2 rounded-lg border border-border p-4",
|
|
18564
|
+
children: [
|
|
18565
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("div", { className: "flex items-baseline gap-2", children: [
|
|
18566
|
+
chapter.time !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: chapter.time, size: "small", type: "secondary" }) : null,
|
|
18567
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: chapter.title, strong: true, size: "small" })
|
|
18568
|
+
] }),
|
|
18569
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: chapter.content, size: "small" })
|
|
18570
|
+
]
|
|
18571
|
+
},
|
|
18572
|
+
chapter.time ?? index
|
|
18573
|
+
))
|
|
18574
|
+
] }) : null,
|
|
18575
|
+
insight.viewpoints !== void 0 && insight.viewpoints.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("section", { className: "flex flex-col gap-3", children: [
|
|
18576
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: insight.viewpointsTitle ?? "\u89C2\u70B9\u5206\u6790", strong: true, size: "large" }),
|
|
18577
|
+
insight.viewpoints.map((viewpoint, index) => /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)(
|
|
18578
|
+
"div",
|
|
18579
|
+
{
|
|
18580
|
+
"data-slot": "recording-insight-viewpoint",
|
|
18581
|
+
className: "flex flex-col gap-2 rounded-lg border border-border p-4",
|
|
18582
|
+
children: [
|
|
18583
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
18584
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
18585
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Avatar2, { fallback: viewpoint.avatarText ?? viewpoint.speaker.charAt(0) }),
|
|
18586
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: viewpoint.speaker, strong: true, size: "small" })
|
|
18587
|
+
] }),
|
|
18588
|
+
viewpoint.tag !== "" ? /* @__PURE__ */ (0, import_jsx_runtime220.jsx)(Text, { text: viewpoint.tag ?? "\u81EA\u52A8\u8BC6\u522B", size: "small", type: "secondary" }) : null
|
|
18589
|
+
] }),
|
|
18590
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("p", { className: "text-sm", children: [
|
|
18591
|
+
viewpoint.label !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime220.jsxs)("strong", { children: [
|
|
18592
|
+
viewpoint.label,
|
|
18593
|
+
"\uFF1A"
|
|
18594
|
+
] }) : null,
|
|
18595
|
+
viewpoint.content
|
|
18596
|
+
] })
|
|
18597
|
+
]
|
|
18598
|
+
},
|
|
18599
|
+
viewpoint.speaker ?? index
|
|
18600
|
+
))
|
|
18601
|
+
] }) : null,
|
|
18602
|
+
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)(
|
|
18603
|
+
Button2,
|
|
18604
|
+
{
|
|
18605
|
+
icon: action.icon,
|
|
18606
|
+
variant: "text",
|
|
18607
|
+
size: "small",
|
|
18608
|
+
onClick: () => onInsightAction?.(action.key)
|
|
18609
|
+
},
|
|
18610
|
+
action.key
|
|
18611
|
+
)) }) : null,
|
|
18612
|
+
/* @__PURE__ */ (0, import_jsx_runtime220.jsx)(
|
|
18613
|
+
RecordingPerspectiveDialog,
|
|
18614
|
+
{
|
|
18615
|
+
open: dialogOpen,
|
|
18616
|
+
title: insight.perspectiveDialogTitle ?? "\u4FEE\u6539\u89E3\u8BFB\u8EAB\u4EFD",
|
|
18617
|
+
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",
|
|
18618
|
+
value: draftInput,
|
|
18619
|
+
placeholder: insight.perspectivePlaceholder,
|
|
18620
|
+
cancelLabel: insight.perspectiveCancelLabel ?? "\u53D6\u6D88",
|
|
18621
|
+
confirmLabel: insight.perspectiveConfirmLabel ?? "\u5E94\u7528\u8EAB\u4EFD",
|
|
18622
|
+
onChange: setDraftInput,
|
|
18623
|
+
onCancel: () => setDialogOpen(false),
|
|
18624
|
+
onConfirm: confirmDialog
|
|
18625
|
+
}
|
|
18626
|
+
)
|
|
18627
|
+
] });
|
|
18497
18628
|
}
|
|
18498
|
-
|
|
18499
|
-
|
|
18500
|
-
var
|
|
18501
|
-
function
|
|
18502
|
-
|
|
18503
|
-
|
|
18504
|
-
|
|
18505
|
-
|
|
18506
|
-
|
|
18507
|
-
|
|
18508
|
-
|
|
18629
|
+
|
|
18630
|
+
// src/components/business/RecordingPage/memory.tsx
|
|
18631
|
+
var import_jsx_runtime221 = require("react/jsx-runtime");
|
|
18632
|
+
function RecordingMemoryView({ memory, onMemoryAction }) {
|
|
18633
|
+
return /* @__PURE__ */ (0, import_jsx_runtime221.jsxs)("div", { "data-slot": "recording-memory", className: "flex flex-col gap-6", children: [
|
|
18634
|
+
(memory.groups ?? []).map((group, groupIndex) => /* @__PURE__ */ (0, import_jsx_runtime221.jsxs)("section", { className: "flex flex-col gap-3", children: [
|
|
18635
|
+
/* @__PURE__ */ (0, import_jsx_runtime221.jsx)(Text, { text: `${group.label} \xB7 ${group.items.length}`, strong: true, size: "large" }),
|
|
18636
|
+
group.items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime221.jsxs)(
|
|
18637
|
+
"div",
|
|
18638
|
+
{
|
|
18639
|
+
"data-slot": "recording-memory-item",
|
|
18640
|
+
className: "flex flex-col gap-2 rounded-lg border border-border p-4",
|
|
18641
|
+
children: [
|
|
18642
|
+
/* @__PURE__ */ (0, import_jsx_runtime221.jsx)(Text, { text: item.title, strong: true, size: "small" }),
|
|
18643
|
+
/* @__PURE__ */ (0, import_jsx_runtime221.jsx)(Text, { text: item.content, size: "small" })
|
|
18644
|
+
]
|
|
18645
|
+
},
|
|
18646
|
+
index
|
|
18647
|
+
))
|
|
18648
|
+
] }, group.key ?? group.label ?? groupIndex)),
|
|
18649
|
+
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)(
|
|
18650
|
+
Button2,
|
|
18651
|
+
{
|
|
18652
|
+
icon: action.icon,
|
|
18653
|
+
variant: "text",
|
|
18654
|
+
size: "small",
|
|
18655
|
+
onClick: () => onMemoryAction?.(action.key)
|
|
18656
|
+
},
|
|
18657
|
+
action.key
|
|
18658
|
+
)) }) : null
|
|
18659
|
+
] });
|
|
18509
18660
|
}
|
|
18510
|
-
|
|
18511
|
-
|
|
18512
|
-
|
|
18513
|
-
|
|
18514
|
-
|
|
18515
|
-
|
|
18661
|
+
|
|
18662
|
+
// src/components/business/RecordingPage/share.tsx
|
|
18663
|
+
var import_react77 = require("react");
|
|
18664
|
+
var import_jsx_runtime222 = require("react/jsx-runtime");
|
|
18665
|
+
function copyText(text) {
|
|
18666
|
+
try {
|
|
18667
|
+
if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) {
|
|
18668
|
+
void navigator.clipboard.writeText(text);
|
|
18669
|
+
return;
|
|
18670
|
+
}
|
|
18671
|
+
const textarea = document.createElement("textarea");
|
|
18672
|
+
textarea.value = text;
|
|
18673
|
+
document.body.appendChild(textarea);
|
|
18674
|
+
textarea.select();
|
|
18675
|
+
document.execCommand?.("copy");
|
|
18676
|
+
textarea.remove();
|
|
18677
|
+
} catch {
|
|
18516
18678
|
}
|
|
18517
|
-
if (Array.isArray(value)) return value.join(", ");
|
|
18518
|
-
return String(value);
|
|
18519
18679
|
}
|
|
18520
|
-
function
|
|
18521
|
-
|
|
18522
|
-
|
|
18523
|
-
|
|
18524
|
-
|
|
18525
|
-
|
|
18526
|
-
|
|
18527
|
-
|
|
18528
|
-
|
|
18529
|
-
|
|
18530
|
-
|
|
18531
|
-
|
|
18532
|
-
|
|
18533
|
-
|
|
18534
|
-
|
|
18535
|
-
|
|
18536
|
-
|
|
18537
|
-
|
|
18538
|
-
(0,
|
|
18539
|
-
|
|
18540
|
-
|
|
18541
|
-
|
|
18542
|
-
|
|
18543
|
-
|
|
18544
|
-
|
|
18545
|
-
|
|
18546
|
-
|
|
18547
|
-
},
|
|
18548
|
-
[onChange, conditions]
|
|
18549
|
-
);
|
|
18550
|
-
const normalizeScore = (n) => Math.min(1e3, Math.max(1, Math.round(n)));
|
|
18551
|
-
const handleScoreTextChange = (text) => {
|
|
18552
|
-
setScoreText(text);
|
|
18553
|
-
if (text === "") return;
|
|
18554
|
-
const n = Number(text);
|
|
18555
|
-
if (Number.isFinite(n) && n >= 1 && n <= 1e3 && Number.isInteger(n)) {
|
|
18556
|
-
commitScore(n);
|
|
18680
|
+
function RecordingShare({
|
|
18681
|
+
shareLabel,
|
|
18682
|
+
options,
|
|
18683
|
+
selectedKeys,
|
|
18684
|
+
popoverTitle,
|
|
18685
|
+
cancelLabel,
|
|
18686
|
+
confirmLabel,
|
|
18687
|
+
dialogTitle,
|
|
18688
|
+
link,
|
|
18689
|
+
copyLinkLabel,
|
|
18690
|
+
copiedLabel,
|
|
18691
|
+
mailLabel,
|
|
18692
|
+
systemLabel,
|
|
18693
|
+
onShare,
|
|
18694
|
+
onSelectionCommit,
|
|
18695
|
+
onShareConfirm,
|
|
18696
|
+
onShareChannel
|
|
18697
|
+
}) {
|
|
18698
|
+
const [popoverOpen, setPopoverOpen] = (0, import_react77.useState)(false);
|
|
18699
|
+
const [dialogOpen, setDialogOpen] = (0, import_react77.useState)(false);
|
|
18700
|
+
const [draftKeys, setDraftKeys] = (0, import_react77.useState)(selectedKeys);
|
|
18701
|
+
const [copied, setCopied] = (0, import_react77.useState)(false);
|
|
18702
|
+
const copyLink = () => {
|
|
18703
|
+
if (link !== void 0) {
|
|
18704
|
+
copyText(link);
|
|
18705
|
+
setCopied(true);
|
|
18706
|
+
setTimeout(() => setCopied(false), 1500);
|
|
18557
18707
|
}
|
|
18708
|
+
onShareChannel?.("copyLink");
|
|
18558
18709
|
};
|
|
18559
|
-
const
|
|
18560
|
-
|
|
18561
|
-
|
|
18562
|
-
|
|
18563
|
-
|
|
18710
|
+
const openPopover = (next) => {
|
|
18711
|
+
if (next) {
|
|
18712
|
+
setDraftKeys(selectedKeys);
|
|
18713
|
+
onShare?.();
|
|
18714
|
+
}
|
|
18715
|
+
setPopoverOpen(next);
|
|
18564
18716
|
};
|
|
18565
|
-
const
|
|
18566
|
-
(
|
|
18567
|
-
|
|
18568
|
-
|
|
18569
|
-
}),
|
|
18570
|
-
[onChange, initScore]
|
|
18571
|
-
);
|
|
18572
|
-
const handleOptChange = (key, opt) => {
|
|
18573
|
-
update(
|
|
18574
|
-
conditions.map(
|
|
18575
|
-
(c) => c.key === key ? { ...c, opt, value: opt === "BETWEEN" ? [] : void 0 } : c
|
|
18576
|
-
)
|
|
18717
|
+
const toggleOption = (option) => {
|
|
18718
|
+
if (option.disabled === true) return;
|
|
18719
|
+
setDraftKeys(
|
|
18720
|
+
(prev) => prev.includes(option.key) ? prev.filter((key) => key !== option.key) : [...prev, option.key]
|
|
18577
18721
|
);
|
|
18578
18722
|
};
|
|
18579
|
-
const
|
|
18580
|
-
|
|
18581
|
-
|
|
18582
|
-
|
|
18583
|
-
|
|
18584
|
-
|
|
18585
|
-
);
|
|
18723
|
+
const confirm = () => {
|
|
18724
|
+
const next = options.filter((option) => draftKeys.includes(option.key)).map((option) => option.key);
|
|
18725
|
+
onSelectionCommit(next);
|
|
18726
|
+
onShareConfirm?.(next);
|
|
18727
|
+
setPopoverOpen(false);
|
|
18728
|
+
setDialogOpen(true);
|
|
18586
18729
|
};
|
|
18587
|
-
const
|
|
18588
|
-
|
|
18589
|
-
|
|
18590
|
-
|
|
18591
|
-
|
|
18592
|
-
/* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { className: "text-muted-foreground", children: "\u6743\u91CD" }),
|
|
18593
|
-
/* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { className: "font-medium", children: initScore })
|
|
18594
|
-
] }),
|
|
18595
|
-
conditions.map((condition) => /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
18596
|
-
/* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { children: operatorLabel2(condition.opt) }),
|
|
18597
|
-
!NO_VALUE_OPT.includes(condition.opt) && /* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { className: "font-medium", children: formatConditionValue2(condition) }),
|
|
18598
|
-
/* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("span", { className: "text-muted-foreground", children: [
|
|
18599
|
-
"\u8BC4\u5206: ",
|
|
18600
|
-
condition.score ?? "-"
|
|
18601
|
-
] })
|
|
18602
|
-
] }, condition.key))
|
|
18603
|
-
] });
|
|
18604
|
-
}
|
|
18605
|
-
return /* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("div", { className: "space-y-2", children: [
|
|
18606
|
-
/* @__PURE__ */ (0, import_jsx_runtime219.jsxs)("div", { className: "flex items-center gap-1 pb-2 border-b gap-2", children: [
|
|
18607
|
-
/* @__PURE__ */ (0, import_jsx_runtime219.jsx)("span", { className: "text-sm shrink-0", children: "\u6743\u91CD" }),
|
|
18608
|
-
/* @__PURE__ */ (0, import_jsx_runtime219.jsx)(
|
|
18609
|
-
Input,
|
|
18730
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(Button2, { text: shareLabel, size: "small" });
|
|
18731
|
+
return /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)(import_jsx_runtime222.Fragment, { children: [
|
|
18732
|
+
/* @__PURE__ */ (0, import_jsx_runtime222.jsxs)(Popover, { open: popoverOpen, onOpenChange: openPopover, children: [
|
|
18733
|
+
/* @__PURE__ */ (0, import_jsx_runtime222.jsx)(
|
|
18734
|
+
PopoverTrigger,
|
|
18610
18735
|
{
|
|
18611
|
-
|
|
18612
|
-
|
|
18613
|
-
|
|
18614
|
-
max: 1e3,
|
|
18615
|
-
step: 1,
|
|
18616
|
-
value: scoreText,
|
|
18617
|
-
disabled,
|
|
18618
|
-
placeholder: "\u8BF7\u8F93\u5165\u6743\u91CD",
|
|
18619
|
-
onChange: (e) => handleScoreTextChange(e.target.value),
|
|
18620
|
-
onBlur: handleScoreBlur
|
|
18736
|
+
nativeButton: false,
|
|
18737
|
+
render: /* @__PURE__ */ (0, import_jsx_runtime222.jsx)("span", { "data-slot": "recording-share-trigger", className: "inline-flex" }),
|
|
18738
|
+
children: trigger
|
|
18621
18739
|
}
|
|
18622
|
-
)
|
|
18740
|
+
),
|
|
18741
|
+
/* @__PURE__ */ (0, import_jsx_runtime222.jsxs)(
|
|
18742
|
+
PopoverContent,
|
|
18743
|
+
{
|
|
18744
|
+
align: "end",
|
|
18745
|
+
sideOffset: 8,
|
|
18746
|
+
className: "w-64 p-0",
|
|
18747
|
+
"data-slot": "recording-share-popover",
|
|
18748
|
+
children: [
|
|
18749
|
+
/* @__PURE__ */ (0, import_jsx_runtime222.jsx)("div", { className: "px-4 pt-4 pb-2 text-sm font-semibold", children: popoverTitle }),
|
|
18750
|
+
/* @__PURE__ */ (0, import_jsx_runtime222.jsx)("div", { className: "flex flex-col px-2 pb-2", children: options.map((option) => {
|
|
18751
|
+
const checked = draftKeys.includes(option.key);
|
|
18752
|
+
const disabled = option.disabled === true;
|
|
18753
|
+
return /* @__PURE__ */ (0, import_jsx_runtime222.jsxs)(
|
|
18754
|
+
"button",
|
|
18755
|
+
{
|
|
18756
|
+
type: "button",
|
|
18757
|
+
"data-slot": "recording-share-option",
|
|
18758
|
+
"aria-pressed": checked,
|
|
18759
|
+
disabled,
|
|
18760
|
+
className: cn(
|
|
18761
|
+
"flex w-full items-center gap-2.5 rounded-md px-2 py-2 text-left text-sm",
|
|
18762
|
+
disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer hover:bg-muted"
|
|
18763
|
+
),
|
|
18764
|
+
onClick: () => toggleOption(option),
|
|
18765
|
+
children: [
|
|
18766
|
+
/* @__PURE__ */ (0, import_jsx_runtime222.jsx)(
|
|
18767
|
+
"span",
|
|
18768
|
+
{
|
|
18769
|
+
className: cn(
|
|
18770
|
+
"flex h-5 w-5 shrink-0 items-center justify-center rounded-full",
|
|
18771
|
+
checked ? "bg-primary text-primary-foreground" : "border border-input"
|
|
18772
|
+
),
|
|
18773
|
+
children: checked ? /* @__PURE__ */ (0, import_jsx_runtime222.jsx)(Icon, { name: "check", size: 12 }) : null
|
|
18774
|
+
}
|
|
18775
|
+
),
|
|
18776
|
+
option.label
|
|
18777
|
+
]
|
|
18778
|
+
},
|
|
18779
|
+
option.key
|
|
18780
|
+
);
|
|
18781
|
+
}) }),
|
|
18782
|
+
/* @__PURE__ */ (0, import_jsx_runtime222.jsxs)("div", { className: "flex items-center justify-end gap-2 border-t border-border px-4 py-3", children: [
|
|
18783
|
+
/* @__PURE__ */ (0, import_jsx_runtime222.jsx)(Button2, { text: cancelLabel, variant: "text", onClick: () => setPopoverOpen(false) }),
|
|
18784
|
+
/* @__PURE__ */ (0, import_jsx_runtime222.jsx)(Button2, { text: confirmLabel, variant: "primary", onClick: confirm })
|
|
18785
|
+
] })
|
|
18786
|
+
]
|
|
18787
|
+
}
|
|
18788
|
+
)
|
|
18789
|
+
] }),
|
|
18790
|
+
/* @__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: [
|
|
18791
|
+
/* @__PURE__ */ (0, import_jsx_runtime222.jsx)(DialogTitle, { children: dialogTitle }),
|
|
18792
|
+
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: [
|
|
18793
|
+
/* @__PURE__ */ (0, import_jsx_runtime222.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm", children: link }),
|
|
18794
|
+
/* @__PURE__ */ (0, import_jsx_runtime222.jsx)(
|
|
18795
|
+
Button2,
|
|
18796
|
+
{
|
|
18797
|
+
text: copied ? copiedLabel : copyLinkLabel,
|
|
18798
|
+
variant: "link",
|
|
18799
|
+
size: "small",
|
|
18800
|
+
onClick: copyLink
|
|
18801
|
+
}
|
|
18802
|
+
)
|
|
18803
|
+
] }) : null,
|
|
18804
|
+
/* @__PURE__ */ (0, import_jsx_runtime222.jsxs)("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
18805
|
+
/* @__PURE__ */ (0, import_jsx_runtime222.jsx)(
|
|
18806
|
+
Button2,
|
|
18807
|
+
{
|
|
18808
|
+
text: mailLabel,
|
|
18809
|
+
icon: "mail",
|
|
18810
|
+
className: "h-12",
|
|
18811
|
+
onClick: () => onShareChannel?.("mail")
|
|
18812
|
+
}
|
|
18813
|
+
),
|
|
18814
|
+
/* @__PURE__ */ (0, import_jsx_runtime222.jsx)(
|
|
18815
|
+
Button2,
|
|
18816
|
+
{
|
|
18817
|
+
text: systemLabel,
|
|
18818
|
+
icon: "share",
|
|
18819
|
+
className: "h-12",
|
|
18820
|
+
onClick: () => onShareChannel?.("system")
|
|
18821
|
+
}
|
|
18822
|
+
)
|
|
18823
|
+
] })
|
|
18824
|
+
] }) })
|
|
18825
|
+
] });
|
|
18826
|
+
}
|
|
18827
|
+
|
|
18828
|
+
// src/components/business/RecordingPage/speaker-dialog.tsx
|
|
18829
|
+
var import_jsx_runtime223 = require("react/jsx-runtime");
|
|
18830
|
+
function RecordingSpeakerDialog({
|
|
18831
|
+
open,
|
|
18832
|
+
title,
|
|
18833
|
+
hint,
|
|
18834
|
+
speakers,
|
|
18835
|
+
selectedIndex,
|
|
18836
|
+
customName,
|
|
18837
|
+
inputPlaceholder,
|
|
18838
|
+
applyLabel,
|
|
18839
|
+
onSelect,
|
|
18840
|
+
onInputName,
|
|
18841
|
+
onCancel,
|
|
18842
|
+
onConfirm
|
|
18843
|
+
}) {
|
|
18844
|
+
const canApply = customName.trim() !== "" || selectedIndex >= 0;
|
|
18845
|
+
return /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
|
|
18846
|
+
Dialog,
|
|
18847
|
+
{
|
|
18848
|
+
open,
|
|
18849
|
+
onOpenChange: (next) => {
|
|
18850
|
+
if (!next) onCancel();
|
|
18851
|
+
},
|
|
18852
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)(
|
|
18853
|
+
DialogContent,
|
|
18854
|
+
{
|
|
18855
|
+
"data-slot": "recording-speaker-dialog",
|
|
18856
|
+
className: "gap-4 sm:max-w-xl",
|
|
18857
|
+
children: [
|
|
18858
|
+
/* @__PURE__ */ (0, import_jsx_runtime223.jsx)(DialogTitle, { children: title }),
|
|
18859
|
+
hint !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(DialogDescription, { children: hint }) : null,
|
|
18860
|
+
speakers.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("div", { className: "flex flex-col divide-y divide-border", children: speakers.map((speaker, index) => {
|
|
18861
|
+
const selected = index === selectedIndex;
|
|
18862
|
+
return /* @__PURE__ */ (0, import_jsx_runtime223.jsxs)(
|
|
18863
|
+
"button",
|
|
18864
|
+
{
|
|
18865
|
+
type: "button",
|
|
18866
|
+
"data-slot": "recording-speaker-option",
|
|
18867
|
+
"aria-pressed": selected,
|
|
18868
|
+
className: cn(
|
|
18869
|
+
"flex w-full cursor-pointer items-center gap-3 px-3 py-3 text-left",
|
|
18870
|
+
selected ? "bg-primary/10" : "hover:bg-muted"
|
|
18871
|
+
),
|
|
18872
|
+
onClick: () => onSelect(index),
|
|
18873
|
+
children: [
|
|
18874
|
+
/* @__PURE__ */ (0, import_jsx_runtime223.jsx)(Avatar2, { fallback: speaker.avatarText ?? speaker.name.charAt(0) }),
|
|
18875
|
+
/* @__PURE__ */ (0, import_jsx_runtime223.jsxs)("span", { className: "flex min-w-0 flex-1 items-baseline gap-2", children: [
|
|
18876
|
+
/* @__PURE__ */ (0, import_jsx_runtime223.jsx)("span", { className: "text-sm font-medium", children: speaker.name }),
|
|
18877
|
+
speaker.role !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("span", { className: "truncate text-sm text-muted-foreground", children: speaker.role }) : null
|
|
18878
|
+
] }),
|
|
18879
|
+
speaker.tag !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime223.jsx)("span", { className: "shrink-0 text-sm text-muted-foreground", children: speaker.tag }) : null
|
|
18880
|
+
]
|
|
18881
|
+
},
|
|
18882
|
+
`${speaker.name}-${index}`
|
|
18883
|
+
);
|
|
18884
|
+
}) }) : null,
|
|
18885
|
+
/* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
|
|
18886
|
+
Input2,
|
|
18887
|
+
{
|
|
18888
|
+
value: customName,
|
|
18889
|
+
placeholder: inputPlaceholder,
|
|
18890
|
+
onChange: onInputName
|
|
18891
|
+
}
|
|
18892
|
+
),
|
|
18893
|
+
/* @__PURE__ */ (0, import_jsx_runtime223.jsx)("div", { className: "flex items-center justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime223.jsx)(
|
|
18894
|
+
Button2,
|
|
18895
|
+
{
|
|
18896
|
+
text: applyLabel,
|
|
18897
|
+
variant: "primary",
|
|
18898
|
+
disabled: !canApply,
|
|
18899
|
+
onClick: onConfirm
|
|
18900
|
+
}
|
|
18901
|
+
) })
|
|
18902
|
+
]
|
|
18903
|
+
}
|
|
18904
|
+
)
|
|
18905
|
+
}
|
|
18906
|
+
);
|
|
18907
|
+
}
|
|
18908
|
+
|
|
18909
|
+
// src/components/business/RecordingPage/summary.tsx
|
|
18910
|
+
var import_jsx_runtime224 = require("react/jsx-runtime");
|
|
18911
|
+
function MindmapPill({ label, center }) {
|
|
18912
|
+
return /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
18913
|
+
"span",
|
|
18914
|
+
{
|
|
18915
|
+
className: cn(
|
|
18916
|
+
"rounded-lg px-4 py-1.5 text-sm",
|
|
18917
|
+
center ? "bg-primary px-5 py-2.5 font-medium text-primary-foreground" : "border border-border bg-background"
|
|
18918
|
+
),
|
|
18919
|
+
children: label
|
|
18920
|
+
}
|
|
18921
|
+
);
|
|
18922
|
+
}
|
|
18923
|
+
var mindmapLine = /* @__PURE__ */ (0, import_jsx_runtime224.jsx)("div", { className: "h-px w-10 shrink-0", style: { background: "var(--border)" } });
|
|
18924
|
+
function RecordingSummaryView({
|
|
18925
|
+
summary,
|
|
18926
|
+
onMindmapAction,
|
|
18927
|
+
onMaterialClick,
|
|
18928
|
+
selectedTodoIds,
|
|
18929
|
+
onTodoToggle,
|
|
18930
|
+
onSummaryAction
|
|
18931
|
+
}) {
|
|
18932
|
+
return /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("div", { "data-slot": "recording-summary", className: "flex flex-col gap-6", children: [
|
|
18933
|
+
summary.mindmap ? /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("section", { className: "rounded-lg border border-border", children: [
|
|
18934
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("div", { className: "flex items-center justify-between px-4 py-3", children: [
|
|
18935
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(Text, { text: summary.mindmapTitle ?? "\u601D\u7EF4\u5BFC\u56FE", strong: true }),
|
|
18936
|
+
summary.mindmapActionLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
18937
|
+
Button2,
|
|
18938
|
+
{
|
|
18939
|
+
text: summary.mindmapActionLabel,
|
|
18940
|
+
variant: "link",
|
|
18941
|
+
size: "small",
|
|
18942
|
+
className: "text-success",
|
|
18943
|
+
onClick: () => onMindmapAction?.()
|
|
18944
|
+
}
|
|
18945
|
+
) : null
|
|
18946
|
+
] }),
|
|
18947
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("div", { className: "mx-4 mb-4 flex items-center justify-center rounded-lg bg-muted p-8", children: [
|
|
18948
|
+
/* @__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)) }),
|
|
18949
|
+
mindmapLine,
|
|
18950
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(MindmapPill, { label: summary.mindmap.center, center: true }),
|
|
18951
|
+
mindmapLine,
|
|
18952
|
+
/* @__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)) })
|
|
18953
|
+
] })
|
|
18954
|
+
] }) : null,
|
|
18955
|
+
summary.overview !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("section", { className: "flex flex-col gap-3", children: [
|
|
18956
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
18957
|
+
Text,
|
|
18958
|
+
{
|
|
18959
|
+
text: summary.overviewTitle ?? "\u4F1A\u8BAE\u6982\u51B5",
|
|
18960
|
+
strong: true,
|
|
18961
|
+
size: "large"
|
|
18962
|
+
}
|
|
18963
|
+
),
|
|
18964
|
+
/* @__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 }) })
|
|
18965
|
+
] }) : null,
|
|
18966
|
+
summary.topics !== void 0 && summary.topics.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("section", { className: "flex flex-col gap-3", children: [
|
|
18967
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(Text, { text: summary.topicsTitle ?? "\u4E3B\u8981\u8BAE\u9898", strong: true, size: "large" }),
|
|
18968
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
18969
|
+
"div",
|
|
18970
|
+
{
|
|
18971
|
+
className: "grid gap-3",
|
|
18972
|
+
style: { gridTemplateColumns: "1fr 1fr" },
|
|
18973
|
+
children: summary.topics.map((topic, index) => /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)(
|
|
18974
|
+
"div",
|
|
18975
|
+
{
|
|
18976
|
+
className: "flex flex-col gap-2 rounded-lg border border-border p-4",
|
|
18977
|
+
children: [
|
|
18978
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(Text, { text: topic.title, strong: true, size: "small" }),
|
|
18979
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(Text, { text: topic.content, size: "small" })
|
|
18980
|
+
]
|
|
18981
|
+
},
|
|
18982
|
+
index
|
|
18983
|
+
))
|
|
18984
|
+
}
|
|
18985
|
+
)
|
|
18986
|
+
] }) : null,
|
|
18987
|
+
summary.conclusions !== void 0 && summary.conclusions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("section", { className: "rounded-lg border border-border p-4", children: [
|
|
18988
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
18989
|
+
Text,
|
|
18990
|
+
{
|
|
18991
|
+
text: summary.conclusionsTitle ?? "\u8BC4\u5BA1\u7ED3\u8BBA\u4E0E\u540E\u7EED\u5B89\u6392",
|
|
18992
|
+
strong: true,
|
|
18993
|
+
size: "small"
|
|
18994
|
+
}
|
|
18995
|
+
),
|
|
18996
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
18997
|
+
Table3,
|
|
18998
|
+
{
|
|
18999
|
+
className: "mt-3",
|
|
19000
|
+
columns: [
|
|
19001
|
+
{ title: "\u4E8B\u9879", dataIndex: "item" },
|
|
19002
|
+
{ title: "\u4F1A\u8BAE\u7ED3\u8BBA", dataIndex: "conclusion" },
|
|
19003
|
+
{ title: "\u8D1F\u8D23\u4EBA", dataIndex: "owner" }
|
|
19004
|
+
],
|
|
19005
|
+
dataSource: summary.conclusions.map((row, index) => ({
|
|
19006
|
+
id: index,
|
|
19007
|
+
...row
|
|
19008
|
+
}))
|
|
19009
|
+
}
|
|
19010
|
+
)
|
|
19011
|
+
] }) : null,
|
|
19012
|
+
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: [
|
|
19013
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(Text, { text: summary.followUpTitle, strong: true, size: "small" }),
|
|
19014
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(Text, { text: summary.followUp, size: "small" })
|
|
19015
|
+
] }) : null,
|
|
19016
|
+
summary.materials !== void 0 && summary.materials.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("section", { className: "flex flex-col gap-3", children: [
|
|
19017
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
19018
|
+
Text,
|
|
19019
|
+
{
|
|
19020
|
+
text: summary.materialsTitle ?? "\u76F8\u5173\u6750\u6599",
|
|
19021
|
+
strong: true,
|
|
19022
|
+
size: "large"
|
|
19023
|
+
}
|
|
19024
|
+
),
|
|
19025
|
+
/* @__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)(
|
|
19026
|
+
"button",
|
|
19027
|
+
{
|
|
19028
|
+
type: "button",
|
|
19029
|
+
"data-slot": "recording-material",
|
|
19030
|
+
className: "flex cursor-pointer items-center gap-2 px-4 py-3 text-left",
|
|
19031
|
+
onClick: () => onMaterialClick?.(material.id ?? index),
|
|
19032
|
+
children: [
|
|
19033
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
19034
|
+
Icon,
|
|
19035
|
+
{
|
|
19036
|
+
name: material.icon ?? "file-text",
|
|
19037
|
+
size: 16,
|
|
19038
|
+
className: "text-muted-foreground"
|
|
19039
|
+
}
|
|
19040
|
+
),
|
|
19041
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
19042
|
+
Text,
|
|
19043
|
+
{
|
|
19044
|
+
text: material.title,
|
|
19045
|
+
size: "small",
|
|
19046
|
+
className: "min-w-0 flex-1 truncate"
|
|
19047
|
+
}
|
|
19048
|
+
),
|
|
19049
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
19050
|
+
Text,
|
|
19051
|
+
{
|
|
19052
|
+
text: material.meta,
|
|
19053
|
+
size: "small",
|
|
19054
|
+
type: "secondary",
|
|
19055
|
+
className: "shrink-0"
|
|
19056
|
+
}
|
|
19057
|
+
),
|
|
19058
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
19059
|
+
Icon,
|
|
19060
|
+
{
|
|
19061
|
+
name: "chevron-right",
|
|
19062
|
+
size: 14,
|
|
19063
|
+
className: "text-muted-foreground"
|
|
19064
|
+
}
|
|
19065
|
+
)
|
|
19066
|
+
]
|
|
19067
|
+
},
|
|
19068
|
+
material.id ?? index
|
|
19069
|
+
)) })
|
|
19070
|
+
] }) : null,
|
|
19071
|
+
summary.todos !== void 0 && summary.todos.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)("section", { className: "flex flex-col gap-3", children: [
|
|
19072
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(Text, { text: summary.todosTitle ?? "\u5F85\u529E\u4E8B\u9879", strong: true, size: "large" }),
|
|
19073
|
+
/* @__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) => {
|
|
19074
|
+
const todoId = todo.id ?? index;
|
|
19075
|
+
const checked = selectedTodoIds !== void 0 ? selectedTodoIds.includes(todoId) : todo.done === true;
|
|
19076
|
+
return /* @__PURE__ */ (0, import_jsx_runtime224.jsxs)(
|
|
19077
|
+
"button",
|
|
19078
|
+
{
|
|
19079
|
+
type: "button",
|
|
19080
|
+
"data-slot": "recording-todo",
|
|
19081
|
+
"aria-pressed": checked,
|
|
19082
|
+
className: "flex cursor-pointer items-center gap-2 px-4 py-3 text-left",
|
|
19083
|
+
onClick: () => onTodoToggle?.(todoId),
|
|
19084
|
+
children: [
|
|
19085
|
+
checked ? /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
19086
|
+
Icon,
|
|
19087
|
+
{
|
|
19088
|
+
name: "check-circle",
|
|
19089
|
+
size: 16,
|
|
19090
|
+
className: "shrink-0 text-success"
|
|
19091
|
+
}
|
|
19092
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
19093
|
+
"span",
|
|
19094
|
+
{
|
|
19095
|
+
className: "shrink-0 rounded-full border border-border",
|
|
19096
|
+
style: { width: 16, height: 16 }
|
|
19097
|
+
}
|
|
19098
|
+
),
|
|
19099
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
19100
|
+
Text,
|
|
19101
|
+
{
|
|
19102
|
+
text: todo.title,
|
|
19103
|
+
size: "small",
|
|
19104
|
+
className: "min-w-0 flex-1 truncate"
|
|
19105
|
+
}
|
|
19106
|
+
),
|
|
19107
|
+
/* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
19108
|
+
Text,
|
|
19109
|
+
{
|
|
19110
|
+
text: todo.owner,
|
|
19111
|
+
size: "small",
|
|
19112
|
+
type: "secondary",
|
|
19113
|
+
className: "shrink-0"
|
|
19114
|
+
}
|
|
19115
|
+
)
|
|
19116
|
+
]
|
|
19117
|
+
},
|
|
19118
|
+
todoId
|
|
19119
|
+
);
|
|
19120
|
+
}) })
|
|
19121
|
+
] }) : null,
|
|
19122
|
+
summary.actions !== void 0 && summary.actions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
19123
|
+
"div",
|
|
19124
|
+
{
|
|
19125
|
+
"data-slot": "recording-summary-actions",
|
|
19126
|
+
className: "flex items-center gap-1",
|
|
19127
|
+
children: summary.actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime224.jsx)(
|
|
19128
|
+
Button2,
|
|
19129
|
+
{
|
|
19130
|
+
icon: action.icon,
|
|
19131
|
+
variant: "text",
|
|
19132
|
+
size: "small",
|
|
19133
|
+
onClick: () => onSummaryAction?.(action.key)
|
|
19134
|
+
},
|
|
19135
|
+
action.key
|
|
19136
|
+
))
|
|
19137
|
+
}
|
|
19138
|
+
) : null
|
|
19139
|
+
] });
|
|
19140
|
+
}
|
|
19141
|
+
|
|
19142
|
+
// src/components/business/RecordingPage/translation.tsx
|
|
19143
|
+
var import_react78 = require("react");
|
|
19144
|
+
|
|
19145
|
+
// src/components/business/RecordingPage/language-dialog.tsx
|
|
19146
|
+
var import_jsx_runtime225 = require("react/jsx-runtime");
|
|
19147
|
+
function LanguageOptionItem({
|
|
19148
|
+
option,
|
|
19149
|
+
selected,
|
|
19150
|
+
onSelect
|
|
19151
|
+
}) {
|
|
19152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime225.jsxs)(
|
|
19153
|
+
"button",
|
|
19154
|
+
{
|
|
19155
|
+
type: "button",
|
|
19156
|
+
"data-slot": "recording-language-option",
|
|
19157
|
+
"aria-pressed": selected,
|
|
19158
|
+
className: cn(
|
|
19159
|
+
"flex w-full cursor-pointer items-center gap-2.5 px-3 py-2.5 text-left text-sm",
|
|
19160
|
+
selected ? "bg-primary/10" : "hover:bg-muted"
|
|
19161
|
+
),
|
|
19162
|
+
onClick: () => onSelect(option.key),
|
|
19163
|
+
children: [
|
|
19164
|
+
/* @__PURE__ */ (0, import_jsx_runtime225.jsx)(
|
|
19165
|
+
"span",
|
|
19166
|
+
{
|
|
19167
|
+
className: cn(
|
|
19168
|
+
"flex h-4 w-4 shrink-0 items-center justify-center rounded-full border",
|
|
19169
|
+
selected ? "border-primary" : "border-input"
|
|
19170
|
+
),
|
|
19171
|
+
children: selected ? /* @__PURE__ */ (0, import_jsx_runtime225.jsx)("span", { className: "h-2 w-2 rounded-full bg-primary" }) : null
|
|
19172
|
+
}
|
|
19173
|
+
),
|
|
19174
|
+
/* @__PURE__ */ (0, import_jsx_runtime225.jsx)("span", { className: cn(selected && "font-medium"), children: option.label })
|
|
19175
|
+
]
|
|
19176
|
+
}
|
|
19177
|
+
);
|
|
19178
|
+
}
|
|
19179
|
+
function RecordingLanguageDialog({
|
|
19180
|
+
open,
|
|
19181
|
+
title,
|
|
19182
|
+
sourceTitle,
|
|
19183
|
+
targetTitle,
|
|
19184
|
+
sourceLanguages,
|
|
19185
|
+
targetLanguages,
|
|
19186
|
+
source,
|
|
19187
|
+
target,
|
|
19188
|
+
cancelLabel,
|
|
19189
|
+
confirmLabel,
|
|
19190
|
+
onSelectSource,
|
|
19191
|
+
onSelectTarget,
|
|
19192
|
+
onCancel,
|
|
19193
|
+
onConfirm
|
|
19194
|
+
}) {
|
|
19195
|
+
const renderColumn = (columnTitle, options, value, onSelect) => /* @__PURE__ */ (0, import_jsx_runtime225.jsxs)("div", { className: "flex min-w-0 flex-col gap-2", children: [
|
|
19196
|
+
/* @__PURE__ */ (0, import_jsx_runtime225.jsx)("span", { className: "text-sm font-medium", children: columnTitle }),
|
|
19197
|
+
/* @__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)(
|
|
19198
|
+
LanguageOptionItem,
|
|
19199
|
+
{
|
|
19200
|
+
option,
|
|
19201
|
+
selected: option.key === value,
|
|
19202
|
+
onSelect
|
|
19203
|
+
},
|
|
19204
|
+
option.key
|
|
19205
|
+
)) })
|
|
19206
|
+
] });
|
|
19207
|
+
return /* @__PURE__ */ (0, import_jsx_runtime225.jsx)(
|
|
19208
|
+
Dialog,
|
|
19209
|
+
{
|
|
19210
|
+
open,
|
|
19211
|
+
onOpenChange: (next) => {
|
|
19212
|
+
if (!next) onCancel();
|
|
19213
|
+
},
|
|
19214
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime225.jsxs)(
|
|
19215
|
+
DialogContent,
|
|
19216
|
+
{
|
|
19217
|
+
"data-slot": "recording-language-dialog",
|
|
19218
|
+
className: "gap-6 sm:max-w-xl",
|
|
19219
|
+
children: [
|
|
19220
|
+
/* @__PURE__ */ (0, import_jsx_runtime225.jsx)(DialogTitle, { children: title }),
|
|
19221
|
+
/* @__PURE__ */ (0, import_jsx_runtime225.jsxs)("div", { className: "grid grid-cols-2 gap-6", children: [
|
|
19222
|
+
renderColumn(sourceTitle, sourceLanguages, source, onSelectSource),
|
|
19223
|
+
renderColumn(targetTitle, targetLanguages, target, onSelectTarget)
|
|
19224
|
+
] }),
|
|
19225
|
+
/* @__PURE__ */ (0, import_jsx_runtime225.jsxs)("div", { className: "flex items-center justify-end gap-2", children: [
|
|
19226
|
+
/* @__PURE__ */ (0, import_jsx_runtime225.jsx)(Button2, { text: cancelLabel, onClick: onCancel }),
|
|
19227
|
+
/* @__PURE__ */ (0, import_jsx_runtime225.jsx)(Button2, { text: confirmLabel, variant: "primary", onClick: onConfirm })
|
|
19228
|
+
] })
|
|
19229
|
+
]
|
|
19230
|
+
}
|
|
19231
|
+
)
|
|
19232
|
+
}
|
|
19233
|
+
);
|
|
19234
|
+
}
|
|
19235
|
+
|
|
19236
|
+
// src/components/business/RecordingPage/translation.tsx
|
|
19237
|
+
var import_jsx_runtime226 = require("react/jsx-runtime");
|
|
19238
|
+
function RecordingTranslationView({
|
|
19239
|
+
translation,
|
|
19240
|
+
onLanguageClick,
|
|
19241
|
+
onLanguageChange,
|
|
19242
|
+
onTranslationAction
|
|
19243
|
+
}) {
|
|
19244
|
+
const sourceLanguages = translation.sourceLanguages ?? [];
|
|
19245
|
+
const targetLanguages = translation.targetLanguages ?? [];
|
|
19246
|
+
const dialogEnabled = sourceLanguages.length > 0 || targetLanguages.length > 0;
|
|
19247
|
+
const [dialogOpen, setDialogOpen] = (0, import_react78.useState)(false);
|
|
19248
|
+
const sourceControlled = translation.sourceLanguage !== void 0;
|
|
19249
|
+
const targetControlled = translation.targetLanguage !== void 0;
|
|
19250
|
+
const [innerSource, setInnerSource] = (0, import_react78.useState)(
|
|
19251
|
+
translation.defaultSourceLanguage ?? sourceLanguages[0]?.key
|
|
19252
|
+
);
|
|
19253
|
+
const [innerTarget, setInnerTarget] = (0, import_react78.useState)(
|
|
19254
|
+
translation.defaultTargetLanguage ?? targetLanguages[0]?.key
|
|
19255
|
+
);
|
|
19256
|
+
const committedSource = sourceControlled ? translation.sourceLanguage : innerSource;
|
|
19257
|
+
const committedTarget = targetControlled ? translation.targetLanguage : innerTarget;
|
|
19258
|
+
const [draftSource, setDraftSource] = (0, import_react78.useState)(committedSource);
|
|
19259
|
+
const [draftTarget, setDraftTarget] = (0, import_react78.useState)(committedTarget);
|
|
19260
|
+
const openDialog = () => {
|
|
19261
|
+
setDraftSource(committedSource);
|
|
19262
|
+
setDraftTarget(committedTarget);
|
|
19263
|
+
setDialogOpen(true);
|
|
19264
|
+
};
|
|
19265
|
+
const confirmDialog = () => {
|
|
19266
|
+
if (!sourceControlled) setInnerSource(draftSource);
|
|
19267
|
+
if (!targetControlled) setInnerTarget(draftTarget);
|
|
19268
|
+
onLanguageChange?.({
|
|
19269
|
+
source: draftSource,
|
|
19270
|
+
sourceLabel: sourceLanguages.find((item) => item.key === draftSource)?.label,
|
|
19271
|
+
target: draftTarget,
|
|
19272
|
+
targetLabel: targetLanguages.find((item) => item.key === draftTarget)?.label
|
|
19273
|
+
});
|
|
19274
|
+
setDialogOpen(false);
|
|
19275
|
+
};
|
|
19276
|
+
return /* @__PURE__ */ (0, import_jsx_runtime226.jsxs)("div", { "data-slot": "recording-translation", className: "flex flex-col gap-4", children: [
|
|
19277
|
+
translation.languageLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime226.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime226.jsxs)(
|
|
19278
|
+
"button",
|
|
19279
|
+
{
|
|
19280
|
+
type: "button",
|
|
19281
|
+
"data-slot": "recording-translation-language",
|
|
19282
|
+
className: "inline-flex cursor-pointer items-center gap-1.5 rounded-full bg-primary/10 px-3 py-1.5 text-sm",
|
|
19283
|
+
onClick: () => {
|
|
19284
|
+
onLanguageClick?.();
|
|
19285
|
+
if (dialogEnabled) openDialog();
|
|
19286
|
+
},
|
|
19287
|
+
children: [
|
|
19288
|
+
/* @__PURE__ */ (0, import_jsx_runtime226.jsx)(Icon, { name: "globe", size: 14 }),
|
|
19289
|
+
translation.languageLabel,
|
|
19290
|
+
/* @__PURE__ */ (0, import_jsx_runtime226.jsx)(Icon, { name: "chevron-down", size: 14, className: "text-muted-foreground" })
|
|
19291
|
+
]
|
|
19292
|
+
}
|
|
19293
|
+
) }) : null,
|
|
19294
|
+
/* @__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)(
|
|
19295
|
+
"div",
|
|
19296
|
+
{
|
|
19297
|
+
"data-slot": "recording-translation-segment",
|
|
19298
|
+
className: "grid gap-4 py-4",
|
|
19299
|
+
style: { gridTemplateColumns: "1fr 1fr" },
|
|
19300
|
+
children: [
|
|
19301
|
+
/* @__PURE__ */ (0, import_jsx_runtime226.jsxs)("div", { className: "flex min-w-0 flex-col gap-3", children: [
|
|
19302
|
+
/* @__PURE__ */ (0, import_jsx_runtime226.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
19303
|
+
/* @__PURE__ */ (0, import_jsx_runtime226.jsx)(Avatar2, { fallback: segment.avatarText ?? segment.speaker?.charAt(0) ?? "?" }),
|
|
19304
|
+
/* @__PURE__ */ (0, import_jsx_runtime226.jsx)(Text, { text: segment.speaker, strong: true, size: "small" })
|
|
19305
|
+
] }),
|
|
19306
|
+
/* @__PURE__ */ (0, import_jsx_runtime226.jsx)(Text, { text: segment.source })
|
|
19307
|
+
] }),
|
|
19308
|
+
/* @__PURE__ */ (0, import_jsx_runtime226.jsxs)("div", { className: "flex min-w-0 flex-col gap-3", children: [
|
|
19309
|
+
/* @__PURE__ */ (0, import_jsx_runtime226.jsx)(Text, { text: translation.targetLabel ?? "\u8BD1\u6587", strong: true, size: "small" }),
|
|
19310
|
+
/* @__PURE__ */ (0, import_jsx_runtime226.jsx)(Text, { text: segment.target })
|
|
19311
|
+
] })
|
|
19312
|
+
]
|
|
19313
|
+
},
|
|
19314
|
+
index
|
|
19315
|
+
)) }),
|
|
19316
|
+
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)(
|
|
19317
|
+
Button2,
|
|
19318
|
+
{
|
|
19319
|
+
icon: action.icon,
|
|
19320
|
+
variant: "text",
|
|
19321
|
+
size: "small",
|
|
19322
|
+
onClick: () => onTranslationAction?.(action.key)
|
|
19323
|
+
},
|
|
19324
|
+
action.key
|
|
19325
|
+
)) }) : null,
|
|
19326
|
+
dialogEnabled ? /* @__PURE__ */ (0, import_jsx_runtime226.jsx)(
|
|
19327
|
+
RecordingLanguageDialog,
|
|
19328
|
+
{
|
|
19329
|
+
open: dialogOpen,
|
|
19330
|
+
title: translation.languageDialogTitle ?? "\u9009\u62E9\u7FFB\u8BD1\u8BED\u8A00",
|
|
19331
|
+
sourceTitle: translation.sourceLanguagesTitle ?? "\u539F\u6587\u8BED\u8A00\u8BC6\u522B",
|
|
19332
|
+
targetTitle: translation.targetLanguagesTitle ?? "\u8BD1\u6587\u8BED\u8A00\u9009\u62E9",
|
|
19333
|
+
sourceLanguages,
|
|
19334
|
+
targetLanguages,
|
|
19335
|
+
source: draftSource,
|
|
19336
|
+
target: draftTarget,
|
|
19337
|
+
cancelLabel: translation.cancelLabel ?? "\u53D6\u6D88",
|
|
19338
|
+
confirmLabel: translation.confirmLabel ?? "\u786E\u5B9A",
|
|
19339
|
+
onSelectSource: setDraftSource,
|
|
19340
|
+
onSelectTarget: setDraftTarget,
|
|
19341
|
+
onCancel: () => setDialogOpen(false),
|
|
19342
|
+
onConfirm: confirmDialog
|
|
19343
|
+
}
|
|
19344
|
+
) : null
|
|
19345
|
+
] });
|
|
19346
|
+
}
|
|
19347
|
+
|
|
19348
|
+
// src/components/business/RecordingPage/detail.tsx
|
|
19349
|
+
var import_jsx_runtime227 = require("react/jsx-runtime");
|
|
19350
|
+
function TranscriptSegment({
|
|
19351
|
+
segment,
|
|
19352
|
+
speaker,
|
|
19353
|
+
onRename
|
|
19354
|
+
}) {
|
|
19355
|
+
return /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { "data-slot": "recording-segment", className: "flex flex-col gap-2", children: [
|
|
19356
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
19357
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
19358
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Avatar2, { fallback: segment.avatarText ?? speaker?.charAt(0) ?? "?" }),
|
|
19359
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Text, { text: speaker, strong: true, size: "small" }),
|
|
19360
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
|
|
19361
|
+
"button",
|
|
19362
|
+
{
|
|
19363
|
+
type: "button",
|
|
19364
|
+
"data-slot": "recording-speaker-edit",
|
|
19365
|
+
"aria-label": "\u4FEE\u6539\u53D1\u8A00\u4EBA",
|
|
19366
|
+
className: "cursor-pointer text-muted-foreground",
|
|
19367
|
+
onClick: () => onRename?.(),
|
|
19368
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Icon, { name: "pencil", size: 14 })
|
|
19369
|
+
}
|
|
19370
|
+
)
|
|
19371
|
+
] }),
|
|
19372
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
19373
|
+
segment.marked ? /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Badge2, { text: "\u2691 \u5DF2\u6807\u8BB0", variant: "outline" }) : null,
|
|
19374
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Text, { text: segment.time, size: "small", type: "secondary" })
|
|
19375
|
+
] })
|
|
19376
|
+
] }),
|
|
19377
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Text, { text: segment.content })
|
|
19378
|
+
] });
|
|
19379
|
+
}
|
|
19380
|
+
function RecordingDetail({
|
|
19381
|
+
title,
|
|
19382
|
+
meta,
|
|
19383
|
+
editLabel,
|
|
19384
|
+
shareLabel,
|
|
19385
|
+
shareOptions = [],
|
|
19386
|
+
shareSelectedKeys = [],
|
|
19387
|
+
sharePopoverTitle,
|
|
19388
|
+
shareCancelLabel,
|
|
19389
|
+
shareConfirmLabel,
|
|
19390
|
+
shareDialogTitle,
|
|
19391
|
+
shareLink,
|
|
19392
|
+
shareCopyLinkLabel,
|
|
19393
|
+
shareCopiedLabel,
|
|
19394
|
+
shareMailLabel,
|
|
19395
|
+
shareSystemLabel,
|
|
19396
|
+
onShareSelectionCommit,
|
|
19397
|
+
onShareConfirm,
|
|
19398
|
+
onShareChannel,
|
|
19399
|
+
onEdit,
|
|
19400
|
+
onShare,
|
|
19401
|
+
tabs,
|
|
19402
|
+
activeTab,
|
|
19403
|
+
onTabChange,
|
|
19404
|
+
transcriptTabKey,
|
|
19405
|
+
segments,
|
|
19406
|
+
speakers = [],
|
|
19407
|
+
speakerDialogTitle,
|
|
19408
|
+
speakerDialogHint,
|
|
19409
|
+
speakerInputPlaceholder,
|
|
19410
|
+
speakerApplyLabel,
|
|
19411
|
+
onSpeakerChange,
|
|
19412
|
+
summary,
|
|
19413
|
+
summaryTabKey,
|
|
19414
|
+
onMindmapAction,
|
|
19415
|
+
onMaterialClick,
|
|
19416
|
+
selectedTodoIds,
|
|
19417
|
+
onTodoToggle,
|
|
19418
|
+
onSummaryAction,
|
|
19419
|
+
insight,
|
|
19420
|
+
insightTabKey,
|
|
19421
|
+
onPerspectiveEdit,
|
|
19422
|
+
onPerspectiveApply,
|
|
19423
|
+
onInsightAction,
|
|
19424
|
+
memory,
|
|
19425
|
+
memoryTabKey,
|
|
19426
|
+
onMemoryAction,
|
|
19427
|
+
translation,
|
|
19428
|
+
translationTabKey,
|
|
19429
|
+
onLanguageClick,
|
|
19430
|
+
onLanguageChange,
|
|
19431
|
+
onTranslationAction,
|
|
19432
|
+
player,
|
|
19433
|
+
onPlay,
|
|
19434
|
+
onSkipBack,
|
|
19435
|
+
onSkipForward
|
|
19436
|
+
}) {
|
|
19437
|
+
const { renderChildren } = (0, import_runtime54.useRenderer)();
|
|
19438
|
+
const renderSlot = (slot) => (0, import_react79.isValidElement)(slot) || typeof slot !== "object" || slot === null ? slot : renderChildren([slot]);
|
|
19439
|
+
const activeTabItem = tabs.find((tab) => tab.key === activeTab);
|
|
19440
|
+
const [renameIndex, setRenameIndex] = (0, import_react79.useState)(null);
|
|
19441
|
+
const [draftSpeakerIndex, setDraftSpeakerIndex] = (0, import_react79.useState)(-1);
|
|
19442
|
+
const [draftSpeakerName, setDraftSpeakerName] = (0, import_react79.useState)("");
|
|
19443
|
+
const [speakerOverrides, setSpeakerOverrides] = (0, import_react79.useState)({});
|
|
19444
|
+
const speakerSignature = (0, import_react79.useRef)("");
|
|
19445
|
+
(0, import_react79.useEffect)(() => {
|
|
19446
|
+
const signature = JSON.stringify(segments.map((segment) => segment.speaker ?? ""));
|
|
19447
|
+
if (speakerSignature.current !== signature) {
|
|
19448
|
+
speakerSignature.current = signature;
|
|
19449
|
+
setSpeakerOverrides((prev) => Object.keys(prev).length > 0 ? {} : prev);
|
|
19450
|
+
}
|
|
19451
|
+
}, [segments]);
|
|
19452
|
+
const displaySpeaker = (index) => speakerOverrides[index] ?? segments[index]?.speaker;
|
|
19453
|
+
const openRename = (index) => {
|
|
19454
|
+
const current = displaySpeaker(index);
|
|
19455
|
+
setDraftSpeakerIndex(speakers.findIndex((item) => item.name === current));
|
|
19456
|
+
setDraftSpeakerName("");
|
|
19457
|
+
setRenameIndex(index);
|
|
19458
|
+
};
|
|
19459
|
+
const confirmRename = () => {
|
|
19460
|
+
if (renameIndex === null) return;
|
|
19461
|
+
const name = draftSpeakerName.trim() !== "" ? draftSpeakerName.trim() : speakers[draftSpeakerIndex]?.name;
|
|
19462
|
+
if (name === void 0 || name === "") return;
|
|
19463
|
+
const previous = displaySpeaker(renameIndex);
|
|
19464
|
+
setSpeakerOverrides((prev) => ({ ...prev, [renameIndex]: name }));
|
|
19465
|
+
onSpeakerChange?.({ index: renameIndex, previous, name });
|
|
19466
|
+
setRenameIndex(null);
|
|
19467
|
+
};
|
|
19468
|
+
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: [
|
|
19469
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { className: "flex shrink-0 items-center justify-between px-6 py-4", children: [
|
|
19470
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { className: "flex min-w-0 flex-col gap-1", children: [
|
|
19471
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Text, { text: title, strong: true, size: "large", className: "truncate" }),
|
|
19472
|
+
meta !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Text, { text: meta, size: "small", type: "secondary" }) : null
|
|
19473
|
+
] }),
|
|
19474
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsxs)("div", { className: "flex shrink-0 items-center gap-3", children: [
|
|
19475
|
+
editLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Button2, { text: editLabel, variant: "link", size: "small", onClick: () => onEdit?.() }) : null,
|
|
19476
|
+
shareLabel !== void 0 ? shareOptions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
|
|
19477
|
+
RecordingShare,
|
|
19478
|
+
{
|
|
19479
|
+
shareLabel,
|
|
19480
|
+
options: shareOptions,
|
|
19481
|
+
selectedKeys: shareSelectedKeys,
|
|
19482
|
+
popoverTitle: sharePopoverTitle ?? "\u9009\u62E9\u5206\u4EAB\u5185\u5BB9",
|
|
19483
|
+
cancelLabel: shareCancelLabel ?? "\u53D6\u6D88",
|
|
19484
|
+
confirmLabel: shareConfirmLabel ?? "\u786E\u5B9A",
|
|
19485
|
+
dialogTitle: shareDialogTitle ?? "\u5206\u4EAB\u4F1A\u8BAE\u5185\u5BB9",
|
|
19486
|
+
link: shareLink,
|
|
19487
|
+
copyLinkLabel: shareCopyLinkLabel ?? "\u590D\u5236\u94FE\u63A5",
|
|
19488
|
+
copiedLabel: shareCopiedLabel ?? "\u5DF2\u590D\u5236",
|
|
19489
|
+
mailLabel: shareMailLabel ?? "\u90AE\u4EF6",
|
|
19490
|
+
systemLabel: shareSystemLabel ?? "\u7CFB\u7EDF\u5206\u4EAB",
|
|
19491
|
+
onShare,
|
|
19492
|
+
onSelectionCommit: (keys) => onShareSelectionCommit?.(keys),
|
|
19493
|
+
onShareConfirm,
|
|
19494
|
+
onShareChannel
|
|
19495
|
+
}
|
|
19496
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Button2, { text: shareLabel, size: "small", onClick: () => onShare?.() }) : null
|
|
19497
|
+
] })
|
|
19498
|
+
] }),
|
|
19499
|
+
tabs.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)(import_jsx_runtime227.Fragment, { children: [
|
|
19500
|
+
/* @__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) => {
|
|
19501
|
+
const active = tab.key === activeTab;
|
|
19502
|
+
return /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
|
|
19503
|
+
"button",
|
|
19504
|
+
{
|
|
19505
|
+
type: "button",
|
|
19506
|
+
role: "tab",
|
|
19507
|
+
"aria-selected": active,
|
|
19508
|
+
className: cn(
|
|
19509
|
+
"flex-1 cursor-pointer rounded-md px-3 py-1 text-sm",
|
|
19510
|
+
active ? "bg-background shadow-sm" : "text-muted-foreground"
|
|
19511
|
+
),
|
|
19512
|
+
onClick: () => onTabChange(tab.key),
|
|
19513
|
+
children: tab.label
|
|
19514
|
+
},
|
|
19515
|
+
tab.key
|
|
19516
|
+
);
|
|
19517
|
+
}) }) }),
|
|
19518
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
|
|
19519
|
+
"div",
|
|
19520
|
+
{
|
|
19521
|
+
"data-slot": "recording-page-tab-body",
|
|
19522
|
+
className: "scrollbar-subtle min-h-0 flex-1 overflow-y-auto px-6 py-4",
|
|
19523
|
+
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)(
|
|
19524
|
+
TranscriptSegment,
|
|
19525
|
+
{
|
|
19526
|
+
segment,
|
|
19527
|
+
speaker: displaySpeaker(index),
|
|
19528
|
+
onRename: () => openRename(index)
|
|
19529
|
+
},
|
|
19530
|
+
segment.time ?? index
|
|
19531
|
+
)) }) : activeTabItem?.key === summaryTabKey && summary !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
|
|
19532
|
+
RecordingSummaryView,
|
|
19533
|
+
{
|
|
19534
|
+
summary,
|
|
19535
|
+
onMindmapAction,
|
|
19536
|
+
onMaterialClick,
|
|
19537
|
+
selectedTodoIds,
|
|
19538
|
+
onTodoToggle,
|
|
19539
|
+
onSummaryAction
|
|
19540
|
+
}
|
|
19541
|
+
) : activeTabItem?.key === insightTabKey && insight !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
|
|
19542
|
+
RecordingInsightView,
|
|
19543
|
+
{
|
|
19544
|
+
insight,
|
|
19545
|
+
onPerspectiveEdit,
|
|
19546
|
+
onPerspectiveApply,
|
|
19547
|
+
onInsightAction
|
|
19548
|
+
}
|
|
19549
|
+
) : 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)(
|
|
19550
|
+
RecordingTranslationView,
|
|
19551
|
+
{
|
|
19552
|
+
translation,
|
|
19553
|
+
onLanguageClick,
|
|
19554
|
+
onLanguageChange,
|
|
19555
|
+
onTranslationAction
|
|
19556
|
+
}
|
|
19557
|
+
) : null
|
|
19558
|
+
}
|
|
19559
|
+
)
|
|
19560
|
+
] }) : null,
|
|
19561
|
+
player !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime227.jsxs)(
|
|
19562
|
+
"div",
|
|
19563
|
+
{
|
|
19564
|
+
"data-slot": "recording-page-player",
|
|
19565
|
+
className: "flex shrink-0 items-center gap-3 border-t border-border px-6 py-3",
|
|
19566
|
+
children: [
|
|
19567
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Button2, { icon: "rotate-ccw", variant: "text", onClick: () => onSkipBack?.() }),
|
|
19568
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
|
|
19569
|
+
Button2,
|
|
19570
|
+
{
|
|
19571
|
+
icon: "play",
|
|
19572
|
+
style: { borderRadius: 999 },
|
|
19573
|
+
onClick: () => onPlay?.()
|
|
19574
|
+
}
|
|
19575
|
+
),
|
|
19576
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Button2, { icon: "rotate-cw", variant: "text", onClick: () => onSkipForward?.() }),
|
|
19577
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Text, { text: player.currentTime, size: "small", type: "secondary" }),
|
|
19578
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Progress2, { value: player.progress, style: { flex: 1 } }),
|
|
19579
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsx)(Text, { text: player.totalTime, size: "small", type: "secondary" })
|
|
19580
|
+
]
|
|
19581
|
+
}
|
|
19582
|
+
) : null,
|
|
19583
|
+
/* @__PURE__ */ (0, import_jsx_runtime227.jsx)(
|
|
19584
|
+
RecordingSpeakerDialog,
|
|
19585
|
+
{
|
|
19586
|
+
open: renameIndex !== null,
|
|
19587
|
+
title: speakerDialogTitle ?? "\u4FEE\u6539\u53D1\u8A00\u4EBA",
|
|
19588
|
+
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",
|
|
19589
|
+
speakers,
|
|
19590
|
+
selectedIndex: draftSpeakerIndex,
|
|
19591
|
+
customName: draftSpeakerName,
|
|
19592
|
+
inputPlaceholder: speakerInputPlaceholder ?? "\u8F93\u5165\u59D3\u540D",
|
|
19593
|
+
applyLabel: speakerApplyLabel ?? "\u5E94\u7528\u59D3\u540D",
|
|
19594
|
+
onSelect: setDraftSpeakerIndex,
|
|
19595
|
+
onInputName: setDraftSpeakerName,
|
|
19596
|
+
onCancel: () => setRenameIndex(null),
|
|
19597
|
+
onConfirm: confirmRename
|
|
19598
|
+
}
|
|
19599
|
+
)
|
|
19600
|
+
] });
|
|
19601
|
+
}
|
|
19602
|
+
|
|
19603
|
+
// src/components/business/RecordingPage/list.tsx
|
|
19604
|
+
var import_react80 = require("react");
|
|
19605
|
+
var import_jsx_runtime228 = require("react/jsx-runtime");
|
|
19606
|
+
function RecordingList({
|
|
19607
|
+
listTitle,
|
|
19608
|
+
selectLabel,
|
|
19609
|
+
selectDoneLabel,
|
|
19610
|
+
selectAllLabel,
|
|
19611
|
+
selectedCountText,
|
|
19612
|
+
deleteLabel,
|
|
19613
|
+
deleteConfirmTitle,
|
|
19614
|
+
deleteConfirmText,
|
|
19615
|
+
deleteCancelLabel,
|
|
19616
|
+
deleteConfirmLabel,
|
|
19617
|
+
selecting = false,
|
|
19618
|
+
selectedRecordingIds = [],
|
|
19619
|
+
onEnterSelectMode,
|
|
19620
|
+
onExitSelectMode,
|
|
19621
|
+
onToggleRecordingSelect,
|
|
19622
|
+
onToggleSelectAll,
|
|
19623
|
+
onDeleteSelected,
|
|
19624
|
+
filters,
|
|
19625
|
+
activeFilter,
|
|
19626
|
+
onFilterChange,
|
|
19627
|
+
processingText,
|
|
19628
|
+
processingHint,
|
|
19629
|
+
onProcessingClick,
|
|
19630
|
+
newRecordingLabel,
|
|
19631
|
+
onNewRecording,
|
|
19632
|
+
groups,
|
|
19633
|
+
activeRecordingId,
|
|
19634
|
+
onSelectRecording,
|
|
19635
|
+
listWidth,
|
|
19636
|
+
emptyText
|
|
19637
|
+
}) {
|
|
19638
|
+
const [deleteConfirmOpen, setDeleteConfirmOpen] = (0, import_react80.useState)(false);
|
|
19639
|
+
const renderRecordingItem = (item) => {
|
|
19640
|
+
const active = !selecting && item.id === activeRecordingId;
|
|
19641
|
+
const checked = selecting && selectedRecordingIds.includes(item.id);
|
|
19642
|
+
return /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(
|
|
19643
|
+
"button",
|
|
19644
|
+
{
|
|
19645
|
+
type: "button",
|
|
19646
|
+
"data-slot": "recording-item",
|
|
19647
|
+
"data-active": active || void 0,
|
|
19648
|
+
"aria-pressed": selecting ? checked : void 0,
|
|
19649
|
+
className: cn(
|
|
19650
|
+
"flex w-full cursor-pointer items-start gap-2 rounded-lg p-2 text-left",
|
|
19651
|
+
active ? "bg-background shadow-sm" : void 0
|
|
19652
|
+
),
|
|
19653
|
+
onClick: () => selecting ? onToggleRecordingSelect?.(item.id) : onSelectRecording(item.id),
|
|
19654
|
+
children: [
|
|
19655
|
+
selecting ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
|
|
19656
|
+
"span",
|
|
19657
|
+
{
|
|
19658
|
+
className: cn(
|
|
19659
|
+
"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full",
|
|
19660
|
+
checked ? "bg-success text-background" : "border border-border bg-background"
|
|
19661
|
+
),
|
|
19662
|
+
children: checked ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Icon, { name: "check", size: 12 }) : null
|
|
19663
|
+
}
|
|
19664
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Icon, { name: item.icon ?? "audio-lines", size: 18, className: "mt-0.5 shrink-0" }),
|
|
19665
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
|
|
19666
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
19667
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
|
|
19668
|
+
Text,
|
|
19669
|
+
{
|
|
19670
|
+
text: item.title,
|
|
19671
|
+
size: "small",
|
|
19672
|
+
strong: active || checked,
|
|
19673
|
+
className: "min-w-0 truncate"
|
|
19674
|
+
}
|
|
19675
|
+
),
|
|
19676
|
+
item.status !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
|
|
19677
|
+
Text,
|
|
19678
|
+
{
|
|
19679
|
+
text: item.status,
|
|
19680
|
+
size: "small",
|
|
19681
|
+
type: item.statusType ?? "secondary",
|
|
19682
|
+
className: "shrink-0"
|
|
19683
|
+
}
|
|
19684
|
+
) : null
|
|
19685
|
+
] }),
|
|
19686
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
19687
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Text, { text: item.time, size: "small", type: "secondary" }),
|
|
19688
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Text, { text: item.duration, size: "small", type: "secondary" })
|
|
19689
|
+
] })
|
|
19690
|
+
] })
|
|
19691
|
+
]
|
|
19692
|
+
},
|
|
19693
|
+
item.id
|
|
19694
|
+
);
|
|
19695
|
+
};
|
|
19696
|
+
return /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(
|
|
19697
|
+
"div",
|
|
19698
|
+
{
|
|
19699
|
+
"data-slot": "recording-page-list",
|
|
19700
|
+
className: "m-3 flex min-h-0 shrink-0 flex-col gap-3 rounded-xl bg-muted p-4",
|
|
19701
|
+
style: { width: listWidth },
|
|
19702
|
+
children: [
|
|
19703
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
19704
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Text, { text: listTitle, strong: true, size: "large" }),
|
|
19705
|
+
selecting ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
|
|
19706
|
+
Button2,
|
|
19707
|
+
{
|
|
19708
|
+
text: selectDoneLabel ?? "\u5B8C\u6210",
|
|
19709
|
+
variant: "link",
|
|
19710
|
+
size: "small",
|
|
19711
|
+
onClick: () => onExitSelectMode?.()
|
|
19712
|
+
}
|
|
19713
|
+
) : selectLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Button2, { text: selectLabel, variant: "link", size: "small", onClick: () => onEnterSelectMode?.() }) : null
|
|
19714
|
+
] }),
|
|
19715
|
+
selecting ? /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(
|
|
19716
|
+
"div",
|
|
19717
|
+
{
|
|
19718
|
+
"data-slot": "recording-page-selection-bar",
|
|
19719
|
+
className: "flex items-center justify-between",
|
|
19720
|
+
children: [
|
|
19721
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
|
|
19722
|
+
Text,
|
|
19723
|
+
{
|
|
19724
|
+
text: (selectedCountText ?? "\u5DF2\u9009 {count} \u6761").replace(
|
|
19725
|
+
"{count}",
|
|
19726
|
+
String(selectedRecordingIds.length)
|
|
19727
|
+
),
|
|
19728
|
+
size: "small",
|
|
19729
|
+
type: "secondary"
|
|
19730
|
+
}
|
|
19731
|
+
),
|
|
19732
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
|
|
19733
|
+
Button2,
|
|
19734
|
+
{
|
|
19735
|
+
text: selectAllLabel ?? "\u5168\u9009",
|
|
19736
|
+
variant: "link",
|
|
19737
|
+
size: "small",
|
|
19738
|
+
onClick: () => onToggleSelectAll?.()
|
|
19739
|
+
}
|
|
19740
|
+
)
|
|
19741
|
+
]
|
|
19742
|
+
}
|
|
19743
|
+
) : null,
|
|
19744
|
+
!selecting && filters.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)("div", { "data-slot": "recording-page-filters", className: "flex gap-2", children: filters.map((filter) => {
|
|
19745
|
+
const active = filter.key === activeFilter;
|
|
19746
|
+
return /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
|
|
19747
|
+
"button",
|
|
19748
|
+
{
|
|
19749
|
+
type: "button",
|
|
19750
|
+
"data-active": active || void 0,
|
|
19751
|
+
className: cn(
|
|
19752
|
+
"cursor-pointer rounded-full px-3 py-1 text-xs",
|
|
19753
|
+
active ? "bg-primary text-primary-foreground" : "bg-background"
|
|
19754
|
+
),
|
|
19755
|
+
onClick: () => onFilterChange(filter.key),
|
|
19756
|
+
children: filter.label
|
|
19757
|
+
},
|
|
19758
|
+
filter.key
|
|
19759
|
+
);
|
|
19760
|
+
}) }) : null,
|
|
19761
|
+
!selecting && processingText !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(
|
|
19762
|
+
"button",
|
|
19763
|
+
{
|
|
19764
|
+
type: "button",
|
|
19765
|
+
"data-slot": "recording-page-processing",
|
|
19766
|
+
className: "flex cursor-pointer items-center gap-2 rounded-lg bg-background p-3 text-left",
|
|
19767
|
+
onClick: () => onProcessingClick?.(),
|
|
19768
|
+
children: [
|
|
19769
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Icon, { name: "audio-lines", size: 18 }),
|
|
19770
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsxs)("div", { className: "flex flex-1 flex-col", children: [
|
|
19771
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Text, { text: processingText, size: "small", strong: true }),
|
|
19772
|
+
processingHint !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Text, { text: processingHint, size: "small", type: "secondary" }) : null
|
|
19773
|
+
] }),
|
|
19774
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Icon, { name: "chevron-right", size: 16, className: "text-muted-foreground" })
|
|
19775
|
+
]
|
|
19776
|
+
}
|
|
19777
|
+
) : null,
|
|
19778
|
+
!selecting && newRecordingLabel !== null && newRecordingLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
|
|
19779
|
+
Button2,
|
|
19780
|
+
{
|
|
19781
|
+
text: newRecordingLabel,
|
|
19782
|
+
icon: "mic",
|
|
19783
|
+
variant: "primary",
|
|
19784
|
+
className: "w-full",
|
|
19785
|
+
onClick: () => onNewRecording?.()
|
|
19786
|
+
}
|
|
19787
|
+
) : null,
|
|
19788
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
|
|
19789
|
+
"div",
|
|
19790
|
+
{
|
|
19791
|
+
"data-slot": "recording-page-groups",
|
|
19792
|
+
className: "scrollbar-subtle flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto",
|
|
19793
|
+
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: [
|
|
19794
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsx)(Text, { text: group.label, size: "small", type: "secondary", className: "px-1" }),
|
|
19795
|
+
group.items.map(renderRecordingItem)
|
|
19796
|
+
] }, group.key ?? group.label ?? groupIndex))
|
|
19797
|
+
}
|
|
19798
|
+
),
|
|
19799
|
+
selecting ? /* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(import_jsx_runtime228.Fragment, { children: [
|
|
19800
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
|
|
19801
|
+
Button2,
|
|
19802
|
+
{
|
|
19803
|
+
text: deleteLabel ?? "\u5220\u9664",
|
|
19804
|
+
variant: "primary",
|
|
19805
|
+
danger: true,
|
|
19806
|
+
className: "w-full shrink-0",
|
|
19807
|
+
onClick: () => setDeleteConfirmOpen(true)
|
|
19808
|
+
}
|
|
19809
|
+
),
|
|
19810
|
+
/* @__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: [
|
|
19811
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(AlertDialogHeader, { children: [
|
|
19812
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsx)(AlertDialogTitle, { children: deleteConfirmTitle ?? "\u5220\u9664\u5F55\u97F3" }),
|
|
19813
|
+
/* @__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)) })
|
|
19814
|
+
] }),
|
|
19815
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsxs)(AlertDialogFooter, { children: [
|
|
19816
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsx)(AlertDialogCancel, { children: deleteCancelLabel ?? "\u53D6\u6D88" }),
|
|
19817
|
+
/* @__PURE__ */ (0, import_jsx_runtime228.jsx)(
|
|
19818
|
+
AlertDialogAction,
|
|
19819
|
+
{
|
|
19820
|
+
variant: "destructive",
|
|
19821
|
+
onClick: () => onDeleteSelected?.(),
|
|
19822
|
+
children: deleteConfirmLabel ?? "\u5220\u9664"
|
|
19823
|
+
}
|
|
19824
|
+
)
|
|
19825
|
+
] })
|
|
19826
|
+
] }) })
|
|
19827
|
+
] }) : null
|
|
19828
|
+
]
|
|
19829
|
+
}
|
|
19830
|
+
);
|
|
19831
|
+
}
|
|
19832
|
+
|
|
19833
|
+
// src/components/business/RecordingPage/index.tsx
|
|
19834
|
+
var import_jsx_runtime229 = require("react/jsx-runtime");
|
|
19835
|
+
function RecordingPage({
|
|
19836
|
+
listTitle = "\u5F55\u97F3\u8BB0\u5F55\u5217\u8868",
|
|
19837
|
+
selectLabel,
|
|
19838
|
+
selectDoneLabel,
|
|
19839
|
+
selectAllLabel,
|
|
19840
|
+
selectedCountText,
|
|
19841
|
+
deleteLabel,
|
|
19842
|
+
deleteConfirmTitle,
|
|
19843
|
+
deleteConfirmText,
|
|
19844
|
+
deleteCancelLabel,
|
|
19845
|
+
deleteConfirmLabel,
|
|
19846
|
+
selectedRecordingIds,
|
|
19847
|
+
defaultSelectedRecordingIds,
|
|
19848
|
+
onRecordingSelectionChange,
|
|
19849
|
+
onDeleteRecordings,
|
|
19850
|
+
onSelectClick,
|
|
19851
|
+
filters = [],
|
|
19852
|
+
activeFilterKey,
|
|
19853
|
+
defaultActiveFilterKey,
|
|
19854
|
+
onFilterChange,
|
|
19855
|
+
processingText,
|
|
19856
|
+
processingHint,
|
|
19857
|
+
onProcessingClick,
|
|
19858
|
+
newRecordingLabel = "\u5F00\u59CB\u65B0\u5F55\u97F3",
|
|
19859
|
+
onNewRecording,
|
|
19860
|
+
groups = [],
|
|
19861
|
+
activeRecordingId,
|
|
19862
|
+
defaultActiveRecordingId,
|
|
19863
|
+
onSelectRecording,
|
|
19864
|
+
listWidth = 300,
|
|
19865
|
+
emptyText = "\u6682\u65E0\u5F55\u97F3",
|
|
19866
|
+
title,
|
|
19867
|
+
meta,
|
|
19868
|
+
editLabel,
|
|
19869
|
+
shareLabel,
|
|
19870
|
+
shareOptions,
|
|
19871
|
+
shareSelectedKeys,
|
|
19872
|
+
defaultShareSelectedKeys,
|
|
19873
|
+
sharePopoverTitle,
|
|
19874
|
+
shareCancelLabel,
|
|
19875
|
+
shareConfirmLabel,
|
|
19876
|
+
shareDialogTitle,
|
|
19877
|
+
shareLink,
|
|
19878
|
+
shareCopyLinkLabel,
|
|
19879
|
+
shareCopiedLabel,
|
|
19880
|
+
shareMailLabel,
|
|
19881
|
+
shareSystemLabel,
|
|
19882
|
+
onShareConfirm,
|
|
19883
|
+
onShareChannel,
|
|
19884
|
+
onEdit,
|
|
19885
|
+
onShare,
|
|
19886
|
+
tabs = [],
|
|
19887
|
+
activeTabKey,
|
|
19888
|
+
defaultActiveTabKey,
|
|
19889
|
+
onTabChange,
|
|
19890
|
+
transcriptTabKey = "transcript",
|
|
19891
|
+
segments = [],
|
|
19892
|
+
speakers,
|
|
19893
|
+
speakerDialogTitle,
|
|
19894
|
+
speakerDialogHint,
|
|
19895
|
+
speakerInputPlaceholder,
|
|
19896
|
+
speakerApplyLabel,
|
|
19897
|
+
onSpeakerChange,
|
|
19898
|
+
summary,
|
|
19899
|
+
summaryTabKey = "summary",
|
|
19900
|
+
onMindmapAction,
|
|
19901
|
+
onMaterialClick,
|
|
19902
|
+
onTodoClick,
|
|
19903
|
+
selectedTodoIds,
|
|
19904
|
+
defaultSelectedTodoIds,
|
|
19905
|
+
onTodoSelectionChange,
|
|
19906
|
+
onSummaryAction,
|
|
19907
|
+
insight,
|
|
19908
|
+
insightTabKey = "ai",
|
|
19909
|
+
onPerspectiveEdit,
|
|
19910
|
+
onPerspectiveApply,
|
|
19911
|
+
onInsightAction,
|
|
19912
|
+
memory,
|
|
19913
|
+
memoryTabKey = "knowledge",
|
|
19914
|
+
onMemoryAction,
|
|
19915
|
+
translation,
|
|
19916
|
+
translationTabKey = "translation",
|
|
19917
|
+
onLanguageClick,
|
|
19918
|
+
onLanguageChange,
|
|
19919
|
+
onTranslationAction,
|
|
19920
|
+
player,
|
|
19921
|
+
onPlay,
|
|
19922
|
+
onSkipBack,
|
|
19923
|
+
onSkipForward,
|
|
19924
|
+
className,
|
|
19925
|
+
style
|
|
19926
|
+
}) {
|
|
19927
|
+
const filterControlled = activeFilterKey !== void 0;
|
|
19928
|
+
const [innerFilter, setInnerFilter] = (0, import_react81.useState)(
|
|
19929
|
+
defaultActiveFilterKey ?? filters[0]?.key
|
|
19930
|
+
);
|
|
19931
|
+
const activeFilter = filterControlled ? activeFilterKey : innerFilter;
|
|
19932
|
+
const setActiveFilter = (next) => {
|
|
19933
|
+
if (!filterControlled) setInnerFilter(next);
|
|
19934
|
+
onFilterChange?.(next);
|
|
19935
|
+
};
|
|
19936
|
+
const recControlled = activeRecordingId !== void 0;
|
|
19937
|
+
const [innerRec, setInnerRec] = (0, import_react81.useState)(defaultActiveRecordingId);
|
|
19938
|
+
const activeRec = recControlled ? activeRecordingId : innerRec;
|
|
19939
|
+
const setActiveRec = (next) => {
|
|
19940
|
+
if (!recControlled) setInnerRec(next);
|
|
19941
|
+
onSelectRecording?.(next);
|
|
19942
|
+
};
|
|
19943
|
+
const tabControlled = activeTabKey !== void 0;
|
|
19944
|
+
const [innerTab, setInnerTab] = (0, import_react81.useState)(defaultActiveTabKey ?? tabs[0]?.key);
|
|
19945
|
+
const activeTab = tabControlled ? activeTabKey : innerTab;
|
|
19946
|
+
const setActiveTab = (next) => {
|
|
19947
|
+
if (!tabControlled) setInnerTab(next);
|
|
19948
|
+
onTabChange?.(next);
|
|
19949
|
+
};
|
|
19950
|
+
const todoControlled = selectedTodoIds !== void 0;
|
|
19951
|
+
const [innerTodos, setInnerTodos] = (0, import_react81.useState)(
|
|
19952
|
+
() => defaultSelectedTodoIds ?? (summary?.todos ?? []).flatMap(
|
|
19953
|
+
(todo, index) => todo.done === true ? [todo.id ?? index] : []
|
|
19954
|
+
)
|
|
19955
|
+
);
|
|
19956
|
+
const selectedTodos = todoControlled ? selectedTodoIds : innerTodos;
|
|
19957
|
+
const toggleTodo = (id) => {
|
|
19958
|
+
const next = selectedTodos.includes(id) ? selectedTodos.filter((item) => item !== id) : [...selectedTodos, id];
|
|
19959
|
+
if (!todoControlled) setInnerTodos(next);
|
|
19960
|
+
onTodoClick?.(id);
|
|
19961
|
+
onTodoSelectionChange?.(next);
|
|
19962
|
+
};
|
|
19963
|
+
const shareControlled = shareSelectedKeys !== void 0;
|
|
19964
|
+
const [innerShareKeys, setInnerShareKeys] = (0, import_react81.useState)(
|
|
19965
|
+
() => defaultShareSelectedKeys ?? (shareOptions ?? []).map((option) => option.key)
|
|
19966
|
+
);
|
|
19967
|
+
const shareKeys = shareControlled ? shareSelectedKeys : innerShareKeys;
|
|
19968
|
+
const commitShareKeys = (next) => {
|
|
19969
|
+
if (!shareControlled) setInnerShareKeys(next);
|
|
19970
|
+
};
|
|
19971
|
+
const [selecting, setSelecting] = (0, import_react81.useState)(false);
|
|
19972
|
+
const recSelControlled = selectedRecordingIds !== void 0;
|
|
19973
|
+
const [innerSelectedRecs, setInnerSelectedRecs] = (0, import_react81.useState)(
|
|
19974
|
+
() => defaultSelectedRecordingIds ?? []
|
|
19975
|
+
);
|
|
19976
|
+
const selectedRecs = recSelControlled ? selectedRecordingIds : innerSelectedRecs;
|
|
19977
|
+
const commitSelectedRecs = (next) => {
|
|
19978
|
+
if (!recSelControlled) setInnerSelectedRecs(next);
|
|
19979
|
+
onRecordingSelectionChange?.(next);
|
|
19980
|
+
};
|
|
19981
|
+
const allRecordingIds = groups.flatMap((group) => group.items.map((item) => item.id));
|
|
19982
|
+
const toggleRecordingSelect = (id) => {
|
|
19983
|
+
commitSelectedRecs(
|
|
19984
|
+
selectedRecs.includes(id) ? selectedRecs.filter((item) => item !== id) : [...selectedRecs, id]
|
|
19985
|
+
);
|
|
19986
|
+
};
|
|
19987
|
+
const toggleSelectAll = () => {
|
|
19988
|
+
commitSelectedRecs(
|
|
19989
|
+
selectedRecs.length === allRecordingIds.length ? [] : allRecordingIds
|
|
19990
|
+
);
|
|
19991
|
+
};
|
|
19992
|
+
return /* @__PURE__ */ (0, import_jsx_runtime229.jsxs)(
|
|
19993
|
+
"div",
|
|
19994
|
+
{
|
|
19995
|
+
"data-slot": "recording-page",
|
|
19996
|
+
className: cn("flex h-full w-full min-h-0 items-stretch", className),
|
|
19997
|
+
style,
|
|
19998
|
+
children: [
|
|
19999
|
+
/* @__PURE__ */ (0, import_jsx_runtime229.jsx)(
|
|
20000
|
+
RecordingList,
|
|
20001
|
+
{
|
|
20002
|
+
listTitle,
|
|
20003
|
+
selectLabel,
|
|
20004
|
+
selectDoneLabel,
|
|
20005
|
+
selectAllLabel,
|
|
20006
|
+
selectedCountText,
|
|
20007
|
+
deleteLabel,
|
|
20008
|
+
deleteConfirmTitle,
|
|
20009
|
+
deleteConfirmText,
|
|
20010
|
+
deleteCancelLabel,
|
|
20011
|
+
deleteConfirmLabel,
|
|
20012
|
+
selecting,
|
|
20013
|
+
selectedRecordingIds: selectedRecs,
|
|
20014
|
+
onEnterSelectMode: () => {
|
|
20015
|
+
setSelecting(true);
|
|
20016
|
+
onSelectClick?.();
|
|
20017
|
+
},
|
|
20018
|
+
onExitSelectMode: () => setSelecting(false),
|
|
20019
|
+
onToggleRecordingSelect: toggleRecordingSelect,
|
|
20020
|
+
onToggleSelectAll: toggleSelectAll,
|
|
20021
|
+
onDeleteSelected: () => onDeleteRecordings?.(selectedRecs),
|
|
20022
|
+
filters,
|
|
20023
|
+
activeFilter,
|
|
20024
|
+
onFilterChange: setActiveFilter,
|
|
20025
|
+
processingText,
|
|
20026
|
+
processingHint,
|
|
20027
|
+
onProcessingClick,
|
|
20028
|
+
newRecordingLabel,
|
|
20029
|
+
onNewRecording,
|
|
20030
|
+
groups,
|
|
20031
|
+
activeRecordingId: activeRec,
|
|
20032
|
+
onSelectRecording: setActiveRec,
|
|
20033
|
+
listWidth,
|
|
20034
|
+
emptyText
|
|
20035
|
+
}
|
|
20036
|
+
),
|
|
20037
|
+
/* @__PURE__ */ (0, import_jsx_runtime229.jsx)(
|
|
20038
|
+
RecordingDetail,
|
|
20039
|
+
{
|
|
20040
|
+
title,
|
|
20041
|
+
meta,
|
|
20042
|
+
editLabel,
|
|
20043
|
+
shareLabel,
|
|
20044
|
+
shareOptions,
|
|
20045
|
+
shareSelectedKeys: shareKeys,
|
|
20046
|
+
sharePopoverTitle,
|
|
20047
|
+
shareCancelLabel,
|
|
20048
|
+
shareConfirmLabel,
|
|
20049
|
+
shareDialogTitle,
|
|
20050
|
+
shareLink,
|
|
20051
|
+
shareCopyLinkLabel,
|
|
20052
|
+
shareCopiedLabel,
|
|
20053
|
+
shareMailLabel,
|
|
20054
|
+
shareSystemLabel,
|
|
20055
|
+
onShareSelectionCommit: commitShareKeys,
|
|
20056
|
+
onShareConfirm,
|
|
20057
|
+
onShareChannel,
|
|
20058
|
+
onEdit,
|
|
20059
|
+
onShare,
|
|
20060
|
+
tabs,
|
|
20061
|
+
activeTab,
|
|
20062
|
+
onTabChange: setActiveTab,
|
|
20063
|
+
transcriptTabKey,
|
|
20064
|
+
segments,
|
|
20065
|
+
speakers,
|
|
20066
|
+
speakerDialogTitle,
|
|
20067
|
+
speakerDialogHint,
|
|
20068
|
+
speakerInputPlaceholder,
|
|
20069
|
+
speakerApplyLabel,
|
|
20070
|
+
onSpeakerChange,
|
|
20071
|
+
summary,
|
|
20072
|
+
summaryTabKey,
|
|
20073
|
+
onMindmapAction,
|
|
20074
|
+
onMaterialClick,
|
|
20075
|
+
selectedTodoIds: selectedTodos,
|
|
20076
|
+
onTodoToggle: toggleTodo,
|
|
20077
|
+
onSummaryAction,
|
|
20078
|
+
insight,
|
|
20079
|
+
insightTabKey,
|
|
20080
|
+
onPerspectiveEdit,
|
|
20081
|
+
onPerspectiveApply,
|
|
20082
|
+
onInsightAction,
|
|
20083
|
+
memory,
|
|
20084
|
+
memoryTabKey,
|
|
20085
|
+
onMemoryAction,
|
|
20086
|
+
translation,
|
|
20087
|
+
translationTabKey,
|
|
20088
|
+
onLanguageClick,
|
|
20089
|
+
onLanguageChange,
|
|
20090
|
+
onTranslationAction,
|
|
20091
|
+
player,
|
|
20092
|
+
onPlay,
|
|
20093
|
+
onSkipBack,
|
|
20094
|
+
onSkipForward
|
|
20095
|
+
}
|
|
20096
|
+
)
|
|
20097
|
+
]
|
|
20098
|
+
}
|
|
20099
|
+
);
|
|
20100
|
+
}
|
|
20101
|
+
|
|
20102
|
+
// src/components/business/RuleConfig/index.tsx
|
|
20103
|
+
var import_lucide_react43 = require("lucide-react");
|
|
20104
|
+
var import_react82 = require("react");
|
|
20105
|
+
var import_jsx_runtime230 = require("react/jsx-runtime");
|
|
20106
|
+
var isBlank = (v) => v == null || String(v).trim() === "";
|
|
20107
|
+
function isValueMissing(condition) {
|
|
20108
|
+
const { opt, value } = condition;
|
|
20109
|
+
if (NO_VALUE_OPT.includes(opt)) return false;
|
|
20110
|
+
if (opt === "BETWEEN") {
|
|
20111
|
+
const [a, b] = normalizeBetweenValue(value);
|
|
20112
|
+
return isBlank(a) || isBlank(b);
|
|
20113
|
+
}
|
|
20114
|
+
if (Array.isArray(value)) return value.length === 0 || value.every(isBlank);
|
|
20115
|
+
return isBlank(value);
|
|
20116
|
+
}
|
|
20117
|
+
function getConditionIssue(condition) {
|
|
20118
|
+
const missingValue = isValueMissing(condition);
|
|
20119
|
+
const missingScore = condition.score == null || Number.isNaN(condition.score);
|
|
20120
|
+
if (!missingValue && !missingScore) return null;
|
|
20121
|
+
return { missingValue, missingScore };
|
|
20122
|
+
}
|
|
20123
|
+
var OPERATOR_VALUES = [
|
|
20124
|
+
"GREATER",
|
|
20125
|
+
"GREATER_EQUAL",
|
|
20126
|
+
"LESS_EQUAL",
|
|
20127
|
+
"LESS",
|
|
20128
|
+
"EQUAL",
|
|
20129
|
+
"IN",
|
|
20130
|
+
"NOT_IN",
|
|
20131
|
+
"UNEQUAL",
|
|
20132
|
+
"LIKE",
|
|
20133
|
+
"NULL",
|
|
20134
|
+
"HASVAL",
|
|
20135
|
+
"NOTNULL",
|
|
20136
|
+
"BETWEEN"
|
|
20137
|
+
];
|
|
20138
|
+
var NUMERIC_OPT = [
|
|
20139
|
+
"GREATER",
|
|
20140
|
+
"LESS",
|
|
20141
|
+
"LESS_EQUAL",
|
|
20142
|
+
"GREATER_EQUAL",
|
|
20143
|
+
"UNEQUAL"
|
|
20144
|
+
];
|
|
20145
|
+
var NO_VALUE_OPT = ["NULL", "HASVAL", "NOTNULL"];
|
|
20146
|
+
var MULTI_VALUE_OPT = ["IN", "NOT_IN"];
|
|
20147
|
+
var OPERATOR_LABELS2 = {
|
|
20148
|
+
GREATER: "\u5927\u4E8E",
|
|
20149
|
+
GREATER_EQUAL: "\u5927\u4E8E\u7B49\u4E8E",
|
|
20150
|
+
LESS_EQUAL: "\u5C0F\u4E8E\u7B49\u4E8E",
|
|
20151
|
+
LESS: "\u5C0F\u4E8E",
|
|
20152
|
+
EQUAL: "\u7B49\u4E8E",
|
|
20153
|
+
IN: "\u5305\u542B",
|
|
20154
|
+
NOT_IN: "\u4E0D\u5305\u542B",
|
|
20155
|
+
UNEQUAL: "\u4E0D\u7B49\u4E8E",
|
|
20156
|
+
LIKE: "\u7C7B\u4F3C",
|
|
20157
|
+
NULL: "\u4E3A\u7A7A",
|
|
20158
|
+
HASVAL: "\u6709\u503C",
|
|
20159
|
+
NOTNULL: "\u4E0D\u4E3A\u7A7A",
|
|
20160
|
+
BETWEEN: "\u8303\u56F4"
|
|
20161
|
+
};
|
|
20162
|
+
function operatorLabel2(operator) {
|
|
20163
|
+
return OPERATOR_LABELS2[operator] ?? operator;
|
|
20164
|
+
}
|
|
20165
|
+
var _key = 0;
|
|
20166
|
+
var nextKey = () => ++_key;
|
|
20167
|
+
var defaultCondition = () => ({ key: nextKey(), opt: "EQUAL" });
|
|
20168
|
+
function normalizeBetweenValue(value) {
|
|
20169
|
+
if (Array.isArray(value)) return [value[0], value[1]];
|
|
20170
|
+
if (typeof value === "string" && value.includes(",")) {
|
|
20171
|
+
const [a, b] = value.split(",");
|
|
20172
|
+
return [a?.trim(), b?.trim()];
|
|
20173
|
+
}
|
|
20174
|
+
if (value == null || value === "") return [void 0, void 0];
|
|
20175
|
+
return [value, void 0];
|
|
20176
|
+
}
|
|
20177
|
+
function formatConditionValue2(condition) {
|
|
20178
|
+
const { opt, value } = condition;
|
|
20179
|
+
if (value == null) return "-";
|
|
20180
|
+
if (opt === "BETWEEN") {
|
|
20181
|
+
const [a, b] = normalizeBetweenValue(value);
|
|
20182
|
+
return `${a ?? "-"} ~ ${b ?? "-"}`;
|
|
20183
|
+
}
|
|
20184
|
+
if (Array.isArray(value)) return value.join(", ");
|
|
20185
|
+
return String(value);
|
|
20186
|
+
}
|
|
20187
|
+
function RuleConfig({ value, onChange, disabled, size = "middle" }) {
|
|
20188
|
+
const rawConditions = value?.ruleConditions;
|
|
20189
|
+
const conditions = (0, import_react82.useMemo)(() => {
|
|
20190
|
+
if (!rawConditions?.length) return [defaultCondition()];
|
|
20191
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20192
|
+
return rawConditions.map((c) => {
|
|
20193
|
+
if (c.key != null && !seen.has(c.key)) {
|
|
20194
|
+
seen.add(c.key);
|
|
20195
|
+
return c;
|
|
20196
|
+
}
|
|
20197
|
+
const key = nextKey();
|
|
20198
|
+
seen.add(key);
|
|
20199
|
+
return { ...c, key };
|
|
20200
|
+
});
|
|
20201
|
+
}, [rawConditions]);
|
|
20202
|
+
const initScore = value?.score ?? 1;
|
|
20203
|
+
const [scoreText, setScoreText] = (0, import_react82.useState)(String(initScore));
|
|
20204
|
+
const lastScoreRef = (0, import_react82.useRef)(value?.score);
|
|
20205
|
+
(0, import_react82.useEffect)(() => {
|
|
20206
|
+
if (value?.score === lastScoreRef.current) return;
|
|
20207
|
+
lastScoreRef.current = value?.score;
|
|
20208
|
+
setScoreText(value?.score == null ? "" : String(value.score));
|
|
20209
|
+
}, [value?.score]);
|
|
20210
|
+
const commitScore = (0, import_react82.useCallback)(
|
|
20211
|
+
(score) => {
|
|
20212
|
+
lastScoreRef.current = score;
|
|
20213
|
+
onChange?.({ score, ruleConditions: conditions });
|
|
20214
|
+
},
|
|
20215
|
+
[onChange, conditions]
|
|
20216
|
+
);
|
|
20217
|
+
const normalizeScore = (n) => Math.min(1e3, Math.max(1, Math.round(n)));
|
|
20218
|
+
const handleScoreTextChange = (text) => {
|
|
20219
|
+
setScoreText(text);
|
|
20220
|
+
if (text === "") return;
|
|
20221
|
+
const n = Number(text);
|
|
20222
|
+
if (Number.isFinite(n) && n >= 1 && n <= 1e3 && Number.isInteger(n)) {
|
|
20223
|
+
commitScore(n);
|
|
20224
|
+
}
|
|
20225
|
+
};
|
|
20226
|
+
const handleScoreBlur = () => {
|
|
20227
|
+
const n = scoreText.trim() === "" ? NaN : Number(scoreText);
|
|
20228
|
+
const next = Number.isFinite(n) ? normalizeScore(n) : 1;
|
|
20229
|
+
setScoreText(String(next));
|
|
20230
|
+
if (next !== lastScoreRef.current) commitScore(next);
|
|
20231
|
+
};
|
|
20232
|
+
const update = (0, import_react82.useCallback)(
|
|
20233
|
+
(next, nextScore) => onChange?.({
|
|
20234
|
+
score: nextScore ?? initScore,
|
|
20235
|
+
ruleConditions: next
|
|
20236
|
+
}),
|
|
20237
|
+
[onChange, initScore]
|
|
20238
|
+
);
|
|
20239
|
+
const handleOptChange = (key, opt) => {
|
|
20240
|
+
update(
|
|
20241
|
+
conditions.map(
|
|
20242
|
+
(c) => c.key === key ? { ...c, opt, value: opt === "BETWEEN" ? [] : void 0 } : c
|
|
20243
|
+
)
|
|
20244
|
+
);
|
|
20245
|
+
};
|
|
20246
|
+
const handleValueChange = (key, val) => {
|
|
20247
|
+
update(conditions.map((c) => c.key === key ? { ...c, value: val } : c));
|
|
20248
|
+
};
|
|
20249
|
+
const handleScoreChange = (key, score) => {
|
|
20250
|
+
update(
|
|
20251
|
+
conditions.map((c) => c.key === key ? { ...c, score } : c)
|
|
20252
|
+
);
|
|
20253
|
+
};
|
|
20254
|
+
const handleAdd = () => update([...conditions, defaultCondition()]);
|
|
20255
|
+
const handleDelete = (key) => update(conditions.filter((c) => c.key !== key));
|
|
20256
|
+
if (disabled) {
|
|
20257
|
+
return /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("div", { className: "space-y-2 text-sm", children: [
|
|
20258
|
+
/* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("div", { className: "flex items-center gap-2 pb-2 border-b", children: [
|
|
20259
|
+
/* @__PURE__ */ (0, import_jsx_runtime230.jsx)("span", { className: "text-muted-foreground", children: "\u6743\u91CD" }),
|
|
20260
|
+
/* @__PURE__ */ (0, import_jsx_runtime230.jsx)("span", { className: "font-medium", children: initScore })
|
|
20261
|
+
] }),
|
|
20262
|
+
conditions.map((condition) => /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
20263
|
+
/* @__PURE__ */ (0, import_jsx_runtime230.jsx)("span", { children: operatorLabel2(condition.opt) }),
|
|
20264
|
+
!NO_VALUE_OPT.includes(condition.opt) && /* @__PURE__ */ (0, import_jsx_runtime230.jsx)("span", { className: "font-medium", children: formatConditionValue2(condition) }),
|
|
20265
|
+
/* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("span", { className: "text-muted-foreground", children: [
|
|
20266
|
+
"\u8BC4\u5206: ",
|
|
20267
|
+
condition.score ?? "-"
|
|
20268
|
+
] })
|
|
20269
|
+
] }, condition.key))
|
|
20270
|
+
] });
|
|
20271
|
+
}
|
|
20272
|
+
return /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("div", { className: "space-y-2", children: [
|
|
20273
|
+
/* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("div", { className: "flex items-center gap-1 pb-2 border-b gap-2", children: [
|
|
20274
|
+
/* @__PURE__ */ (0, import_jsx_runtime230.jsx)("span", { className: "text-sm shrink-0", children: "\u6743\u91CD" }),
|
|
20275
|
+
/* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
|
|
20276
|
+
Input,
|
|
20277
|
+
{
|
|
20278
|
+
type: "number",
|
|
20279
|
+
className: cn("w-48", CONTROL_SIZE_BOX[size]),
|
|
20280
|
+
min: 1,
|
|
20281
|
+
max: 1e3,
|
|
20282
|
+
step: 1,
|
|
20283
|
+
value: scoreText,
|
|
20284
|
+
disabled,
|
|
20285
|
+
placeholder: "\u8BF7\u8F93\u5165\u6743\u91CD",
|
|
20286
|
+
onChange: (e) => handleScoreTextChange(e.target.value),
|
|
20287
|
+
onBlur: handleScoreBlur
|
|
20288
|
+
}
|
|
20289
|
+
)
|
|
18623
20290
|
] }),
|
|
18624
|
-
conditions.map((condition) => /* @__PURE__ */ (0,
|
|
20291
|
+
conditions.map((condition) => /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
|
|
18625
20292
|
ConditionRow2,
|
|
18626
20293
|
{
|
|
18627
20294
|
condition,
|
|
@@ -18636,7 +20303,7 @@ function RuleConfig({ value, onChange, disabled, size = "middle" }) {
|
|
|
18636
20303
|
},
|
|
18637
20304
|
condition.key
|
|
18638
20305
|
)),
|
|
18639
|
-
!disabled && /* @__PURE__ */ (0,
|
|
20306
|
+
!disabled && /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)(
|
|
18640
20307
|
Button,
|
|
18641
20308
|
{
|
|
18642
20309
|
type: "button",
|
|
@@ -18645,7 +20312,7 @@ function RuleConfig({ value, onChange, disabled, size = "middle" }) {
|
|
|
18645
20312
|
className: "h-auto p-0 text-sm mt-1",
|
|
18646
20313
|
onClick: handleAdd,
|
|
18647
20314
|
children: [
|
|
18648
|
-
/* @__PURE__ */ (0,
|
|
20315
|
+
/* @__PURE__ */ (0, import_jsx_runtime230.jsx)(import_lucide_react43.Plus, { className: "h-3.5 w-3.5" }),
|
|
18649
20316
|
"\u6DFB\u52A0\u6761\u4EF6"
|
|
18650
20317
|
]
|
|
18651
20318
|
}
|
|
@@ -18666,9 +20333,9 @@ function ConditionRow2({
|
|
|
18666
20333
|
const { opt, value, score } = condition;
|
|
18667
20334
|
const missingValue = !disabled && !!issue?.missingValue;
|
|
18668
20335
|
const missingScore = !disabled && !!issue?.missingScore;
|
|
18669
|
-
return /* @__PURE__ */ (0,
|
|
18670
|
-
/* @__PURE__ */ (0,
|
|
18671
|
-
/* @__PURE__ */ (0,
|
|
20336
|
+
return /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("div", { className: "space-y-1", children: [
|
|
20337
|
+
/* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
20338
|
+
/* @__PURE__ */ (0, import_jsx_runtime230.jsxs)(
|
|
18672
20339
|
Select,
|
|
18673
20340
|
{
|
|
18674
20341
|
items: OPERATOR_VALUES.map((op) => ({
|
|
@@ -18679,23 +20346,23 @@ function ConditionRow2({
|
|
|
18679
20346
|
onValueChange: (v) => onOptChange(v),
|
|
18680
20347
|
disabled,
|
|
18681
20348
|
children: [
|
|
18682
|
-
/* @__PURE__ */ (0,
|
|
20349
|
+
/* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
|
|
18683
20350
|
SelectTrigger,
|
|
18684
20351
|
{
|
|
18685
20352
|
size: CONTROL_SIZE_SELECT_ATTR[size],
|
|
18686
20353
|
className: cn("w-36 shrink-0", CONTROL_SIZE_TRIGGER_TEXT[size]),
|
|
18687
|
-
children: /* @__PURE__ */ (0,
|
|
20354
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(SelectValue, {})
|
|
18688
20355
|
}
|
|
18689
20356
|
),
|
|
18690
|
-
/* @__PURE__ */ (0,
|
|
20357
|
+
/* @__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)) })
|
|
18691
20358
|
]
|
|
18692
20359
|
}
|
|
18693
20360
|
),
|
|
18694
|
-
!NO_VALUE_OPT.includes(opt) && /* @__PURE__ */ (0,
|
|
20361
|
+
!NO_VALUE_OPT.includes(opt) && /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
|
|
18695
20362
|
"div",
|
|
18696
20363
|
{
|
|
18697
20364
|
className: "w-[30%]" + (missingValue ? " [&_input]:border-destructive" : ""),
|
|
18698
|
-
children: /* @__PURE__ */ (0,
|
|
20365
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
|
|
18699
20366
|
ValueInput,
|
|
18700
20367
|
{
|
|
18701
20368
|
opt,
|
|
@@ -18707,7 +20374,7 @@ function ConditionRow2({
|
|
|
18707
20374
|
)
|
|
18708
20375
|
}
|
|
18709
20376
|
),
|
|
18710
|
-
/* @__PURE__ */ (0,
|
|
20377
|
+
/* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
|
|
18711
20378
|
Input,
|
|
18712
20379
|
{
|
|
18713
20380
|
type: "number",
|
|
@@ -18725,7 +20392,7 @@ function ConditionRow2({
|
|
|
18725
20392
|
)
|
|
18726
20393
|
}
|
|
18727
20394
|
),
|
|
18728
|
-
showDelete && !disabled && /* @__PURE__ */ (0,
|
|
20395
|
+
showDelete && !disabled && /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
|
|
18729
20396
|
Button,
|
|
18730
20397
|
{
|
|
18731
20398
|
type: "button",
|
|
@@ -18733,11 +20400,11 @@ function ConditionRow2({
|
|
|
18733
20400
|
size: "icon",
|
|
18734
20401
|
className: "h-8 w-8 shrink-0 text-muted-foreground hover:text-destructive",
|
|
18735
20402
|
onClick: onDelete,
|
|
18736
|
-
children: /* @__PURE__ */ (0,
|
|
20403
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(import_lucide_react43.Trash2, { className: "h-4 w-4" })
|
|
18737
20404
|
}
|
|
18738
20405
|
)
|
|
18739
20406
|
] }),
|
|
18740
|
-
!disabled && issue && /* @__PURE__ */ (0,
|
|
20407
|
+
!disabled && issue && /* @__PURE__ */ (0, import_jsx_runtime230.jsx)("p", { className: "text-xs text-destructive", children: [
|
|
18741
20408
|
missingValue ? "\u8BF7\u586B\u5199\u53D6\u503C" : null,
|
|
18742
20409
|
missingScore ? "\u8BF7\u586B\u5199\u8BC4\u5206" : null
|
|
18743
20410
|
].filter(Boolean).join("\uFF1B") })
|
|
@@ -18749,8 +20416,8 @@ function ValueInput({ opt, value, disabled, size, onChange }) {
|
|
|
18749
20416
|
}
|
|
18750
20417
|
if (opt === "BETWEEN") {
|
|
18751
20418
|
const [v1, v2] = normalizeBetweenValue(value);
|
|
18752
|
-
return /* @__PURE__ */ (0,
|
|
18753
|
-
/* @__PURE__ */ (0,
|
|
20419
|
+
return /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
20420
|
+
/* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
|
|
18754
20421
|
Input,
|
|
18755
20422
|
{
|
|
18756
20423
|
type: "number",
|
|
@@ -18760,8 +20427,8 @@ function ValueInput({ opt, value, disabled, size, onChange }) {
|
|
|
18760
20427
|
onChange: (e) => onChange([e.target.valueAsNumber, v2])
|
|
18761
20428
|
}
|
|
18762
20429
|
),
|
|
18763
|
-
/* @__PURE__ */ (0,
|
|
18764
|
-
/* @__PURE__ */ (0,
|
|
20430
|
+
/* @__PURE__ */ (0, import_jsx_runtime230.jsx)("span", { className: "text-muted-foreground text-sm shrink-0", children: "~" }),
|
|
20431
|
+
/* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
|
|
18765
20432
|
Input,
|
|
18766
20433
|
{
|
|
18767
20434
|
type: "number",
|
|
@@ -18774,7 +20441,7 @@ function ValueInput({ opt, value, disabled, size, onChange }) {
|
|
|
18774
20441
|
] });
|
|
18775
20442
|
}
|
|
18776
20443
|
if (MULTI_VALUE_OPT.includes(opt)) {
|
|
18777
|
-
return /* @__PURE__ */ (0,
|
|
20444
|
+
return /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
|
|
18778
20445
|
TagInput,
|
|
18779
20446
|
{
|
|
18780
20447
|
value: value ?? [],
|
|
@@ -18785,7 +20452,7 @@ function ValueInput({ opt, value, disabled, size, onChange }) {
|
|
|
18785
20452
|
);
|
|
18786
20453
|
}
|
|
18787
20454
|
if (NUMERIC_OPT.includes(opt)) {
|
|
18788
|
-
return /* @__PURE__ */ (0,
|
|
20455
|
+
return /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
|
|
18789
20456
|
Input,
|
|
18790
20457
|
{
|
|
18791
20458
|
type: "number",
|
|
@@ -18796,7 +20463,7 @@ function ValueInput({ opt, value, disabled, size, onChange }) {
|
|
|
18796
20463
|
}
|
|
18797
20464
|
);
|
|
18798
20465
|
}
|
|
18799
|
-
return /* @__PURE__ */ (0,
|
|
20466
|
+
return /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
|
|
18800
20467
|
Input,
|
|
18801
20468
|
{
|
|
18802
20469
|
type: "text",
|
|
@@ -18813,7 +20480,7 @@ function TagInput({
|
|
|
18813
20480
|
size,
|
|
18814
20481
|
onChange
|
|
18815
20482
|
}) {
|
|
18816
|
-
const [input, setInput] = (0,
|
|
20483
|
+
const [input, setInput] = (0, import_react82.useState)("");
|
|
18817
20484
|
const addTag = () => {
|
|
18818
20485
|
const tag = input.trim();
|
|
18819
20486
|
if (tag && !value.includes(tag)) {
|
|
@@ -18822,7 +20489,7 @@ function TagInput({
|
|
|
18822
20489
|
setInput("");
|
|
18823
20490
|
};
|
|
18824
20491
|
const removeTag = (tag) => onChange(value.filter((t) => t !== tag));
|
|
18825
|
-
return /* @__PURE__ */ (0,
|
|
20492
|
+
return /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)(
|
|
18826
20493
|
"div",
|
|
18827
20494
|
{
|
|
18828
20495
|
className: cn(
|
|
@@ -18831,9 +20498,9 @@ function TagInput({
|
|
|
18831
20498
|
),
|
|
18832
20499
|
children: [
|
|
18833
20500
|
" ",
|
|
18834
|
-
value.map((tag) => /* @__PURE__ */ (0,
|
|
20501
|
+
value.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime230.jsxs)(Badge, { variant: "secondary", className: "gap-1 pr-1", children: [
|
|
18835
20502
|
tag,
|
|
18836
|
-
!disabled && /* @__PURE__ */ (0,
|
|
20503
|
+
!disabled && /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
|
|
18837
20504
|
"button",
|
|
18838
20505
|
{
|
|
18839
20506
|
type: "button",
|
|
@@ -18843,7 +20510,7 @@ function TagInput({
|
|
|
18843
20510
|
}
|
|
18844
20511
|
)
|
|
18845
20512
|
] }, tag)),
|
|
18846
|
-
!disabled && /* @__PURE__ */ (0,
|
|
20513
|
+
!disabled && /* @__PURE__ */ (0, import_jsx_runtime230.jsx)(
|
|
18847
20514
|
"input",
|
|
18848
20515
|
{
|
|
18849
20516
|
className: "flex-1 min-w-16 bg-transparent outline-none placeholder:text-muted-foreground",
|
|
@@ -18864,8 +20531,8 @@ function TagInput({
|
|
|
18864
20531
|
}
|
|
18865
20532
|
|
|
18866
20533
|
// src/components/business/RuleExpression/index.tsx
|
|
18867
|
-
var
|
|
18868
|
-
var
|
|
20534
|
+
var import_react83 = require("react");
|
|
20535
|
+
var import_jsx_runtime231 = require("react/jsx-runtime");
|
|
18869
20536
|
function trailingWord(text) {
|
|
18870
20537
|
const m = text.match(/[\w一-龥]+$/u);
|
|
18871
20538
|
return m ? m[0] : "";
|
|
@@ -19003,11 +20670,11 @@ function RuleExpression({
|
|
|
19003
20670
|
id,
|
|
19004
20671
|
className
|
|
19005
20672
|
}) {
|
|
19006
|
-
const editorRef = (0,
|
|
19007
|
-
const [focused, setFocused] = (0,
|
|
19008
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
19009
|
-
const [matchText, setMatchText] = (0,
|
|
19010
|
-
const lastEmittedRef = (0,
|
|
20673
|
+
const editorRef = (0, import_react83.useRef)(null);
|
|
20674
|
+
const [focused, setFocused] = (0, import_react83.useState)(false);
|
|
20675
|
+
const [activeIndex, setActiveIndex] = (0, import_react83.useState)(0);
|
|
20676
|
+
const [matchText, setMatchText] = (0, import_react83.useState)("");
|
|
20677
|
+
const lastEmittedRef = (0, import_react83.useRef)(null);
|
|
19011
20678
|
const matched = matchText ? options.filter((o) => o.label.toLowerCase().includes(matchText.toLowerCase())) : [];
|
|
19012
20679
|
const showSuggestions = focused && !disabled && matched.length > 0;
|
|
19013
20680
|
const emitTokens = (tokens) => {
|
|
@@ -19052,7 +20719,7 @@ function RuleExpression({
|
|
|
19052
20719
|
else ed.appendChild(document.createTextNode(t.text));
|
|
19053
20720
|
}
|
|
19054
20721
|
};
|
|
19055
|
-
(0,
|
|
20722
|
+
(0, import_react83.useLayoutEffect)(() => {
|
|
19056
20723
|
const sig = JSON.stringify(value ?? null);
|
|
19057
20724
|
if (sig !== lastEmittedRef.current) {
|
|
19058
20725
|
rebuild(seedTokens(value, options));
|
|
@@ -19155,7 +20822,7 @@ function RuleExpression({
|
|
|
19155
20822
|
e.preventDefault();
|
|
19156
20823
|
}
|
|
19157
20824
|
};
|
|
19158
|
-
return /* @__PURE__ */ (0,
|
|
20825
|
+
return /* @__PURE__ */ (0, import_jsx_runtime231.jsxs)(
|
|
19159
20826
|
"div",
|
|
19160
20827
|
{
|
|
19161
20828
|
className: cn("relative", className),
|
|
@@ -19165,7 +20832,7 @@ function RuleExpression({
|
|
|
19165
20832
|
}
|
|
19166
20833
|
},
|
|
19167
20834
|
children: [
|
|
19168
|
-
/* @__PURE__ */ (0,
|
|
20835
|
+
/* @__PURE__ */ (0, import_jsx_runtime231.jsx)(
|
|
19169
20836
|
"div",
|
|
19170
20837
|
{
|
|
19171
20838
|
ref: editorRef,
|
|
@@ -19201,13 +20868,13 @@ function RuleExpression({
|
|
|
19201
20868
|
}
|
|
19202
20869
|
}
|
|
19203
20870
|
),
|
|
19204
|
-
showSuggestions && /* @__PURE__ */ (0,
|
|
20871
|
+
showSuggestions && /* @__PURE__ */ (0, import_jsx_runtime231.jsx)(
|
|
19205
20872
|
"ul",
|
|
19206
20873
|
{
|
|
19207
20874
|
role: "list",
|
|
19208
20875
|
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",
|
|
19209
20876
|
onMouseDown: (e) => e.preventDefault(),
|
|
19210
|
-
children: matched.map((opt, index) => /* @__PURE__ */ (0,
|
|
20877
|
+
children: matched.map((opt, index) => /* @__PURE__ */ (0, import_jsx_runtime231.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime231.jsx)(
|
|
19211
20878
|
"button",
|
|
19212
20879
|
{
|
|
19213
20880
|
type: "button",
|
|
@@ -19228,8 +20895,8 @@ function RuleExpression({
|
|
|
19228
20895
|
}
|
|
19229
20896
|
|
|
19230
20897
|
// src/components/business/ScriptEditor/index.tsx
|
|
19231
|
-
var
|
|
19232
|
-
var
|
|
20898
|
+
var import_react84 = require("react");
|
|
20899
|
+
var import_jsx_runtime232 = require("react/jsx-runtime");
|
|
19233
20900
|
function escapeHtml(text) {
|
|
19234
20901
|
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
19235
20902
|
}
|
|
@@ -19296,12 +20963,12 @@ function ScriptEditor({
|
|
|
19296
20963
|
height = 160,
|
|
19297
20964
|
className
|
|
19298
20965
|
}) {
|
|
19299
|
-
const containerRef = (0,
|
|
19300
|
-
const editorRef = (0,
|
|
19301
|
-
const onChangeRef = (0,
|
|
20966
|
+
const containerRef = (0, import_react84.useRef)(null);
|
|
20967
|
+
const editorRef = (0, import_react84.useRef)(null);
|
|
20968
|
+
const onChangeRef = (0, import_react84.useRef)(onChange);
|
|
19302
20969
|
onChangeRef.current = onChange;
|
|
19303
|
-
const [isEmpty2, setIsEmpty] = (0,
|
|
19304
|
-
(0,
|
|
20970
|
+
const [isEmpty2, setIsEmpty] = (0, import_react84.useState)(!value);
|
|
20971
|
+
(0, import_react84.useEffect)(() => {
|
|
19305
20972
|
let disposed = false;
|
|
19306
20973
|
(async () => {
|
|
19307
20974
|
const ace = await import("ace-builds");
|
|
@@ -19339,7 +21006,7 @@ function ScriptEditor({
|
|
|
19339
21006
|
editorRef.current = null;
|
|
19340
21007
|
};
|
|
19341
21008
|
}, []);
|
|
19342
|
-
(0,
|
|
21009
|
+
(0, import_react84.useEffect)(() => {
|
|
19343
21010
|
const editor = editorRef.current;
|
|
19344
21011
|
if (!editor) return;
|
|
19345
21012
|
const next = value ?? "";
|
|
@@ -19348,15 +21015,15 @@ function ScriptEditor({
|
|
|
19348
21015
|
setIsEmpty(next === "");
|
|
19349
21016
|
}
|
|
19350
21017
|
}, [value]);
|
|
19351
|
-
(0,
|
|
21018
|
+
(0, import_react84.useEffect)(() => {
|
|
19352
21019
|
editorRef.current?.setOptions({
|
|
19353
21020
|
enableBasicAutocompletion: [buildScriptCompletions(functions, variables)]
|
|
19354
21021
|
});
|
|
19355
21022
|
}, [functions, variables]);
|
|
19356
|
-
(0,
|
|
21023
|
+
(0, import_react84.useEffect)(() => {
|
|
19357
21024
|
editorRef.current?.setReadOnly(readonly ?? false);
|
|
19358
21025
|
}, [readonly]);
|
|
19359
|
-
return /* @__PURE__ */ (0,
|
|
21026
|
+
return /* @__PURE__ */ (0, import_jsx_runtime232.jsxs)(
|
|
19360
21027
|
"div",
|
|
19361
21028
|
{
|
|
19362
21029
|
className: cn(
|
|
@@ -19365,15 +21032,15 @@ function ScriptEditor({
|
|
|
19365
21032
|
className
|
|
19366
21033
|
),
|
|
19367
21034
|
children: [
|
|
19368
|
-
/* @__PURE__ */ (0,
|
|
19369
|
-
isEmpty2 && placeholder && /* @__PURE__ */ (0,
|
|
21035
|
+
/* @__PURE__ */ (0, import_jsx_runtime232.jsx)("div", { ref: containerRef, id, style: { height }, className: "w-full" }),
|
|
21036
|
+
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 })
|
|
19370
21037
|
]
|
|
19371
21038
|
}
|
|
19372
21039
|
);
|
|
19373
21040
|
}
|
|
19374
21041
|
|
|
19375
21042
|
// src/components/business/SiteFooter/index.tsx
|
|
19376
|
-
var
|
|
21043
|
+
var import_jsx_runtime233 = require("react/jsx-runtime");
|
|
19377
21044
|
function SiteFooter({
|
|
19378
21045
|
brand,
|
|
19379
21046
|
groups,
|
|
@@ -19385,7 +21052,7 @@ function SiteFooter({
|
|
|
19385
21052
|
}) {
|
|
19386
21053
|
const renderLink = (link) => {
|
|
19387
21054
|
if (link.href) {
|
|
19388
|
-
return /* @__PURE__ */ (0,
|
|
21055
|
+
return /* @__PURE__ */ (0, import_jsx_runtime233.jsx)(
|
|
19389
21056
|
Link2,
|
|
19390
21057
|
{
|
|
19391
21058
|
href: link.href,
|
|
@@ -19394,7 +21061,7 @@ function SiteFooter({
|
|
|
19394
21061
|
}
|
|
19395
21062
|
);
|
|
19396
21063
|
}
|
|
19397
|
-
return /* @__PURE__ */ (0,
|
|
21064
|
+
return /* @__PURE__ */ (0, import_jsx_runtime233.jsx)(
|
|
19398
21065
|
"button",
|
|
19399
21066
|
{
|
|
19400
21067
|
type: "button",
|
|
@@ -19411,22 +21078,22 @@ function SiteFooter({
|
|
|
19411
21078
|
if (!hasBrand && !hasGroups && !hasBottom) {
|
|
19412
21079
|
return null;
|
|
19413
21080
|
}
|
|
19414
|
-
return /* @__PURE__ */ (0,
|
|
21081
|
+
return /* @__PURE__ */ (0, import_jsx_runtime233.jsxs)(
|
|
19415
21082
|
"footer",
|
|
19416
21083
|
{
|
|
19417
21084
|
"data-slot": "site-footer",
|
|
19418
21085
|
className: cn("border-t bg-muted/40", className),
|
|
19419
21086
|
style,
|
|
19420
21087
|
children: [
|
|
19421
|
-
hasBrand || hasGroups ? /* @__PURE__ */ (0,
|
|
21088
|
+
hasBrand || hasGroups ? /* @__PURE__ */ (0, import_jsx_runtime233.jsxs)(
|
|
19422
21089
|
"div",
|
|
19423
21090
|
{
|
|
19424
21091
|
"data-slot": "site-footer-main",
|
|
19425
21092
|
className: "mx-auto flex w-full max-w-6xl flex-col gap-8 px-6 py-10 md:flex-row md:justify-between",
|
|
19426
21093
|
children: [
|
|
19427
|
-
hasBrand ? /* @__PURE__ */ (0,
|
|
19428
|
-
brand.logo || brand.name ? /* @__PURE__ */ (0,
|
|
19429
|
-
brand.logo ? /* @__PURE__ */ (0,
|
|
21094
|
+
hasBrand ? /* @__PURE__ */ (0, import_jsx_runtime233.jsxs)("div", { "data-slot": "site-footer-brand", className: "flex max-w-xs flex-col gap-3", children: [
|
|
21095
|
+
brand.logo || brand.name ? /* @__PURE__ */ (0, import_jsx_runtime233.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
21096
|
+
brand.logo ? /* @__PURE__ */ (0, import_jsx_runtime233.jsx)(
|
|
19430
21097
|
"img",
|
|
19431
21098
|
{
|
|
19432
21099
|
src: brand.logo,
|
|
@@ -19434,23 +21101,23 @@ function SiteFooter({
|
|
|
19434
21101
|
className: "size-8 rounded-md object-contain"
|
|
19435
21102
|
}
|
|
19436
21103
|
) : null,
|
|
19437
|
-
brand.name ? /* @__PURE__ */ (0,
|
|
21104
|
+
brand.name ? /* @__PURE__ */ (0, import_jsx_runtime233.jsx)("span", { className: "text-base font-semibold", children: brand.name }) : null
|
|
19438
21105
|
] }) : null,
|
|
19439
|
-
brand.description ? /* @__PURE__ */ (0,
|
|
21106
|
+
brand.description ? /* @__PURE__ */ (0, import_jsx_runtime233.jsx)("p", { className: "text-sm leading-relaxed text-muted-foreground", children: brand.description }) : null
|
|
19440
21107
|
] }) : null,
|
|
19441
|
-
hasGroups ? /* @__PURE__ */ (0,
|
|
21108
|
+
hasGroups ? /* @__PURE__ */ (0, import_jsx_runtime233.jsx)(
|
|
19442
21109
|
"div",
|
|
19443
21110
|
{
|
|
19444
21111
|
"data-slot": "site-footer-groups",
|
|
19445
21112
|
className: "grid flex-1 grid-cols-2 gap-8 sm:grid-cols-3 md:justify-items-end",
|
|
19446
|
-
children: groups.map((group) => /* @__PURE__ */ (0,
|
|
21113
|
+
children: groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime233.jsxs)(
|
|
19447
21114
|
"div",
|
|
19448
21115
|
{
|
|
19449
21116
|
"data-slot": "site-footer-group",
|
|
19450
21117
|
className: "flex min-w-24 flex-col gap-3",
|
|
19451
21118
|
children: [
|
|
19452
|
-
/* @__PURE__ */ (0,
|
|
19453
|
-
/* @__PURE__ */ (0,
|
|
21119
|
+
/* @__PURE__ */ (0, import_jsx_runtime233.jsx)("span", { className: "text-sm font-medium", children: group.title }),
|
|
21120
|
+
/* @__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)) })
|
|
19454
21121
|
]
|
|
19455
21122
|
},
|
|
19456
21123
|
group.title
|
|
@@ -19460,9 +21127,9 @@ function SiteFooter({
|
|
|
19460
21127
|
]
|
|
19461
21128
|
}
|
|
19462
21129
|
) : null,
|
|
19463
|
-
hasBottom ? /* @__PURE__ */ (0,
|
|
19464
|
-
copyright ? /* @__PURE__ */ (0,
|
|
19465
|
-
bottomLinks && bottomLinks.length > 0 ? /* @__PURE__ */ (0,
|
|
21130
|
+
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: [
|
|
21131
|
+
copyright ? /* @__PURE__ */ (0, import_jsx_runtime233.jsx)("span", { children: copyright }) : /* @__PURE__ */ (0, import_jsx_runtime233.jsx)("span", {}),
|
|
21132
|
+
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
|
|
19466
21133
|
] }) }) : null
|
|
19467
21134
|
]
|
|
19468
21135
|
}
|
|
@@ -19642,6 +21309,7 @@ var builtinComponents = {
|
|
|
19642
21309
|
Login,
|
|
19643
21310
|
EntityCard,
|
|
19644
21311
|
CardList,
|
|
21312
|
+
RecordingPage,
|
|
19645
21313
|
SiteFooter,
|
|
19646
21314
|
// 业务表单类组件(value/onChange 受控;DSL 用 props.value + events.onChange 读写 ${event})
|
|
19647
21315
|
SearchableSelect,
|
|
@@ -19781,6 +21449,7 @@ function createComponentRegistry() {
|
|
|
19781
21449
|
RadioGroup,
|
|
19782
21450
|
RailTooltip,
|
|
19783
21451
|
Rate,
|
|
21452
|
+
RecordingPage,
|
|
19784
21453
|
Resizable,
|
|
19785
21454
|
Result,
|
|
19786
21455
|
RichText,
|