@tobycaimf/dsh-archived-sessions 1.0.0 → 1.0.1
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/README.en.md +12 -1
- package/README.md +12 -1
- package/assets/screenshot-archived-sessions.png +0 -0
- package/assets/screenshot-batch-mode.png +0 -0
- package/lib/client.js +256 -0
- package/lib/client.js.map +2 -2
- package/lib/index.js +188 -1
- package/lib/index.js.map +2 -2
- package/package.json +2 -2
- package/src/client/index.jsx +280 -0
- package/src/index.js +188 -6
package/README.en.md
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
> Manage your **archived sessions** in DSH — view, restore, and permanently delete them.
|
|
6
6
|
> Archive logo, session dates, workspace tags, and **batch multi-select** (restore / delete selected).
|
|
7
|
+
> Also ships a **"Move Session"** panel to relocate any conversation to a different workspace (existing or a new directory).
|
|
7
8
|
|
|
8
|
-
A persistent DSH plugin (host + browser halves). Manage every session that has been archived (hidden from the sidebar) under **Settings → 归档会话 (Archived Sessions)**.
|
|
9
|
+
A persistent DSH plugin (host + browser halves). Manage every session that has been archived (hidden from the sidebar) under **Settings → 归档会话 (Archived Sessions)**, and relocate sessions between workspaces under **Settings → 移动会话 (Move Session)**.
|
|
9
10
|
|
|
10
11
|
## Features
|
|
11
12
|
|
|
@@ -13,8 +14,15 @@ A persistent DSH plugin (host + browser halves). Manage every session that has b
|
|
|
13
14
|
- **Restore**: unarchive and put the session back into its group.
|
|
14
15
|
- **Permanently delete**: physically removes the session log file + detaches workspace accounting — **irreversible** (asks for confirmation first).
|
|
15
16
|
- **Batch multi-select**: one-click batch mode — select-all, restore selected, delete selected (single confirmation for batch delete).
|
|
17
|
+
- **Move session to a workspace**: `Settings → 移动会话` lists every session (archived ones included); pick an **existing workspace** or type a **new directory path** (auto-created) and confirm — the session's working directory and log are migrated, and it moves into the corresponding workspace group. Sessions that are currently open must be switched away from first.
|
|
16
18
|
- **Adaptive UI**: follows the theme tokens (light/dark), stacks vertically on narrow screens; loading / empty / error / busy states, keyboard focus and `prefers-reduced-motion` support.
|
|
17
19
|
|
|
20
|
+
## Screenshots
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+

