github-issue-tower-defence-management 1.174.2 → 1.175.0
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/CHANGELOG.md +14 -0
- package/bin/adapter/entry-points/console/consoleDoneStore.js +0 -2
- package/bin/adapter/entry-points/console/consoleDoneStore.js.map +1 -1
- package/bin/adapter/entry-points/console/consoleTabNames.js +0 -1
- package/bin/adapter/entry-points/console/consoleTabNames.js.map +1 -1
- package/bin/adapter/entry-points/console/dashboardComposeService.js +2 -4
- package/bin/adapter/entry-points/console/dashboardComposeService.js.map +1 -1
- package/bin/adapter/entry-points/console/ui-dist/assets/{index-g4SqIzCh.js → index-BhDothvr.js} +1 -1
- package/bin/adapter/entry-points/console/ui-dist/index.html +1 -1
- package/bin/domain/entities/WorkflowStatus.js +1 -6
- package/bin/domain/entities/WorkflowStatus.js.map +1 -1
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js +4 -5
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.js +0 -39
- package/bin/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.js.map +1 -1
- package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js +4 -5
- package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/SetupTowerDefenceProjectUseCase.js +15 -1
- package/bin/domain/usecases/SetupTowerDefenceProjectUseCase.js.map +1 -1
- package/bin/domain/usecases/console/GenerateConsoleListsUseCase.js +0 -2
- package/bin/domain/usecases/console/GenerateConsoleListsUseCase.js.map +1 -1
- package/bin/domain/usecases/dashboard/ComposeDashboardUseCase.js +2 -3
- package/bin/domain/usecases/dashboard/ComposeDashboardUseCase.js.map +1 -1
- package/bin/domain/usecases/dashboard/GenerateDashboardRowUseCase.js +0 -1
- package/bin/domain/usecases/dashboard/GenerateDashboardRowUseCase.js.map +1 -1
- package/bin/domain/usecases/findLastAgentDeclaringReport.js +12 -0
- package/bin/domain/usecases/findLastAgentDeclaringReport.js.map +1 -0
- package/package.json +1 -1
- package/src/adapter/entry-points/console/consoleDoneStore.ts +0 -2
- package/src/adapter/entry-points/console/consoleTabNames.ts +0 -1
- package/src/adapter/entry-points/console/dashboardComposeService.test.ts +4 -8
- package/src/adapter/entry-points/console/dashboardComposeService.ts +1 -3
- package/src/adapter/entry-points/console/dashboardEmitterComposerKey.test.ts +12 -17
- package/src/adapter/entry-points/console/ui/e2e/consoleScenario.spec.ts +4 -32
- package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +1 -18
- package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.stories.tsx +3 -7
- package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.test.tsx +2 -4
- package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleOperationMenu.test.tsx +1 -1
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleNavigation.test.ts +6 -8
- package/src/adapter/entry-points/console/ui/src/features/console/logic/tabAdvance.test.ts +8 -17
- package/src/adapter/entry-points/console/ui/src/features/console/logic/types.ts +0 -2
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.test.tsx +3 -3
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.test.tsx +5 -6
- package/src/adapter/entry-points/console/ui-dist/assets/{index-g4SqIzCh.js → index-BhDothvr.js} +1 -1
- package/src/adapter/entry-points/console/ui-dist/index.html +1 -1
- package/src/adapter/entry-points/console/webServer.test.ts +4 -6
- package/src/adapter/entry-points/handlers/consoleListsWriter.test.ts +30 -26
- package/src/adapter/entry-points/handlers/dashboardRowWriter.test.ts +5 -6
- package/src/domain/entities/WorkflowStatus.ts +0 -5
- package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.test.ts +32 -0
- package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +7 -8
- package/src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.test.ts +198 -863
- package/src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.ts +0 -68
- package/src/domain/usecases/RevertOrphanedPreparationUseCase.ts +8 -11
- package/src/domain/usecases/SetupTowerDefenceProjectUseCase.test.ts +89 -51
- package/src/domain/usecases/SetupTowerDefenceProjectUseCase.ts +30 -2
- package/src/domain/usecases/console/GenerateConsoleListsUseCase.test.ts +62 -72
- package/src/domain/usecases/console/GenerateConsoleListsUseCase.ts +0 -8
- package/src/domain/usecases/dashboard/ComposeDashboardUseCase.test.ts +19 -28
- package/src/domain/usecases/dashboard/ComposeDashboardUseCase.ts +2 -3
- package/src/domain/usecases/dashboard/GenerateDashboardRowUseCase.test.ts +11 -12
- package/src/domain/usecases/dashboard/GenerateDashboardRowUseCase.ts +0 -3
- package/src/domain/usecases/findLastAgentDeclaringReport.test.ts +71 -0
- package/src/domain/usecases/findLastAgentDeclaringReport.ts +17 -0
- package/src/domain/usecases/intmux/GenerateInTmuxByHumanDataUseCase.test.ts +2 -2
- package/types/adapter/entry-points/console/consoleDoneStore.d.ts.map +1 -1
- package/types/adapter/entry-points/console/consoleTabNames.d.ts.map +1 -1
- package/types/adapter/entry-points/console/dashboardComposeService.d.ts.map +1 -1
- package/types/domain/entities/WorkflowStatus.d.ts +0 -1
- package/types/domain/entities/WorkflowStatus.d.ts.map +1 -1
- package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.d.ts.map +1 -1
- package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/SetupTowerDefenceProjectUseCase.d.ts +1 -0
- package/types/domain/usecases/SetupTowerDefenceProjectUseCase.d.ts.map +1 -1
- package/types/domain/usecases/console/GenerateConsoleListsUseCase.d.ts +1 -2
- package/types/domain/usecases/console/GenerateConsoleListsUseCase.d.ts.map +1 -1
- package/types/domain/usecases/dashboard/ComposeDashboardUseCase.d.ts.map +1 -1
- package/types/domain/usecases/dashboard/GenerateDashboardRowUseCase.d.ts +0 -1
- package/types/domain/usecases/dashboard/GenerateDashboardRowUseCase.d.ts.map +1 -1
- package/types/domain/usecases/findLastAgentDeclaringReport.d.ts +5 -0
- package/types/domain/usecases/findLastAgentDeclaringReport.d.ts.map +1 -0
|
@@ -25,7 +25,6 @@ describe('buildComposeDashboardInput', () => {
|
|
|
25
25
|
writeProject(dataDir, 'acme', {
|
|
26
26
|
pjcode: 'acme',
|
|
27
27
|
capturedAt: 'x',
|
|
28
|
-
unread: 3,
|
|
29
28
|
todo: 1,
|
|
30
29
|
qc: 2,
|
|
31
30
|
fail: 0,
|
|
@@ -42,7 +41,6 @@ describe('buildComposeDashboardInput', () => {
|
|
|
42
41
|
{
|
|
43
42
|
code: 'ac',
|
|
44
43
|
row: {
|
|
45
|
-
unread: 3,
|
|
46
44
|
todo: 1,
|
|
47
45
|
qc: 2,
|
|
48
46
|
fail: 0,
|
|
@@ -62,7 +60,7 @@ describe('buildComposeDashboardInput', () => {
|
|
|
62
60
|
it('treats a project file with a missing field as an absent row', () => {
|
|
63
61
|
const dataDir = makeDataDir();
|
|
64
62
|
try {
|
|
65
|
-
writeProject(dataDir, 'acme', {
|
|
63
|
+
writeProject(dataDir, 'acme', { todo: 1 });
|
|
66
64
|
const input = buildComposeDashboardInput({
|
|
67
65
|
dashboardDataDir: dataDir,
|
|
68
66
|
projectNames: ['acme'],
|
|
@@ -365,7 +363,6 @@ describe('composeDashboardText', () => {
|
|
|
365
363
|
writeProject(dataDir, 'acme', {
|
|
366
364
|
pjcode: 'acme',
|
|
367
365
|
capturedAt: 'x',
|
|
368
|
-
unread: 3,
|
|
369
366
|
todo: 1,
|
|
370
367
|
qc: 2,
|
|
371
368
|
fail: 0,
|
|
@@ -411,9 +408,9 @@ describe('composeDashboardText', () => {
|
|
|
411
408
|
).toBe(
|
|
412
409
|
'<tt>M55% C62% D89% cy14</tt><br>\n' +
|
|
413
410
|
'<tt>LA 16 23 40</tt><br>\n' +
|
|
414
|
-
'<tt>pj
|
|
415
|
-
'<tt>🟢ac
|
|
416
|
-
'<tt> in -- -- -- -- --  
|
|
411
|
+
'<tt>pj tdo aqc fal prp aws dep</tt><br>\n' +
|
|
412
|
+
'<tt>🟢ac 1 2 0 0 4 1</tt><br>\n' +
|
|
413
|
+
'<tt> in -- -- -- -- -- --</tt><br>\n' +
|
|
417
414
|
'<tt></tt><br>\n' +
|
|
418
415
|
'<tt>🟢alice 10% 0d01h00 12% 5d00h00 2 1</tt><br>\n',
|
|
419
416
|
);
|
|
@@ -445,7 +442,6 @@ describe('dashboardComposeFilesPresent', () => {
|
|
|
445
442
|
const minimalProject = {
|
|
446
443
|
pjcode: 'acme',
|
|
447
444
|
capturedAt: 'x',
|
|
448
|
-
unread: 0,
|
|
449
445
|
todo: 0,
|
|
450
446
|
qc: 0,
|
|
451
447
|
fail: 0,
|
|
@@ -44,7 +44,6 @@ const parseDashboardRow = (value: unknown): DashboardRow | null => {
|
|
|
44
44
|
if (!isRecord(value)) {
|
|
45
45
|
return null;
|
|
46
46
|
}
|
|
47
|
-
const unread = asFiniteNumber(value.unread);
|
|
48
47
|
const todo = asFiniteNumber(value.todo);
|
|
49
48
|
const qc = asFiniteNumber(value.qc);
|
|
50
49
|
const fail = asFiniteNumber(value.fail);
|
|
@@ -53,7 +52,6 @@ const parseDashboardRow = (value: unknown): DashboardRow | null => {
|
|
|
53
52
|
const dep = asFiniteNumber(value.dep);
|
|
54
53
|
const blocker = asFiniteNumber(value.blocker);
|
|
55
54
|
if (
|
|
56
|
-
unread === null ||
|
|
57
55
|
todo === null ||
|
|
58
56
|
qc === null ||
|
|
59
57
|
fail === null ||
|
|
@@ -64,7 +62,7 @@ const parseDashboardRow = (value: unknown): DashboardRow | null => {
|
|
|
64
62
|
) {
|
|
65
63
|
return null;
|
|
66
64
|
}
|
|
67
|
-
return {
|
|
65
|
+
return { todo, qc, fail, pr, ws, dep, blocker };
|
|
68
66
|
};
|
|
69
67
|
|
|
70
68
|
const readProjectRow = (
|
|
@@ -71,7 +71,7 @@ describe('dashboard emitter filename matches composer lookup key', () => {
|
|
|
71
71
|
dashboardDataDir: dir,
|
|
72
72
|
pjcode: projectName,
|
|
73
73
|
assigneeLogin: ASSIGNEE,
|
|
74
|
-
issues: [makeIssue({ status: '
|
|
74
|
+
issues: [makeIssue({ status: 'Awaiting Workspace' })],
|
|
75
75
|
generatedAt: '2026-06-26T12:00:00.000Z',
|
|
76
76
|
});
|
|
77
77
|
|
|
@@ -90,7 +90,7 @@ describe('dashboard emitter filename matches composer lookup key', () => {
|
|
|
90
90
|
dashboardDataDir: dir,
|
|
91
91
|
pjcode: projectName,
|
|
92
92
|
assigneeLogin: ASSIGNEE,
|
|
93
|
-
issues: [makeIssue({ status: '
|
|
93
|
+
issues: [makeIssue({ status: 'Awaiting Workspace' })],
|
|
94
94
|
generatedAt: '2026-06-26T12:00:00.000Z',
|
|
95
95
|
});
|
|
96
96
|
}
|
|
@@ -119,7 +119,10 @@ describe('dashboard emitter filename matches composer lookup key', () => {
|
|
|
119
119
|
|
|
120
120
|
it('composes the full grid with no fallback row and shows the 2-char display labels', () => {
|
|
121
121
|
const issuesByName: Record<string, Issue[]> = {
|
|
122
|
-
acme: [
|
|
122
|
+
acme: [
|
|
123
|
+
makeIssue({ status: 'Failed Preparation' }),
|
|
124
|
+
makeIssue({ status: 'Failed Preparation' }),
|
|
125
|
+
],
|
|
123
126
|
globex: [makeIssue({ status: 'Awaiting Quality Check' })],
|
|
124
127
|
initech: [makeIssue({ status: 'Awaiting Workspace' })],
|
|
125
128
|
umbrella: [makeIssue({ status: 'Todo by human' })],
|
|
@@ -160,22 +163,14 @@ describe('dashboard emitter filename matches composer lookup key', () => {
|
|
|
160
163
|
[
|
|
161
164
|
wrap('M55% C62% D93% cy13'),
|
|
162
165
|
wrap('LA 16 23 40'),
|
|
163
|
-
wrap('pj
|
|
166
|
+
wrap('pj tdo aqc fal prp aws dep'),
|
|
167
|
+
wrap(`🟢${toDashboardDisplayLabel('acme')} 0 0 2 0 0 0`),
|
|
168
|
+
wrap(`🟢${toDashboardDisplayLabel('globex')} 0 1 0 0 0 0`),
|
|
169
|
+
wrap(`🟢${toDashboardDisplayLabel('initech')} 0 0 0 0 1 0`),
|
|
164
170
|
wrap(
|
|
165
|
-
`🟢${toDashboardDisplayLabel('
|
|
166
|
-
),
|
|
167
|
-
wrap(
|
|
168
|
-
`🟢${toDashboardDisplayLabel('globex')} 0 0 1 0 0 0 0`,
|
|
169
|
-
),
|
|
170
|
-
wrap(
|
|
171
|
-
`🟢${toDashboardDisplayLabel('initech')} 0 0 0 0 0 1 0`,
|
|
172
|
-
),
|
|
173
|
-
wrap(
|
|
174
|
-
`🟢${toDashboardDisplayLabel('umbrella')} 0 1 0 0 0 0 0`,
|
|
175
|
-
),
|
|
176
|
-
wrap(
|
|
177
|
-
`🟢${toDashboardDisplayLabel('soylent')} 0 0 0 0 1 0 0`,
|
|
171
|
+
`🟢${toDashboardDisplayLabel('umbrella')} 1 0 0 0 0 0`,
|
|
178
172
|
),
|
|
173
|
+
wrap(`🟢${toDashboardDisplayLabel('soylent')} 0 0 0 1 0 0`),
|
|
179
174
|
wrap(''),
|
|
180
175
|
].join('\n') + '\n';
|
|
181
176
|
expect(composed).toBe(expected);
|
|
@@ -28,14 +28,6 @@ const tabBadge = (page: Page, label: string) =>
|
|
|
28
28
|
const itemRowByText = (page: Page, text: string) =>
|
|
29
29
|
page.locator('.console-item-row', { hasText: text });
|
|
30
30
|
|
|
31
|
-
const processSelectedItemViaStatus = async (page: Page): Promise<void> => {
|
|
32
|
-
const statusButton = page
|
|
33
|
-
.locator('.console-op-button', { hasText: 'Awaiting Workspace' })
|
|
34
|
-
.first();
|
|
35
|
-
await expect(statusButton).toBeVisible();
|
|
36
|
-
await statusButton.click();
|
|
37
|
-
};
|
|
38
|
-
|
|
39
31
|
test('shows CI and conflict badges in the directly opened PR detail header', async ({
|
|
40
32
|
page,
|
|
41
33
|
}) => {
|
|
@@ -72,7 +64,6 @@ test('processing tabs drives auto-advance and keeps emptied badges at zero', asy
|
|
|
72
64
|
|
|
73
65
|
await expect(activeTabLabel(page)).toHaveText('Awaiting Quality Check');
|
|
74
66
|
await expect(tabBadge(page, 'Awaiting Quality Check')).toHaveText('1');
|
|
75
|
-
await expect(tabBadge(page, 'Unread')).toHaveText('2');
|
|
76
67
|
await expect(tabBadge(page, 'Triage')).toHaveText('2');
|
|
77
68
|
await expect(tabBadge(page, 'Todo by human')).toHaveText('1');
|
|
78
69
|
|
|
@@ -86,38 +77,19 @@ test('processing tabs drives auto-advance and keeps emptied badges at zero', asy
|
|
|
86
77
|
await expect(approveButton).toBeVisible();
|
|
87
78
|
await approveButton.click();
|
|
88
79
|
|
|
89
|
-
await expect(activeTabLabel(page)).toHaveText('Unread', { timeout: 8000 });
|
|
90
|
-
await expect(tabByLabel(page, 'Awaiting Quality Check')).toHaveCount(0, {
|
|
91
|
-
timeout: 8000,
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
await itemRowByText(
|
|
95
|
-
page,
|
|
96
|
-
'Scaffold React console UI under entry-points with build bundling',
|
|
97
|
-
).click();
|
|
98
|
-
await processSelectedItemViaStatus(page);
|
|
99
|
-
await expect(tabBadge(page, 'Unread')).toHaveText('1', { timeout: 8000 });
|
|
100
|
-
await tabByLabel(page, 'Unread').click();
|
|
101
|
-
|
|
102
|
-
await itemRowByText(
|
|
103
|
-
page,
|
|
104
|
-
'Add server-side console API handlers for read and operation endpoints',
|
|
105
|
-
).click();
|
|
106
|
-
await processSelectedItemViaStatus(page);
|
|
107
|
-
|
|
108
80
|
await expect(activeTabLabel(page)).toHaveText('Triage', { timeout: 8000 });
|
|
109
|
-
await expect(tabByLabel(page, '
|
|
81
|
+
await expect(tabByLabel(page, 'Awaiting Quality Check')).toHaveCount(0, {
|
|
110
82
|
timeout: 8000,
|
|
111
83
|
});
|
|
112
84
|
|
|
113
85
|
await tabByLabel(page, 'Todo by human').click();
|
|
114
86
|
await expect(activeTabLabel(page)).toHaveText('Todo by human');
|
|
115
|
-
await expect(tabByLabel(page, '
|
|
87
|
+
await expect(tabByLabel(page, 'Awaiting Quality Check')).toHaveCount(0);
|
|
116
88
|
await expect(tabBadge(page, 'Todo by human')).toHaveText('1');
|
|
117
89
|
|
|
118
90
|
await tabByLabel(page, 'Triage').click();
|
|
119
91
|
await expect(activeTabLabel(page)).toHaveText('Triage');
|
|
120
|
-
await expect(tabByLabel(page, '
|
|
92
|
+
await expect(tabByLabel(page, 'Awaiting Quality Check')).toHaveCount(0);
|
|
121
93
|
await expect(tabBadge(page, 'Triage')).toHaveText('2');
|
|
122
94
|
});
|
|
123
95
|
|
|
@@ -348,7 +320,7 @@ test('renders the stories tab with non-gray stories, their open item counts, and
|
|
|
348
320
|
const tdpmRow = page.locator('.console-story-list-row', {
|
|
349
321
|
hasText: 'TDPM Console port',
|
|
350
322
|
});
|
|
351
|
-
await expect(tdpmRow.locator('.console-story-count')).toHaveText('
|
|
323
|
+
await expect(tdpmRow.locator('.console-story-count')).toHaveText('4');
|
|
352
324
|
await expect(
|
|
353
325
|
tdpmRow.locator('.console-op-button', { hasText: 'Add task' }),
|
|
354
326
|
).toBeVisible();
|
|
@@ -110,7 +110,6 @@ const AWAITING_WORKSPACE_OPTION: ConsoleFixtureFieldOption = {
|
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
const STATUS_OPTIONS: ConsoleFixtureFieldOption[] = [
|
|
113
|
-
{ id: 'f75ad846', name: 'Unread', color: 'ORANGE' },
|
|
114
113
|
AWAITING_WORKSPACE_OPTION,
|
|
115
114
|
{ id: 'f57f1ce9', name: 'Preparation', color: 'YELLOW' },
|
|
116
115
|
{ id: 'fd313492', name: 'Failed Preparation', color: 'RED' },
|
|
@@ -236,22 +235,6 @@ export const CONSOLE_E2E_TAB_ITEMS: Record<string, ConsoleFixtureListItem[]> = {
|
|
|
236
235
|
'2026-06-10T11:42:00.000Z',
|
|
237
236
|
),
|
|
238
237
|
],
|
|
239
|
-
unread: [
|
|
240
|
-
issueItem(
|
|
241
|
-
845,
|
|
242
|
-
'Scaffold React console UI under entry-points with build bundling',
|
|
243
|
-
'UNR00845',
|
|
244
|
-
'TDPM Console port',
|
|
245
|
-
'2026-06-16T22:01:55.000Z',
|
|
246
|
-
),
|
|
247
|
-
issueItem(
|
|
248
|
-
853,
|
|
249
|
-
'Add server-side console API handlers for read and operation endpoints',
|
|
250
|
-
'UNR00853',
|
|
251
|
-
'TDPM Console port',
|
|
252
|
-
'2026-06-17T05:48:09.000Z',
|
|
253
|
-
),
|
|
254
|
-
],
|
|
255
238
|
'failed-preparation': [
|
|
256
239
|
{
|
|
257
240
|
...issueItem(
|
|
@@ -295,7 +278,7 @@ const CONSOLE_E2E_STORIES_SNAPSHOT = {
|
|
|
295
278
|
storyName: 'TDPM Console port',
|
|
296
279
|
storyOptionId: '1491051e',
|
|
297
280
|
color: 'BLUE',
|
|
298
|
-
openItemCount:
|
|
281
|
+
openItemCount: 4,
|
|
299
282
|
},
|
|
300
283
|
{
|
|
301
284
|
storyName: 'Publish product documentation site',
|
|
@@ -23,7 +23,6 @@ const counts: Record<ConsoleTabName, number> = {
|
|
|
23
23
|
'workflow-blocker': 5,
|
|
24
24
|
prs: 35,
|
|
25
25
|
triage: 132,
|
|
26
|
-
unread: 18,
|
|
27
26
|
'failed-preparation': 2,
|
|
28
27
|
'todo-by-human': 66,
|
|
29
28
|
'todo-by-agent': 24,
|
|
@@ -44,9 +43,8 @@ export const ZeroCountTabsHidden: Story = {
|
|
|
44
43
|
'workflow-blocker': 0,
|
|
45
44
|
prs: 35,
|
|
46
45
|
triage: 0,
|
|
47
|
-
unread: 18,
|
|
48
46
|
'failed-preparation': 0,
|
|
49
|
-
'todo-by-human':
|
|
47
|
+
'todo-by-human': 18,
|
|
50
48
|
'todo-by-agent': 0,
|
|
51
49
|
stories: 0,
|
|
52
50
|
},
|
|
@@ -60,9 +58,8 @@ export const ZeroCountActiveTabStaysVisible: Story = {
|
|
|
60
58
|
'workflow-blocker': 0,
|
|
61
59
|
prs: 35,
|
|
62
60
|
triage: 0,
|
|
63
|
-
unread: 18,
|
|
64
61
|
'failed-preparation': 0,
|
|
65
|
-
'todo-by-human':
|
|
62
|
+
'todo-by-human': 18,
|
|
66
63
|
'todo-by-agent': 0,
|
|
67
64
|
stories: 0,
|
|
68
65
|
},
|
|
@@ -71,12 +68,11 @@ export const ZeroCountActiveTabStaysVisible: Story = {
|
|
|
71
68
|
|
|
72
69
|
export const AfterAutoAdvanceToNextTab: Story = {
|
|
73
70
|
args: {
|
|
74
|
-
activeTab: '
|
|
71
|
+
activeTab: 'failed-preparation',
|
|
75
72
|
counts: {
|
|
76
73
|
'workflow-blocker': 0,
|
|
77
74
|
prs: 0,
|
|
78
75
|
triage: 0,
|
|
79
|
-
unread: 7,
|
|
80
76
|
'failed-preparation': 2,
|
|
81
77
|
'todo-by-human': 4,
|
|
82
78
|
'todo-by-agent': 0,
|
|
@@ -6,7 +6,6 @@ const counts: Record<ConsoleTabName, number> = {
|
|
|
6
6
|
'workflow-blocker': 4,
|
|
7
7
|
prs: 3,
|
|
8
8
|
triage: 0,
|
|
9
|
-
unread: 5,
|
|
10
9
|
'failed-preparation': 0,
|
|
11
10
|
'todo-by-human': 2,
|
|
12
11
|
'todo-by-agent': 3,
|
|
@@ -27,7 +26,6 @@ describe('ConsoleTabList', () => {
|
|
|
27
26
|
<ConsoleTabList {...baseProps} activeTab="prs" counts={counts} />,
|
|
28
27
|
);
|
|
29
28
|
expect(queryByText('Awaiting Quality Check')).not.toBeNull();
|
|
30
|
-
expect(queryByText('Unread')).not.toBeNull();
|
|
31
29
|
expect(queryByText('Todo by human')).not.toBeNull();
|
|
32
30
|
expect(queryByText('Todo by agent')).not.toBeNull();
|
|
33
31
|
expect(queryByText('Triage')).toBeNull();
|
|
@@ -114,8 +112,8 @@ describe('ConsoleTabList', () => {
|
|
|
114
112
|
onSelectTab={onSelectTab}
|
|
115
113
|
/>,
|
|
116
114
|
);
|
|
117
|
-
fireEvent.click(getByText('
|
|
118
|
-
expect(onSelectTab).toHaveBeenCalledWith('
|
|
115
|
+
fireEvent.click(getByText('Todo by human'));
|
|
116
|
+
expect(onSelectTab).toHaveBeenCalledWith('todo-by-human');
|
|
119
117
|
});
|
|
120
118
|
|
|
121
119
|
it('prefixes the snapshot info with "(cached)" and sets data-from-cache when data is from cache', () => {
|
|
@@ -91,7 +91,7 @@ describe('ConsoleOperationMenu', () => {
|
|
|
91
91
|
it('hides the review group when there is no pull request', () => {
|
|
92
92
|
const { queryByText } = render(
|
|
93
93
|
<ConsoleOperationMenu
|
|
94
|
-
tab="
|
|
94
|
+
tab="todo-by-human"
|
|
95
95
|
item={issueItem}
|
|
96
96
|
hasPullRequest={false}
|
|
97
97
|
rejectEnabled={false}
|
package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleNavigation.test.ts
CHANGED
|
@@ -12,7 +12,6 @@ const counts = (
|
|
|
12
12
|
'workflow-blocker': 0,
|
|
13
13
|
prs: 0,
|
|
14
14
|
triage: 0,
|
|
15
|
-
unread: 0,
|
|
16
15
|
'failed-preparation': 0,
|
|
17
16
|
'todo-by-human': 0,
|
|
18
17
|
'todo-by-agent': 0,
|
|
@@ -63,10 +62,10 @@ describe('useConsoleNavigation', () => {
|
|
|
63
62
|
it('selects a tab and updates the path', () => {
|
|
64
63
|
const { result } = renderHook(() => useConsoleNavigation('acme', counts()));
|
|
65
64
|
act(() => {
|
|
66
|
-
result.current.selectTab('
|
|
65
|
+
result.current.selectTab('triage');
|
|
67
66
|
});
|
|
68
|
-
expect(result.current.activeTab).toBe('
|
|
69
|
-
expect(window.location.pathname).toBe('/projects/acme/
|
|
67
|
+
expect(result.current.activeTab).toBe('triage');
|
|
68
|
+
expect(window.location.pathname).toBe('/projects/acme/triage');
|
|
70
69
|
});
|
|
71
70
|
|
|
72
71
|
it('opens an item and reflects it in the hash', () => {
|
|
@@ -103,7 +102,6 @@ describe('useConsoleNavigation default tab without a tab segment', () => {
|
|
|
103
102
|
'workflow-blocker': 3,
|
|
104
103
|
prs: 5,
|
|
105
104
|
triage: 2,
|
|
106
|
-
unread: 9,
|
|
107
105
|
'failed-preparation': 1,
|
|
108
106
|
'todo-by-human': 4,
|
|
109
107
|
}),
|
|
@@ -134,14 +132,14 @@ describe('useConsoleNavigation default tab without a tab segment', () => {
|
|
|
134
132
|
{ initialProps: { tabCounts: counts() } },
|
|
135
133
|
);
|
|
136
134
|
expect(result.current.activeTab).toBe('workflow-blocker');
|
|
137
|
-
rerender({ tabCounts: counts({
|
|
138
|
-
expect(result.current.activeTab).toBe('
|
|
135
|
+
rerender({ tabCounts: counts({ triage: 6 }) });
|
|
136
|
+
expect(result.current.activeTab).toBe('triage');
|
|
139
137
|
});
|
|
140
138
|
|
|
141
139
|
it('keeps the tab from the path even when counts are present', () => {
|
|
142
140
|
window.history.replaceState({}, '', '/projects/acme/triage?k=token');
|
|
143
141
|
const { result } = renderHook(() =>
|
|
144
|
-
useConsoleNavigation('acme', counts({
|
|
142
|
+
useConsoleNavigation('acme', counts({ triage: 6 })),
|
|
145
143
|
);
|
|
146
144
|
expect(result.current.activeTab).toBe('triage');
|
|
147
145
|
});
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
findNextNonEmptyTabToRight,
|
|
3
3
|
resolveDefaultActiveTab,
|
|
4
4
|
} from './tabAdvance';
|
|
5
|
-
import {
|
|
5
|
+
import type { ConsoleTabName } from './types';
|
|
6
6
|
|
|
7
7
|
const counts = (
|
|
8
8
|
overrides: Partial<Record<ConsoleTabName, number>>,
|
|
@@ -10,7 +10,6 @@ const counts = (
|
|
|
10
10
|
'workflow-blocker': 0,
|
|
11
11
|
prs: 0,
|
|
12
12
|
triage: 0,
|
|
13
|
-
unread: 0,
|
|
14
13
|
'failed-preparation': 0,
|
|
15
14
|
'todo-by-human': 0,
|
|
16
15
|
'todo-by-agent': 0,
|
|
@@ -18,17 +17,10 @@ const counts = (
|
|
|
18
17
|
...overrides,
|
|
19
18
|
});
|
|
20
19
|
|
|
21
|
-
describe('CONSOLE_TABS ordering', () => {
|
|
22
|
-
it('places Unread before Triage so unseen items are worked first', () => {
|
|
23
|
-
const names = CONSOLE_TABS.map((tab) => tab.name);
|
|
24
|
-
expect(names.indexOf('unread')).toBeLessThan(names.indexOf('triage'));
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
|
|
28
20
|
describe('findNextNonEmptyTabToRight', () => {
|
|
29
21
|
it('returns the first non-empty tab to the right of the active tab', () => {
|
|
30
|
-
expect(findNextNonEmptyTabToRight('prs', counts({
|
|
31
|
-
'
|
|
22
|
+
expect(findNextNonEmptyTabToRight('prs', counts({ triage: 7 }))).toBe(
|
|
23
|
+
'triage',
|
|
32
24
|
);
|
|
33
25
|
});
|
|
34
26
|
|
|
@@ -36,7 +28,7 @@ describe('findNextNonEmptyTabToRight', () => {
|
|
|
36
28
|
expect(
|
|
37
29
|
findNextNonEmptyTabToRight(
|
|
38
30
|
'prs',
|
|
39
|
-
counts({ triage: 0,
|
|
31
|
+
counts({ triage: 0, 'todo-by-human': 4 }),
|
|
40
32
|
),
|
|
41
33
|
).toBe('todo-by-human');
|
|
42
34
|
});
|
|
@@ -51,14 +43,14 @@ describe('findNextNonEmptyTabToRight', () => {
|
|
|
51
43
|
});
|
|
52
44
|
|
|
53
45
|
it('returns the immediately adjacent tab when it is non-empty', () => {
|
|
54
|
-
expect(
|
|
55
|
-
|
|
56
|
-
)
|
|
46
|
+
expect(findNextNonEmptyTabToRight('prs', counts({ triage: 12 }))).toBe(
|
|
47
|
+
'triage',
|
|
48
|
+
);
|
|
57
49
|
});
|
|
58
50
|
|
|
59
51
|
it('returns null when no tab to the right has any items', () => {
|
|
60
52
|
expect(
|
|
61
|
-
findNextNonEmptyTabToRight('
|
|
53
|
+
findNextNonEmptyTabToRight('todo-by-human', counts({ prs: 35 })),
|
|
62
54
|
).toBeNull();
|
|
63
55
|
});
|
|
64
56
|
|
|
@@ -77,7 +69,6 @@ describe('resolveDefaultActiveTab', () => {
|
|
|
77
69
|
'workflow-blocker': 3,
|
|
78
70
|
prs: 5,
|
|
79
71
|
triage: 2,
|
|
80
|
-
unread: 9,
|
|
81
72
|
'failed-preparation': 1,
|
|
82
73
|
'todo-by-human': 4,
|
|
83
74
|
}),
|
|
@@ -145,7 +145,6 @@ export type ConsoleTabName =
|
|
|
145
145
|
| 'workflow-blocker'
|
|
146
146
|
| 'prs'
|
|
147
147
|
| 'triage'
|
|
148
|
-
| 'unread'
|
|
149
148
|
| 'failed-preparation'
|
|
150
149
|
| 'todo-by-human'
|
|
151
150
|
| 'todo-by-agent'
|
|
@@ -166,7 +165,6 @@ export type ConsoleTab = {
|
|
|
166
165
|
export const CONSOLE_TABS: ConsoleTab[] = [
|
|
167
166
|
{ name: 'workflow-blocker', label: 'Workflow Blocker' },
|
|
168
167
|
{ name: 'prs', label: 'Awaiting Quality Check' },
|
|
169
|
-
{ name: 'unread', label: 'Unread' },
|
|
170
168
|
{ name: 'triage', label: 'Triage' },
|
|
171
169
|
{ name: 'failed-preparation', label: 'Failed Preparation' },
|
|
172
170
|
{ name: 'todo-by-human', label: 'Todo by human' },
|
|
@@ -163,7 +163,7 @@ describe('ConsoleItemDetailContainer', () => {
|
|
|
163
163
|
}));
|
|
164
164
|
const { container, getByPlaceholderText, getByText } = render(
|
|
165
165
|
<ConsoleItemDetailContainer
|
|
166
|
-
tab="
|
|
166
|
+
tab="todo-by-human"
|
|
167
167
|
item={issueItem}
|
|
168
168
|
caches={buildCaches()}
|
|
169
169
|
operations={operations}
|
|
@@ -253,7 +253,7 @@ describe('ConsoleItemDetailContainer', () => {
|
|
|
253
253
|
}));
|
|
254
254
|
const { container, getByPlaceholderText, getByText } = render(
|
|
255
255
|
<ConsoleItemDetailContainer
|
|
256
|
-
tab="
|
|
256
|
+
tab="todo-by-human"
|
|
257
257
|
item={issueItem}
|
|
258
258
|
caches={buildCaches()}
|
|
259
259
|
operations={operations}
|
|
@@ -420,7 +420,7 @@ describe('ConsoleItemDetailContainer', () => {
|
|
|
420
420
|
getByText,
|
|
421
421
|
} = render(
|
|
422
422
|
<ConsoleItemDetailContainer
|
|
423
|
-
tab="
|
|
423
|
+
tab="todo-by-human"
|
|
424
424
|
item={issueItemWithRelatedPullRequest}
|
|
425
425
|
caches={buildCaches({
|
|
426
426
|
relatedPrs: [relatedPullRequest],
|
|
@@ -47,7 +47,7 @@ const listPayload = (tab: string) => ({
|
|
|
47
47
|
createdAt: '2026-06-17T00:00:00.000Z',
|
|
48
48
|
},
|
|
49
49
|
]
|
|
50
|
-
: tab === '
|
|
50
|
+
: tab === 'todo-by-human'
|
|
51
51
|
? [
|
|
52
52
|
{
|
|
53
53
|
number: 866,
|
|
@@ -60,7 +60,7 @@ const listPayload = (tab: string) => ({
|
|
|
60
60
|
isPr: false,
|
|
61
61
|
relatedOpenPullRequestUrls: [],
|
|
62
62
|
story: 'TDPM Console port',
|
|
63
|
-
status: '
|
|
63
|
+
status: 'Todo by human',
|
|
64
64
|
nextActionDate: null,
|
|
65
65
|
nextActionHour: null,
|
|
66
66
|
dependedIssueUrls: [],
|
|
@@ -271,7 +271,7 @@ describe('ConsolePage', () => {
|
|
|
271
271
|
expect(getByText('Add serveConsole subcommand')).toBeInTheDocument();
|
|
272
272
|
});
|
|
273
273
|
|
|
274
|
-
fireEvent.click(getByText('
|
|
274
|
+
fireEvent.click(getByText('Todo by human'));
|
|
275
275
|
await waitFor(() => {
|
|
276
276
|
expect(
|
|
277
277
|
getByText('Notify finished issue preparation'),
|
|
@@ -288,10 +288,9 @@ describe('ConsolePage', () => {
|
|
|
288
288
|
});
|
|
289
289
|
const tabs = within(tabBar());
|
|
290
290
|
expect(tabs.queryByText('Awaiting Quality Check')).not.toBeNull();
|
|
291
|
-
expect(tabs.queryByText('
|
|
291
|
+
expect(tabs.queryByText('Todo by human')).not.toBeNull();
|
|
292
292
|
expect(tabs.queryByText('Triage')).toBeNull();
|
|
293
293
|
expect(tabs.queryByText('Failed Preparation')).toBeNull();
|
|
294
|
-
expect(tabs.queryByText('Todo by human')).toBeNull();
|
|
295
294
|
});
|
|
296
295
|
|
|
297
296
|
it('does not render the project header bar above the tab bar', async () => {
|
|
@@ -855,7 +854,7 @@ describe('ConsolePage auto-advance tab', () => {
|
|
|
855
854
|
});
|
|
856
855
|
expect(
|
|
857
856
|
within(tabBar())
|
|
858
|
-
.getByText('
|
|
857
|
+
.getByText('Todo by human')
|
|
859
858
|
.closest('a')
|
|
860
859
|
?.getAttribute('aria-current'),
|
|
861
860
|
).toBe('page');
|