dsh-better-workspace 0.17.0 → 0.17.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/dsh.plugin.json +1 -1
- package/package.json +1 -1
- package/src/client.js +53 -10
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-external/dsh-better-workspace",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"description": "侧边栏工作区树:按官方磁盘目录嵌套(官方 workspace-tree 语义),可选按名称中的 / 分组(默认关闭,设置里开启);添加工作区由官方目录流承载。Workspace tree for the DSH sidebar workspace list, nested by official disk folders with optional \"/\"-name grouping.",
|
|
6
6
|
"engines": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-better-workspace",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"description": "侧边栏工作区树:按官方磁盘目录嵌套(官方 workspace-tree 语义),可选按名称中的 / 分组(默认关闭,设置里开启);添加工作区走官方目录流。Workspace tree for the DSH sidebar: disk-path nesting (official workspace-tree semantics), with optional \"/\"-name grouping (off by default); add-workspace rides the official directory flow.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
package/src/client.js
CHANGED
|
@@ -3294,6 +3294,11 @@ window.__ModuleLoader__.load({
|
|
|
3294
3294
|
'.bw-seg-btn-on{background:var(--dsw-alias-bg-layer-2,rgba(127,127,127,.16));color:var(--dsw-alias-label-primary,#e6e6e6);font-weight:500}',
|
|
3295
3295
|
'.bw-seg-btn+.bw-seg-btn{border-left:1px solid var(--dsw-alias-border-l1,rgba(127,127,127,.25))}',
|
|
3296
3296
|
'.bw-gn-hint{font-size:12px;color:var(--dsw-alias-label-tertiary,#9a9a9a)}',
|
|
3297
|
+
// A container-only node (a workspace name-group in the session layer):
|
|
3298
|
+
// still expandable, but it carries no workspaceId to file against.
|
|
3299
|
+
'.bw-gn-row-hold{cursor:default}',
|
|
3300
|
+
'.bw-gn-row-hold:hover{background:transparent}',
|
|
3301
|
+
'.bw-gn-row-hold .bw-gn-label{color:var(--dsw-alias-label-secondary,#b8b8b8)}',
|
|
3297
3302
|
'.bw-gn-empty{font-size:12px;color:var(--dsw-alias-label-tertiary,#9a9a9a);padding:10px 8px;text-align:center}',
|
|
3298
3303
|
'.bw-gn-tree{max-height:250px;overflow:auto;padding:4px;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l1,rgba(127,127,127,.22));border-radius:8px;background:var(--dsw-alias-bg-layer-2,rgba(127,127,127,.06))}',
|
|
3299
3304
|
'.bw-gn-row{display:flex;align-items:center;gap:6px;min-height:26px;padding-right:8px;border-radius:6px;cursor:pointer;user-select:none}',
|
|
@@ -3837,7 +3842,7 @@ window.__ModuleLoader__.load({
|
|
|
3837
3842
|
const [error, setError] = React.useState('')
|
|
3838
3843
|
const plan = treeOf(kind)
|
|
3839
3844
|
const toggle = (id) => setOpenKeys((prev) => ({ ...prev, [id]: !prev[id] }))
|
|
3840
|
-
const pick = (node) => { setPicked(node); setError('') }
|
|
3845
|
+
const pick = (node) => { if (node.pickable === false) return; setPicked(node); setError('') }
|
|
3841
3846
|
const submit = () => {
|
|
3842
3847
|
const clean = String(name).split('/').filter((s) => s !== '').join('/')
|
|
3843
3848
|
if (clean === '') { setError(t('group.new.empty')); return }
|
|
@@ -3854,7 +3859,7 @@ window.__ModuleLoader__.load({
|
|
|
3854
3859
|
const expanded = openKeys[node.id] === true || (depth === 0 && openKeys[node.id] !== false)
|
|
3855
3860
|
out.push(E('div', {
|
|
3856
3861
|
key: 'n-' + node.id,
|
|
3857
|
-
className: cls('bw-gn-row', picked && picked.id === node.id && 'bw-gn-row-on'),
|
|
3862
|
+
className: cls('bw-gn-row', node.pickable === false && 'bw-gn-row-hold', picked && picked.id === node.id && 'bw-gn-row-on'),
|
|
3858
3863
|
style: { paddingLeft: 6 + depth * 14 },
|
|
3859
3864
|
role: 'treeitem',
|
|
3860
3865
|
'aria-selected': picked && picked.id === node.id ? 'true' : 'false',
|
|
@@ -5384,22 +5389,60 @@ window.__ModuleLoader__.load({
|
|
|
5384
5389
|
children: sessGroupNodesOf(g, workspaceId),
|
|
5385
5390
|
}))
|
|
5386
5391
|
const newGroupTreeOf = (kind) => {
|
|
5392
|
+
// The container tree MIRRORS the sidebar's current view mode (v0.17.1):
|
|
5393
|
+
// "workspace tree" offers the real hierarchy (disk nesting + name
|
|
5394
|
+
// groups); the one-level modes ("workspaces" / "flat") render no
|
|
5395
|
+
// hierarchy to mirror, so they fall back to a flat workspace list.
|
|
5396
|
+
// Offering a nesting the sidebar is not showing would be a lie about
|
|
5397
|
+
// where the new group lands.
|
|
5398
|
+
const treeView = groupBy === 'workspace-tree'
|
|
5387
5399
|
if (kind === 'workspace') {
|
|
5388
5400
|
// "Top level" IS a real target here (a group at the root of the
|
|
5389
5401
|
// workspace tree), so it is a node like any other.
|
|
5390
|
-
return {
|
|
5402
|
+
return {
|
|
5403
|
+
hint: null,
|
|
5404
|
+
nodes: [{
|
|
5405
|
+
id: '|', scope: '', path: '', label: t('group.new.root'), kind: 'folder',
|
|
5406
|
+
children: treeView ? wsGroupNodesOf(tree) : [],
|
|
5407
|
+
}],
|
|
5408
|
+
}
|
|
5391
5409
|
}
|
|
5392
5410
|
// A session group lives INSIDE one workspace (folders.sess is keyed by
|
|
5393
|
-
// workspaceId), so there is no "top level" to declare into
|
|
5394
|
-
// workspace
|
|
5395
|
-
//
|
|
5396
|
-
//
|
|
5397
|
-
|
|
5411
|
+
// workspaceId), so there is no "top level" to declare into — the
|
|
5412
|
+
// workspace tree IS the top level, introduced by a plain hint rather
|
|
5413
|
+
// than wrapped in a fake root node (a header row that looked like a
|
|
5414
|
+
// tree node read as a container you could pick).
|
|
5415
|
+
//
|
|
5416
|
+
// The walk follows the SAME tree the sidebar renders (disk nesting
|
|
5417
|
+
// included), not the flat registry list: a child workspace must appear
|
|
5418
|
+
// nested under its parent exactly as it does in "workspace tree" view.
|
|
5419
|
+
// Name-group folders are containers here — a session group cannot be
|
|
5420
|
+
// filed against one (they carry no workspaceId) — so they expand but
|
|
5421
|
+
// refuse selection.
|
|
5422
|
+
const sessNodesOf = (node) => {
|
|
5423
|
+
const out = []
|
|
5424
|
+
for (const f of node.folders || []) {
|
|
5425
|
+
out.push({ id: f.scope + '|' + f.path, scope: '', path: '', label: f.name, kind: 'folder', pickable: false, children: sessNodesOf(f) })
|
|
5426
|
+
}
|
|
5427
|
+
for (const w of node.workspaces || []) {
|
|
5428
|
+
const inner = sessGroupNodesOf(buildSessionTree(sessionsOf(w), sessionSlash, sessFolders, w.workspaceId), w.workspaceId)
|
|
5429
|
+
const subNodes = w.sub ? sessNodesOf(w.sub) : []
|
|
5430
|
+
out.push({
|
|
5431
|
+
id: w.workspaceId + '|', scope: w.workspaceId, path: '', label: w.leaf || w.title, kind: 'ws',
|
|
5432
|
+
children: [...inner, ...subNodes],
|
|
5433
|
+
})
|
|
5434
|
+
}
|
|
5435
|
+
return out
|
|
5436
|
+
}
|
|
5437
|
+
if (treeView) return { hint: t('group.new.pickWorkspace'), nodes: sessNodesOf(tree) }
|
|
5438
|
+
// One-level modes: every workspace sits at the root, exactly as the
|
|
5439
|
+
// sidebar draws it (raw items — there is no .sub level to nest here).
|
|
5440
|
+
const flat = []
|
|
5398
5441
|
for (const w of items) {
|
|
5399
5442
|
const inner = sessGroupNodesOf(buildSessionTree(sessionsOf(w), sessionSlash, sessFolders, w.workspaceId), w.workspaceId)
|
|
5400
|
-
|
|
5443
|
+
flat.push({ id: w.workspaceId + '|', scope: w.workspaceId, path: '', label: w.leaf || w.title, kind: 'ws', children: inner })
|
|
5401
5444
|
}
|
|
5402
|
-
return { hint: t('group.new.pickWorkspace'), nodes }
|
|
5445
|
+
return { hint: t('group.new.pickWorkspace'), nodes: flat }
|
|
5403
5446
|
}
|
|
5404
5447
|
/**
|
|
5405
5448
|
* Picker entries for the header button: every workspace, then its
|