pi-skill-evolve 0.1.7 → 0.1.9
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.
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
telemetryOffWhileEnabled,
|
|
22
22
|
} from "../flags.ts";
|
|
23
23
|
import type { WebView } from "./data.ts";
|
|
24
|
-
import { RANGE_KEYS, RANGE_LABEL,
|
|
24
|
+
import { RANGE_KEYS, RANGE_LABEL, type ListFilter, type ViewPage } from "./filter.ts";
|
|
25
25
|
import { listHref, type ListExtras } from "./list-query.ts";
|
|
26
26
|
import { escapeHtml, formatStamp, formatTimeSeconds } from "./text.ts";
|
|
27
27
|
import type { WebControls } from "./activity.ts";
|
|
@@ -106,15 +106,7 @@ ${run}</div>
|
|
|
106
106
|
${warn}${backlog}`;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
/**
|
|
110
|
-
function statusSelect(current: string): string {
|
|
111
|
-
const options = [`<option value="">全部状态</option>`];
|
|
112
|
-
for (const status of STATUS_OPTIONS) {
|
|
113
|
-
options.push(`<option value="${status}"${status === current ? " selected" : ""}>${status}</option>`);
|
|
114
|
-
}
|
|
115
|
-
return options.join("");
|
|
116
|
-
}
|
|
117
|
-
|
|
109
|
+
/** 时间下拉:只有「看多久内」需要人手动换,状态与技能已在 tab 与技能页面各自解决了 */
|
|
118
110
|
function rangeSelect(current: string): string {
|
|
119
111
|
return RANGE_KEYS.map(
|
|
120
112
|
(key) => `<option value="${key}"${key === current ? " selected" : ""}>${RANGE_LABEL[key]}</option>`,
|
|
@@ -122,16 +114,16 @@ function rangeSelect(current: string): string {
|
|
|
122
114
|
}
|
|
123
115
|
|
|
124
116
|
/**
|
|
125
|
-
*
|
|
126
|
-
*
|
|
117
|
+
* 筛选表单:只留「时间」一个条件。
|
|
118
|
+
* 技能:每个列表页的行里已经有技能列,技能页可以按技能点进来,再摆一个模糊搜索框没人知道该填什么;
|
|
119
|
+
* 状态:顶部 tab 本身就是按状态分的(待处理 / 待审批 / 已采纳 / 已处理 / 复盘报告),重复选毫无意义。
|
|
120
|
+
* 两个参数(skill / status)仍由 `parseListQuery` 支持,旧链接与代码内部跳转不会断,只是不再出输入框。
|
|
127
121
|
*/
|
|
128
122
|
export function renderFilterForm(view: WebView, filter: ListFilter, extras: ListExtras): string {
|
|
129
123
|
const keep = extraInputs(extras);
|
|
130
124
|
return `<form class="filter" method="get">
|
|
131
125
|
<input type="hidden" name="view" value="${view}">
|
|
132
|
-
${keep}<label
|
|
133
|
-
<label>状态 <select name="status">${statusSelect(filter.status)}</select></label>
|
|
134
|
-
<label>时间 <select name="range">${rangeSelect(filter.range)}</select></label>
|
|
126
|
+
${keep}<label>时间 <select name="range">${rangeSelect(filter.range)}</select></label>
|
|
135
127
|
<button type="submit">筛选</button>
|
|
136
128
|
<a class="btn" href="${escapeHtml(listHref(view, filter, 1, extras))}">重置</a>
|
|
137
129
|
</form>`;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 筛选栏的验收测试(用户 2026-11-08:「这个搜索框的技能和状态不用了吧, 技能不知道用来搜索什么,
|
|
3
|
+
* 状态应该在顶部 tab 包含了吧」)。
|
|
4
|
+
*
|
|
5
|
+
* 口径:
|
|
6
|
+
* 1. 表单**只剩「时间」**一个条件——技能看不出该填什么、状态与顶部 tab 重复,两个都撤掉;
|
|
7
|
+
* 2. 撤掉的是**输入控件**,不是参数:`?skill=` / `?status=` 仍由 `parseListQuery` 解析,
|
|
8
|
+
* 技能页点进来、旧书签、代码内部跳转都不会断;
|
|
9
|
+
* 3. 表单仍是 GET + 保留 `view`,否则一提交就跳出当前页。
|
|
10
|
+
*
|
|
11
|
+
* 纪律:纯字符串断言,不碰文件系统、不起服务。
|
|
12
|
+
*/
|
|
13
|
+
import { test } from "node:test";
|
|
14
|
+
import assert from "node:assert/strict";
|
|
15
|
+
|
|
16
|
+
import { parseListQuery } from "../lib/web/filter.ts";
|
|
17
|
+
import { renderFilterForm } from "../lib/web/render-controls.ts";
|
|
18
|
+
|
|
19
|
+
const FILTER = parseListQuery(new URLSearchParams(""));
|
|
20
|
+
const EXTRAS = { live: false, open: "all", only: false } as never;
|
|
21
|
+
|
|
22
|
+
function form(): string {
|
|
23
|
+
return renderFilterForm("pending", FILTER, EXTRAS);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
test("筛选栏不再有技能输入框与状态下拉", () => {
|
|
27
|
+
const html = form();
|
|
28
|
+
assert.ok(!html.includes('name="skill"'), "技能搜索框已撤掉");
|
|
29
|
+
assert.ok(!html.includes('name="status"'), "状态下拉已撤掉(顶部 tab 就是状态)");
|
|
30
|
+
assert.ok(!html.includes("全部状态"));
|
|
31
|
+
assert.ok(!html.includes("全部技能"));
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("时间筛选还在,且三个档位齐全", () => {
|
|
35
|
+
const html = form();
|
|
36
|
+
assert.ok(html.includes('name="range"'));
|
|
37
|
+
for (const label of ["最近 7 天", "最近 30 天", "全部时间"]) {
|
|
38
|
+
assert.ok(html.includes(`>${label}<`), `缺时间档位:${label}`);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("表单仍是 GET,且保留 view", () => {
|
|
43
|
+
const html = form();
|
|
44
|
+
assert.ok(html.includes('method="get"'));
|
|
45
|
+
assert.ok(html.includes('<input type="hidden" name="view" value="pending">'));
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("参数没被删:URL 里的 skill / status 仍然生效", () => {
|
|
49
|
+
const parsed = parseListQuery(new URLSearchParams("skill=deploy-test&status=stale&range=30d"));
|
|
50
|
+
assert.equal(parsed.skill, "deploy-test");
|
|
51
|
+
assert.equal(parsed.status, "stale");
|
|
52
|
+
assert.equal(parsed.range, "30d");
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("技能页跳过来的链接照旧能带 skill 参数(只是不再有输入框)", () => {
|
|
56
|
+
const parsed = parseListQuery(new URLSearchParams("skill=ui-verify"));
|
|
57
|
+
const html = renderFilterForm("reports", parsed, EXTRAS);
|
|
58
|
+
assert.ok(!html.includes('name="skill"'));
|
|
59
|
+
assert.equal(parsed.skill, "ui-verify", "筛选逻辑要能吃到链接里的技能");
|
|
60
|
+
});
|