@lmzhen/dsh-evolution-merge-ui 0.29.0 → 0.30.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/lib/client.js
CHANGED
|
@@ -31,8 +31,8 @@ window.__ModuleLoader__.load({
|
|
|
31
31
|
merge: {
|
|
32
32
|
view: "/api/dsh-evolution/merge/view",
|
|
33
33
|
rows: "/api/dsh-evolution/merge/rows",
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
body: "/api/dsh-evolution/merge/body",
|
|
35
|
+
history: "/api/dsh-evolution/merge/history"
|
|
36
36
|
},
|
|
37
37
|
diagnostics: { view: "/api/dsh-evolution/diagnostics" }
|
|
38
38
|
};
|
|
@@ -149,6 +149,27 @@ window.__ModuleLoader__.load({
|
|
|
149
149
|
failure: answer.failure
|
|
150
150
|
};
|
|
151
151
|
}
|
|
152
|
+
async function body(id, side) {
|
|
153
|
+
const url = HOST_ROUTES.body + "?id=" + encodeURIComponent(id) + "&side=" + side;
|
|
154
|
+
const answer = await requestJson(fetch, url, { headers: { accept: "application/json" } });
|
|
155
|
+
return answer.ok ? {
|
|
156
|
+
ok: true,
|
|
157
|
+
payload: answer.data
|
|
158
|
+
} : {
|
|
159
|
+
ok: false,
|
|
160
|
+
failure: answer.failure
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
async function history() {
|
|
164
|
+
const answer = await requestJson(fetch, HOST_ROUTES.history, { headers: { accept: "application/json" } });
|
|
165
|
+
return answer.ok ? {
|
|
166
|
+
ok: true,
|
|
167
|
+
payload: answer.data
|
|
168
|
+
} : {
|
|
169
|
+
ok: false,
|
|
170
|
+
failure: answer.failure
|
|
171
|
+
};
|
|
172
|
+
}
|
|
152
173
|
//#endregion
|
|
153
174
|
//#region src/client/seam.ts
|
|
154
175
|
const PANEL_ID = "merge";
|
|
@@ -158,11 +179,15 @@ window.__ModuleLoader__.load({
|
|
|
158
179
|
const zh = {
|
|
159
180
|
"entry.label": "技能合并",
|
|
160
181
|
"hint": "手动触发;后台逐对判定。这里只读,不写技能。",
|
|
182
|
+
"history": "历史",
|
|
183
|
+
"close": "关闭",
|
|
184
|
+
"tab.verify": "待判断",
|
|
161
185
|
"tab.pending": "待批准",
|
|
162
|
-
"tab.
|
|
186
|
+
"tab.fuse": "待合并",
|
|
163
187
|
"tab.skipped": "无需合并",
|
|
188
|
+
"empty.verify": "没有待判断的对。",
|
|
164
189
|
"empty.pending": "没有待批准的合并。",
|
|
165
|
-
"empty.
|
|
190
|
+
"empty.fuse": "没有待合并的对。",
|
|
166
191
|
"empty.skipped": "没有标记为无需合并的对。",
|
|
167
192
|
"loading": "正在读取…",
|
|
168
193
|
"refresh": "刷新",
|
|
@@ -179,6 +204,8 @@ window.__ModuleLoader__.load({
|
|
|
179
204
|
"row.attempts": "尝试",
|
|
180
205
|
"row.origin": "来源",
|
|
181
206
|
"row.expires": "暂存到期",
|
|
207
|
+
"row.expired": "已过期",
|
|
208
|
+
"row.reason": "原因",
|
|
182
209
|
"row.failure": "失败",
|
|
183
210
|
"row.noRetry": "不可重试",
|
|
184
211
|
"row.copy": "复制命令",
|
|
@@ -186,17 +213,22 @@ window.__ModuleLoader__.load({
|
|
|
186
213
|
"origin.human": "人工",
|
|
187
214
|
"state.verify": "待判定",
|
|
188
215
|
"state.pending": "待批准",
|
|
189
|
-
"state.
|
|
216
|
+
"state.approved": "已批准",
|
|
217
|
+
"state.fuse": "待合并",
|
|
190
218
|
"state.skipped": "已跳过"
|
|
191
219
|
};
|
|
192
220
|
const en = {
|
|
193
221
|
"entry.label": "Skill merge",
|
|
194
222
|
"hint": "Manual only; pairs are judged in the background. Read-only here.",
|
|
195
|
-
"
|
|
196
|
-
"
|
|
223
|
+
"history": "History",
|
|
224
|
+
"close": "Close",
|
|
225
|
+
"tab.verify": "To judge",
|
|
226
|
+
"tab.pending": "Pending approval",
|
|
227
|
+
"tab.fuse": "Ready to merge",
|
|
197
228
|
"tab.skipped": "Skipped",
|
|
229
|
+
"empty.verify": "No pairs to judge.",
|
|
198
230
|
"empty.pending": "No pending merges.",
|
|
199
|
-
"empty.
|
|
231
|
+
"empty.fuse": "No pairs ready to merge.",
|
|
200
232
|
"empty.skipped": "No pairs marked as not worth merging.",
|
|
201
233
|
"loading": "Loading…",
|
|
202
234
|
"refresh": "Refresh",
|
|
@@ -213,6 +245,8 @@ window.__ModuleLoader__.load({
|
|
|
213
245
|
"row.attempts": "Attempts",
|
|
214
246
|
"row.origin": "Origin",
|
|
215
247
|
"row.expires": "Staging expires",
|
|
248
|
+
"row.expired": "Expired",
|
|
249
|
+
"row.reason": "Reason",
|
|
216
250
|
"row.failure": "Failure",
|
|
217
251
|
"row.noRetry": "not retryable",
|
|
218
252
|
"row.copy": "Copy command",
|
|
@@ -220,7 +254,8 @@ window.__ModuleLoader__.load({
|
|
|
220
254
|
"origin.human": "human",
|
|
221
255
|
"state.verify": "Unverified",
|
|
222
256
|
"state.pending": "Pending approval",
|
|
223
|
-
"state.
|
|
257
|
+
"state.approved": "Approved",
|
|
258
|
+
"state.fuse": "Ready to merge",
|
|
224
259
|
"state.skipped": "Skipped"
|
|
225
260
|
};
|
|
226
261
|
//#endregion
|
|
@@ -297,8 +332,9 @@ window.__ModuleLoader__.load({
|
|
|
297
332
|
* intentionally copied commands, not buttons that write from the browser.
|
|
298
333
|
*/
|
|
299
334
|
const QUEUES = [
|
|
335
|
+
"verify",
|
|
300
336
|
"pending",
|
|
301
|
-
"
|
|
337
|
+
"fuse",
|
|
302
338
|
"skipped"
|
|
303
339
|
];
|
|
304
340
|
function failure(t, failure) {
|
|
@@ -316,6 +352,7 @@ window.__ModuleLoader__.load({
|
|
|
316
352
|
const [loading, setLoading] = (0, react.useState)(face.loadRows !== void 0 || face.loadView !== void 0);
|
|
317
353
|
const [failed, setFailed] = (0, react.useState)(void 0);
|
|
318
354
|
const [nextCursor, setNextCursor] = (0, react.useState)(void 0);
|
|
355
|
+
const [overlay, setOverlay] = (0, react.useState)(void 0);
|
|
319
356
|
const request = (0, react.useRef)(0);
|
|
320
357
|
const loadRows = (queue, cursor = 0) => {
|
|
321
358
|
const load = face.loadRows;
|
|
@@ -347,7 +384,7 @@ window.__ModuleLoader__.load({
|
|
|
347
384
|
setFailed(outcome.failure);
|
|
348
385
|
return;
|
|
349
386
|
}
|
|
350
|
-
if (outcome.payload.schemaVersion !== void 0 && outcome.payload.schemaVersion !==
|
|
387
|
+
if (outcome.payload.schemaVersion !== void 0 && outcome.payload.schemaVersion !== 2) {
|
|
351
388
|
setFailed({
|
|
352
389
|
kind: "server",
|
|
353
390
|
status: 0
|
|
@@ -362,6 +399,39 @@ window.__ModuleLoader__.load({
|
|
|
362
399
|
});
|
|
363
400
|
});
|
|
364
401
|
};
|
|
402
|
+
const openBody = (id, side) => {
|
|
403
|
+
const load = face.loadBody;
|
|
404
|
+
if (load === void 0) return;
|
|
405
|
+
load(id, side).then((outcome) => {
|
|
406
|
+
if (outcome.ok) setOverlay({
|
|
407
|
+
kind: "body",
|
|
408
|
+
html: outcome.payload.html,
|
|
409
|
+
label: id + ":" + side
|
|
410
|
+
});
|
|
411
|
+
else setFailed(outcome.failure);
|
|
412
|
+
}).catch(() => {
|
|
413
|
+
setFailed({
|
|
414
|
+
kind: "server",
|
|
415
|
+
status: 0
|
|
416
|
+
});
|
|
417
|
+
});
|
|
418
|
+
};
|
|
419
|
+
const openHistory = () => {
|
|
420
|
+
const load = face.loadHistory;
|
|
421
|
+
if (load === void 0) return;
|
|
422
|
+
load().then((outcome) => {
|
|
423
|
+
if (outcome.ok) setOverlay({
|
|
424
|
+
kind: "history",
|
|
425
|
+
items: outcome.payload.items
|
|
426
|
+
});
|
|
427
|
+
else setFailed(outcome.failure);
|
|
428
|
+
}).catch(() => {
|
|
429
|
+
setFailed({
|
|
430
|
+
kind: "server",
|
|
431
|
+
status: 0
|
|
432
|
+
});
|
|
433
|
+
});
|
|
434
|
+
};
|
|
365
435
|
(0, react.useEffect)(() => {
|
|
366
436
|
loadView();
|
|
367
437
|
loadRows("pending");
|
|
@@ -399,12 +469,27 @@ window.__ModuleLoader__.load({
|
|
|
399
469
|
row.attempts === void 0 ? void 0 : t("row.attempts") + " " + String(row.attempts),
|
|
400
470
|
row.origin === void 0 ? void 0 : t("row.origin") + " " + t("origin." + row.origin),
|
|
401
471
|
row.stagingExpiresAt === void 0 ? void 0 : t("row.expires") + " " + new Date(row.stagingExpiresAt).toLocaleString(),
|
|
472
|
+
row.expired === void 0 ? void 0 : t("row.expired") + " " + row.expired,
|
|
473
|
+
row.reason === void 0 ? void 0 : t("row.reason") + " " + row.reason,
|
|
474
|
+
row.summary === void 0 ? void 0 : row.summary.filter(Boolean).join(" · "),
|
|
402
475
|
row.failure === void 0 ? void 0 : t("row.failure") + " " + row.failure.message + (row.failure.retryable ? "" : " · " + t("row.noRetry"))
|
|
403
476
|
].filter((value) => value !== void 0).join(" · ");
|
|
404
477
|
return (0, react.createElement)("div", {
|
|
405
478
|
key: row.id,
|
|
406
479
|
"data-role": "row"
|
|
407
|
-
}, (0, react.createElement)("div", null, (0, react.createElement)("div", { "data-role": "row-label" }, row.label), (0, react.createElement)("div", { "data-role": "row-meta" }, t("state." + row.state) + (row.stage === null ? "" : " · " + t("stage." + row.stage))), facts === "" ? null : (0, react.createElement)("div", { "data-role": "row-facts" }, facts)), (0, react.createElement)("div", null, (0, react.createElement)("div", { "data-role": "row-meta" }, row.updatedAt), (0, react.createElement)("div", { "data-role": "row-actions" },
|
|
480
|
+
}, (0, react.createElement)("div", null, (0, react.createElement)("div", { "data-role": "row-label" }, row.label), (0, react.createElement)("div", { "data-role": "row-meta" }, t("state." + row.state) + (row.stage === null ? "" : " · " + t("stage." + row.stage))), facts === "" ? null : (0, react.createElement)("div", { "data-role": "row-facts" }, facts)), (0, react.createElement)("div", null, (0, react.createElement)("div", { "data-role": "row-meta" }, row.updatedAt), (0, react.createElement)("div", { "data-role": "row-actions" }, face.loadBody === void 0 ? null : (0, react.createElement)("button", {
|
|
481
|
+
type: "button",
|
|
482
|
+
"data-role": "body-a",
|
|
483
|
+
onClick: () => {
|
|
484
|
+
openBody(row.id, "a");
|
|
485
|
+
}
|
|
486
|
+
}, "A"), face.loadBody === void 0 ? null : (0, react.createElement)("button", {
|
|
487
|
+
type: "button",
|
|
488
|
+
"data-role": "body-b",
|
|
489
|
+
onClick: () => {
|
|
490
|
+
openBody(row.id, "b");
|
|
491
|
+
}
|
|
492
|
+
}, "B"), (row.actions ?? []).filter((action) => view.approval !== false || !action.includes("/evolution merge approve")).map((action) => (0, react.createElement)("button", {
|
|
408
493
|
key: action,
|
|
409
494
|
type: "button",
|
|
410
495
|
"data-role": "row-action",
|
|
@@ -423,7 +508,21 @@ window.__ModuleLoader__.load({
|
|
|
423
508
|
onClick: () => {
|
|
424
509
|
loadRows(tab, Number(nextCursor));
|
|
425
510
|
}
|
|
426
|
-
}, t("loadMore")), (0, react.createElement)("button", {
|
|
511
|
+
}, t("loadMore")), face.loadHistory === void 0 ? null : (0, react.createElement)("button", {
|
|
512
|
+
type: "button",
|
|
513
|
+
"data-role": "history",
|
|
514
|
+
onClick: openHistory
|
|
515
|
+
}, t("history")), overlay === void 0 ? null : (0, react.createElement)("section", { "data-role": "overlay" }, (0, react.createElement)("button", {
|
|
516
|
+
type: "button",
|
|
517
|
+
"data-role": "overlay-close",
|
|
518
|
+
onClick: () => {
|
|
519
|
+
setOverlay(void 0);
|
|
520
|
+
}
|
|
521
|
+
}, t("close")), overlay.kind === "body" ? (0, react.createElement)("div", {
|
|
522
|
+
"data-role": "body",
|
|
523
|
+
"data-label": overlay.label,
|
|
524
|
+
dangerouslySetInnerHTML: { __html: overlay.html }
|
|
525
|
+
}) : (0, react.createElement)("ul", { "data-role": "history-list" }, overlay.items.map((item) => (0, react.createElement)("li", { key: item.name }, item.name + " · " + item.kind + " · " + item.reason + " · v" + String(item.lastVersion))))), (0, react.createElement)("button", {
|
|
427
526
|
type: "button",
|
|
428
527
|
"data-role": "refresh",
|
|
429
528
|
onClick: () => {
|
|
@@ -452,17 +551,22 @@ window.__ModuleLoader__.load({
|
|
|
452
551
|
function seedView() {
|
|
453
552
|
return {
|
|
454
553
|
counts: {
|
|
554
|
+
verify: 0,
|
|
455
555
|
pending: 0,
|
|
456
|
-
|
|
556
|
+
fuse: 0,
|
|
457
557
|
skipped: 0
|
|
458
558
|
},
|
|
459
559
|
tabs: [
|
|
560
|
+
{
|
|
561
|
+
queue: "verify",
|
|
562
|
+
count: 0
|
|
563
|
+
},
|
|
460
564
|
{
|
|
461
565
|
queue: "pending",
|
|
462
566
|
count: 0
|
|
463
567
|
},
|
|
464
568
|
{
|
|
465
|
-
queue: "
|
|
569
|
+
queue: "fuse",
|
|
466
570
|
count: 0
|
|
467
571
|
},
|
|
468
572
|
{
|
|
@@ -524,6 +628,8 @@ window.__ModuleLoader__.load({
|
|
|
524
628
|
rows: [],
|
|
525
629
|
loadView: view,
|
|
526
630
|
loadRows: rows,
|
|
631
|
+
loadBody: body,
|
|
632
|
+
loadHistory: history,
|
|
527
633
|
t
|
|
528
634
|
})
|
|
529
635
|
}, MergePanel);
|
|
@@ -3,12 +3,16 @@
|
|
|
3
3
|
* intentionally copied commands, not buttons that write from the browser.
|
|
4
4
|
*/
|
|
5
5
|
import { type ReactNode } from 'react';
|
|
6
|
-
import type { MergeOutcome, MergeQueue, MergeRowView, MergeViewPayload, QueuePage } from './api.ts';
|
|
6
|
+
import type { MergeBody, MergeHistoryItem, MergeOutcome, MergeQueue, MergeRowView, MergeViewPayload, QueuePage } from './api.ts';
|
|
7
7
|
export interface MergeFace {
|
|
8
8
|
view: MergeViewPayload;
|
|
9
9
|
rows: MergeRowView[];
|
|
10
10
|
loadView?: () => Promise<MergeOutcome<MergeViewPayload>>;
|
|
11
11
|
loadRows?: (queue: MergeQueue, cursor?: number) => Promise<MergeOutcome<QueuePage>>;
|
|
12
|
+
loadBody?: (id: string, side: 'a' | 'b') => Promise<MergeOutcome<MergeBody>>;
|
|
13
|
+
loadHistory?: () => Promise<MergeOutcome<{
|
|
14
|
+
items: MergeHistoryItem[];
|
|
15
|
+
}>>;
|
|
12
16
|
t: (key: string) => string;
|
|
13
17
|
}
|
|
14
18
|
export declare function MergePanel(face: MergeFace): ReactNode;
|
|
@@ -2,13 +2,14 @@ import { type RouteFailure } from './route-client.generated.ts';
|
|
|
2
2
|
export declare const HOST_ROUTES: {
|
|
3
3
|
readonly view: "/api/dsh-evolution/merge/view";
|
|
4
4
|
readonly rows: "/api/dsh-evolution/merge/rows";
|
|
5
|
-
readonly
|
|
6
|
-
readonly
|
|
5
|
+
readonly body: "/api/dsh-evolution/merge/body";
|
|
6
|
+
readonly history: "/api/dsh-evolution/merge/history";
|
|
7
7
|
};
|
|
8
|
-
export type MergeQueue = 'pending' | '
|
|
8
|
+
export type MergeQueue = 'verify' | 'pending' | 'fuse' | 'skipped';
|
|
9
9
|
export interface MergeCounts {
|
|
10
|
+
verify: number;
|
|
10
11
|
pending: number;
|
|
11
|
-
|
|
12
|
+
fuse: number;
|
|
12
13
|
skipped: number;
|
|
13
14
|
}
|
|
14
15
|
export interface MergeRunView {
|
|
@@ -55,6 +56,9 @@ export interface MergeRowView {
|
|
|
55
56
|
attempts?: number;
|
|
56
57
|
origin?: 'agent' | 'human';
|
|
57
58
|
stagingExpiresAt?: number;
|
|
59
|
+
expired?: 'target-taken' | 'source-changed';
|
|
60
|
+
reason?: string;
|
|
61
|
+
summary?: string[];
|
|
58
62
|
actions?: string[];
|
|
59
63
|
}
|
|
60
64
|
export interface QueuePage {
|
|
@@ -62,6 +66,19 @@ export interface QueuePage {
|
|
|
62
66
|
items: MergeRowView[];
|
|
63
67
|
nextCursor?: string;
|
|
64
68
|
}
|
|
69
|
+
export interface MergeBody {
|
|
70
|
+
content: string;
|
|
71
|
+
markdown: boolean;
|
|
72
|
+
html: string;
|
|
73
|
+
}
|
|
74
|
+
export interface MergeHistoryItem {
|
|
75
|
+
name: string;
|
|
76
|
+
kind: 'merged' | 'deleted' | 'split' | 'other';
|
|
77
|
+
reason: string;
|
|
78
|
+
lastVersion: number;
|
|
79
|
+
archivedAt: string;
|
|
80
|
+
sourceRunId?: string;
|
|
81
|
+
}
|
|
65
82
|
export type MergeOutcome<T> = {
|
|
66
83
|
ok: true;
|
|
67
84
|
payload: T;
|
|
@@ -71,4 +88,8 @@ export type MergeOutcome<T> = {
|
|
|
71
88
|
};
|
|
72
89
|
export declare function view(): Promise<MergeOutcome<MergeViewPayload>>;
|
|
73
90
|
export declare function rows(queue: MergeQueue, cursor?: number): Promise<MergeOutcome<QueuePage>>;
|
|
91
|
+
export declare function body(id: string, side: 'a' | 'b'): Promise<MergeOutcome<MergeBody>>;
|
|
92
|
+
export declare function history(): Promise<MergeOutcome<{
|
|
93
|
+
items: MergeHistoryItem[];
|
|
94
|
+
}>>;
|
|
74
95
|
//# sourceMappingURL=api.d.ts.map
|
|
@@ -27,8 +27,8 @@ export declare const ROUTES: {
|
|
|
27
27
|
readonly merge: {
|
|
28
28
|
readonly view: "/api/dsh-evolution/merge/view";
|
|
29
29
|
readonly rows: "/api/dsh-evolution/merge/rows";
|
|
30
|
-
readonly
|
|
31
|
-
readonly
|
|
30
|
+
readonly body: "/api/dsh-evolution/merge/body";
|
|
31
|
+
readonly history: "/api/dsh-evolution/merge/history";
|
|
32
32
|
};
|
|
33
33
|
readonly diagnostics: {
|
|
34
34
|
readonly view: "/api/dsh-evolution/diagnostics";
|