github-issue-tower-defence-management 1.165.1 → 1.166.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.
Files changed (47) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/bin/adapter/entry-points/console/consoleOperationApi.js +44 -1
  3. package/bin/adapter/entry-points/console/consoleOperationApi.js.map +1 -1
  4. package/bin/adapter/entry-points/console/consoleTabNames.js +1 -0
  5. package/bin/adapter/entry-points/console/consoleTabNames.js.map +1 -1
  6. package/bin/adapter/entry-points/console/ui-dist/assets/index-CrSqMAVR.js +86 -0
  7. package/bin/adapter/entry-points/console/ui-dist/index.html +1 -1
  8. package/bin/adapter/entry-points/console/webServer.js +2 -0
  9. package/bin/adapter/entry-points/console/webServer.js.map +1 -1
  10. package/bin/domain/usecases/ClearDependedIssueURLUseCase.js +32 -24
  11. package/bin/domain/usecases/ClearDependedIssueURLUseCase.js.map +1 -1
  12. package/bin/domain/usecases/console/GenerateConsoleListsUseCase.js +23 -0
  13. package/bin/domain/usecases/console/GenerateConsoleListsUseCase.js.map +1 -1
  14. package/package.json +1 -1
  15. package/src/adapter/entry-points/console/consoleOperationApi.test.ts +211 -0
  16. package/src/adapter/entry-points/console/consoleOperationApi.ts +63 -0
  17. package/src/adapter/entry-points/console/consoleTabNames.ts +1 -0
  18. package/src/adapter/entry-points/console/ui/e2e/consoleScenario.spec.ts +61 -0
  19. package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +63 -2
  20. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.stories.tsx +4 -0
  21. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.test.tsx +1 -0
  22. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryList.stories.tsx +77 -0
  23. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryList.test.tsx +196 -0
  24. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryList.tsx +163 -0
  25. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleNavigation.test.ts +1 -0
  26. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleTabData.ts +15 -0
  27. package/src/adapter/entry-points/console/ui/src/features/console/lib/consoleApi.ts +29 -0
  28. package/src/adapter/entry-points/console/ui/src/features/console/logic/tabAdvance.test.ts +1 -0
  29. package/src/adapter/entry-points/console/ui/src/features/console/logic/types.ts +10 -1
  30. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.tsx +43 -8
  31. package/src/adapter/entry-points/console/ui-dist/assets/index-CrSqMAVR.js +86 -0
  32. package/src/adapter/entry-points/console/ui-dist/index.html +1 -1
  33. package/src/adapter/entry-points/console/webServer.ts +3 -0
  34. package/src/domain/usecases/ClearDependedIssueURLUseCase.test.ts +80 -1
  35. package/src/domain/usecases/ClearDependedIssueURLUseCase.ts +45 -31
  36. package/src/domain/usecases/console/GenerateConsoleListsUseCase.test.ts +86 -1
  37. package/src/domain/usecases/console/GenerateConsoleListsUseCase.ts +49 -1
  38. package/types/adapter/entry-points/console/consoleOperationApi.d.ts +1 -0
  39. package/types/adapter/entry-points/console/consoleOperationApi.d.ts.map +1 -1
  40. package/types/adapter/entry-points/console/consoleTabNames.d.ts.map +1 -1
  41. package/types/adapter/entry-points/console/webServer.d.ts.map +1 -1
  42. package/types/domain/usecases/ClearDependedIssueURLUseCase.d.ts +1 -0
  43. package/types/domain/usecases/ClearDependedIssueURLUseCase.d.ts.map +1 -1
  44. package/types/domain/usecases/console/GenerateConsoleListsUseCase.d.ts +18 -1
  45. package/types/domain/usecases/console/GenerateConsoleListsUseCase.d.ts.map +1 -1
  46. package/bin/adapter/entry-points/console/ui-dist/assets/index-CHUtr_4X.js +0 -86
  47. package/src/adapter/entry-points/console/ui-dist/assets/index-CHUtr_4X.js +0 -86
@@ -3,6 +3,7 @@ import type {
3
3
  ConsoleFieldOption,
4
4
  ConsoleListItem,
5
5
  ConsoleStoryColorSource,
6
+ ConsoleStoryEntry,
6
7
  ConsoleTabName,
7
8
  } from '../logic/types';
