feat(console): simplify workspace and add filtered resource pagination

This commit is contained in:
2026-09-29 22:31:19 +08:00
parent 6138c103d5
commit f7409afd24
14 changed files with 666 additions and 306 deletions

View File

@@ -191,7 +191,7 @@ assert status == 200, status
status, body = request("/console/auth/session")
assert status == 200 and json.loads(body).get("authenticated") is True
status, body = request("/console/")
assert status == 200 and "运行统计".encode("utf-8") in body, status
assert status == 200 and b'id="overview-task-list"' in body and b'id="tasks-filters"' in body and b'/console/console-core.js' in body, status
status, body = request("/console/config")
assert status == 200 and json.loads(body).get("default_queue_id") == queue
status, _ = request("/v1/tasks?" + urllib.parse.urlencode({"queue_id": queue, "limit": 20}))

View File

@@ -0,0 +1,54 @@
const { test } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const vm = require('node:vm');
const context = vm.createContext({ URLSearchParams });
vm.runInContext(fs.readFileSync(require('node:path').join(__dirname, '../internal/transport/httpserver/console/console-core.js'), 'utf8'), context);
const { listURL, readFilters, ListPage } = context.OrbitConsole;
test('精确业务键、筛选和游标跨页保持,不静默扩展查询范围', () => {
const page = new ListPage();
page.reset({ business_key: '订单 +%_ ', state: 'NEEDS_REVIEW', created_from: '2026-09-01T00:00:00.000Z' });
assert.ok(page.accept(page.begin(), { next_cursor: 'opaque+/=' }));
assert.ok(page.move('next'));
const query = new URL(listURL('tasks', 'queue-1', page.filters, page.cursor), 'http://localhost').searchParams;
assert.equal(query.get('business_key'), '订单 +%_ ');
assert.equal(query.get('state'), 'NEEDS_REVIEW');
assert.equal(query.get('queue_id'), 'queue-1');
assert.equal(query.get('cursor'), 'opaque+/=');
assert.ok(page.move('prev'));
assert.equal(page.cursor, '');
assert.equal(page.filters.state, 'NEEDS_REVIEW');
});
test('查询重置后迟到的旧页面不会覆盖新条件和翻页状态', () => {
const page = new ListPage();
const slow = page.begin();
page.reset({ state: 'FAILED' });
const latest = page.begin();
assert.equal(page.accept(slow, { next_cursor: 'wrong' }), false);
assert.equal(page.loading, true);
assert.equal(page.move('next'), false);
assert.equal(page.accept(latest, {}), true);
assert.equal(page.next, '');
assert.equal(page.filters.state, 'FAILED');
});
test('失败保留原查询与原页,不自动回到无筛选列表', () => {
const page = new ListPage();
page.reset({ state: 'RUNNING' });
page.accept(page.begin(), { next_cursor: 'page-2' });
page.move('next');
assert.equal(page.fail(page.begin()), true);
assert.equal(page.cursor, 'page-2');
assert.equal(page.history.length, 1);
assert.equal(page.filters.state, 'RUNNING');
assert.equal(page.next, '');
});
test('时间边界验证、流程范围与无队列保护', () => {
assert.throws(() => readFilters({ created_from: '2026-09-29T12:00', created_before: '2026-09-29T11:00' }), /结束时间/);
assert.throws(() => readFilters({ created_from: 'not a date' }), /有效/);
const f = readFilters({ created_from: '2026-09-29T12:00:00+08:00', business_key: ' key ' });
assert.equal(f.created_from, '2026-09-29T04:00:00.000Z');
assert.equal(f.business_key, ' key ');
assert.throws(() => listURL('tasks', ''), /选择队列/);
assert.equal(new URL(listURL('workflows', 'ignored'), 'http://localhost').searchParams.has('queue_id'), false);
});