dsh-prime-memory 0.20.0-beta.25 → 0.20.0-beta.26
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/CHANGELOG.md +11 -0
- package/dist/client.js +236 -138
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,17 @@
|
|
|
17
17
|
- **建议状态(`longtask-hint-get`)以纯端点提供**:判定 = 上下文占用达 `contextThresholdPct` 或 todo 漂移达 `driftThreshold`(部署配置可调);配合 `longtask-compress-tail` 作手动压缩入口。
|
|
18
18
|
- **撤下浮动球 UI(`client/src/longtask-fab.ts`;beta.1 起曾随包发布)**:悬浮建议面板的归属本在 context-compression 侧(「建议启动压缩」是其领域),pm 属误载——2026-10-02 用户裁定撤下。撤下不违座位契约(settings.section 恰一个 + 输入栏 pill,body 单例不占座位),但全应用级 overlay 会与其他插件的悬浮 UI 抢占屏幕角落;长任务开关与手动压缩入口待长任务定版时落记忆设置分节。
|
|
19
19
|
- **`session-mode-set` 的 `mode` 转为可选**:与 `longTask` 二选一必传——纯切长任务开关不再被迫发送档位(旧客户端恒传 mode,行为不变)。响应 `mode` 改回当前生效值。
|
|
20
|
+
## [0.20.0-beta.26] — 2026-10-03
|
|
21
|
+
|
|
22
|
+
### 新增(Hall/Room 增长后的可用性)
|
|
23
|
+
|
|
24
|
+
- **Hall/Room 名称搜索过滤**:Hall 页新增搜索框(slug、显示名、别名,大小写不敏感)
|
|
25
|
+
—— hall 自身命中显示全部子 room,否则只留命中的子 room,整组无命中即隐藏;
|
|
26
|
+
搜索时匹配组自动展开(折叠态不再藏住结果);自生长未注册区同滤。
|
|
27
|
+
Room 页同款搜索框,与退场筛选 chips 叠加生效。
|
|
28
|
+
- **Hall 分组折叠,默认全折叠**:hall 头只显示「合计 N 条 · M 个 room」,点头部或
|
|
29
|
+
▸/▾ 钮展开/收起子 room;「展开全部/收起全部」批量钮;展开状态 localStorage 记忆
|
|
30
|
+
(`dsh.memory.halls.open`)。归类点选(点 hall 头完成归类)优先级不变。
|
|
20
31
|
## [0.20.0-beta.25] — 2026-10-02
|
|
21
32
|
|
|
22
33
|
> 自生长 room 退场后状态不可见修复 + Hall 子 room 显示规则(用户裁定)。
|
package/dist/client.js
CHANGED
|
@@ -3897,6 +3897,15 @@ var __defProp = Object.defineProperty;
|
|
|
3897
3897
|
const [editing, setEditing] = (0, import_react16.useState)(null);
|
|
3898
3898
|
const [expandedRooms, setExpandedRooms] = (0, import_react16.useState)(/* @__PURE__ */ new Set());
|
|
3899
3899
|
const [roomRecords, setRoomRecords] = (0, import_react16.useState)({});
|
|
3900
|
+
const [expandedHalls, setExpandedHalls] = (0, import_react16.useState)(() => {
|
|
3901
|
+
try {
|
|
3902
|
+
const v = window.localStorage.getItem("dsh.memory.halls.open");
|
|
3903
|
+
return v ? new Set(JSON.parse(v)) : /* @__PURE__ */ new Set();
|
|
3904
|
+
} catch {
|
|
3905
|
+
return /* @__PURE__ */ new Set();
|
|
3906
|
+
}
|
|
3907
|
+
});
|
|
3908
|
+
const [filter, setFilter] = (0, import_react16.useState)("");
|
|
3900
3909
|
const dragRef = (0, import_react16.useRef)(null);
|
|
3901
3910
|
const [ghost, setGhost] = (0, import_react16.useState)(null);
|
|
3902
3911
|
const onDragLabelDown = (ev, slug) => {
|
|
@@ -4107,6 +4116,39 @@ var __defProp = Object.defineProperty;
|
|
|
4107
4116
|
})).sort((a, b) => a.hall.localeCompare(b.hall));
|
|
4108
4117
|
}, [registry, rooms]);
|
|
4109
4118
|
const grownOnly = (0, import_react16.useMemo)(() => rooms.filter((r) => !registry.some((e) => e.slug === r.room)), [rooms, registry]);
|
|
4119
|
+
const persistHalls = (next) => {
|
|
4120
|
+
try {
|
|
4121
|
+
window.localStorage.setItem("dsh.memory.halls.open", JSON.stringify([...next]));
|
|
4122
|
+
} catch {
|
|
4123
|
+
}
|
|
4124
|
+
};
|
|
4125
|
+
const toggleHall = (hall) => setExpandedHalls((cur) => {
|
|
4126
|
+
const next = new Set(cur);
|
|
4127
|
+
if (next.has(hall)) next.delete(hall);
|
|
4128
|
+
else next.add(hall);
|
|
4129
|
+
persistHalls(next);
|
|
4130
|
+
return next;
|
|
4131
|
+
});
|
|
4132
|
+
const setAllHalls = (open) => {
|
|
4133
|
+
const next = open ? new Set(groups.map((g) => g.hall)) : /* @__PURE__ */ new Set();
|
|
4134
|
+
setExpandedHalls(next);
|
|
4135
|
+
persistHalls(next);
|
|
4136
|
+
};
|
|
4137
|
+
const normFilter = filter.trim().toLowerCase();
|
|
4138
|
+
const visibleGroups = (0, import_react16.useMemo)(() => {
|
|
4139
|
+
if (!normFilter) return groups;
|
|
4140
|
+
return groups.map((g) => {
|
|
4141
|
+
const hallHit = g.hall.toLowerCase().includes(normFilter) || (g.label ?? "").toLowerCase().includes(normFilter);
|
|
4142
|
+
const entries = hallHit ? g.entries : g.entries.filter(
|
|
4143
|
+
(e) => e.slug.toLowerCase().includes(normFilter) || (e.label ?? "").toLowerCase().includes(normFilter) || (e.aliases ?? []).some((a) => a.toLowerCase().includes(normFilter))
|
|
4144
|
+
);
|
|
4145
|
+
return { ...g, entries };
|
|
4146
|
+
}).filter((g) => g.entries.length > 0);
|
|
4147
|
+
}, [groups, normFilter]);
|
|
4148
|
+
const visibleGrown = (0, import_react16.useMemo)(
|
|
4149
|
+
() => normFilter ? grownOnly.filter((r) => r.room.toLowerCase().includes(normFilter)) : grownOnly,
|
|
4150
|
+
[grownOnly, normFilter]
|
|
4151
|
+
);
|
|
4110
4152
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
|
|
4111
4153
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { ...S.flexRow, marginBottom: 8 }, children: [
|
|
4112
4154
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.muted, children: "Hall = Room 大类 · 大类上限 200,小类「大类/小类」细分不占额度 · 与 Wing(域)筛选无关" }),
|
|
@@ -4165,6 +4207,22 @@ var __defProp = Object.defineProperty;
|
|
|
4165
4207
|
),
|
|
4166
4208
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", style: btn, onClick: loadAll, title: "重拉注册表与计数", children: "刷新" })
|
|
4167
4209
|
] }),
|
|
4210
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center", marginBottom: 8, flexWrap: "wrap" }, children: [
|
|
4211
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4212
|
+
"input",
|
|
4213
|
+
{
|
|
4214
|
+
value: filter,
|
|
4215
|
+
onChange: (e) => setFilter(e.target.value),
|
|
4216
|
+
placeholder: "搜索 hall/room(slug、显示名、别名)",
|
|
4217
|
+
style: { ...S.input, width: 250, fontSize: 12 }
|
|
4218
|
+
}
|
|
4219
|
+
),
|
|
4220
|
+
filter ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", style: btn, onClick: () => setFilter(""), children: "清除" }) : null,
|
|
4221
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.muted, children: `匹配 ${visibleGroups.reduce((s2, g) => s2 + g.entries.length, 0)} room / ${visibleGroups.length} hall` }),
|
|
4222
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.grow }),
|
|
4223
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", style: btn, title: "展开全部 hall 的子 room", onClick: () => setAllHalls(true), children: "展开全部" }),
|
|
4224
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", style: btn, title: "收起全部 hall(只留 hall 头)", onClick: () => setAllHalls(false), children: "收起全部" })
|
|
4225
|
+
] }),
|
|
4168
4226
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center", marginBottom: 10 }, children: [
|
|
4169
4227
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4170
4228
|
"input",
|
|
@@ -4268,163 +4326,187 @@ var __defProp = Object.defineProperty;
|
|
|
4268
4326
|
msg ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.hint, children: msg }) : null,
|
|
4269
4327
|
error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.error, children: error }) : null,
|
|
4270
4328
|
ghost ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { position: "fixed", left: ghost.x + 12, top: ghost.y + 12, zIndex: 9999, pointerEvents: "none", fontSize: 12, padding: "2px 10px", borderRadius: 999, border: "1px solid var(--dsh-mem-accent)", background: "var(--dsh-mem-bg-inset)", color: "var(--dsh-mem-accent)" }, children: ghost.text }) : null,
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
"
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
ev
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
padding: "5px 10px",
|
|
4301
|
-
background: "var(--dsh-mem-bg-inset)",
|
|
4302
|
-
outline: dragOverHall === g.hall || picking !== null ? "2px dashed var(--dsh-mem-accent)" : void 0,
|
|
4303
|
-
outlineOffset: dragOverHall === g.hall || picking !== null ? "-2px" : void 0,
|
|
4304
|
-
cursor: picking ? "pointer" : void 0
|
|
4305
|
-
},
|
|
4306
|
-
title: picking ? "点击此 hall:把「" + picking + "」归入 " + g.hall + " 下(major/minor,预览后确认)" : hiPriv ? "拖入 room 归类到该 hall 下(major/minor;记录随迁,旧名进别名,预览后确认)" : void 0,
|
|
4307
|
-
children: [
|
|
4308
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { style: { fontSize: 12, fontWeight: 600 }, children: [
|
|
4309
|
-
g.hall,
|
|
4310
|
-
g.label ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.muted, children: " (" + g.label + ")" }) : null
|
|
4311
|
-
] }),
|
|
4312
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.muted, children: `合计 ${g.total} 条 · ${g.entries.length} 个 room` }),
|
|
4313
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.grow }),
|
|
4314
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4315
|
-
"button",
|
|
4316
|
-
{
|
|
4317
|
-
type: "button",
|
|
4318
|
-
disabled: !hiPriv || busy,
|
|
4319
|
-
title: `预填注册表单为 ${g.hall}/…(注册该 hall 下的小类)`,
|
|
4320
|
-
onClick: () => setRegSlug(g.hall + "/"),
|
|
4321
|
-
style: btn,
|
|
4322
|
-
children: "+小类"
|
|
4329
|
+
visibleGroups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { style: S.intro, children: normFilter ? "无匹配的 hall/room。" : "注册表为空。在上方注册 Hall/Room(如 dsh-plugin),或把自生长 slug「收编」进词表 —— 之后候选标注器会优先把相关记忆挂到这些 slug 上。" }) : visibleGroups.map((g) => {
|
|
4330
|
+
const hallOpen = !!normFilter || expandedHalls.has(g.hall);
|
|
4331
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { marginBottom: 10, border: "1px solid var(--dsh-mem-border)", borderRadius: 8, overflow: "hidden" }, children: [
|
|
4332
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
4333
|
+
"div",
|
|
4334
|
+
{
|
|
4335
|
+
"data-hall": g.hall,
|
|
4336
|
+
onDragOver: (ev) => {
|
|
4337
|
+
if (!hiPriv || busy) return;
|
|
4338
|
+
ev.preventDefault();
|
|
4339
|
+
ev.dataTransfer.dropEffect = "move";
|
|
4340
|
+
setDragOverHall(g.hall);
|
|
4341
|
+
},
|
|
4342
|
+
onDragLeave: () => setDragOverHall((cur) => cur === g.hall ? null : cur),
|
|
4343
|
+
onDrop: (ev) => {
|
|
4344
|
+
ev.preventDefault();
|
|
4345
|
+
setDragOverHall(null);
|
|
4346
|
+
if (!hiPriv || busy) return;
|
|
4347
|
+
const from = ev.dataTransfer.getData("text/dsh-room");
|
|
4348
|
+
if (from) beginReclass(from, g.hall);
|
|
4349
|
+
},
|
|
4350
|
+
onClick: () => {
|
|
4351
|
+
if (picking) {
|
|
4352
|
+
if (!busy) {
|
|
4353
|
+
const from = picking;
|
|
4354
|
+
setPicking(null);
|
|
4355
|
+
beginReclass(from, g.hall);
|
|
4356
|
+
}
|
|
4357
|
+
return;
|
|
4323
4358
|
}
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4359
|
+
toggleHall(g.hall);
|
|
4360
|
+
},
|
|
4361
|
+
style: {
|
|
4362
|
+
display: "flex",
|
|
4363
|
+
alignItems: "center",
|
|
4364
|
+
gap: 8,
|
|
4365
|
+
padding: "5px 10px",
|
|
4366
|
+
background: "var(--dsh-mem-bg-inset)",
|
|
4367
|
+
outline: dragOverHall === g.hall || picking !== null ? "2px dashed var(--dsh-mem-accent)" : void 0,
|
|
4368
|
+
outlineOffset: dragOverHall === g.hall || picking !== null ? "-2px" : void 0,
|
|
4369
|
+
cursor: "pointer"
|
|
4370
|
+
},
|
|
4371
|
+
title: picking ? "点击此 hall:把「" + picking + "」归入 " + g.hall + " 下(major/minor,预览后确认)" : hiPriv ? "拖入 room 归类到该 hall 下(major/minor;记录随迁,旧名进别名,预览后确认)" : void 0,
|
|
4372
|
+
children: [
|
|
4335
4373
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4336
4374
|
"button",
|
|
4337
4375
|
{
|
|
4338
4376
|
type: "button",
|
|
4339
|
-
title:
|
|
4340
|
-
onClick: () =>
|
|
4377
|
+
title: hallOpen ? "收起子 room" : "展开子 room(默认折叠)",
|
|
4378
|
+
onClick: (ev) => {
|
|
4379
|
+
ev.stopPropagation();
|
|
4380
|
+
toggleHall(g.hall);
|
|
4381
|
+
},
|
|
4341
4382
|
style: { ...btn, borderRadius: 999, padding: "1px 7px", flexShrink: 0 },
|
|
4342
|
-
children:
|
|
4383
|
+
children: hallOpen ? "▾" : "▸"
|
|
4343
4384
|
}
|
|
4344
4385
|
),
|
|
4345
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
4346
|
-
|
|
4386
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { style: { fontSize: 12, fontWeight: 600 }, children: [
|
|
4387
|
+
g.hall,
|
|
4388
|
+
g.label ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.muted, children: " (" + g.label + ")" }) : null
|
|
4389
|
+
] }),
|
|
4390
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.muted, children: `合计 ${g.total} 条 · ${g.entries.length} 个 room` }),
|
|
4391
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.grow }),
|
|
4392
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4393
|
+
"button",
|
|
4347
4394
|
{
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4395
|
+
type: "button",
|
|
4396
|
+
disabled: !hiPriv || busy,
|
|
4397
|
+
title: `预填注册表单为 ${g.hall}/…(注册该 hall 下的小类)`,
|
|
4398
|
+
onClick: (ev) => {
|
|
4399
|
+
ev.stopPropagation();
|
|
4400
|
+
setRegSlug(g.hall + "/");
|
|
4401
|
+
},
|
|
4402
|
+
style: btn,
|
|
4403
|
+
children: "+小类"
|
|
4357
4404
|
}
|
|
4358
|
-
)
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
setPreview(null);
|
|
4370
|
-
setPicking(null);
|
|
4371
|
-
}, style: btn, children: "编辑" }),
|
|
4405
|
+
)
|
|
4406
|
+
]
|
|
4407
|
+
}
|
|
4408
|
+
),
|
|
4409
|
+
hallOpen ? g.entries.map((e) => {
|
|
4410
|
+
const standalone = e.slug === g.hall;
|
|
4411
|
+
const count = rooms.find((r) => r.room === e.slug)?.count ?? 0;
|
|
4412
|
+
const retired = e.status === "retired";
|
|
4413
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { padding: "4px 10px", borderTop: "1px solid var(--dsh-mem-border)", opacity: retired ? 0.55 : 1 }, children: [
|
|
4414
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
4415
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { flex: 1, minWidth: 0, display: "flex", flexWrap: "wrap", gap: "2px 8px", alignItems: "baseline" }, children: [
|
|
4372
4416
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4373
4417
|
"button",
|
|
4374
4418
|
{
|
|
4375
4419
|
type: "button",
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
children:
|
|
4420
|
+
title: expandedRooms.has(e.slug) ? "收起内容" : "展开查看该 Room 的记录内容(默认收起)",
|
|
4421
|
+
onClick: () => void toggleRoomExpand(e.slug),
|
|
4422
|
+
style: { ...btn, borderRadius: 999, padding: "1px 7px", flexShrink: 0 },
|
|
4423
|
+
children: expandedRooms.has(e.slug) ? "▾" : "▸"
|
|
4424
|
+
}
|
|
4425
|
+
),
|
|
4426
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
4427
|
+
"span",
|
|
4428
|
+
{
|
|
4429
|
+
style: { fontSize: 12, cursor: hiPriv && !busy ? "grab" : "default", touchAction: "none" },
|
|
4430
|
+
onPointerDown: (ev) => onDragLabelDown(ev, e.slug),
|
|
4431
|
+
onPointerMove: onDragLabelMove,
|
|
4432
|
+
onPointerUp: onDragLabelUp,
|
|
4433
|
+
title: hiPriv && !busy ? "按住拖到某个 hall 头上归类(major/minor;记录随迁,旧名进别名)" : e.description ? `${e.slug} — ${e.description}` : e.slug,
|
|
4434
|
+
children: [
|
|
4435
|
+
standalone ? e.slug : "· " + e.slug.slice(g.hall.length + 1),
|
|
4436
|
+
e.source === "pre-registered" ? " ⭐" : ""
|
|
4437
|
+
]
|
|
4391
4438
|
}
|
|
4392
4439
|
),
|
|
4393
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", disabled: busy, title: "合并到另一个 Room(dryRun 预览→确认实跑)", onClick: () => {
|
|
4398
|
-
setForm({ action: "merge", from: e.slug, to: "" });
|
|
4399
|
-
setPreview(null);
|
|
4400
|
-
}, style: btn, children: "合并" }),
|
|
4401
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", disabled: busy, title: retired ? "恢复该 Room 到词表" : "退役该 Room(存量 tags 不动)", onClick: () => retire(e.slug, retired), style: { ...btn, ...retired ? { color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)" } : { color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)" } }, children: retired ? "恢复" : "退役" }),
|
|
4402
|
-
!retired ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", disabled: busy, title: "退役并退场该 Room 下全部记忆(软删,可在「已退场」区恢复)", onClick: () => retire(e.slug, false, true), style: { ...btn, color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)" }, children: "退场" }) : null
|
|
4440
|
+
e.label ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.muted, children: e.label }) : null,
|
|
4441
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.muted, children: count + " 条" }),
|
|
4442
|
+
retired ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: { ...S.muted, color: "var(--dsh-mem-danger)" }, children: "已退役" }) : null,
|
|
4443
|
+
(e.aliases ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: { ...S.muted, wordBreak: "break-all" }, children: "别名: " + (e.aliases ?? []).join(", ") }) : null
|
|
4403
4444
|
] }),
|
|
4404
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4445
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { display: "flex", gap: 6, flexShrink: 0, alignItems: "center" }, children: [
|
|
4446
|
+
!hiPriv ? null : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
4447
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", disabled: busy, title: "编辑显示名/归类说明", onClick: () => {
|
|
4448
|
+
setEditing({ slug: e.slug, label: e.label ?? "", description: e.description ?? "" });
|
|
4449
|
+
setForm(null);
|
|
4450
|
+
setPreview(null);
|
|
4451
|
+
setPicking(null);
|
|
4452
|
+
}, style: btn, children: "编辑" }),
|
|
4453
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4454
|
+
"button",
|
|
4455
|
+
{
|
|
4456
|
+
type: "button",
|
|
4457
|
+
disabled: busy,
|
|
4458
|
+
title: picking === e.slug ? "再点一次取消挑选;然后点击目标 hall 头完成归类" : "归类到已有 hall 下:点击后选目标 hall(记录随迁,旧名进别名)",
|
|
4459
|
+
onClick: () => {
|
|
4460
|
+
if (picking === e.slug) {
|
|
4461
|
+
setPicking(null);
|
|
4462
|
+
return;
|
|
4463
|
+
}
|
|
4464
|
+
setForm({ action: "rename", from: e.slug, to: "" });
|
|
4465
|
+
setPreview(null);
|
|
4466
|
+
setPicking(e.slug);
|
|
4467
|
+
setMsg(null);
|
|
4468
|
+
setError(null);
|
|
4469
|
+
},
|
|
4470
|
+
style: { ...btn, ...picking === e.slug ? { color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)" } : {} },
|
|
4471
|
+
children: picking === e.slug ? "选 hall…" : "归类"
|
|
4472
|
+
}
|
|
4473
|
+
),
|
|
4474
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", disabled: busy, title: `改名(= merge 1:1 + 注册表改名)`, onClick: () => {
|
|
4475
|
+
setForm({ action: "rename", from: e.slug, to: "" });
|
|
4476
|
+
setPreview(null);
|
|
4477
|
+
}, style: btn, children: "改名" }),
|
|
4478
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", disabled: busy, title: "合并到另一个 Room(dryRun 预览→确认实跑)", onClick: () => {
|
|
4479
|
+
setForm({ action: "merge", from: e.slug, to: "" });
|
|
4480
|
+
setPreview(null);
|
|
4481
|
+
}, style: btn, children: "合并" }),
|
|
4482
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", disabled: busy, title: retired ? "恢复该 Room 到词表" : "退役该 Room(存量 tags 不动)", onClick: () => retire(e.slug, retired), style: { ...btn, ...retired ? { color: "var(--dsh-mem-accent)", borderColor: "var(--dsh-mem-accent)" } : { color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)" } }, children: retired ? "恢复" : "退役" }),
|
|
4483
|
+
!retired ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", disabled: busy, title: "退役并退场该 Room 下全部记忆(软删,可在「已退场」区恢复)", onClick: () => retire(e.slug, false, true), style: { ...btn, color: "var(--dsh-mem-danger)", borderColor: "var(--dsh-mem-danger)" }, children: "退场" }) : null
|
|
4484
|
+
] }),
|
|
4485
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", disabled: busy, title: "导出该 Room 的记录清单 CSV", onClick: () => exportRecords(e.slug), style: btn, children: "导出" })
|
|
4486
|
+
] })
|
|
4487
|
+
] }),
|
|
4488
|
+
expandedRooms.has(e.slug) ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { margin: "4px 0 2px", padding: "4px 8px", border: "1px dashed var(--dsh-mem-border)", borderRadius: 6 }, children: [
|
|
4489
|
+
(roomRecords[e.slug]?.items ?? []).map((it) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { fontSize: 11, padding: "3px 0", borderBottom: "1px solid var(--dsh-mem-border)" }, children: [
|
|
4490
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "dsh-mem-tag dsh-mem-tag-" + it.type, children: TYPE_LABELS[it.type] || it.type }),
|
|
4491
|
+
" ",
|
|
4492
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.muted, children: it.updatedAt ? fmtTime(it.updatedAt) : "" }),
|
|
4493
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { marginTop: 2, wordBreak: "break-all", color: "var(--dsh-mem-text-2)" }, children: it.content.length > 120 ? it.content.slice(0, 120) + "…" : it.content })
|
|
4494
|
+
] }, it.id)),
|
|
4495
|
+
(roomRecords[e.slug]?.items.length ?? 0) === 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: S.muted, children: "该 Room 暂无记录。" }) : null,
|
|
4496
|
+
(roomRecords[e.slug]?.total ?? 0) > (roomRecords[e.slug]?.items.length ?? 0) ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { ...S.muted, fontSize: 11 }, children: "共 " + roomRecords[e.slug].total + " 条,仅显示前 " + roomRecords[e.slug].items.length + " 条" }) : null
|
|
4497
|
+
] }) : null
|
|
4498
|
+
] }, e.slug);
|
|
4499
|
+
}) : null
|
|
4500
|
+
] }, g.hall);
|
|
4501
|
+
}),
|
|
4502
|
+
visibleGrown.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { marginTop: 4 }, children: [
|
|
4421
4503
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("button", { type: "button", onClick: () => setGrownOpen(!grownOpen), style: btn, title: grownOpen ? "收起未注册自生长 Room" : "展开未注册自生长 Room", children: [
|
|
4422
4504
|
grownOpen ? "▾" : "▸",
|
|
4423
4505
|
" 自生长未注册 · 共 ",
|
|
4424
|
-
|
|
4506
|
+
visibleGrown.length
|
|
4425
4507
|
] }),
|
|
4426
4508
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: S.muted, children: "(只在 tags 里涌现,不在词表 —— 收编后标注器才会优先挂靠)" }),
|
|
4427
|
-
grownOpen ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center", marginTop: 6 }, children:
|
|
4509
|
+
grownOpen ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center", marginTop: 6 }, children: visibleGrown.map((r) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { style: { display: "inline-flex", alignItems: "center", gap: 4 }, children: [
|
|
4428
4510
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4429
4511
|
"span",
|
|
4430
4512
|
{
|
|
@@ -4499,6 +4581,7 @@ var __defProp = Object.defineProperty;
|
|
|
4499
4581
|
const [renaming, setRenaming] = (0, import_react17.useState)(null);
|
|
4500
4582
|
const [expanded, setExpanded] = (0, import_react17.useState)(/* @__PURE__ */ new Set());
|
|
4501
4583
|
const [retiredFilter, setRetiredFilter] = (0, import_react17.useState)("");
|
|
4584
|
+
const [filter, setFilter] = (0, import_react17.useState)("");
|
|
4502
4585
|
const [records, setRecords] = (0, import_react17.useState)({});
|
|
4503
4586
|
const loadAll = (0, import_react17.useCallback)(() => {
|
|
4504
4587
|
rpc("dsh-memory/rooms-get", {}).then((r) => {
|
|
@@ -4649,6 +4732,10 @@ var __defProp = Object.defineProperty;
|
|
|
4649
4732
|
if (retiredFilter === "retired") return row2.entry?.status === "retired";
|
|
4650
4733
|
return true;
|
|
4651
4734
|
});
|
|
4735
|
+
const normFilter = filter.trim().toLowerCase();
|
|
4736
|
+
const visibleRows = normFilter ? rows.filter(
|
|
4737
|
+
(row2) => row2.slug.toLowerCase().includes(normFilter) || (row2.entry?.label ?? "").toLowerCase().includes(normFilter) || (row2.entry?.aliases ?? []).some((a) => a.toLowerCase().includes(normFilter))
|
|
4738
|
+
) : rows;
|
|
4652
4739
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
|
|
4653
4740
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { ...S.flexRow, marginBottom: 8, flexWrap: "wrap" }, children: [
|
|
4654
4741
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: S.muted, children: "Room 级管理:存在(注册/收编/退役)· 名称(显示名/说明/改名)· 条目(展开浏览) · 归类到 hall 请到「Hall」页" }),
|
|
@@ -4699,7 +4786,7 @@ var __defProp = Object.defineProperty;
|
|
|
4699
4786
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", disabled: busy, onClick: () => setRenaming(null), style: btn2, children: "取消" }),
|
|
4700
4787
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: S.muted, children: "记录随迁;与反刍并发会互相覆盖,请在反刍空闲时执行。" })
|
|
4701
4788
|
] }) : null,
|
|
4702
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, marginBottom: 8 }, children: [
|
|
4789
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, marginBottom: 8, flexWrap: "wrap" }, children: [
|
|
4703
4790
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: S.muted, children: "退场筛选" }),
|
|
4704
4791
|
[["", "全部"], ["active", "活跃"], ["retired", "已退役"]].map(([val, label]) => {
|
|
4705
4792
|
const on = retiredFilter === val;
|
|
@@ -4722,7 +4809,18 @@ var __defProp = Object.defineProperty;
|
|
|
4722
4809
|
},
|
|
4723
4810
|
val
|
|
4724
4811
|
);
|
|
4725
|
-
})
|
|
4812
|
+
}),
|
|
4813
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.grow }),
|
|
4814
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4815
|
+
"input",
|
|
4816
|
+
{
|
|
4817
|
+
value: filter,
|
|
4818
|
+
onChange: (e) => setFilter(e.target.value),
|
|
4819
|
+
placeholder: "搜索 room(slug、显示名、别名)",
|
|
4820
|
+
style: { ...S.input, width: 230, fontSize: 12 }
|
|
4821
|
+
}
|
|
4822
|
+
),
|
|
4823
|
+
filter ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", style: btn2, onClick: () => setFilter(""), children: "清除" }) : null
|
|
4726
4824
|
] }),
|
|
4727
4825
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, alignItems: "center", marginBottom: 10 }, children: [
|
|
4728
4826
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("input", { value: reg.slug, onChange: (e) => setReg({ ...reg, slug: e.target.value }), placeholder: "slug(如 dsh-plugin 或 dsh-plugin/merge)", disabled: !hiPriv || busy, style: { ...S.input, width: 210, fontSize: 12 } }),
|
|
@@ -4733,7 +4831,7 @@ var __defProp = Object.defineProperty;
|
|
|
4733
4831
|
] }),
|
|
4734
4832
|
msg ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.hint, children: msg }) : null,
|
|
4735
4833
|
error ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: S.error, children: error }) : null,
|
|
4736
|
-
|
|
4834
|
+
visibleRows.length === 0 ? normFilter ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: S.intro, children: "无匹配的 Room。" }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: S.intro, children: "暂无 Room:对话/反刍会从标签涌现,或在上方注册。" }) : visibleRows.map((row2) => {
|
|
4737
4835
|
const e = row2.entry;
|
|
4738
4836
|
const retired = e?.status === "retired";
|
|
4739
4837
|
const grownOnly = !e;
|