|
|
25
|
+
|
|
18
26
|
## Install
|
|
19
27
|
|
|
20
28
|
```sh
|
|
@@ -61,6 +69,9 @@ lib/client.js pre-built client (ModuleLoader CJS handshake)
|
|
|
61
69
|
| POST | `/archived-sessions/restore-many` | Unarchive many |
|
|
62
70
|
| POST | `/archived-sessions/delete` | Permanently delete a single session (physically removes log, keeps hidden) |
|
|
63
71
|
| POST | `/archived-sessions/delete-many` | Permanently delete many |
|
|
72
|
+
| POST | `/archived-sessions/sessions` | List all sessions (with archived flag) for the Move Session panel |
|
|
73
|
+
| POST | `/archived-sessions/workspaces` | List available target workspaces |
|
|
74
|
+
| POST | `/archived-sessions/move` | Move a session to a target workspace `{ sessionId, targetPath }` |
|
|
64
75
|
|
|
65
76
|
> On delete the session **stays archived** (is not unarchived), so it won't pop back into the sidebar / "ungrouped"; entries whose log is already gone are skipped.
|
|
66
77
|
> DSH has no official session-delete API; this plugin implements "physically remove log + detach ownership + keep hidden".
|
package/README.md
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
> DSH 设置面板「归档会话」管理器:查看、恢复、彻底删除已归档的 session。
|
|
6
6
|
> 带归档 logo、会话日期、所属工作区标签,以及**批量多选**(恢复所选 / 删除所选)。
|
|
7
|
+
> 另有**「移动会话」**面板,可把任意会话移动到不同工作区(现有或新建目录)。
|
|
7
8
|
|
|
8
|
-
一个 DSH 持久化插件(host + browser 双半)。在 **设置 → 归档会话**
|
|
9
|
+
一个 DSH 持久化插件(host + browser 双半)。在 **设置 → 归档会话** 里管理所有被归档(从侧栏隐藏)的会话;在 **设置 → 移动会话** 里把会话迁移到其它工作区。
|
|
9
10
|
|
|
10
11
|
## 功能
|
|
11
12
|
|
|
@@ -13,8 +14,15 @@
|
|
|
13
14
|
- **恢复**:取消归档,放回原分组。
|
|
14
15
|
- **彻底删除**:物理删除会话日志文件 + 解除工作区归属,**不可恢复**(删除前有二次确认)。
|
|
15
16
|
- **批量多选**:一键进入批量模式,全选 / 恢复所选 / 删除所选(批量删除一次二次确认)。
|
|
17
|
+
- **移动会话到工作区**:`设置 → 移动会话` 列出全部会话(含已归档),任选**已有工作区**或**新建目录路径**(自动创建)后确认,即把该会话的工作目录与日志合迁移过去,会话随之下滑到对应工作区分组;处于打开状态的会话需先切走。
|
|
16
18
|
- **自适应 UI**:深浅色跟随主题 token,窄屏自动纵向堆叠;加载/空/错误/操作中状态齐全;支持键盘焦点、`prefers-reduced-motion`。
|
|
17
19
|
|
|
20
|
+
## 截图
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+

|
|
25
|
+
|
|
18
26
|
## 安装
|
|
19
27
|
|
|
20
28
|
```sh
|
|
@@ -61,6 +69,9 @@ lib/client.js 预构建 client(ModuleLoader CJS handshake)
|
|
|
61
69
|
| POST | `/archived-sessions/restore-many` | 批量取消归档 |
|
|
62
70
|
| POST | `/archived-sessions/delete` | 彻底删除单个(物理删日志,保持隐藏) |
|
|
63
71
|
| POST | `/archived-sessions/delete-many` | 批量彻底删除 |
|
|
72
|
+
| POST | `/archived-sessions/sessions` | 列出全部会话(含已归档标记),供「移动会话」面板 |
|
|
73
|
+
| POST | `/archived-sessions/workspaces` | 列出可选目标工作区 |
|
|
74
|
+
| POST | `/archived-sessions/move` | 把会话移动到目标工作区 `{ sessionId, targetPath }` |
|
|
64
75
|
|
|
65
76
|
> 删除时会**保留归档位**(不取消归档),从而不会把会话放回侧栏/未分组;并跳过日志已不存在的条目。
|
|
66
77
|
> DSH 本身没有官方 session 删除接口,本插件是「物理删日志 + 解除归属 + 保持隐藏」的实现。
|
|
Binary file
|
|
Binary file
|
package/lib/client.js
CHANGED
|
@@ -194,7 +194,256 @@ function ArchivedPanel() {
|
|
|
194
194
|
toast && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "archv-status", role: "status", children: toast })
|
|
195
195
|
] });
|
|
196
196
|
}
|
|
197
|
+
var MOVE_CSS = `
|
|
198
|
+
.mv{display:flex;flex-direction:column;gap:4px;max-width:800px;padding:8px 2px 28px}
|
|
199
|
+
.mv-head{display:flex;align-items:center;gap:10px;margin:0 0 2px}
|
|
200
|
+
.mv-title{font-size:16px;font-weight:650;color:var(--dsw-alias-label-primary);letter-spacing:-0.01em;margin:0}
|
|
201
|
+
.mv-count{font-size:11px;font-weight:600;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-fill-subtle);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;padding:1px 8px;flex:none}
|
|
202
|
+
.mv-sub{font-size:12px;line-height:1.55;color:var(--dsw-alias-label-tertiary);margin:0 0 12px;max-width:64ch}
|
|
203
|
+
.mv-err{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 12px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary) 40%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 8%,transparent);border-radius:10px;color:var(--dsw-alias-state-error-primary);font-size:12px;margin-bottom:10px}
|
|
204
|
+
.mv-errretry{appearance:none;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary) 45%,transparent);background:transparent;color:inherit;border-radius:8px;padding:4px 10px;font-size:11px;cursor:pointer;flex:none}
|
|
205
|
+
.mv-list{display:flex;flex-direction:column;gap:8px}
|
|
206
|
+
.mv-card{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:12px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-fill-elevated);transition:border-color .15s ease}
|
|
207
|
+
.mv-card:hover{border-color:var(--dsw-alias-border-l4)}
|
|
208
|
+
.mv-main{min-width:0;display:flex;flex-direction:column;gap:4px}
|
|
209
|
+
.mv-name{font-size:13px;font-weight:550;color:var(--dsw-alias-label-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
210
|
+
.mv-meta{display:flex;align-items:center;gap:7px;flex-wrap:wrap;min-width:0}
|
|
211
|
+
.mv-wtag{display:inline-flex;align-items:center;gap:4px;max-width:100%;font-size:11px;font-weight:500;line-height:1;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-fill-subtle);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;padding:3px 8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
212
|
+
.mv-archived{color:var(--dsw-alias-state-warning-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-warning-primary) 50%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-warning-primary) 8%,transparent)}
|
|
213
|
+
.mv-date{font-size:11px;color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none}
|
|
214
|
+
.mv-id{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:10.5px;color:var(--dsw-alias-label-tertiary);flex:none}
|
|
215
|
+
.mv-dot{color:var(--dsw-alias-border-l3);flex:none}
|
|
216
|
+
.mv-actions{display:flex;gap:8px;flex:none}
|
|
217
|
+
.mv-btn{appearance:none;min-height:32px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-fill-subtle);color:var(--dsw-alias-label-secondary);border-radius:9px;font-size:12px;font-weight:500;cursor:pointer;display:inline-flex;align-items:center;gap:6px;transition:background-color .15s ease,border-color .15s ease,color .15s ease}
|
|
218
|
+
.mv-btn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}
|
|
219
|
+
.mv-btn:disabled{opacity:.5;cursor:default}
|
|
220
|
+
.mv-go{color:var(--dsw-alias-state-business-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-business-primary) 45%,transparent)}
|
|
221
|
+
.mv-go:hover:not(:disabled){background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 10%,transparent);color:var(--dsw-alias-state-business-primary)}
|
|
222
|
+
.mv-sheet{display:flex;flex-direction:column;gap:10px;margin-top:10px;padding:12px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-fill-subtle)}
|
|
223
|
+
.mv-sheet-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:12px;color:var(--dsw-alias-label-secondary)}
|
|
224
|
+
.mv-sheet-row input[type=radio]{accent-color:var(--dsw-alias-state-business-primary)}
|
|
225
|
+
.mv-sheet select,.mv-sheet input[type=text]{appearance:none;min-height:32px;padding:0 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:9px;background:var(--dsw-alias-fill-elevated);color:var(--dsw-alias-label-primary);font-size:12px;font-family:inherit}
|
|
226
|
+
.mv-sheet input[type=text]{flex:1;min-width:220px}
|
|
227
|
+
.mv-sheet select:focus-visible,.mv-sheet input[type=text]:focus-visible,.mv-go:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}
|
|
228
|
+
.mv-empty{display:flex;align-items:center;gap:10px;padding:20px 14px;border:1px dashed var(--dsw-alias-border-l3);border-radius:12px;color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}
|
|
229
|
+
.mv-skel{display:flex;flex-direction:column;gap:8px}
|
|
230
|
+
.mv-skel-card{height:58px;border-radius:12px;background:var(--dsw-alias-fill-subtle);position:relative;overflow:hidden}
|
|
231
|
+
.mv-skel-card::after{content:'';position:absolute;inset:0;transform:translateX(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--dsw-alias-fill-elevated) 75%,transparent),transparent);animation:mv-shimmer 1.4s infinite}
|
|
232
|
+
@keyframes mv-shimmer{100%{transform:translateX(100%)}}
|
|
233
|
+
@keyframes mv-pop{from{opacity:0;transform:translateX(-50%) translateY(10px)}}
|
|
234
|
+
.mv-status{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);z-index:60;background:var(--dsw-alias-fill-elevated);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);padding:9px 16px;border-radius:999px;font-size:12px;box-shadow:0 8px 24px rgb(0 0 0/.18);display:flex;align-items:center;gap:8px;animation:mv-pop .18s ease-out;max-width:min(90vw,420px)}
|
|
235
|
+
.mv-spin{width:12px;height:12px;border:2px solid color-mix(in srgb,var(--dsw-alias-label-secondary) 35%,transparent);border-top-color:var(--dsw-alias-label-secondary);border-radius:50%;animation:archv-rot .8s linear infinite;flex:none}
|
|
236
|
+
@media (prefers-reduced-motion:reduce){.mv-skel-card::after{animation:none}.mv-card,.mv-btn{transition:none}.mv-status,.mv-spin{animation:none}}
|
|
237
|
+
@media (max-width:560px){.mv-card{flex-direction:column;align-items:stretch;gap:10px}.mv-actions{justify-content:flex-end}.mv-sheet input[type=text]{min-width:0}}
|
|
238
|
+
`;
|
|
239
|
+
function MovePanel() {
|
|
240
|
+
const [sessions, setSessions] = (0, import_react.useState)(null);
|
|
241
|
+
const [workspaces, setWorkspaces] = (0, import_react.useState)([]);
|
|
242
|
+
const [busy, setBusy] = (0, import_react.useState)(null);
|
|
243
|
+
const [open, setOpen] = (0, import_react.useState)(null);
|
|
244
|
+
const [mode, setMode] = (0, import_react.useState)("existing");
|
|
245
|
+
const [targetWs, setTargetWs] = (0, import_react.useState)("");
|
|
246
|
+
const [newPath, setNewPath] = (0, import_react.useState)("");
|
|
247
|
+
const [error, setError] = (0, import_react.useState)(null);
|
|
248
|
+
const [toast, setToast] = (0, import_react.useState)(null);
|
|
249
|
+
const timer = (0, import_react.useRef)(null);
|
|
250
|
+
const showToast = (msg) => {
|
|
251
|
+
if (timer.current) clearTimeout(timer.current);
|
|
252
|
+
setToast(msg);
|
|
253
|
+
timer.current = setTimeout(() => setToast(null), 2400);
|
|
254
|
+
};
|
|
255
|
+
const refresh = () => {
|
|
256
|
+
setError(null);
|
|
257
|
+
Promise.all([
|
|
258
|
+
postJSON("/archived-sessions/sessions", {}),
|
|
259
|
+
postJSON("/archived-sessions/workspaces", {})
|
|
260
|
+
]).then(([s, works]) => {
|
|
261
|
+
setSessions(s.items || []);
|
|
262
|
+
setWorkspaces(works.items || []);
|
|
263
|
+
if (!targetWs && works.items && works.items.length) setTargetWs(works.items[0].workspaceId);
|
|
264
|
+
}).catch((e) => setError(String(e && e.message || e)));
|
|
265
|
+
};
|
|
266
|
+
(0, import_react.useEffect)(() => {
|
|
267
|
+
refresh();
|
|
268
|
+
return () => {
|
|
269
|
+
if (timer.current) clearTimeout(timer.current);
|
|
270
|
+
};
|
|
271
|
+
}, []);
|
|
272
|
+
const wsPath = (id) => {
|
|
273
|
+
const w = workspaces.find((x) => x.workspaceId === id);
|
|
274
|
+
return w ? w.path : "";
|
|
275
|
+
};
|
|
276
|
+
const doMove = (it) => {
|
|
277
|
+
const targetPath = mode === "new" ? newPath.trim() : wsPath(targetWs);
|
|
278
|
+
if (!targetPath) {
|
|
279
|
+
setError("\u8BF7\u9009\u62E9\u5DF2\u6709\u5DE5\u4F5C\u533A\u6216\u8F93\u5165\u65B0\u7684\u76EE\u6807\u76EE\u5F55\u8DEF\u5F84");
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
setBusy(it.sessionId);
|
|
283
|
+
setError(null);
|
|
284
|
+
postJSON("/archived-sessions/move", { sessionId: it.sessionId, targetPath }).then((r) => {
|
|
285
|
+
setBusy(null);
|
|
286
|
+
setOpen(null);
|
|
287
|
+
setMode("existing");
|
|
288
|
+
setNewPath("");
|
|
289
|
+
showToast(`\u5DF2\u628A\u300C${it.title || it.sessionId}\u300D\u79FB\u5230 ${r.workspaceTitle || targetPath}`);
|
|
290
|
+
refresh();
|
|
291
|
+
}).catch((e) => {
|
|
292
|
+
setBusy(null);
|
|
293
|
+
setError(String(e && e.message || e));
|
|
294
|
+
});
|
|
295
|
+
};
|
|
296
|
+
const wtag = (it) => {
|
|
297
|
+
if (it.workspacePath) {
|
|
298
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mv-wtag", title: it.workspacePath, children: it.workspaceTitle || pathName(it.workspacePath) });
|
|
299
|
+
}
|
|
300
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mv-wtag", children: "\u672A\u5206\u7EC4" });
|
|
301
|
+
};
|
|
302
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mv", role: "region", "aria-label": "\u79FB\u52A8\u4F1A\u8BDD", children: [
|
|
303
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: MOVE_CSS }),
|
|
304
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mv-head", children: [
|
|
305
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "mv-title", children: "\u79FB\u52A8\u4F1A\u8BDD\u5230\u5DE5\u4F5C\u533A" }),
|
|
306
|
+
sessions !== null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mv-count", "aria-label": `${sessions.length} \u4E2A\u4F1A\u8BDD`, children: sessions.length })
|
|
307
|
+
] }),
|
|
308
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mv-sub", children: "\u628A\u4EFB\u610F\u4F1A\u8BDD\u79FB\u52A8\u5230\u67D0\u4E2A\u5DE5\u4F5C\u533A\u76EE\u5F55\uFF08\u53EF\u9009\u7528\u73B0\u6709\u5DE5\u4F5C\u533A\u6216\u8F93\u5165\u65B0\u76EE\u5F55\uFF0C\u81EA\u52A8\u521B\u5EFA\uFF09\u3002\u79FB\u52A8\u4F1A\u6539\u5199\u4F1A\u8BDD\u7684\u5DE5\u4F5C\u76EE\u5F55\u5E76\u628A\u65E5\u5FD7\u8FC1\u79FB\u8FC7\u53BB\uFF1B \u4F1A\u8BDD\u5F53\u524D\u5904\u4E8E\u6253\u5F00\u72B6\u6001\u65F6\u9700\u5148\u5728\u4FA7\u680F\u5207\u8D70\u624D\u80FD\u79FB\u52A8\u3002" }),
|
|
309
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mv-err", role: "alert", children: [
|
|
310
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: error }),
|
|
311
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "mv-errretry", onClick: refresh, children: "\u91CD\u8BD5" })
|
|
312
|
+
] }),
|
|
313
|
+
sessions === null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mv-skel", "aria-label": "\u52A0\u8F7D\u4E2D", children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mv-skel-card" }, i)) }) : sessions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mv-empty", children: "\u6682\u65E0\u53EF\u79FB\u52A8\u7684\u4F1A\u8BDD\u3002" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mv-list", role: "list", children: sessions.map((it) => {
|
|
314
|
+
const date = fmtDate(it.createdAt);
|
|
315
|
+
const expanded = open === it.sessionId;
|
|
316
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mv-card", role: "listitem", children: [
|
|
317
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mv-main", children: [
|
|
318
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mv-name", title: it.title || "", children: it.title || "(\u65E0\u6807\u9898)" }),
|
|
319
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mv-meta", children: [
|
|
320
|
+
it.archived && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mv-wtag mv-archived", children: "\u5DF2\u5F52\u6863" }),
|
|
321
|
+
wtag(it),
|
|
322
|
+
date && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
323
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mv-dot", children: "\xB7" }),
|
|
324
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mv-date", children: date })
|
|
325
|
+
] }),
|
|
326
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mv-id", children: it.sessionId })
|
|
327
|
+
] }),
|
|
328
|
+
expanded && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mv-sheet", children: [
|
|
329
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "mv-sheet-row", children: [
|
|
330
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "radio", name: "mv-target", checked: mode === "existing", onChange: () => setMode("existing") }),
|
|
331
|
+
"\u5DF2\u6709\u5DE5\u4F5C\u533A"
|
|
332
|
+
] }),
|
|
333
|
+
mode === "existing" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mv-sheet-row", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { value: targetWs, onChange: (e) => setTargetWs(e.target.value), "aria-label": "\u76EE\u6807\u5DE5\u4F5C\u533A", children: [
|
|
334
|
+
workspaces.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "\uFF08\u6682\u65E0\u5DE5\u4F5C\u533A\uFF09" }),
|
|
335
|
+
workspaces.map((w) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("option", { value: w.workspaceId, children: [
|
|
336
|
+
w.title,
|
|
337
|
+
" \xB7 ",
|
|
338
|
+
w.path
|
|
339
|
+
] }, w.workspaceId))
|
|
340
|
+
] }) }),
|
|
341
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "mv-sheet-row", children: [
|
|
342
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "radio", name: "mv-target", checked: mode === "new", onChange: () => setMode("new") }),
|
|
343
|
+
"\u65B0\u5EFA\u5DE5\u4F5C\u533A\u76EE\u5F55"
|
|
344
|
+
] }),
|
|
345
|
+
mode === "new" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mv-sheet-row", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
346
|
+
"input",
|
|
347
|
+
{
|
|
348
|
+
type: "text",
|
|
349
|
+
value: newPath,
|
|
350
|
+
onChange: (e) => setNewPath(e.target.value),
|
|
351
|
+
placeholder: "\u4F8B\u5982 /Users/you/Projects/demo \u6216 ~/demo",
|
|
352
|
+
"aria-label": "\u65B0\u5DE5\u4F5C\u533A\u76EE\u5F55\u8DEF\u5F84"
|
|
353
|
+
}
|
|
354
|
+
) }),
|
|
355
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mv-sheet-row", children: [
|
|
356
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", className: "mv-btn mv-go", disabled: busy !== null, onClick: () => doMove(it), children: [
|
|
357
|
+
busy === it.sessionId && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mv-spin", "aria-hidden": "true" }),
|
|
358
|
+
"\u786E\u8BA4\u79FB\u52A8"
|
|
359
|
+
] }),
|
|
360
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "mv-btn", disabled: busy !== null, onClick: () => {
|
|
361
|
+
setOpen(null);
|
|
362
|
+
setMode("existing");
|
|
363
|
+
setNewPath("");
|
|
364
|
+
}, children: "\u53D6\u6D88" })
|
|
365
|
+
] })
|
|
366
|
+
] })
|
|
367
|
+
] }),
|
|
368
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mv-actions", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
369
|
+
"button",
|
|
370
|
+
{
|
|
371
|
+
type: "button",
|
|
372
|
+
className: "mv-btn mv-go",
|
|
373
|
+
disabled: busy !== null,
|
|
374
|
+
"aria-label": "\u79FB\u52A8 " + (it.title || it.sessionId),
|
|
375
|
+
onClick: () => {
|
|
376
|
+
if (expanded) {
|
|
377
|
+
setOpen(null);
|
|
378
|
+
} else {
|
|
379
|
+
setTargetWs(workspaces.length ? targetWs || workspaces[0].workspaceId : "");
|
|
380
|
+
setMode("existing");
|
|
381
|
+
setNewPath("");
|
|
382
|
+
setOpen(it.sessionId);
|
|
383
|
+
}
|
|
384
|
+
},
|
|
385
|
+
children: expanded ? "\u6536\u8D77" : "\u79FB\u52A8\u5230\u2026"
|
|
386
|
+
}
|
|
387
|
+
) })
|
|
388
|
+
] }, it.sessionId);
|
|
389
|
+
}) }),
|
|
390
|
+
toast && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mv-status", role: "status", children: toast })
|
|
391
|
+
] });
|
|
392
|
+
}
|
|
393
|
+
var NAV_CSS = `
|
|
394
|
+
[data-dsh-nav-archived] > svg:first-child,
|
|
395
|
+
[data-dsh-nav-move] > svg:first-child { display: none; }
|
|
396
|
+
[data-dsh-nav-archived]::before,
|
|
397
|
+
[data-dsh-nav-move]::before {
|
|
398
|
+
content: ''; flex: none; width: 16px; height: 16px; background: currentColor;
|
|
399
|
+
-webkit-mask: center / contain no-repeat; mask: center / contain no-repeat;
|
|
400
|
+
}
|
|
401
|
+
[data-dsh-nav-archived]::before {
|
|
402
|
+
-webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D'http://www.w3.org/2000/svg'%20width%3D'24'%20height%3D'24'%20viewBox%3D'0%200%2024%2024'%20fill%3D'none'%20stroke%3D'black'%20stroke-width%3D'2'%20stroke-linecap%3D'round'%20stroke-linejoin%3D'round'%3E%3Cpath%20d%3D'M21%208v13H3V8'/%3E%3Cpath%20d%3D'M1%203h22v5H1z'/%3E%3Cpath%20d%3D'M10%2012h4'/%3E%3C/svg%3E");
|
|
403
|
+
mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D'http://www.w3.org/2000/svg'%20width%3D'24'%20height%3D'24'%20viewBox%3D'0%200%2024%2024'%20fill%3D'none'%20stroke%3D'black'%20stroke-width%3D'2'%20stroke-linecap%3D'round'%20stroke-linejoin%3D'round'%3E%3Cpath%20d%3D'M21%208v13H3V8'/%3E%3Cpath%20d%3D'M1%203h22v5H1z'/%3E%3Cpath%20d%3D'M10%2012h4'/%3E%3C/svg%3E");
|
|
404
|
+
}
|
|
405
|
+
[data-dsh-nav-move]::before {
|
|
406
|
+
-webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D'http://www.w3.org/2000/svg'%20width%3D'24'%20height%3D'24'%20viewBox%3D'0%200%2024%2024'%20fill%3D'none'%20stroke%3D'black'%20stroke-width%3D'2'%20stroke-linecap%3D'round'%20stroke-linejoin%3D'round'%3E%3Cpath%20d%3D'M22%2019a2%202%200%200%201-2%202H4a2%202%200%200%201-2-2V5a2%202%200%200%201%202-2h5l2%203h9a2%202%200%200%201%202%202z'/%3E%3Cpath%20d%3D'M12%2010v6'/%3E%3Cpath%20d%3D'm15%2013-3%203-3-3'/%3E%3C/svg%3E");
|
|
407
|
+
mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D'http://www.w3.org/2000/svg'%20width%3D'24'%20height%3D'24'%20viewBox%3D'0%200%2024%2024'%20fill%3D'none'%20stroke%3D'black'%20stroke-width%3D'2'%20stroke-linecap%3D'round'%20stroke-linejoin%3D'round'%3E%3Cpath%20d%3D'M22%2019a2%202%200%200%201-2%202H4a2%202%200%200%201-2-2V5a2%202%200%200%201%202-2h5l2%203h9a2%202%200%200%201%202%202z'/%3E%3Cpath%20d%3D'M12%2010v6'/%3E%3Cpath%20d%3D'm15%2013-3%203-3-3'/%3E%3C/svg%3E");
|
|
408
|
+
}
|
|
409
|
+
`;
|
|
410
|
+
function markSettingsNav() {
|
|
411
|
+
const ARCHIVED_LABEL = "\u5F52\u6863\u4F1A\u8BDD";
|
|
412
|
+
const MOVE_LABEL = "\u79FB\u52A8\u4F1A\u8BDD";
|
|
413
|
+
let disposed = false;
|
|
414
|
+
const sync = () => {
|
|
415
|
+
if (disposed) return;
|
|
416
|
+
const buttons = document.querySelectorAll('[role="dialog"] nav button');
|
|
417
|
+
for (const b of buttons) {
|
|
418
|
+
const t = (b.textContent || "").trim();
|
|
419
|
+
if (t === ARCHIVED_LABEL) b.setAttribute("data-dsh-nav-archived", "");
|
|
420
|
+
else b.removeAttribute("data-dsh-nav-archived");
|
|
421
|
+
if (t === MOVE_LABEL) b.setAttribute("data-dsh-nav-move", "");
|
|
422
|
+
else b.removeAttribute("data-dsh-nav-move");
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
sync();
|
|
426
|
+
const obs = new MutationObserver(sync);
|
|
427
|
+
obs.observe(document.body, { childList: true, subtree: true, characterData: true });
|
|
428
|
+
return () => {
|
|
429
|
+
disposed = true;
|
|
430
|
+
obs.disconnect();
|
|
431
|
+
document.querySelectorAll("[data-dsh-nav-archived]").forEach((e) => e.removeAttribute("data-dsh-nav-archived"));
|
|
432
|
+
document.querySelectorAll("[data-dsh-nav-move]").forEach((e) => e.removeAttribute("data-dsh-nav-move"));
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
function installSettingsNavIcons(ctx) {
|
|
436
|
+
const styleEl = document.createElement("style");
|
|
437
|
+
styleEl.textContent = NAV_CSS;
|
|
438
|
+
document.head.appendChild(styleEl);
|
|
439
|
+
const dispose = markSettingsNav();
|
|
440
|
+
ctx.effect(() => () => {
|
|
441
|
+
dispose();
|
|
442
|
+
if (styleEl.parentNode) styleEl.parentNode.removeChild(styleEl);
|
|
443
|
+
});
|
|
444
|
+
}
|
|
197
445
|
function apply(ctx) {
|
|
446
|
+
installSettingsNavIcons(ctx);
|
|
198
447
|
ctx.slots.inject(
|
|
199
448
|
"settings.section",
|
|
200
449
|
() => ctx.slots.register(
|
|
@@ -202,6 +451,13 @@ function apply(ctx) {
|
|
|
202
451
|
(props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArchivedPanel, { ...props })
|
|
203
452
|
)
|
|
204
453
|
);
|
|
454
|
+
ctx.slots.inject(
|
|
455
|
+
"settings.section",
|
|
456
|
+
() => ctx.slots.register(
|
|
457
|
+
{ name: "settings.section", id: "move-sessions", order: 91, label: "\u79FB\u52A8\u4F1A\u8BDD" },
|
|
458
|
+
(props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MovePanel, { ...props })
|
|
459
|
+
)
|
|
460
|
+
);
|
|
205
461
|
}
|
|
206
462
|
return module.exports; } });
|
|
207
463
|
//# sourceMappingURL=client.js.map
|
package/lib/client.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/client/index.jsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * dsh-archived-sessions \u2014 browser half: renders the \"\u5F52\u6863\u4F1A\u8BDD\" Settings\n * section (settings.section list slot). It talks to the host half's\n * /archived-sessions/* JSON routes (list / restore / delete) by fetch,\n * showing title, session date, and a workspace tag (handles deleted\n * workspaces). All DOM/runtime wiring failures are logged, never thrown \u2014 a\n * thrown plugin apply takes down the whole web-shell boot.\n *\n * @module dsh-archived-sessions/client\n */\n\nimport React, { useEffect, useRef, useState } from 'react'\n\nexport const inject = ['slots']\n\nconst CSS = `\n.archv{display:flex;flex-direction:column;gap:4px;max-width:800px;padding:8px 2px 28px}\n.archv-head{display:flex;align-items:center;gap:10px;margin:0 0 2px}\n.archv-title{font-size:16px;font-weight:650;color:var(--dsw-alias-label-primary);letter-spacing:-0.01em;margin:0}\n.archv-count{font-size:11px;font-weight:600;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-fill-subtle);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;padding:1px 8px;flex:none}\n.archv-sub{font-size:12px;line-height:1.55;color:var(--dsw-alias-label-tertiary);margin:0 0 12px;max-width:64ch}\n.archv-err{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 12px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary) 40%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 8%,transparent);border-radius:10px;color:var(--dsw-alias-state-error-primary);font-size:12px;margin-bottom:10px}\n.archv-errretry{appearance:none;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary) 45%,transparent);background:transparent;color:inherit;border-radius:8px;padding:4px 10px;font-size:11px;cursor:pointer;flex:none}\n.archv-errretry:focus-visible,.archv-btn:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}\n.archv-list{display:flex;flex-direction:column;gap:8px}\n.archv-card{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:12px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-fill-elevated);transition:border-color .15s ease,background-color .15s ease}\n.archv-card:hover{border-color:var(--dsw-alias-border-l4)}\n.archv-main{min-width:0;display:flex;flex-direction:column;gap:4px}\n.archv-name{font-size:13px;font-weight:550;color:var(--dsw-alias-label-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.archv-meta{display:flex;align-items:center;gap:7px;flex-wrap:wrap;min-width:0}\n.archv-wtag{display:inline-flex;align-items:center;gap:4px;max-width:100%;font-size:11px;font-weight:500;line-height:1;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-fill-subtle);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;padding:3px 8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.archv-wgone{border-style:dashed;color:var(--dsw-alias-state-error-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 7%,transparent)}\n.archv-date{font-size:11px;color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none}\n.archv-id{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:10.5px;color:var(--dsw-alias-label-tertiary);flex:none}\n.archv-dot{color:var(--dsw-alias-border-l3);flex:none}\n.archv-actions{display:flex;gap:8px;flex:none}\n.archv-btn{appearance:none;min-height:32px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-fill-subtle);color:var(--dsw-alias-label-secondary);border-radius:9px;font-size:12px;font-weight:500;cursor:pointer;display:inline-flex;align-items:center;gap:6px;transition:background-color .15s ease,border-color .15s ease,color .15s ease}\n.archv-btn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.archv-btn:disabled{opacity:.5;cursor:default}\n.archv-restore{min-width:62px;justify-content:center}\n.archv-del{color:var(--dsw-alias-state-error-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 45%,transparent)}\n.archv-del:hover:not(:disabled){background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}\n.archv-empty{display:flex;align-items:center;gap:10px;padding:20px 14px;border:1px dashed var(--dsw-alias-border-l3);border-radius:12px;color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}\n.archv-skel{display:flex;flex-direction:column;gap:8px}\n.archv-skel-card{height:58px;border-radius:12px;background:var(--dsw-alias-fill-subtle);position:relative;overflow:hidden}\n.archv-skel-card::after{content:'';position:absolute;inset:0;transform:translateX(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--dsw-alias-fill-elevated) 75%,transparent),transparent);animation:archv-shimmer 1.4s infinite}\n.archv-status{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);z-index:60;background:var(--dsw-alias-fill-elevated);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);padding:9px 16px;border-radius:999px;font-size:12px;box-shadow:0 8px 24px rgb(0 0 0/.18);display:flex;align-items:center;gap:8px;animation:archv-pop .18s ease-out;max-width:min(90vw,420px)}\n.archv-spin{width:12px;height:12px;border:2px solid color-mix(in srgb,var(--dsw-alias-label-secondary) 35%,transparent);border-top-color:var(--dsw-alias-label-secondary);border-radius:50%;animation:archv-rot .8s linear infinite;flex:none}\n@keyframes archv-shimmer{100%{transform:translateX(100%)}}\n@keyframes archv-rot{to{transform:rotate(360deg)}}\n@keyframes archv-pop{from{opacity:0;transform:translateX(-50%) translateY(10px)}}\n@media (prefers-reduced-motion:reduce){.archv-skel-card::after{animation:none}.archv-card,.archv-btn{transition:none}.archv-status,.archv-spin{animation:none}}\n@media (max-width:560px){.archv-card{flex-direction:column;align-items:stretch;gap:10px}.archv-actions{justify-content:flex-end}}\n`\n\nfunction fmtDate(iso) {\n if (!iso) return null\n const d = new Date(iso)\n if (isNaN(d.getTime())) return null\n try {\n return new Intl.DateTimeFormat('zh-CN', { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }).format(d)\n } catch {\n return String(iso)\n }\n}\n\nfunction pathName(p) {\n if (!p) return null\n const parts = String(p).replace(/\\\\+$/, '').split(/[/\\\\]/)\n return parts[parts.length - 1] || p\n}\n\nasync function postJSON(path, body) {\n const res = await fetch(path, {\n method: 'POST',\n headers: { 'content-type': 'application/json', accept: 'application/json' },\n body: JSON.stringify(body || {}),\n })\n const data = await res.json().catch(() => null)\n if (!res.ok || !data) throw new Error((data && (data.error || data.message)) || `request failed (${res.status})`)\n return data\n}\n\nfunction ArchivedPanel() {\n const [items, setItems] = useState(null)\n const [busy, setBusy] = useState(null)\n const [confirmId, setConfirmId] = useState(null)\n const [error, setError] = useState(null)\n const [toast, setToast] = useState(null)\n const timer = useRef(null)\n\n const showToast = (msg) => {\n if (timer.current) clearTimeout(timer.current)\n setToast(msg)\n timer.current = setTimeout(() => setToast(null), 2400)\n }\n\n const refresh = () => {\n setError(null)\n postJSON('/archived-sessions/list', {})\n .then((r) => setItems(r.items || []))\n .catch((e) => setError(String((e && e.message) || e)))\n }\n\n useEffect(() => {\n refresh()\n return () => { if (timer.current) clearTimeout(timer.current) }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const act = (action, it) => {\n if (busy) return\n if (action === 'delete') {\n if (confirmId !== it.sessionId) { setConfirmId(it.sessionId); return }\n setConfirmId(null)\n } else { setConfirmId(null); setError(null) }\n setBusy(it.sessionId)\n postJSON('/archived-sessions/' + action, { sessionId: it.sessionId })\n .then(() => {\n setBusy(null)\n showToast(action === 'restore' ? `\u5DF2\u6062\u590D\u300C${it.title || it.sessionId}\u300D` : `\u5DF2\u5220\u9664 ${it.title || it.sessionId}`)\n refresh()\n })\n .catch((e) => { setBusy(null); setConfirmId(null); setError(String((e && e.message) || e)) })\n }\n\n const workspaceTag = (it) => {\n if (it.hasWorkspace && it.workspaceGone) {\n return (\n <span className=\"archv-wtag archv-wgone\" title={(it.workspacePath || '') + '\uFF08\u539F\u5DE5\u4F5C\u533A\u5DF2\u5220\u9664\uFF09'}>\n \u5DE5\u4F5C\u533A\u5DF2\u5220 \u00B7 {pathName(it.workspacePath) || '?'}\n </span>\n )\n }\n const wName = it.workspaceTitle || pathName(it.workspacePath)\n if (wName) return <span className=\"archv-wtag\" title={it.workspacePath || ''}>{wName}</span>\n return null\n }\n\n return (\n <div className=\"archv\" role=\"region\" aria-label=\"\u5F52\u6863\u4F1A\u8BDD\">\n <style>{CSS}</style>\n <div className=\"archv-head\">\n <h2 className=\"archv-title\">\u5F52\u6863\u4F1A\u8BDD</h2>\n {items !== null && <span className=\"archv-count\" aria-label={`${items.length} \u4E2A\u5F52\u6863\u4F1A\u8BDD`}>{items.length}</span>}\n </div>\n <p className=\"archv-sub\">\n \u88AB\u5F52\u6863\uFF08\u4ECE\u4FA7\u680F\u9690\u85CF\uFF09\u7684\u4F1A\u8BDD\u90FD\u5728\u8FD9\u91CC\u3002\u6062\u590D\u4F1A\u628A\u4F1A\u8BDD\u653E\u56DE\u539F\u5206\u7EC4\uFF1B\u5220\u9664\u4F1A\u5F7B\u5E95\u79FB\u9664\u65E5\u5FD7\u6587\u4EF6\uFF0C\u4E0D\u53EF\u6062\u590D\u3002\n </p>\n {error && (\n <div className=\"archv-err\" role=\"alert\">\n <span>{error}</span>\n <button type=\"button\" className=\"archv-errretry\" onClick={refresh}>\u91CD\u8BD5</button>\n </div>\n )}\n {items === null ? (\n <div className=\"archv-skel\" aria-label=\"\u52A0\u8F7D\u4E2D\">\n {[0, 1, 2].map((i) => <div key={i} className=\"archv-skel-card\" />)}\n </div>\n ) : items.length === 0 ? (\n <div className=\"archv-empty\">\u76EE\u524D\u6CA1\u6709\u5F52\u6863\u4F1A\u8BDD\u3002\u5728\u4FA7\u680F\u4EFB\u4E00\u4F1A\u8BDD\u7684\u83DC\u5355\u91CC\u9009\u62E9\u300C\u5F52\u6863\u300D\u5373\u53EF\u6536\u7EB3\u8FDB\u6765\u3002</div>\n ) : (\n <div className=\"archv-list\" role=\"list\">\n {items.map((it) => {\n const isConfirm = confirmId === it.sessionId\n const date = fmtDate(it.createdAt)\n const wtag = workspaceTag(it)\n return (\n <div key={it.sessionId} className=\"archv-card\" role=\"listitem\">\n <div className=\"archv-main\">\n <div className=\"archv-name\" title={it.title || ''}>{it.title || '(\u65E0\u6807\u9898)'}</div>\n <div className=\"archv-meta\">\n {date && <span className=\"archv-date\">{date}</span>}\n {date && wtag && <span className=\"archv-dot\">\u00B7</span>}\n {wtag}\n <span className=\"archv-id\">{it.sessionId}</span>\n </div>\n </div>\n <div className=\"archv-actions\">\n <button type=\"button\" className=\"archv-btn archv-restore\" disabled={busy !== null} aria-label={'\u6062\u590D ' + (it.title || it.sessionId)} onClick={() => act('restore', it)}>\n {busy === it.sessionId && <span className=\"archv-spin\" aria-hidden=\"true\" />}\u6062\u590D\n </button>\n <button type=\"button\" className=\"archv-btn archv-del\" disabled={busy !== null} aria-label={(isConfirm ? '\u786E\u8BA4\u5220\u9664 ' : '\u5220\u9664 ') + (it.title || it.sessionId)} onClick={() => act('delete', it)}>\n {isConfirm ? '\u786E\u8BA4\u5220\u9664?' : '\u5220\u9664'}\n </button>\n </div>\n </div>\n )\n })}\n </div>\n )}\n {toast && <div className=\"archv-status\" role=\"status\">{toast}</div>}\n </div>\n )\n}\n\nexport function apply(ctx) {\n ctx.slots.inject('settings.section', () =>\n ctx.slots.register(\n { name: 'settings.section', id: 'archived-sessions', order: 90, label: '\u5F52\u6863\u4F1A\u8BDD' },\n (props) => <ArchivedPanel {...props} />,\n ),\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * dsh-archived-sessions \u2014 browser half: renders the \"\u5F52\u6863\u4F1A\u8BDD\" Settings\n * section (settings.section list slot). It talks to the host half's\n * /archived-sessions/* JSON routes (list / restore / delete) by fetch,\n * showing title, session date, and a workspace tag (handles deleted\n * workspaces). All DOM/runtime wiring failures are logged, never thrown \u2014 a\n * thrown plugin apply takes down the whole web-shell boot.\n *\n * @module dsh-archived-sessions/client\n */\n\nimport React, { useEffect, useRef, useState } from 'react'\n\nexport const inject = ['slots']\n\nconst CSS = `\n.archv{display:flex;flex-direction:column;gap:4px;max-width:800px;padding:8px 2px 28px}\n.archv-head{display:flex;align-items:center;gap:10px;margin:0 0 2px}\n.archv-title{font-size:16px;font-weight:650;color:var(--dsw-alias-label-primary);letter-spacing:-0.01em;margin:0}\n.archv-count{font-size:11px;font-weight:600;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-fill-subtle);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;padding:1px 8px;flex:none}\n.archv-sub{font-size:12px;line-height:1.55;color:var(--dsw-alias-label-tertiary);margin:0 0 12px;max-width:64ch}\n.archv-err{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 12px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary) 40%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 8%,transparent);border-radius:10px;color:var(--dsw-alias-state-error-primary);font-size:12px;margin-bottom:10px}\n.archv-errretry{appearance:none;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary) 45%,transparent);background:transparent;color:inherit;border-radius:8px;padding:4px 10px;font-size:11px;cursor:pointer;flex:none}\n.archv-errretry:focus-visible,.archv-btn:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}\n.archv-list{display:flex;flex-direction:column;gap:8px}\n.archv-card{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:12px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-fill-elevated);transition:border-color .15s ease,background-color .15s ease}\n.archv-card:hover{border-color:var(--dsw-alias-border-l4)}\n.archv-main{min-width:0;display:flex;flex-direction:column;gap:4px}\n.archv-name{font-size:13px;font-weight:550;color:var(--dsw-alias-label-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.archv-meta{display:flex;align-items:center;gap:7px;flex-wrap:wrap;min-width:0}\n.archv-wtag{display:inline-flex;align-items:center;gap:4px;max-width:100%;font-size:11px;font-weight:500;line-height:1;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-fill-subtle);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;padding:3px 8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.archv-wgone{border-style:dashed;color:var(--dsw-alias-state-error-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 7%,transparent)}\n.archv-date{font-size:11px;color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none}\n.archv-id{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:10.5px;color:var(--dsw-alias-label-tertiary);flex:none}\n.archv-dot{color:var(--dsw-alias-border-l3);flex:none}\n.archv-actions{display:flex;gap:8px;flex:none}\n.archv-btn{appearance:none;min-height:32px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-fill-subtle);color:var(--dsw-alias-label-secondary);border-radius:9px;font-size:12px;font-weight:500;cursor:pointer;display:inline-flex;align-items:center;gap:6px;transition:background-color .15s ease,border-color .15s ease,color .15s ease}\n.archv-btn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.archv-btn:disabled{opacity:.5;cursor:default}\n.archv-restore{min-width:62px;justify-content:center}\n.archv-del{color:var(--dsw-alias-state-error-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 45%,transparent)}\n.archv-del:hover:not(:disabled){background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}\n.archv-empty{display:flex;align-items:center;gap:10px;padding:20px 14px;border:1px dashed var(--dsw-alias-border-l3);border-radius:12px;color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}\n.archv-skel{display:flex;flex-direction:column;gap:8px}\n.archv-skel-card{height:58px;border-radius:12px;background:var(--dsw-alias-fill-subtle);position:relative;overflow:hidden}\n.archv-skel-card::after{content:'';position:absolute;inset:0;transform:translateX(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--dsw-alias-fill-elevated) 75%,transparent),transparent);animation:archv-shimmer 1.4s infinite}\n.archv-status{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);z-index:60;background:var(--dsw-alias-fill-elevated);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);padding:9px 16px;border-radius:999px;font-size:12px;box-shadow:0 8px 24px rgb(0 0 0/.18);display:flex;align-items:center;gap:8px;animation:archv-pop .18s ease-out;max-width:min(90vw,420px)}\n.archv-spin{width:12px;height:12px;border:2px solid color-mix(in srgb,var(--dsw-alias-label-secondary) 35%,transparent);border-top-color:var(--dsw-alias-label-secondary);border-radius:50%;animation:archv-rot .8s linear infinite;flex:none}\n@keyframes archv-shimmer{100%{transform:translateX(100%)}}\n@keyframes archv-rot{to{transform:rotate(360deg)}}\n@keyframes archv-pop{from{opacity:0;transform:translateX(-50%) translateY(10px)}}\n@media (prefers-reduced-motion:reduce){.archv-skel-card::after{animation:none}.archv-card,.archv-btn{transition:none}.archv-status,.archv-spin{animation:none}}\n@media (max-width:560px){.archv-card{flex-direction:column;align-items:stretch;gap:10px}.archv-actions{justify-content:flex-end}}\n`\n\nfunction fmtDate(iso) {\n if (!iso) return null\n const d = new Date(iso)\n if (isNaN(d.getTime())) return null\n try {\n return new Intl.DateTimeFormat('zh-CN', { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }).format(d)\n } catch {\n return String(iso)\n }\n}\n\nfunction pathName(p) {\n if (!p) return null\n const parts = String(p).replace(/\\\\+$/, '').split(/[/\\\\]/)\n return parts[parts.length - 1] || p\n}\n\nasync function postJSON(path, body) {\n const res = await fetch(path, {\n method: 'POST',\n headers: { 'content-type': 'application/json', accept: 'application/json' },\n body: JSON.stringify(body || {}),\n })\n const data = await res.json().catch(() => null)\n if (!res.ok || !data) throw new Error((data && (data.error || data.message)) || `request failed (${res.status})`)\n return data\n}\n\nfunction ArchivedPanel() {\n const [items, setItems] = useState(null)\n const [busy, setBusy] = useState(null)\n const [confirmId, setConfirmId] = useState(null)\n const [error, setError] = useState(null)\n const [toast, setToast] = useState(null)\n const timer = useRef(null)\n\n const showToast = (msg) => {\n if (timer.current) clearTimeout(timer.current)\n setToast(msg)\n timer.current = setTimeout(() => setToast(null), 2400)\n }\n\n const refresh = () => {\n setError(null)\n postJSON('/archived-sessions/list', {})\n .then((r) => setItems(r.items || []))\n .catch((e) => setError(String((e && e.message) || e)))\n }\n\n useEffect(() => {\n refresh()\n return () => { if (timer.current) clearTimeout(timer.current) }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const act = (action, it) => {\n if (busy) return\n if (action === 'delete') {\n if (confirmId !== it.sessionId) { setConfirmId(it.sessionId); return }\n setConfirmId(null)\n } else { setConfirmId(null); setError(null) }\n setBusy(it.sessionId)\n postJSON('/archived-sessions/' + action, { sessionId: it.sessionId })\n .then(() => {\n setBusy(null)\n showToast(action === 'restore' ? `\u5DF2\u6062\u590D\u300C${it.title || it.sessionId}\u300D` : `\u5DF2\u5220\u9664 ${it.title || it.sessionId}`)\n refresh()\n })\n .catch((e) => { setBusy(null); setConfirmId(null); setError(String((e && e.message) || e)) })\n }\n\n const workspaceTag = (it) => {\n if (it.hasWorkspace && it.workspaceGone) {\n return (\n <span className=\"archv-wtag archv-wgone\" title={(it.workspacePath || '') + '\uFF08\u539F\u5DE5\u4F5C\u533A\u5DF2\u5220\u9664\uFF09'}>\n \u5DE5\u4F5C\u533A\u5DF2\u5220 \u00B7 {pathName(it.workspacePath) || '?'}\n </span>\n )\n }\n const wName = it.workspaceTitle || pathName(it.workspacePath)\n if (wName) return <span className=\"archv-wtag\" title={it.workspacePath || ''}>{wName}</span>\n return null\n }\n\n return (\n <div className=\"archv\" role=\"region\" aria-label=\"\u5F52\u6863\u4F1A\u8BDD\">\n <style>{CSS}</style>\n <div className=\"archv-head\">\n <h2 className=\"archv-title\">\u5F52\u6863\u4F1A\u8BDD</h2>\n {items !== null && <span className=\"archv-count\" aria-label={`${items.length} \u4E2A\u5F52\u6863\u4F1A\u8BDD`}>{items.length}</span>}\n </div>\n <p className=\"archv-sub\">\n \u88AB\u5F52\u6863\uFF08\u4ECE\u4FA7\u680F\u9690\u85CF\uFF09\u7684\u4F1A\u8BDD\u90FD\u5728\u8FD9\u91CC\u3002\u6062\u590D\u4F1A\u628A\u4F1A\u8BDD\u653E\u56DE\u539F\u5206\u7EC4\uFF1B\u5220\u9664\u4F1A\u5F7B\u5E95\u79FB\u9664\u65E5\u5FD7\u6587\u4EF6\uFF0C\u4E0D\u53EF\u6062\u590D\u3002\n </p>\n {error && (\n <div className=\"archv-err\" role=\"alert\">\n <span>{error}</span>\n <button type=\"button\" className=\"archv-errretry\" onClick={refresh}>\u91CD\u8BD5</button>\n </div>\n )}\n {items === null ? (\n <div className=\"archv-skel\" aria-label=\"\u52A0\u8F7D\u4E2D\">\n {[0, 1, 2].map((i) => <div key={i} className=\"archv-skel-card\" />)}\n </div>\n ) : items.length === 0 ? (\n <div className=\"archv-empty\">\u76EE\u524D\u6CA1\u6709\u5F52\u6863\u4F1A\u8BDD\u3002\u5728\u4FA7\u680F\u4EFB\u4E00\u4F1A\u8BDD\u7684\u83DC\u5355\u91CC\u9009\u62E9\u300C\u5F52\u6863\u300D\u5373\u53EF\u6536\u7EB3\u8FDB\u6765\u3002</div>\n ) : (\n <div className=\"archv-list\" role=\"list\">\n {items.map((it) => {\n const isConfirm = confirmId === it.sessionId\n const date = fmtDate(it.createdAt)\n const wtag = workspaceTag(it)\n return (\n <div key={it.sessionId} className=\"archv-card\" role=\"listitem\">\n <div className=\"archv-main\">\n <div className=\"archv-name\" title={it.title || ''}>{it.title || '(\u65E0\u6807\u9898)'}</div>\n <div className=\"archv-meta\">\n {date && <span className=\"archv-date\">{date}</span>}\n {date && wtag && <span className=\"archv-dot\">\u00B7</span>}\n {wtag}\n <span className=\"archv-id\">{it.sessionId}</span>\n </div>\n </div>\n <div className=\"archv-actions\">\n <button type=\"button\" className=\"archv-btn archv-restore\" disabled={busy !== null} aria-label={'\u6062\u590D ' + (it.title || it.sessionId)} onClick={() => act('restore', it)}>\n {busy === it.sessionId && <span className=\"archv-spin\" aria-hidden=\"true\" />}\u6062\u590D\n </button>\n <button type=\"button\" className=\"archv-btn archv-del\" disabled={busy !== null} aria-label={(isConfirm ? '\u786E\u8BA4\u5220\u9664 ' : '\u5220\u9664 ') + (it.title || it.sessionId)} onClick={() => act('delete', it)}>\n {isConfirm ? '\u786E\u8BA4\u5220\u9664?' : '\u5220\u9664'}\n </button>\n </div>\n </div>\n )\n })}\n </div>\n )}\n {toast && <div className=\"archv-status\" role=\"status\">{toast}</div>}\n </div>\n )\n}\n\nconst MOVE_CSS = `\n.mv{display:flex;flex-direction:column;gap:4px;max-width:800px;padding:8px 2px 28px}\n.mv-head{display:flex;align-items:center;gap:10px;margin:0 0 2px}\n.mv-title{font-size:16px;font-weight:650;color:var(--dsw-alias-label-primary);letter-spacing:-0.01em;margin:0}\n.mv-count{font-size:11px;font-weight:600;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-fill-subtle);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;padding:1px 8px;flex:none}\n.mv-sub{font-size:12px;line-height:1.55;color:var(--dsw-alias-label-tertiary);margin:0 0 12px;max-width:64ch}\n.mv-err{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 12px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary) 40%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 8%,transparent);border-radius:10px;color:var(--dsw-alias-state-error-primary);font-size:12px;margin-bottom:10px}\n.mv-errretry{appearance:none;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary) 45%,transparent);background:transparent;color:inherit;border-radius:8px;padding:4px 10px;font-size:11px;cursor:pointer;flex:none}\n.mv-list{display:flex;flex-direction:column;gap:8px}\n.mv-card{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:12px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-fill-elevated);transition:border-color .15s ease}\n.mv-card:hover{border-color:var(--dsw-alias-border-l4)}\n.mv-main{min-width:0;display:flex;flex-direction:column;gap:4px}\n.mv-name{font-size:13px;font-weight:550;color:var(--dsw-alias-label-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.mv-meta{display:flex;align-items:center;gap:7px;flex-wrap:wrap;min-width:0}\n.mv-wtag{display:inline-flex;align-items:center;gap:4px;max-width:100%;font-size:11px;font-weight:500;line-height:1;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-fill-subtle);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;padding:3px 8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.mv-archived{color:var(--dsw-alias-state-warning-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-warning-primary) 50%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-warning-primary) 8%,transparent)}\n.mv-date{font-size:11px;color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none}\n.mv-id{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:10.5px;color:var(--dsw-alias-label-tertiary);flex:none}\n.mv-dot{color:var(--dsw-alias-border-l3);flex:none}\n.mv-actions{display:flex;gap:8px;flex:none}\n.mv-btn{appearance:none;min-height:32px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-fill-subtle);color:var(--dsw-alias-label-secondary);border-radius:9px;font-size:12px;font-weight:500;cursor:pointer;display:inline-flex;align-items:center;gap:6px;transition:background-color .15s ease,border-color .15s ease,color .15s ease}\n.mv-btn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.mv-btn:disabled{opacity:.5;cursor:default}\n.mv-go{color:var(--dsw-alias-state-business-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-business-primary) 45%,transparent)}\n.mv-go:hover:not(:disabled){background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 10%,transparent);color:var(--dsw-alias-state-business-primary)}\n.mv-sheet{display:flex;flex-direction:column;gap:10px;margin-top:10px;padding:12px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-fill-subtle)}\n.mv-sheet-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:12px;color:var(--dsw-alias-label-secondary)}\n.mv-sheet-row input[type=radio]{accent-color:var(--dsw-alias-state-business-primary)}\n.mv-sheet select,.mv-sheet input[type=text]{appearance:none;min-height:32px;padding:0 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:9px;background:var(--dsw-alias-fill-elevated);color:var(--dsw-alias-label-primary);font-size:12px;font-family:inherit}\n.mv-sheet input[type=text]{flex:1;min-width:220px}\n.mv-sheet select:focus-visible,.mv-sheet input[type=text]:focus-visible,.mv-go:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}\n.mv-empty{display:flex;align-items:center;gap:10px;padding:20px 14px;border:1px dashed var(--dsw-alias-border-l3);border-radius:12px;color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}\n.mv-skel{display:flex;flex-direction:column;gap:8px}\n.mv-skel-card{height:58px;border-radius:12px;background:var(--dsw-alias-fill-subtle);position:relative;overflow:hidden}\n.mv-skel-card::after{content:'';position:absolute;inset:0;transform:translateX(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--dsw-alias-fill-elevated) 75%,transparent),transparent);animation:mv-shimmer 1.4s infinite}\n@keyframes mv-shimmer{100%{transform:translateX(100%)}}\n@keyframes mv-pop{from{opacity:0;transform:translateX(-50%) translateY(10px)}}\n.mv-status{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);z-index:60;background:var(--dsw-alias-fill-elevated);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);padding:9px 16px;border-radius:999px;font-size:12px;box-shadow:0 8px 24px rgb(0 0 0/.18);display:flex;align-items:center;gap:8px;animation:mv-pop .18s ease-out;max-width:min(90vw,420px)}\n.mv-spin{width:12px;height:12px;border:2px solid color-mix(in srgb,var(--dsw-alias-label-secondary) 35%,transparent);border-top-color:var(--dsw-alias-label-secondary);border-radius:50%;animation:archv-rot .8s linear infinite;flex:none}\n@media (prefers-reduced-motion:reduce){.mv-skel-card::after{animation:none}.mv-card,.mv-btn{transition:none}.mv-status,.mv-spin{animation:none}}\n@media (max-width:560px){.mv-card{flex-direction:column;align-items:stretch;gap:10px}.mv-actions{justify-content:flex-end}.mv-sheet input[type=text]{min-width:0}}\n`\n\nfunction MovePanel() {\n const [sessions, setSessions] = useState(null)\n const [workspaces, setWorkspaces] = useState([])\n const [busy, setBusy] = useState(null)\n const [open, setOpen] = useState(null)\n const [mode, setMode] = useState('existing')\n const [targetWs, setTargetWs] = useState('')\n const [newPath, setNewPath] = useState('')\n const [error, setError] = useState(null)\n const [toast, setToast] = useState(null)\n const timer = useRef(null)\n\n const showToast = (msg) => {\n if (timer.current) clearTimeout(timer.current)\n setToast(msg)\n timer.current = setTimeout(() => setToast(null), 2400)\n }\n\n const refresh = () => {\n setError(null)\n Promise.all([\n postJSON('/archived-sessions/sessions', {}),\n postJSON('/archived-sessions/workspaces', {}),\n ])\n .then(([s, works]) => {\n setSessions(s.items || [])\n setWorkspaces(works.items || [])\n if (!targetWs && works.items && works.items.length) setTargetWs(works.items[0].workspaceId)\n })\n .catch((e) => setError(String((e && e.message) || e)))\n }\n\n useEffect(() => {\n refresh()\n return () => { if (timer.current) clearTimeout(timer.current) }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const wsPath = (id) => {\n const w = workspaces.find((x) => x.workspaceId === id)\n return w ? w.path : ''\n }\n\n const doMove = (it) => {\n const targetPath = mode === 'new' ? newPath.trim() : wsPath(targetWs)\n if (!targetPath) { setError('\u8BF7\u9009\u62E9\u5DF2\u6709\u5DE5\u4F5C\u533A\u6216\u8F93\u5165\u65B0\u7684\u76EE\u6807\u76EE\u5F55\u8DEF\u5F84'); return }\n setBusy(it.sessionId)\n setError(null)\n postJSON('/archived-sessions/move', { sessionId: it.sessionId, targetPath })\n .then((r) => {\n setBusy(null)\n setOpen(null)\n setMode('existing')\n setNewPath('')\n showToast(`\u5DF2\u628A\u300C${it.title || it.sessionId}\u300D\u79FB\u5230 ${r.workspaceTitle || targetPath}`)\n refresh()\n })\n .catch((e) => { setBusy(null); setError(String((e && e.message) || e)) })\n }\n\n const wtag = (it) => {\n if (it.workspacePath) {\n return <span className=\"mv-wtag\" title={it.workspacePath}>{it.workspaceTitle || pathName(it.workspacePath)}</span>\n }\n return <span className=\"mv-wtag\">\u672A\u5206\u7EC4</span>\n }\n\n return (\n <div className=\"mv\" role=\"region\" aria-label=\"\u79FB\u52A8\u4F1A\u8BDD\">\n <style>{MOVE_CSS}</style>\n <div className=\"mv-head\">\n <h2 className=\"mv-title\">\u79FB\u52A8\u4F1A\u8BDD\u5230\u5DE5\u4F5C\u533A</h2>\n {sessions !== null && <span className=\"mv-count\" aria-label={`${sessions.length} \u4E2A\u4F1A\u8BDD`}>{sessions.length}</span>}\n </div>\n <p className=\"mv-sub\">\n \u628A\u4EFB\u610F\u4F1A\u8BDD\u79FB\u52A8\u5230\u67D0\u4E2A\u5DE5\u4F5C\u533A\u76EE\u5F55\uFF08\u53EF\u9009\u7528\u73B0\u6709\u5DE5\u4F5C\u533A\u6216\u8F93\u5165\u65B0\u76EE\u5F55\uFF0C\u81EA\u52A8\u521B\u5EFA\uFF09\u3002\u79FB\u52A8\u4F1A\u6539\u5199\u4F1A\u8BDD\u7684\u5DE5\u4F5C\u76EE\u5F55\u5E76\u628A\u65E5\u5FD7\u8FC1\u79FB\u8FC7\u53BB\uFF1B\n \u4F1A\u8BDD\u5F53\u524D\u5904\u4E8E\u6253\u5F00\u72B6\u6001\u65F6\u9700\u5148\u5728\u4FA7\u680F\u5207\u8D70\u624D\u80FD\u79FB\u52A8\u3002\n </p>\n {error && (\n <div className=\"mv-err\" role=\"alert\">\n <span>{error}</span>\n <button type=\"button\" className=\"mv-errretry\" onClick={refresh}>\u91CD\u8BD5</button>\n </div>\n )}\n {sessions === null ? (\n <div className=\"mv-skel\" aria-label=\"\u52A0\u8F7D\u4E2D\">\n {[0, 1, 2].map((i) => <div key={i} className=\"mv-skel-card\" />)}\n </div>\n ) : sessions.length === 0 ? (\n <div className=\"mv-empty\">\u6682\u65E0\u53EF\u79FB\u52A8\u7684\u4F1A\u8BDD\u3002</div>\n ) : (\n <div className=\"mv-list\" role=\"list\">\n {sessions.map((it) => {\n const date = fmtDate(it.createdAt)\n const expanded = open === it.sessionId\n return (\n <div key={it.sessionId} className=\"mv-card\" role=\"listitem\">\n <div className=\"mv-main\">\n <div className=\"mv-name\" title={it.title || ''}>{it.title || '(\u65E0\u6807\u9898)'}</div>\n <div className=\"mv-meta\">\n {it.archived && <span className=\"mv-wtag mv-archived\">\u5DF2\u5F52\u6863</span>}\n {wtag(it)}\n {date && <><span className=\"mv-dot\">\u00B7</span><span className=\"mv-date\">{date}</span></>}\n <span className=\"mv-id\">{it.sessionId}</span>\n </div>\n {expanded && (\n <div className=\"mv-sheet\">\n <label className=\"mv-sheet-row\">\n <input type=\"radio\" name=\"mv-target\" checked={mode === 'existing'} onChange={() => setMode('existing')} />\n \u5DF2\u6709\u5DE5\u4F5C\u533A\n </label>\n {mode === 'existing' && (\n <div className=\"mv-sheet-row\">\n <select value={targetWs} onChange={(e) => setTargetWs(e.target.value)} aria-label=\"\u76EE\u6807\u5DE5\u4F5C\u533A\">\n {workspaces.length === 0 && <option value=\"\">\uFF08\u6682\u65E0\u5DE5\u4F5C\u533A\uFF09</option>}\n {workspaces.map((w) => (\n <option key={w.workspaceId} value={w.workspaceId}>{w.title} \u00B7 {w.path}</option>\n ))}\n </select>\n </div>\n )}\n <label className=\"mv-sheet-row\">\n <input type=\"radio\" name=\"mv-target\" checked={mode === 'new'} onChange={() => setMode('new')} />\n \u65B0\u5EFA\u5DE5\u4F5C\u533A\u76EE\u5F55\n </label>\n {mode === 'new' && (\n <div className=\"mv-sheet-row\">\n <input\n type=\"text\"\n value={newPath}\n onChange={(e) => setNewPath(e.target.value)}\n placeholder=\"\u4F8B\u5982 /Users/you/Projects/demo \u6216 ~/demo\"\n aria-label=\"\u65B0\u5DE5\u4F5C\u533A\u76EE\u5F55\u8DEF\u5F84\"\n />\n </div>\n )}\n <div className=\"mv-sheet-row\">\n <button type=\"button\" className=\"mv-btn mv-go\" disabled={busy !== null} onClick={() => doMove(it)}>\n {busy === it.sessionId && <span className=\"mv-spin\" aria-hidden=\"true\" />}\u786E\u8BA4\u79FB\u52A8\n </button>\n <button type=\"button\" className=\"mv-btn\" disabled={busy !== null} onClick={() => { setOpen(null); setMode('existing'); setNewPath(''); }}>\u53D6\u6D88</button>\n </div>\n </div>\n )}\n </div>\n <div className=\"mv-actions\">\n <button\n type=\"button\"\n className=\"mv-btn mv-go\"\n disabled={busy !== null}\n aria-label={'\u79FB\u52A8 ' + (it.title || it.sessionId)}\n onClick={() => { if (expanded) { setOpen(null) } else { setTargetWs(workspaces.length ? (targetWs || workspaces[0].workspaceId) : ''); setMode('existing'); setNewPath(''); setOpen(it.sessionId) } }}\n >\n {expanded ? '\u6536\u8D77' : '\u79FB\u52A8\u5230\u2026'}\n </button>\n </div>\n </div>\n )\n })}\n </div>\n )}\n {toast && <div className=\"mv-status\" role=\"status\">{toast}</div>}\n </div>\n )\n}\n\n// Left-nav icon swap for the two plugin settings sections.\n//\n// DSH's settings shell renders a *shared* fallback gear for every custom\n// section (its internal navIcon() only differentiates \u6A21\u578B/\u63D2\u4EF6/Agent\u9884\u8BBE), and\n// settings.section has no per-section icon field. So \u2014 exactly like\n// dsh-better-sidebar \u2014 we mark our own rows by matching their visible label\n// text against the shell DOM, then let CSS swap the gear for a distinct glyph.\n// The marker owns no shell structure and is removed on fiber disposal, so the\n// adaptation stays HMR-safe and ships with the plugin.\nconst NAV_CSS = `\n[data-dsh-nav-archived] > svg:first-child,\n[data-dsh-nav-move] > svg:first-child { display: none; }\n[data-dsh-nav-archived]::before,\n[data-dsh-nav-move]::before {\n content: ''; flex: none; width: 16px; height: 16px; background: currentColor;\n -webkit-mask: center / contain no-repeat; mask: center / contain no-repeat;\n}\n[data-dsh-nav-archived]::before {\n -webkit-mask-image: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http://www.w3.org/2000/svg'%20width%3D'24'%20height%3D'24'%20viewBox%3D'0%200%2024%2024'%20fill%3D'none'%20stroke%3D'black'%20stroke-width%3D'2'%20stroke-linecap%3D'round'%20stroke-linejoin%3D'round'%3E%3Cpath%20d%3D'M21%208v13H3V8'/%3E%3Cpath%20d%3D'M1%203h22v5H1z'/%3E%3Cpath%20d%3D'M10%2012h4'/%3E%3C/svg%3E\");\n mask-image: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http://www.w3.org/2000/svg'%20width%3D'24'%20height%3D'24'%20viewBox%3D'0%200%2024%2024'%20fill%3D'none'%20stroke%3D'black'%20stroke-width%3D'2'%20stroke-linecap%3D'round'%20stroke-linejoin%3D'round'%3E%3Cpath%20d%3D'M21%208v13H3V8'/%3E%3Cpath%20d%3D'M1%203h22v5H1z'/%3E%3Cpath%20d%3D'M10%2012h4'/%3E%3C/svg%3E\");\n}\n[data-dsh-nav-move]::before {\n -webkit-mask-image: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http://www.w3.org/2000/svg'%20width%3D'24'%20height%3D'24'%20viewBox%3D'0%200%2024%2024'%20fill%3D'none'%20stroke%3D'black'%20stroke-width%3D'2'%20stroke-linecap%3D'round'%20stroke-linejoin%3D'round'%3E%3Cpath%20d%3D'M22%2019a2%202%200%200%201-2%202H4a2%202%200%200%201-2-2V5a2%202%200%200%201%202-2h5l2%203h9a2%202%200%200%201%202%202z'/%3E%3Cpath%20d%3D'M12%2010v6'/%3E%3Cpath%20d%3D'm15%2013-3%203-3-3'/%3E%3C/svg%3E\");\n mask-image: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http://www.w3.org/2000/svg'%20width%3D'24'%20height%3D'24'%20viewBox%3D'0%200%2024%2024'%20fill%3D'none'%20stroke%3D'black'%20stroke-width%3D'2'%20stroke-linecap%3D'round'%20stroke-linejoin%3D'round'%3E%3Cpath%20d%3D'M22%2019a2%202%200%200%201-2%202H4a2%202%200%200%201-2-2V5a2%202%200%200%201%202-2h5l2%203h9a2%202%200%200%201%202%202z'/%3E%3Cpath%20d%3D'M12%2010v6'/%3E%3Cpath%20d%3D'm15%2013-3%203-3-3'/%3E%3C/svg%3E\");\n}\n`\n\nfunction markSettingsNav() {\n const ARCHIVED_LABEL = '\u5F52\u6863\u4F1A\u8BDD'\n const MOVE_LABEL = '\u79FB\u52A8\u4F1A\u8BDD'\n let disposed = false\n const sync = () => {\n if (disposed) return\n const buttons = document.querySelectorAll('[role=\"dialog\"] nav button')\n for (const b of buttons) {\n const t = (b.textContent || '').trim()\n if (t === ARCHIVED_LABEL) b.setAttribute('data-dsh-nav-archived', '')\n else b.removeAttribute('data-dsh-nav-archived')\n if (t === MOVE_LABEL) b.setAttribute('data-dsh-nav-move', '')\n else b.removeAttribute('data-dsh-nav-move')\n }\n }\n sync()\n const obs = new MutationObserver(sync)\n obs.observe(document.body, { childList: true, subtree: true, characterData: true })\n return () => {\n disposed = true\n obs.disconnect()\n document.querySelectorAll('[data-dsh-nav-archived]').forEach((e) => e.removeAttribute('data-dsh-nav-archived'))\n document.querySelectorAll('[data-dsh-nav-move]').forEach((e) => e.removeAttribute('data-dsh-nav-move'))\n }\n}\n\nfunction installSettingsNavIcons(ctx) {\n const styleEl = document.createElement('style')\n styleEl.textContent = NAV_CSS\n document.head.appendChild(styleEl)\n const dispose = markSettingsNav()\n ctx.effect(() => () => {\n dispose()\n if (styleEl.parentNode) styleEl.parentNode.removeChild(styleEl)\n })\n}\n\nexport function apply(ctx) {\n installSettingsNavIcons(ctx)\n ctx.slots.inject('settings.section', () =>\n ctx.slots.register(\n { name: 'settings.section', id: 'archived-sessions', order: 90, label: '\u5F52\u6863\u4F1A\u8BDD' },\n (props) => <ArchivedPanel {...props} />,\n ),\n )\n ctx.slots.inject('settings.section', () =>\n ctx.slots.register(\n { name: 'settings.section', id: 'move-sessions', order: 91, label: '\u79FB\u52A8\u4F1A\u8BDD' },\n (props) => <MovePanel {...props} />,\n ),\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|