dsh-session-manager 0.6.4 → 0.7.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/CHANGELOG.md +35 -0
- package/README.md +16 -4
- package/README.zh.md +19 -7
- package/lib/client.js +2215 -221
- package/lib/index.js +746 -194
- package/lib/workspace-archive-store.js +235 -0
- package/package.json +5 -3
package/lib/client.js
CHANGED
|
@@ -174,8 +174,8 @@ function isTopmostDialog(z) {
|
|
|
174
174
|
"menu.delete": "删除会话…",
|
|
175
175
|
"menu.move": "移动到工作区…",
|
|
176
176
|
"menu.manage": "打开会话管理…",
|
|
177
|
-
"footer.aria": "
|
|
178
|
-
"footer.label": "
|
|
177
|
+
"footer.aria": "会话与工作区",
|
|
178
|
+
"footer.label": "会话与工作区",
|
|
179
179
|
"panel.title": "会话管理",
|
|
180
180
|
"panel.github.title": "欢迎Star和提交Issue",
|
|
181
181
|
"panel.update.title": "检查更新",
|
|
@@ -200,14 +200,14 @@ function isTopmostDialog(z) {
|
|
|
200
200
|
"update.autoCheck": "自动检查更新",
|
|
201
201
|
"update.autoCheck.enable": "开启",
|
|
202
202
|
"settings.registry": "安装源",
|
|
203
|
-
"settings.registry.npm": "npm 官方源
|
|
204
|
-
"settings.registry.china": "
|
|
203
|
+
"settings.registry.npm": "npm 官方源 (npmjs.org)",
|
|
204
|
+
"settings.registry.china": "国内镜像源 (npmmirror.com)",
|
|
205
205
|
"settings.title": "会话管理",
|
|
206
206
|
"settings.pluginName": "dsh-session-manager",
|
|
207
207
|
"settings.versionSection": "插件版本",
|
|
208
208
|
"settings.prefSection": "偏好设置",
|
|
209
209
|
"settings.dialogOpacity": "弹窗透明度",
|
|
210
|
-
"settings.dialogOpacity.hint": "
|
|
210
|
+
"settings.dialogOpacity.hint": "仅调整插件弹窗的背景透明度",
|
|
211
211
|
"settings.dialogOpacity.value": "{value}%",
|
|
212
212
|
"settings.dialogOpacity.reset": "恢复默认",
|
|
213
213
|
"settings.projectSection": "项目",
|
|
@@ -229,6 +229,8 @@ function isTopmostDialog(z) {
|
|
|
229
229
|
"panel.sort.updated-asc": "最早更新",
|
|
230
230
|
"panel.sort.created-desc": "最新创建",
|
|
231
231
|
"panel.sort.created-asc": "最早创建",
|
|
232
|
+
"panel.sort.name-asc": "名称升序",
|
|
233
|
+
"panel.sort.name-desc": "名称降序",
|
|
232
234
|
"panel.count": "显示 {shown} / {total} 个会话",
|
|
233
235
|
"panel.reset": "重置筛选",
|
|
234
236
|
"panel.empty.filtered": "没有匹配的会话,请调整搜索或筛选条件",
|
|
@@ -238,6 +240,9 @@ function isTopmostDialog(z) {
|
|
|
238
240
|
"panel.empty": "暂无会话",
|
|
239
241
|
"panel.empty.archived": "归档为空",
|
|
240
242
|
"panel.archived": "已归档",
|
|
243
|
+
"panel.workspaceArchived": "工作区已归档",
|
|
244
|
+
"notice.workspaceReAdded": "工作区已恢复显示,但旧会话继续归档",
|
|
245
|
+
"error.workspaceArchived": "所属工作区已归档,无法取消归档该会话。请先在工作区管理中恢复工作区。",
|
|
241
246
|
"panel.running": "运行中",
|
|
242
247
|
"panel.current": "当前",
|
|
243
248
|
"panel.session.new": "新建会话",
|
|
@@ -259,6 +264,9 @@ function isTopmostDialog(z) {
|
|
|
259
264
|
"confirm.delete.title": "删除会话",
|
|
260
265
|
"confirm.delete.desc": "「{title}」:删除,不可恢复",
|
|
261
266
|
"confirm.delete.running": "该会话正在运行,删除将立即中断它。",
|
|
267
|
+
"confirm.delete.subagents": "将连带删除 {count} 个关联的子智能体会话。",
|
|
268
|
+
"confirm.delete.previewLoading": "正在检查关联的子智能体会话…",
|
|
269
|
+
"confirm.delete.previewError": "检查关联子智能体会话失败,无法确认删除安全,请稍后重试。",
|
|
262
270
|
"confirm.delete.confirm": "确认删除",
|
|
263
271
|
"confirm.move.title": "移动会话到工作区",
|
|
264
272
|
"confirm.move.desc": "「{title}」:移动至目标工作区",
|
|
@@ -273,9 +281,34 @@ function isTopmostDialog(z) {
|
|
|
273
281
|
"error.operation": "操作失败:{message}",
|
|
274
282
|
"workspace.default": "默认工作区",
|
|
275
283
|
"workspace.sessions": "{count} 个会话",
|
|
284
|
+
"panel.tab.sessions": "会话管理",
|
|
285
|
+
"panel.tab.workspaces": "工作区管理",
|
|
286
|
+
"workspace.search": "搜索工作区名称或路径",
|
|
287
|
+
"workspace.filter.all": "全部",
|
|
288
|
+
"workspace.filter.active": "未归档",
|
|
289
|
+
"workspace.filter.archived": "已归档",
|
|
290
|
+
"workspace.sort.updated-desc": "最近更新",
|
|
291
|
+
"workspace.sort.updated-asc": "最早更新",
|
|
292
|
+
"workspace.sort.name-asc": "名称升序",
|
|
293
|
+
"workspace.sort.name-desc": "名称降序",
|
|
294
|
+
"workspace.bulk.archive": "归档",
|
|
295
|
+
"workspace.bulk.unarchive": "取消归档",
|
|
296
|
+
"workspace.count": "显示 {shown} / {total} 个工作区",
|
|
297
|
+
"workspace.reset": "重置筛选",
|
|
298
|
+
"workspace.empty.filtered": "没有匹配的工作区,请调整搜索或筛选条件",
|
|
299
|
+
"workspace.empty": "暂无工作区",
|
|
300
|
+
"workspace.badge.archived": "已归档",
|
|
301
|
+
"workspace.lastUpdated": "最近更新:{time}",
|
|
302
|
+
"workspace.switch.active": "已在原生侧边栏显示(点击归档隐藏)",
|
|
303
|
+
"workspace.switch.archived": "已在原生侧边栏隐藏(点击恢复显示)",
|
|
304
|
+
"workspace.switch.aria": "工作区显示开关:{name}",
|
|
305
|
+
"workspace.archive.confirm.title": "归档工作区",
|
|
306
|
+
"workspace.archive.confirm.desc": "确认归档工作区「{name}」?此操作将同时归档该工作区下的 {count} 个未归档会话并在原生侧边栏隐藏该工作区。",
|
|
307
|
+
"workspace.archive.failed": "归档工作区失败:{message}",
|
|
308
|
+
"workspace.unarchive.failed": "恢复工作区失败:{message}",
|
|
276
309
|
"bulk.title": "批量管理",
|
|
277
310
|
"bulk.selectedFiltered": "已选 {selected} / {filtered} 项",
|
|
278
|
-
"bulk.selectAllFiltered": "
|
|
311
|
+
"bulk.selectAllFiltered": "全选筛选",
|
|
279
312
|
"bulk.clear": "清空选择",
|
|
280
313
|
"bulk.archive": "归档",
|
|
281
314
|
"bulk.unarchive": "取消归档",
|
|
@@ -412,8 +445,8 @@ function isTopmostDialog(z) {
|
|
|
412
445
|
"menu.delete": "Delete session…",
|
|
413
446
|
"menu.move": "Move to workspace…",
|
|
414
447
|
"menu.manage": "Open session manager…",
|
|
415
|
-
"footer.aria": "
|
|
416
|
-
"footer.label": "Sessions",
|
|
448
|
+
"footer.aria": "Sessions & Workspaces",
|
|
449
|
+
"footer.label": "Sessions & Workspaces",
|
|
417
450
|
"panel.title": "Session manager",
|
|
418
451
|
"panel.github.title": "Star the project or open an issue",
|
|
419
452
|
"panel.update.title": "Check for updates",
|
|
@@ -438,14 +471,14 @@ function isTopmostDialog(z) {
|
|
|
438
471
|
"update.autoCheck": "Automatically check for updates",
|
|
439
472
|
"update.autoCheck.enable": "Enable",
|
|
440
473
|
"settings.registry": "Install Source",
|
|
441
|
-
"settings.registry.npm": "npm
|
|
442
|
-
"settings.registry.china": "China
|
|
474
|
+
"settings.registry.npm": "Official npm (npmjs.org)",
|
|
475
|
+
"settings.registry.china": "China mirror (npmmirror.com)",
|
|
443
476
|
"settings.title": "Session Manager",
|
|
444
477
|
"settings.pluginName": "dsh-session-manager",
|
|
445
478
|
"settings.versionSection": "Plugin Version",
|
|
446
479
|
"settings.prefSection": "Preferences",
|
|
447
480
|
"settings.dialogOpacity": "Dialog opacity",
|
|
448
|
-
"settings.dialogOpacity.hint": "Adjusts
|
|
481
|
+
"settings.dialogOpacity.hint": "Adjusts dialog background opacity only",
|
|
449
482
|
"settings.dialogOpacity.value": "{value}%",
|
|
450
483
|
"settings.dialogOpacity.reset": "Reset to default",
|
|
451
484
|
"settings.projectSection": "Project",
|
|
@@ -467,6 +500,8 @@ function isTopmostDialog(z) {
|
|
|
467
500
|
"panel.sort.updated-asc": "Least recently updated",
|
|
468
501
|
"panel.sort.created-desc": "Newest created",
|
|
469
502
|
"panel.sort.created-asc": "Oldest created",
|
|
503
|
+
"panel.sort.name-asc": "Name (A-Z)",
|
|
504
|
+
"panel.sort.name-desc": "Name (Z-A)",
|
|
470
505
|
"panel.count": "Showing {shown} / {total} sessions",
|
|
471
506
|
"panel.reset": "Reset filters",
|
|
472
507
|
"panel.empty.filtered": "No matching sessions. Adjust your search or filters.",
|
|
@@ -543,6 +578,9 @@ function isTopmostDialog(z) {
|
|
|
543
578
|
"panel.empty": "No sessions",
|
|
544
579
|
"panel.empty.archived": "No archived sessions",
|
|
545
580
|
"panel.archived": "Archived",
|
|
581
|
+
"panel.workspaceArchived": "Workspace Archived",
|
|
582
|
+
"notice.workspaceReAdded": "Workspace restored to view, but previous sessions remain archived.",
|
|
583
|
+
"error.workspaceArchived": "The workspace for this session is archived. Please restore the workspace in Workspace Management first.",
|
|
546
584
|
"panel.running": "Running",
|
|
547
585
|
"panel.current": "Current",
|
|
548
586
|
"panel.session.new": "New session",
|
|
@@ -564,6 +602,9 @@ function isTopmostDialog(z) {
|
|
|
564
602
|
"confirm.delete.title": "Delete session",
|
|
565
603
|
"confirm.delete.desc": "\"{title}\": Delete, cannot be undone",
|
|
566
604
|
"confirm.delete.running": "This session is running; deleting will interrupt it immediately.",
|
|
605
|
+
"confirm.delete.subagents": "Will also delete {count} associated subagent session(s).",
|
|
606
|
+
"confirm.delete.previewLoading": "Checking for associated subagent sessions...",
|
|
607
|
+
"confirm.delete.previewError": "Failed to check associated subagents. Cannot verify deletion safety. Please try again later.",
|
|
567
608
|
"confirm.delete.confirm": "Delete",
|
|
568
609
|
"confirm.move.title": "Move session to workspace",
|
|
569
610
|
"confirm.move.desc": "\"{title}\": Move to target workspace",
|
|
@@ -577,7 +618,52 @@ function isTopmostDialog(z) {
|
|
|
577
618
|
"busy.processing": "Working…",
|
|
578
619
|
"error.operation": "Operation failed: {message}",
|
|
579
620
|
"workspace.default": "Default workspace",
|
|
580
|
-
"workspace.sessions": "{count} sessions"
|
|
621
|
+
"workspace.sessions": "{count} sessions",
|
|
622
|
+
"panel.tab.sessions": "Sessions",
|
|
623
|
+
"panel.tab.workspaces": "Workspaces",
|
|
624
|
+
"workspace.search": "Search by name or path",
|
|
625
|
+
"workspace.filter.all": "All",
|
|
626
|
+
"workspace.filter.active": "Active",
|
|
627
|
+
"workspace.filter.archived": "Archived",
|
|
628
|
+
"workspace.sort.updated-desc": "Recently updated",
|
|
629
|
+
"workspace.sort.updated-asc": "Earliest updated",
|
|
630
|
+
"workspace.sort.name-asc": "Name (A-Z)",
|
|
631
|
+
"workspace.sort.name-desc": "Name (Z-A)",
|
|
632
|
+
"workspace.bulk.archive": "Archive",
|
|
633
|
+
"workspace.bulk.unarchive": "Unarchive",
|
|
634
|
+
"workspace.count": "Showing {shown} / {total} workspaces",
|
|
635
|
+
"workspace.reset": "Reset filters",
|
|
636
|
+
"workspace.empty.filtered": "No matching workspaces",
|
|
637
|
+
"workspace.empty": "No workspaces",
|
|
638
|
+
"workspace.badge.archived": "Archived",
|
|
639
|
+
"workspace.lastUpdated": "Updated: {time}",
|
|
640
|
+
"workspace.switch.active": "Shown in sidebar (click to archive)",
|
|
641
|
+
"workspace.switch.archived": "Hidden from sidebar (click to restore)",
|
|
642
|
+
"workspace.switch.aria": "Workspace visibility toggle: {name}",
|
|
643
|
+
"workspace.archive.confirm.title": "Archive Workspace",
|
|
644
|
+
"workspace.archive.confirm.desc": "Archive workspace \"{name}\"? This will also archive {count} active sessions in this workspace and hide it from the sidebar.",
|
|
645
|
+
"workspace.archive.failed": "Failed to archive workspace: {message}",
|
|
646
|
+
"workspace.unarchive.failed": "Failed to restore workspace: {message}"
|
|
647
|
+
};
|
|
648
|
+
|
|
649
|
+
const smTranslate = (k, vars) => {
|
|
650
|
+
const lang = (typeof window !== "undefined" && window.__smActiveLanguage) || "zh";
|
|
651
|
+
const dict = lang === "en" ? (en[k] || zh[k] || k) : (zh[k] || en[k] || k);
|
|
652
|
+
if (!vars || typeof dict !== "string") return dict;
|
|
653
|
+
return dict.replace(/\{(\w+)\}/g, (_, key) => vars[key] !== undefined ? vars[key] : "{" + key + "}");
|
|
654
|
+
};
|
|
655
|
+
|
|
656
|
+
const showNotice = (msg) => {
|
|
657
|
+
if (!msg) return;
|
|
658
|
+
try {
|
|
659
|
+
if (activeClientCtx?.notifications?.info && typeof activeClientCtx.notifications.info === "function") {
|
|
660
|
+
activeClientCtx.notifications.info(msg);
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
} catch (_) {}
|
|
664
|
+
if (typeof window !== "undefined" && typeof window.alert === "function") {
|
|
665
|
+
window.alert(msg);
|
|
666
|
+
}
|
|
581
667
|
};
|
|
582
668
|
|
|
583
669
|
const css = [
|
|
@@ -593,10 +679,15 @@ function isTopmostDialog(z) {
|
|
|
593
679
|
".sm-footerBtn svg{flex:none}",
|
|
594
680
|
".sm-panel{display:flex;flex-direction:column;gap:10px;min-height:280px;max-height:min(70vh,640px);min-width:480px}",
|
|
595
681
|
".sm-filter{display:flex;gap:4px;flex-wrap:wrap}",
|
|
596
|
-
".sm-filterBtn{cursor:pointer;display:inline-flex;align-items:center;color:var(--dsw-alias-label-secondary);background:0 0;border:1px solid var(--dsw-alias-border-l2);border-radius:999px;height:28px;padding:3px 10px;font-size:12px;line-height:18px;white-space:nowrap;box-sizing:border-box}",
|
|
597
|
-
".sm-filterBtn:hover{background:var(--dsw-alias-interactive-bg-hover)}",
|
|
682
|
+
".sm-filterBtn{cursor:pointer;display:inline-flex;align-items:center;color:var(--dsw-alias-label-secondary);background:0 0;border:1px solid var(--dsw-alias-border-l2);border-radius:999px;height:28px;padding:3px 10px;font-size:12px;line-height:18px;white-space:nowrap;box-sizing:border-box;transition:all .15s ease}",
|
|
683
|
+
".sm-filterBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}",
|
|
684
|
+
".sm-filterBtn:disabled{opacity:.4;cursor:not-allowed}",
|
|
598
685
|
".sm-filterBtn.sm-on{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-module-platform);border-color:transparent}",
|
|
599
|
-
".sm-list{display:flex;flex-direction:column;gap:4px;min-height:0;overflow:auto;flex:1}",
|
|
686
|
+
".sm-list{display:flex;flex-direction:column;gap:4px;min-height:0;overflow:auto;flex:1;scrollbar-gutter:stable}",
|
|
687
|
+
".sm-list::-webkit-scrollbar{width:6px;height:6px}",
|
|
688
|
+
".sm-list::-webkit-scrollbar-track{background:transparent}",
|
|
689
|
+
".sm-list::-webkit-scrollbar-thumb{background:var(--dsw-alias-scrollbar-bg-l1,rgba(128,128,128,.2));border-radius:999px}",
|
|
690
|
+
".sm-list::-webkit-scrollbar-thumb:hover{background:var(--dsw-alias-scrollbar-hover-l1,rgba(128,128,128,.35))}",
|
|
600
691
|
".sm-row{box-sizing:border-box;display:flex;align-items:center;gap:10px;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px}",
|
|
601
692
|
".sm-row:hover{background:var(--dsw-alias-interactive-bg-hover)}",
|
|
602
693
|
".sm-rowCurrent{border-color:var(--dsw-alias-state-business-primary,var(--dsw-alias-label-secondary))}",
|
|
@@ -607,6 +698,7 @@ function isTopmostDialog(z) {
|
|
|
607
698
|
".sm-rowActions{display:flex;gap:4px;flex:none;flex-wrap:wrap;justify-content:flex-end}",
|
|
608
699
|
".sm-badge{flex:none;border-radius:999px;padding:0 6px;font-size:10px;line-height:16px}",
|
|
609
700
|
".sm-badgeArchived{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-markdown-tag)}",
|
|
701
|
+
".sm-badgeWorkspaceArchived{color:var(--dsw-alias-state-warn-label,#dd8629);background:var(--dsw-alias-state-warn-tertiary,#fef5e7)}",
|
|
610
702
|
".sm-badgeRunning{color:var(--dsw-alias-state-warn-label,#dd8629);background:var(--dsw-alias-state-warn-tertiary,#fef5e7)}",
|
|
611
703
|
".sm-badgeCurrent{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-markdown-tag)}",
|
|
612
704
|
// The former .sm-danger / .sm-dangerText rules were removed: no element
|
|
@@ -628,7 +720,7 @@ function isTopmostDialog(z) {
|
|
|
628
720
|
".sm-moveItemSelected{border-color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-state-business-tertiary)}",
|
|
629
721
|
".sm-moveItemName{color:var(--dsw-alias-label-primary);font-size:13px;line-height:18px}",
|
|
630
722
|
".sm-moveItemMeta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.sm-panelModal{width:760px;max-width:92vw}.sm-panelModal .sm-rowActions{flex-wrap:wrap;justify-content:flex-end}.sm-headerMenu{position:absolute;right:0;top:100%;margin-top:4px;z-index:100005;display:flex;flex-direction:column;min-width:140px;padding:4px;background:var(--dsw-alias-bg-layer-2,#fff);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;box-shadow:0 4px 16px rgba(0,0,0,.15)}.sm-headerMenuItem{display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:0 0;border:0;border-radius:6px;color:var(--dsw-alias-label-primary,#111);cursor:pointer;padding:6px 10px;font-size:13px;line-height:18px;white-space:nowrap}.sm-headerMenuItem:hover{background:var(--dsw-alias-interactive-bg-hover)}.sm-headerMenuItem:disabled{opacity:.5;cursor:not-allowed}.sm-headerMenuItem .sm-headerBtnIcon{width:20px;min-width:20px;text-align:center;flex-shrink:0}.sm-headerMenuItemDanger{color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-headerMenuItemDanger:hover{background:var(--dsw-alias-interactive-bg-hover-danger)}.sm-headerMenuUltraOnly{display:none!important}.sm-headerBtn{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:32px;height:32px;box-sizing:border-box;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-button-floating-fill,#fff);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;cursor:pointer;padding:0 10px;font-size:13px;line-height:1;white-space:nowrap;transition:background .15s,color .15s,border-color .15s;flex-shrink:0}.sm-headerBtn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l1)}.sm-headerBtn:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}.sm-headerBtn svg{width:16px;height:16px;display:block;margin:auto;flex-shrink:0}.sm-migratePanel{display:flex;flex-direction:column;gap:14px;min-width:480px}.sm-migrateRow{display:flex;flex-direction:column;gap:8px}.sm-migrateRow>label{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:16px;font-weight:500}.sm-migrateChips{display:flex;flex-wrap:wrap;gap:6px}.sm-migrateChip{padding:6px 12px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);background:transparent;cursor:pointer;font-size:13px;line-height:18px;color:var(--dsw-alias-label-primary);white-space:nowrap}.sm-migrateChip:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-migrateChip:disabled{opacity:.5;cursor:not-allowed}.sm-migrateChipOn{background:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary)}.sm-migrateEmpty{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.sm-migratePreview{padding:10px 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font-size:13px;line-height:18px}.sm-migrateWarn{padding:10px 12px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary,#f59e0b) 30%,transparent);border-radius:8px;background:var(--dsw-alias-state-warn-tertiary,#fef5e7);color:var(--dsw-alias-label-secondary);font-size:13px;line-height:18px}.sm-migrateList{max-height:200px;overflow:auto;border:1px solid var(--dsw-alias-border-l2);border-radius:8px}.sm-headerBtnDanger{background:var(--dsw-alias-button-floating-fill,#fff);color:var(--dsw-alias-state-error-primary,#d92d20);border-color:var(--dsw-alias-state-error-primary,#d92d20);font-weight:500}.sm-headerBtnDanger:hover:not(:disabled){background:var(--dsw-alias-state-error-primary,#d92d20);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-header{display:inline-flex;align-items:center;gap:6px;flex-wrap:nowrap}.sm-headerSecondaryActions{display:inline-flex;align-items:center;gap:6px;flex-wrap:nowrap}.sm-headerCompactMenu{display:none;position:relative}.sm-headerCompactMenu.sm-headerCompactMenuOpen{position:relative;z-index:100004}.sm-headerCompactMenuBtn{width:32px;min-width:32px;height:32px;padding:0;justify-content:center;font-size:16px;line-height:1}.sm-headerBtnIcon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:14px;line-height:1;vertical-align:middle;flex-shrink:0}.sm-headerBtn.sm-markIcon{width:32px;min-width:32px;height:32px;padding:0;justify-content:center}.sm-headerBtn.sm-markIcon .sm-headerBtnIcon{width:16px;height:16px;font-size:15px;line-height:1}.sm-headerCompactMenuBtn .sm-headerBtnIcon{width:16px;height:16px;font-size:16px;line-height:1}.sm-annotationToggleOpen{position:relative;z-index:100004}.sm-headerBtnActive{background:var(--dsw-alias-button-ghost-active-fill);color:var(--dsw-alias-label-primary)}@container (max-width:1000px){.sm-headerBtn{width:32px;min-width:32px;height:32px;padding:0;justify-content:center}.sm-headerBtnLabel,.sm-priorityText,.sm-priorityBadge{display:none}.sm-headerBtn.sm-headerBtn-withBadge{width:auto;min-width:32px;padding:0 6px}}@container (max-width:520px){.sm-headerSecondaryActions,.sm-headerSecondaryAction{display:none!important}.sm-headerCompactMenu{display:inline-flex}}@container (max-width:420px){.sm-header>:not(.sm-headerCompactMenu){display:none!important}.sm-header .sm-headerBtn:not(.sm-headerCompactMenuBtn){display:none!important}.sm-headerCompactMenu{display:inline-flex!important}.sm-headerMenu{right:auto!important;left:0!important}.sm-headerMenuUltraOnly{display:flex!important}}",
|
|
631
|
-
".sm-panelDialog{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);width:600px;max-width:calc(100vw - 32px);max-height:560px;height:auto;box-sizing:border-box;display:flex;flex-direction:column;gap:0;background:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);overflow:hidden;z-index:1020}.sm-panelDialog .sm-nativeDialogHeader{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;position:relative;min-height:46px;box-sizing:border-box}.sm-panelDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;min-width:0;max-width:calc(100% - 140px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center;pointer-events:auto;z-index:0}.sm-panelDialog .sm-nativeDialogHeaderActions{display:flex;align-items:center;gap:6px;flex:none;position:relative;z-index:1;margin-left:auto}.sm-nativeDialogFooter,.sm-bulkDialog .sm-nativeDialogFooter,.sm-confirmDialog .sm-nativeDialogFooter,.sm-migrateDialog .sm-nativeDialogFooter{display:flex;padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex:none;flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-panelDialog .sm-panel{display:flex;flex-direction:column;gap:6px;min-height:0;flex:1 1 auto;overflow:auto;padding:8px 12px}.sm-panelDialog .sm-list{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-height:0;overflow:auto}.sm-panelDialog .sm-row{display:flex;align-items:center;gap:8px;padding:6px 10px;min-height:36px;border:1px solid transparent;border-radius:8px;background:transparent;flex-shrink:0}.sm-panelDialog .sm-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.sm-panelDialog .sm-rowCurrent{background:var(--dsw-alias-bg-module-platform);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-panelDialog .sm-rowMain{display:flex;align-items:stretch!important;gap:8px;min-width:0;flex:1 1 auto;overflow:visible;text-align:left!important}.sm-panelDialog .sm-rowTitle{min-width:0;flex:1 1 0%;width:100%;align-self:stretch;display:flex;align-items:center;justify-content:flex-start;gap:6px;font-size:12px;line-height:16px;overflow:hidden;text-align:left!important;direction:ltr!important;unicode-bidi:plaintext}.sm-confirmDialog{z-index:10000}.sm-confirmDialog.sm-nativeDialogLayer{position:fixed;left:calc(50vw + 184px);top:calc(50vh - 90px);width:360px;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);display:block;align-items:initial;justify-content:initial;box-sizing:border-box;background:transparent;border:0;box-shadow:none;padding:0;inset:calc(50vh - 90px) auto auto calc(50vw + 308px)}.sm-confirmDialog.sm-nativeDialogLayer .sm-nativeDialogBackdrop{display:none}.sm-confirmDialog.sm-nativeDialogLayer .sm-nativeDialog{position:relative;left:auto;top:auto;transform:none;width:auto;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);display:flex;flex-direction:column;box-sizing:border-box;background:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);padding:0;overflow:hidden;animation:sm-confirmPop .14s ease-out}.sm-confirmDialog .sm-nativeDialogHeader{position:relative;padding:12px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);display:flex;align-items:center;justify-content:center;min-height:44px;box-sizing:border-box}.sm-confirmDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;text-align:center;width:auto;max-width:calc(100% - 32px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm-confirmDialog .sm-nativeDialogBody{padding:10px 16px;display:flex;flex-direction:column;gap:8px;min-height:0;max-height:calc(100vh - 120px);overflow-y:auto}.sm-confirmDialog .sm-nativeDialogDescription{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary);white-space:pre-wrap}.sm-confirmDialog .sm-warn{display:flex;align-items:flex-start;gap:8px;color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px;background:color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 8%,transparent);border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 25%,transparent);border-radius:8px;padding:8px 10px;margin-top:0}.sm-confirmDialog .sm-nativeDialogFooter{padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-confirmDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;cursor:pointer;background:transparent;color:var(--dsw-alias-label-primary);text-align:center}.sm-confirmDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-migrateDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-updateDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-bulkDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-panelDialog .sm-nativeDialogCancel:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-confirmDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-confirmDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}@keyframes sm-confirmPop{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.sm-confirmDialog.sm-nativeDialog{padding:0;width:auto;max-width:none}.sm-panelDialog .sm-rowTitle>span:first-child{display:block;min-width:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;flex:1 1 auto;width:auto;text-align:left!important;direction:ltr!important;unicode-bidi:plaintext}.sm-panelDialog .sm-rowMeta{display:none}.sm-panelDialog .sm-rowActions{display:flex;gap:2px;flex:none;justify-content:flex-end}.sm-panelDialog .sm-rowActions .sm-rowBtn{min-height:22px;padding:0 7px;font-size:11px;line-height:18px;border-radius:6px;border:1px solid transparent;background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer;white-space:nowrap}.sm-rowBtn.sm-markIcon{padding:0 6px;font-size:13px;line-height:18px}.sm-panelDialog .sm-rowActions .sm-rowBtn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.sm-panelDialog .sm-rowActions .sm-rowBtnDanger{color:var(--dsw-alias-state-error-primary)}.sm-panelDialog .sm-rowActions .sm-rowBtnDanger:hover{background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary)}.sm-panelDialog .sm-filter{flex:none;padding:6px 12px 4px;gap:4px;display:flex;flex-wrap:wrap}.sm-panelDialog .sm-filterBtn{min-height:24px;padding:2px 10px;font-size:11px;line-height:16px;border-radius:4px;border:1px solid var(--dsw-alias-border-l2);background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer}.sm-panelDialog .sm-filterBtn.sm-on{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-primary)}.sm-panelDialog .sm-badge{font-size:10px;line-height:14px;padding:0 5px;border-radius:6px;flex:none}.sm-panelDialog .sm-error{padding:6px 10px;margin:0;font-size:12px;line-height:16px}.sm-panelDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:transparent;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:center}.sm-panelDialog .sm-nativeDialogCancel{background:transparent}.sm-panelDialog .sm-nativeDialogConfirm,.sm-annotationDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-panelDialog .sm-nativeDialogConfirm:hover:not(:disabled),.sm-annotationDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}.sm-nativeDialogDanger{background:var(--dsw-alias-state-error-primary,#d92d20);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-nativeDialogDanger:hover:not(:disabled){filter:brightness(.92)}.sm-confirmDialog .sm-nativeDialogDanger,.sm-migrateDialog .sm-nativeDialogDanger,.sm-bulkDialog .sm-nativeDialogDanger{background:var(--dsw-alias-state-error-primary,#d92d20);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-confirmDialog .sm-nativeDialogDanger:hover:not(:disabled),.sm-migrateDialog .sm-nativeDialogDanger:hover:not(:disabled),.sm-bulkDialog .sm-nativeDialogDanger:hover:not(:disabled){filter:brightness(.92)}.sm-panelDialog .sm-empty{padding:18px 0;font-size:12px;color:var(--dsw-alias-label-tertiary);text-align:center}.sm-panelDialog .sm-footError{font-size:11px;color:var(--dsw-alias-state-error-primary);margin-right:auto;line-height:20px}.sm-panelDialog .sm-moveLabel{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary)}.sm-migrateDialog .sm-nativeDialogFooter{flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-migrateDialog .sm-migrateChip{cursor:pointer;pointer-events:auto;position:relative;z-index:1}.sm-migrateDialog .sm-migrateChip[disabled]{opacity:.5;cursor:not-allowed}.sm-migrateDialog.sm-nativeDialogLayer{position:fixed;left:50vw;top:auto;bottom:48px;transform:translateX(-50%);width:min(560px,calc(100vw - 32px));max-height:none;display:block;align-items:initial;justify-content:initial;box-sizing:border-box;background:transparent;border:0;box-shadow:none;padding:0;inset:auto;z-index:10001}.sm-migrateDialog.sm-nativeDialogLayer .sm-nativeDialogBackdrop{display:none}.sm-migrateDialog.sm-nativeDialogLayer .sm-nativeDialog{position:relative;left:auto;top:auto;transform:none;width:360px;max-width:calc(100vw - 32px);max-height:min(70vh,520px);box-sizing:border-box;background-color:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.45);overflow:hidden;padding:0;display:flex;flex-direction:column;gap:0}.sm-migrateDialog{position:fixed;left:50vw;top:auto;bottom:48px;transform:translateX(-50%);width:min(560px,calc(100vw - 32px));max-height:min(70vh,520px);box-sizing:border-box;display:flex;flex-direction:column;gap:0;background-color:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.45);overflow:hidden;z-index:10001}.sm-migrateDialog .sm-nativeDialogHeader{padding:12px 18px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;position:relative;display:flex;align-items:center;justify-content:center;min-height:44px;box-sizing:border-box}.sm-migrateDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;color:var(--dsw-alias-label-primary,#111);text-align:center;width:auto;max-width:calc(100% - 36px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm-migrateDialog .sm-migratePanel{padding:12px 18px;display:flex;flex-direction:column;gap:14px}.sm-migrateDialog .sm-nativeDialogBody{padding:0}.sm-migrateDialog .sm-nativeDialogFooter{padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex:none;flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0;gap:8px}.sm-migrateDialog .sm-migrateRow>label{color:var(--dsw-alias-label-secondary,#444)}.sm-migrateDialog .sm-migrateChip{padding:6px 12px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2,#ddd);background-color:var(--dsw-alias-markdown-tag,#f1f3f5);color:var(--dsw-alias-label-primary,#111);font-size:13px;line-height:18px;cursor:pointer;pointer-events:auto;position:relative;z-index:1;white-space:nowrap}.sm-migrateDialog .sm-migrateChip:hover:not(:disabled){background-color:var(--dsw-alias-interactive-bg-hover,#e8e8e8)}.sm-migrateDialog .sm-migrateChipOn{background-color:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-migrateDialog .sm-migrateChip.sm-migrateChipOn:hover:not(:disabled){background-color:var(--dsw-alias-button-info-hover,#4576f0);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-button-info-hover,#4576f0);filter:none}.sm-migrateDialog .sm-migrateChipOn:hover:not(:disabled){filter:brightness(.92)}.sm-migrateDialog .sm-migrateChip[disabled]{opacity:.5;cursor:not-allowed}.sm-migrateDialog .sm-migrateEmpty{color:var(--dsw-alias-label-tertiary,#888)}.sm-migrateDialog .sm-migratePreview{padding:10px 12px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;background-color:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#111);font-size:13px;line-height:18px}.sm-migrateDialog .sm-migrateWarn{padding:10px 12px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary,#f59e0b) 30%,transparent);border-radius:8px;background-color:var(--dsw-alias-state-warn-tertiary,#fef5e7);color:var(--dsw-alias-label-secondary,#444);font-size:13px;line-height:18px}.sm-migrateDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;cursor:pointer;background-color:transparent;color:var(--dsw-alias-label-primary,#111);text-align:center}.sm-migrateDialog .sm-nativeDialogButton:hover:not(:disabled){background-color:var(--dsw-alias-interactive-bg-hover,#e8e8e8)}.sm-migrateDialog .sm-nativeDialogConfirm{background-color:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-migrateDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}",
|
|
723
|
+
".sm-panelDialog{position:fixed;inset:0;margin:auto;transform:none;width:680px;max-width:calc(100vw - 32px);height:560px;max-height:calc(100vh - 32px);box-sizing:border-box;display:flex;flex-direction:column;gap:0;background:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);overflow:hidden;z-index:1020}.sm-panelDialog .sm-nativeDialogHeader{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;position:relative;min-height:46px;box-sizing:border-box}.sm-panelDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;min-width:0;max-width:calc(100% - 140px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center;pointer-events:auto;z-index:0}.sm-panelDialog .sm-nativeDialogHeaderActions{display:flex;align-items:center;gap:6px;flex:none;position:relative;z-index:1;margin-left:auto}.sm-nativeDialogFooter,.sm-bulkDialog .sm-nativeDialogFooter,.sm-confirmDialog .sm-nativeDialogFooter,.sm-migrateDialog .sm-nativeDialogFooter{display:flex;padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex:none;flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-panelDialog .sm-panel{display:flex;flex-direction:column;gap:6px;min-height:0;flex:1 1 auto;overflow:auto;padding:8px 12px}.sm-panelDialog .sm-list{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-height:0;overflow:auto;scrollbar-gutter:stable}.sm-panelDialog .sm-row{display:flex;align-items:center;gap:8px;padding:6px 10px;min-height:36px;border:1px solid transparent;border-radius:8px;background:transparent;flex-shrink:0;transition:background .12s ease,border-color .12s ease}.sm-panelDialog .sm-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.sm-panelDialog .sm-rowCurrent{background:var(--dsw-alias-bg-module-platform);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-panelDialog .sm-rowMain{display:flex;align-items:stretch!important;gap:8px;min-width:0;flex:1 1 auto;overflow:visible;text-align:left!important}.sm-panelDialog .sm-rowTitle{min-width:0;flex:1 1 0%;width:100%;align-self:stretch;display:flex;align-items:center;justify-content:flex-start;gap:6px;font-size:12px;line-height:16px;overflow:hidden;text-align:left!important;direction:ltr!important;unicode-bidi:plaintext}.sm-confirmDialog{z-index:10000}.sm-confirmDialog.sm-nativeDialogLayer{position:fixed;left:calc(50vw + 184px);top:calc(50vh - 90px);width:360px;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);display:block;align-items:initial;justify-content:initial;box-sizing:border-box;background:transparent;border:0;box-shadow:none;padding:0;inset:calc(50vh - 90px) auto auto calc(50vw + 308px)}.sm-confirmDialog.sm-nativeDialogLayer .sm-nativeDialogBackdrop{display:none}.sm-confirmDialog.sm-nativeDialogLayer .sm-nativeDialog{position:relative;left:auto;top:auto;transform:none;width:auto;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);display:flex;flex-direction:column;box-sizing:border-box;background:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);padding:0;overflow:hidden;animation:sm-confirmPop .14s ease-out}.sm-confirmDialog .sm-nativeDialogHeader{position:relative;padding:12px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);display:flex;align-items:center;justify-content:center;min-height:44px;box-sizing:border-box}.sm-confirmDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;text-align:center;width:auto;max-width:calc(100% - 32px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm-confirmDialog .sm-nativeDialogBody{padding:10px 16px;display:flex;flex-direction:column;gap:8px;min-height:0;max-height:calc(100vh - 120px);overflow-y:auto}.sm-confirmDialog .sm-nativeDialogDescription{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary);white-space:pre-wrap}.sm-confirmDialog .sm-warn{display:flex;align-items:flex-start;gap:8px;color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px;background:color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 8%,transparent);border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 25%,transparent);border-radius:8px;padding:8px 10px;margin-top:0}.sm-confirmDialog .sm-nativeDialogFooter{padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-confirmDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;cursor:pointer;background:transparent;color:var(--dsw-alias-label-primary);text-align:center}.sm-confirmDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-migrateDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-updateDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-bulkDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-panelDialog .sm-nativeDialogCancel:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-confirmDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-confirmDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}@keyframes sm-confirmPop{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.sm-confirmDialog.sm-nativeDialog{padding:0;width:auto;max-width:none}.sm-panelDialog .sm-rowTitle>span:first-child{display:block;min-width:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;flex:1 1 auto;width:auto;text-align:left!important;direction:ltr!important;unicode-bidi:plaintext}.sm-panelDialog .sm-rowMeta{display:none}.sm-panelDialog .sm-rowActions{display:flex;gap:2px;flex:none;justify-content:flex-end}.sm-panelDialog .sm-rowActions .sm-rowBtn{min-height:22px;padding:0 7px;font-size:11px;line-height:18px;border-radius:6px;border:1px solid transparent;background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer;white-space:nowrap}.sm-rowBtn.sm-markIcon{padding:0 6px;font-size:13px;line-height:18px}.sm-panelDialog .sm-rowActions .sm-rowBtn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.sm-panelDialog .sm-rowActions .sm-rowBtnDanger{color:var(--dsw-alias-state-error-primary)}.sm-panelDialog .sm-rowActions .sm-rowBtnDanger:hover{background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary)}.sm-panelDialog .sm-filter{flex:none;padding:6px 12px 4px;gap:4px;display:flex;flex-wrap:wrap}.sm-panelDialog .sm-filterBtn{height:28px;min-height:28px;padding:3px 10px;font-size:12px;line-height:18px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer;box-sizing:border-box;white-space:nowrap;flex-shrink:0;transition:all .15s ease}.sm-panelDialog .sm-filterBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-panelDialog .sm-filterBtn:disabled{opacity:.4;cursor:not-allowed}.sm-panelDialog .sm-filterBtn.sm-on{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-primary)}.sm-panelDialog .sm-badge{font-size:10px;line-height:14px;padding:0 5px;border-radius:6px;flex:none}.sm-panelDialog .sm-error{padding:6px 10px;margin:0;font-size:12px;line-height:16px}.sm-panelDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:transparent;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:center}.sm-panelDialog .sm-nativeDialogCancel{background:transparent}.sm-panelDialog .sm-nativeDialogConfirm,.sm-annotationDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-panelDialog .sm-nativeDialogConfirm:hover:not(:disabled),.sm-annotationDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}.sm-nativeDialogDanger{background:var(--dsw-alias-state-error-primary,#d92d20);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-nativeDialogDanger:hover:not(:disabled){filter:brightness(.92)}.sm-confirmDialog .sm-nativeDialogDanger,.sm-migrateDialog .sm-nativeDialogDanger,.sm-bulkDialog .sm-nativeDialogDanger{background:var(--dsw-alias-state-error-primary,#d92d20);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-confirmDialog .sm-nativeDialogDanger:hover:not(:disabled),.sm-migrateDialog .sm-nativeDialogDanger:hover:not(:disabled),.sm-bulkDialog .sm-nativeDialogDanger:hover:not(:disabled){filter:brightness(.92)}.sm-panelDialog .sm-empty{padding:18px 0;font-size:12px;color:var(--dsw-alias-label-tertiary);text-align:center}.sm-panelDialog .sm-footError{font-size:11px;color:var(--dsw-alias-state-error-primary);margin-right:auto;line-height:20px}.sm-panelDialog .sm-moveLabel{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary)}.sm-migrateDialog .sm-nativeDialogFooter{flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-migrateDialog .sm-migrateChip{cursor:pointer;pointer-events:auto;position:relative;z-index:1}.sm-migrateDialog .sm-migrateChip[disabled]{opacity:.5;cursor:not-allowed}.sm-migrateDialog.sm-nativeDialogLayer{position:fixed;left:50vw;top:auto;bottom:48px;transform:translateX(-50%);width:min(560px,calc(100vw - 32px));max-height:none;display:block;align-items:initial;justify-content:initial;box-sizing:border-box;background:transparent;border:0;box-shadow:none;padding:0;inset:auto;z-index:10001}.sm-migrateDialog.sm-nativeDialogLayer .sm-nativeDialogBackdrop{display:none}.sm-migrateDialog.sm-nativeDialogLayer .sm-nativeDialog{position:relative;left:auto;top:auto;transform:none;width:360px;max-width:calc(100vw - 32px);max-height:min(70vh,520px);box-sizing:border-box;background-color:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.45);overflow:hidden;padding:0;display:flex;flex-direction:column;gap:0}.sm-migrateDialog{position:fixed;left:50vw;top:auto;bottom:48px;transform:translateX(-50%);width:min(560px,calc(100vw - 32px));max-height:min(70vh,520px);box-sizing:border-box;display:flex;flex-direction:column;gap:0;background-color:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.45);overflow:hidden;z-index:10001}.sm-migrateDialog .sm-nativeDialogHeader{padding:12px 18px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;position:relative;display:flex;align-items:center;justify-content:center;min-height:44px;box-sizing:border-box}.sm-migrateDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;color:var(--dsw-alias-label-primary,#111);text-align:center;width:auto;max-width:calc(100% - 36px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm-migrateDialog .sm-migratePanel{padding:12px 18px;display:flex;flex-direction:column;gap:14px}.sm-migrateDialog .sm-nativeDialogBody{padding:0}.sm-migrateDialog .sm-nativeDialogFooter{padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex:none;flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0;gap:8px}.sm-migrateDialog .sm-migrateRow>label{color:var(--dsw-alias-label-secondary,#444)}.sm-migrateDialog .sm-migrateChip{padding:6px 12px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2,#ddd);background-color:var(--dsw-alias-markdown-tag,#f1f3f5);color:var(--dsw-alias-label-primary,#111);font-size:13px;line-height:18px;cursor:pointer;pointer-events:auto;position:relative;z-index:1;white-space:nowrap}.sm-migrateDialog .sm-migrateChip:hover:not(:disabled){background-color:var(--dsw-alias-interactive-bg-hover,#e8e8e8)}.sm-migrateDialog .sm-migrateChipOn{background-color:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-migrateDialog .sm-migrateChip.sm-migrateChipOn:hover:not(:disabled){background-color:var(--dsw-alias-button-info-hover,#4576f0);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-button-info-hover,#4576f0);filter:none}.sm-migrateDialog .sm-migrateChipOn:hover:not(:disabled){filter:brightness(.92)}.sm-migrateDialog .sm-migrateChip[disabled]{opacity:.5;cursor:not-allowed}.sm-migrateDialog .sm-migrateEmpty{color:var(--dsw-alias-label-tertiary,#888)}.sm-migrateDialog .sm-migratePreview{padding:10px 12px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;background-color:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#111);font-size:13px;line-height:18px}.sm-migrateDialog .sm-migrateWarn{padding:10px 12px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary,#f59e0b) 30%,transparent);border-radius:8px;background-color:var(--dsw-alias-state-warn-tertiary,#fef5e7);color:var(--dsw-alias-label-secondary,#444);font-size:13px;line-height:18px}.sm-migrateDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;cursor:pointer;background-color:transparent;color:var(--dsw-alias-label-primary,#111);text-align:center}.sm-migrateDialog .sm-nativeDialogButton:hover:not(:disabled){background-color:var(--dsw-alias-interactive-bg-hover,#e8e8e8)}.sm-migrateDialog .sm-nativeDialogConfirm{background-color:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-migrateDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}",
|
|
632
724
|
// The .sm-tooltip rule below deliberately keeps !important: it targets
|
|
633
725
|
// DSH's Tooltip primitive (used through renderTip), which ships its own
|
|
634
726
|
// inline styles, so a plugin rule cannot win on specificity alone
|
|
@@ -640,7 +732,7 @@ function isTopmostDialog(z) {
|
|
|
640
732
|
// applied). Tooltip visibility is governed by the layering contract
|
|
641
733
|
// above, not by this rule; it is kept as the scoped replacement for the
|
|
642
734
|
// unscoped selector Issue #21 removed.
|
|
643
|
-
".sm-panelHeaderClose{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;min-height:26px;padding:0;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:7px;background:transparent;color:var(--dsw-alias-label-secondary,#555);cursor:pointer;flex:none;box-sizing:border-box;outline:none}.sm-panelHeaderClose:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-label-primary,#111)}.sm-panelHeaderClose svg{display:block;width:14px;height:14px;margin:auto}.sm-panelHeaderGithub{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:6px;color:var(--dsw-alias-label-secondary,#555);text-decoration:none;flex:none;transition:background .15s,color .15s;cursor:pointer}.sm-panelHeaderGithub:hover{background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-label-primary,#111)}.sm-panelHeaderGithub svg{display:block;width:16px;height:16px;fill:currentColor}.sm-panelHeaderLeft{display:flex;align-items:center;gap:4px;flex:none;position:relative;z-index:1}.sm-panelHeaderWhale{display:inline-flex;align-items:center;justify-content:center;position:relative;width:26px;height:26px;border-radius:6px;color:var(--dsw-alias-label-secondary,#555);text-decoration:none;flex:none;transition:background .15s,color .15s;cursor:pointer}.sm-panelHeaderWhale:hover{background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-label-primary,#111)}.sm-panelHeaderWhale svg{display:block;width:16px;height:16px;margin:auto}.sm-panelHeaderWhale .sm-updateDot{position:absolute;top:2px;right:2px;width:7px;height:7px;border-radius:50%;background:var(--dsw-alias-state-error-primary,#e53e3e);border:1.5px solid var(--dsw-alias-bg-layer-1,#fff)}.sm-panelHeaderWhale .sm-updateSpinner{position:absolute;inset:2px;border:2px solid transparent;border-top-color:var(--dsw-alias-state-business-primary,#356ae6);border-radius:50%;animation:sm-spin .8s linear infinite}@keyframes sm-spin{to{transform:rotate(360deg)}}.sm-updateDialogLayer{display:flex!important;align-items:center!important;justify-content:center!important;position:fixed;inset:0;padding:16px;box-sizing:border-box;background:transparent;border:0;box-shadow:none;z-index:10010;pointer-events:none}.sm-updateDialogLayer .sm-nativeDialog{position:relative;width:380px;max-width:calc(100vw - 32px);box-sizing:border-box;background:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);overflow:hidden;animation:sm-confirmPop .14s ease-out;pointer-events:auto}.sm-updateDialog .sm-nativeDialogHeader{position:relative;display:flex;align-items:center;justify-content:space-between;gap:8px;padding:12px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;min-height:46px;box-sizing:border-box}.sm-updateDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:15px;line-height:20px;font-weight:600;text-align:center;width:auto;max-width:calc(100% - 80px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;z-index:0}.sm-updateDialog .sm-nativeDialogHeader .sm-panelHeaderClose{position:relative;z-index:1;margin-left:auto}.sm-updateDialog .sm-nativeDialogBody{padding:14px 16px;display:flex;flex-direction:column;gap:10px;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111)}.sm-updateDialog .sm-nativeDialogFooter{display:flex;padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex:none;flex-wrap:wrap;justify-content:space-between;gap:8px;margin-top:0}.sm-updateDialog .sm-nativeDialogFooter .sm-nativeDialogConfirm:only-child{margin-left:auto}.sm-updateDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;cursor:pointer;background:transparent;color:var(--dsw-alias-label-primary,#111);text-align:center}.sm-updateDialog .sm-nativeDialogButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-updateDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-updateDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}.sm-updateVersionGrid{display:grid;grid-template-columns:auto 1fr;gap:6px 12px;padding:12px;background:var(--dsw-alias-bg-layer-2,#fff);border:1px solid var(--dsw-alias-border-l2,#eee);border-radius:8px;font-size:13px;line-height:20px}.sm-updateVersionLabel{color:var(--dsw-alias-label-secondary,#666);font-weight:500}.sm-updateVersionValue{color:var(--dsw-alias-label-primary,#111);font-family:monospace;font-size:13px}.sm-updateStatusBox{margin-top:10px;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111)}.sm-updateStatusBox.sm-warn{color:var(--dsw-alias-state-warn-label,#dd8629);background:var(--dsw-alias-state-warn-tertiary,#fef5e7);padding:8px 10px;border-radius:6px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary,#f59e0b) 25%,transparent)}.sm-updateStatusBox.sm-error{color:var(--dsw-alias-state-error-primary,#ec1313);background:color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 8%,transparent);padding:8px 10px;border-radius:6px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 22%,transparent)}.sm-updateStatusBox.sm-success{color:var(--dsw-alias-state-success-primary,#22c55e);background:var(--dsw-alias-state-success-tertiary,#e6faed);padding:8px 10px;border-radius:6px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-success-primary,#22c55e) 25%,transparent)}.sm-settingsCard{background:var(--sm-dialog-surface);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;padding:16px 20px;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111);box-sizing:border-box;width:100%}.sm-settingsHeader{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px;padding-bottom:10px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee)}.sm-settingsTitle{margin:0;font-size:16px;line-height:22px;font-weight:600;display:flex;align-items:center;gap:8px}.sm-settingsTag{font-size:12px;padding:2px 8px;border-radius:999px;background:var(--dsw-alias-markdown-tag,#f1f3f5);color:var(--dsw-alias-label-secondary,#666);font-family:monospace}.sm-settingsSection{margin-top:14px;padding-top:12px;border-top:1px solid var(--dsw-alias-border-l2,#eee)}.sm-settingsSectionTitle{font-size:13px;font-weight:600;color:var(--dsw-alias-label-secondary,#666);margin-bottom:8px;text-transform:uppercase;letter-spacing:.5px}.sm-settingsRow{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:32px}.sm-settingsActions{display:flex;align-items:center;gap:8px;margin-top:10px}.sm-settingsLink{color:var(--dsw-alias-state-business-primary,#356ae6);text-decoration:none}.sm-settingsLink:hover{text-decoration:underline}.sm-settingsCheckbox{display:inline-flex;align-items:center;gap:6px;cursor:pointer}.sm-settingsSelect{min-height:28px;padding:3px 8px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:6px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#111);cursor:pointer;outline:none}.sm-panelHeaderClose:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-label-primary,#111)}.sm-panelHeaderClose:disabled{opacity:.5;cursor:not-allowed}.sm-migrateCurrent{padding:8px 10px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;background:var(--dsw-alias-bg-layer-2,#fff);font-size:13px;line-height:18px;color:var(--dsw-alias-label-primary,#111)}.sm-migrateConfirmLayer.sm-confirmDialog.sm-nativeDialogLayer{width:360px;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);inset:calc(50vh - 90px) auto auto calc(50vw + 308px)}.sm-migrateConfirmLayer.sm-confirmDialog.sm-nativeDialogLayer .sm-migrateDialog{position:relative;left:auto;top:auto;bottom:auto;transform:none;width:100%;max-width:calc(100vw - 32px);max-height:min(70vh,calc(100vh - 32px));z-index:auto;display:flex;flex-direction:column;overflow:hidden}.sm-migrateConfirmLayer .sm-migratePanel{min-width:0;max-height:calc(100vh - 120px);overflow-y:auto}.sm-migrateConfirmLayer .sm-nativeDialogButton.sm-nativeDialogConfirm:hover:not(:disabled){background-color:var(--dsw-alias-button-info-hover,#4576f0);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-button-info-hover,#4576f0);filter:none}.sm-settingsSectionHeader{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}.sm-settingsSectionHeader .sm-settingsSectionTitle{margin-bottom:0}.sm-settingsVersionActions{display:flex;align-items:center;gap:8px}.sm-settingsCheckBtn{min-height:26px;padding:2px 12px;font-size:12px;line-height:18px;border-radius:6px;border:1px solid var(--dsw-alias-border-l2,#ddd);background:transparent;color:var(--dsw-alias-label-primary,#111);cursor:pointer;white-space:nowrap}.sm-settingsCheckBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-settingsRowInline{justify-content:flex-start;flex-wrap:wrap;gap:8px;align-items:center}.sm-settingsBadgeLink{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:6px;border:1px solid var(--dsw-alias-border-l2,#ddd);background:var(--dsw-alias-markdown-tag,#f1f3f5);color:var(--dsw-alias-label-secondary,#555);font-size:12px;line-height:18px;text-decoration:none;cursor:pointer;transition:all .15s}.sm-settingsBadgeLink:hover{background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-state-business-primary,#356ae6);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-settingsBadgeLink svg{flex:none}.sm-tooltip{z-index:1100!important;box-shadow:none!important;border:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.15))!important;filter:none!important}",
|
|
735
|
+
".sm-panelHeaderClose{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;min-height:26px;padding:0;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:7px;background:transparent;color:var(--dsw-alias-label-secondary,#555);cursor:pointer;flex:none;box-sizing:border-box;outline:none}.sm-panelHeaderClose:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-label-primary,#111)}.sm-panelHeaderClose svg{display:block;width:14px;height:14px;margin:auto}.sm-panelHeaderGithub{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:6px;color:var(--dsw-alias-label-secondary,#555);text-decoration:none;flex:none;transition:background .15s,color .15s;cursor:pointer}.sm-panelHeaderGithub:hover{background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-label-primary,#111)}.sm-panelHeaderGithub svg{display:block;width:16px;height:16px;fill:currentColor}.sm-panelHeaderLeft{display:flex;align-items:center;gap:4px;flex:none;position:relative;z-index:1}.sm-panelHeaderWhale{display:inline-flex;align-items:center;justify-content:center;position:relative;width:26px;height:26px;border-radius:6px;color:var(--dsw-alias-label-secondary,#555);text-decoration:none;flex:none;transition:background .15s,color .15s;cursor:pointer}.sm-panelHeaderWhale:hover{background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-label-primary,#111)}.sm-panelHeaderWhale svg{display:block;width:16px;height:16px;margin:auto}.sm-panelHeaderWhale .sm-updateDot{position:absolute;top:2px;right:2px;width:7px;height:7px;border-radius:50%;background:var(--dsw-alias-state-error-primary,#e53e3e);border:1.5px solid var(--dsw-alias-bg-layer-1,#fff)}.sm-panelHeaderWhale .sm-updateSpinner{position:absolute;inset:2px;border:2px solid transparent;border-top-color:var(--dsw-alias-state-business-primary,#356ae6);border-radius:50%;animation:sm-spin .8s linear infinite}@keyframes sm-spin{to{transform:rotate(360deg)}}.sm-updateDialogLayer{display:flex!important;align-items:center!important;justify-content:center!important;position:fixed;inset:0;padding:16px;box-sizing:border-box;background:transparent;border:0;box-shadow:none;z-index:10010;pointer-events:none}.sm-updateDialogLayer .sm-nativeDialog{position:relative;width:380px;max-width:calc(100vw - 32px);box-sizing:border-box;background:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);overflow:hidden;animation:sm-confirmPop .14s ease-out;pointer-events:auto}.sm-updateDialog .sm-nativeDialogHeader{position:relative;display:flex;align-items:center;justify-content:space-between;gap:8px;padding:12px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;min-height:46px;box-sizing:border-box}.sm-updateDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:15px;line-height:20px;font-weight:600;text-align:center;width:auto;max-width:calc(100% - 80px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;z-index:0}.sm-updateDialog .sm-nativeDialogHeader .sm-panelHeaderClose{position:relative;z-index:1;margin-left:auto}.sm-updateDialog .sm-nativeDialogBody{padding:14px 16px;display:flex;flex-direction:column;gap:10px;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111)}.sm-updateDialog .sm-nativeDialogFooter{display:flex;padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex:none;flex-wrap:wrap;justify-content:space-between;gap:8px;margin-top:0}.sm-updateDialog .sm-nativeDialogFooter .sm-nativeDialogConfirm:only-child{margin-left:auto}.sm-updateDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;cursor:pointer;background:transparent;color:var(--dsw-alias-label-primary,#111);text-align:center}.sm-updateDialog .sm-nativeDialogButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-updateDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-updateDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}.sm-updateVersionGrid{display:grid;grid-template-columns:auto 1fr;gap:6px 12px;padding:12px;background:var(--dsw-alias-bg-layer-2,#fff);border:1px solid var(--dsw-alias-border-l2,#eee);border-radius:8px;font-size:13px;line-height:20px}.sm-updateVersionLabel{color:var(--dsw-alias-label-secondary,#666);font-weight:500}.sm-updateVersionValue{color:var(--dsw-alias-label-primary,#111);font-family:monospace;font-size:13px}.sm-updateStatusBox{margin-top:10px;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111)}.sm-updateStatusBox.sm-warn{color:var(--dsw-alias-state-warn-label,#dd8629);background:var(--dsw-alias-state-warn-tertiary,#fef5e7);padding:8px 10px;border-radius:6px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary,#f59e0b) 25%,transparent)}.sm-updateStatusBox.sm-error{color:var(--dsw-alias-state-error-primary,#ec1313);background:color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 8%,transparent);padding:8px 10px;border-radius:6px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 22%,transparent)}.sm-updateStatusBox.sm-success{color:var(--dsw-alias-state-success-primary,#22c55e);background:var(--dsw-alias-state-success-tertiary,#e6faed);padding:8px 10px;border-radius:6px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-success-primary,#22c55e) 25%,transparent)}.sm-settingsCard{background:var(--sm-dialog-surface);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;padding:16px 20px;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111);box-sizing:border-box;width:100%}.sm-settingsHeader{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px;padding-bottom:10px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee)}.sm-settingsTitle{margin:0;font-size:16px;line-height:22px;font-weight:600;display:flex;align-items:center;gap:8px}.sm-settingsTag{font-size:12px;padding:2px 8px;border-radius:999px;background:var(--dsw-alias-markdown-tag,#f1f3f5);color:var(--dsw-alias-label-secondary,#666);font-family:monospace}.sm-settingsSection{margin-top:14px;padding-top:12px;border-top:1px solid var(--dsw-alias-border-l2,#eee)}.sm-settingsSectionTitle{font-size:13px;font-weight:600;color:var(--dsw-alias-label-secondary,#666);margin-bottom:8px;text-transform:uppercase;letter-spacing:.5px}.sm-settingsRow{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:36px;margin-top:8px}.sm-settingsRow:first-of-type{margin-top:0}.sm-settingsRow>span:first-child{white-space:nowrap;flex-shrink:0}.sm-settingsActions{display:flex;align-items:center;gap:8px;margin-top:10px}.sm-settingsLink{color:var(--dsw-alias-state-business-primary,#356ae6);text-decoration:none}.sm-settingsLink:hover{text-decoration:underline}.sm-settingsCheckbox{display:inline-flex;align-items:center;gap:6px;cursor:pointer}.sm-settingsSelect{min-height:30px;height:30px;width:280px;min-width:280px;max-width:280px;flex:0 0 280px;box-sizing:border-box;font-size:12px;line-height:20px;padding:4px 26px 4px 10px;border-radius:8px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#111);cursor:pointer}.sm-settingsRowLeft{display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:2px;min-width:0;flex:1 1 auto}.sm-settingsRowLeft>span:first-child{white-space:nowrap;flex-shrink:0}.sm-panelHeaderClose:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-label-primary,#111)}.sm-panelHeaderClose:disabled{opacity:.5;cursor:not-allowed}.sm-migrateCurrent{padding:8px 10px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;background:var(--dsw-alias-bg-layer-2,#fff);font-size:13px;line-height:18px;color:var(--dsw-alias-label-primary,#111)}.sm-migrateConfirmLayer.sm-confirmDialog.sm-nativeDialogLayer{width:360px;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);inset:calc(50vh - 90px) auto auto calc(50vw + 308px)}.sm-migrateConfirmLayer.sm-confirmDialog.sm-nativeDialogLayer .sm-migrateDialog{position:relative;left:auto;top:auto;bottom:auto;transform:none;width:100%;max-width:calc(100vw - 32px);max-height:min(70vh,calc(100vh - 32px));z-index:auto;display:flex;flex-direction:column;overflow:hidden}.sm-migrateConfirmLayer .sm-migratePanel{min-width:0;max-height:calc(100vh - 120px);overflow-y:auto}.sm-migrateConfirmLayer .sm-nativeDialogButton.sm-nativeDialogConfirm:hover:not(:disabled){background-color:var(--dsw-alias-button-info-hover,#4576f0);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-button-info-hover,#4576f0);filter:none}.sm-settingsSectionHeader{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}.sm-settingsSectionHeader .sm-settingsSectionTitle{margin-bottom:0}.sm-settingsVersionActions{display:flex;align-items:center;gap:8px}.sm-settingsCheckBtn{min-height:26px;padding:2px 12px;font-size:12px;line-height:18px;border-radius:6px;border:1px solid var(--dsw-alias-border-l2,#ddd);background:transparent;color:var(--dsw-alias-label-primary,#111);cursor:pointer;white-space:nowrap}.sm-settingsCheckBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-settingsRowInline{justify-content:flex-start;flex-wrap:wrap;gap:8px;align-items:center}.sm-settingsProjectLeft{display:flex;align-items:center;gap:8px;min-width:0;flex-wrap:nowrap}.sm-settingsProjectLabel{color:var(--dsw-alias-label-primary,#111);white-space:nowrap;flex-shrink:0}.sm-settingsBadgeActions{display:flex;align-items:center;gap:8px;margin-left:auto;flex:0 0 280px;width:280px;min-width:280px;max-width:280px;box-sizing:border-box;justify-content:flex-end}.sm-settingsBadgeActions>*{display:inline-flex;flex:1 1 0;min-width:0}.sm-settingsBadgeLink{display:inline-flex;align-items:center;justify-content:center;gap:6px;width:100%;padding:4px 10px;min-height:28px;height:28px;box-sizing:border-box;border-radius:6px;border:1px solid var(--dsw-alias-border-l2,#ddd);background:var(--dsw-alias-markdown-tag,#f1f3f5);color:var(--dsw-alias-label-secondary,#555);font-size:12px;line-height:18px;text-decoration:none;cursor:pointer;white-space:nowrap;transition:all .15s}.sm-settingsBadgeLink:hover{background:var(--dsw-alias-interactive-bg-hover,#eee);color:var(--dsw-alias-state-business-primary,#356ae6);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-settingsBadgeLink svg{flex:none}.sm-tooltip{z-index:1100!important;box-shadow:none!important;border:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.15))!important;filter:none!important}",
|
|
644
736
|
|
|
645
737
|
// Issue #23 — dialog opacity.
|
|
646
738
|
//
|
|
@@ -682,14 +774,14 @@ function isTopmostDialog(z) {
|
|
|
682
774
|
".sm-panelDialog option:checked,.sm-nativeDialog option:checked,.sm-settingsCard option:checked,.sm-headerMenu option:checked{background-color:var(--dsw-alias-bg-layer-3,#fff);color:var(--dsw-alias-state-business-primary,#356ae6)}",
|
|
683
775
|
".sm-panelDialog option:disabled,.sm-nativeDialog option:disabled,.sm-settingsCard option:disabled,.sm-headerMenu option:disabled{color:var(--dsw-alias-label-tertiary,#888)}",
|
|
684
776
|
".sm-nativeDialog,.sm-panelDialog,.sm-migrateDialog,.sm-settingsCard{--sm-dialog-surface:var(--dsw-alias-bg-layer-1,var(--sm-dialog-surface-fallback,#fff));--sm-dialog-fill:color-mix(in srgb,var(--sm-dialog-surface) var(--sm-dialog-opacity,100%),transparent)}",
|
|
685
|
-
".sm-settingsSlider{display:flex;align-items:center;gap:8px;flex:
|
|
686
|
-
".sm-settingsRange{flex:1 1
|
|
777
|
+
".sm-settingsSlider{display:flex;align-items:center;gap:8px;flex:0 0 280px;width:280px;min-width:280px;max-width:280px;box-sizing:border-box;justify-content:flex-end}",
|
|
778
|
+
".sm-settingsRange{flex:1 1 auto;min-width:70px;margin:0;cursor:pointer;accent-color:var(--dsw-alias-state-business-primary,#356ae6)}",
|
|
687
779
|
".sm-settingsRange:disabled{cursor:not-allowed}",
|
|
688
|
-
".sm-settingsRangeValue{min-width:38px;text-align:right;font-size:12px;line-height:18px;font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-secondary,#666)}",
|
|
689
|
-
".sm-settingsResetBtn{min-height:
|
|
780
|
+
".sm-settingsRangeValue{min-width:38px;text-align:right;font-size:12px;line-height:18px;font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-secondary,#666);flex-shrink:0}",
|
|
781
|
+
".sm-settingsResetBtn{min-height:28px;height:28px;padding:2px 10px;font-size:12px;line-height:18px;border-radius:6px;border:1px solid var(--dsw-alias-border-l2,#ddd);background:transparent;color:var(--dsw-alias-label-secondary,#666);cursor:pointer;white-space:nowrap;flex:0 0 auto;box-sizing:border-box}",
|
|
690
782
|
".sm-settingsResetBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary,#111)}",
|
|
691
783
|
".sm-settingsResetBtn:disabled{opacity:.5;cursor:not-allowed}",
|
|
692
|
-
".sm-settingsHint{
|
|
784
|
+
".sm-settingsHint{font-size:11px;line-height:16px;color:var(--dsw-alias-label-tertiary,#888)}.sm-settingsHintInline{margin-left:0;font-weight:normal}",
|
|
693
785
|
|
|
694
786
|
// DSH's own theme is the single source of colour. Every rule above reads
|
|
695
787
|
// --dsw-alias-* tokens directly and none of them is redefined here: the
|
|
@@ -703,12 +795,18 @@ function isTopmostDialog(z) {
|
|
|
703
795
|
"[data-sm-theme=dark] .sm-nativeDialog,[data-sm-theme=dark] .sm-panelDialog,[data-sm-theme=dark] .sm-migrateDialog,[data-sm-theme=dark] .sm-settingsCard{--sm-dialog-surface-fallback:#1f1f23}",
|
|
704
796
|
".sm-panelDialog{max-height:min(640px,calc(100vh - 32px))}.sm-panelDialog .sm-panel{min-width:0;overflow:hidden}",
|
|
705
797
|
".sm-panelTools{display:flex;flex-direction:column;gap:8px;flex:none;padding:2px 0 6px}",
|
|
706
|
-
".sm-queryInput,.sm-viewSelect{box-sizing:border-box;width:100%;min-width:0;height:32px;padding:5px 9px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:
|
|
707
|
-
".sm-
|
|
708
|
-
".sm-
|
|
709
|
-
".sm-
|
|
798
|
+
".sm-queryInput,.sm-viewSelect{box-sizing:border-box;width:100%;min-width:0;height:32px;padding:5px 9px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#111);font:inherit;font-size:12px;line-height:20px;transition:border-color .15s ease,box-shadow .15s ease}",
|
|
799
|
+
".sm-viewSelect,.sm-settingsSelect,.sm-wsSortSelect,.sm-prioritySelectInline,.sm-panelDialog select,.sm-nativeDialog select,.sm-settingsCard select{box-sizing:border-box!important;appearance:none;-webkit-appearance:none;-moz-appearance:none;border:1px solid var(--dsw-alias-border-l2,#ddd)!important;border-radius:8px!important;background-color:var(--dsw-alias-bg-layer-2,#fff)!important;color:var(--dsw-alias-label-primary,#111)!important;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%23888888' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E\")!important;background-repeat:no-repeat!important;background-position:right 8px center!important;background-size:10px 10px!important;padding-right:26px!important;cursor:pointer!important;outline:none!important;font:inherit;transition:border-color .15s ease,box-shadow .15s ease!important}",
|
|
800
|
+
".sm-viewSelect:hover:not(:disabled),.sm-settingsSelect:hover:not(:disabled),.sm-wsSortSelect:hover:not(:disabled),.sm-prioritySelectInline:hover:not(:disabled),.sm-panelDialog select:hover:not(:disabled),.sm-nativeDialog select:hover:not(:disabled),.sm-settingsCard select:hover:not(:disabled){border-color:var(--dsw-alias-border-l1,#aaa)!important}",
|
|
801
|
+
".sm-queryInput::placeholder{color:var(--dsw-alias-label-tertiary,#888)}.sm-queryInput:focus-visible,.sm-viewSelect:focus-visible,.sm-settingsSelect:focus-visible,.sm-wsSortSelect:focus-visible,.sm-prioritySelectInline:focus-visible,.sm-panelDialog select:focus-visible,.sm-nativeDialog select:focus-visible,.sm-settingsCard select:focus-visible,.sm-resetFilters:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,#356ae6)!important;outline-offset:1px!important}.sm-viewSelect:disabled,.sm-settingsSelect:disabled,.sm-wsSortSelect:disabled,.sm-prioritySelectInline:disabled,.sm-panelDialog select:disabled,.sm-nativeDialog select:disabled,.sm-settingsCard select:disabled{opacity:.5!important;cursor:not-allowed!important}",
|
|
802
|
+
".sm-selectExpanded{border-color:var(--dsw-alias-state-business-primary,#356ae6)!important;box-shadow:0 0 0 1px var(--dsw-alias-state-business-primary,#356ae6)!important;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%23356ae6' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m18 15-6-6-6 6'/%3E%3C/svg%3E\")!important}",
|
|
803
|
+
".sm-customSelectMenu{position:fixed;z-index:100030;box-sizing:border-box;min-width:120px;max-height:260px;overflow-y:auto;overflow-x:hidden;padding:4px;background:var(--dsw-alias-bg-layer-3,var(--dsw-alias-bg-layer-2,#fff));border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;box-shadow:none!important;font-family:inherit;font-size:12px;line-height:18px;color:var(--dsw-alias-label-primary,#111);user-select:none;scrollbar-width:thin;scrollbar-color:var(--dsw-alias-scrollbar-bg-l1,var(--dsw-alias-border-l1,rgba(128,128,128,.3))) transparent}.sm-customSelectMenu-dropUp{box-shadow:none!important}.sm-customSelectOption{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 10px;border-radius:6px;font-size:12px;line-height:18px;color:var(--dsw-alias-label-primary,#111);cursor:pointer;white-space:nowrap;user-select:none;transition:background-color .1s ease,color .1s ease}.sm-customSelectOption:hover:not(.sm-customSelectOptionDisabled){background-color:var(--dsw-alias-interactive-bg-hover,rgba(0,0,0,.05))}.sm-customSelectOptionSelected{background-color:var(--dsw-alias-interactive-bg-active,rgba(53,106,230,.08));color:var(--dsw-alias-state-business-primary,#356ae6);font-weight:500}.sm-customSelectOptionDisabled{opacity:.45;cursor:not-allowed;color:var(--dsw-alias-label-tertiary,#888)!important}.sm-customSelectOptionLabel{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1 1 auto}.sm-customSelectOptionCheck{font-size:11px;font-weight:bold;color:var(--dsw-alias-state-business-primary,#356ae6);margin-left:6px;flex-shrink:0}",
|
|
804
|
+
".sm-wsSortSelect,.sm-prioritySelectInline,.sm-panelSelects .sm-viewSelect{pointer-events:none!important}",
|
|
805
|
+
".sm-wsSortField,.sm-annotationPriority,.sm-viewField,.sm-moveSection,.sm-settingsRow{cursor:pointer}",
|
|
806
|
+
".sm-panelSelects{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px}.sm-panelSelects .sm-viewField>span{display:none}.sm-panelSelects .sm-viewField .sm-viewSelect{font-size:11px;padding:4px 24px 4px 8px;height:28px;line-height:18px;background-position:right 6px center}.sm-viewField{display:flex;flex-direction:column;gap:3px;min-width:0;color:var(--dsw-alias-label-secondary,#666);font-size:11px;line-height:16px}.sm-wsSortField{display:inline-flex;margin:0;vertical-align:middle}.sm-wsSortSelect{height:28px;font-size:11px;padding:3px 24px 3px 8px;width:auto;min-width:120px;border-radius:8px;line-height:18px;background-position:right 6px center;cursor:pointer}",
|
|
807
|
+
".sm-filterBar{display:flex;align-items:center;justify-content:space-between;gap:6px;flex-wrap:wrap}.sm-resultSummary{display:flex;align-items:center;gap:8px;flex-wrap:nowrap;height:20px;min-height:20px;max-height:20px;line-height:20px;font-size:11px;color:var(--dsw-alias-label-tertiary,#888);box-sizing:border-box}.sm-resetFilters{padding:0 4px;height:20px;line-height:20px;border:0;background:none;color:var(--dsw-alias-state-business-primary,#356ae6);font:inherit;font-size:11px;cursor:pointer;display:inline-flex;align-items:center;white-space:nowrap;border-radius:4px;box-sizing:border-box}.sm-resetFilters:hover{text-decoration:underline}.sm-workspaceNotice{display:flex;gap:8px;align-items:center;font-size:12px;color:var(--dsw-alias-label-secondary,#666)}",
|
|
710
808
|
"@media(max-width:540px){.sm-panelSelects{grid-template-columns:minmax(0,1fr)}.sm-panelDialog .sm-row{height:auto;min-height:36px;flex-shrink:0;flex-wrap:wrap;padding:6px 8px}.sm-panelDialog .sm-rowMain{flex-basis:100%}.sm-panelDialog .sm-rowActions{width:100%;min-width:0;flex:1 1 100%;justify-content:flex-start}}",
|
|
711
|
-
".sm-panelDialog:not(.sm-annotationSurface){width:680px}.sm-panelDialog .sm-row{flex-shrink:0;padding:5px 8px}.sm-panelDialog .sm-rowMain{flex:1 1 200px;flex-direction:column;gap:4px}.sm-panelDialog .sm-rowActions{max-width:100%}.sm-rowSecondary{display:flex;flex-wrap:nowrap;align-items:center;gap:6px;min-width:0;line-height:18px}.sm-rowBadges{display:flex;align-items:center;gap:5px;min-width:0;flex:1 1 auto;flex-wrap:wrap;font-size:11px;line-height:18px}.sm-rowMeta{color:var(--dsw-alias-label-tertiary,#888);font-size:11px;line-height:18px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex:none}.sm-rowAnnotations{display:flex;align-items:center;gap:5px;min-width:0;font-size:10px;line-height:16px}",
|
|
809
|
+
".sm-panelDialog:not(.sm-annotationSurface){position:fixed;inset:0;margin:auto;transform:none;width:680px;height:560px;max-height:calc(100vh - 32px)}.sm-panelDialog .sm-row{flex-shrink:0;padding:5px 8px}.sm-panelDialog .sm-rowMain{flex:1 1 200px;flex-direction:column;gap:4px}.sm-panelDialog .sm-rowActions{max-width:100%}.sm-rowSecondary{display:flex;flex-wrap:nowrap;align-items:center;gap:6px;min-width:0;line-height:18px}.sm-rowBadges{display:flex;align-items:center;gap:5px;min-width:0;flex:1 1 auto;flex-wrap:wrap;font-size:11px;line-height:18px}.sm-rowMeta{color:var(--dsw-alias-label-tertiary,#888);font-size:11px;line-height:18px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex:none}.sm-rowAnnotations{display:flex;align-items:center;gap:5px;min-width:0;font-size:10px;line-height:16px}",
|
|
712
810
|
// .sm-markIcon.sm-markOn keeps !important because the generic
|
|
713
811
|
// `.sm-panelDialog .sm-rowActions .sm-rowBtn` colour rule (3 classes)
|
|
714
812
|
// outranks this 2-class selector; it overrides the plugin's own rule,
|
|
@@ -730,7 +828,7 @@ function isTopmostDialog(z) {
|
|
|
730
828
|
// 1000..1100 gap -- the panel at 1020 and this overlay root at 1050 --
|
|
731
829
|
// and everything portaled into this root is relative to its context.
|
|
732
830
|
"#dsh-session-manager-overlay-root{position:fixed!important;inset:0!important;width:100%!important;height:100%!important;z-index:1050!important;pointer-events:none!important;overflow:visible!important}.sm-annotationDialog.sm-nativeDialogLayer{position:fixed;display:block;pointer-events:none;z-index:100002;background:transparent}.sm-annotationDialog .sm-nativeDialogBackdrop{display:none}.sm-annotationDialog.sm-annotationDialog-anchored.sm-nativeDialogLayer,.sm-confirmDialog.sm-confirmDialog-anchored.sm-nativeDialogLayer,.sm-bulkDialog.sm-bulkDialog-anchored.sm-nativeDialogLayer{inset:auto;background:transparent}.sm-annotationDialog.sm-confirmDialog.sm-nativeDialogLayer:not(.sm-annotationDialog-anchored){inset:50% auto auto calc(50vw + 308px);transform:translateY(-50%);max-height:calc(100vh - 32px)}.sm-panelDialog.sm-annotationSurface{position:absolute;width:360px;max-height:min(680px,calc(100vh - 32px));pointer-events:auto;z-index:100003;box-shadow:0 16px 48px rgba(0,0,0,.25)}.sm-panelDialog.sm-annotationSurface.sm-annotationSurface-anchored{position:relative;transform:none;left:auto;top:auto;margin:0}.sm-annotationCloseHint{margin:0 16px 8px;font-size:11px;line-height:16px;color:var(--dsw-alias-label-tertiary)}",
|
|
733
|
-
".sm-annotationBody{padding:14px 16px;display:flex;flex-direction:column;gap:12px;min-height:0;overflow:auto;flex:1 1 auto}.sm-annotationTarget{font-size:12px;line-height:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-secondary,#666)}.sm-annotationChecks{display:grid;grid-template-columns:auto 1fr;column-gap:14px;row-gap:4px;align-items:center;font-size:13px}.sm-annotationChecks>label{display:flex;gap:6px;align-items:center;cursor:pointer}.sm-annotationChecks .sm-annotationPriority{display:inline-flex;align-items:center;gap:6px;font-size:13px;line-height:18px;color:inherit}.sm-annotationChecks .sm-prioritySelectInline{height:
|
|
831
|
+
".sm-annotationBody{padding:14px 16px;display:flex;flex-direction:column;gap:12px;min-height:0;overflow:auto;flex:1 1 auto}.sm-annotationTarget{font-size:12px;line-height:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-secondary,#666)}.sm-annotationChecks{display:grid;grid-template-columns:auto 1fr;column-gap:14px;row-gap:4px;align-items:center;font-size:13px}.sm-annotationChecks>label{display:flex;gap:6px;align-items:center;cursor:pointer}.sm-annotationChecks .sm-annotationPriority{display:inline-flex;align-items:center;gap:6px;font-size:13px;line-height:18px;color:inherit}.sm-annotationChecks .sm-prioritySelectInline{height:26px;padding:2px 24px 2px 8px;font-size:12px;line-height:18px;min-width:104px;width:auto;border-radius:8px!important;background-position:right 6px center!important;color:var(--dsw-alias-label-primary,#111)}.sm-annotationChecks>small{font-size:11px;line-height:16px;color:var(--dsw-alias-label-tertiary,#888);justify-self:start}.sm-annotationHint,.sm-annotationBody small{font-size:11px;line-height:16px;color:var(--dsw-alias-label-tertiary,#888)}",
|
|
734
832
|
".sm-noteInput{box-sizing:border-box;width:100%;min-height:60px;resize:vertical;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:7px;padding:8px;background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#111);font:inherit;font-size:13px;line-height:19px}.sm-noteInput:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,#356ae6);outline-offset:2px}.sm-markConflict{display:flex;flex-direction:column;gap:5px;font-size:12px;padding:8px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:6px}.sm-fieldWithClear .sm-fieldRow{position:relative;display:flex;align-items:flex-start;gap:4px}.sm-fieldRow .sm-queryInput{flex:1 1 auto;min-width:0}.sm-fieldRowNote{align-items:stretch}.sm-fieldClear{position:absolute;top:5px;right:6px;width:22px;height:22px;border:0;background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer;border-radius:4px;font-size:14px;line-height:18px;display:inline-flex;align-items:center;justify-content:center;padding:0}.sm-fieldClear:hover,.sm-fieldClear:focus-visible{color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-interactive-bg-hover);outline:none}.sm-fieldClearNote{top:6px}.sm-importGroup{display:flex;flex-direction:column;gap:8px;padding:12px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee)}.sm-importGroupHeader{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:20px}.sm-importLabel{color:var(--dsw-alias-label-secondary,#666);font-size:11px;line-height:16px}.sm-importGroupButtons{display:flex;align-items:center;gap:6px;flex:none}.sm-importBtn{cursor:pointer;color:var(--dsw-alias-label-primary,#111);background:transparent;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;text-align:center}.sm-importBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.sm-importBtn:disabled{opacity:.5;cursor:not-allowed}.sm-importStatus{margin:0;padding:8px 10px;font-size:12px;line-height:18px;background:var(--dsw-alias-state-business-tertiary,rgba(53,106,230,.08));color:var(--dsw-alias-label-secondary);border-radius:6px;white-space:pre-wrap;word-break:break-word}",
|
|
735
833
|
".sm-bulkBar{box-sizing:border-box;display:grid;grid-template-columns:repeat(6,minmax(0,1fr));align-items:stretch;gap:6px;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:10px;background:var(--dsw-alias-bg-layer-2,#fff)}.sm-bulkBar .sm-bulkSummary{grid-column:1/-1;color:var(--dsw-alias-label-primary,#111);font-size:12px;line-height:18px;font-weight:500;margin:0 0 2px}",
|
|
736
834
|
".sm-bulkSummary{color:var(--dsw-alias-label-primary,#111);font-size:12px;line-height:18px;font-weight:500}",
|
|
@@ -746,11 +844,11 @@ function isTopmostDialog(z) {
|
|
|
746
844
|
".sm-bulkRowCheckbox input{width:14px;height:14px;cursor:pointer;margin:0}",
|
|
747
845
|
".sm-bulkRowCheckbox input:disabled{cursor:not-allowed}",
|
|
748
846
|
".sm-rowBulkSelected{border-color:var(--dsw-alias-state-business-primary,#356ae6);background:var(--dsw-alias-state-business-tertiary,rgba(53,106,230,.06))}",
|
|
749
|
-
".sm-bulkDialog.sm-nativeDialogLayer{position:fixed;left:calc(50vw + 184px);top:calc(50vh - 90px);width:360px;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);display:block;align-items:initial;justify-content:initial;box-sizing:border-box;background:transparent;border:0;box-shadow:none;padding:0;inset:calc(50vh - 90px) auto auto calc(50vw + 308px);z-index:10002}.sm-bulkDialog.sm-nativeDialogLayer .sm-nativeDialogBackdrop{display:none}.sm-bulkDialog.sm-nativeDialogLayer .sm-nativeDialog{position:relative;left:auto;top:auto;transform:none;width:auto;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);display:flex;flex-direction:column;box-sizing:border-box;background:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);padding:0;overflow:hidden;animation:sm-confirmPop .14s ease-out}.sm-bulkDialog .sm-nativeDialogHeader{padding:10px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;position:relative;display:flex;align-items:center;justify-content:center;min-height:44px;box-sizing:border-box}.sm-bulkDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;text-align:center;width:auto;max-width:calc(100% - 32px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm-bulkDialog .sm-nativeDialogBody{padding:12px 16px;display:flex;flex-direction:column;gap:10px;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111);min-height:0;max-height:calc(100vh - 120px);overflow-y:auto}.sm-bulkDialog .sm-nativeDialogFooter{padding:10px 16px;display:flex;flex-wrap:wrap;justify-content:space-between;gap:6px}.sm-bulkDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;cursor:pointer;background:transparent;color:var(--dsw-alias-label-primary,#111);text-align:center}.sm-bulkDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-bulkDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}.sm-bulkDialog .sm-nativeDialogDanger{background:var(--dsw-alias-state-error-primary,#d92d20);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-bulkDialog .sm-nativeDialogDanger:hover:not(:disabled){filter:brightness(.92)}.sm-bulkDialog .sm-nativeDialog select.sm-viewSelect{font-size:13px;line-height:20px;height:32px;padding:5px
|
|
847
|
+
".sm-bulkDialog.sm-nativeDialogLayer{position:fixed;left:calc(50vw + 184px);top:calc(50vh - 90px);width:360px;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);display:block;align-items:initial;justify-content:initial;box-sizing:border-box;background:transparent;border:0;box-shadow:none;padding:0;inset:calc(50vh - 90px) auto auto calc(50vw + 308px);z-index:10002}.sm-bulkDialog.sm-nativeDialogLayer .sm-nativeDialogBackdrop{display:none}.sm-bulkDialog.sm-nativeDialogLayer .sm-nativeDialog{position:relative;left:auto;top:auto;transform:none;width:auto;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);display:flex;flex-direction:column;box-sizing:border-box;background:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);padding:0;overflow:hidden;animation:sm-confirmPop .14s ease-out}.sm-bulkDialog .sm-nativeDialogHeader{padding:10px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;position:relative;display:flex;align-items:center;justify-content:center;min-height:44px;box-sizing:border-box}.sm-bulkDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;text-align:center;width:auto;max-width:calc(100% - 32px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm-bulkDialog .sm-nativeDialogBody{padding:12px 16px;display:flex;flex-direction:column;gap:10px;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111);min-height:0;max-height:calc(100vh - 120px);overflow-y:auto}.sm-bulkDialog .sm-nativeDialogFooter{padding:10px 16px;display:flex;flex-wrap:wrap;justify-content:space-between;gap:6px}.sm-bulkDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;cursor:pointer;background:transparent;color:var(--dsw-alias-label-primary,#111);text-align:center}.sm-bulkDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-bulkDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}.sm-bulkDialog .sm-nativeDialogDanger{background:var(--dsw-alias-state-error-primary,#d92d20);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-bulkDialog .sm-nativeDialogDanger:hover:not(:disabled){filter:brightness(.92)}.sm-bulkDialog .sm-nativeDialog select.sm-viewSelect{font-size:13px;line-height:20px;height:32px;padding:5px 26px 5px 10px}",
|
|
750
848
|
".sm-bulkDialog .sm-nativeDialog{width:100%;max-height:min(640px,calc(100vh - 32px))}",
|
|
751
849
|
".sm-bulkDialogBody{display:flex;flex-direction:column;gap:12px;min-height:0}",
|
|
752
850
|
".sm-bulkDialogSummary{font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#111)}",
|
|
753
|
-
".sm-bulkDialogWarn{display:flex;align-items:flex-start;gap:8px;color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px;background:color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 8%,transparent);border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 25%,transparent);border-radius:8px;padding:8px 10px}",
|
|
851
|
+
".sm-bulkDialogWarn{display:flex;align-items:flex-start;gap:8px;color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px;background:color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 8%,transparent);border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 25%,transparent);border-radius:8px;padding:8px 10px;white-space:pre-line}",
|
|
754
852
|
".sm-bulkSessionList{display:flex;flex-direction:column;gap:4px;max-height:200px;overflow:auto;border:1px solid var(--dsw-alias-border-l2,#eee);border-radius:8px;padding:6px}",
|
|
755
853
|
".sm-bulkSessionItem{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary,#666);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}",
|
|
756
854
|
".sm-bulkProgressBar{position:relative;height:8px;background:var(--dsw-alias-bg-skeleton,#0000000a);border-radius:4px;overflow:hidden}",
|
|
@@ -772,6 +870,28 @@ function isTopmostDialog(z) {
|
|
|
772
870
|
".sm-overlayLayer{position:fixed;inset:0;pointer-events:none}",
|
|
773
871
|
".sm-overlayLayer>*{pointer-events:auto}",
|
|
774
872
|
".sm-overlayBackdrop{position:fixed;inset:0;background:transparent;pointer-events:auto}",
|
|
873
|
+
".sm-panelNav{display:inline-flex;align-items:center;background:var(--dsw-alias-bg-layer-2,rgba(128,128,128,0.12));border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;padding:2px;gap:2px;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:0}",
|
|
874
|
+
".sm-panelNavTab{border:0;background:transparent;color:var(--dsw-alias-label-secondary,#666);font-size:13px;line-height:20px;font-weight:500;padding:2px 14px;border-radius:6px;cursor:pointer;transition:all .15s ease;white-space:nowrap;outline:none}",
|
|
875
|
+
".sm-panelNavTab:hover:not(:disabled){color:var(--dsw-alias-label-primary,#111)}",
|
|
876
|
+
".sm-panelNavTab.sm-on{background:var(--dsw-alias-bg-layer-1,#fff);color:var(--dsw-alias-label-primary,#111);box-shadow:0 1px 3px rgba(0,0,0,0.12),0 1px 2px rgba(0,0,0,0.06);font-weight:600}",
|
|
877
|
+
".sm-switch{position:relative;width:38px;height:22px;flex:0 0 38px;min-width:38px;min-height:22px;max-width:38px;max-height:22px;padding:0;border-radius:11px;border:1px solid var(--dsw-alias-border-l2,#ddd);background:var(--dsw-alias-bg-layer-2,rgba(128,128,128,0.25));cursor:pointer;transition:background .2s cubic-bezier(0.4,0,0.2,1),border-color .2s cubic-bezier(0.4,0,0.2,1);box-sizing:border-box;display:inline-flex;align-items:center;overflow:hidden}",
|
|
878
|
+
".sm-switch:hover:not(:disabled){border-color:var(--dsw-alias-border-l1,#bbb)}",
|
|
879
|
+
".sm-switch.sm-switchChecked{background:var(--dsw-alias-state-business-primary,#356ae6);border-color:var(--dsw-alias-state-business-primary,#356ae6)}",
|
|
880
|
+
".sm-switch:disabled{opacity:0.4;cursor:not-allowed}",
|
|
881
|
+
".sm-switchThumb{position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--dsw-alias-switch-thumb,#ffffff);transition:left 0.2s cubic-bezier(0.4,0,0.2,1);box-shadow:0 1px 3px rgba(0,0,0,0.22);display:flex;align-items:center;justify-content:center}",
|
|
882
|
+
".sm-switchChecked .sm-switchThumb{left:18px}",
|
|
883
|
+
".sm-switchSpinner{width:10px;height:10px;border:1.5px solid transparent;border-top-color:var(--dsw-alias-state-business-primary,#356ae6);border-radius:50%;animation:sm-spin 0.7s linear infinite}",
|
|
884
|
+
".sm-rowArchived{opacity:0.72}",
|
|
885
|
+
".sm-workspaceRowActions{display:flex;align-items:center;justify-content:flex-end;flex:0 0 44px;min-width:44px;max-width:44px}",
|
|
886
|
+
".sm-workspaceRow .sm-rowMeta{display:block!important}",
|
|
887
|
+
".sm-wsFilters{display:flex;flex-wrap:wrap;align-items:center;gap:6px;width:100%;min-width:0;box-sizing:border-box}",
|
|
888
|
+
".sm-wsFilters .sm-markFiltersGroup{display:flex;flex-wrap:wrap;align-items:center;gap:6px}",
|
|
889
|
+
".sm-wsFilters .sm-markFiltersSpacer{flex:1 1 auto;min-width:8px}",
|
|
890
|
+
".sm-wsFilters .sm-wsSortSelect{height:28px;min-height:28px;font-size:11px;padding:3px 24px 3px 8px;line-height:18px;width:auto;min-width:120px;border-radius:8px;box-sizing:border-box;background-position:right 6px center;cursor:pointer}",
|
|
891
|
+
".sm-wsSortSelect-en{min-width:138px}",
|
|
892
|
+
".sm-wsFiltersBulk{display:flex;flex-wrap:wrap;align-items:center;gap:6px}",
|
|
893
|
+
"@media(max-width:720px){.sm-wsFilters .sm-markFiltersSpacer{display:none}.sm-wsFilters .sm-wsFiltersBulk{width:100%}}",
|
|
894
|
+
".sm-visuallyHidden{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}",
|
|
775
895
|
"@media(max-width:720px){.sm-panelSelects{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}.sm-panelDialog .sm-row{flex-wrap:wrap}.sm-panelDialog .sm-rowMain{flex-basis:100%}.sm-panelDialog .sm-rowActions{width:100%;min-width:0;flex:1 1 100%;justify-content:flex-start}}@media(max-width:540px){.sm-panelSelects{grid-template-columns:minmax(0,1fr)}}",
|
|
776
896
|
].join("");
|
|
777
897
|
|
|
@@ -1017,6 +1137,10 @@ function isTopmostDialog(z) {
|
|
|
1017
1137
|
if (zRef.current === null) {
|
|
1018
1138
|
zRef.current = nextDialogZ();
|
|
1019
1139
|
}
|
|
1140
|
+
useEffect(() => {
|
|
1141
|
+
registerDialogZ(zRef.current);
|
|
1142
|
+
return () => unregisterDialogZ(zRef.current);
|
|
1143
|
+
}, []);
|
|
1020
1144
|
const root = getOverlayRoot();
|
|
1021
1145
|
const portal = getPortalFn();
|
|
1022
1146
|
|
|
@@ -1044,6 +1168,8 @@ function isTopmostDialog(z) {
|
|
|
1044
1168
|
zIndex: -1
|
|
1045
1169
|
},
|
|
1046
1170
|
onClick: (e) => {
|
|
1171
|
+
if (e && typeof e.stopPropagation === "function") e.stopPropagation();
|
|
1172
|
+
if (e && typeof e.stopImmediatePropagation === "function") e.stopImmediatePropagation();
|
|
1047
1173
|
if (e.target === e.currentTarget && onBackdropClick) {
|
|
1048
1174
|
onBackdropClick(e);
|
|
1049
1175
|
}
|
|
@@ -1368,6 +1494,885 @@ function isTopmostDialog(z) {
|
|
|
1368
1494
|
return { sessionId, status: "success", via: "endpoint" };
|
|
1369
1495
|
}
|
|
1370
1496
|
|
|
1497
|
+
const WORKSPACE_ARCHIVE_STORAGE_KEY = "dsh-session-manager-workspace-archive-v1";
|
|
1498
|
+
const WORKSPACE_ARCHIVE_LEGACY_KEY = "dsh-workspace-hide.hidden.v2";
|
|
1499
|
+
const WORKSPACE_MODEL_MARK = "__dshSmWorkspaceModel";
|
|
1500
|
+
const WORKSPACE_CREATE_MARK = "__dshSmWorkspaceCreate";
|
|
1501
|
+
const WORKSPACE_ORIGINAL_CREATE = "__dshSmWorkspaceOrigCreate";
|
|
1502
|
+
const UI_CONNECT_MARK = "__dshSmUiConnect";
|
|
1503
|
+
const UI_ORIGINAL_CONNECT = "__dshSmUiOrigConnect";
|
|
1504
|
+
|
|
1505
|
+
const pathKey = (value) => {
|
|
1506
|
+
if (typeof value !== "string" || value === "") return "";
|
|
1507
|
+
const path = value.replace(/\\/g, "/").replace(/\/+$/, "") || "/";
|
|
1508
|
+
return /^[a-z]:(?:\/|$)/i.test(path) || path.startsWith("//") ? path.toLowerCase() : path;
|
|
1509
|
+
};
|
|
1510
|
+
|
|
1511
|
+
const workspaceArchiveStore = (() => {
|
|
1512
|
+
const archives = new Map();
|
|
1513
|
+
const busyWorkspaces = new Set();
|
|
1514
|
+
const listeners = new Set();
|
|
1515
|
+
let version = 0;
|
|
1516
|
+
let readRaw = null;
|
|
1517
|
+
let viewCache = null;
|
|
1518
|
+
let viewRaw = null;
|
|
1519
|
+
let viewVersion = -1;
|
|
1520
|
+
|
|
1521
|
+
const isId = v => typeof v === "string" && v !== "";
|
|
1522
|
+
|
|
1523
|
+
function loadLocal() {
|
|
1524
|
+
try {
|
|
1525
|
+
if (typeof localStorage === "undefined") return;
|
|
1526
|
+
const text = localStorage.getItem(WORKSPACE_ARCHIVE_STORAGE_KEY);
|
|
1527
|
+
if (text) {
|
|
1528
|
+
const parsed = JSON.parse(text);
|
|
1529
|
+
if (parsed && typeof parsed.archives === "object" && !Array.isArray(parsed.archives)) {
|
|
1530
|
+
for (const [wsId, rec] of Object.entries(parsed.archives)) {
|
|
1531
|
+
if (!isId(wsId) || !rec) continue;
|
|
1532
|
+
archives.set(wsId, {
|
|
1533
|
+
workspaceId: wsId,
|
|
1534
|
+
archived: rec.archived === true,
|
|
1535
|
+
archivedAt: typeof rec.archivedAt === "number" ? rec.archivedAt : Date.now(),
|
|
1536
|
+
sessionIds: Array.isArray(rec.sessionIds) ? rec.sessionIds.filter(isId) : [],
|
|
1537
|
+
pending: Array.isArray(rec.pending) ? rec.pending.filter(isId) : []
|
|
1538
|
+
});
|
|
1539
|
+
}
|
|
1540
|
+
return;
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
const legacy = localStorage.getItem(WORKSPACE_ARCHIVE_LEGACY_KEY);
|
|
1544
|
+
if (legacy) {
|
|
1545
|
+
const parsed = JSON.parse(legacy);
|
|
1546
|
+
if (parsed && typeof parsed.hidden === "object" && !Array.isArray(parsed.hidden)) {
|
|
1547
|
+
for (const [wsId, ids] of Object.entries(parsed.hidden)) {
|
|
1548
|
+
if (!isId(wsId)) continue;
|
|
1549
|
+
archives.set(wsId, {
|
|
1550
|
+
workspaceId: wsId,
|
|
1551
|
+
archived: true,
|
|
1552
|
+
archivedAt: Date.now(),
|
|
1553
|
+
sessionIds: Array.isArray(ids) ? ids.filter(isId) : [],
|
|
1554
|
+
pending: []
|
|
1555
|
+
});
|
|
1556
|
+
}
|
|
1557
|
+
saveLocal();
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
} catch (_) {}
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
function saveLocal() {
|
|
1564
|
+
try {
|
|
1565
|
+
if (typeof localStorage === "undefined") return;
|
|
1566
|
+
const obj = {};
|
|
1567
|
+
for (const [wsId, rec] of archives) {
|
|
1568
|
+
if (rec.archived === true || (Array.isArray(rec.pending) && rec.pending.length > 0) || (Array.isArray(rec.sessionIds) && rec.sessionIds.length > 0)) {
|
|
1569
|
+
obj[wsId] = {
|
|
1570
|
+
workspaceId: wsId,
|
|
1571
|
+
archived: rec.archived === true,
|
|
1572
|
+
archivedAt: rec.archivedAt,
|
|
1573
|
+
sessionIds: rec.sessionIds,
|
|
1574
|
+
pending: rec.pending
|
|
1575
|
+
};
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
localStorage.setItem(WORKSPACE_ARCHIVE_STORAGE_KEY, JSON.stringify({ version: 1, archives: obj }));
|
|
1579
|
+
} catch (_) {}
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
const EMPTY_WORKSPACES_SNAPSHOT = Object.freeze({ items: Object.freeze([]) });
|
|
1583
|
+
let snapshotCache = { archives, version, busyWorkspaces };
|
|
1584
|
+
|
|
1585
|
+
loadLocal();
|
|
1586
|
+
|
|
1587
|
+
function notify() {
|
|
1588
|
+
version += 1;
|
|
1589
|
+
snapshotCache = { archives, version, busyWorkspaces };
|
|
1590
|
+
viewCache = null;
|
|
1591
|
+
viewRaw = null;
|
|
1592
|
+
viewVersion = -1;
|
|
1593
|
+
for (const listener of [...listeners]) {
|
|
1594
|
+
try { listener(); } catch (_) {}
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
function rawSnapshot() {
|
|
1599
|
+
if (typeof readRaw === "function") {
|
|
1600
|
+
try { return readRaw() ?? EMPTY_WORKSPACES_SNAPSHOT; } catch (_) {}
|
|
1601
|
+
}
|
|
1602
|
+
return EMPTY_WORKSPACES_SNAPSHOT;
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
function getViewSnapshot() {
|
|
1606
|
+
const raw = rawSnapshot();
|
|
1607
|
+
if (viewCache !== null && viewRaw === raw && viewVersion === version) {
|
|
1608
|
+
return viewCache;
|
|
1609
|
+
}
|
|
1610
|
+
viewRaw = raw;
|
|
1611
|
+
viewVersion = version;
|
|
1612
|
+
|
|
1613
|
+
const items = Array.isArray(raw?.items) ? raw.items : [];
|
|
1614
|
+
const baseArchived = Array.isArray(raw?.archivedSessionIds) ? raw.archivedSessionIds : [];
|
|
1615
|
+
|
|
1616
|
+
const hasArchived = [...archives.values()].some(r => r.archived === true);
|
|
1617
|
+
if (!hasArchived) {
|
|
1618
|
+
viewCache = raw;
|
|
1619
|
+
return viewCache;
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1622
|
+
const visible = items.filter(item => {
|
|
1623
|
+
const rec = archives.get(item.workspaceId || item.id);
|
|
1624
|
+
return !rec || rec.archived !== true;
|
|
1625
|
+
});
|
|
1626
|
+
|
|
1627
|
+
const archivedSet = new Set(baseArchived);
|
|
1628
|
+
let changed = false;
|
|
1629
|
+
|
|
1630
|
+
for (const item of items) {
|
|
1631
|
+
const wsId = item.workspaceId || item.id;
|
|
1632
|
+
const rec = archives.get(wsId);
|
|
1633
|
+
if (rec && rec.archived === true) {
|
|
1634
|
+
const sids = Array.isArray(item.sessionIds) ? item.sessionIds : [];
|
|
1635
|
+
for (const sid of sids) {
|
|
1636
|
+
if (!archivedSet.has(sid)) {
|
|
1637
|
+
archivedSet.add(sid);
|
|
1638
|
+
changed = true;
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
for (const rec of archives.values()) {
|
|
1644
|
+
if (rec.archived === true && Array.isArray(rec.sessionIds)) {
|
|
1645
|
+
for (const sid of rec.sessionIds) {
|
|
1646
|
+
if (!archivedSet.has(sid)) {
|
|
1647
|
+
archivedSet.add(sid);
|
|
1648
|
+
changed = true;
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
const finalArchived = changed ? [...archivedSet] : baseArchived;
|
|
1655
|
+
viewCache = (visible.length === items.length && finalArchived === baseArchived)
|
|
1656
|
+
? raw
|
|
1657
|
+
: { ...raw, items: visible, archivedSessionIds: finalArchived };
|
|
1658
|
+
return viewCache;
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
function revealWorkspace(wsId, options = {}) {
|
|
1662
|
+
if (!isId(wsId)) return null;
|
|
1663
|
+
const existing = archives.get(wsId);
|
|
1664
|
+
if (!existing || existing.archived !== true) return null;
|
|
1665
|
+
const record = {
|
|
1666
|
+
...existing,
|
|
1667
|
+
workspaceId: wsId,
|
|
1668
|
+
archived: false,
|
|
1669
|
+
sessionIds: Array.isArray(existing.sessionIds) ? [...existing.sessionIds] : [],
|
|
1670
|
+
pending: Array.isArray(existing.pending) ? [...existing.pending] : []
|
|
1671
|
+
};
|
|
1672
|
+
archives.set(wsId, record);
|
|
1673
|
+
saveLocal();
|
|
1674
|
+
notify();
|
|
1675
|
+
try {
|
|
1676
|
+
callApi("/workspace-unarchive", { workspaceId: wsId, retainSessionIds: true }).catch(() => {});
|
|
1677
|
+
} catch (_) {}
|
|
1678
|
+
if (options && options.silent === false) {
|
|
1679
|
+
const msg = smTranslate("notice.workspaceReAdded");
|
|
1680
|
+
showNotice(msg);
|
|
1681
|
+
}
|
|
1682
|
+
return record;
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
function installWorkspaceCreate(workspacesService) {
|
|
1686
|
+
if (!workspacesService || typeof workspacesService.create !== "function") return null;
|
|
1687
|
+
|
|
1688
|
+
let originalCreate = workspacesService[WORKSPACE_ORIGINAL_CREATE] || workspacesService.create;
|
|
1689
|
+
while (originalCreate && (originalCreate.__dshSmWrapper || originalCreate[WORKSPACE_CREATE_MARK])) {
|
|
1690
|
+
if (originalCreate.__dshSmUnderlying) originalCreate = originalCreate.__dshSmUnderlying;
|
|
1691
|
+
else break;
|
|
1692
|
+
}
|
|
1693
|
+
workspacesService[WORKSPACE_ORIGINAL_CREATE] = originalCreate;
|
|
1694
|
+
|
|
1695
|
+
const wrappedCreate = async function (...args) {
|
|
1696
|
+
const options = args[0];
|
|
1697
|
+
const targetPath = typeof options === "string" ? options : (options && typeof options.path === "string" ? options.path : "");
|
|
1698
|
+
let knownArchivedId = null;
|
|
1699
|
+
if (targetPath) {
|
|
1700
|
+
const raw = rawSnapshot();
|
|
1701
|
+
const items = Array.isArray(raw?.items) ? raw.items : [];
|
|
1702
|
+
const match = items.find(item => item.path && pathKey(item.path) === pathKey(targetPath));
|
|
1703
|
+
if (match) {
|
|
1704
|
+
const id = match.workspaceId || match.id;
|
|
1705
|
+
if (id && archives.get(id)?.archived === true) {
|
|
1706
|
+
knownArchivedId = id;
|
|
1707
|
+
revealWorkspace(id, { silent: false });
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1712
|
+
const res = await originalCreate.apply(this, args);
|
|
1713
|
+
|
|
1714
|
+
const createdId = typeof res === "string" ? res : (res && (res.id || res.workspaceId));
|
|
1715
|
+
const targetId = createdId || knownArchivedId;
|
|
1716
|
+
if (targetId && archives.get(targetId)?.archived === true) {
|
|
1717
|
+
revealWorkspace(targetId, { silent: false });
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
return res;
|
|
1721
|
+
};
|
|
1722
|
+
wrappedCreate.__dshSmWrapper = true;
|
|
1723
|
+
wrappedCreate.__dshSmUnderlying = originalCreate;
|
|
1724
|
+
|
|
1725
|
+
const ownCreate = Object.getOwnPropertyDescriptor(workspacesService, "create");
|
|
1726
|
+
try {
|
|
1727
|
+
workspacesService.create = wrappedCreate;
|
|
1728
|
+
Object.defineProperty(workspacesService, WORKSPACE_CREATE_MARK, { value: true, configurable: true, writable: true });
|
|
1729
|
+
} catch (err) {
|
|
1730
|
+
console.warn("[session-manager] Failed to wrap workspaces.create:", err);
|
|
1731
|
+
return null;
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
return function dispose() {
|
|
1735
|
+
try {
|
|
1736
|
+
if (workspacesService.create === wrappedCreate) {
|
|
1737
|
+
if (ownCreate !== undefined) Object.defineProperty(workspacesService, "create", ownCreate);
|
|
1738
|
+
else workspacesService.create = originalCreate;
|
|
1739
|
+
}
|
|
1740
|
+
delete workspacesService[WORKSPACE_CREATE_MARK];
|
|
1741
|
+
delete workspacesService[WORKSPACE_ORIGINAL_CREATE];
|
|
1742
|
+
} catch (_) {}
|
|
1743
|
+
};
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
function installConnectWorkspace(uiWorkspaceService) {
|
|
1747
|
+
if (!uiWorkspaceService || typeof uiWorkspaceService.connectWorkspace !== "function") return null;
|
|
1748
|
+
|
|
1749
|
+
let originalConnect = uiWorkspaceService[UI_ORIGINAL_CONNECT] || uiWorkspaceService.connectWorkspace;
|
|
1750
|
+
while (originalConnect && (originalConnect.__dshSmWrapper || originalConnect[UI_CONNECT_MARK])) {
|
|
1751
|
+
if (originalConnect.__dshSmUnderlying) originalConnect = originalConnect.__dshSmUnderlying;
|
|
1752
|
+
else break;
|
|
1753
|
+
}
|
|
1754
|
+
uiWorkspaceService[UI_ORIGINAL_CONNECT] = originalConnect;
|
|
1755
|
+
|
|
1756
|
+
const wrappedConnect = async function (workspaceId, ...rest) {
|
|
1757
|
+
if (typeof workspaceId === "string" && archives.get(workspaceId)?.archived === true) {
|
|
1758
|
+
revealWorkspace(workspaceId, { silent: true });
|
|
1759
|
+
}
|
|
1760
|
+
return await originalConnect.call(this, workspaceId, ...rest);
|
|
1761
|
+
};
|
|
1762
|
+
wrappedConnect.__dshSmWrapper = true;
|
|
1763
|
+
wrappedConnect.__dshSmUnderlying = originalConnect;
|
|
1764
|
+
|
|
1765
|
+
const ownConnect = Object.getOwnPropertyDescriptor(uiWorkspaceService, "connectWorkspace");
|
|
1766
|
+
try {
|
|
1767
|
+
uiWorkspaceService.connectWorkspace = wrappedConnect;
|
|
1768
|
+
Object.defineProperty(uiWorkspaceService, UI_CONNECT_MARK, { value: true, configurable: true, writable: true });
|
|
1769
|
+
} catch (err) {
|
|
1770
|
+
console.warn("[session-manager] Failed to wrap uiWorkspace.connectWorkspace:", err);
|
|
1771
|
+
return null;
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
return function dispose() {
|
|
1775
|
+
try {
|
|
1776
|
+
if (uiWorkspaceService.connectWorkspace === wrappedConnect) {
|
|
1777
|
+
if (ownConnect !== undefined) Object.defineProperty(uiWorkspaceService, "connectWorkspace", ownConnect);
|
|
1778
|
+
else uiWorkspaceService.connectWorkspace = originalConnect;
|
|
1779
|
+
}
|
|
1780
|
+
delete uiWorkspaceService[UI_CONNECT_MARK];
|
|
1781
|
+
delete uiWorkspaceService[UI_ORIGINAL_CONNECT];
|
|
1782
|
+
} catch (_) {}
|
|
1783
|
+
};
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1786
|
+
return {
|
|
1787
|
+
getSnapshot: () => snapshotCache,
|
|
1788
|
+
getVersion: () => version,
|
|
1789
|
+
subscribe(listener) {
|
|
1790
|
+
listeners.add(listener);
|
|
1791
|
+
return () => listeners.delete(listener);
|
|
1792
|
+
},
|
|
1793
|
+
isArchived(wsId) {
|
|
1794
|
+
const rec = archives.get(wsId);
|
|
1795
|
+
return rec ? rec.archived === true : false;
|
|
1796
|
+
},
|
|
1797
|
+
isBusy(wsId) {
|
|
1798
|
+
return busyWorkspaces.has(wsId);
|
|
1799
|
+
},
|
|
1800
|
+
getRecord(wsId) {
|
|
1801
|
+
return archives.get(wsId) || null;
|
|
1802
|
+
},
|
|
1803
|
+
getAllRecords() {
|
|
1804
|
+
return archives;
|
|
1805
|
+
},
|
|
1806
|
+
rawSnapshot,
|
|
1807
|
+
getViewSnapshot,
|
|
1808
|
+
setReadRaw(fn) {
|
|
1809
|
+
readRaw = fn;
|
|
1810
|
+
},
|
|
1811
|
+
notify,
|
|
1812
|
+
syncFromHost(hostArchives) {
|
|
1813
|
+
if (!hostArchives || typeof hostArchives !== "object" || Array.isArray(hostArchives)) return;
|
|
1814
|
+
let changed = false;
|
|
1815
|
+
for (const [wsId, rec] of Object.entries(hostArchives)) {
|
|
1816
|
+
if (!isId(wsId) || !rec) continue;
|
|
1817
|
+
const existing = archives.get(wsId);
|
|
1818
|
+
if (!existing || existing.archived !== (rec.archived === true) || existing.sessionIds?.length !== (rec.sessionIds || []).length) {
|
|
1819
|
+
archives.set(wsId, {
|
|
1820
|
+
workspaceId: wsId,
|
|
1821
|
+
archived: rec.archived === true,
|
|
1822
|
+
archivedAt: typeof rec.archivedAt === "number" ? rec.archivedAt : Date.now(),
|
|
1823
|
+
sessionIds: Array.isArray(rec.sessionIds) ? rec.sessionIds.filter(isId) : [],
|
|
1824
|
+
pending: Array.isArray(rec.pending) ? rec.pending.filter(isId) : []
|
|
1825
|
+
});
|
|
1826
|
+
changed = true;
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
if (changed) {
|
|
1830
|
+
saveLocal();
|
|
1831
|
+
notify();
|
|
1832
|
+
}
|
|
1833
|
+
},
|
|
1834
|
+
markBusy(wsId, busy) {
|
|
1835
|
+
if (busy) busyWorkspaces.add(wsId);
|
|
1836
|
+
else busyWorkspaces.delete(wsId);
|
|
1837
|
+
notify();
|
|
1838
|
+
},
|
|
1839
|
+
saveArchiveRecord(wsId, record) {
|
|
1840
|
+
archives.set(wsId, record);
|
|
1841
|
+
saveLocal();
|
|
1842
|
+
notify();
|
|
1843
|
+
},
|
|
1844
|
+
removeArchiveRecord(wsId) {
|
|
1845
|
+
archives.delete(wsId);
|
|
1846
|
+
saveLocal();
|
|
1847
|
+
notify();
|
|
1848
|
+
},
|
|
1849
|
+
revealWorkspace,
|
|
1850
|
+
installWorkspaceCreate,
|
|
1851
|
+
installConnectWorkspace,
|
|
1852
|
+
installWorkspaceModel(model) {
|
|
1853
|
+
if (!model || model[WORKSPACE_MODEL_MARK] === true) return null;
|
|
1854
|
+
const originalGetSnapshot = model.getSnapshot;
|
|
1855
|
+
const originalSubscribe = model.subscribe;
|
|
1856
|
+
if (typeof originalGetSnapshot !== "function" || typeof originalSubscribe !== "function") return null;
|
|
1857
|
+
|
|
1858
|
+
readRaw = () => {
|
|
1859
|
+
try { return originalGetSnapshot.call(model); }
|
|
1860
|
+
catch (err) { console.warn("[session-manager] Failed to read raw workspaces snapshot:", err); return { items: [] }; }
|
|
1861
|
+
};
|
|
1862
|
+
|
|
1863
|
+
const wrappedGetSnapshot = function () {
|
|
1864
|
+
return getViewSnapshot();
|
|
1865
|
+
};
|
|
1866
|
+
const wrappedSubscribe = function (listener) {
|
|
1867
|
+
const off = originalSubscribe.call(model, listener);
|
|
1868
|
+
listeners.add(listener);
|
|
1869
|
+
return () => {
|
|
1870
|
+
listeners.delete(listener);
|
|
1871
|
+
if (typeof off === "function") off();
|
|
1872
|
+
};
|
|
1873
|
+
};
|
|
1874
|
+
|
|
1875
|
+
const ownGetSnapshot = Object.getOwnPropertyDescriptor(model, "getSnapshot");
|
|
1876
|
+
const ownSubscribe = Object.getOwnPropertyDescriptor(model, "subscribe");
|
|
1877
|
+
|
|
1878
|
+
try {
|
|
1879
|
+
model.getSnapshot = wrappedGetSnapshot;
|
|
1880
|
+
model.subscribe = wrappedSubscribe;
|
|
1881
|
+
Object.defineProperty(model, WORKSPACE_MODEL_MARK, { value: true, configurable: true });
|
|
1882
|
+
} catch (err) {
|
|
1883
|
+
console.warn("[session-manager] Failed to wrap workspaces.list:", err);
|
|
1884
|
+
return null;
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1887
|
+
return function dispose() {
|
|
1888
|
+
try {
|
|
1889
|
+
if (model.getSnapshot === wrappedGetSnapshot) {
|
|
1890
|
+
if (ownGetSnapshot !== undefined) Object.defineProperty(model, "getSnapshot", ownGetSnapshot);
|
|
1891
|
+
else delete model.getSnapshot;
|
|
1892
|
+
}
|
|
1893
|
+
if (model.subscribe === wrappedSubscribe) {
|
|
1894
|
+
if (ownSubscribe !== undefined) Object.defineProperty(model, "subscribe", ownSubscribe);
|
|
1895
|
+
else delete model.subscribe;
|
|
1896
|
+
}
|
|
1897
|
+
if (model[WORKSPACE_MODEL_MARK] === true) delete model[WORKSPACE_MODEL_MARK];
|
|
1898
|
+
} catch (_) {}
|
|
1899
|
+
listeners.clear();
|
|
1900
|
+
viewCache = null;
|
|
1901
|
+
viewRaw = null;
|
|
1902
|
+
viewVersion = -1;
|
|
1903
|
+
};
|
|
1904
|
+
}
|
|
1905
|
+
};
|
|
1906
|
+
})();
|
|
1907
|
+
|
|
1908
|
+
if (typeof window !== "undefined") {
|
|
1909
|
+
window.revealWorkspace = (id, opts) => workspaceArchiveStore.revealWorkspace(id, opts);
|
|
1910
|
+
}
|
|
1911
|
+
if (typeof globalThis !== "undefined") {
|
|
1912
|
+
globalThis.revealWorkspace = (id, opts) => workspaceArchiveStore.revealWorkspace(id, opts);
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
const SM_SELECT_SELECTOR = ".sm-viewSelect, .sm-settingsSelect, .sm-wsSortSelect, .sm-prioritySelectInline, .sm-panelDialog select, .sm-nativeDialog select, .sm-settingsCard select";
|
|
1916
|
+
|
|
1917
|
+
let activeCustomSelect = null;
|
|
1918
|
+
let activeCustomMenu = null;
|
|
1919
|
+
|
|
1920
|
+
function closeCustomSelect() {
|
|
1921
|
+
if (activeCustomMenu) {
|
|
1922
|
+
try { activeCustomMenu.remove(); } catch (_) {}
|
|
1923
|
+
activeCustomMenu = null;
|
|
1924
|
+
}
|
|
1925
|
+
if (typeof document !== "undefined") {
|
|
1926
|
+
try {
|
|
1927
|
+
const oldMenus = document.querySelectorAll(".sm-customSelectMenu");
|
|
1928
|
+
for (let i = 0; i < oldMenus.length; i++) {
|
|
1929
|
+
try { oldMenus[i].remove(); } catch (_) {}
|
|
1930
|
+
}
|
|
1931
|
+
} catch (_) {}
|
|
1932
|
+
}
|
|
1933
|
+
if (activeCustomSelect) {
|
|
1934
|
+
try { activeCustomSelect.classList.remove("sm-selectExpanded"); } catch (_) {}
|
|
1935
|
+
activeCustomSelect = null;
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1939
|
+
function applyCustomSelection(select, val) {
|
|
1940
|
+
closeCustomSelect();
|
|
1941
|
+
if (!select) return;
|
|
1942
|
+
if (select.value !== val) {
|
|
1943
|
+
try {
|
|
1944
|
+
const descriptor = Object.getOwnPropertyDescriptor(window.HTMLSelectElement?.prototype || {}, "value");
|
|
1945
|
+
if (descriptor && descriptor.set) {
|
|
1946
|
+
descriptor.set.call(select, val);
|
|
1947
|
+
} else {
|
|
1948
|
+
select.value = val;
|
|
1949
|
+
}
|
|
1950
|
+
} catch (_) {
|
|
1951
|
+
select.value = val;
|
|
1952
|
+
}
|
|
1953
|
+
try {
|
|
1954
|
+
const Evt = typeof Event !== "undefined" ? Event : (typeof window !== "undefined" ? window.Event : null);
|
|
1955
|
+
if (Evt) {
|
|
1956
|
+
select.dispatchEvent(new Evt("input", { bubbles: true }));
|
|
1957
|
+
select.dispatchEvent(new Evt("change", { bubbles: true }));
|
|
1958
|
+
} else if (typeof select.dispatchEvent === "function") {
|
|
1959
|
+
select.dispatchEvent({ type: "input", bubbles: true });
|
|
1960
|
+
select.dispatchEvent({ type: "change", bubbles: true });
|
|
1961
|
+
}
|
|
1962
|
+
} catch (_) {
|
|
1963
|
+
try {
|
|
1964
|
+
select.dispatchEvent({ type: "input", bubbles: true });
|
|
1965
|
+
select.dispatchEvent({ type: "change", bubbles: true });
|
|
1966
|
+
} catch (_) {}
|
|
1967
|
+
}
|
|
1968
|
+
try {
|
|
1969
|
+
const key = Object.keys(select).find(k => k.startsWith("__reactProps") || k.startsWith("__reactEventHandlers"));
|
|
1970
|
+
if (key && typeof select[key]?.onChange === "function") {
|
|
1971
|
+
select[key].onChange({ target: select, currentTarget: select });
|
|
1972
|
+
}
|
|
1973
|
+
} catch (_) {}
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
function openCustomSelect(select) {
|
|
1978
|
+
if (!select || select.disabled) return;
|
|
1979
|
+
if (activeCustomSelect === select && activeCustomMenu) {
|
|
1980
|
+
closeCustomSelect();
|
|
1981
|
+
return;
|
|
1982
|
+
}
|
|
1983
|
+
closeCustomSelect();
|
|
1984
|
+
|
|
1985
|
+
const options = Array.from(select.options || []);
|
|
1986
|
+
if (options.length === 0) return;
|
|
1987
|
+
|
|
1988
|
+
const doc = select.ownerDocument || (typeof document !== "undefined" ? document : null);
|
|
1989
|
+
if (!doc || !doc.body) return;
|
|
1990
|
+
|
|
1991
|
+
activeCustomSelect = select;
|
|
1992
|
+
select.classList.add("sm-selectExpanded");
|
|
1993
|
+
|
|
1994
|
+
const menu = doc.createElement("div");
|
|
1995
|
+
menu.className = "sm-customSelectMenu";
|
|
1996
|
+
menu.setAttribute("role", "listbox");
|
|
1997
|
+
const ariaLabel = select.getAttribute("aria-label");
|
|
1998
|
+
if (ariaLabel) menu.setAttribute("aria-label", ariaLabel);
|
|
1999
|
+
|
|
2000
|
+
try {
|
|
2001
|
+
const theme = doc.documentElement?.getAttribute?.("data-sm-theme") || (doc.body?.getAttribute?.("data-ds-dark-theme") === "true" ? "dark" : null);
|
|
2002
|
+
if (theme && typeof menu.setAttribute === "function") menu.setAttribute("data-sm-theme", theme);
|
|
2003
|
+
const cs = typeof window !== "undefined" && typeof window.getComputedStyle === "function" ? window.getComputedStyle(select) : null;
|
|
2004
|
+
if (cs) {
|
|
2005
|
+
if (cs.colorScheme) menu.style.colorScheme = cs.colorScheme;
|
|
2006
|
+
if (cs.fontFamily) menu.style.fontFamily = cs.fontFamily;
|
|
2007
|
+
}
|
|
2008
|
+
} catch (_) {}
|
|
2009
|
+
|
|
2010
|
+
options.forEach((opt) => {
|
|
2011
|
+
const item = doc.createElement("div");
|
|
2012
|
+
const isSelected = opt.value === select.value || opt.selected;
|
|
2013
|
+
item.className = "sm-customSelectOption" +
|
|
2014
|
+
(isSelected ? " sm-customSelectOptionSelected" : "") +
|
|
2015
|
+
(opt.disabled ? " sm-customSelectOptionDisabled" : "");
|
|
2016
|
+
item.setAttribute("role", "option");
|
|
2017
|
+
item.setAttribute("aria-selected", isSelected ? "true" : "false");
|
|
2018
|
+
item.title = opt.title || opt.text || opt.label || opt.value || "";
|
|
2019
|
+
|
|
2020
|
+
const labelSpan = doc.createElement("span");
|
|
2021
|
+
labelSpan.className = "sm-customSelectOptionLabel";
|
|
2022
|
+
labelSpan.textContent = opt.text || opt.label || opt.value;
|
|
2023
|
+
if (typeof item.appendChild === "function") {
|
|
2024
|
+
item.appendChild(labelSpan);
|
|
2025
|
+
} else if (item.children && Array.isArray(item.children)) {
|
|
2026
|
+
item.children.push(labelSpan);
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
if (isSelected) {
|
|
2030
|
+
const checkSpan = doc.createElement("span");
|
|
2031
|
+
checkSpan.className = "sm-customSelectOptionCheck";
|
|
2032
|
+
checkSpan.textContent = "✓";
|
|
2033
|
+
if (typeof item.appendChild === "function") {
|
|
2034
|
+
item.appendChild(checkSpan);
|
|
2035
|
+
} else if (item.children && Array.isArray(item.children)) {
|
|
2036
|
+
item.children.push(checkSpan);
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
|
|
2040
|
+
const handleOptClick = (e) => {
|
|
2041
|
+
if (e && e.preventDefault) e.preventDefault();
|
|
2042
|
+
if (e && e.stopPropagation) e.stopPropagation();
|
|
2043
|
+
if (opt.disabled) return;
|
|
2044
|
+
applyCustomSelection(select, opt.value);
|
|
2045
|
+
};
|
|
2046
|
+
if (typeof item.addEventListener === "function") {
|
|
2047
|
+
item.addEventListener("mousedown", handleOptClick);
|
|
2048
|
+
} else {
|
|
2049
|
+
item.onmousedown = handleOptClick;
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
if (typeof menu.appendChild === "function") {
|
|
2053
|
+
menu.appendChild(item);
|
|
2054
|
+
} else if (menu.children && Array.isArray(menu.children)) {
|
|
2055
|
+
menu.children.push(item);
|
|
2056
|
+
}
|
|
2057
|
+
});
|
|
2058
|
+
|
|
2059
|
+
if (typeof doc.body?.appendChild === "function") {
|
|
2060
|
+
doc.body.appendChild(menu);
|
|
2061
|
+
}
|
|
2062
|
+
activeCustomMenu = menu;
|
|
2063
|
+
|
|
2064
|
+
const rect = select.getBoundingClientRect();
|
|
2065
|
+
const spaceBelow = (typeof window !== "undefined" ? window.innerHeight : 800) - rect.bottom;
|
|
2066
|
+
const spaceAbove = rect.top;
|
|
2067
|
+
const estimatedHeight = Math.min(260, Math.max(36, options.length * 30 + 8));
|
|
2068
|
+
const dropUp = spaceBelow < estimatedHeight && spaceAbove > spaceBelow;
|
|
2069
|
+
|
|
2070
|
+
if (dropUp) {
|
|
2071
|
+
menu.style.bottom = ((typeof window !== "undefined" ? window.innerHeight : 800) - rect.top + 4) + "px";
|
|
2072
|
+
menu.style.top = "auto";
|
|
2073
|
+
menu.classList.add("sm-customSelectMenu-dropUp");
|
|
2074
|
+
} else {
|
|
2075
|
+
menu.style.top = (rect.bottom + 4) + "px";
|
|
2076
|
+
menu.style.bottom = "auto";
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
const selectWidth = rect.width;
|
|
2080
|
+
if (selectWidth > 0) {
|
|
2081
|
+
menu.style.width = selectWidth + "px";
|
|
2082
|
+
menu.style.minWidth = selectWidth + "px";
|
|
2083
|
+
menu.style.maxWidth = selectWidth + "px";
|
|
2084
|
+
menu.style.boxSizing = "border-box";
|
|
2085
|
+
} else {
|
|
2086
|
+
menu.style.minWidth = "120px";
|
|
2087
|
+
}
|
|
2088
|
+
const spaceRight = (typeof window !== "undefined" ? window.innerWidth : 1200) - rect.left;
|
|
2089
|
+
if (spaceRight < 220 && rect.right > 220) {
|
|
2090
|
+
menu.style.right = ((typeof window !== "undefined" ? window.innerWidth : 1200) - rect.right) + "px";
|
|
2091
|
+
menu.style.left = "auto";
|
|
2092
|
+
} else {
|
|
2093
|
+
menu.style.left = rect.left + "px";
|
|
2094
|
+
menu.style.right = "auto";
|
|
2095
|
+
}
|
|
2096
|
+
|
|
2097
|
+
const selectedEl = typeof menu.querySelector === "function" ? menu.querySelector(".sm-customSelectOptionSelected") : null;
|
|
2098
|
+
if (selectedEl && typeof selectedEl.scrollIntoView === "function") {
|
|
2099
|
+
selectedEl.scrollIntoView({ block: "nearest" });
|
|
2100
|
+
}
|
|
2101
|
+
}
|
|
2102
|
+
|
|
2103
|
+
function installCustomDropdownInterceptor() {
|
|
2104
|
+
if (typeof document === "undefined" || typeof document.addEventListener !== "function") {
|
|
2105
|
+
return () => {};
|
|
2106
|
+
}
|
|
2107
|
+
|
|
2108
|
+
if (typeof window !== "undefined" && typeof window.__dshSmDropdownInterceptorOff === "function") {
|
|
2109
|
+
try { window.__dshSmDropdownInterceptorOff(); } catch (_) {}
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
const onMouseDown = (e) => {
|
|
2113
|
+
if (activeCustomMenu && activeCustomMenu.contains(e.target)) return;
|
|
2114
|
+
if (e.target?.closest?.("button, input, textarea, a")) return;
|
|
2115
|
+
|
|
2116
|
+
let select = null;
|
|
2117
|
+
if (e.target?.matches?.("select")) {
|
|
2118
|
+
select = e.target;
|
|
2119
|
+
} else if (e.target?.closest?.("select")) {
|
|
2120
|
+
select = e.target.closest("select");
|
|
2121
|
+
} else {
|
|
2122
|
+
const container = e.target?.closest?.(".sm-wsSortField, .sm-annotationPriority, .sm-viewField, .sm-moveSection, .sm-settingsRow, .sm-customSelectWrapper");
|
|
2123
|
+
if (container) {
|
|
2124
|
+
select = container.querySelector("select");
|
|
2125
|
+
} else {
|
|
2126
|
+
const nearest = e.target?.closest?.(SM_SELECT_SELECTOR);
|
|
2127
|
+
if (nearest && nearest.tagName === "SELECT") {
|
|
2128
|
+
select = nearest;
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
|
|
2133
|
+
if (select && select.tagName === "SELECT") {
|
|
2134
|
+
e.preventDefault();
|
|
2135
|
+
e.stopPropagation();
|
|
2136
|
+
if (select.disabled) return;
|
|
2137
|
+
try { select.focus(); } catch (_) {}
|
|
2138
|
+
openCustomSelect(select);
|
|
2139
|
+
return;
|
|
2140
|
+
}
|
|
2141
|
+
|
|
2142
|
+
if (activeCustomMenu) {
|
|
2143
|
+
closeCustomSelect();
|
|
2144
|
+
}
|
|
2145
|
+
};
|
|
2146
|
+
|
|
2147
|
+
const onClick = (e) => {
|
|
2148
|
+
if (e.target?.closest?.("button, input, textarea, a")) return;
|
|
2149
|
+
let select = null;
|
|
2150
|
+
if (e.target?.matches?.("select")) {
|
|
2151
|
+
select = e.target;
|
|
2152
|
+
} else {
|
|
2153
|
+
const container = e.target?.closest?.(".sm-wsSortField, .sm-annotationPriority, .sm-viewField, .sm-moveSection, .sm-settingsRow, .sm-customSelectWrapper");
|
|
2154
|
+
if (container) select = container.querySelector("select");
|
|
2155
|
+
}
|
|
2156
|
+
if (select && select.tagName === "SELECT") {
|
|
2157
|
+
e.preventDefault();
|
|
2158
|
+
e.stopPropagation();
|
|
2159
|
+
}
|
|
2160
|
+
};
|
|
2161
|
+
|
|
2162
|
+
const onKeyDown = (e) => {
|
|
2163
|
+
if (e.key === "Escape") {
|
|
2164
|
+
if (activeCustomMenu) {
|
|
2165
|
+
e.preventDefault();
|
|
2166
|
+
e.stopPropagation();
|
|
2167
|
+
closeCustomSelect();
|
|
2168
|
+
}
|
|
2169
|
+
return;
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2172
|
+
const focused = document.activeElement;
|
|
2173
|
+
const targetSelect = activeCustomSelect || (focused?.matches?.(SM_SELECT_SELECTOR) ? focused : null) || (focused?.closest?.(".sm-wsSortField, .sm-annotationPriority, .sm-viewField, .sm-moveSection, .sm-settingsRow")?.querySelector("select"));
|
|
2174
|
+
if (!targetSelect || targetSelect.tagName !== "SELECT") return;
|
|
2175
|
+
|
|
2176
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
2177
|
+
if (!activeCustomMenu) {
|
|
2178
|
+
e.preventDefault();
|
|
2179
|
+
e.stopPropagation();
|
|
2180
|
+
openCustomSelect(targetSelect);
|
|
2181
|
+
} else {
|
|
2182
|
+
e.preventDefault();
|
|
2183
|
+
e.stopPropagation();
|
|
2184
|
+
closeCustomSelect();
|
|
2185
|
+
}
|
|
2186
|
+
} else if (e.key === "ArrowDown" || e.key === "ArrowUp") {
|
|
2187
|
+
e.preventDefault();
|
|
2188
|
+
e.stopPropagation();
|
|
2189
|
+
const opts = Array.from(targetSelect.options || []).filter(o => !o.disabled);
|
|
2190
|
+
if (opts.length === 0) return;
|
|
2191
|
+
const currentIdx = opts.findIndex(o => o.value === targetSelect.value);
|
|
2192
|
+
const step = e.key === "ArrowDown" ? 1 : -1;
|
|
2193
|
+
const nextIdx = (currentIdx + step + opts.length) % opts.length;
|
|
2194
|
+
applyCustomSelection(targetSelect, opts[nextIdx].value);
|
|
2195
|
+
openCustomSelect(targetSelect);
|
|
2196
|
+
}
|
|
2197
|
+
};
|
|
2198
|
+
|
|
2199
|
+
const onResizeOrScroll = () => {
|
|
2200
|
+
if (activeCustomMenu) closeCustomSelect();
|
|
2201
|
+
};
|
|
2202
|
+
|
|
2203
|
+
document.addEventListener("mousedown", onMouseDown, true);
|
|
2204
|
+
document.addEventListener("click", onClick, true);
|
|
2205
|
+
document.addEventListener("keydown", onKeyDown, true);
|
|
2206
|
+
if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
|
|
2207
|
+
window.addEventListener("resize", onResizeOrScroll, { passive: true });
|
|
2208
|
+
window.addEventListener("scroll", onResizeOrScroll, { passive: true, capture: true });
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2211
|
+
const dispose = function dispose() {
|
|
2212
|
+
closeCustomSelect();
|
|
2213
|
+
document.removeEventListener("mousedown", onMouseDown, true);
|
|
2214
|
+
document.removeEventListener("click", onClick, true);
|
|
2215
|
+
document.removeEventListener("keydown", onKeyDown, true);
|
|
2216
|
+
if (typeof window !== "undefined" && typeof window.removeEventListener === "function") {
|
|
2217
|
+
window.removeEventListener("resize", onResizeOrScroll);
|
|
2218
|
+
window.removeEventListener("scroll", onResizeOrScroll, true);
|
|
2219
|
+
}
|
|
2220
|
+
if (typeof window !== "undefined" && window.__dshSmDropdownInterceptorOff === dispose) {
|
|
2221
|
+
window.__dshSmDropdownInterceptorOff = null;
|
|
2222
|
+
}
|
|
2223
|
+
};
|
|
2224
|
+
if (typeof window !== "undefined") {
|
|
2225
|
+
window.__dshSmDropdownInterceptorOff = dispose;
|
|
2226
|
+
}
|
|
2227
|
+
return dispose;
|
|
2228
|
+
}
|
|
2229
|
+
|
|
2230
|
+
async function executeArchiveWorkspace(workspaceId, { allWorkspaces, t } = {}) {
|
|
2231
|
+
if (workspaceArchiveStore.isBusy(workspaceId)) return false;
|
|
2232
|
+
const raw = workspaceArchiveStore.rawSnapshot();
|
|
2233
|
+
const rawItems = Array.isArray(raw?.items) ? raw.items : [];
|
|
2234
|
+
const rawItem = rawItems.find(w => (w.workspaceId || w.id) === workspaceId);
|
|
2235
|
+
const ws = (Array.isArray(allWorkspaces) ? allWorkspaces.find(w => w.id === workspaceId) : null) || rawItem;
|
|
2236
|
+
if (!ws) return false;
|
|
2237
|
+
|
|
2238
|
+
const hostArchivedSet = new Set(Array.isArray(raw?.archivedSessionIds) ? raw.archivedSessionIds : []);
|
|
2239
|
+
const allSessionIds = Array.isArray(ws.sessionIds) ? ws.sessionIds : [];
|
|
2240
|
+
const toArchive = allSessionIds.filter(id => !hostArchivedSet.has(id));
|
|
2241
|
+
|
|
2242
|
+
workspaceArchiveStore.markBusy(workspaceId, true);
|
|
2243
|
+
const succeeded = [];
|
|
2244
|
+
let failureError = null;
|
|
2245
|
+
|
|
2246
|
+
try {
|
|
2247
|
+
for (const sid of toArchive) {
|
|
2248
|
+
try {
|
|
2249
|
+
await runArchiveCommand("archive", sid, { stopActivity: false });
|
|
2250
|
+
succeeded.push(sid);
|
|
2251
|
+
} catch (err) {
|
|
2252
|
+
failureError = err;
|
|
2253
|
+
break;
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
|
|
2257
|
+
if (failureError) {
|
|
2258
|
+
// Rollback: unarchive whatever we archived in this run
|
|
2259
|
+
for (const sid of succeeded) {
|
|
2260
|
+
try { await runArchiveCommand("unarchive", sid); } catch (_) {}
|
|
2261
|
+
}
|
|
2262
|
+
const msg = failureError?.message || String(failureError);
|
|
2263
|
+
const alertMsg = (t ? t("workspace.archive.failed", { message: msg }) : "归档工作区失败:{message}").replace("{message}", msg);
|
|
2264
|
+
if (typeof window !== "undefined" && typeof window.alert === "function") {
|
|
2265
|
+
window.alert(alertMsg);
|
|
2266
|
+
}
|
|
2267
|
+
return false;
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
const prevRecord = workspaceArchiveStore.getRecord(workspaceId);
|
|
2271
|
+
const combinedSessionIds = Array.from(new Set([...(prevRecord?.sessionIds || []), ...succeeded]));
|
|
2272
|
+
const record = {
|
|
2273
|
+
workspaceId,
|
|
2274
|
+
archived: true,
|
|
2275
|
+
archivedAt: Date.now(),
|
|
2276
|
+
sessionIds: combinedSessionIds,
|
|
2277
|
+
pending: []
|
|
2278
|
+
};
|
|
2279
|
+
workspaceArchiveStore.saveArchiveRecord(workspaceId, record);
|
|
2280
|
+
try {
|
|
2281
|
+
await callApi("/workspace-archive", record);
|
|
2282
|
+
} catch (e) {
|
|
2283
|
+
console.warn("[session-manager] Failed to persist workspace archive to host:", e);
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2286
|
+
const currentId = activeClientCtx?.sessions?.list?.getSnapshot?.()?.current
|
|
2287
|
+
|| activeClientCtx?.uiWorkspace?.mainReference?.sessionId;
|
|
2288
|
+
if (currentId && toArchive.includes(currentId)) {
|
|
2289
|
+
try {
|
|
2290
|
+
activeClientCtx?.uiWorkspace?.clearMain?.();
|
|
2291
|
+
} catch (_) {}
|
|
2292
|
+
}
|
|
2293
|
+
|
|
2294
|
+
try { await activeClientCtx?.sessions?.refresh?.(); } catch (_) {}
|
|
2295
|
+
try { await activeClientCtx?.workspaces?.refresh?.(); } catch (_) {}
|
|
2296
|
+
return true;
|
|
2297
|
+
} finally {
|
|
2298
|
+
workspaceArchiveStore.markBusy(workspaceId, false);
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2302
|
+
async function executeUnarchiveWorkspace(workspaceId, { t } = {}) {
|
|
2303
|
+
if (workspaceArchiveStore.isBusy(workspaceId)) return false;
|
|
2304
|
+
const record = workspaceArchiveStore.getRecord(workspaceId);
|
|
2305
|
+
workspaceArchiveStore.markBusy(workspaceId, true);
|
|
2306
|
+
try {
|
|
2307
|
+
const raw = workspaceArchiveStore.rawSnapshot();
|
|
2308
|
+
const hostArchivedSet = new Set(Array.isArray(raw?.archivedSessionIds) ? raw.archivedSessionIds : []);
|
|
2309
|
+
const idsToRestore = [...(record?.sessionIds || []), ...(record?.pending || [])];
|
|
2310
|
+
const failed = [];
|
|
2311
|
+
|
|
2312
|
+
for (const sid of idsToRestore) {
|
|
2313
|
+
if (!hostArchivedSet.has(sid)) continue;
|
|
2314
|
+
try {
|
|
2315
|
+
await runArchiveCommand("unarchive", sid);
|
|
2316
|
+
} catch (err) {
|
|
2317
|
+
failed.push(sid);
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
if (failed.length > 0) {
|
|
2322
|
+
const updatedRecord = {
|
|
2323
|
+
...(record || { workspaceId }),
|
|
2324
|
+
archived: true,
|
|
2325
|
+
pending: failed
|
|
2326
|
+
};
|
|
2327
|
+
workspaceArchiveStore.saveArchiveRecord(workspaceId, updatedRecord);
|
|
2328
|
+
try {
|
|
2329
|
+
await callApi("/workspace-archive", updatedRecord);
|
|
2330
|
+
} catch (_) {}
|
|
2331
|
+
const msg = (t ? t("workspace.unarchive.failed", { message: failed.length + " 个会话恢复失败" }) : "恢复工作区失败:{message}").replace("{message}", failed.length + " 个会话恢复失败");
|
|
2332
|
+
if (typeof window !== "undefined" && typeof window.alert === "function") {
|
|
2333
|
+
window.alert(msg);
|
|
2334
|
+
}
|
|
2335
|
+
return false;
|
|
2336
|
+
}
|
|
2337
|
+
|
|
2338
|
+
workspaceArchiveStore.removeArchiveRecord(workspaceId);
|
|
2339
|
+
try {
|
|
2340
|
+
await callApi("/workspace-unarchive", { workspaceId });
|
|
2341
|
+
} catch (_) {}
|
|
2342
|
+
|
|
2343
|
+
try { await activeClientCtx?.sessions?.refresh?.(); } catch (_) {}
|
|
2344
|
+
try { await activeClientCtx?.workspaces?.refresh?.(); } catch (_) {}
|
|
2345
|
+
return true;
|
|
2346
|
+
} finally {
|
|
2347
|
+
workspaceArchiveStore.markBusy(workspaceId, false);
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
|
|
2351
|
+
function SmSwitch(props) {
|
|
2352
|
+
const checked = props.checked === true;
|
|
2353
|
+
const disabled = props.disabled === true;
|
|
2354
|
+
const loading = props.loading === true;
|
|
2355
|
+
const onChange = typeof props.onChange === "function" ? props.onChange : () => {};
|
|
2356
|
+
return h("button", {
|
|
2357
|
+
type: "button",
|
|
2358
|
+
role: "switch",
|
|
2359
|
+
className: "sm-switch" + (checked ? " sm-switchChecked" : "") + (loading ? " sm-switchLoading" : ""),
|
|
2360
|
+
"aria-checked": checked,
|
|
2361
|
+
"aria-label": props.ariaLabel,
|
|
2362
|
+
disabled: disabled || loading,
|
|
2363
|
+
onClick: (e) => {
|
|
2364
|
+
if (e && typeof e.stopPropagation === "function") e.stopPropagation();
|
|
2365
|
+
if (disabled || loading) return;
|
|
2366
|
+
if (typeof props.onClick === "function") props.onClick(e);
|
|
2367
|
+
else onChange(!checked);
|
|
2368
|
+
}
|
|
2369
|
+
},
|
|
2370
|
+
h("span", { className: "sm-switchThumb" },
|
|
2371
|
+
loading ? h("span", { className: "sm-switchSpinner" }) : null
|
|
2372
|
+
)
|
|
2373
|
+
);
|
|
2374
|
+
}
|
|
2375
|
+
|
|
1371
2376
|
const EMPTY_ANNOTATION = Object.freeze({ favorite: false, reviewLater: false, tags: Object.freeze([]), note: "", priority: 3, revision: 0 });
|
|
1372
2377
|
const validAnnotation = value => value && typeof value.favorite === "boolean" && typeof value.reviewLater === "boolean" && Array.isArray(value.tags) && value.tags.every(tag => typeof tag === "string") && typeof value.note === "string" && (value.priority === null || Number.isInteger(value.priority) && value.priority >= 1 && value.priority <= 5) && Number.isSafeInteger(value.revision) && value.revision >= 0;
|
|
1373
2378
|
const annotationOf = (state, id) => Object.hasOwn(state.entries, id) ? state.entries[id] : EMPTY_ANNOTATION;
|
|
@@ -1598,18 +2603,51 @@ function isTopmostDialog(z) {
|
|
|
1598
2603
|
].join(String.fromCharCode(10))
|
|
1599
2604
|
};
|
|
1600
2605
|
const promptFor = lang => CLIPBOARD_PROMPT_TEXT[lang] || CLIPBOARD_PROMPT_TEXT.zh;
|
|
2606
|
+
function isClickInsideDialog(e, dialogRef, layerRef) {
|
|
2607
|
+
if (!e || !e.target) return false;
|
|
2608
|
+
const target = e.target;
|
|
2609
|
+
if (dialogRef && dialogRef.current && typeof dialogRef.current.contains === "function" && dialogRef.current.contains(target)) {
|
|
2610
|
+
return true;
|
|
2611
|
+
}
|
|
2612
|
+
if (layerRef && layerRef.current && typeof layerRef.current.contains === "function" && layerRef.current.contains(target)) {
|
|
2613
|
+
return true;
|
|
2614
|
+
}
|
|
2615
|
+
if (typeof target.closest === "function") {
|
|
2616
|
+
if (dialogRef && dialogRef.current && target.closest(".sm-nativeDialog") === dialogRef.current) {
|
|
2617
|
+
return true;
|
|
2618
|
+
}
|
|
2619
|
+
if (layerRef && layerRef.current && target.closest(".sm-nativeDialogLayer") === layerRef.current) {
|
|
2620
|
+
return true;
|
|
2621
|
+
}
|
|
2622
|
+
}
|
|
2623
|
+
if (activeCustomMenu && typeof activeCustomMenu.contains === "function" && activeCustomMenu.contains(target)) {
|
|
2624
|
+
if (activeCustomSelect) {
|
|
2625
|
+
if (dialogRef && dialogRef.current && typeof dialogRef.current.contains === "function" && dialogRef.current.contains(activeCustomSelect)) {
|
|
2626
|
+
return true;
|
|
2627
|
+
}
|
|
2628
|
+
if (layerRef && layerRef.current && typeof layerRef.current.contains === "function" && layerRef.current.contains(activeCustomSelect)) {
|
|
2629
|
+
return true;
|
|
2630
|
+
}
|
|
2631
|
+
}
|
|
2632
|
+
}
|
|
2633
|
+
return false;
|
|
2634
|
+
}
|
|
2635
|
+
|
|
1601
2636
|
function BatchPreviewDialog(props) {
|
|
1602
2637
|
const t = typeof props.t === "function" ? props.t : (key) => key;
|
|
1603
2638
|
const open = props.open === true;
|
|
1604
2639
|
const onCancel = typeof props.onCancel === "function" ? props.onCancel : () => {};
|
|
1605
2640
|
const onExecute = typeof props.onExecute === "function" ? props.onExecute : () => {};
|
|
2641
|
+
const danger = props.danger === true;
|
|
1606
2642
|
const actionLabel = props.actionLabel || "";
|
|
1607
2643
|
const summaryAction = props.summaryAction || actionLabel;
|
|
2644
|
+
const title = props.title || (props.action === "delete" ? (props.t ? t("confirm.delete.title") : "删除会话") : t("bulk.dialog.title", { action: actionLabel }));
|
|
1608
2645
|
const sessions = Array.isArray(props.sessions) ? props.sessions : [];
|
|
1609
2646
|
const warning = typeof props.warning === "string" ? props.warning : "";
|
|
1610
2647
|
const confirmLabel = props.confirmLabel || t("bulk.dialog.execute");
|
|
1611
2648
|
const cancelLabel = props.cancelLabel || t("bulk.dialog.cancel");
|
|
1612
|
-
const
|
|
2649
|
+
const dialogRef = useRef(null);
|
|
2650
|
+
const layerRef = useRef(null);
|
|
1613
2651
|
const [expanded, setExpanded] = useState(false);
|
|
1614
2652
|
const [zIndex] = useState(() => open ? nextDialogZ() : 0);
|
|
1615
2653
|
const floatingCoords = useFloatingPosition(props.anchor, open, { placement: "bottom-end", dialogWidth: 360, dialogHeight: 320 });
|
|
@@ -1621,15 +2659,33 @@ function isTopmostDialog(z) {
|
|
|
1621
2659
|
const handler = (e) => {
|
|
1622
2660
|
if (e.key !== "Escape" || e.defaultPrevented) return;
|
|
1623
2661
|
if (!isTopmostDialog(zIndex)) return;
|
|
2662
|
+
if (props.busy) return;
|
|
1624
2663
|
e.preventDefault(); e.stopPropagation(); escStateRef.current.onCancel();
|
|
1625
2664
|
};
|
|
1626
2665
|
window.addEventListener("keydown", handler);
|
|
2666
|
+
const mountTime = Date.now();
|
|
2667
|
+
const clickHandler = (e) => {
|
|
2668
|
+
if (Date.now() - mountTime < 50) return;
|
|
2669
|
+
if (e.defaultPrevented) return;
|
|
2670
|
+
if (props.busy) return;
|
|
2671
|
+
if (!isTopmostDialog(zIndex)) return;
|
|
2672
|
+
if (isClickInsideDialog(e, dialogRef, layerRef)) return;
|
|
2673
|
+
if (e && typeof e.preventDefault === "function") e.preventDefault();
|
|
2674
|
+
if (e && typeof e.stopPropagation === "function") e.stopPropagation();
|
|
2675
|
+
if (e && typeof e.stopImmediatePropagation === "function") e.stopImmediatePropagation();
|
|
2676
|
+
escStateRef.current.onCancel();
|
|
2677
|
+
};
|
|
2678
|
+
window.addEventListener("click", clickHandler, true);
|
|
1627
2679
|
return () => {
|
|
1628
2680
|
unregisterDialogZ(zIndex);
|
|
1629
2681
|
window.removeEventListener("keydown", handler);
|
|
2682
|
+
window.removeEventListener("click", clickHandler, true);
|
|
1630
2683
|
};
|
|
1631
2684
|
}, [open, zIndex]);
|
|
1632
2685
|
if (!open) return null;
|
|
2686
|
+
const loading = props.loading === true;
|
|
2687
|
+
const hasError = Boolean(props.error);
|
|
2688
|
+
const confirmDisabled = loading || hasError;
|
|
1633
2689
|
const showExpand = sessions.length > 12;
|
|
1634
2690
|
const visible = expanded ? sessions : sessions.slice(0, 12);
|
|
1635
2691
|
const topPx = floatingCoords ? floatingCoords.top : null;
|
|
@@ -1651,9 +2707,9 @@ function isTopmostDialog(z) {
|
|
|
1651
2707
|
: {})
|
|
1652
2708
|
};
|
|
1653
2709
|
const portalOverlay = renderInOverlay;
|
|
1654
|
-
return portalOverlay(h("div", { className: "sm-nativeDialogLayer sm-bulkDialog" + (hasCoords ? " sm-bulkDialog-anchored" : ""), role: "presentation", style: layerStyle },
|
|
1655
|
-
h("section", { className: "sm-nativeDialog", style: { pointerEvents: "auto" }, role: "dialog", "aria-modal": "true", "aria-labelledby": "sm-batch-preview-title" },
|
|
1656
|
-
h("div", { className: "sm-nativeDialogHeader" }, h("h2", { id: "sm-batch-preview-title", className: "sm-nativeDialogTitle" },
|
|
2710
|
+
return portalOverlay(h("div", { ref: layerRef, className: "sm-nativeDialogLayer sm-bulkDialog" + (hasCoords ? " sm-bulkDialog-anchored" : ""), role: "presentation", style: layerStyle },
|
|
2711
|
+
h("section", { ref: dialogRef, className: "sm-nativeDialog", style: { pointerEvents: "auto" }, role: "dialog", "aria-modal": "true", "aria-labelledby": "sm-batch-preview-title" },
|
|
2712
|
+
h("div", { className: "sm-nativeDialogHeader" }, h("h2", { id: "sm-batch-preview-title", className: "sm-nativeDialogTitle" }, title)),
|
|
1657
2713
|
h("div", { className: "sm-nativeDialogBody" },
|
|
1658
2714
|
h("div", { className: "sm-bulkDialogSummary" }, t("bulk.dialog.summary", { count: sessions.length, action: actionLabel })),
|
|
1659
2715
|
warning ? h("div", { className: "sm-bulkDialogWarn" }, warning) : null,
|
|
@@ -1664,7 +2720,12 @@ function isTopmostDialog(z) {
|
|
|
1664
2720
|
),
|
|
1665
2721
|
h("div", { className: "sm-nativeDialogFooter" },
|
|
1666
2722
|
h("button", { type: "button", className: "sm-nativeDialogButton sm-nativeDialogCancel", onClick: onCancel }, cancelLabel),
|
|
1667
|
-
h("button", {
|
|
2723
|
+
h("button", {
|
|
2724
|
+
type: "button",
|
|
2725
|
+
className: "sm-nativeDialogButton" + (danger ? " sm-nativeDialogDanger" : " sm-nativeDialogConfirm"),
|
|
2726
|
+
disabled: props.busy || confirmDisabled,
|
|
2727
|
+
onClick: () => { if (!props.busy && !confirmDisabled) onExecute(); }
|
|
2728
|
+
}, confirmLabel)
|
|
1668
2729
|
)
|
|
1669
2730
|
)
|
|
1670
2731
|
));
|
|
@@ -1674,6 +2735,11 @@ function isTopmostDialog(z) {
|
|
|
1674
2735
|
const t = typeof props.t === "function" ? props.t : (key) => key;
|
|
1675
2736
|
const open = props.open === true;
|
|
1676
2737
|
const [zIndex] = useState(() => open ? nextDialogZ() : 0);
|
|
2738
|
+
useEffect(() => {
|
|
2739
|
+
if (!open) return;
|
|
2740
|
+
registerDialogZ(zIndex);
|
|
2741
|
+
return () => unregisterDialogZ(zIndex);
|
|
2742
|
+
}, [open, zIndex]);
|
|
1677
2743
|
const actionLabel = props.actionLabel || "";
|
|
1678
2744
|
const done = Number.isInteger(props.done) ? props.done : 0;
|
|
1679
2745
|
const total = Number.isInteger(props.total) ? props.total : 0;
|
|
@@ -1721,6 +2787,8 @@ function isTopmostDialog(z) {
|
|
|
1721
2787
|
function BatchResultDialog(props) {
|
|
1722
2788
|
const t = typeof props.t === "function" ? props.t : (key) => key;
|
|
1723
2789
|
const open = props.open === true;
|
|
2790
|
+
const dialogRef = useRef(null);
|
|
2791
|
+
const layerRef = useRef(null);
|
|
1724
2792
|
const [zIndex] = useState(() => open ? nextDialogZ() : 0);
|
|
1725
2793
|
const actionLabel = props.actionLabel || "";
|
|
1726
2794
|
const items = Array.isArray(props.items) ? props.items : [];
|
|
@@ -1740,9 +2808,22 @@ function isTopmostDialog(z) {
|
|
|
1740
2808
|
e.preventDefault(); e.stopPropagation(); escStateRef.current.onClose();
|
|
1741
2809
|
};
|
|
1742
2810
|
window.addEventListener("keydown", handler);
|
|
2811
|
+
const mountTime = Date.now();
|
|
2812
|
+
const clickHandler = (e) => {
|
|
2813
|
+
if (Date.now() - mountTime < 50) return;
|
|
2814
|
+
if (e.defaultPrevented) return;
|
|
2815
|
+
if (!isTopmostDialog(zIndex)) return;
|
|
2816
|
+
if (isClickInsideDialog(e, dialogRef, layerRef)) return;
|
|
2817
|
+
if (e && typeof e.preventDefault === "function") e.preventDefault();
|
|
2818
|
+
if (e && typeof e.stopPropagation === "function") e.stopPropagation();
|
|
2819
|
+
if (e && typeof e.stopImmediatePropagation === "function") e.stopImmediatePropagation();
|
|
2820
|
+
escStateRef.current.onClose();
|
|
2821
|
+
};
|
|
2822
|
+
window.addEventListener("click", clickHandler, true);
|
|
1743
2823
|
return () => {
|
|
1744
2824
|
unregisterDialogZ(zIndex);
|
|
1745
2825
|
window.removeEventListener("keydown", handler);
|
|
2826
|
+
window.removeEventListener("click", clickHandler, true);
|
|
1746
2827
|
};
|
|
1747
2828
|
}, [open, zIndex]);
|
|
1748
2829
|
if (!open) return null;
|
|
@@ -1784,8 +2865,8 @@ function isTopmostDialog(z) {
|
|
|
1784
2865
|
: {})
|
|
1785
2866
|
};
|
|
1786
2867
|
const portalOverlay = renderInOverlay;
|
|
1787
|
-
return portalOverlay(h("div", { className: "sm-nativeDialogLayer sm-bulkDialog" + (hasCoords ? " sm-bulkDialog-anchored" : ""), role: "presentation", style: layerStyle },
|
|
1788
|
-
h("section", { className: "sm-nativeDialog", style: { pointerEvents: "auto" }, role: "dialog", "aria-modal": "true", "aria-labelledby": "sm-batch-result-title" },
|
|
2868
|
+
return portalOverlay(h("div", { ref: layerRef, className: "sm-nativeDialogLayer sm-bulkDialog" + (hasCoords ? " sm-bulkDialog-anchored" : ""), role: "presentation", style: layerStyle },
|
|
2869
|
+
h("section", { ref: dialogRef, className: "sm-nativeDialog", style: { pointerEvents: "auto" }, role: "dialog", "aria-modal": "true", "aria-labelledby": "sm-batch-result-title" },
|
|
1789
2870
|
h("div", { className: "sm-nativeDialogHeader" }, h("h2", { id: "sm-batch-result-title", className: "sm-nativeDialogTitle" }, t("bulk.result.title", { action: actionLabel }))),
|
|
1790
2871
|
h("div", { className: "sm-nativeDialogBody" },
|
|
1791
2872
|
renderGroup("bulk.result.successGroup", groups.success),
|
|
@@ -1833,6 +2914,8 @@ function isTopmostDialog(z) {
|
|
|
1833
2914
|
function BulkTagInputDialog(props) {
|
|
1834
2915
|
const t = typeof props.t === "function" ? props.t : (key) => key;
|
|
1835
2916
|
const open = props.open === true;
|
|
2917
|
+
const dialogRef = useRef(null);
|
|
2918
|
+
const layerRef = useRef(null);
|
|
1836
2919
|
const [zIndex] = useState(() => open ? nextDialogZ() : 0);
|
|
1837
2920
|
const title = props.title || t("bulk.tagsAdd");
|
|
1838
2921
|
const description = props.description || "";
|
|
@@ -1854,9 +2937,22 @@ function isTopmostDialog(z) {
|
|
|
1854
2937
|
e.preventDefault(); e.stopPropagation(); escStateRef.current.onCancel();
|
|
1855
2938
|
};
|
|
1856
2939
|
window.addEventListener("keydown", handler);
|
|
2940
|
+
const mountTime = Date.now();
|
|
2941
|
+
const clickHandler = (e) => {
|
|
2942
|
+
if (Date.now() - mountTime < 50) return;
|
|
2943
|
+
if (e.defaultPrevented) return;
|
|
2944
|
+
if (!isTopmostDialog(zIndex)) return;
|
|
2945
|
+
if (isClickInsideDialog(e, dialogRef, layerRef)) return;
|
|
2946
|
+
if (e && typeof e.preventDefault === "function") e.preventDefault();
|
|
2947
|
+
if (e && typeof e.stopPropagation === "function") e.stopPropagation();
|
|
2948
|
+
if (e && typeof e.stopImmediatePropagation === "function") e.stopImmediatePropagation();
|
|
2949
|
+
escStateRef.current.onCancel();
|
|
2950
|
+
};
|
|
2951
|
+
window.addEventListener("click", clickHandler, true);
|
|
1857
2952
|
return () => {
|
|
1858
2953
|
unregisterDialogZ(zIndex);
|
|
1859
2954
|
window.removeEventListener("keydown", handler);
|
|
2955
|
+
window.removeEventListener("click", clickHandler, true);
|
|
1860
2956
|
};
|
|
1861
2957
|
}, [open, zIndex]);
|
|
1862
2958
|
if (!open) return null;
|
|
@@ -1883,8 +2979,8 @@ function isTopmostDialog(z) {
|
|
|
1883
2979
|
: {})
|
|
1884
2980
|
};
|
|
1885
2981
|
const portalOverlay = renderInOverlay;
|
|
1886
|
-
return portalOverlay(h("div", { className: "sm-nativeDialogLayer sm-bulkDialog" + (hasCoords ? " sm-bulkDialog-anchored" : ""), role: "presentation", style: layerStyle },
|
|
1887
|
-
h("section", { className: "sm-nativeDialog", style: { pointerEvents: "auto" }, role: "dialog", "aria-modal": "true", "aria-labelledby": "sm-bulk-tags-title" },
|
|
2982
|
+
return portalOverlay(h("div", { ref: layerRef, className: "sm-nativeDialogLayer sm-bulkDialog" + (hasCoords ? " sm-bulkDialog-anchored" : ""), role: "presentation", style: layerStyle },
|
|
2983
|
+
h("section", { ref: dialogRef, className: "sm-nativeDialog", style: { pointerEvents: "auto" }, role: "dialog", "aria-modal": "true", "aria-labelledby": "sm-bulk-tags-title" },
|
|
1888
2984
|
h("div", { className: "sm-nativeDialogHeader" }, h("h2", { id: "sm-bulk-tags-title", className: "sm-nativeDialogTitle" }, title)),
|
|
1889
2985
|
h("div", { className: "sm-nativeDialogBody" },
|
|
1890
2986
|
description ? h("div", { className: "sm-bulkDialogSummary" }, description) : null,
|
|
@@ -1901,6 +2997,8 @@ function isTopmostDialog(z) {
|
|
|
1901
2997
|
function BulkChoiceDialog(props) {
|
|
1902
2998
|
const t = typeof props.t === "function" ? props.t : (key) => key;
|
|
1903
2999
|
const open = props.open === true;
|
|
3000
|
+
const dialogRef = useRef(null);
|
|
3001
|
+
const layerRef = useRef(null);
|
|
1904
3002
|
const [zIndex] = useState(() => open ? nextDialogZ() : 0);
|
|
1905
3003
|
const title = props.title || "";
|
|
1906
3004
|
const description = props.description || "";
|
|
@@ -1922,9 +3020,22 @@ function isTopmostDialog(z) {
|
|
|
1922
3020
|
e.preventDefault(); e.stopPropagation(); escStateRef.current.onCancel();
|
|
1923
3021
|
};
|
|
1924
3022
|
window.addEventListener("keydown", handler);
|
|
3023
|
+
const mountTime = Date.now();
|
|
3024
|
+
const clickHandler = (e) => {
|
|
3025
|
+
if (Date.now() - mountTime < 50) return;
|
|
3026
|
+
if (e.defaultPrevented) return;
|
|
3027
|
+
if (!isTopmostDialog(zIndex)) return;
|
|
3028
|
+
if (isClickInsideDialog(e, dialogRef, layerRef)) return;
|
|
3029
|
+
if (e && typeof e.preventDefault === "function") e.preventDefault();
|
|
3030
|
+
if (e && typeof e.stopPropagation === "function") e.stopPropagation();
|
|
3031
|
+
if (e && typeof e.stopImmediatePropagation === "function") e.stopImmediatePropagation();
|
|
3032
|
+
escStateRef.current.onCancel();
|
|
3033
|
+
};
|
|
3034
|
+
window.addEventListener("click", clickHandler, true);
|
|
1925
3035
|
return () => {
|
|
1926
3036
|
unregisterDialogZ(zIndex);
|
|
1927
3037
|
window.removeEventListener("keydown", handler);
|
|
3038
|
+
window.removeEventListener("click", clickHandler, true);
|
|
1928
3039
|
};
|
|
1929
3040
|
}, [open, zIndex]);
|
|
1930
3041
|
if (!open) return null;
|
|
@@ -1947,8 +3058,8 @@ function isTopmostDialog(z) {
|
|
|
1947
3058
|
: {})
|
|
1948
3059
|
};
|
|
1949
3060
|
const portalOverlay = renderInOverlay;
|
|
1950
|
-
return portalOverlay(h("div", { className: "sm-nativeDialogLayer sm-bulkDialog" + (hasCoords ? " sm-bulkDialog-anchored" : ""), role: "presentation", style: layerStyle },
|
|
1951
|
-
h("section", { className: "sm-nativeDialog", style: { pointerEvents: "auto" }, role: "dialog", "aria-modal": "true", "aria-labelledby": "sm-bulk-choice-title" },
|
|
3061
|
+
return portalOverlay(h("div", { ref: layerRef, className: "sm-nativeDialogLayer sm-bulkDialog" + (hasCoords ? " sm-bulkDialog-anchored" : ""), role: "presentation", style: layerStyle },
|
|
3062
|
+
h("section", { ref: dialogRef, className: "sm-nativeDialog", style: { pointerEvents: "auto" }, role: "dialog", "aria-modal": "true", "aria-labelledby": "sm-bulk-choice-title" },
|
|
1952
3063
|
h("div", { className: "sm-nativeDialogHeader" }, h("h2", { id: "sm-bulk-choice-title", className: "sm-nativeDialogTitle" }, title)),
|
|
1953
3064
|
h("div", { className: "sm-nativeDialogBody" },
|
|
1954
3065
|
description ? h("div", { className: "sm-bulkDialogSummary" }, description) : null,
|
|
@@ -2174,6 +3285,8 @@ function isTopmostDialog(z) {
|
|
|
2174
3285
|
const onConfirm = typeof props.onConfirm === "function" ? props.onConfirm : () => {};
|
|
2175
3286
|
const busy = props.busy === true;
|
|
2176
3287
|
const danger = props.danger === true;
|
|
3288
|
+
const dialogRef = useRef(null);
|
|
3289
|
+
const layerRef = useRef(null);
|
|
2177
3290
|
// Claim a fresh z-index so this popup sits above any earlier popup.
|
|
2178
3291
|
const [zIndex] = useState(() => open ? nextDialogZ() : 0);
|
|
2179
3292
|
const title = props.title || "";
|
|
@@ -2209,9 +3322,23 @@ function isTopmostDialog(z) {
|
|
|
2209
3322
|
if (ae && typeof ae.blur === "function" && ae !== document.body) ae.blur();
|
|
2210
3323
|
};
|
|
2211
3324
|
window.addEventListener("keydown", handler);
|
|
3325
|
+
const mountTime = Date.now();
|
|
3326
|
+
const clickHandler = (e) => {
|
|
3327
|
+
if (Date.now() - mountTime < 50) return;
|
|
3328
|
+
if (e.defaultPrevented) return;
|
|
3329
|
+
if (escStateRef.current.busy) return;
|
|
3330
|
+
if (!isTopmostDialog(effectiveZ)) return;
|
|
3331
|
+
if (isClickInsideDialog(e, dialogRef, layerRef)) return;
|
|
3332
|
+
if (e && typeof e.preventDefault === "function") e.preventDefault();
|
|
3333
|
+
if (e && typeof e.stopPropagation === "function") e.stopPropagation();
|
|
3334
|
+
if (e && typeof e.stopImmediatePropagation === "function") e.stopImmediatePropagation();
|
|
3335
|
+
escStateRef.current.onCancel();
|
|
3336
|
+
};
|
|
3337
|
+
window.addEventListener("click", clickHandler, true);
|
|
2212
3338
|
return () => {
|
|
2213
3339
|
unregisterDialogZ(effectiveZ);
|
|
2214
3340
|
window.removeEventListener("keydown", handler);
|
|
3341
|
+
window.removeEventListener("click", clickHandler, true);
|
|
2215
3342
|
};
|
|
2216
3343
|
}, [open, zIndex]);
|
|
2217
3344
|
|
|
@@ -2239,13 +3366,17 @@ function isTopmostDialog(z) {
|
|
|
2239
3366
|
: {})
|
|
2240
3367
|
};
|
|
2241
3368
|
|
|
3369
|
+
const confirmDisabled = props.confirmDisabled === true;
|
|
3370
|
+
|
|
2242
3371
|
return renderInOverlay(
|
|
2243
3372
|
h("div", {
|
|
3373
|
+
ref: layerRef,
|
|
2244
3374
|
className: "sm-nativeDialogLayer sm-confirmDialog" + (hasCoords ? " sm-confirmDialog-anchored" : ""),
|
|
2245
3375
|
style: layerStyle,
|
|
2246
3376
|
role: "presentation"
|
|
2247
3377
|
},
|
|
2248
3378
|
h("section", {
|
|
3379
|
+
ref: dialogRef,
|
|
2249
3380
|
className: "sm-nativeDialog",
|
|
2250
3381
|
style: { pointerEvents: "auto" },
|
|
2251
3382
|
role: "dialog",
|
|
@@ -2269,8 +3400,8 @@ function isTopmostDialog(z) {
|
|
|
2269
3400
|
h("button", {
|
|
2270
3401
|
type: "button",
|
|
2271
3402
|
className: "sm-nativeDialogButton" + (danger ? " sm-nativeDialogDanger" : " sm-nativeDialogConfirm"),
|
|
2272
|
-
disabled: busy,
|
|
2273
|
-
onClick: () => { if (!busy) onConfirm(); }
|
|
3403
|
+
disabled: busy || confirmDisabled,
|
|
3404
|
+
onClick: () => { if (!busy && !confirmDisabled) onConfirm(); }
|
|
2274
3405
|
}, confirmLabel)
|
|
2275
3406
|
)
|
|
2276
3407
|
)
|
|
@@ -2283,6 +3414,8 @@ function isTopmostDialog(z) {
|
|
|
2283
3414
|
const onCancel = typeof props.onCancel === "function" ? props.onCancel : () => {};
|
|
2284
3415
|
const onConfirm = typeof props.onConfirm === "function" ? props.onConfirm : () => {};
|
|
2285
3416
|
const busy = props.busy === true;
|
|
3417
|
+
const dialogRef = useRef(null);
|
|
3418
|
+
const layerRef = useRef(null);
|
|
2286
3419
|
const title = props.title || t("confirm.move.title");
|
|
2287
3420
|
const description = props.description || "";
|
|
2288
3421
|
const currentWorkspaceId = props.currentWorkspaceId || "";
|
|
@@ -2331,9 +3464,23 @@ function isTopmostDialog(z) {
|
|
|
2331
3464
|
if (ae && typeof ae.blur === "function" && ae !== document.body) ae.blur();
|
|
2332
3465
|
};
|
|
2333
3466
|
window.addEventListener("keydown", handler);
|
|
3467
|
+
const mountTime = Date.now();
|
|
3468
|
+
const clickHandler = (e) => {
|
|
3469
|
+
if (Date.now() - mountTime < 50) return;
|
|
3470
|
+
if (e.defaultPrevented) return;
|
|
3471
|
+
if (escStateRef.current.busy) return;
|
|
3472
|
+
if (!isTopmostDialog(effectiveZ)) return;
|
|
3473
|
+
if (isClickInsideDialog(e, dialogRef, layerRef)) return;
|
|
3474
|
+
if (e && typeof e.preventDefault === "function") e.preventDefault();
|
|
3475
|
+
if (e && typeof e.stopPropagation === "function") e.stopPropagation();
|
|
3476
|
+
if (e && typeof e.stopImmediatePropagation === "function") e.stopImmediatePropagation();
|
|
3477
|
+
escStateRef.current.onCancel();
|
|
3478
|
+
};
|
|
3479
|
+
window.addEventListener("click", clickHandler, true);
|
|
2334
3480
|
return () => {
|
|
2335
3481
|
unregisterDialogZ(effectiveZ);
|
|
2336
3482
|
window.removeEventListener("keydown", handler);
|
|
3483
|
+
window.removeEventListener("click", clickHandler, true);
|
|
2337
3484
|
};
|
|
2338
3485
|
}, [open, zIndex]);
|
|
2339
3486
|
if (!open) return null;
|
|
@@ -2391,12 +3538,14 @@ function isTopmostDialog(z) {
|
|
|
2391
3538
|
};
|
|
2392
3539
|
return renderInOverlay(
|
|
2393
3540
|
h("div", {
|
|
3541
|
+
ref: layerRef,
|
|
2394
3542
|
className: "sm-nativeDialogLayer sm-confirmDialog" + (hasCoords ? " sm-confirmDialog-anchored" : ""),
|
|
2395
3543
|
style: layerStyle,
|
|
2396
3544
|
role: "presentation",
|
|
2397
3545
|
onKeyDown
|
|
2398
3546
|
},
|
|
2399
3547
|
h("section", {
|
|
3548
|
+
ref: dialogRef,
|
|
2400
3549
|
className: "sm-nativeDialog",
|
|
2401
3550
|
style: { pointerEvents: "auto" },
|
|
2402
3551
|
role: "dialog",
|
|
@@ -2432,6 +3581,8 @@ function isTopmostDialog(z) {
|
|
|
2432
3581
|
const onCancel = typeof props.onCancel === "function" ? props.onCancel : () => {};
|
|
2433
3582
|
const onRun = typeof props.onRun === "function" ? props.onRun : () => {};
|
|
2434
3583
|
const busy = props.busy === true;
|
|
3584
|
+
const dialogRef = useRef(null);
|
|
3585
|
+
const layerRef = useRef(null);
|
|
2435
3586
|
const sessionId = props.sessionId || "";
|
|
2436
3587
|
const description = props.description || "";
|
|
2437
3588
|
const fallbackPreset = props.currentPreset || "";
|
|
@@ -2490,9 +3641,23 @@ function isTopmostDialog(z) {
|
|
|
2490
3641
|
if (ae && typeof ae.blur === "function" && ae !== document.body) ae.blur();
|
|
2491
3642
|
};
|
|
2492
3643
|
window.addEventListener("keydown", handler);
|
|
3644
|
+
const mountTime = Date.now();
|
|
3645
|
+
const clickHandler = (e) => {
|
|
3646
|
+
if (Date.now() - mountTime < 50) return;
|
|
3647
|
+
if (e.defaultPrevented) return;
|
|
3648
|
+
if (escStateRef.current.busy) return;
|
|
3649
|
+
if (!isTopmostDialog(effectiveZ)) return;
|
|
3650
|
+
if (isClickInsideDialog(e, dialogRef, layerRef)) return;
|
|
3651
|
+
if (e && typeof e.preventDefault === "function") e.preventDefault();
|
|
3652
|
+
if (e && typeof e.stopPropagation === "function") e.stopPropagation();
|
|
3653
|
+
if (e && typeof e.stopImmediatePropagation === "function") e.stopImmediatePropagation();
|
|
3654
|
+
escStateRef.current.onCancel();
|
|
3655
|
+
};
|
|
3656
|
+
window.addEventListener("click", clickHandler, true);
|
|
2493
3657
|
return () => {
|
|
2494
3658
|
unregisterDialogZ(effectiveZ);
|
|
2495
3659
|
window.removeEventListener("keydown", handler);
|
|
3660
|
+
window.removeEventListener("click", clickHandler, true);
|
|
2496
3661
|
};
|
|
2497
3662
|
}, [open, zIndex]);
|
|
2498
3663
|
if (!open) return null;
|
|
@@ -2549,11 +3714,13 @@ function isTopmostDialog(z) {
|
|
|
2549
3714
|
};
|
|
2550
3715
|
return renderInOverlay(
|
|
2551
3716
|
h("div", {
|
|
3717
|
+
ref: layerRef,
|
|
2552
3718
|
className: "sm-nativeDialogLayer sm-confirmDialog" + (hasCoords ? " sm-confirmDialog-anchored" : ""),
|
|
2553
3719
|
role: "presentation",
|
|
2554
3720
|
style: layerStyle
|
|
2555
3721
|
},
|
|
2556
3722
|
h("section", {
|
|
3723
|
+
ref: dialogRef,
|
|
2557
3724
|
className: "sm-nativeDialog",
|
|
2558
3725
|
style: { pointerEvents: "auto" },
|
|
2559
3726
|
role: "dialog",
|
|
@@ -2582,7 +3749,7 @@ function isTopmostDialog(z) {
|
|
|
2582
3749
|
));
|
|
2583
3750
|
}
|
|
2584
3751
|
|
|
2585
|
-
const CURRENT_VERSION = "0.
|
|
3752
|
+
const CURRENT_VERSION = "0.7.1";
|
|
2586
3753
|
|
|
2587
3754
|
function compareSemver(v1, v2) {
|
|
2588
3755
|
if (typeof v1 !== "string" || typeof v2 !== "string") return 0;
|
|
@@ -2643,7 +3810,11 @@ function isTopmostDialog(z) {
|
|
|
2643
3810
|
application: null,
|
|
2644
3811
|
dialogOpen: false,
|
|
2645
3812
|
checkedAt: null,
|
|
3813
|
+
lastAttemptAt: null,
|
|
2646
3814
|
},
|
|
3815
|
+
CHECK_INTERVAL_MS: 6 * 60 * 60 * 1000,
|
|
3816
|
+
RETRY_COOLDOWN_MS: 30 * 60 * 1000,
|
|
3817
|
+
lastFailedAt: null,
|
|
2647
3818
|
listeners: new Set(),
|
|
2648
3819
|
getSnapshot() { return this.state; },
|
|
2649
3820
|
subscribe(cb) {
|
|
@@ -2678,6 +3849,29 @@ function isTopmostDialog(z) {
|
|
|
2678
3849
|
} catch (_) {}
|
|
2679
3850
|
this._notify();
|
|
2680
3851
|
},
|
|
3852
|
+
shouldAutoCheck(now = Date.now()) {
|
|
3853
|
+
if (!this.getAutoCheck()) return false;
|
|
3854
|
+
if (this.state.status === "checking" || this.state.status === "updating") return false;
|
|
3855
|
+
if (this.state.status === "available") return false;
|
|
3856
|
+
if (this.lastFailedAt && (now - this.lastFailedAt < this.RETRY_COOLDOWN_MS)) {
|
|
3857
|
+
return false;
|
|
3858
|
+
}
|
|
3859
|
+
if (this.state.checkedAt && (now - this.state.checkedAt < this.CHECK_INTERVAL_MS)) {
|
|
3860
|
+
return false;
|
|
3861
|
+
}
|
|
3862
|
+
return true;
|
|
3863
|
+
},
|
|
3864
|
+
async maybeAutoCheck(options = {}) {
|
|
3865
|
+
const now = typeof options.now === "number" ? options.now : Date.now();
|
|
3866
|
+
if (!this.shouldAutoCheck(now)) return this.state;
|
|
3867
|
+
return this.checkForUpdate({
|
|
3868
|
+
silent: true,
|
|
3869
|
+
openOnFound: false,
|
|
3870
|
+
openDialog: false,
|
|
3871
|
+
...options,
|
|
3872
|
+
manual: false
|
|
3873
|
+
});
|
|
3874
|
+
},
|
|
2681
3875
|
// Dialog opacity preference (Issue #23). Reuses the same localStorage
|
|
2682
3876
|
// backed preference store as autoCheck / registry instead of adding a
|
|
2683
3877
|
// second storage mechanism.
|
|
@@ -2740,7 +3934,17 @@ function isTopmostDialog(z) {
|
|
|
2740
3934
|
}
|
|
2741
3935
|
this._notify();
|
|
2742
3936
|
|
|
3937
|
+
const timeoutMs = typeof options.timeoutMs === "number" ? options.timeoutMs : 10000;
|
|
3938
|
+
let timeoutTimer = null;
|
|
3939
|
+
const abortController = typeof AbortController !== "undefined" ? new AbortController() : null;
|
|
3940
|
+
|
|
2743
3941
|
try {
|
|
3942
|
+
if (abortController) {
|
|
3943
|
+
timeoutTimer = setTimeout(() => {
|
|
3944
|
+
abortController.abort(new Error("检查更新超时"));
|
|
3945
|
+
}, timeoutMs);
|
|
3946
|
+
}
|
|
3947
|
+
|
|
2744
3948
|
let res = null;
|
|
2745
3949
|
if (typeof window !== "undefined" && window.__DSH_SM_TEST_UPDATE__) {
|
|
2746
3950
|
const testOverride = window.__DSH_SM_TEST_UPDATE__;
|
|
@@ -2754,12 +3958,16 @@ function isTopmostDialog(z) {
|
|
|
2754
3958
|
} else {
|
|
2755
3959
|
const registryUrl = this.getRegistryUrl();
|
|
2756
3960
|
const registryParam = encodeURIComponent(registryUrl);
|
|
3961
|
+
const fetchOpts = abortController ? { signal: abortController.signal } : undefined;
|
|
2757
3962
|
try {
|
|
2758
|
-
res = await fetchApi("/update/check?registry=" + registryParam);
|
|
3963
|
+
res = await fetchApi("/update/check?registry=" + registryParam, fetchOpts);
|
|
2759
3964
|
} catch (fetchErr) {
|
|
3965
|
+
if (abortController?.signal?.aborted || fetchErr.name === "AbortError" || fetchErr.message?.includes("超时")) {
|
|
3966
|
+
throw new Error("检查更新超时");
|
|
3967
|
+
}
|
|
2760
3968
|
try {
|
|
2761
3969
|
const base = registryUrl.endsWith("/") ? registryUrl : registryUrl + "/";
|
|
2762
|
-
const npmRes = await fetch(base + "dsh-session-manager/latest");
|
|
3970
|
+
const npmRes = await fetch(base + "dsh-session-manager/latest", fetchOpts);
|
|
2763
3971
|
if (npmRes.ok) {
|
|
2764
3972
|
const npmData = await npmRes.json();
|
|
2765
3973
|
if (npmData && npmData.version) {
|
|
@@ -2769,7 +3977,11 @@ function isTopmostDialog(z) {
|
|
|
2769
3977
|
res = { ok: true, result: { currentVersion: cur, latestVersion: lat, hasUpdate } };
|
|
2770
3978
|
}
|
|
2771
3979
|
}
|
|
2772
|
-
} catch (_) {
|
|
3980
|
+
} catch (_) {
|
|
3981
|
+
if (abortController?.signal?.aborted || fetchErr.name === "AbortError" || fetchErr.message?.includes("超时")) {
|
|
3982
|
+
throw new Error("检查更新超时");
|
|
3983
|
+
}
|
|
3984
|
+
}
|
|
2773
3985
|
if (!res) throw fetchErr;
|
|
2774
3986
|
}
|
|
2775
3987
|
}
|
|
@@ -2785,7 +3997,10 @@ function isTopmostDialog(z) {
|
|
|
2785
3997
|
|
|
2786
3998
|
this.state.currentVersion = currentVersion;
|
|
2787
3999
|
this.state.latestVersion = latestVersion;
|
|
2788
|
-
|
|
4000
|
+
const now = Date.now();
|
|
4001
|
+
this.state.checkedAt = now;
|
|
4002
|
+
this.state.lastAttemptAt = now;
|
|
4003
|
+
this.lastFailedAt = null;
|
|
2789
4004
|
|
|
2790
4005
|
if (hasUpdate) {
|
|
2791
4006
|
this.state.status = "available";
|
|
@@ -2801,13 +4016,18 @@ function isTopmostDialog(z) {
|
|
|
2801
4016
|
this._notify();
|
|
2802
4017
|
return this.state;
|
|
2803
4018
|
} catch (err) {
|
|
4019
|
+
const now = Date.now();
|
|
2804
4020
|
this.state.status = "error";
|
|
2805
|
-
this.state.error = err.message || "检查更新失败";
|
|
4021
|
+
this.state.error = (abortController?.signal?.aborted ? "检查更新超时" : (err.message || "检查更新失败"));
|
|
4022
|
+
this.state.lastAttemptAt = now;
|
|
4023
|
+
this.lastFailedAt = now;
|
|
2806
4024
|
if (shouldOpenDialog) {
|
|
2807
4025
|
this.state.dialogOpen = true;
|
|
2808
4026
|
}
|
|
2809
4027
|
this._notify();
|
|
2810
4028
|
return this.state;
|
|
4029
|
+
} finally {
|
|
4030
|
+
if (timeoutTimer) clearTimeout(timeoutTimer);
|
|
2811
4031
|
}
|
|
2812
4032
|
},
|
|
2813
4033
|
async startUpdate(options = {}) {
|
|
@@ -2871,8 +4091,15 @@ function isTopmostDialog(z) {
|
|
|
2871
4091
|
listeners: new Set(),
|
|
2872
4092
|
getSnapshot() { return this.open; },
|
|
2873
4093
|
subscribe(cb) { this.listeners.add(cb); return () => this.listeners.delete(cb); },
|
|
2874
|
-
set(v) {
|
|
2875
|
-
|
|
4094
|
+
set(v) {
|
|
4095
|
+
if (this.open === v) return;
|
|
4096
|
+
this.open = v;
|
|
4097
|
+
if (this.open) {
|
|
4098
|
+
try { updateStore.maybeAutoCheck().catch(() => {}); } catch (_) {}
|
|
4099
|
+
}
|
|
4100
|
+
for (const fn of [...this.listeners]) fn();
|
|
4101
|
+
},
|
|
4102
|
+
toggle() { this.set(!this.open); },
|
|
2876
4103
|
// Pending action queued by the title-bar buttons (e.g. 移动至工作区).
|
|
2877
4104
|
// The SessionManagerPanel consumes this on mount so it can pre-open
|
|
2878
4105
|
// the matching inner dialog (move / delete / migrate) next to itself.
|
|
@@ -2886,13 +4113,8 @@ function isTopmostDialog(z) {
|
|
|
2886
4113
|
const lastBatchContext = { action: null, ids: [] };
|
|
2887
4114
|
|
|
2888
4115
|
const DEFAULT_SORT = "updated-desc";
|
|
2889
|
-
const SORT_ORDERS = ["updated-desc", "updated-asc", "created-desc", "created-asc", "priority"];
|
|
4116
|
+
const SORT_ORDERS = ["updated-desc", "updated-asc", "created-desc", "created-asc", "name-asc", "name-desc", "priority"];
|
|
2890
4117
|
const workspaceValue = (id) => "workspace:" + id;
|
|
2891
|
-
const pathKey = (value) => {
|
|
2892
|
-
if (typeof value !== "string" || value === "") return "";
|
|
2893
|
-
const path = value.replace(/\\/g, "/").replace(/\/+$/, "") || "/";
|
|
2894
|
-
return /^[a-z]:(?:\/|$)/i.test(path) || path.startsWith("//") ? path.toLowerCase() : path;
|
|
2895
|
-
};
|
|
2896
4118
|
const sessionTime = (value) => {
|
|
2897
4119
|
if (typeof value !== "number" && typeof value !== "string") return null;
|
|
2898
4120
|
if (typeof value === "string" && value.trim() === "") return null;
|
|
@@ -2926,17 +4148,33 @@ function isTopmostDialog(z) {
|
|
|
2926
4148
|
};
|
|
2927
4149
|
|
|
2928
4150
|
function SessionManagerPanel(props) {
|
|
2929
|
-
const t = props.t;
|
|
4151
|
+
const t = typeof props.t === "function" ? props.t : (k => k);
|
|
2930
4152
|
const open = props.open;
|
|
2931
4153
|
const onClose = props.onClose;
|
|
2932
|
-
const useSessions = props.useSessions;
|
|
2933
|
-
const useWorkspaces = props.useWorkspaces;
|
|
2934
4154
|
const onOpen = props.onOpen;
|
|
2935
4155
|
const onArchive = props.onArchive;
|
|
2936
4156
|
const onUnarchive = props.onUnarchive;
|
|
2937
4157
|
const onRemove = props.onRemove;
|
|
2938
4158
|
const onMove = props.onMove;
|
|
2939
4159
|
const onMigrate = props.onMigrate;
|
|
4160
|
+
const defaultUseSessions = (selector = s => s) => {
|
|
4161
|
+
const model = activeClientCtx?.sessions?.list;
|
|
4162
|
+
return useSyncExternalStore(
|
|
4163
|
+
(cb) => (model?.subscribe ? model.subscribe(cb) : () => {}),
|
|
4164
|
+
() => (model?.getSnapshot ? selector(model.getSnapshot()) : selector({ ids: [], byId: {} })),
|
|
4165
|
+
() => (model?.getSnapshot ? selector(model.getSnapshot()) : selector({ ids: [], byId: {} }))
|
|
4166
|
+
);
|
|
4167
|
+
};
|
|
4168
|
+
const defaultUseWorkspaces = (selector = s => s) => {
|
|
4169
|
+
const model = activeClientCtx?.workspaces?.list;
|
|
4170
|
+
return useSyncExternalStore(
|
|
4171
|
+
(cb) => (model?.subscribe ? model.subscribe(cb) : () => {}),
|
|
4172
|
+
() => (model?.getSnapshot ? selector(model.getSnapshot()) : selector({ items: [] })),
|
|
4173
|
+
() => (model?.getSnapshot ? selector(model.getSnapshot()) : selector({ items: [] }))
|
|
4174
|
+
);
|
|
4175
|
+
};
|
|
4176
|
+
const useSessions = typeof props.useSessions === "function" ? props.useSessions : defaultUseSessions;
|
|
4177
|
+
const useWorkspaces = typeof props.useWorkspaces === "function" ? props.useWorkspaces : defaultUseWorkspaces;
|
|
2940
4178
|
const annotations = useAnnotations(true);
|
|
2941
4179
|
const marksReady = annotations.loaded && !annotations.error;
|
|
2942
4180
|
const updateState = useSyncExternalStore(
|
|
@@ -2950,9 +4188,22 @@ function isTopmostDialog(z) {
|
|
|
2950
4188
|
const [priorityFilter, setPriorityFilter] = useState("all");
|
|
2951
4189
|
const [annotationFor, setAnnotationFor] = useState(null);
|
|
2952
4190
|
const [annotationAnchor, setAnnotationAnchor] = useState(null);
|
|
2953
|
-
const list = useSessions((s) => s);
|
|
2954
|
-
const workspaceSnapshot = useWorkspaces((s) => s);
|
|
4191
|
+
const list = (typeof useSessions === "function" ? useSessions((s) => s) : null) || { ids: [], byId: {} };
|
|
4192
|
+
const workspaceSnapshot = (typeof useWorkspaces === "function" ? useWorkspaces((s) => s) : null) || { items: [] };
|
|
2955
4193
|
const archivedIds = workspaceSnapshot.archivedSessionIds || [];
|
|
4194
|
+
const [panelTab, setPanelTab] = useState("sessions");
|
|
4195
|
+
const [wsQuery, setWsQuery] = useState("");
|
|
4196
|
+
const [wsFilter, setWsFilter] = useState("all");
|
|
4197
|
+
const [wsSort, setWsSort] = useState("updated-desc");
|
|
4198
|
+
const [wsSelectedIds, setWsSelectedIds] = useState(() => new Set());
|
|
4199
|
+
const [wsSelectModeEnabled, setWsSelectModeEnabled] = useState(false);
|
|
4200
|
+
const [wsBulkBusy, setWsBulkBusy] = useState(false);
|
|
4201
|
+
const [wsLastClickedRank, setWsLastClickedRank] = useState(null);
|
|
4202
|
+
const archiveVersion = useSyncExternalStore(
|
|
4203
|
+
(cb) => workspaceArchiveStore.subscribe(cb),
|
|
4204
|
+
() => workspaceArchiveStore.getVersion(),
|
|
4205
|
+
() => workspaceArchiveStore.getVersion()
|
|
4206
|
+
);
|
|
2956
4207
|
const [filter, setFilter] = useState("all");
|
|
2957
4208
|
const [query, setQuery] = useState("");
|
|
2958
4209
|
const [workspaceFilter, setWorkspaceFilter] = useState("all");
|
|
@@ -2962,14 +4213,39 @@ function isTopmostDialog(z) {
|
|
|
2962
4213
|
const [now, setNow] = useState(() => Date.now());
|
|
2963
4214
|
const [moveFor, setMoveFor] = useState(null);
|
|
2964
4215
|
const [confirmFor, setConfirmFor] = useState(null);
|
|
4216
|
+
const [confirmPreviewState, setConfirmPreviewState] = useState({ loading: false, error: null, subagentCount: 0 });
|
|
4217
|
+
useEffect(() => {
|
|
4218
|
+
if (!confirmFor || !confirmFor.id) {
|
|
4219
|
+
setConfirmPreviewState({ loading: false, error: null, subagentCount: 0 });
|
|
4220
|
+
return;
|
|
4221
|
+
}
|
|
4222
|
+
let alive = true;
|
|
4223
|
+
setConfirmPreviewState({ loading: true, error: null, subagentCount: 0 });
|
|
4224
|
+
fetchApi("/delete-preview?sessionId=" + encodeURIComponent(confirmFor.id))
|
|
4225
|
+
.then((res) => {
|
|
4226
|
+
if (!alive) return;
|
|
4227
|
+
if (res && res.ok && res.result && typeof res.result.subagentCount === "number") {
|
|
4228
|
+
setConfirmPreviewState({ loading: false, error: null, subagentCount: res.result.subagentCount });
|
|
4229
|
+
} else {
|
|
4230
|
+
setConfirmPreviewState({ loading: false, error: res?.error || "获取子智能体预览失败", subagentCount: 0 });
|
|
4231
|
+
}
|
|
4232
|
+
})
|
|
4233
|
+
.catch((err) => {
|
|
4234
|
+
if (!alive) return;
|
|
4235
|
+
setConfirmPreviewState({ loading: false, error: err instanceof Error ? err.message : String(err), subagentCount: 0 });
|
|
4236
|
+
});
|
|
4237
|
+
return () => { alive = false; };
|
|
4238
|
+
}, [confirmFor?.id]);
|
|
2965
4239
|
const [workspaces, setWorkspaces] = useState([]);
|
|
2966
4240
|
const [createdTimes, setCreatedTimes] = useState({});
|
|
4241
|
+
const [updatedTimes, setUpdatedTimes] = useState({});
|
|
2967
4242
|
const [workspacesLoading, setWorkspacesLoading] = useState(true);
|
|
2968
4243
|
const [workspacesError, setWorkspacesError] = useState(null);
|
|
2969
4244
|
const [workspaceRefresh, setWorkspaceRefresh] = useState(0);
|
|
2970
4245
|
const [migrating, setMigrating] = useState(false);
|
|
2971
4246
|
const [migrateFor, setMigrateFor] = useState(null);
|
|
2972
|
-
const sessionMembershipKey = useMemo(() => [...list.ids].sort().join("\0"), [list
|
|
4247
|
+
const sessionMembershipKey = useMemo(() => (Array.isArray(list?.ids) ? [...list.ids].sort().join("\0") : ""), [list?.ids]);
|
|
4248
|
+
let isSessionWorkspaceArchived = () => false;
|
|
2973
4249
|
// ----- Bulk-action selection state -----
|
|
2974
4250
|
const [selectedIds, setSelectedIds] = useState(() => new Set());
|
|
2975
4251
|
const [lastClickedRank, setLastClickedRank] = useState(null);
|
|
@@ -2997,6 +4273,10 @@ function isTopmostDialog(z) {
|
|
|
2997
4273
|
setBulkPresetOptions([]);
|
|
2998
4274
|
setBulkBusy(false);
|
|
2999
4275
|
setSelectModeEnabled(false);
|
|
4276
|
+
setWsSelectedIds(new Set());
|
|
4277
|
+
setWsSelectModeEnabled(false);
|
|
4278
|
+
setWsBulkBusy(false);
|
|
4279
|
+
setWsLastClickedRank(null);
|
|
3000
4280
|
}
|
|
3001
4281
|
}, [open]);
|
|
3002
4282
|
const toggleSelectMode = () => {
|
|
@@ -3111,6 +4391,15 @@ function isTopmostDialog(z) {
|
|
|
3111
4391
|
if (ids.length === 0) return;
|
|
3112
4392
|
if (ids.length > 200) { setError(t("bulk.error.tooMany")); return; }
|
|
3113
4393
|
const sessions = selectedSessions;
|
|
4394
|
+
if (action === "unarchive") {
|
|
4395
|
+
const hasBlocked = sessions.some(s => isSessionWorkspaceArchived(s));
|
|
4396
|
+
if (hasBlocked) {
|
|
4397
|
+
if (typeof window !== "undefined" && typeof window.alert === "function") {
|
|
4398
|
+
window.alert(t("error.workspaceArchived"));
|
|
4399
|
+
}
|
|
4400
|
+
return;
|
|
4401
|
+
}
|
|
4402
|
+
}
|
|
3114
4403
|
const resolvedLabel = actionLabel || ({
|
|
3115
4404
|
archive: t("bulk.archive"), unarchive: t("bulk.unarchive"), delete: t("bulk.delete"),
|
|
3116
4405
|
move: t("bulk.move"), "preset-migrate": t("bulk.presetMigrate"),
|
|
@@ -3135,7 +4424,59 @@ function isTopmostDialog(z) {
|
|
|
3135
4424
|
};
|
|
3136
4425
|
const summaryAction = actionSummaryMap[action] || resolvedLabel;
|
|
3137
4426
|
if (needsConfirm) {
|
|
3138
|
-
|
|
4427
|
+
const baseWarning = action === "delete" ? t("bulk.dialog.warning.delete") : "";
|
|
4428
|
+
if (action === "delete") {
|
|
4429
|
+
setBulkPreview({
|
|
4430
|
+
action,
|
|
4431
|
+
payload,
|
|
4432
|
+
actionLabel: summaryAction,
|
|
4433
|
+
sessions,
|
|
4434
|
+
warning: baseWarning,
|
|
4435
|
+
loading: true,
|
|
4436
|
+
error: null
|
|
4437
|
+
});
|
|
4438
|
+
fetchApi("/delete-preview?sessionIds=" + encodeURIComponent(ids.join(",")))
|
|
4439
|
+
.then((res) => {
|
|
4440
|
+
if (res && res.ok && res.result && typeof res.result.subagentCount === "number") {
|
|
4441
|
+
const subCount = res.result.subagentCount;
|
|
4442
|
+
setBulkPreview((prev) => {
|
|
4443
|
+
if (!prev || prev.action !== "delete") return prev;
|
|
4444
|
+
const subText = subCount > 0 ? t("confirm.delete.subagents", { count: subCount }) : "";
|
|
4445
|
+
return {
|
|
4446
|
+
...prev,
|
|
4447
|
+
loading: false,
|
|
4448
|
+
error: null,
|
|
4449
|
+
warning: subText ? `${subText}\n${baseWarning}` : baseWarning
|
|
4450
|
+
};
|
|
4451
|
+
});
|
|
4452
|
+
} else {
|
|
4453
|
+
const errMsg = (res && res.error) || t("confirm.delete.previewError") || "检查关联子智能体会话失败,请稍后重试";
|
|
4454
|
+
setBulkPreview((prev) => {
|
|
4455
|
+
if (!prev || prev.action !== "delete") return prev;
|
|
4456
|
+
return {
|
|
4457
|
+
...prev,
|
|
4458
|
+
loading: false,
|
|
4459
|
+
error: errMsg,
|
|
4460
|
+
warning: `${errMsg}\n${baseWarning}`
|
|
4461
|
+
};
|
|
4462
|
+
});
|
|
4463
|
+
}
|
|
4464
|
+
})
|
|
4465
|
+
.catch((err) => {
|
|
4466
|
+
const errMsg = (err && err.message) || t("confirm.delete.previewError") || "检查关联子智能体会话失败,请稍后重试";
|
|
4467
|
+
setBulkPreview((prev) => {
|
|
4468
|
+
if (!prev || prev.action !== "delete") return prev;
|
|
4469
|
+
return {
|
|
4470
|
+
...prev,
|
|
4471
|
+
loading: false,
|
|
4472
|
+
error: errMsg,
|
|
4473
|
+
warning: `${errMsg}\n${baseWarning}`
|
|
4474
|
+
};
|
|
4475
|
+
});
|
|
4476
|
+
});
|
|
4477
|
+
return;
|
|
4478
|
+
}
|
|
4479
|
+
setBulkPreview({ action, payload, actionLabel: summaryAction, sessions, warning: baseWarning });
|
|
3139
4480
|
return;
|
|
3140
4481
|
}
|
|
3141
4482
|
void executeBulk({ action, payload, actionLabel: resolvedLabel, ids, sessions });
|
|
@@ -3213,15 +4554,20 @@ function isTopmostDialog(z) {
|
|
|
3213
4554
|
if (!open) return;
|
|
3214
4555
|
let alive = true;
|
|
3215
4556
|
const controller = new AbortController();
|
|
3216
|
-
setWorkspacesLoading(true);
|
|
4557
|
+
if (workspaces.length === 0) setWorkspacesLoading(true);
|
|
3217
4558
|
setWorkspacesError(null);
|
|
3218
4559
|
fetchApi("/workspaces", { signal: controller.signal }).then((data) => {
|
|
3219
4560
|
if (!data?.ok || !Array.isArray(data.result?.workspaces)) throw new Error(data?.error || "Invalid workspace response");
|
|
3220
4561
|
const next = data.result.workspaces.filter(workspace => workspace && typeof workspace.id === "string");
|
|
3221
4562
|
if (!alive) return;
|
|
4563
|
+
if (data.result.workspaceArchives) {
|
|
4564
|
+
workspaceArchiveStore.syncFromHost(data.result.workspaceArchives);
|
|
4565
|
+
}
|
|
3222
4566
|
setWorkspaces(next);
|
|
3223
4567
|
const times = data.result.sessionCreatedAt;
|
|
3224
4568
|
setCreatedTimes(times && typeof times === "object" && !Array.isArray(times) ? times : {});
|
|
4569
|
+
const updated = data.result.sessionUpdatedAt;
|
|
4570
|
+
setUpdatedTimes(updated && typeof updated === "object" && !Array.isArray(updated) ? updated : {});
|
|
3225
4571
|
setWorkspaceFilter(value => value.startsWith("workspace:") && !next.some(workspace => workspaceValue(workspace.id) === value) ? "all" : value);
|
|
3226
4572
|
}).catch(error => {
|
|
3227
4573
|
if (alive) setWorkspacesError(error instanceof Error ? error.message : String(error));
|
|
@@ -3242,8 +4588,26 @@ function isTopmostDialog(z) {
|
|
|
3242
4588
|
}, [open]);
|
|
3243
4589
|
const archived = useMemo(() => new Set(archivedIds), [archivedIds]);
|
|
3244
4590
|
const workspaceIndex = useMemo(() => indexWorkspaces(workspaces), [workspaces]);
|
|
3245
|
-
|
|
3246
|
-
|
|
4591
|
+
isSessionWorkspaceArchived = (session) => {
|
|
4592
|
+
if (!session) return false;
|
|
4593
|
+
if (session.workspaceId && workspaceArchiveStore.isArchived(session.workspaceId)) return true;
|
|
4594
|
+
const memberships = rowWorkspaces(session, workspaceIndex);
|
|
4595
|
+
for (const wsId of memberships) {
|
|
4596
|
+
if (workspaceArchiveStore.isArchived(wsId)) return true;
|
|
4597
|
+
}
|
|
4598
|
+
for (const [, rec] of workspaceArchiveStore.getAllRecords()) {
|
|
4599
|
+
if (rec.archived === true && Array.isArray(rec.sessionIds) && rec.sessionIds.includes(session.id)) {
|
|
4600
|
+
return true;
|
|
4601
|
+
}
|
|
4602
|
+
}
|
|
4603
|
+
return false;
|
|
4604
|
+
};
|
|
4605
|
+
const allRows = useMemo(() => {
|
|
4606
|
+
const ids = Array.isArray(list?.ids) ? list.ids : [];
|
|
4607
|
+
const byId = list?.byId || {};
|
|
4608
|
+
return ids.map(id => byId[id])
|
|
4609
|
+
.filter(session => session != null && session.origin !== "subagent" && (!session.blank || session.id === list?.current));
|
|
4610
|
+
}, [list]);
|
|
3247
4611
|
const availableTags = useMemo(() => {
|
|
3248
4612
|
const tags = new Map();
|
|
3249
4613
|
for (const session of allRows) for (const tag of annotationOf(annotations, session.id).tags) if (!tags.has(tag.toLowerCase())) tags.set(tag.toLowerCase(), tag);
|
|
@@ -3273,6 +4637,16 @@ function isTopmostDialog(z) {
|
|
|
3273
4637
|
}
|
|
3274
4638
|
return true;
|
|
3275
4639
|
});
|
|
4640
|
+
if (sortOrder.startsWith("name-")) {
|
|
4641
|
+
const dir = sortOrder === "name-asc" ? 1 : -1;
|
|
4642
|
+
const nameOf = s => (s.blank ? t("panel.session.new") : (s.displayTitle || s.id || "")).toLowerCase();
|
|
4643
|
+
return selected.map((session, rank) => ({ session, rank, name: nameOf(session) }))
|
|
4644
|
+
.sort((a, b) => {
|
|
4645
|
+
const cmp = a.name.localeCompare(b.name);
|
|
4646
|
+
return cmp !== 0 ? dir * cmp : a.rank - b.rank;
|
|
4647
|
+
})
|
|
4648
|
+
.map(item => item.session);
|
|
4649
|
+
}
|
|
3276
4650
|
const field = sortOrder.startsWith("created-") ? "createdAt" : "updatedAt";
|
|
3277
4651
|
const direction = sortOrder === "priority" || sortOrder.endsWith("-asc") ? 1 : -1;
|
|
3278
4652
|
// Sort a derived array only. Equal timestamps preserve source order;
|
|
@@ -3308,8 +4682,6 @@ function isTopmostDialog(z) {
|
|
|
3308
4682
|
}, [currentFilterIds]);
|
|
3309
4683
|
const creationTimeUnavailable = sortOrder.startsWith("created-") && allRows.length > 0
|
|
3310
4684
|
&& !allRows.some(session => (sessionTime(session.createdAt) ?? sessionTime(createdTimes[session.id])) !== null);
|
|
3311
|
-
const hasViewChanges = onlyFavorite || onlyReview || tagFilter !== "all" || priorityFilter !== "all" || query !== "" || filter !== "all" || workspaceFilter !== "all" || sortOrder !== DEFAULT_SORT;
|
|
3312
|
-
const resetView = () => { setQuery(""); setFilter("all"); setWorkspaceFilter("all"); setSortOrder(DEFAULT_SORT); setOnlyFavorite(false); setOnlyReview(false); setTagFilter("all"); setPriorityFilter("all"); };
|
|
3313
4685
|
const runRow = async (sessionId, fn) => {
|
|
3314
4686
|
if (busyId !== null) return;
|
|
3315
4687
|
setBusyId(sessionId);
|
|
@@ -3329,12 +4701,24 @@ function isTopmostDialog(z) {
|
|
|
3329
4701
|
"aria-pressed": filter === id,
|
|
3330
4702
|
onClick: () => setFilter(id)
|
|
3331
4703
|
}, label);
|
|
4704
|
+
const hasViewChanges = query !== "" || filter !== "all" || workspaceFilter !== "all" || sortOrder !== DEFAULT_SORT || onlyFavorite || onlyReview || tagFilter !== "all" || priorityFilter !== "all";
|
|
4705
|
+
const resetView = () => {
|
|
4706
|
+
setQuery("");
|
|
4707
|
+
setFilter("all");
|
|
4708
|
+
setWorkspaceFilter("all");
|
|
4709
|
+
setSortOrder(DEFAULT_SORT);
|
|
4710
|
+
setOnlyFavorite(false);
|
|
4711
|
+
setOnlyReview(false);
|
|
4712
|
+
setTagFilter("all");
|
|
4713
|
+
setPriorityFilter("all");
|
|
4714
|
+
};
|
|
3332
4715
|
const renderRow = (s, rank) => {
|
|
3333
4716
|
const isArchived = archived.has(s.id);
|
|
3334
4717
|
const isCurrent = s.id === list.current;
|
|
3335
4718
|
const busy = busyId === s.id;
|
|
3336
4719
|
const mark = annotationOf(annotations, s.id);
|
|
3337
4720
|
const isSelected = selectedIds.has(s.id);
|
|
4721
|
+
const isWsArchived = isSessionWorkspaceArchived(s);
|
|
3338
4722
|
const checkbox = (selectedIds.size === 0 && !selectModeEnabled)
|
|
3339
4723
|
? null
|
|
3340
4724
|
: h("label", { className: "sm-bulkRowCheckbox", onClick: (e) => e.stopPropagation() },
|
|
@@ -3355,6 +4739,7 @@ function isTopmostDialog(z) {
|
|
|
3355
4739
|
h("div", { className: "sm-rowMain" },
|
|
3356
4740
|
h("div", { className: "sm-rowTitle" },
|
|
3357
4741
|
h("span", null, s.blank ? t("panel.session.new") : (s.displayTitle || s.id)),
|
|
4742
|
+
isWsArchived ? h("span", { className: "sm-badge sm-badgeWorkspaceArchived" }, t("panel.workspaceArchived")) : null,
|
|
3358
4743
|
isArchived ? h("span", { className: "sm-badge sm-badgeArchived" }, t("panel.archived")) : null,
|
|
3359
4744
|
s.running ? h("span", { className: "sm-badge sm-badgeRunning" }, t("panel.running")) : null,
|
|
3360
4745
|
isCurrent ? h("span", { className: "sm-badge sm-badgeCurrent" }, t("panel.current")) : null
|
|
@@ -3368,8 +4753,8 @@ function isTopmostDialog(z) {
|
|
|
3368
4753
|
),
|
|
3369
4754
|
h("div", { className: "sm-rowMeta" }, shortPath(s.cwd) + (s.cwd ? " · " : "") + formatRelative(s.updatedAt, now)),
|
|
3370
4755
|
h("div", { className: "sm-rowActions" },
|
|
3371
|
-
h("button", { type: "button", className: "sm-rowBtn", disabled: busy, onClick: () => { if (isArchived) { /* DSH refuses to surface an archived session as the current view: clicking "Open" on an archived row flashes an empty chat panel and bounces back to "no session selected". Unarchive first, then open. (issue #17.4) */ runRow(s.id, async () => { await onUnarchive(s.id); await onOpen(s.id); }); } else { onOpen(s.id); } } }, t("row.open")),
|
|
3372
|
-
h("button", { type: "button", className: "sm-rowBtn", disabled: busy, onClick: () => runRow(s.id, () => isArchived
|
|
4756
|
+
h("button", { type: "button", className: "sm-rowBtn", disabled: busy, onClick: () => { if (isArchived) { if (isWsArchived) { if (typeof window !== "undefined" && typeof window.alert === "function") { window.alert(t("error.workspaceArchived")); } return; } /* DSH refuses to surface an archived session as the current view: clicking "Open" on an archived row flashes an empty chat panel and bounces back to "no session selected". Unarchive first, then open. (issue #17.4) */ runRow(s.id, async () => { await onUnarchive(s.id); await onOpen(s.id); }); } else { onOpen(s.id); } } }, t("row.open")),
|
|
4757
|
+
h("button", { type: "button", className: "sm-rowBtn", disabled: busy, onClick: () => runRow(s.id, () => { if (isArchived) { if (isWsArchived) { if (typeof window !== "undefined" && typeof window.alert === "function") { window.alert(t("error.workspaceArchived")); } return; } return onUnarchive(s.id); } return onArchive(s.id); }) }, t(isArchived ? "row.unarchive" : "row.archive")),
|
|
3373
4758
|
annotationButtons(s.id, s.displayTitle || s.id, t, annotations, "sm-rowBtn", patch => runRow(s.id, () => annotationStore.save(s.id, patch)), () => { setAnnotationAnchor(null); setAnnotationFor(current => current?.id === s.id ? null : s); }, busy),
|
|
3374
4759
|
h("button", { type: "button", className: "sm-rowBtn", disabled: busy, onClick: () => { if (moveFor && moveFor.id === s.id) setMoveFor(null); else setMoveFor(s); } }, t("row.move")),
|
|
3375
4760
|
h("button", { type: "button", className: "sm-rowBtn", disabled: busy, onClick: () => { if (migrateFor && migrateFor.id === s.id) setMigrateFor(null); else setMigrateFor(s); } }, t("row.migrate")),
|
|
@@ -3382,8 +4767,288 @@ function isTopmostDialog(z) {
|
|
|
3382
4767
|
const rowsList = rows.length === 0
|
|
3383
4768
|
? h("div", { className: "sm-empty" }, allRows.length > 0 ? t("panel.empty.filtered") : filter === "archived" ? t("panel.empty.archived") : t("panel.empty"))
|
|
3384
4769
|
: h("div", { className: "sm-list" }, rows.map((s, i) => renderRow(s, i)));
|
|
4770
|
+
|
|
4771
|
+
const allWorkspaceRows = useMemo(() => {
|
|
4772
|
+
const hasSessionList = Array.isArray(list?.ids);
|
|
4773
|
+
const sessionsByWorkspace = new Map();
|
|
4774
|
+
for (const ws of workspaces) {
|
|
4775
|
+
sessionsByWorkspace.set(ws.id, []);
|
|
4776
|
+
}
|
|
4777
|
+
if (hasSessionList) {
|
|
4778
|
+
for (const s of allRows) {
|
|
4779
|
+
const matchedWsIds = rowWorkspaces(s, workspaceIndex);
|
|
4780
|
+
for (const wsId of matchedWsIds) {
|
|
4781
|
+
const wsList = sessionsByWorkspace.get(wsId);
|
|
4782
|
+
if (wsList) wsList.push(s);
|
|
4783
|
+
}
|
|
4784
|
+
}
|
|
4785
|
+
}
|
|
4786
|
+
return workspaces.map(ws => {
|
|
4787
|
+
const wsSessions = sessionsByWorkspace.get(ws.id) || [];
|
|
4788
|
+
let sessionCount = 0;
|
|
4789
|
+
let latestSessionTime = null;
|
|
4790
|
+
if (hasSessionList) {
|
|
4791
|
+
sessionCount = wsSessions.length;
|
|
4792
|
+
for (const s of wsSessions) {
|
|
4793
|
+
const st = sessionTime(s?.updatedAt) ?? sessionTime(s?.createdAt);
|
|
4794
|
+
if (st !== null) {
|
|
4795
|
+
if (latestSessionTime === null || st > latestSessionTime) {
|
|
4796
|
+
latestSessionTime = st;
|
|
4797
|
+
}
|
|
4798
|
+
}
|
|
4799
|
+
}
|
|
4800
|
+
} else {
|
|
4801
|
+
const sids = Array.isArray(ws.sessionIds) ? ws.sessionIds : [];
|
|
4802
|
+
const byId = list?.byId || {};
|
|
4803
|
+
for (const sid of sids) {
|
|
4804
|
+
const s = byId[sid];
|
|
4805
|
+
if (s && (s.origin === "subagent" || (s.blank && s.id !== list?.current))) continue;
|
|
4806
|
+
sessionCount++;
|
|
4807
|
+
const st = sessionTime(s?.updatedAt) ?? sessionTime(s?.createdAt);
|
|
4808
|
+
if (st !== null) {
|
|
4809
|
+
if (latestSessionTime === null || st > latestSessionTime) {
|
|
4810
|
+
latestSessionTime = st;
|
|
4811
|
+
}
|
|
4812
|
+
}
|
|
4813
|
+
}
|
|
4814
|
+
}
|
|
4815
|
+
return {
|
|
4816
|
+
...ws,
|
|
4817
|
+
sessionCount,
|
|
4818
|
+
latestUpdatedAt: latestSessionTime
|
|
4819
|
+
};
|
|
4820
|
+
});
|
|
4821
|
+
}, [workspaces, allRows, workspaceIndex, list?.ids, list?.byId, list?.current]);
|
|
4822
|
+
|
|
4823
|
+
const filteredWorkspaceRows = useMemo(() => {
|
|
4824
|
+
const needle = wsQuery.trim().toLowerCase();
|
|
4825
|
+
const selected = allWorkspaceRows.filter(ws => {
|
|
4826
|
+
const isArchived = workspaceArchiveStore.isArchived(ws.id);
|
|
4827
|
+
if (wsFilter === "active" && isArchived) return false;
|
|
4828
|
+
if (wsFilter === "archived" && !isArchived) return false;
|
|
4829
|
+
if (needle) {
|
|
4830
|
+
const title = ws.title || ws.name || ws.id;
|
|
4831
|
+
const path = ws.path || "";
|
|
4832
|
+
const matchesTitle = title.toLowerCase().includes(needle);
|
|
4833
|
+
const matchesPath = path.toLowerCase().includes(needle);
|
|
4834
|
+
const matchesId = ws.id.toLowerCase().includes(needle);
|
|
4835
|
+
if (!matchesTitle && !matchesPath && !matchesId) return false;
|
|
4836
|
+
}
|
|
4837
|
+
return true;
|
|
4838
|
+
});
|
|
4839
|
+
|
|
4840
|
+
if (wsSort.startsWith("name-")) {
|
|
4841
|
+
const dir = wsSort === "name-asc" ? 1 : -1;
|
|
4842
|
+
return selected.map((ws, rank) => {
|
|
4843
|
+
const name = (ws.title || ws.name || ws.id || "").toLowerCase();
|
|
4844
|
+
return { ws, rank, name };
|
|
4845
|
+
}).sort((a, b) => {
|
|
4846
|
+
const cmp = a.name.localeCompare(b.name);
|
|
4847
|
+
return cmp !== 0 ? dir * cmp : a.rank - b.rank;
|
|
4848
|
+
}).map(item => item.ws);
|
|
4849
|
+
}
|
|
4850
|
+
|
|
4851
|
+
const direction = wsSort === "updated-asc" ? 1 : -1;
|
|
4852
|
+
return selected.map((ws, rank) => ({ ws, rank, time: ws.latestUpdatedAt }))
|
|
4853
|
+
.sort((a, b) => {
|
|
4854
|
+
if (a.time === b.time) return a.rank - b.rank;
|
|
4855
|
+
if (a.time === null) return 1;
|
|
4856
|
+
if (b.time === null) return -1;
|
|
4857
|
+
return direction * (a.time - b.time);
|
|
4858
|
+
})
|
|
4859
|
+
.map(item => item.ws);
|
|
4860
|
+
}, [allWorkspaceRows, wsQuery, wsFilter, wsSort, archiveVersion]);
|
|
4861
|
+
|
|
4862
|
+
const currentWsFilterIds = useMemo(() => filteredWorkspaceRows.map(ws => ws.id), [filteredWorkspaceRows]);
|
|
4863
|
+
useEffect(() => {
|
|
4864
|
+
const allowed = new Set(currentWsFilterIds);
|
|
4865
|
+
setWsSelectedIds(prev => {
|
|
4866
|
+
let changed = false;
|
|
4867
|
+
const next = new Set();
|
|
4868
|
+
for (const id of prev) if (allowed.has(id)) next.add(id); else changed = true;
|
|
4869
|
+
return changed ? next : prev;
|
|
4870
|
+
});
|
|
4871
|
+
}, [currentWsFilterIds]);
|
|
4872
|
+
|
|
4873
|
+
const toggleWsSelectMode = () => {
|
|
4874
|
+
if (wsSelectModeEnabled) {
|
|
4875
|
+
setWsSelectModeEnabled(false);
|
|
4876
|
+
setWsSelectedIds(new Set());
|
|
4877
|
+
setWsLastClickedRank(null);
|
|
4878
|
+
} else {
|
|
4879
|
+
setWsSelectModeEnabled(true);
|
|
4880
|
+
}
|
|
4881
|
+
};
|
|
4882
|
+
|
|
4883
|
+
const toggleWsSelect = (id, isRange, rank) => {
|
|
4884
|
+
if (wsBulkBusy) return;
|
|
4885
|
+
setWsSelectedIds(prev => {
|
|
4886
|
+
const next = new Set(prev);
|
|
4887
|
+
if (isRange && wsLastClickedRank !== null && typeof rank === "number") {
|
|
4888
|
+
const low = Math.min(wsLastClickedRank, rank);
|
|
4889
|
+
const high = Math.max(wsLastClickedRank, rank);
|
|
4890
|
+
for (let i = low; i <= high; i++) {
|
|
4891
|
+
const row = filteredWorkspaceRows[i];
|
|
4892
|
+
if (row) next.add(row.id);
|
|
4893
|
+
}
|
|
4894
|
+
} else {
|
|
4895
|
+
if (next.has(id)) next.delete(id); else next.add(id);
|
|
4896
|
+
}
|
|
4897
|
+
return next;
|
|
4898
|
+
});
|
|
4899
|
+
setWsLastClickedRank(rank);
|
|
4900
|
+
};
|
|
4901
|
+
|
|
4902
|
+
const onWsBulkSelectAll = () => {
|
|
4903
|
+
setWsSelectModeEnabled(true);
|
|
4904
|
+
setWsSelectedIds(new Set(filteredWorkspaceRows.map(ws => ws.id)));
|
|
4905
|
+
};
|
|
4906
|
+
|
|
4907
|
+
const onWsBulkClear = () => {
|
|
4908
|
+
setWsSelectedIds(new Set());
|
|
4909
|
+
setWsLastClickedRank(null);
|
|
4910
|
+
};
|
|
4911
|
+
|
|
4912
|
+
const onWsBulkArchive = async () => {
|
|
4913
|
+
if (wsBulkBusy || !wsSelectModeEnabled || wsSelectedIds.size === 0) return;
|
|
4914
|
+
const targetWs = workspaces.filter(ws => wsSelectedIds.has(ws.id) && !workspaceArchiveStore.isArchived(ws.id));
|
|
4915
|
+
if (targetWs.length === 0) return;
|
|
4916
|
+
|
|
4917
|
+
const hostArchivedSet = new Set(workspaceSnapshot.archivedSessionIds || []);
|
|
4918
|
+
for (const ws of targetWs) {
|
|
4919
|
+
const toArchive = (ws.sessionIds || []).filter(id => !hostArchivedSet.has(id));
|
|
4920
|
+
const runningSession = toArchive.map(id => list.byId[id]).find(s => s && s.running);
|
|
4921
|
+
if (runningSession) {
|
|
4922
|
+
const rTitle = runningSession.displayTitle || runningSession.id;
|
|
4923
|
+
const wsTitle = ws.title || ws.name || ws.id;
|
|
4924
|
+
const msg = (t("confirm.delete.running") || "该会话正在运行,无法归档。") + " (" + wsTitle + ": " + rTitle + ")";
|
|
4925
|
+
if (typeof window !== "undefined" && typeof window.alert === "function") {
|
|
4926
|
+
window.alert(msg);
|
|
4927
|
+
}
|
|
4928
|
+
return;
|
|
4929
|
+
}
|
|
4930
|
+
}
|
|
4931
|
+
|
|
4932
|
+
setWsBulkBusy(true);
|
|
4933
|
+
try {
|
|
4934
|
+
for (const ws of targetWs) {
|
|
4935
|
+
await executeArchiveWorkspace(ws.id, { allWorkspaces: workspaces, t });
|
|
4936
|
+
}
|
|
4937
|
+
setWsSelectedIds(new Set());
|
|
4938
|
+
} catch (err) {
|
|
4939
|
+
setError(err?.message || String(err));
|
|
4940
|
+
} finally {
|
|
4941
|
+
setWsBulkBusy(false);
|
|
4942
|
+
}
|
|
4943
|
+
};
|
|
4944
|
+
|
|
4945
|
+
const onWsBulkUnarchive = async () => {
|
|
4946
|
+
if (wsBulkBusy || !wsSelectModeEnabled || wsSelectedIds.size === 0) return;
|
|
4947
|
+
const targetWs = workspaces.filter(ws => wsSelectedIds.has(ws.id) && workspaceArchiveStore.isArchived(ws.id));
|
|
4948
|
+
if (targetWs.length === 0) return;
|
|
4949
|
+
|
|
4950
|
+
setWsBulkBusy(true);
|
|
4951
|
+
try {
|
|
4952
|
+
for (const ws of targetWs) {
|
|
4953
|
+
await executeUnarchiveWorkspace(ws.id, { t });
|
|
4954
|
+
}
|
|
4955
|
+
setWsSelectedIds(new Set());
|
|
4956
|
+
} catch (err) {
|
|
4957
|
+
setError(err?.message || String(err));
|
|
4958
|
+
} finally {
|
|
4959
|
+
setWsBulkBusy(false);
|
|
4960
|
+
}
|
|
4961
|
+
};
|
|
4962
|
+
|
|
4963
|
+
const hasWsViewChanges = wsQuery !== "" || wsFilter !== "all" || wsSort !== "updated-desc";
|
|
4964
|
+
const resetWsView = () => { setWsQuery(""); setWsFilter("all"); setWsSort("updated-desc"); };
|
|
4965
|
+
const wsIsEn = typeof t === "function" && (t("workspace.filter.all") === "All" || t("marks.favorite") === "Favorite");
|
|
4966
|
+
|
|
4967
|
+
const renderWorkspaceRow = (ws, rank) => {
|
|
4968
|
+
const isArchived = workspaceArchiveStore.isArchived(ws.id);
|
|
4969
|
+
const isBusy = workspaceArchiveStore.isBusy(ws.id);
|
|
4970
|
+
const title = ws.title || ws.name || ws.id;
|
|
4971
|
+
const path = ws.path || "";
|
|
4972
|
+
const sessionCount = typeof ws.sessionCount === "number" ? ws.sessionCount : (Array.isArray(ws.sessionIds) ? ws.sessionIds.length : 0);
|
|
4973
|
+
const timeFormatted = ws.latestUpdatedAt !== null
|
|
4974
|
+
? t("workspace.lastUpdated", { time: formatRelative(ws.latestUpdatedAt, now) })
|
|
4975
|
+
: "—";
|
|
4976
|
+
|
|
4977
|
+
const isWsSelected = wsSelectedIds.has(ws.id);
|
|
4978
|
+
const checkbox = (wsSelectedIds.size === 0 && !wsSelectModeEnabled)
|
|
4979
|
+
? null
|
|
4980
|
+
: h("label", { className: "sm-bulkRowCheckbox", onClick: (e) => e.stopPropagation() },
|
|
4981
|
+
h("input", {
|
|
4982
|
+
type: "checkbox",
|
|
4983
|
+
checked: isWsSelected,
|
|
4984
|
+
disabled: isBusy || wsBulkBusy,
|
|
4985
|
+
"aria-label": t("bulk.checkbox.aria", { title: title }),
|
|
4986
|
+
onChange: (e) => toggleWsSelect(ws.id, e.shiftKey === true, rank)
|
|
4987
|
+
})
|
|
4988
|
+
);
|
|
4989
|
+
|
|
4990
|
+
const handleToggleArchive = (e) => {
|
|
4991
|
+
if (e && typeof e.stopPropagation === "function") e.stopPropagation();
|
|
4992
|
+
if (isBusy || wsBulkBusy) return;
|
|
4993
|
+
if (!isArchived) {
|
|
4994
|
+
const hostArchivedSet = new Set(workspaceSnapshot.archivedSessionIds || []);
|
|
4995
|
+
const toArchive = (ws.sessionIds || []).filter(id => !hostArchivedSet.has(id));
|
|
4996
|
+
const runningSession = toArchive.map(id => list.byId[id]).find(s => s && s.running);
|
|
4997
|
+
if (runningSession) {
|
|
4998
|
+
const rTitle = runningSession.displayTitle || runningSession.id;
|
|
4999
|
+
const msg = (t("confirm.delete.running") || "该会话正在运行,无法归档。") + " (" + rTitle + ")";
|
|
5000
|
+
if (typeof window !== "undefined" && typeof window.alert === "function") {
|
|
5001
|
+
window.alert(msg);
|
|
5002
|
+
}
|
|
5003
|
+
return;
|
|
5004
|
+
}
|
|
5005
|
+
void executeArchiveWorkspace(ws.id, { allWorkspaces: workspaces, t });
|
|
5006
|
+
} else {
|
|
5007
|
+
void executeUnarchiveWorkspace(ws.id, { t });
|
|
5008
|
+
}
|
|
5009
|
+
};
|
|
5010
|
+
|
|
5011
|
+
const switchNode = h(SmSwitch, {
|
|
5012
|
+
role: "switch",
|
|
5013
|
+
"aria-checked": !isArchived,
|
|
5014
|
+
checked: !isArchived,
|
|
5015
|
+
loading: isBusy,
|
|
5016
|
+
disabled: isBusy || wsBulkBusy,
|
|
5017
|
+
ariaLabel: t("workspace.switch.aria", { name: title }),
|
|
5018
|
+
onClick: handleToggleArchive,
|
|
5019
|
+
onChange: handleToggleArchive
|
|
5020
|
+
});
|
|
5021
|
+
|
|
5022
|
+
return h("div", {
|
|
5023
|
+
key: ws.id,
|
|
5024
|
+
"data-workspace-id": ws.id,
|
|
5025
|
+
className: "sm-row sm-workspaceRow" + (isArchived ? " sm-rowArchived" : "") + (isWsSelected ? " sm-rowBulkSelected" : "")
|
|
5026
|
+
},
|
|
5027
|
+
h("div", { className: "sm-rowCheckboxSlot" + ((wsSelectedIds.size > 0 || wsSelectModeEnabled) ? " sm-rowCheckboxSlot-visible" : "") }, checkbox),
|
|
5028
|
+
h("div", { className: "sm-rowMain" },
|
|
5029
|
+
h("div", { className: "sm-rowTitle", title: path || title },
|
|
5030
|
+
h("span", null, title),
|
|
5031
|
+
isArchived ? h("span", { className: "sm-badge sm-badgeArchived" }, t("workspace.badge.archived")) : null
|
|
5032
|
+
),
|
|
5033
|
+
h("div", { className: "sm-rowSecondary" },
|
|
5034
|
+
h("div", { className: "sm-rowMeta" },
|
|
5035
|
+
t("workspace.sessions", { count: sessionCount }) +
|
|
5036
|
+
" · " +
|
|
5037
|
+
timeFormatted
|
|
5038
|
+
)
|
|
5039
|
+
)
|
|
5040
|
+
),
|
|
5041
|
+
h("div", { className: "sm-rowActions sm-workspaceRowActions" },
|
|
5042
|
+
switchNode
|
|
5043
|
+
)
|
|
5044
|
+
);
|
|
5045
|
+
};
|
|
5046
|
+
const workspaceRowsList = filteredWorkspaceRows.length === 0
|
|
5047
|
+
? h("div", { className: "sm-empty" }, allWorkspaceRows.length > 0 ? t("workspace.empty.filtered") : t("workspace.empty"))
|
|
5048
|
+
: h("div", { className: "sm-list" }, filteredWorkspaceRows.map((ws, rank) => renderWorkspaceRow(ws, rank)));
|
|
5049
|
+
|
|
3385
5050
|
const onPanelClose = () => {
|
|
3386
|
-
if (busyId !== null) return;
|
|
5051
|
+
if (busyId !== null || wsBulkBusy) return;
|
|
3387
5052
|
setConfirmFor(null);
|
|
3388
5053
|
setMoveFor(null);
|
|
3389
5054
|
setMigrateFor(null);
|
|
@@ -3397,8 +5062,23 @@ function isTopmostDialog(z) {
|
|
|
3397
5062
|
// without re-subscribing on every render. The panel listener
|
|
3398
5063
|
// returns early when any inner dialog is open so the child
|
|
3399
5064
|
// dialog's own window listener gets the first shot at Esc.
|
|
5065
|
+
const panelRef = useRef(null);
|
|
3400
5066
|
const escStateRef = useRef({});
|
|
3401
|
-
escStateRef.current = {
|
|
5067
|
+
escStateRef.current = {
|
|
5068
|
+
busyId,
|
|
5069
|
+
confirmFor,
|
|
5070
|
+
moveFor,
|
|
5071
|
+
migrateFor,
|
|
5072
|
+
annotationFor,
|
|
5073
|
+
bulkPreview,
|
|
5074
|
+
bulkProgress,
|
|
5075
|
+
bulkResult,
|
|
5076
|
+
bulkBusy,
|
|
5077
|
+
bulkTagDraft,
|
|
5078
|
+
bulkPresetDraft,
|
|
5079
|
+
wsBulkBusy,
|
|
5080
|
+
onPanelClose
|
|
5081
|
+
};
|
|
3402
5082
|
useEffect(() => {
|
|
3403
5083
|
if (!open) return;
|
|
3404
5084
|
const handler = (e) => {
|
|
@@ -3406,8 +5086,10 @@ function isTopmostDialog(z) {
|
|
|
3406
5086
|
if (e.defaultPrevented) return;
|
|
3407
5087
|
if (e.isComposing || e.keyCode === 229) return;
|
|
3408
5088
|
const s = escStateRef.current;
|
|
3409
|
-
if (s.busyId !== null) return;
|
|
3410
|
-
if (s.confirmFor || s.moveFor || s.migrateFor || s.annotationFor ||
|
|
5089
|
+
if (s.busyId !== null || s.wsBulkBusy || s.bulkBusy) return;
|
|
5090
|
+
if (s.confirmFor || s.moveFor || s.migrateFor || s.annotationFor || s.bulkPreview || s.bulkProgress || s.bulkResult || s.bulkTagDraft || s.bulkPresetDraft) return;
|
|
5091
|
+
if (typeof updateStore !== "undefined" && updateStore && typeof updateStore.getSnapshot === "function" && updateStore.getSnapshot()?.dialogOpen) return;
|
|
5092
|
+
if (activeDialogZStack && activeDialogZStack.length > 0) return;
|
|
3411
5093
|
e.preventDefault();
|
|
3412
5094
|
e.stopPropagation();
|
|
3413
5095
|
s.onPanelClose();
|
|
@@ -3421,7 +5103,28 @@ function isTopmostDialog(z) {
|
|
|
3421
5103
|
if (ae && typeof ae.blur === "function" && ae !== document.body) ae.blur();
|
|
3422
5104
|
};
|
|
3423
5105
|
window.addEventListener("keydown", handler);
|
|
3424
|
-
|
|
5106
|
+
const mountTime = Date.now();
|
|
5107
|
+
const clickHandler = (e) => {
|
|
5108
|
+
if (Date.now() - mountTime < 50) return;
|
|
5109
|
+
if (e.defaultPrevented) return;
|
|
5110
|
+
const s = escStateRef.current;
|
|
5111
|
+
if (s.busyId !== null || s.wsBulkBusy || s.bulkBusy) return;
|
|
5112
|
+
if (s.annotationFor !== null) return;
|
|
5113
|
+
if (s.confirmFor || s.moveFor || s.migrateFor) return;
|
|
5114
|
+
if (s.bulkPreview || s.bulkProgress || s.bulkResult || s.bulkTagDraft || s.bulkPresetDraft) return;
|
|
5115
|
+
if (typeof updateStore !== "undefined" && updateStore && typeof updateStore.getSnapshot === "function" && updateStore.getSnapshot()?.dialogOpen) return;
|
|
5116
|
+
if (activeDialogZStack && activeDialogZStack.length > 0) return;
|
|
5117
|
+
if (panelRef.current && typeof panelRef.current.contains === "function" && panelRef.current.contains(e.target)) return;
|
|
5118
|
+
if (e.target && typeof e.target.closest === "function") {
|
|
5119
|
+
if (e.target.closest(".sm-nativeDialog, .sm-panelDialog, .sm-bulkDialog, .sm-annotationDialog, .sm-annotationSurface, .sm-tooltip, .sm-footerBtn")) return;
|
|
5120
|
+
}
|
|
5121
|
+
s.onPanelClose();
|
|
5122
|
+
};
|
|
5123
|
+
window.addEventListener("click", clickHandler);
|
|
5124
|
+
return () => {
|
|
5125
|
+
window.removeEventListener("keydown", handler);
|
|
5126
|
+
window.removeEventListener("click", clickHandler);
|
|
5127
|
+
};
|
|
3425
5128
|
}, [open]);
|
|
3426
5129
|
// The panel is a document-level floating window, so it is portaled into
|
|
3427
5130
|
// the plugin's overlay root like every other dialog here (issue #28).
|
|
@@ -3444,6 +5147,7 @@ function isTopmostDialog(z) {
|
|
|
3444
5147
|
role: "presentation"
|
|
3445
5148
|
},
|
|
3446
5149
|
h("section", {
|
|
5150
|
+
ref: panelRef,
|
|
3447
5151
|
className: "sm-nativeDialog sm-panelDialog",
|
|
3448
5152
|
role: "dialog",
|
|
3449
5153
|
"aria-modal": "true",
|
|
@@ -3509,106 +5213,235 @@ function isTopmostDialog(z) {
|
|
|
3509
5213
|
updateState.status === "checking" ? h("span", { className: "sm-updateSpinner", "aria-hidden": "true" }) : null
|
|
3510
5214
|
)),
|
|
3511
5215
|
),
|
|
3512
|
-
h("h2", { id: "sm-panel-dialog-title", className: "sm-nativeDialogTitle" }, t("panel.title")),
|
|
5216
|
+
h("h2", { id: "sm-panel-dialog-title", className: "sm-nativeDialogTitle sm-visuallyHidden" }, t("panel.title")),
|
|
5217
|
+
h("nav", { className: "sm-panelNav", "aria-label": t("panel.tab.sessions") || "页面切换" },
|
|
5218
|
+
h("button", {
|
|
5219
|
+
type: "button",
|
|
5220
|
+
role: "tab",
|
|
5221
|
+
"aria-selected": panelTab === "sessions",
|
|
5222
|
+
className: "sm-panelNavTab" + (panelTab === "sessions" ? " sm-on" : ""),
|
|
5223
|
+
onClick: () => setPanelTab("sessions")
|
|
5224
|
+
}, t("panel.tab.sessions")),
|
|
5225
|
+
h("button", {
|
|
5226
|
+
type: "button",
|
|
5227
|
+
role: "tab",
|
|
5228
|
+
"aria-selected": panelTab === "workspaces",
|
|
5229
|
+
className: "sm-panelNavTab" + (panelTab === "workspaces" ? " sm-on" : ""),
|
|
5230
|
+
onClick: () => setPanelTab("workspaces")
|
|
5231
|
+
}, t("panel.tab.workspaces"))
|
|
5232
|
+
),
|
|
3513
5233
|
h("div", { className: "sm-nativeDialogHeaderActions" },
|
|
3514
5234
|
renderTip(t("panel.close") || "关闭", h("button", {
|
|
3515
5235
|
type: "button",
|
|
3516
5236
|
className: "sm-panelHeaderClose",
|
|
3517
|
-
disabled: busyId !== null || migrating,
|
|
5237
|
+
disabled: busyId !== null || migrating || wsBulkBusy,
|
|
3518
5238
|
onClick: onPanelClose,
|
|
3519
5239
|
"aria-label": t("panel.close")
|
|
3520
5240
|
}, h(CloseIcon, { size: 14 })))
|
|
3521
5241
|
)
|
|
3522
5242
|
),
|
|
3523
5243
|
h("div", { className: "sm-panel" },
|
|
3524
|
-
|
|
3525
|
-
h("
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
h("
|
|
3532
|
-
h("
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
h("
|
|
3540
|
-
|
|
5244
|
+
panelTab === "workspaces" ? h(React.Fragment, null,
|
|
5245
|
+
h("div", { className: "sm-panelTools" },
|
|
5246
|
+
h("input", {
|
|
5247
|
+
type: "search", className: "sm-queryInput", value: wsQuery,
|
|
5248
|
+
placeholder: t("workspace.search"), "aria-label": t("workspace.search"), autoComplete: "off",
|
|
5249
|
+
onChange: event => setWsQuery(event.target.value)
|
|
5250
|
+
}),
|
|
5251
|
+
h("div", { className: "sm-markFilters sm-wsFilters" },
|
|
5252
|
+
h("div", { className: "sm-markFiltersGroup" },
|
|
5253
|
+
h("button", {
|
|
5254
|
+
type: "button", key: "all",
|
|
5255
|
+
className: "sm-filterBtn" + (wsFilter === "all" ? " sm-on" : ""),
|
|
5256
|
+
"aria-pressed": wsFilter === "all",
|
|
5257
|
+
onClick: () => setWsFilter("all")
|
|
5258
|
+
}, t("workspace.filter.all")),
|
|
5259
|
+
h("button", {
|
|
5260
|
+
type: "button", key: "active",
|
|
5261
|
+
className: "sm-filterBtn" + (wsFilter === "active" ? " sm-on" : ""),
|
|
5262
|
+
"aria-pressed": wsFilter === "active",
|
|
5263
|
+
onClick: () => setWsFilter("active")
|
|
5264
|
+
}, t("workspace.filter.active")),
|
|
5265
|
+
h("button", {
|
|
5266
|
+
type: "button", key: "archived",
|
|
5267
|
+
className: "sm-filterBtn" + (wsFilter === "archived" ? " sm-on" : ""),
|
|
5268
|
+
"aria-pressed": wsFilter === "archived",
|
|
5269
|
+
onClick: () => setWsFilter("archived")
|
|
5270
|
+
}, t("workspace.filter.archived")),
|
|
5271
|
+
h("div", { className: "sm-viewField sm-wsSortField" },
|
|
5272
|
+
h("select", {
|
|
5273
|
+
className: "sm-viewSelect sm-wsSortSelect" + (wsIsEn ? " sm-wsSortSelect-en" : ""), "aria-label": t("panel.sort"), value: wsSort,
|
|
5274
|
+
onMouseDown: e => e.stopPropagation(),
|
|
5275
|
+
onClick: e => e.stopPropagation(),
|
|
5276
|
+
onChange: event => setWsSort(event.target.value)
|
|
5277
|
+
},
|
|
5278
|
+
h("option", { value: "updated-desc" }, t("workspace.sort.updated-desc")),
|
|
5279
|
+
h("option", { value: "updated-asc" }, t("workspace.sort.updated-asc")),
|
|
5280
|
+
h("option", { value: "name-asc" }, t("workspace.sort.name-asc")),
|
|
5281
|
+
h("option", { value: "name-desc" }, t("workspace.sort.name-desc"))
|
|
5282
|
+
)
|
|
5283
|
+
)
|
|
5284
|
+
),
|
|
5285
|
+
h("div", { className: "sm-markFiltersSpacer" }),
|
|
5286
|
+
h("div", { className: "sm-markFiltersGroup sm-wsFiltersBulk" },
|
|
5287
|
+
h("button", {
|
|
5288
|
+
type: "button",
|
|
5289
|
+
className: "sm-filterBtn" + (wsSelectModeEnabled ? " sm-on" : ""),
|
|
5290
|
+
disabled: busyId !== null || migrating || wsBulkBusy,
|
|
5291
|
+
"aria-pressed": wsSelectModeEnabled,
|
|
5292
|
+
"aria-label": t(wsSelectModeEnabled ? "panel.selectMode.exit" : "panel.selectMode.aria"),
|
|
5293
|
+
onClick: toggleWsSelectMode
|
|
5294
|
+
}, wsSelectModeEnabled ? t("panel.selectMode.exit") : t("panel.selectMode")),
|
|
5295
|
+
h("button", {
|
|
5296
|
+
type: "button",
|
|
5297
|
+
className: "sm-filterBtn sm-bulkSelectBtn",
|
|
5298
|
+
disabled: filteredWorkspaceRows.length === 0 || wsSelectedIds.size === filteredWorkspaceRows.length || wsBulkBusy,
|
|
5299
|
+
onClick: onWsBulkSelectAll,
|
|
5300
|
+
"aria-label": t("bulk.selectAllFiltered")
|
|
5301
|
+
}, t("bulk.selectAllFiltered")),
|
|
5302
|
+
h("button", {
|
|
5303
|
+
type: "button",
|
|
5304
|
+
className: "sm-filterBtn sm-bulkSelectBtn",
|
|
5305
|
+
disabled: wsSelectedIds.size === 0 || wsBulkBusy,
|
|
5306
|
+
onClick: onWsBulkClear,
|
|
5307
|
+
"aria-label": t("bulk.clear")
|
|
5308
|
+
}, t("bulk.clear")),
|
|
5309
|
+
h("button", {
|
|
5310
|
+
type: "button",
|
|
5311
|
+
className: "sm-filterBtn",
|
|
5312
|
+
disabled: !wsSelectModeEnabled || wsSelectedIds.size === 0 || wsBulkBusy,
|
|
5313
|
+
onClick: onWsBulkArchive,
|
|
5314
|
+
"aria-label": t("workspace.bulk.archive")
|
|
5315
|
+
}, t("workspace.bulk.archive")),
|
|
5316
|
+
h("button", {
|
|
5317
|
+
type: "button",
|
|
5318
|
+
className: "sm-filterBtn",
|
|
5319
|
+
disabled: !wsSelectModeEnabled || wsSelectedIds.size === 0 || wsBulkBusy,
|
|
5320
|
+
onClick: onWsBulkUnarchive,
|
|
5321
|
+
"aria-label": t("workspace.bulk.unarchive")
|
|
5322
|
+
}, t("workspace.bulk.unarchive"))
|
|
3541
5323
|
)
|
|
3542
5324
|
),
|
|
3543
|
-
h("
|
|
3544
|
-
h("span",
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
5325
|
+
h("div", { className: "sm-resultSummary" },
|
|
5326
|
+
h("span", { role: "status", "aria-live": "polite", "aria-atomic": "true" },
|
|
5327
|
+
(wsSelectModeEnabled || wsSelectedIds.size > 0)
|
|
5328
|
+
? t("bulk.selectedFiltered", { selected: wsSelectedIds.size, filtered: filteredWorkspaceRows.length })
|
|
5329
|
+
: t("workspace.count", { shown: filteredWorkspaceRows.length, total: allWorkspaceRows.length })
|
|
5330
|
+
),
|
|
5331
|
+
hasWsViewChanges ? h("button", { type: "button", className: "sm-resetFilters", onClick: resetWsView }, t("workspace.reset")) : null
|
|
3549
5332
|
),
|
|
3550
|
-
h("
|
|
3551
|
-
|
|
3552
|
-
h("
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
5333
|
+
(workspacesLoading && workspaces.length === 0) ? h("div", { className: "sm-workspaceNotice", role: "status" }, t("panel.workspace.loading")) : null,
|
|
5334
|
+
workspacesError ? h("div", { className: "sm-workspaceNotice", role: "alert" },
|
|
5335
|
+
h("span", null, t("panel.workspace.error", { message: workspacesError })),
|
|
5336
|
+
h("button", { type: "button", className: "sm-resetFilters", onClick: () => setWorkspaceRefresh(value => value + 1) }, t("panel.workspace.retry"))
|
|
5337
|
+
) : null
|
|
5338
|
+
),
|
|
5339
|
+
error ? h("div", { className: "sm-error", role: "alert" }, t("error.operation", { message: error })) : null,
|
|
5340
|
+
workspaceRowsList
|
|
5341
|
+
) : h(React.Fragment, null,
|
|
5342
|
+
h("div", { className: "sm-panelTools" },
|
|
5343
|
+
h("input", {
|
|
5344
|
+
type: "search", className: "sm-queryInput", value: query,
|
|
5345
|
+
placeholder: t("panel.search"), "aria-label": t("panel.search"), autoComplete: "off",
|
|
5346
|
+
onChange: event => setQuery(event.target.value)
|
|
5347
|
+
}),
|
|
5348
|
+
h("div", { className: "sm-panelSelects" },
|
|
5349
|
+
h("div", { className: "sm-viewField" },
|
|
5350
|
+
h("span", null, t("panel.workspace")),
|
|
5351
|
+
h("select", {
|
|
5352
|
+
className: "sm-viewSelect", "aria-label": t("panel.workspace"), value: workspaceFilter,
|
|
5353
|
+
disabled: workspacesLoading || workspacesError !== null,
|
|
5354
|
+
onMouseDown: e => e.stopPropagation(),
|
|
5355
|
+
onClick: e => e.stopPropagation(),
|
|
5356
|
+
onChange: event => setWorkspaceFilter(event.target.value)
|
|
5357
|
+
},
|
|
5358
|
+
h("option", { value: "all" }, t("panel.workspace.all")),
|
|
5359
|
+
h("option", { value: "ungrouped" }, t("panel.workspace.ungrouped")),
|
|
5360
|
+
workspaces.map(workspace => h("option", { key: workspace.id, value: workspaceValue(workspace.id), title: workspace.path || workspace.id }, workspace.title || workspace.name || workspace.id))
|
|
5361
|
+
)
|
|
5362
|
+
),
|
|
5363
|
+
h("div", { className: "sm-viewField" },
|
|
5364
|
+
h("span", null, t("panel.sort")),
|
|
5365
|
+
h("select", {
|
|
5366
|
+
className: "sm-viewSelect", "aria-label": t("panel.sort"), value: sortOrder,
|
|
5367
|
+
onMouseDown: e => e.stopPropagation(),
|
|
5368
|
+
onClick: e => e.stopPropagation(),
|
|
5369
|
+
onChange: event => setSortOrder(event.target.value)
|
|
5370
|
+
}, SORT_ORDERS.map(value => h("option", { key: value, value, disabled: value === "priority" && !marksReady }, t(value === "priority" ? "marks.sort" : "panel.sort." + value))))
|
|
5371
|
+
),
|
|
5372
|
+
h("div", { className: "sm-viewField" },
|
|
5373
|
+
h("span", null, t("marks.tags")),
|
|
5374
|
+
h("select", {
|
|
5375
|
+
className: "sm-viewSelect", "aria-label": t("marks.filter.tags"), value: tagFilter, disabled: !marksReady,
|
|
5376
|
+
onMouseDown: e => e.stopPropagation(),
|
|
5377
|
+
onClick: e => e.stopPropagation(),
|
|
5378
|
+
onChange: e => setTagFilter(e.target.value)
|
|
5379
|
+
},
|
|
5380
|
+
h("option", { value: "all" }, t("marks.tags.all")), h("option", { value: "none" }, t("marks.tags.none")),
|
|
5381
|
+
availableTags.map(([key, tag]) => h("option", { key, value: "tag:" + key }, tag)),
|
|
5382
|
+
tagFilter.startsWith("tag:") && !availableTags.some(([key]) => "tag:" + key === tagFilter) ? h("option", { value: tagFilter }, t("marks.tags.missing", { tag: tagFilter.slice(4) })) : null
|
|
5383
|
+
)
|
|
5384
|
+
),
|
|
5385
|
+
h("div", { className: "sm-viewField" },
|
|
5386
|
+
h("span", null, t("marks.priority")),
|
|
5387
|
+
h("select", {
|
|
5388
|
+
className: "sm-viewSelect", "aria-label": t("marks.filter.priority"), value: priorityFilter, disabled: !marksReady,
|
|
5389
|
+
onMouseDown: e => e.stopPropagation(),
|
|
5390
|
+
onClick: e => e.stopPropagation(),
|
|
5391
|
+
onChange: e => setPriorityFilter(e.target.value)
|
|
5392
|
+
},
|
|
5393
|
+
h("option", { value: "all" }, t("marks.priority.all")),
|
|
5394
|
+
[1,2,3,4,5].map(value => h("option", { key: value, value: String(value) }, t("marks.priority." + value)))
|
|
5395
|
+
)
|
|
3556
5396
|
)
|
|
3557
5397
|
),
|
|
3558
|
-
h("
|
|
3559
|
-
h("
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
5398
|
+
h("div", { className: "sm-markFilters" },
|
|
5399
|
+
h("div", { className: "sm-markFiltersGroup" },
|
|
5400
|
+
filterBtn("all", t("panel.filter.all")),
|
|
5401
|
+
filterBtn("active", t("panel.filter.active")),
|
|
5402
|
+
filterBtn("archived", t("panel.filter.archived")),
|
|
5403
|
+
h("button", { type: "button", className: "sm-filterBtn sm-markFilterToggle" + (onlyFavorite ? " sm-on" : ""), "aria-label": t("marks.filter.favorite.aria"), "aria-pressed": onlyFavorite, disabled: !marksReady, onClick: () => setOnlyFavorite(value => !value) }, "★ " + t("marks.filter.favorite")),
|
|
5404
|
+
h("button", { type: "button", className: "sm-filterBtn sm-markFilterToggle" + (onlyReview ? " sm-on" : ""), "aria-label": t("marks.filter.review.aria"), "aria-pressed": onlyReview, disabled: !marksReady, onClick: () => setOnlyReview(value => !value) }, "◷ " + t("marks.filter.review"))
|
|
5405
|
+
),
|
|
5406
|
+
h("div", { className: "sm-markFiltersSpacer" }),
|
|
5407
|
+
h("div", { className: "sm-markFiltersGroup" },
|
|
5408
|
+
h("button", {
|
|
5409
|
+
type: "button",
|
|
5410
|
+
className: "sm-filterBtn" + (selectModeEnabled ? " sm-on" : ""),
|
|
5411
|
+
disabled: busyId !== null || migrating,
|
|
5412
|
+
"aria-pressed": selectModeEnabled,
|
|
5413
|
+
"aria-label": t(selectModeEnabled ? "panel.selectMode.active.aria" : "panel.selectMode.aria"),
|
|
5414
|
+
onClick: toggleSelectMode
|
|
5415
|
+
}, selectModeEnabled ? t("panel.selectMode.exit") : t("panel.selectMode")),
|
|
5416
|
+
h("button", { type: "button", className: "sm-filterBtn sm-bulkSelectBtn", disabled: rows.length === 0 || rows.length === selectedIds.size || bulkBusy, onClick: onBulkSelectAll, "aria-label": t("bulk.selectAllFiltered") }, t("bulk.selectAllFiltered")),
|
|
5417
|
+
h("button", { type: "button", className: "sm-filterBtn sm-bulkSelectBtn", disabled: selectedIds.size === 0 || bulkBusy, onClick: onBulkClear, "aria-label": t("bulk.clear") }, t("bulk.clear"))
|
|
3563
5418
|
)
|
|
3564
|
-
)
|
|
3565
|
-
),
|
|
3566
|
-
h("div", { className: "sm-markFilters" },
|
|
3567
|
-
h("div", { className: "sm-markFiltersGroup" },
|
|
3568
|
-
filterBtn("all", t("panel.filter.all")),
|
|
3569
|
-
filterBtn("active", t("panel.filter.active")),
|
|
3570
|
-
filterBtn("archived", t("panel.filter.archived")),
|
|
3571
|
-
h("button", { type: "button", className: "sm-filterBtn sm-markFilterToggle" + (onlyFavorite ? " sm-on" : ""), "aria-label": t("marks.filter.favorite.aria"), "aria-pressed": onlyFavorite, disabled: !marksReady, onClick: () => setOnlyFavorite(value => !value) }, "★ " + t("marks.filter.favorite")),
|
|
3572
|
-
h("button", { type: "button", className: "sm-filterBtn sm-markFilterToggle" + (onlyReview ? " sm-on" : ""), "aria-label": t("marks.filter.review.aria"), "aria-pressed": onlyReview, disabled: !marksReady, onClick: () => setOnlyReview(value => !value) }, "◷ " + t("marks.filter.review"))
|
|
3573
5419
|
),
|
|
3574
|
-
h("div", { className: "sm-
|
|
3575
|
-
|
|
3576
|
-
h("button", {
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
h("button", { type: "button", className: "sm-
|
|
3585
|
-
|
|
3586
|
-
)
|
|
3587
|
-
),
|
|
3588
|
-
h("div", { className: "sm-resultSummary" },
|
|
3589
|
-
h("span", { role: "status", "aria-live": "polite", "aria-atomic": "true" }, t("panel.count", { shown: rows.length, total: allRows.length })),
|
|
3590
|
-
hasViewChanges ? h("button", { type: "button", className: "sm-resetFilters", onClick: resetView }, t("panel.reset")) : null
|
|
5420
|
+
h("div", { className: "sm-resultSummary" },
|
|
5421
|
+
h("span", { role: "status", "aria-live": "polite", "aria-atomic": "true" }, t("panel.count", { shown: rows.length, total: allRows.length })),
|
|
5422
|
+
hasViewChanges ? h("button", { type: "button", className: "sm-resetFilters", onClick: resetView }, t("panel.reset")) : null
|
|
5423
|
+
),
|
|
5424
|
+
annotations.loading && !annotations.loaded ? h("div", { className: "sm-workspaceNotice", role: "status" }, t("marks.loading")) : null,
|
|
5425
|
+
annotations.error ? h("div", { className: "sm-workspaceNotice", role: "alert" }, t("marks.error", { message: annotations.error }), h("button", { type: "button", className: "sm-resetFilters", onClick: () => annotationStore.load(true) }, t("marks.retry"))) : null,
|
|
5426
|
+
creationTimeUnavailable && !(workspacesLoading && workspaces.length === 0) ? h("div", { className: "sm-workspaceNotice", role: "status" }, t("panel.sort.unavailable")) : null,
|
|
5427
|
+
(workspacesLoading && workspaces.length === 0) ? h("div", { className: "sm-workspaceNotice", role: "status" }, t("panel.workspace.loading")) : null,
|
|
5428
|
+
workspacesError ? h("div", { className: "sm-workspaceNotice", role: "alert" },
|
|
5429
|
+
h("span", null, t("panel.workspace.error", { message: workspacesError })),
|
|
5430
|
+
h("button", { type: "button", className: "sm-resetFilters", onClick: () => setWorkspaceRefresh(value => value + 1) }, t("panel.workspace.retry"))
|
|
5431
|
+
) : null
|
|
3591
5432
|
),
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
onSelectAll: onBulkSelectAll, onClear: onBulkClear,
|
|
3605
|
-
onAction: onBulkAction,
|
|
3606
|
-
onOpenTagDialog: onBulkTagsAdd,
|
|
3607
|
-
onOpenPriorityDialog: onBulkPriority,
|
|
3608
|
-
onOpenMoveDialog: onBulkMove,
|
|
3609
|
-
onOpenPresetDialog: onBulkPreset
|
|
3610
|
-
}) : null,
|
|
3611
|
-
rowsList
|
|
5433
|
+
error ? h("div", { className: "sm-error", role: "alert" }, t("error.operation", { message: error })) : null,
|
|
5434
|
+
(selectedIds.size > 0 || selectModeEnabled) ? h(BulkActionBar, {
|
|
5435
|
+
t, selectedCount: selectedIds.size, filteredCount: rows.length, busy: bulkBusy,
|
|
5436
|
+
onSelectAll: onBulkSelectAll, onClear: onBulkClear,
|
|
5437
|
+
onAction: onBulkAction,
|
|
5438
|
+
onOpenTagDialog: onBulkTagsAdd,
|
|
5439
|
+
onOpenPriorityDialog: onBulkPriority,
|
|
5440
|
+
onOpenMoveDialog: onBulkMove,
|
|
5441
|
+
onOpenPresetDialog: onBulkPreset
|
|
5442
|
+
}) : null,
|
|
5443
|
+
rowsList
|
|
5444
|
+
)
|
|
3612
5445
|
)
|
|
3613
5446
|
)
|
|
3614
5447
|
)));
|
|
@@ -3618,13 +5451,27 @@ function isTopmostDialog(z) {
|
|
|
3618
5451
|
onClose: () => { if (busyId === null) setConfirmFor(null); },
|
|
3619
5452
|
title: t("confirm.delete.title"),
|
|
3620
5453
|
description: (confirmFor.displayTitle && t("confirm.delete.desc", { title: confirmFor.displayTitle })) || "",
|
|
3621
|
-
warning:
|
|
5454
|
+
warning: (() => {
|
|
5455
|
+
const baseWarning = (confirmFor.running ? (t("confirm.delete.running") + " " + t("bulk.dialog.warning.delete")) : t("bulk.dialog.warning.delete"));
|
|
5456
|
+
if (confirmPreviewState.loading) {
|
|
5457
|
+
const loadingMsg = t("confirm.delete.previewLoading") || "正在检查关联的子智能体会话…";
|
|
5458
|
+
return `${loadingMsg}\n${baseWarning}`;
|
|
5459
|
+
}
|
|
5460
|
+
if (confirmPreviewState.error) {
|
|
5461
|
+
const errorMsg = confirmPreviewState.error;
|
|
5462
|
+
return `${errorMsg}\n${baseWarning}`;
|
|
5463
|
+
}
|
|
5464
|
+
const subagentWarning = confirmPreviewState.subagentCount > 0 ? t("confirm.delete.subagents", { count: confirmPreviewState.subagentCount }) : "";
|
|
5465
|
+
return subagentWarning ? `${subagentWarning}\n${baseWarning}` : baseWarning;
|
|
5466
|
+
})(),
|
|
5467
|
+
confirmDisabled: confirmPreviewState.loading || Boolean(confirmPreviewState.error),
|
|
3622
5468
|
confirmLabel: t("confirm.delete.confirm"),
|
|
3623
5469
|
cancelLabel: t("confirm.cancel"),
|
|
3624
5470
|
busy: busyId !== null,
|
|
3625
5471
|
danger: true,
|
|
3626
5472
|
onCancel: () => { if (busyId === null) setConfirmFor(null); },
|
|
3627
5473
|
onConfirm: () => {
|
|
5474
|
+
if (confirmPreviewState.loading || confirmPreviewState.error) return;
|
|
3628
5475
|
const target = confirmFor;
|
|
3629
5476
|
setConfirmFor(null);
|
|
3630
5477
|
runRow(target.id, () => onRemove(target.id));
|
|
@@ -3710,12 +5557,16 @@ function isTopmostDialog(z) {
|
|
|
3710
5557
|
delete: t("bulk.confirm.delete")
|
|
3711
5558
|
})[action] || t("bulk.dialog.execute");
|
|
3712
5559
|
const bulkPreviewDialog = bulkPreview ? h(BatchPreviewDialog, {
|
|
3713
|
-
open: true, t, actionLabel: bulkPreview.actionLabel,
|
|
5560
|
+
open: true, t, action: bulkPreview.action, actionLabel: bulkPreview.actionLabel,
|
|
5561
|
+
title: bulkPreview.action === "delete" ? t("confirm.delete.title") : undefined,
|
|
3714
5562
|
sessions: bulkPreview.sessions, warning: bulkPreview.warning,
|
|
3715
5563
|
confirmLabel: bulkConfirmLabelFor(bulkPreview.action),
|
|
3716
5564
|
danger: bulkPreview.action === "delete",
|
|
5565
|
+
loading: bulkPreview.loading === true,
|
|
5566
|
+
error: bulkPreview.error || null,
|
|
3717
5567
|
onCancel: () => setBulkPreview(null),
|
|
3718
5568
|
onExecute: () => {
|
|
5569
|
+
if (bulkPreview.loading || bulkPreview.error) return;
|
|
3719
5570
|
const preview = bulkPreview;
|
|
3720
5571
|
setBulkPreview(null);
|
|
3721
5572
|
void executeBulk({
|
|
@@ -3771,10 +5622,11 @@ function isTopmostDialog(z) {
|
|
|
3771
5622
|
onCancel: () => setBulkPresetDraft(null),
|
|
3772
5623
|
onApply: onBulkPresetApply
|
|
3773
5624
|
}) : null;
|
|
5625
|
+
const workspaceArchiveConfirmDialog = null;
|
|
3774
5626
|
// Bulk dialogs are portaled into the overlay root like every other
|
|
3775
5627
|
// dialog, so their static z-index (10002) only orders them inside that
|
|
3776
5628
|
// context; the root's own 1050 keeps them below DSH's 1100 tooltip tier.
|
|
3777
|
-
return h(React.Fragment, null, panelModal, annotationDialog, moveDialog, deleteDialog, migrateDialog, bulkPreviewDialog, bulkProgressDialog, bulkResultDialog, bulkTagDialog, bulkPriorityDialog, bulkMoveDialog, bulkPresetDialog);
|
|
5629
|
+
return h(React.Fragment, null, panelModal, annotationDialog, moveDialog, deleteDialog, migrateDialog, bulkPreviewDialog, bulkProgressDialog, bulkResultDialog, bulkTagDialog, bulkPriorityDialog, bulkMoveDialog, bulkPresetDialog, workspaceArchiveConfirmDialog);
|
|
3778
5630
|
}
|
|
3779
5631
|
|
|
3780
5632
|
function HeaderAction(props) {
|
|
@@ -3820,6 +5672,29 @@ function isTopmostDialog(z) {
|
|
|
3820
5672
|
|
|
3821
5673
|
const [confirmFor, setConfirmFor] = useState(null);
|
|
3822
5674
|
const [confirmAnchor, setConfirmAnchor] = useState(null);
|
|
5675
|
+
const [confirmPreviewState, setConfirmPreviewState] = useState({ loading: false, error: null, subagentCount: 0 });
|
|
5676
|
+
useEffect(() => {
|
|
5677
|
+
if (!confirmFor || !confirmFor.id) {
|
|
5678
|
+
setConfirmPreviewState({ loading: false, error: null, subagentCount: 0 });
|
|
5679
|
+
return;
|
|
5680
|
+
}
|
|
5681
|
+
let alive = true;
|
|
5682
|
+
setConfirmPreviewState({ loading: true, error: null, subagentCount: 0 });
|
|
5683
|
+
fetchApi("/delete-preview?sessionId=" + encodeURIComponent(confirmFor.id))
|
|
5684
|
+
.then((res) => {
|
|
5685
|
+
if (!alive) return;
|
|
5686
|
+
if (res && res.ok && res.result && typeof res.result.subagentCount === "number") {
|
|
5687
|
+
setConfirmPreviewState({ loading: false, error: null, subagentCount: res.result.subagentCount });
|
|
5688
|
+
} else {
|
|
5689
|
+
setConfirmPreviewState({ loading: false, error: res?.error || (t ? t("confirm.delete.previewError") : "检查关联子智能体会话失败,请稍后重试"), subagentCount: 0 });
|
|
5690
|
+
}
|
|
5691
|
+
})
|
|
5692
|
+
.catch((err) => {
|
|
5693
|
+
if (!alive) return;
|
|
5694
|
+
setConfirmPreviewState({ loading: false, error: (err && err.message) || (t ? t("confirm.delete.previewError") : "检查关联子智能体会话失败,请稍后重试"), subagentCount: 0 });
|
|
5695
|
+
});
|
|
5696
|
+
return () => { alive = false; };
|
|
5697
|
+
}, [confirmFor?.id]);
|
|
3823
5698
|
const [moveFor, setMoveFor] = useState(null);
|
|
3824
5699
|
const [moveAnchor, setMoveAnchor] = useState(null);
|
|
3825
5700
|
const [workspaces, setWorkspaces] = useState([]);
|
|
@@ -4149,13 +6024,30 @@ function isTopmostDialog(z) {
|
|
|
4149
6024
|
onClose: () => setConfirmFor(null),
|
|
4150
6025
|
onCancel: () => setConfirmFor(null),
|
|
4151
6026
|
onConfirm: () => {
|
|
6027
|
+
if (confirmPreviewState.loading || confirmPreviewState.error) return;
|
|
4152
6028
|
const target = confirmFor;
|
|
4153
6029
|
setConfirmFor(null);
|
|
4154
6030
|
runWithAlert("delete", () => onRemove(target.id));
|
|
4155
6031
|
},
|
|
4156
6032
|
title: t ? t("confirm.delete.title") : "删除会话",
|
|
4157
6033
|
description: (confirmFor && confirmFor.displayTitle && (t ? t("confirm.delete.desc", { title: confirmFor.displayTitle }) : ("「" + confirmFor.displayTitle + "」:删除,不可恢复"))) || "",
|
|
4158
|
-
warning: (
|
|
6034
|
+
warning: (() => {
|
|
6035
|
+
const baseWarn = (confirmFor && confirmFor.running && t ? t("confirm.delete.running") + " " : "") +
|
|
6036
|
+
(t ? t("bulk.dialog.warning.delete") : "删除操作不可撤销,请确认后再继续。");
|
|
6037
|
+
if (confirmPreviewState.loading) {
|
|
6038
|
+
const loadingMsg = (t ? t("confirm.delete.previewLoading") : "") || "正在检查关联的子智能体会话…";
|
|
6039
|
+
return `${loadingMsg}\n${baseWarn}`;
|
|
6040
|
+
}
|
|
6041
|
+
if (confirmPreviewState.error) {
|
|
6042
|
+
const errorMsg = confirmPreviewState.error;
|
|
6043
|
+
return `${errorMsg}\n${baseWarn}`;
|
|
6044
|
+
}
|
|
6045
|
+
const subagentsWarn = confirmPreviewState.subagentCount > 0
|
|
6046
|
+
? (t ? t("confirm.delete.subagents", { count: confirmPreviewState.subagentCount }) : `将连带删除 ${confirmPreviewState.subagentCount} 个关联的子智能体会话。`)
|
|
6047
|
+
: "";
|
|
6048
|
+
return subagentsWarn ? `${subagentsWarn}\n${baseWarn}` : baseWarn;
|
|
6049
|
+
})(),
|
|
6050
|
+
confirmDisabled: confirmPreviewState.loading || Boolean(confirmPreviewState.error),
|
|
4159
6051
|
confirmLabel: t ? t("confirm.delete.confirm") : "确认删除",
|
|
4160
6052
|
cancelLabel: t ? t("confirm.cancel") : "取消",
|
|
4161
6053
|
busy: false,
|
|
@@ -4185,36 +6077,55 @@ function isTopmostDialog(z) {
|
|
|
4185
6077
|
}
|
|
4186
6078
|
|
|
4187
6079
|
class SafePanel extends React.Component {
|
|
4188
|
-
constructor(p) { super(p); this.state = { failed: false }; }
|
|
4189
|
-
static getDerivedStateFromError() { return { failed: true }; }
|
|
6080
|
+
constructor(p) { super(p); this.state = { failed: false, error: null }; }
|
|
6081
|
+
static getDerivedStateFromError(error) { return { failed: true, error }; }
|
|
4190
6082
|
componentDidCatch(error) { try { console.error("[dsh-session-manager] SessionManagerPanel crashed:", error); } catch (_) {} }
|
|
4191
6083
|
render() {
|
|
4192
|
-
if (this.state.failed)
|
|
6084
|
+
if (this.state.failed) {
|
|
6085
|
+
const t = typeof this.props.t === "function" ? this.props.t : (k => k);
|
|
6086
|
+
const errorOverlay = renderInOverlay(h("div", { className: "sm-overlayLayer" },
|
|
6087
|
+
h("div", { className: "sm-nativeDialogLayer" },
|
|
6088
|
+
h("div", { className: "sm-nativeDialog sm-panelDialog", style: { padding: "20px" } },
|
|
6089
|
+
h("h3", null, t("panel.title") || "会话管理"),
|
|
6090
|
+
h("div", { className: "sm-error" }, "面板加载出错: " + (this.state.error?.message || String(this.state.error))),
|
|
6091
|
+
h("button", {
|
|
6092
|
+
type: "button",
|
|
6093
|
+
className: "sm-resetFilters",
|
|
6094
|
+
onClick: () => {
|
|
6095
|
+
this.setState({ failed: false, error: null });
|
|
6096
|
+
try { this.props.panelStore.set(false); } catch (_) {}
|
|
6097
|
+
}
|
|
6098
|
+
}, t("confirm.cancel") || "关闭")
|
|
6099
|
+
)
|
|
6100
|
+
)
|
|
6101
|
+
));
|
|
6102
|
+
return errorOverlay;
|
|
6103
|
+
}
|
|
4193
6104
|
return h(SessionManagerPanel, {
|
|
4194
6105
|
open: true,
|
|
4195
6106
|
onClose: () => { try { this.props.panelStore.set(false); } catch (_) {} },
|
|
4196
|
-
useSessions: this.props.useSessions,
|
|
4197
|
-
useWorkspaces: this.props.useWorkspaces,
|
|
6107
|
+
useSessions: this.props.useSessions || this.props.props?.useSessions,
|
|
6108
|
+
useWorkspaces: this.props.useWorkspaces || this.props.props?.useWorkspaces,
|
|
4198
6109
|
t: this.props.t,
|
|
4199
6110
|
// Bulk operations need to refresh ctx.sessions.list and the
|
|
4200
6111
|
// workspace projection after /batch mutates disk state so the
|
|
4201
6112
|
// panel reflects the new layout.
|
|
4202
6113
|
onRefreshAfterBulk: async (...args) => {
|
|
4203
|
-
try { await this.props.props
|
|
6114
|
+
try { await this.props.props?.onBulkRefresh?.(...args); } catch (_) { /* ignore */ }
|
|
4204
6115
|
},
|
|
4205
|
-
onOpen: (id) => { try { this.props.panelStore.set(false); this.props.props
|
|
4206
|
-
onArchive: this.props.props
|
|
4207
|
-
onUnarchive: this.props.props
|
|
4208
|
-
onRemove: this.props.props
|
|
4209
|
-
onMove: this.props.props
|
|
4210
|
-
onMigrate: this.props.props
|
|
6116
|
+
onOpen: (id) => { try { this.props.panelStore.set(false); this.props.props?.onOpen?.(id); } catch (_) {} },
|
|
6117
|
+
onArchive: this.props.props?.onArchive,
|
|
6118
|
+
onUnarchive: this.props.props?.onUnarchive,
|
|
6119
|
+
onRemove: this.props.props?.onRemove,
|
|
6120
|
+
onMove: this.props.props?.onMove,
|
|
6121
|
+
onMigrate: this.props.props?.onMigrate
|
|
4211
6122
|
});
|
|
4212
6123
|
}
|
|
4213
6124
|
}
|
|
4214
6125
|
|
|
4215
6126
|
function FooterAction(props) {
|
|
4216
|
-
const t = props.t;
|
|
4217
|
-
const onOpenPanel = props.onOpenPanel;
|
|
6127
|
+
const t = typeof props.t === "function" ? props.t : (k => k);
|
|
6128
|
+
const onOpenPanel = typeof props.onOpenPanel === "function" ? props.onOpenPanel : () => panelStore.toggle();
|
|
4218
6129
|
// props.wide comes from SidebarRoot via SidebarFooterActionOwnerProps.
|
|
4219
6130
|
// When the sidebar is collapsed into the 56px rail, render a 36x36
|
|
4220
6131
|
// icon-only button so the Chinese label does not word-wrap vertically
|
|
@@ -4245,6 +6156,7 @@ function isTopmostDialog(z) {
|
|
|
4245
6156
|
wide ? h("span", { className: "sm-footerBtn-label" }, t("footer.label")) : null
|
|
4246
6157
|
),
|
|
4247
6158
|
open ? h(SafePanel, {
|
|
6159
|
+
key: "sm-safe-panel",
|
|
4248
6160
|
panelStore: panelStore,
|
|
4249
6161
|
props: props,
|
|
4250
6162
|
t: t,
|
|
@@ -4532,18 +6444,6 @@ function isTopmostDialog(z) {
|
|
|
4532
6444
|
),
|
|
4533
6445
|
h("div", { className: "sm-settingsSection" },
|
|
4534
6446
|
h("div", { className: "sm-settingsSectionTitle" }, t("settings.prefSection")),
|
|
4535
|
-
h("div", { className: "sm-settingsRow" },
|
|
4536
|
-
h("span", null, t("settings.registry")),
|
|
4537
|
-
h("select", {
|
|
4538
|
-
className: "sm-settingsSelect",
|
|
4539
|
-
value: currentRegistry,
|
|
4540
|
-
onChange: onRegistryChange,
|
|
4541
|
-
"aria-label": t("settings.registry")
|
|
4542
|
-
},
|
|
4543
|
-
h("option", { value: "registry.npmjs.org" }, t("settings.registry.npm")),
|
|
4544
|
-
h("option", { value: "registry.npmmirror.com" }, t("settings.registry.china"))
|
|
4545
|
-
)
|
|
4546
|
-
),
|
|
4547
6447
|
h("div", { className: "sm-settingsRow" },
|
|
4548
6448
|
h("span", null, t("update.autoCheck")),
|
|
4549
6449
|
h("label", { className: "sm-settingsCheckbox" },
|
|
@@ -4557,7 +6457,22 @@ function isTopmostDialog(z) {
|
|
|
4557
6457
|
)
|
|
4558
6458
|
),
|
|
4559
6459
|
h("div", { className: "sm-settingsRow" },
|
|
4560
|
-
h("span", null, t("settings.
|
|
6460
|
+
h("span", null, t("settings.registry")),
|
|
6461
|
+
h("select", {
|
|
6462
|
+
className: "sm-settingsSelect",
|
|
6463
|
+
value: currentRegistry,
|
|
6464
|
+
onChange: onRegistryChange,
|
|
6465
|
+
"aria-label": t("settings.registry")
|
|
6466
|
+
},
|
|
6467
|
+
h("option", { value: "registry.npmjs.org" }, t("settings.registry.npm")),
|
|
6468
|
+
h("option", { value: "registry.npmmirror.com" }, t("settings.registry.china"))
|
|
6469
|
+
)
|
|
6470
|
+
),
|
|
6471
|
+
h("div", { className: "sm-settingsRow" },
|
|
6472
|
+
h("div", { className: "sm-settingsRowLeft" },
|
|
6473
|
+
h("span", null, t("settings.dialogOpacity")),
|
|
6474
|
+
h("span", { className: "sm-settingsHint sm-settingsHintInline" }, t("settings.dialogOpacity.hint"))
|
|
6475
|
+
),
|
|
4561
6476
|
h("div", { className: "sm-settingsSlider" },
|
|
4562
6477
|
h("input", {
|
|
4563
6478
|
type: "range",
|
|
@@ -4581,39 +6496,42 @@ function isTopmostDialog(z) {
|
|
|
4581
6496
|
onClick: () => updateStore.resetDialogOpacity()
|
|
4582
6497
|
}, t("settings.dialogOpacity.reset"))
|
|
4583
6498
|
)
|
|
4584
|
-
)
|
|
4585
|
-
h("div", { className: "sm-settingsHint" }, t("settings.dialogOpacity.hint"))
|
|
6499
|
+
)
|
|
4586
6500
|
),
|
|
4587
6501
|
h("div", { className: "sm-settingsSection" },
|
|
4588
6502
|
h("div", { className: "sm-settingsSectionTitle" }, t("settings.projectSection")),
|
|
4589
|
-
h("div", { className: "sm-settingsRow
|
|
4590
|
-
h("
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
6503
|
+
h("div", { className: "sm-settingsRow" },
|
|
6504
|
+
h("div", { className: "sm-settingsProjectLeft" },
|
|
6505
|
+
h("span", { className: "sm-settingsProjectLabel" }, t("settings.github")),
|
|
6506
|
+
h("a", {
|
|
6507
|
+
href: "https://github.com/hkkz9522/dsh-session-manager",
|
|
6508
|
+
target: "_blank",
|
|
6509
|
+
rel: "noopener noreferrer",
|
|
6510
|
+
className: "sm-settingsLink"
|
|
6511
|
+
}, "hkkz9522/dsh-session-manager")
|
|
6512
|
+
),
|
|
6513
|
+
h("div", { className: "sm-settingsBadgeActions" },
|
|
6514
|
+
renderTip(t("settings.star.tip"), h("a", {
|
|
6515
|
+
href: "https://github.com/hkkz9522/dsh-session-manager",
|
|
6516
|
+
target: "_blank",
|
|
6517
|
+
rel: "noopener noreferrer",
|
|
6518
|
+
className: "sm-settingsBadgeLink",
|
|
6519
|
+
"aria-label": t("settings.star.tip")
|
|
6520
|
+
},
|
|
6521
|
+
h(StarIcon, { size: 14 }),
|
|
6522
|
+
h("span", null, t("settings.star"))
|
|
6523
|
+
)),
|
|
6524
|
+
renderTip(t("settings.feedback.tip"), h("a", {
|
|
6525
|
+
href: "https://github.com/hkkz9522/dsh-session-manager/issues",
|
|
6526
|
+
target: "_blank",
|
|
6527
|
+
rel: "noopener noreferrer",
|
|
6528
|
+
className: "sm-settingsBadgeLink",
|
|
6529
|
+
"aria-label": t("settings.feedback.tip")
|
|
6530
|
+
},
|
|
6531
|
+
h(IssueIcon, { size: 14 }),
|
|
6532
|
+
h("span", null, t("settings.feedback"))
|
|
6533
|
+
))
|
|
6534
|
+
)
|
|
4617
6535
|
)
|
|
4618
6536
|
)
|
|
4619
6537
|
);
|
|
@@ -4691,6 +6609,15 @@ function isTopmostDialog(z) {
|
|
|
4691
6609
|
await runArchiveCommand("archive", sessionId);
|
|
4692
6610
|
},
|
|
4693
6611
|
onUnarchive: async (sessionId) => {
|
|
6612
|
+
for (const [, rec] of workspaceArchiveStore.getAllRecords()) {
|
|
6613
|
+
if (rec.archived === true && Array.isArray(rec.sessionIds) && rec.sessionIds.includes(sessionId)) {
|
|
6614
|
+
if (typeof window !== "undefined" && typeof window.alert === "function") {
|
|
6615
|
+
const msg = (typeof t === "function" ? t("error.workspaceArchived") : null) || "所属工作区已归档,无法取消归档该会话。请先在工作区管理中恢复工作区。";
|
|
6616
|
+
window.alert(msg);
|
|
6617
|
+
}
|
|
6618
|
+
return;
|
|
6619
|
+
}
|
|
6620
|
+
}
|
|
4694
6621
|
// DSH ships the inverse command in 0.2.x; the old assumption that only
|
|
4695
6622
|
// archive existed is what made unarchive bypass client state.
|
|
4696
6623
|
await runArchiveCommand("unarchive", sessionId);
|
|
@@ -4698,7 +6625,18 @@ function isTopmostDialog(z) {
|
|
|
4698
6625
|
onRemove: async (sessionId) => {
|
|
4699
6626
|
const wasCurrent = isCurrentSession(sessionId);
|
|
4700
6627
|
const response = await callApi("/delete", { sessionId });
|
|
4701
|
-
if (!response.ok)
|
|
6628
|
+
if (!response.ok) {
|
|
6629
|
+
if (Array.isArray(response.deletedSubagents) && response.deletedSubagents.length > 0) {
|
|
6630
|
+
try { await annotationStore.load(true); } catch (_) {}
|
|
6631
|
+
try { await ctx.sessions?.refresh?.(); } catch (_) {}
|
|
6632
|
+
try { await ctx.workspaces?.refresh?.(); } catch (_) {}
|
|
6633
|
+
}
|
|
6634
|
+
const err = new Error(response.error || "delete failed");
|
|
6635
|
+
err.deletedSubagents = response.deletedSubagents || [];
|
|
6636
|
+
err.remainingSessions = response.remainingSessions || [sessionId];
|
|
6637
|
+
err.partialFailure = Boolean(response.partialFailure);
|
|
6638
|
+
throw err;
|
|
6639
|
+
}
|
|
4702
6640
|
await annotationStore.load(true);
|
|
4703
6641
|
if (response.result?.warning) window.alert(response.result.warning);
|
|
4704
6642
|
if (wasCurrent || isCurrentSession(sessionId)) {
|
|
@@ -4771,6 +6709,16 @@ function isTopmostDialog(z) {
|
|
|
4771
6709
|
}
|
|
4772
6710
|
}
|
|
4773
6711
|
},
|
|
6712
|
+
useSessions: (selector = s => s) => useSyncExternalStore(
|
|
6713
|
+
(cb) => (ctx.sessions?.list?.subscribe ? ctx.sessions.list.subscribe(cb) : () => {}),
|
|
6714
|
+
() => (ctx.sessions?.list?.getSnapshot ? selector(ctx.sessions.list.getSnapshot()) : selector({ ids: [], byId: {} })),
|
|
6715
|
+
() => (ctx.sessions?.list?.getSnapshot ? selector(ctx.sessions.list.getSnapshot()) : selector({ ids: [], byId: {} }))
|
|
6716
|
+
),
|
|
6717
|
+
useWorkspaces: (selector = s => s) => useSyncExternalStore(
|
|
6718
|
+
(cb) => (ctx.workspaces?.list?.subscribe ? ctx.workspaces.list.subscribe(cb) : () => {}),
|
|
6719
|
+
() => (ctx.workspaces?.list?.getSnapshot ? selector(ctx.workspaces.list.getSnapshot()) : selector({ items: [] })),
|
|
6720
|
+
() => (ctx.workspaces?.list?.getSnapshot ? selector(ctx.workspaces.list.getSnapshot()) : selector({ items: [] }))
|
|
6721
|
+
),
|
|
4774
6722
|
});
|
|
4775
6723
|
ctx.slots.inject("conversation.session.header.actions", () => ctx.slots.register({
|
|
4776
6724
|
name: "conversation.session.header.actions",
|
|
@@ -4822,7 +6770,7 @@ function isTopmostDialog(z) {
|
|
|
4822
6770
|
ctx.effect(() => {
|
|
4823
6771
|
if (!updateStore.getAutoCheck()) return;
|
|
4824
6772
|
const timer = setTimeout(() => {
|
|
4825
|
-
updateStore.
|
|
6773
|
+
updateStore.maybeAutoCheck({ isStartup: true }).catch(() => {});
|
|
4826
6774
|
}, 1500);
|
|
4827
6775
|
return () => {
|
|
4828
6776
|
try {
|
|
@@ -4832,6 +6780,34 @@ function isTopmostDialog(z) {
|
|
|
4832
6780
|
};
|
|
4833
6781
|
}, "session-manager: auto update check");
|
|
4834
6782
|
|
|
6783
|
+
ctx.effect(() => {
|
|
6784
|
+
const disposes = [];
|
|
6785
|
+
if (ctx.workspaces?.list) {
|
|
6786
|
+
const d = workspaceArchiveStore.installWorkspaceModel(ctx.workspaces.list);
|
|
6787
|
+
if (typeof d === "function") disposes.push(d);
|
|
6788
|
+
}
|
|
6789
|
+
if (ctx.workspaces) {
|
|
6790
|
+
const d = workspaceArchiveStore.installWorkspaceCreate(ctx.workspaces);
|
|
6791
|
+
if (typeof d === "function") disposes.push(d);
|
|
6792
|
+
}
|
|
6793
|
+
if (ctx.uiWorkspace) {
|
|
6794
|
+
const d = workspaceArchiveStore.installConnectWorkspace(ctx.uiWorkspace);
|
|
6795
|
+
if (typeof d === "function") disposes.push(d);
|
|
6796
|
+
}
|
|
6797
|
+
return () => {
|
|
6798
|
+
for (const d of disposes) {
|
|
6799
|
+
try { d(); } catch (_) {}
|
|
6800
|
+
}
|
|
6801
|
+
};
|
|
6802
|
+
}, "session-manager: workspace sidebar hide");
|
|
6803
|
+
|
|
6804
|
+
ctx.effect(() => {
|
|
6805
|
+
const off = installCustomDropdownInterceptor();
|
|
6806
|
+
return () => {
|
|
6807
|
+
try { if (typeof off === "function") off(); } catch (_) {}
|
|
6808
|
+
};
|
|
6809
|
+
}, "session-manager: custom select popups");
|
|
6810
|
+
|
|
4835
6811
|
// Keep <html data-sm-theme> in step with DSH through the official theme
|
|
4836
6812
|
// event. ui-layout's ThemePresenter subscribes to the same event and
|
|
4837
6813
|
// writes documentElement.colorScheme plus body[data-ds-dark-theme], so
|
|
@@ -4855,14 +6831,32 @@ function isTopmostDialog(z) {
|
|
|
4855
6831
|
exports.apply = apply;
|
|
4856
6832
|
exports.inject = inject;
|
|
4857
6833
|
exports.updateStore = updateStore;
|
|
6834
|
+
exports.panelStore = panelStore;
|
|
4858
6835
|
exports.compareSemver = compareSemver;
|
|
6836
|
+
exports.OverlayLayer = OverlayLayer;
|
|
4859
6837
|
exports.UpdateDialog = UpdateDialog;
|
|
6838
|
+
exports.ConfirmDialog = ConfirmDialog;
|
|
6839
|
+
exports.MoveDialog = MoveDialog;
|
|
6840
|
+
exports.MigratePresetDialog = MigratePresetDialog;
|
|
6841
|
+
exports.BatchPreviewDialog = BatchPreviewDialog;
|
|
6842
|
+
exports.BatchResultDialog = BatchResultDialog;
|
|
6843
|
+
exports.BulkTagInputDialog = BulkTagInputDialog;
|
|
6844
|
+
exports.BulkChoiceDialog = BulkChoiceDialog;
|
|
6845
|
+
exports.AnnotationDialog = AnnotationDialog;
|
|
4860
6846
|
exports.SessionManagerSettingsCard = SessionManagerSettingsCard;
|
|
4861
6847
|
exports.WhaleIcon = WhaleIcon;
|
|
4862
6848
|
exports.NpmIcon = NpmIcon;
|
|
4863
6849
|
exports.CloseIcon = CloseIcon;
|
|
4864
6850
|
exports.StarIcon = StarIcon;
|
|
4865
6851
|
exports.IssueIcon = IssueIcon;
|
|
6852
|
+
exports.workspaceArchiveStore = workspaceArchiveStore;
|
|
6853
|
+
exports.SmSwitch = SmSwitch;
|
|
6854
|
+
exports.executeArchiveWorkspace = executeArchiveWorkspace;
|
|
6855
|
+
exports.executeUnarchiveWorkspace = executeUnarchiveWorkspace;
|
|
6856
|
+
exports.openCustomSelect = openCustomSelect;
|
|
6857
|
+
exports.closeCustomSelect = closeCustomSelect;
|
|
6858
|
+
exports.installCustomDropdownInterceptor = installCustomDropdownInterceptor;
|
|
6859
|
+
exports.SM_SELECT_SELECTOR = SM_SELECT_SELECTOR;
|
|
4866
6860
|
return module.exports;
|
|
4867
6861
|
}
|
|
4868
6862
|
});
|