dsh-conversation-navigator 0.1.15 → 0.1.16
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/lib/client.js +101 -50
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -163,6 +163,19 @@ window.__ModuleLoader__.load({
|
|
|
163
163
|
flex: none; color: var(--dsw-alias-label-secondary, #888); font-size: 10px; opacity: .8;
|
|
164
164
|
}
|
|
165
165
|
.cnvnav-empty { padding: 18px 10px; text-align: center; color: var(--dsw-alias-label-secondary, #888); }
|
|
166
|
+
.cnvnav-filter-row { padding: 6px 6px 0; }
|
|
167
|
+
.cnvnav-filter {
|
|
168
|
+
width: 100%; box-sizing: border-box;
|
|
169
|
+
height: 28px; padding: 0 8px;
|
|
170
|
+
border: 1px solid var(--dsw-alias-border-l1, rgba(128,128,128,.35));
|
|
171
|
+
border-radius: 8px;
|
|
172
|
+
background: var(--dsw-alias-bg-layer-1, rgba(128,128,128,.06));
|
|
173
|
+
color: var(--dsw-alias-label-primary, #222);
|
|
174
|
+
font-family: var(--dsw-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', sans-serif);
|
|
175
|
+
font-size: 12px; outline: none;
|
|
176
|
+
}
|
|
177
|
+
.cnvnav-filter::placeholder { color: var(--dsw-alias-label-secondary, #888); }
|
|
178
|
+
.cnvnav-filter:focus { border-color: var(--dsw-alias-brand-primary, #4f46e5); }
|
|
166
179
|
.cnvnav-topbar { display: flex; gap: 6px; margin: 6px 6px 0; }
|
|
167
180
|
.cnvnav-footer { display: flex; gap: 6px; margin: 0 6px 6px; }
|
|
168
181
|
.cnvnav-bar-btn { flex: 1; display: block; }
|
|
@@ -467,6 +480,7 @@ window.__ModuleLoader__.load({
|
|
|
467
480
|
/* ---------- floating navigator panel ---------- */
|
|
468
481
|
function Panel() {
|
|
469
482
|
const snap = useStore();
|
|
483
|
+
const [filter, setFilter] = React.useState("");
|
|
470
484
|
|
|
471
485
|
React.useEffect(() => {
|
|
472
486
|
if (!snap.open) return;
|
|
@@ -531,35 +545,77 @@ window.__ModuleLoader__.load({
|
|
|
531
545
|
const groups = snap.outline !== null ? snap.outline.groups : [];
|
|
532
546
|
const count = snap.outline !== null ? snap.outline.count : 0;
|
|
533
547
|
|
|
534
|
-
const
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
return React.createElement("
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
548
|
+
const kw = filter.trim().toLowerCase();
|
|
549
|
+
const filtering = kw !== "";
|
|
550
|
+
function hit(text) {
|
|
551
|
+
return typeof text === "string" && text !== "" && text.toLowerCase().indexOf(kw) !== -1;
|
|
552
|
+
}
|
|
553
|
+
function renderItem(item) {
|
|
554
|
+
return React.createElement("button", {
|
|
555
|
+
key: item.key,
|
|
556
|
+
type: "button",
|
|
557
|
+
ref: (el) => { itemEls[item.key] = el; },
|
|
558
|
+
className: "cnvnav-item" + (item.key === snap.activeKey ? " cnvnav-item-active" : ""),
|
|
559
|
+
onClick: () => jumpTo(item.key),
|
|
560
|
+
},
|
|
561
|
+
React.createElement("span", { className: "cnvnav-badge cnvnav-badge-" + item.cls }, item.label),
|
|
562
|
+
item.preview !== null && item.preview !== ""
|
|
563
|
+
? React.createElement("span", { className: "cnvnav-item-preview" }, item.preview)
|
|
564
|
+
: null,
|
|
565
|
+
item.time !== ""
|
|
566
|
+
? React.createElement("span", { className: "cnvnav-item-time" }, item.time)
|
|
567
|
+
: null,
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
function renderGroupHead(g, groupActive) {
|
|
571
|
+
return React.createElement("div", {
|
|
572
|
+
ref: (el) => { groupEls[g.gid] = el; },
|
|
573
|
+
className: "cnvnav-group-row" + (groupActive ? " cnvnav-group-row-active" : ""),
|
|
574
|
+
},
|
|
575
|
+
React.createElement(Tooltip, {
|
|
576
|
+
label: "跳转到此位置",
|
|
577
|
+
side: "top",
|
|
578
|
+
delayMs: 500,
|
|
544
579
|
},
|
|
545
|
-
React.createElement(
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
React.createElement("
|
|
552
|
-
|
|
553
|
-
className: "cnvnav-group-
|
|
554
|
-
|
|
555
|
-
},
|
|
556
|
-
React.createElement("span", { className: "cnvnav-group-title" }, g.title),
|
|
557
|
-
g.subtitle !== ""
|
|
558
|
-
? React.createElement("span", { className: "cnvnav-group-sub" }, g.subtitle)
|
|
559
|
-
: null,
|
|
560
|
-
),
|
|
580
|
+
React.createElement("span", { className: "cnvnav-group-head-wrap" },
|
|
581
|
+
React.createElement("button", {
|
|
582
|
+
type: "button",
|
|
583
|
+
className: "cnvnav-group-head",
|
|
584
|
+
onClick: () => jumpTo(g.headKey),
|
|
585
|
+
},
|
|
586
|
+
React.createElement("span", { className: "cnvnav-group-title" }, g.title),
|
|
587
|
+
g.subtitle !== ""
|
|
588
|
+
? React.createElement("span", { className: "cnvnav-group-sub" }, g.subtitle)
|
|
589
|
+
: null,
|
|
561
590
|
),
|
|
562
591
|
),
|
|
592
|
+
),
|
|
593
|
+
);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
let groupNodes;
|
|
597
|
+
if (filtering) {
|
|
598
|
+
groupNodes = [];
|
|
599
|
+
for (const g of groups) {
|
|
600
|
+
const subtitleHit = hit(g.subtitle);
|
|
601
|
+
const hitItems = g.items.filter((it) => hit(it.preview) || hit(it.label));
|
|
602
|
+
if (!subtitleHit && hitItems.length === 0) continue;
|
|
603
|
+
const rows = subtitleHit ? g.items : hitItems;
|
|
604
|
+
const groupActive = g.items.some((it) => it.key === snap.activeKey);
|
|
605
|
+
groupNodes.push(React.createElement("div", { key: g.gid, className: "cnvnav-group" },
|
|
606
|
+
renderGroupHead(g, groupActive),
|
|
607
|
+
rows.map(renderItem),
|
|
608
|
+
));
|
|
609
|
+
}
|
|
610
|
+
} else {
|
|
611
|
+
groupNodes = groups.map((g) => {
|
|
612
|
+
const expanded = snap.expanded[g.gid] === true;
|
|
613
|
+
const isTurnGroup = g.turn !== null;
|
|
614
|
+
const stepItems = isTurnGroup ? (g.headIsUser ? g.items.slice(1) : g.items) : [];
|
|
615
|
+
const hasSteps = stepItems.length > 0;
|
|
616
|
+
const groupActive = g.items.some((it) => it.key === snap.activeKey);
|
|
617
|
+
return React.createElement("div", { key: g.gid, className: "cnvnav-group" },
|
|
618
|
+
renderGroupHead(g, groupActive),
|
|
563
619
|
hasSteps
|
|
564
620
|
? React.createElement(Tooltip, {
|
|
565
621
|
label: expanded ? "折叠步次" : "展开步次",
|
|
@@ -581,28 +637,12 @@ window.__ModuleLoader__.load({
|
|
|
581
637
|
),
|
|
582
638
|
)
|
|
583
639
|
: null,
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
ref: (el) => { itemEls[item.key] = el; },
|
|
591
|
-
className: "cnvnav-item" + (item.key === snap.activeKey ? " cnvnav-item-active" : ""),
|
|
592
|
-
onClick: () => jumpTo(item.key),
|
|
593
|
-
},
|
|
594
|
-
React.createElement("span", { className: "cnvnav-badge cnvnav-badge-" + item.cls }, item.label),
|
|
595
|
-
item.preview !== null && item.preview !== ""
|
|
596
|
-
? React.createElement("span", { className: "cnvnav-item-preview" }, item.preview)
|
|
597
|
-
: null,
|
|
598
|
-
item.time !== ""
|
|
599
|
-
? React.createElement("span", { className: "cnvnav-item-time" }, item.time)
|
|
600
|
-
: null,
|
|
601
|
-
),
|
|
602
|
-
)
|
|
603
|
-
: null,
|
|
604
|
-
);
|
|
605
|
-
});
|
|
640
|
+
expanded && hasSteps
|
|
641
|
+
? stepItems.map(renderItem)
|
|
642
|
+
: null,
|
|
643
|
+
);
|
|
644
|
+
});
|
|
645
|
+
}
|
|
606
646
|
|
|
607
647
|
return React.createElement("div", {
|
|
608
648
|
ref: (el) => { panelEl = el; },
|
|
@@ -612,7 +652,7 @@ window.__ModuleLoader__.load({
|
|
|
612
652
|
},
|
|
613
653
|
React.createElement("div", { className: "cnvnav-head" },
|
|
614
654
|
React.createElement("span", { className: "cnvnav-title" }, "会话导航"),
|
|
615
|
-
React.createElement("span", { className: "cnvnav-count" }, String(count) + " 条"),
|
|
655
|
+
React.createElement("span", { className: "cnvnav-count" }, (filtering ? groupNodes.length + " / " : "") + String(count) + " 条"),
|
|
616
656
|
React.createElement(Tooltip, {
|
|
617
657
|
label: "收起面板",
|
|
618
658
|
side: "bottom",
|
|
@@ -628,6 +668,15 @@ window.__ModuleLoader__.load({
|
|
|
628
668
|
),
|
|
629
669
|
),
|
|
630
670
|
),
|
|
671
|
+
React.createElement("div", { className: "cnvnav-filter-row" },
|
|
672
|
+
React.createElement("input", {
|
|
673
|
+
type: "text",
|
|
674
|
+
className: "cnvnav-filter",
|
|
675
|
+
placeholder: "过滤提问 / 回复…",
|
|
676
|
+
value: filter,
|
|
677
|
+
onChange: (e) => setFilter(e.target.value),
|
|
678
|
+
}),
|
|
679
|
+
),
|
|
631
680
|
React.createElement("div", { className: "cnvnav-topbar" },
|
|
632
681
|
React.createElement(Tooltip, {
|
|
633
682
|
label: "加载更早的一批轮次",
|
|
@@ -670,7 +719,9 @@ window.__ModuleLoader__.load({
|
|
|
670
719
|
},
|
|
671
720
|
groups.length === 0
|
|
672
721
|
? React.createElement("div", { className: "cnvnav-empty" }, "当前会话暂无对话节点")
|
|
673
|
-
: groupNodes
|
|
722
|
+
: (filtering && groupNodes.length === 0
|
|
723
|
+
? React.createElement("div", { className: "cnvnav-empty" }, "无匹配结果")
|
|
724
|
+
: groupNodes),
|
|
674
725
|
),
|
|
675
726
|
React.createElement("div", { className: "cnvnav-footer" },
|
|
676
727
|
React.createElement(Tooltip, {
|