feat(swarm): implement Swarm View remake with Operations, Archetypes, and Templates
This commit includes the new SwarmWorkspace with its 3 sub-tabs, the LeftPanel mission picker, and the comprehensive Operations Command Dashboard featuring the live interactive DAG telemetry and task assignment prep flow.
This commit is contained in:
parent
409a7e7256
commit
dfaf523029
74 changed files with 11066 additions and 2046 deletions
|
|
@ -14,127 +14,119 @@ function createMockSearchParams(params: Record<string, string | null> = {}) {
|
|||
|
||||
describe('useUrlState', () => {
|
||||
describe('parseUrlState', () => {
|
||||
it('should return defaults for empty params', () => {
|
||||
const sp = createMockSearchParams({});
|
||||
const state = parseUrlState(sp);
|
||||
it('returns defaults for empty params', () => {
|
||||
const state = parseUrlState(createMockSearchParams({}));
|
||||
assert.deepStrictEqual(state, {
|
||||
view: 'social',
|
||||
taskId: null,
|
||||
swarmId: null,
|
||||
panel: 'closed',
|
||||
agentId: null,
|
||||
epicId: null,
|
||||
leftPanel: 'open',
|
||||
rightPanel: 'open',
|
||||
blockedOnly: false,
|
||||
panel: 'open',
|
||||
drawer: 'closed',
|
||||
graphTab: 'flow',
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse view=social', () => {
|
||||
const sp = createMockSearchParams({ view: 'social' });
|
||||
const state = parseUrlState(sp);
|
||||
assert.strictEqual(state.view, 'social');
|
||||
it('parses all core identifiers', () => {
|
||||
const state = parseUrlState(
|
||||
createMockSearchParams({
|
||||
view: 'activity',
|
||||
task: 'bb-vt.1.2',
|
||||
swarm: 'bb-vt',
|
||||
agent: 'codex',
|
||||
epic: 'bb-vt',
|
||||
}),
|
||||
);
|
||||
|
||||
assert.strictEqual(state.view, 'activity');
|
||||
assert.strictEqual(state.taskId, 'bb-vt.1.2');
|
||||
assert.strictEqual(state.swarmId, 'bb-vt');
|
||||
assert.strictEqual(state.agentId, 'codex');
|
||||
assert.strictEqual(state.epicId, 'bb-vt');
|
||||
});
|
||||
|
||||
it('should parse view=graph', () => {
|
||||
const sp = createMockSearchParams({ view: 'graph' });
|
||||
const state = parseUrlState(sp);
|
||||
assert.strictEqual(state.view, 'graph');
|
||||
});
|
||||
|
||||
it('should parse view=swarm', () => {
|
||||
const sp = createMockSearchParams({ view: 'swarm' });
|
||||
const state = parseUrlState(sp);
|
||||
assert.strictEqual(state.view, 'swarm');
|
||||
});
|
||||
|
||||
it('should fall back to default for invalid view values', () => {
|
||||
const sp = createMockSearchParams({ view: 'invalid' });
|
||||
const state = parseUrlState(sp);
|
||||
assert.strictEqual(state.view, 'social');
|
||||
});
|
||||
|
||||
it('should parse task id', () => {
|
||||
const sp = createMockSearchParams({ view: 'social', task: 'bb-buff.1' });
|
||||
const state = parseUrlState(sp);
|
||||
assert.strictEqual(state.view, 'social');
|
||||
assert.strictEqual(state.taskId, 'bb-buff.1');
|
||||
});
|
||||
|
||||
it('should parse swarm id', () => {
|
||||
const sp = createMockSearchParams({ view: 'swarm', swarm: 'bb-buff' });
|
||||
const state = parseUrlState(sp);
|
||||
assert.strictEqual(state.view, 'swarm');
|
||||
assert.strictEqual(state.swarmId, 'bb-buff');
|
||||
});
|
||||
|
||||
it('should parse panel state', () => {
|
||||
const sp = createMockSearchParams({ view: 'social', task: 'bb-buff.1', panel: 'open' });
|
||||
const state = parseUrlState(sp);
|
||||
it('parses explicit left/right panel params', () => {
|
||||
const state = parseUrlState(createMockSearchParams({ left: 'closed', right: 'open' }));
|
||||
assert.strictEqual(state.leftPanel, 'closed');
|
||||
assert.strictEqual(state.rightPanel, 'open');
|
||||
assert.strictEqual(state.panel, 'open');
|
||||
});
|
||||
|
||||
it('should parse graphTab', () => {
|
||||
const sp = createMockSearchParams({ view: 'graph', task: 'bb-buff.1', graphTab: 'flow' });
|
||||
const state = parseUrlState(sp);
|
||||
assert.strictEqual(state.graphTab, 'flow');
|
||||
});
|
||||
|
||||
it('should fall back to default for invalid panel values', () => {
|
||||
const sp = createMockSearchParams({ panel: 'invalid' });
|
||||
const state = parseUrlState(sp);
|
||||
it('uses legacy panel param when right is absent', () => {
|
||||
const state = parseUrlState(createMockSearchParams({ panel: 'closed' }));
|
||||
assert.strictEqual(state.rightPanel, 'closed');
|
||||
assert.strictEqual(state.panel, 'closed');
|
||||
});
|
||||
|
||||
it('should fall back to default for invalid graphTab values', () => {
|
||||
const sp = createMockSearchParams({ graphTab: 'invalid' });
|
||||
const state = parseUrlState(sp);
|
||||
it('prefers right param over legacy panel when both are present', () => {
|
||||
const state = parseUrlState(createMockSearchParams({ right: 'open', panel: 'closed' }));
|
||||
assert.strictEqual(state.rightPanel, 'open');
|
||||
assert.strictEqual(state.panel, 'open');
|
||||
});
|
||||
|
||||
it('falls back to defaults for invalid panel params', () => {
|
||||
const state = parseUrlState(createMockSearchParams({ left: 'invalid', right: 'invalid', panel: 'invalid' }));
|
||||
assert.strictEqual(state.leftPanel, 'open');
|
||||
assert.strictEqual(state.rightPanel, 'open');
|
||||
assert.strictEqual(state.panel, 'open');
|
||||
});
|
||||
|
||||
it('parses blocked filter state', () => {
|
||||
assert.strictEqual(parseUrlState(createMockSearchParams({ blocked: '1' })).blockedOnly, true);
|
||||
assert.strictEqual(parseUrlState(createMockSearchParams({ blocked: 'true' })).blockedOnly, true);
|
||||
assert.strictEqual(parseUrlState(createMockSearchParams({ blocked: '0' })).blockedOnly, false);
|
||||
});
|
||||
|
||||
it('falls back to default for invalid view and graph tab values', () => {
|
||||
const state = parseUrlState(createMockSearchParams({ view: 'invalid', graphTab: 'invalid' }));
|
||||
assert.strictEqual(state.view, 'social');
|
||||
assert.strictEqual(state.graphTab, 'flow');
|
||||
});
|
||||
});
|
||||
|
||||
describe('buildUrlParams', () => {
|
||||
it('should build URL with view param', () => {
|
||||
const sp = createMockSearchParams({});
|
||||
const url = buildUrlParams(sp, { view: 'social' });
|
||||
it('builds URL with view param', () => {
|
||||
const url = buildUrlParams(createMockSearchParams({}), { view: 'social' });
|
||||
assert.strictEqual(url, '/?view=social');
|
||||
});
|
||||
|
||||
it('should add task param', () => {
|
||||
const sp = createMockSearchParams({ view: 'social' });
|
||||
const url = buildUrlParams(sp, { task: 'bb-buff.1' });
|
||||
assert.strictEqual(url, '/?view=social&task=bb-buff.1');
|
||||
it('adds task param', () => {
|
||||
const url = buildUrlParams(createMockSearchParams({ view: 'social' }), { task: 'bb-vt.2.1' });
|
||||
assert.strictEqual(url, '/?view=social&task=bb-vt.2.1');
|
||||
});
|
||||
|
||||
it('should remove param when null', () => {
|
||||
const sp = createMockSearchParams({ view: 'social', task: 'bb-buff.1' });
|
||||
const url = buildUrlParams(sp, { task: null });
|
||||
it('removes params when value is null', () => {
|
||||
const url = buildUrlParams(createMockSearchParams({ view: 'social', task: 'bb-vt.2.1' }), { task: null });
|
||||
assert.strictEqual(url, '/?view=social');
|
||||
});
|
||||
|
||||
it('should toggle panel', () => {
|
||||
const sp = createMockSearchParams({ view: 'social', panel: 'closed' });
|
||||
const url = buildUrlParams(sp, { panel: 'open' });
|
||||
assert.strictEqual(url, '/?view=social&panel=open');
|
||||
it('supports dual right/panel sync updates', () => {
|
||||
const url = buildUrlParams(createMockSearchParams({ view: 'social' }), { right: 'open', panel: 'open' });
|
||||
assert.strictEqual(url, '/?view=social&right=open&panel=open');
|
||||
});
|
||||
|
||||
it('should return root for empty params', () => {
|
||||
const sp = createMockSearchParams({});
|
||||
const url = buildUrlParams(sp, {});
|
||||
it('returns root for empty params', () => {
|
||||
const url = buildUrlParams(createMockSearchParams({}), {});
|
||||
assert.strictEqual(url, '/');
|
||||
});
|
||||
|
||||
it('should clear all selection params', () => {
|
||||
const sp = createMockSearchParams({ view: 'social', task: 'bb-buff.1', swarm: 'buff', panel: 'open', graphTab: 'flow' });
|
||||
const url = buildUrlParams(sp, { task: null, swarm: null, panel: null, graphTab: null });
|
||||
assert.strictEqual(url, '/?view=social');
|
||||
it('clears selection params and keeps view', () => {
|
||||
const url = buildUrlParams(
|
||||
createMockSearchParams({ view: 'social', task: 'bb-vt.2.1', swarm: 'bb-vt', right: 'open', panel: 'open' }),
|
||||
{ task: null, swarm: null, right: 'closed', panel: 'closed' },
|
||||
);
|
||||
assert.strictEqual(url, '/?view=social&right=closed&panel=closed');
|
||||
});
|
||||
});
|
||||
|
||||
describe('module import', () => {
|
||||
it('should load the module without error', async () => {
|
||||
try {
|
||||
await import('../../src/hooks/use-url-state');
|
||||
assert.ok(true, 'Module loaded');
|
||||
} catch (err) {
|
||||
assert.fail(err as Error);
|
||||
}
|
||||
it('loads the module without error', async () => {
|
||||
await import('../../src/hooks/use-url-state');
|
||||
assert.ok(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue