@dsh-workbench/shared 0.1.7 → 0.1.8
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/dist/api/dsh-client.d.ts +11 -0
- package/dist/components/Activity.css +69 -0
- package/dist/components/Activity.d.ts +23 -0
- package/dist/components/Activity.js +23 -0
- package/dist/components/ApprovalPlan.css +41 -0
- package/dist/components/ApprovalPlan.d.ts +13 -0
- package/dist/components/ApprovalPlan.js +11 -0
- package/dist/components/Card.css +20 -0
- package/dist/components/Card.d.ts +13 -0
- package/dist/components/Card.js +8 -0
- package/dist/components/Note.css +14 -0
- package/dist/components/Note.d.ts +8 -0
- package/dist/components/Note.js +6 -0
- package/dist/components/ResourceStates.css +5 -1
- package/dist/components/Rows.css +30 -0
- package/dist/components/Rows.d.ts +11 -0
- package/dist/components/Rows.js +10 -0
- package/dist/components/SettingsSection.css +26 -0
- package/dist/components/SettingsSection.d.ts +9 -0
- package/dist/components/SettingsSection.js +9 -0
- package/dist/components/Stack.css +7 -0
- package/dist/components/Stack.d.ts +6 -0
- package/dist/components/Stack.js +5 -0
- package/dist/components/StateBlock.css +36 -0
- package/dist/components/StateBlock.d.ts +11 -0
- package/dist/components/StateBlock.js +12 -0
- package/dist/components/StateDot.d.ts +5 -0
- package/dist/components/StateDot.js +10 -0
- package/dist/components/icons.d.ts +1 -0
- package/dist/components/icons.js +4 -0
- package/dist/config/constants.d.ts +2 -0
- package/dist/config/constants.js +2 -0
- package/dist/host/__tests__/fakes.d.ts +41 -0
- package/dist/host/__tests__/fakes.js +76 -0
- package/dist/host/__tests__/preflight-fixtures.d.ts +19 -0
- package/dist/host/__tests__/preflight-fixtures.js +47 -0
- package/dist/host/context-inject.d.ts +24 -0
- package/dist/host/context-inject.js +74 -0
- package/dist/host/events.d.ts +9 -0
- package/dist/host/events.js +70 -0
- package/dist/host/mount-units.d.ts +52 -0
- package/dist/host/mount-units.js +186 -0
- package/dist/host/preflight.d.ts +58 -0
- package/dist/host/preflight.js +233 -0
- package/dist/host/probe-cache.d.ts +6 -0
- package/dist/host/probe-cache.js +19 -0
- package/dist/host/probe-libs.d.ts +45 -0
- package/dist/host/probe-libs.js +61 -0
- package/dist/host/probe-units.d.ts +17 -0
- package/dist/host/probe-units.js +102 -0
- package/dist/host/probe-verdict.d.ts +7 -0
- package/dist/host/probe-verdict.js +143 -0
- package/dist/host/tool-scope.d.ts +32 -0
- package/dist/host/tool-scope.js +84 -0
- package/dist/host/unit-readiness.d.ts +7 -0
- package/dist/host/unit-readiness.js +5 -0
- package/dist/host/unit-registry.d.ts +9 -0
- package/dist/host/unit-registry.js +33 -0
- package/dist/host/version-range.d.ts +2 -0
- package/dist/host/version-range.js +73 -0
- package/dist/i18n/en.js +4 -1
- package/dist/i18n/index.d.ts +5 -2
- package/dist/i18n/zh.d.ts +4 -1
- package/dist/i18n/zh.js +4 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.js +8 -0
- package/dist/lib/react.d.ts +1 -0
- package/dist/lib/react.js +1 -0
- package/package.json +1 -1
- package/src/api/dsh-client.ts +13 -0
- package/src/components/Activity.css +69 -0
- package/src/components/Activity.tsx +76 -0
- package/src/components/ApprovalPlan.css +41 -0
- package/src/components/ApprovalPlan.tsx +33 -0
- package/src/components/Card.css +20 -0
- package/src/components/Card.tsx +28 -0
- package/src/components/Note.css +14 -0
- package/src/components/Note.tsx +14 -0
- package/src/components/ResourceStates.css +5 -1
- package/src/components/Rows.css +30 -0
- package/src/components/Rows.tsx +25 -0
- package/src/components/SettingsSection.css +26 -0
- package/src/components/SettingsSection.tsx +22 -0
- package/src/components/Stack.css +7 -0
- package/src/components/Stack.tsx +11 -0
- package/src/components/StateBlock.css +36 -0
- package/src/components/StateBlock.tsx +29 -0
- package/src/components/icons.tsx +16 -0
- package/src/config/constants.ts +4 -0
- package/src/i18n/en.ts +4 -1
- package/src/i18n/zh.ts +4 -1
- package/src/index.ts +8 -0
- package/src/lib/react.test.ts +2 -1
- package/src/lib/react.ts +1 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
function agentOf(value) {
|
|
2
|
+
return typeof value === 'object' && value !== null ? value : undefined;
|
|
3
|
+
}
|
|
4
|
+
function workspaceOf(handle) {
|
|
5
|
+
const cwd = handle.session?.header?.cwd;
|
|
6
|
+
return typeof cwd === 'string' && cwd !== '' ? cwd : null;
|
|
7
|
+
}
|
|
8
|
+
export function createToolScope(options) {
|
|
9
|
+
const applied = new WeakMap();
|
|
10
|
+
const seen = new Set();
|
|
11
|
+
function toolsOf(handle) {
|
|
12
|
+
const byProperty = handle.ctx?.tools;
|
|
13
|
+
if (byProperty?.restrict !== undefined)
|
|
14
|
+
return byProperty;
|
|
15
|
+
const byGet = handle.ctx?.get?.('tools');
|
|
16
|
+
return byGet?.restrict === undefined ? undefined : byGet;
|
|
17
|
+
}
|
|
18
|
+
function sync(handle) {
|
|
19
|
+
const tools = toolsOf(handle);
|
|
20
|
+
if (tools === undefined) {
|
|
21
|
+
options.logger?.warn?.('[dsh-workbench] 拿不到 agent 作用域的工具面:这次不收窄(下次再试)');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const workspace = workspaceOf(handle);
|
|
25
|
+
const deny = [...options.deniedTools(workspace)];
|
|
26
|
+
const signature = `${workspace ?? ''}\u0000${deny.join(',')}`;
|
|
27
|
+
const previous = applied.get(handle);
|
|
28
|
+
if (previous !== undefined && previous.signature === signature)
|
|
29
|
+
return;
|
|
30
|
+
if (previous === undefined)
|
|
31
|
+
seen.add(new WeakRef(handle));
|
|
32
|
+
previous?.dispose();
|
|
33
|
+
if (deny.length === 0) {
|
|
34
|
+
options.logger?.info?.('[dsh-workbench] 这个工作区启用了全部套件:不收窄工具面');
|
|
35
|
+
applied.delete(handle);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
applied.set(handle, { signature, dispose: tools.restrict({ deny }) });
|
|
40
|
+
options.logger?.info?.(`[dsh-workbench] 按工作区收窄工具面:${workspace ?? '(未知工作区)'} 里收起 ${deny.length} 个工具(${deny.join(', ')})`);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
options.logger?.warn?.(`[dsh-workbench] 收窄工具面失败:${String(error)}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
apply(agent) {
|
|
48
|
+
const handle = agentOf(agent);
|
|
49
|
+
if (handle === undefined)
|
|
50
|
+
return;
|
|
51
|
+
sync(handle);
|
|
52
|
+
},
|
|
53
|
+
narrow(assembly, agent) {
|
|
54
|
+
const handle = agentOf(agent);
|
|
55
|
+
const tools = assembly?.tools;
|
|
56
|
+
if (handle === undefined || tools === undefined)
|
|
57
|
+
return assembly;
|
|
58
|
+
const deny = new Set(options.deniedTools(workspaceOf(handle)));
|
|
59
|
+
if (deny.size === 0)
|
|
60
|
+
return assembly;
|
|
61
|
+
const kept = tools.filter((tool) => !deny.has(tool.name));
|
|
62
|
+
return kept.length === tools.length ? assembly : { ...assembly, tools: kept };
|
|
63
|
+
},
|
|
64
|
+
reapply() {
|
|
65
|
+
for (const ref of [...seen]) {
|
|
66
|
+
const handle = ref.deref();
|
|
67
|
+
if (handle === undefined)
|
|
68
|
+
seen.delete(ref);
|
|
69
|
+
else
|
|
70
|
+
sync(handle);
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
disposeAll() {
|
|
74
|
+
for (const ref of [...seen]) {
|
|
75
|
+
const handle = ref.deref();
|
|
76
|
+
if (handle === undefined)
|
|
77
|
+
continue;
|
|
78
|
+
applied.get(handle)?.dispose();
|
|
79
|
+
applied.delete(handle);
|
|
80
|
+
}
|
|
81
|
+
seen.clear();
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { UnitManifest } from '@dsh-workbench/shared';
|
|
2
|
+
export interface UnitReadiness {
|
|
3
|
+
readonly canMount: boolean;
|
|
4
|
+
readonly missingHard: readonly string[];
|
|
5
|
+
readonly missingSoft: readonly string[];
|
|
6
|
+
}
|
|
7
|
+
export declare function unitReadiness(manifest: UnitManifest, lookup: (name: string) => unknown): UnitReadiness;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export function unitReadiness(manifest, lookup) {
|
|
2
|
+
const missingHard = manifest.host.inject.filter((name) => lookup(name) === undefined);
|
|
3
|
+
const missingSoft = (manifest.host.optional ?? []).filter((name) => lookup(name) === undefined);
|
|
4
|
+
return { canMount: missingHard.length === 0, missingHard, missingSoft };
|
|
5
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { UnitManifest } from '@dsh-workbench/shared';
|
|
2
|
+
import type { UnitHostFace } from './unit-face';
|
|
3
|
+
export interface UnitRegistry {
|
|
4
|
+
register(face: UnitHostFace): () => void;
|
|
5
|
+
all(): readonly UnitHostFace[];
|
|
6
|
+
manifests(): readonly UnitManifest[];
|
|
7
|
+
subscribe(listener: () => void): () => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function createUnitRegistry(): UnitRegistry;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export function createUnitRegistry() {
|
|
2
|
+
const faces = [];
|
|
3
|
+
const ids = new Set();
|
|
4
|
+
const listeners = new Set();
|
|
5
|
+
function notify() {
|
|
6
|
+
for (const listener of listeners)
|
|
7
|
+
listener();
|
|
8
|
+
}
|
|
9
|
+
return {
|
|
10
|
+
register(face) {
|
|
11
|
+
const id = face.manifest.id;
|
|
12
|
+
if (ids.has(id))
|
|
13
|
+
throw new Error(`套件 id 重复:${id}(id 会进持久化配置,不能撞)`);
|
|
14
|
+
ids.add(id);
|
|
15
|
+
faces.push(face);
|
|
16
|
+
notify();
|
|
17
|
+
return () => {
|
|
18
|
+
const index = faces.indexOf(face);
|
|
19
|
+
if (index < 0)
|
|
20
|
+
return;
|
|
21
|
+
faces.splice(index, 1);
|
|
22
|
+
ids.delete(id);
|
|
23
|
+
notify();
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
all: () => faces,
|
|
27
|
+
manifests: () => faces.map((face) => face.manifest),
|
|
28
|
+
subscribe(listener) {
|
|
29
|
+
listeners.add(listener);
|
|
30
|
+
return () => listeners.delete(listener);
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { compareVersions } from './release';
|
|
2
|
+
function readable(version) {
|
|
3
|
+
return compareVersions(version, '0.0.0') !== undefined;
|
|
4
|
+
}
|
|
5
|
+
function segmentsOf(version) {
|
|
6
|
+
if (!readable(version))
|
|
7
|
+
return undefined;
|
|
8
|
+
return version.split('.').map((part) => Number.parseInt(part, 10));
|
|
9
|
+
}
|
|
10
|
+
function caretUpper(base) {
|
|
11
|
+
const [major = 0, minor = 0, patch = 0] = base;
|
|
12
|
+
if (major > 0)
|
|
13
|
+
return `${major + 1}.0.0`;
|
|
14
|
+
return minor > 0 ? `0.${minor + 1}.0` : `0.0.${patch + 1}`;
|
|
15
|
+
}
|
|
16
|
+
function tildeUpper(base) {
|
|
17
|
+
const [major = 0, minor = 0] = base;
|
|
18
|
+
return `${major}.${minor + 1}.0`;
|
|
19
|
+
}
|
|
20
|
+
function comparator(token, version) {
|
|
21
|
+
const match = /^(>=|<=|>|<|=|\^|~)?\s*(.+)$/.exec(token.trim());
|
|
22
|
+
if (match === null)
|
|
23
|
+
return undefined;
|
|
24
|
+
const [, operator = '', raw = ''] = match;
|
|
25
|
+
const base = segmentsOf(raw.trim());
|
|
26
|
+
if (base === undefined)
|
|
27
|
+
return undefined;
|
|
28
|
+
const at = (other) => compareVersions(version, other);
|
|
29
|
+
switch (operator) {
|
|
30
|
+
case '^':
|
|
31
|
+
return (at(raw) ?? -1) >= 0 && (at(caretUpper(base)) ?? 1) < 0;
|
|
32
|
+
case '~':
|
|
33
|
+
return (at(raw) ?? -1) >= 0 && (at(tildeUpper(base)) ?? 1) < 0;
|
|
34
|
+
default:
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
const compared = at(raw.trim());
|
|
38
|
+
if (compared === undefined)
|
|
39
|
+
return undefined;
|
|
40
|
+
switch (operator) {
|
|
41
|
+
case '>=':
|
|
42
|
+
return compared >= 0;
|
|
43
|
+
case '<=':
|
|
44
|
+
return compared <= 0;
|
|
45
|
+
case '>':
|
|
46
|
+
return compared > 0;
|
|
47
|
+
case '<':
|
|
48
|
+
return compared < 0;
|
|
49
|
+
case '=':
|
|
50
|
+
case '':
|
|
51
|
+
return compared === 0;
|
|
52
|
+
default:
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function checkVersionRange(contract, version) {
|
|
57
|
+
const spec = contract?.trim() ?? '';
|
|
58
|
+
if (spec === '')
|
|
59
|
+
return 'satisfied';
|
|
60
|
+
if (!readable(version))
|
|
61
|
+
return 'malformed';
|
|
62
|
+
const tokens = spec.split(/\s+/).filter((token) => token !== '');
|
|
63
|
+
if (tokens.length === 0)
|
|
64
|
+
return 'satisfied';
|
|
65
|
+
for (const token of tokens) {
|
|
66
|
+
const verdict = comparator(token, version);
|
|
67
|
+
if (verdict === undefined)
|
|
68
|
+
return 'malformed';
|
|
69
|
+
if (!verdict)
|
|
70
|
+
return 'unsatisfied';
|
|
71
|
+
}
|
|
72
|
+
return 'satisfied';
|
|
73
|
+
}
|
package/dist/i18n/en.js
CHANGED
|
@@ -275,13 +275,16 @@ export const en = {
|
|
|
275
275
|
'rightbar.label': 'Data panels',
|
|
276
276
|
'rightbar.expand': 'Expand the data panel',
|
|
277
277
|
'rightbar.collapse': 'Collapse the data panel',
|
|
278
|
+
'rightbar.column.label': 'Right column',
|
|
279
|
+
'rightbar.column.workbench': 'Workbench panel',
|
|
280
|
+
'rightbar.column.dsh': 'dsh panel',
|
|
278
281
|
'rightbar.refresh': 'Refresh',
|
|
279
282
|
'rightbar.refreshing': 'Refreshing…',
|
|
280
283
|
'rightbar.updatedAt': 'updated {time}',
|
|
281
284
|
'rightbar.noProject': 'The current session has no workspace',
|
|
282
285
|
'coding.notARepo.title': 'This workspace is not a Coding repository',
|
|
283
286
|
'error.unknown': 'Something went wrong',
|
|
284
|
-
'board.title': '
|
|
287
|
+
'board.title': 'Workbench panel',
|
|
285
288
|
'panel.conversation': 'Conversation',
|
|
286
289
|
'panels.label': 'Global panels',
|
|
287
290
|
};
|
package/dist/i18n/index.d.ts
CHANGED
|
@@ -277,17 +277,20 @@ export declare const dictionaries: {
|
|
|
277
277
|
readonly 'rightbar.label': "数据面板";
|
|
278
278
|
readonly 'rightbar.expand': "展开数据面板";
|
|
279
279
|
readonly 'rightbar.collapse': "收起数据面板";
|
|
280
|
+
readonly 'rightbar.column.label': "右侧栏";
|
|
281
|
+
readonly 'rightbar.column.workbench': "工作台面板";
|
|
282
|
+
readonly 'rightbar.column.dsh': "dsh 面板";
|
|
280
283
|
readonly 'rightbar.refresh': "刷新";
|
|
281
284
|
readonly 'rightbar.refreshing': "刷新中…";
|
|
282
285
|
readonly 'rightbar.updatedAt': "更新于 {time}";
|
|
283
286
|
readonly 'rightbar.noProject': "当前会话没有所属项目";
|
|
284
287
|
readonly 'coding.notARepo.title': "这个项目不是 Coding 仓库";
|
|
285
288
|
readonly 'error.unknown': "出错了";
|
|
286
|
-
readonly 'board.title': "
|
|
289
|
+
readonly 'board.title': "工作台面板";
|
|
287
290
|
readonly 'panel.conversation': "对话";
|
|
288
291
|
readonly 'panels.label': "全局面板";
|
|
289
292
|
};
|
|
290
|
-
en: Record<"time.now" | "time.minutes" | "time.hours" | "time.days" | "blocker.retry" | "blocker.copy" | "blocker.unknown.title" | "blocker.login.go" | "blocker.login.titleGeneric" | "blocker.login.title" | "blocker.login.manual" | "blocker.login.hint" | "blocker.forbidden.open" | "blocker.forbidden.titleGeneric" | "blocker.forbidden.title" | "blocker.forbidden.hint" | "blocker.timeout.hint" | "blocker.exec.hint" | "blocker.fix.install" | "blocker.fix.update" | "blocker.market.open" | "env.unit.missingPlugin" | "env.unit.hint" | "env.unit.missingCommands" | "env.unit.missingCommandsHint" | "env.unit.unchecked" | "env.unit.uncheckedHint" | "brand.name" | "toggle.open" | "toggle.collapse" | "project.label" | "workspace.section" | "project.none" | "project.empty" | "project.add" | "session.new" | "session.new.label" | "session.empty" | "session.noProject" | "session.pinned" | "session.actions" | "status.idle" | "status.running" | "status.waitingApproval" | "status.planReview" | "status.waitingAnswer" | "status.completed" | "status.subagentsRunning.one" | "status.subagentsRunning.other" | "panels.title" | "panels.reset" | "panels.enabled" | "panels.disabled" | "panels.choose" | "panels.failed" | "panels.hintEffect" | "panels.dragHint" | "panels.unknownStep" | "panels.labelWithHint" | "panels.dep.missingPlugin" | "panels.dep.missingCommands" | "panels.dep.unchecked" | "panels.tab.modules" | "panels.tab.market" | "panels.browseMarket" | "panels.noneInstalled" | "panels.noneInstalledHint" | "panels.market.installed" | "panels.market.outdated" | "panels.market.hasNew" | "panels.market.missing" | "panels.market.unchecked" | "panels.market.checking" | "panels.market.sectionInstalled" | "panels.market.sectionPending" | "panels.market.sectionShared" | "panels.market.sharedUsedBy" | "panels.market.listSeparator" | "panels.market.sharedMissing" | "panels.market.sharedOutdated" | "panels.market.sharedUnsatisfied" | "panels.market.sharedOk" | "panels.market.versionArrow" | "panels.market.lead" | "panels.market.install" | "panels.market.update" | "panels.market.uninstall" | "panels.market.uninstallLabel" | "panels.market.installing" | "panels.market.updating" | "panels.market.uninstalling" | "panels.market.confirmUninstallTitle" | "panels.market.confirmUninstallDetail" | "panels.market.confirmUninstallAck" | "panels.market.confirmYes" | "panels.market.confirmNo" | "panels.market.failed" | "panels.market.needEnv" | "panels.market.noSource" | "panels.market.badSource" | "panels.market.empty" | "panels.market.installedSection" | "panels.market.moduleOutdated" | "panels.market.moduleRestartHint" | "panels.market.restartNeeded" | "panels.market.foot" | "panels.market.recheck" | "panels.market.checkUpdates" | "panels.market.checkedAt" | "panels.market.justNow" | "panels.market.minutesAgo" | "panels.market.hoursAgo" | "panels.market.add.description" | "panels.market.add.specPlaceholder" | "panels.market.add.guideToggle" | "panels.market.add.guideHide" | "panels.market.add.guideIdTitle" | "panels.market.add.guideIdExample" | "panels.market.add.guideIdHint" | "panels.market.add.guideGitTitle" | "panels.market.add.guideGitExample" | "panels.market.add.guideGitHint" | "panels.market.add.guidePathTitle" | "panels.market.add.guidePathExample" | "panels.market.add.guidePathHint" | "panels.market.add.guideExampleLabel" | "panels.market.add.guideFill" | "panels.market.add.guideSafety" | "panels.market.add.registryLegend" | "panels.market.add.registryOfficial" | "panels.market.add.registryMirror" | "panels.market.add.registryWithHost" | "panels.market.add.registryToggle" | "panels.market.add.installVersion" | "panels.market.add.registryDefault" | "panels.market.add.registryCustom" | "panels.market.add.registryCustomPlaceholder" | "panels.market.add.registryCustomHint" | "panels.market.add.registryCustomInvalid" | "panels.market.add.run" | "panels.market.add.edit" | "panels.market.add.changeRegistry" | "panels.market.add.installingTitle" | "panels.market.add.installedTitle" | "panels.market.add.failedTitle" | "panels.market.add.cancelledTitle" | "panels.market.add.failureNetworkHost" | "panels.market.add.problemInvalid" | "panels.market.add.problemInstalled" | "panels.market.add.problemNotFound" | "panels.market.add.problemNotPackage" | "panels.market.add.problemNotBundle" | "panels.market.add.problemNetwork" | "panels.market.add.problemUnknown" | "panels.market.add.failureNetwork" | "panels.market.add.failureNotFound" | "panels.market.add.failureNoMatchingVersion" | "panels.market.add.failureDiskFull" | "panels.market.add.failurePermission" | "panels.market.add.failureBuildBlocked" | "panels.market.add.failureIntegrity" | "panels.market.add.failureTimeout" | "panels.market.add.failurePnpmMissing" | "panels.market.add.failureGeneric" | "panels.market.add.approveTitle" | "panels.market.add.approveCaution" | "panels.market.add.approveRun" | "panels.market.add.restart" | "panels.market.add.tookEffect" | "panels.market.add.details" | "panels.market.add.open" | "panels.market.add.title" | "panels.market.add.intro" | "panels.market.add.specLabel" | "panels.market.add.specHint" | "panels.market.add.exampleTitle" | "panels.market.add.exampleFill" | "panels.market.add.registryLabel" | "panels.market.add.registryProfile" | "panels.market.add.registryPnpm" | "panels.market.add.check" | "panels.market.add.checking" | "panels.market.add.change" | "panels.market.add.previewTitle" | "panels.market.add.fieldName" | "panels.market.add.fieldVersion" | "panels.market.add.fieldDescription" | "panels.market.add.fieldSource" | "panels.market.add.install" | "panels.market.add.installing" | "panels.market.add.cancel" | "panels.market.add.close" | "panels.market.add.retry" | "panels.market.add.changeSource" | "panels.market.add.approveBuilds" | "panels.market.add.approveHint" | "panels.market.add.doneApplied" | "panels.market.add.doneRestart" | "panels.market.add.cancelled" | "panels.market.add.failed" | "panels.market.add.removed" | "panels.market.add.supplyPending" | "panels.market.add.supplyFailed" | "panels.market.add.notModule" | "panels.market.add.removedRestart" | "panels.market.add.remove" | "panels.market.add.problem.invalidSpec" | "panels.market.add.problem.alreadyInstalled" | "panels.market.add.problem.notFound" | "panels.market.add.problem.notAPackage" | "panels.market.add.problem.notABundle" | "panels.market.add.problem.network" | "panels.market.add.problem.unknown" | "panels.market.add.reason.invalidSpec" | "panels.market.add.reason.incompatible" | "panels.market.add.reason.notBundle" | "panels.market.add.reason.notRemovable" | "panels.market.add.reason.bundleInUse" | "panels.market.add.reason.stopProfile" | "panels.market.add.reason.staleApproval" | "panels.market.add.reason.operationError" | "panels.market.add.reason.buildBlocked" | "panels.market.add.reason.pnpmMissing" | "panels.market.add.reason.noMatchingVersion" | "panels.market.add.reason.diskFull" | "panels.market.add.reason.permission" | "panels.market.add.reason.integrity" | "panels.market.add.reason.timeout" | "panels.market.add.reason.network" | "panels.market.add.reason.notFound" | "panels.market.add.reason.unknown" | "blocker.fix.running" | "blocker.fix.failed" | "blocker.retry.running" | "panels.reading" | "panels.empty" | "panels.emptyHint" | "env.title" | "env.checking" | "env.installing" | "env.failed" | "env.elapsed" | "env.stepFailed.install" | "env.stepFailed.path" | "env.stepFailed.shell" | "env.bridge.ok" | "env.bridge.short" | "env.bridge.why" | "env.bridge.daemon" | "env.bridge.extension" | "env.bridge.extensionLink" | "env.bridge.profile" | "env.bridge.stale" | "env.bridge.unknown" | "env.fix.title" | "env.fix.why" | "env.fix.whyPath" | "env.fix.whyShell" | "env.fix.step" | "env.fix.stepPath" | "env.fix.stepShell" | "env.fix.permission" | "env.fix.network" | "env.fix.details" | "env.retry" | "env.copyCommand" | "env.copied" | "env.step.opencli" | "env.step.codingPlugin" | "env.step.bridge" | "env.step.warm" | "env.warm.done" | "env.warm.short" | "rightbar.label" | "rightbar.expand" | "rightbar.collapse" | "rightbar.refresh" | "rightbar.refreshing" | "rightbar.updatedAt" | "rightbar.noProject" | "coding.notARepo.title" | "error.unknown" | "board.title" | "panel.conversation" | "panels.label", string>;
|
|
293
|
+
en: Record<"time.now" | "time.minutes" | "time.hours" | "time.days" | "blocker.retry" | "blocker.copy" | "blocker.unknown.title" | "blocker.login.go" | "blocker.login.titleGeneric" | "blocker.login.title" | "blocker.login.manual" | "blocker.login.hint" | "blocker.forbidden.open" | "blocker.forbidden.titleGeneric" | "blocker.forbidden.title" | "blocker.forbidden.hint" | "blocker.timeout.hint" | "blocker.exec.hint" | "blocker.fix.install" | "blocker.fix.update" | "blocker.market.open" | "env.unit.missingPlugin" | "env.unit.hint" | "env.unit.missingCommands" | "env.unit.missingCommandsHint" | "env.unit.unchecked" | "env.unit.uncheckedHint" | "brand.name" | "toggle.open" | "toggle.collapse" | "project.label" | "workspace.section" | "project.none" | "project.empty" | "project.add" | "session.new" | "session.new.label" | "session.empty" | "session.noProject" | "session.pinned" | "session.actions" | "status.idle" | "status.running" | "status.waitingApproval" | "status.planReview" | "status.waitingAnswer" | "status.completed" | "status.subagentsRunning.one" | "status.subagentsRunning.other" | "panels.title" | "panels.reset" | "panels.enabled" | "panels.disabled" | "panels.choose" | "panels.failed" | "panels.hintEffect" | "panels.dragHint" | "panels.unknownStep" | "panels.labelWithHint" | "panels.dep.missingPlugin" | "panels.dep.missingCommands" | "panels.dep.unchecked" | "panels.tab.modules" | "panels.tab.market" | "panels.browseMarket" | "panels.noneInstalled" | "panels.noneInstalledHint" | "panels.market.installed" | "panels.market.outdated" | "panels.market.hasNew" | "panels.market.missing" | "panels.market.unchecked" | "panels.market.checking" | "panels.market.sectionInstalled" | "panels.market.sectionPending" | "panels.market.sectionShared" | "panels.market.sharedUsedBy" | "panels.market.listSeparator" | "panels.market.sharedMissing" | "panels.market.sharedOutdated" | "panels.market.sharedUnsatisfied" | "panels.market.sharedOk" | "panels.market.versionArrow" | "panels.market.lead" | "panels.market.install" | "panels.market.update" | "panels.market.uninstall" | "panels.market.uninstallLabel" | "panels.market.installing" | "panels.market.updating" | "panels.market.uninstalling" | "panels.market.confirmUninstallTitle" | "panels.market.confirmUninstallDetail" | "panels.market.confirmUninstallAck" | "panels.market.confirmYes" | "panels.market.confirmNo" | "panels.market.failed" | "panels.market.needEnv" | "panels.market.noSource" | "panels.market.badSource" | "panels.market.empty" | "panels.market.installedSection" | "panels.market.moduleOutdated" | "panels.market.moduleRestartHint" | "panels.market.restartNeeded" | "panels.market.foot" | "panels.market.recheck" | "panels.market.checkUpdates" | "panels.market.checkedAt" | "panels.market.justNow" | "panels.market.minutesAgo" | "panels.market.hoursAgo" | "panels.market.add.description" | "panels.market.add.specPlaceholder" | "panels.market.add.guideToggle" | "panels.market.add.guideHide" | "panels.market.add.guideIdTitle" | "panels.market.add.guideIdExample" | "panels.market.add.guideIdHint" | "panels.market.add.guideGitTitle" | "panels.market.add.guideGitExample" | "panels.market.add.guideGitHint" | "panels.market.add.guidePathTitle" | "panels.market.add.guidePathExample" | "panels.market.add.guidePathHint" | "panels.market.add.guideExampleLabel" | "panels.market.add.guideFill" | "panels.market.add.guideSafety" | "panels.market.add.registryLegend" | "panels.market.add.registryOfficial" | "panels.market.add.registryMirror" | "panels.market.add.registryWithHost" | "panels.market.add.registryToggle" | "panels.market.add.installVersion" | "panels.market.add.registryDefault" | "panels.market.add.registryCustom" | "panels.market.add.registryCustomPlaceholder" | "panels.market.add.registryCustomHint" | "panels.market.add.registryCustomInvalid" | "panels.market.add.run" | "panels.market.add.edit" | "panels.market.add.changeRegistry" | "panels.market.add.installingTitle" | "panels.market.add.installedTitle" | "panels.market.add.failedTitle" | "panels.market.add.cancelledTitle" | "panels.market.add.failureNetworkHost" | "panels.market.add.problemInvalid" | "panels.market.add.problemInstalled" | "panels.market.add.problemNotFound" | "panels.market.add.problemNotPackage" | "panels.market.add.problemNotBundle" | "panels.market.add.problemNetwork" | "panels.market.add.problemUnknown" | "panels.market.add.failureNetwork" | "panels.market.add.failureNotFound" | "panels.market.add.failureNoMatchingVersion" | "panels.market.add.failureDiskFull" | "panels.market.add.failurePermission" | "panels.market.add.failureBuildBlocked" | "panels.market.add.failureIntegrity" | "panels.market.add.failureTimeout" | "panels.market.add.failurePnpmMissing" | "panels.market.add.failureGeneric" | "panels.market.add.approveTitle" | "panels.market.add.approveCaution" | "panels.market.add.approveRun" | "panels.market.add.restart" | "panels.market.add.tookEffect" | "panels.market.add.details" | "panels.market.add.open" | "panels.market.add.title" | "panels.market.add.intro" | "panels.market.add.specLabel" | "panels.market.add.specHint" | "panels.market.add.exampleTitle" | "panels.market.add.exampleFill" | "panels.market.add.registryLabel" | "panels.market.add.registryProfile" | "panels.market.add.registryPnpm" | "panels.market.add.check" | "panels.market.add.checking" | "panels.market.add.change" | "panels.market.add.previewTitle" | "panels.market.add.fieldName" | "panels.market.add.fieldVersion" | "panels.market.add.fieldDescription" | "panels.market.add.fieldSource" | "panels.market.add.install" | "panels.market.add.installing" | "panels.market.add.cancel" | "panels.market.add.close" | "panels.market.add.retry" | "panels.market.add.changeSource" | "panels.market.add.approveBuilds" | "panels.market.add.approveHint" | "panels.market.add.doneApplied" | "panels.market.add.doneRestart" | "panels.market.add.cancelled" | "panels.market.add.failed" | "panels.market.add.removed" | "panels.market.add.supplyPending" | "panels.market.add.supplyFailed" | "panels.market.add.notModule" | "panels.market.add.removedRestart" | "panels.market.add.remove" | "panels.market.add.problem.invalidSpec" | "panels.market.add.problem.alreadyInstalled" | "panels.market.add.problem.notFound" | "panels.market.add.problem.notAPackage" | "panels.market.add.problem.notABundle" | "panels.market.add.problem.network" | "panels.market.add.problem.unknown" | "panels.market.add.reason.invalidSpec" | "panels.market.add.reason.incompatible" | "panels.market.add.reason.notBundle" | "panels.market.add.reason.notRemovable" | "panels.market.add.reason.bundleInUse" | "panels.market.add.reason.stopProfile" | "panels.market.add.reason.staleApproval" | "panels.market.add.reason.operationError" | "panels.market.add.reason.buildBlocked" | "panels.market.add.reason.pnpmMissing" | "panels.market.add.reason.noMatchingVersion" | "panels.market.add.reason.diskFull" | "panels.market.add.reason.permission" | "panels.market.add.reason.integrity" | "panels.market.add.reason.timeout" | "panels.market.add.reason.network" | "panels.market.add.reason.notFound" | "panels.market.add.reason.unknown" | "blocker.fix.running" | "blocker.fix.failed" | "blocker.retry.running" | "panels.reading" | "panels.empty" | "panels.emptyHint" | "env.title" | "env.checking" | "env.installing" | "env.failed" | "env.elapsed" | "env.stepFailed.install" | "env.stepFailed.path" | "env.stepFailed.shell" | "env.bridge.ok" | "env.bridge.short" | "env.bridge.why" | "env.bridge.daemon" | "env.bridge.extension" | "env.bridge.extensionLink" | "env.bridge.profile" | "env.bridge.stale" | "env.bridge.unknown" | "env.fix.title" | "env.fix.why" | "env.fix.whyPath" | "env.fix.whyShell" | "env.fix.step" | "env.fix.stepPath" | "env.fix.stepShell" | "env.fix.permission" | "env.fix.network" | "env.fix.details" | "env.retry" | "env.copyCommand" | "env.copied" | "env.step.opencli" | "env.step.codingPlugin" | "env.step.bridge" | "env.step.warm" | "env.warm.done" | "env.warm.short" | "rightbar.label" | "rightbar.expand" | "rightbar.collapse" | "rightbar.column.label" | "rightbar.column.workbench" | "rightbar.column.dsh" | "rightbar.refresh" | "rightbar.refreshing" | "rightbar.updatedAt" | "rightbar.noProject" | "coding.notARepo.title" | "error.unknown" | "board.title" | "panel.conversation" | "panels.label", string>;
|
|
291
294
|
};
|
|
292
295
|
export type { WorkbenchMessages };
|
|
293
296
|
export interface Dictionaries {
|
package/dist/i18n/zh.d.ts
CHANGED
|
@@ -275,13 +275,16 @@ export declare const zh: {
|
|
|
275
275
|
readonly 'rightbar.label': "数据面板";
|
|
276
276
|
readonly 'rightbar.expand': "展开数据面板";
|
|
277
277
|
readonly 'rightbar.collapse': "收起数据面板";
|
|
278
|
+
readonly 'rightbar.column.label': "右侧栏";
|
|
279
|
+
readonly 'rightbar.column.workbench': "工作台面板";
|
|
280
|
+
readonly 'rightbar.column.dsh': "dsh 面板";
|
|
278
281
|
readonly 'rightbar.refresh': "刷新";
|
|
279
282
|
readonly 'rightbar.refreshing': "刷新中…";
|
|
280
283
|
readonly 'rightbar.updatedAt': "更新于 {time}";
|
|
281
284
|
readonly 'rightbar.noProject': "当前会话没有所属项目";
|
|
282
285
|
readonly 'coding.notARepo.title': "这个项目不是 Coding 仓库";
|
|
283
286
|
readonly 'error.unknown': "出错了";
|
|
284
|
-
readonly 'board.title': "
|
|
287
|
+
readonly 'board.title': "工作台面板";
|
|
285
288
|
readonly 'panel.conversation': "对话";
|
|
286
289
|
readonly 'panels.label': "全局面板";
|
|
287
290
|
};
|
package/dist/i18n/zh.js
CHANGED
|
@@ -275,13 +275,16 @@ export const zh = {
|
|
|
275
275
|
'rightbar.label': '数据面板',
|
|
276
276
|
'rightbar.expand': '展开数据面板',
|
|
277
277
|
'rightbar.collapse': '收起数据面板',
|
|
278
|
+
'rightbar.column.label': '右侧栏',
|
|
279
|
+
'rightbar.column.workbench': '工作台面板',
|
|
280
|
+
'rightbar.column.dsh': 'dsh 面板',
|
|
278
281
|
'rightbar.refresh': '刷新',
|
|
279
282
|
'rightbar.refreshing': '刷新中…',
|
|
280
283
|
'rightbar.updatedAt': '更新于 {time}',
|
|
281
284
|
'rightbar.noProject': '当前会话没有所属项目',
|
|
282
285
|
'coding.notARepo.title': '这个项目不是 Coding 仓库',
|
|
283
286
|
'error.unknown': '出错了',
|
|
284
|
-
'board.title': '
|
|
287
|
+
'board.title': '工作台面板',
|
|
285
288
|
'panel.conversation': '对话',
|
|
286
289
|
'panels.label': '全局面板',
|
|
287
290
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -10,13 +10,21 @@ export * from './api/unit-board.js';
|
|
|
10
10
|
export * from './api/unit.js';
|
|
11
11
|
export * from './api/workbench-client.js';
|
|
12
12
|
export * from './api/workbench-contract.js';
|
|
13
|
+
export * from './components/Activity.js';
|
|
13
14
|
export * from './components/ApprovalDetail.js';
|
|
15
|
+
export * from './components/ApprovalPlan.js';
|
|
16
|
+
export * from './components/Card.js';
|
|
14
17
|
export * from './components/CardHead.js';
|
|
15
18
|
export * from './components/ChoiceGroup.js';
|
|
16
19
|
export * from './components/LongTaskRow.js';
|
|
17
20
|
export * from './components/MockStrip.js';
|
|
21
|
+
export * from './components/Note.js';
|
|
18
22
|
export * from './components/ResourceStates.js';
|
|
23
|
+
export * from './components/Rows.js';
|
|
19
24
|
export * from './components/SaveBar.js';
|
|
25
|
+
export * from './components/SettingsSection.js';
|
|
26
|
+
export * from './components/Stack.js';
|
|
27
|
+
export * from './components/StateBlock.js';
|
|
20
28
|
export * from './components/TextField.js';
|
|
21
29
|
export * from './components/board-module.js';
|
|
22
30
|
export * from './components/icons.js';
|
package/dist/index.js
CHANGED
|
@@ -10,13 +10,21 @@ export * from './api/unit-board.js';
|
|
|
10
10
|
export * from './api/unit.js';
|
|
11
11
|
export * from './api/workbench-client.js';
|
|
12
12
|
export * from './api/workbench-contract.js';
|
|
13
|
+
export * from './components/Activity.js';
|
|
13
14
|
export * from './components/ApprovalDetail.js';
|
|
15
|
+
export * from './components/ApprovalPlan.js';
|
|
16
|
+
export * from './components/Card.js';
|
|
14
17
|
export * from './components/CardHead.js';
|
|
15
18
|
export * from './components/ChoiceGroup.js';
|
|
16
19
|
export * from './components/LongTaskRow.js';
|
|
17
20
|
export * from './components/MockStrip.js';
|
|
21
|
+
export * from './components/Note.js';
|
|
18
22
|
export * from './components/ResourceStates.js';
|
|
23
|
+
export * from './components/Rows.js';
|
|
19
24
|
export * from './components/SaveBar.js';
|
|
25
|
+
export * from './components/SettingsSection.js';
|
|
26
|
+
export * from './components/Stack.js';
|
|
27
|
+
export * from './components/StateBlock.js';
|
|
20
28
|
export * from './components/TextField.js';
|
|
21
29
|
export * from './components/board-module.js';
|
|
22
30
|
export * from './components/icons.js';
|
package/dist/lib/react.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export declare const h: typeof ReactTypes.createElement;
|
|
|
3
3
|
export declare const Fragment: ReactTypes.ExoticComponent<ReactTypes.FragmentProps>;
|
|
4
4
|
export declare const useState: typeof ReactTypes.useState;
|
|
5
5
|
export declare const useEffect: typeof ReactTypes.useEffect;
|
|
6
|
+
export declare const useLayoutEffect: typeof ReactTypes.useLayoutEffect;
|
|
6
7
|
export declare const useMemo: typeof ReactTypes.useMemo;
|
|
7
8
|
export declare const useCallback: typeof ReactTypes.useCallback;
|
|
8
9
|
export declare const useRef: typeof ReactTypes.useRef;
|
package/dist/lib/react.js
CHANGED
|
@@ -3,6 +3,7 @@ export const h = react.createElement;
|
|
|
3
3
|
export const Fragment = react.Fragment;
|
|
4
4
|
export const useState = react.useState;
|
|
5
5
|
export const useEffect = react.useEffect;
|
|
6
|
+
export const useLayoutEffect = react.useLayoutEffect;
|
|
6
7
|
export const useMemo = react.useMemo;
|
|
7
8
|
export const useCallback = react.useCallback;
|
|
8
9
|
export const useRef = react.useRef;
|
package/package.json
CHANGED
package/src/api/dsh-client.ts
CHANGED
|
@@ -163,6 +163,19 @@ export interface DshSessionsService {
|
|
|
163
163
|
scope(sessionId: string): unknown | undefined;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
export interface DshObservable<T> {
|
|
167
|
+
getSnapshot(): T;
|
|
168
|
+
subscribe(listener: () => void): () => void;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export interface DshSidebarRight {
|
|
172
|
+
readonly mounted: DshObservable<string | undefined>;
|
|
173
|
+
isExpanded(): boolean;
|
|
174
|
+
toggleExpanded(): void;
|
|
175
|
+
openResource(address: string, options?: unknown): void;
|
|
176
|
+
openTab(kind: string, options?: unknown): void;
|
|
177
|
+
}
|
|
178
|
+
|
|
166
179
|
export interface DshClientContext {
|
|
167
180
|
get<T = unknown>(name: string): T | undefined;
|
|
168
181
|
provide(name: string, value: unknown): void;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
|
|
2
|
+
.wb-activityBlock {
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
gap: var(--wb-len-6);
|
|
6
|
+
padding-top: var(--wb-len-10);
|
|
7
|
+
border-top: 0.5px solid var(--dsw-alias-border-l2);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.wb-activityBlock:first-child {
|
|
11
|
+
border-top: none;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.wb-activityBlockHead {
|
|
15
|
+
display: flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
justify-content: space-between;
|
|
18
|
+
gap: var(--wb-len-8);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.wb-activityLine {
|
|
22
|
+
display: flex;
|
|
23
|
+
align-items: center;
|
|
24
|
+
gap: var(--wb-len-6);
|
|
25
|
+
margin: 0;
|
|
26
|
+
font-size: var(--dsw-font-xxs-12-font-size);
|
|
27
|
+
line-height: var(--wb-line-18);
|
|
28
|
+
color: var(--dsw-alias-label-secondary);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.wb-activityLineText {
|
|
32
|
+
flex: none;
|
|
33
|
+
min-width: 0;
|
|
34
|
+
font-size: var(--dsw-font-xxs-12-font-size);
|
|
35
|
+
line-height: var(--wb-line-18);
|
|
36
|
+
overflow-wrap: anywhere;
|
|
37
|
+
white-space: pre-wrap;
|
|
38
|
+
max-height: var(--wb-len-72);
|
|
39
|
+
overflow-y: auto;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.wb-activityLineAt {
|
|
43
|
+
flex: none;
|
|
44
|
+
margin-left: auto;
|
|
45
|
+
font-size: var(--wb-font-10);
|
|
46
|
+
line-height: var(--wb-line-16);
|
|
47
|
+
font-variant-numeric: tabular-nums;
|
|
48
|
+
color: var(--dsw-alias-label-tertiary);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.wb-activityLine > .wb-activityLineAt,
|
|
52
|
+
.wb-activityLine > .wb-activityLineActions {
|
|
53
|
+
margin-left: auto;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.wb-activityLine > .wb-activityLineAt + .wb-activityLineActions {
|
|
57
|
+
margin-left: 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.wb-activityLineActions {
|
|
61
|
+
flex: none;
|
|
62
|
+
display: inline-flex;
|
|
63
|
+
align-items: center;
|
|
64
|
+
gap: var(--wb-len-6);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.wb-activityActionFailed {
|
|
68
|
+
color: var(--dsw-alias-state-error-primary);
|
|
69
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { ReactNode } from '../lib/react.js';
|
|
2
|
+
import { Button, Tooltip } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
3
|
+
import { h } from '../lib/react.js';
|
|
4
|
+
import './Activity.css';
|
|
5
|
+
|
|
6
|
+
export interface ActivityBlockProps {
|
|
7
|
+
readonly head?: ReactNode | undefined;
|
|
8
|
+
readonly children?: ReactNode | undefined;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function ActivityBlock({ head, children }: ActivityBlockProps) {
|
|
12
|
+
return (
|
|
13
|
+
<div className="wb-activityBlock">
|
|
14
|
+
{head === undefined ? null : <div className="wb-activityBlockHead">{head}</div>}
|
|
15
|
+
{children}
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface ActivityLineProps {
|
|
21
|
+
readonly dot?: ReactNode | undefined;
|
|
22
|
+
readonly text: ReactNode;
|
|
23
|
+
readonly at?: ReactNode | undefined;
|
|
24
|
+
readonly actions?: ReactNode | undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function ActivityLine({ dot, text, at, actions }: ActivityLineProps) {
|
|
28
|
+
return (
|
|
29
|
+
<div className="wb-activityLine">
|
|
30
|
+
{dot}
|
|
31
|
+
<span className="wb-activityLineText">{text}</span>
|
|
32
|
+
{at === undefined ? null : <span className="wb-activityLineAt">{at}</span>}
|
|
33
|
+
{actions === undefined ? null : <span className="wb-activityLineActions">{actions}</span>}
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ActivityActionProps {
|
|
39
|
+
readonly label: string;
|
|
40
|
+
readonly hint?: string | undefined;
|
|
41
|
+
readonly icon: ReactNode;
|
|
42
|
+
readonly href?: string | undefined;
|
|
43
|
+
readonly onClick?: (() => void) | undefined;
|
|
44
|
+
readonly failed?: boolean | undefined;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function ActivityAction({ label, hint, icon, href, onClick, failed }: ActivityActionProps) {
|
|
48
|
+
const tip = hint ?? label;
|
|
49
|
+
if (href !== undefined) {
|
|
50
|
+
return (
|
|
51
|
+
<a
|
|
52
|
+
className="wb-iconButton"
|
|
53
|
+
href={href}
|
|
54
|
+
target="_blank"
|
|
55
|
+
rel="noreferrer noopener"
|
|
56
|
+
title={tip}
|
|
57
|
+
aria-label={label}
|
|
58
|
+
>
|
|
59
|
+
{icon}
|
|
60
|
+
</a>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
return (
|
|
64
|
+
<Tooltip side="bottom" align="end" gap={6} portal label={tip}>
|
|
65
|
+
<Button
|
|
66
|
+
type="button"
|
|
67
|
+
variant="ghost"
|
|
68
|
+
size="sm"
|
|
69
|
+
className={failed === true ? 'wb-iconButton wb-activityActionFailed' : 'wb-iconButton'}
|
|
70
|
+
aria-label={label}
|
|
71
|
+
icon={icon}
|
|
72
|
+
onClick={onClick}
|
|
73
|
+
/>
|
|
74
|
+
</Tooltip>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
.wb-approvalPlan {
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
gap: var(--wb-len-6);
|
|
6
|
+
}
|
|
7
|
+
.wb-approvalHint {
|
|
8
|
+
margin: 0;
|
|
9
|
+
font-size: var(--dsw-font-xxs-12-font-size);
|
|
10
|
+
line-height: var(--wb-line-18);
|
|
11
|
+
color: var(--dsw-alias-label-secondary);
|
|
12
|
+
}
|
|
13
|
+
.wb-approvalRows {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
gap: var(--wb-len-2);
|
|
17
|
+
margin: 0;
|
|
18
|
+
}
|
|
19
|
+
.wb-approvalRow {
|
|
20
|
+
display: flex;
|
|
21
|
+
align-items: baseline;
|
|
22
|
+
gap: var(--wb-len-8);
|
|
23
|
+
}
|
|
24
|
+
.wb-approvalLabel {
|
|
25
|
+
flex: none;
|
|
26
|
+
width: var(--wb-len-56);
|
|
27
|
+
font-size: var(--dsw-font-xxs-12-font-size);
|
|
28
|
+
line-height: var(--wb-line-18);
|
|
29
|
+
color: var(--dsw-alias-label-tertiary);
|
|
30
|
+
}
|
|
31
|
+
.wb-approvalValue {
|
|
32
|
+
margin: 0;
|
|
33
|
+
font-size: var(--dsw-font-xs-13-font-size);
|
|
34
|
+
line-height: var(--wb-line-18);
|
|
35
|
+
font-weight: 500;
|
|
36
|
+
color: var(--dsw-alias-label-primary);
|
|
37
|
+
overflow-wrap: anywhere;
|
|
38
|
+
}
|
|
39
|
+
.wb-approvalWarn {
|
|
40
|
+
color: var(--dsw-alias-label-secondary);
|
|
41
|
+
}
|