8
9
  import { CONSOLE_TABS } from '../logic/types';
@@ -13,6 +14,8 @@ export type ConsoleTabSnapshot = {
13
14
  statusOptions: ConsoleFieldOption[];
14
15
  storyOptions: ConsoleFieldOption[];
15
16
  storyColors: ConsoleStoryColorSource;
17
+ stories: ConsoleStoryEntry[];
18
+ defaultNameWithOwner: string | null;
16
19
  };
17
20
 
18
21
  export type ConsoleTabDataState = {
@@ -51,6 +54,13 @@ const parseOptions = (value: unknown): ConsoleFieldOption[] => {
51
54
  return value.filter(isRecord) as unknown as ConsoleFieldOption[];
52
55
  };
53
56
 
57
+ const parseStoryEntries = (value: unknown): ConsoleStoryEntry[] => {
58
+ if (!Array.isArray(value)) {
59
+ return [];
60
+ }
61
+ return value.filter(isRecord) as unknown as ConsoleStoryEntry[];
62
+ };
63
+
54
64
  const parseSnapshot = (payload: unknown): ConsoleTabSnapshot => ({
55
65
  items: parseItems(payload),
56
66
  generatedAt:
@@ -63,6 +73,11 @@ const parseSnapshot = (payload: unknown): ConsoleTabSnapshot => ({
63
73
  isRecord(payload) && isRecord(payload.storyColors)
64
74
  ? (payload.storyColors as ConsoleStoryColorSource)
65
75
  : {},
76
+ stories: isRecord(payload) ? parseStoryEntries(payload.stories) : [],
77
+ defaultNameWithOwner:
78
+ isRecord(payload) && typeof payload.defaultNameWithOwner === 'string'
79
+ ? payload.defaultNameWithOwner
80
+ : null,
66
81
  });
67
82
 
68
83
  const emptySnapshots = (): Record<
@@ -339,3 +339,32 @@ export const postConsoleReviewComment = async (
339
339
  throw new Error(await readOperationErrorReason(response));
340
340
  }
341
341
  };
342
+
343
+ export const CREATE_ISSUE_OPERATION_PATH = '/api/createissue';
344
+
345
+ export type ConsoleCreateIssueRequest = {
346
+ pjcode: string;
347
+ title: string;
348
+ storyOptionId: string;
349
+ nameWithOwner: string;
350
+ };
351
+
352
+ export const postConsoleCreateIssue = async (
353
+ request: ConsoleCreateIssueRequest,
354
+ ): Promise<string> => {
355
+ const response = await fetch(CREATE_ISSUE_OPERATION_PATH, {
356
+ method: 'POST',
357
+ headers: { 'Content-Type': 'application/json' },
358
+ body: JSON.stringify(request),
359
+ });
360
+ if (!response.ok) {
361
+ throw new Error(await readOperationErrorReason(response));
362
+ }
363
+ const payload: unknown = await response.json();
364
+ const isRecord = (v: unknown): v is Record<string, unknown> =>
365
+ v !== null && typeof v === 'object' && !Array.isArray(v);
366
+ if (!isRecord(payload) || typeof payload.issueUrl !== 'string') {
367
+ throw new Error('issueUrl was not returned');
368
+ }
369
+ return payload.issueUrl;
370
+ };
@@ -14,6 +14,7 @@ const counts = (
14
14
  'failed-preparation': 0,
15
15
  'todo-by-human': 0,
16
16
  'todo-by-agent': 0,
17
+ stories: 0,
17
18
  ...overrides,
18
19
  });
19
20
 
@@ -147,7 +147,15 @@ export type ConsoleTabName =
147
147
  | 'unread'
148
148
  | 'failed-preparation'
149
149
  | 'todo-by-human'
150
- | 'todo-by-agent';
150
+ | 'todo-by-agent'
151
+ | 'stories';
152
+
153
+ export type ConsoleStoryEntry = {
154
+ storyName: string;
155
+ storyOptionId: string;
156
+ color: ConsoleColor;
157
+ openItemCount: number;
158
+ };
151
159
 
152
160
  export type ConsoleTab = {
153
161
  name: ConsoleTabName;
@@ -162,4 +170,5 @@ export const CONSOLE_TABS: ConsoleTab[] = [
162
170
  { name: 'failed-preparation', label: 'Failed Preparation' },
163
171
  { name: 'todo-by-human', label: 'Todo by human' },
164
172
  { name: 'todo-by-agent', label: 'Todo by agent' },
173
+ { name: 'stories', label: 'Stories' },
165
174
  ];
@@ -1,6 +1,7 @@
1
1
  import { useCallback, useEffect, useMemo, useRef } from 'react';
2
2
  import { ConsoleTabList } from '../components/layout/ConsoleTabList';
3
3
  import { ConsoleItemList } from '../components/list/ConsoleItemList';
4
+ import { ConsoleStoryList } from '../components/list/ConsoleStoryList';
4
5
  import {
5
6
  ConsoleErrorToast,
6
7
  ConsoleUndoToast,
@@ -14,6 +15,7 @@ import { useConsoleOverlay } from '../hooks/useConsoleOverlay';
14
15
  import { useConsolePjcode } from '../hooks/useConsolePjcode';
15
16
  import { useConsoleSwipeNavigation } from '../hooks/useConsoleSwipeNavigation';
16
17
  import { useConsoleTabData } from '../hooks/useConsoleTabData';
18
+ import { postConsoleCreateIssue } from '../lib/consoleApi';
17
19
  import {
18
20
  actionAdvances,
19
21
  actionToastColor,
@@ -67,13 +69,17 @@ export const ConsolePage = () => {
67
69
  if (snapshot === null) {
68
70
  continue;
69
71
  }
70
- result[tab.name] = countPendingItems(
71
- snapshot.items,
72
- overlayEntriesActedSinceSnapshot(
73
- overlayState.overlay,
74
- snapshot.generatedAt,
75
- ),
76
- );
72
+ if (tab.name === 'stories') {
73
+ result[tab.name] = snapshot.stories.length;
74
+ } else {
75
+ result[tab.name] = countPendingItems(
76
+ snapshot.items,
77
+ overlayEntriesActedSinceSnapshot(
78
+ overlayState.overlay,
79
+ snapshot.generatedAt,
80
+ ),
81
+ );
82
+ }
77
83
  }
78
84
  return result;
79
85
  }, [snapshots, overlayState.overlay]);
@@ -224,6 +230,28 @@ export const ConsolePage = () => {
224
230
 
225
231
  const detailScreenRef = useConsoleSwipeNavigation(handleSwipe);
226
232
 
233
+ const storiesSnapshot = snapshots.stories;
234
+ const storyEntries = storiesSnapshot?.stories ?? [];
235
+ const defaultNameWithOwner = storiesSnapshot?.defaultNameWithOwner ?? null;
236
+
237
+ const handleCreateIssue = useCallback(
238
+ async (storyOptionId: string, title: string): Promise<void> => {
239
+ if (pjcode === null) {
240
+ throw new Error('No project specified in the URL path.');
241
+ }
242
+ if (defaultNameWithOwner === null) {
243
+ throw new Error('No repository configured for this project.');
244
+ }
245
+ await postConsoleCreateIssue({
246
+ pjcode,
247
+ title,
248
+ storyOptionId,
249
+ nameWithOwner: defaultNameWithOwner,
250
+ });
251
+ },
252
+ [pjcode, defaultNameWithOwner],
253
+ );
254
+
227
255
  return (
228
256
  <main className="console-app">
229
257
  {actionQueue.pending !== null && (
@@ -249,7 +277,14 @@ export const ConsolePage = () => {
249
277
  tabHref={navigation.tabHref}
250
278
  onSelectTab={navigation.selectTab}
251
279
  />
252
- {selectedItem === null ? (
280
+ {activeTab === 'stories' ? (
281
+ <ConsoleStoryList
282
+ stories={storyEntries}
283
+ isLoading={isLoading}
284
+ error={error}
285
+ onCreateIssue={handleCreateIssue}
286
+ />
287
+ ) : selectedItem === null ? (
253
288
  <ConsoleItemList
254
289
  rows={rows}
255
290
  storyColors={storyColors}