github-issue-tower-defence-management 1.178.1 → 1.180.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 +22 -0
- package/README.md +1 -0
- package/bin/adapter/entry-points/cli/index.js +2 -0
- package/bin/adapter/entry-points/cli/index.js.map +1 -1
- package/bin/adapter/entry-points/console/consoleOperationApi.js +42 -1
- package/bin/adapter/entry-points/console/consoleOperationApi.js.map +1 -1
- package/bin/adapter/entry-points/console/ui-dist/assets/index-I_2Yu8fM.js +86 -0
- package/bin/adapter/entry-points/console/ui-dist/index.html +1 -1
- package/bin/adapter/entry-points/console/webServer.js +6 -0
- package/bin/adapter/entry-points/console/webServer.js.map +1 -1
- package/bin/adapter/repositories/SystemDateRepository.js +10 -10
- package/bin/adapter/repositories/SystemDateRepository.js.map +1 -1
- package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js +23 -4
- package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js.map +1 -1
- package/bin/domain/usecases/AnalyzeProblemByIssueUseCase.js +1 -1
- package/bin/domain/usecases/AnalyzeProblemByIssueUseCase.js.map +1 -1
- package/bin/domain/usecases/AnalyzeStoriesUseCase.js +1 -1
- package/bin/domain/usecases/AnalyzeStoriesUseCase.js.map +1 -1
- package/bin/domain/usecases/ClearPastNextActionDateHourUseCase.js +1 -1
- package/bin/domain/usecases/ClearPastNextActionDateHourUseCase.js.map +1 -1
- package/bin/domain/usecases/CreateEstimationIssueUseCase.js +3 -3
- package/bin/domain/usecases/CreateEstimationIssueUseCase.js.map +1 -1
- package/bin/domain/usecases/HandleScheduledEventUseCase.js +6 -6
- package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -1
- package/bin/domain/usecases/IssueRejectionEvaluator.js +3 -1
- package/bin/domain/usecases/IssueRejectionEvaluator.js.map +1 -1
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js +13 -0
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/StartPreparationUseCase.js +1 -1
- package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/issueReactivationTriggerIsPending.js +2 -2
- package/bin/domain/usecases/issueReactivationTriggerIsPending.js.map +1 -1
- package/package.json +1 -1
- package/src/adapter/entry-points/cli/index.test.ts +2 -0
- package/src/adapter/entry-points/cli/index.ts +6 -0
- package/src/adapter/entry-points/console/consoleOperationApi.test.ts +230 -0
- package/src/adapter/entry-points/console/consoleOperationApi.ts +48 -1
- package/src/adapter/entry-points/console/ui/e2e/consoleScenario.spec.ts +36 -0
- package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +25 -1
- package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryReorderPanel.stories.tsx +30 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryReorderPanel.test.tsx +111 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryReorderPanel.tsx +91 -0
- package/src/adapter/entry-points/console/ui/src/features/console/lib/consoleApi.ts +21 -0
- package/src/adapter/entry-points/console/ui/src/features/console/logic/relativeTime.test.ts +24 -2
- package/src/adapter/entry-points/console/ui/src/features/console/logic/relativeTime.ts +3 -1
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.tsx +60 -11
- package/src/adapter/entry-points/console/ui-dist/assets/index-I_2Yu8fM.js +86 -0
- package/src/adapter/entry-points/console/ui-dist/index.html +1 -1
- package/src/adapter/entry-points/console/webServer.ts +11 -0
- package/src/adapter/repositories/SystemDateRepository.test.ts +60 -0
- package/src/adapter/repositories/SystemDateRepository.ts +10 -10
- package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.test.ts +268 -2
- package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts +33 -4
- package/src/domain/usecases/AnalyzeProblemByIssueUseCase.ts +1 -1
- package/src/domain/usecases/AnalyzeStoriesUseCase.test.ts +80 -0
- package/src/domain/usecases/AnalyzeStoriesUseCase.ts +1 -1
- package/src/domain/usecases/ClearPastNextActionDateHourUseCase.ts +6 -4
- package/src/domain/usecases/CreateEstimationIssueUseCase.test.ts +225 -0
- package/src/domain/usecases/CreateEstimationIssueUseCase.ts +3 -3
- package/src/domain/usecases/HandleScheduledEventUseCase.test.ts +107 -0
- package/src/domain/usecases/HandleScheduledEventUseCase.ts +7 -7
- package/src/domain/usecases/IssueRejectionEvaluator.test.ts +83 -0
- package/src/domain/usecases/IssueRejectionEvaluator.ts +3 -1
- package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.test.ts +136 -0
- package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +42 -1
- package/src/domain/usecases/StartPreparationUseCase.ts +5 -3
- package/src/domain/usecases/issueReactivationTriggerIsPending.test.ts +35 -33
- package/src/domain/usecases/issueReactivationTriggerIsPending.ts +6 -4
- package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
- package/types/adapter/entry-points/console/consoleOperationApi.d.ts +3 -1
- package/types/adapter/entry-points/console/consoleOperationApi.d.ts.map +1 -1
- package/types/adapter/entry-points/console/webServer.d.ts +2 -0
- package/types/adapter/entry-points/console/webServer.d.ts.map +1 -1
- package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts.map +1 -1
- package/types/domain/usecases/ClearPastNextActionDateHourUseCase.d.ts.map +1 -1
- package/types/domain/usecases/IssueRejectionEvaluator.d.ts.map +1 -1
- package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts +3 -1
- package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/issueReactivationTriggerIsPending.d.ts.map +1 -1
- package/bin/adapter/entry-points/console/ui-dist/assets/index-KCmqh781.js +0 -86
- package/src/adapter/entry-points/console/ui-dist/assets/index-KCmqh781.js +0 -86
|
@@ -417,3 +417,24 @@ export const postConsoleCreateIssue = async (
|
|
|
417
417
|
}
|
|
418
418
|
return payload.issueUrl;
|
|
419
419
|
};
|
|
420
|
+
|
|
421
|
+
export const REORDER_STORY_OPERATION_PATH = '/api/reorderstory';
|
|
422
|
+
|
|
423
|
+
export type ConsoleReorderStoryRequest = {
|
|
424
|
+
pjcode: string;
|
|
425
|
+
storyOptionId: string;
|
|
426
|
+
direction: 'up' | 'down';
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
export const postConsoleReorderStory = async (
|
|
430
|
+
request: ConsoleReorderStoryRequest,
|
|
431
|
+
): Promise<void> => {
|
|
432
|
+
const response = await fetch(REORDER_STORY_OPERATION_PATH, {
|
|
433
|
+
method: 'POST',
|
|
434
|
+
headers: { 'Content-Type': 'application/json' },
|
|
435
|
+
body: JSON.stringify(request),
|
|
436
|
+
});
|
|
437
|
+
if (!response.ok) {
|
|
438
|
+
throw new Error(await readOperationErrorReason(response));
|
|
439
|
+
}
|
|
440
|
+
};
|
|
@@ -39,14 +39,36 @@ describe('formatRelativeTime', () => {
|
|
|
39
39
|
);
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
+
it('returns month and day for 30+ days in the same UTC year', () => {
|
|
43
|
+
expect(formatRelativeTime('2026-05-01T12:00:00.000Z', now)).toBe('May 1');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('includes the UTC year when the date is in a prior year', () => {
|
|
47
|
+
const result = formatRelativeTime('2025-12-01T12:00:00.000Z', now);
|
|
48
|
+
expect(result).toContain('2025');
|
|
49
|
+
expect(result).toContain('Dec');
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('uses UTC date boundary for the same-year check', () => {
|
|
53
|
+
const nowEndOf2025 = Date.parse('2025-12-31T23:59:59.000Z');
|
|
54
|
+
const result = formatRelativeTime('2025-10-01T00:00:00.000Z', nowEndOf2025);
|
|
55
|
+
expect(result).toContain('Oct');
|
|
56
|
+
expect(result).not.toContain('2025');
|
|
57
|
+
});
|
|
58
|
+
|
|
42
59
|
it('returns an empty string for an invalid date', () => {
|
|
43
60
|
expect(formatRelativeTime('nonsense', now)).toBe('');
|
|
44
61
|
});
|
|
45
62
|
});
|
|
46
63
|
|
|
47
64
|
describe('formatFullTimestamp', () => {
|
|
48
|
-
it('formats a timestamp
|
|
49
|
-
expect(formatFullTimestamp('2026-06-
|
|
65
|
+
it('formats a UTC timestamp in ja-JP locale', () => {
|
|
66
|
+
expect(formatFullTimestamp('2026-06-19T09:05:00.000Z')).toMatch(
|
|
67
|
+
/2026.06.19.09.05/,
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('returns empty string for invalid input', () => {
|
|
50
72
|
expect(formatFullTimestamp('nonsense')).toBe('');
|
|
51
73
|
});
|
|
52
74
|
});
|
|
@@ -28,8 +28,9 @@ export const formatRelativeTime = (iso: string, now: number): string => {
|
|
|
28
28
|
return `${days} days ago`;
|
|
29
29
|
}
|
|
30
30
|
const date = new Date(then);
|
|
31
|
-
const sameYear = date.
|
|
31
|
+
const sameYear = date.getUTCFullYear() === new Date(now).getUTCFullYear();
|
|
32
32
|
return date.toLocaleDateString('en-US', {
|
|
33
|
+
timeZone: 'UTC',
|
|
33
34
|
year: sameYear ? undefined : 'numeric',
|
|
34
35
|
month: 'short',
|
|
35
36
|
day: 'numeric',
|
|
@@ -42,6 +43,7 @@ export const formatFullTimestamp = (iso: string): string => {
|
|
|
42
43
|
return '';
|
|
43
44
|
}
|
|
44
45
|
return new Date(then).toLocaleString('ja-JP', {
|
|
46
|
+
timeZone: 'UTC',
|
|
45
47
|
year: 'numeric',
|
|
46
48
|
month: '2-digit',
|
|
47
49
|
day: '2-digit',
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
1
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import { ConsoleTabList } from '../components/layout/ConsoleTabList';
|
|
3
3
|
import { ConsoleItemList } from '../components/list/ConsoleItemList';
|
|
4
4
|
import { ConsoleStoryList } from '../components/list/ConsoleStoryList';
|
|
5
|
+
import { ConsoleStoryReorderPanel } from '../components/list/ConsoleStoryReorderPanel';
|
|
5
6
|
import {
|
|
6
7
|
ConsoleErrorToast,
|
|
7
8
|
ConsoleUndoToast,
|
|
@@ -15,7 +16,10 @@ import { useConsoleOverlay } from '../hooks/useConsoleOverlay';
|
|
|
15
16
|
import { useConsolePjcode } from '../hooks/useConsolePjcode';
|
|
16
17
|
import { useConsoleSwipeNavigation } from '../hooks/useConsoleSwipeNavigation';
|
|
17
18
|
import { useConsoleTabData } from '../hooks/useConsoleTabData';
|
|
18
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
postConsoleCreateIssue,
|
|
21
|
+
postConsoleReorderStory,
|
|
22
|
+
} from '../lib/consoleApi';
|
|
19
23
|
import {
|
|
20
24
|
actionAdvances,
|
|
21
25
|
actionToastColor,
|
|
@@ -136,6 +140,17 @@ export const ConsolePage = () => {
|
|
|
136
140
|
const generatedAt = activeSnapshot?.generatedAt ?? null;
|
|
137
141
|
const fromCache = activeSnapshot?.fromCache ?? false;
|
|
138
142
|
|
|
143
|
+
const [localStoryOptionsOverride, setLocalStoryOptionsOverride] = useState<{
|
|
144
|
+
generatedAt: string | undefined;
|
|
145
|
+
stories: typeof storyOptions;
|
|
146
|
+
} | null>(null);
|
|
147
|
+
|
|
148
|
+
const triageStoryOptions =
|
|
149
|
+
localStoryOptionsOverride !== null &&
|
|
150
|
+
localStoryOptionsOverride.generatedAt === activeSnapshot?.generatedAt
|
|
151
|
+
? localStoryOptionsOverride.stories
|
|
152
|
+
: storyOptions.filter((o) => o.color !== 'GRAY');
|
|
153
|
+
|
|
139
154
|
const selectedItem = useMemo<ConsoleListItem | null>(() => {
|
|
140
155
|
if (selectedItemKey === null || activeSnapshot === null) {
|
|
141
156
|
return null;
|
|
@@ -265,6 +280,32 @@ export const ConsolePage = () => {
|
|
|
265
280
|
[pjcode, defaultNameWithOwner],
|
|
266
281
|
);
|
|
267
282
|
|
|
283
|
+
const handleReorderStory = useCallback(
|
|
284
|
+
async (storyOptionId: string, direction: 'up' | 'down'): Promise<void> => {
|
|
285
|
+
if (pjcode === null) {
|
|
286
|
+
throw new Error('No project specified in the URL path.');
|
|
287
|
+
}
|
|
288
|
+
await postConsoleReorderStory({ pjcode, storyOptionId, direction });
|
|
289
|
+
const index = triageStoryOptions.findIndex((o) => o.id === storyOptionId);
|
|
290
|
+
if (index === -1) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
const swapIndex = index + (direction === 'up' ? -1 : 1);
|
|
294
|
+
if (swapIndex < 0 || swapIndex >= triageStoryOptions.length) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
const next = [...triageStoryOptions];
|
|
298
|
+
const temp = next[index];
|
|
299
|
+
next[index] = next[swapIndex];
|
|
300
|
+
next[swapIndex] = temp;
|
|
301
|
+
setLocalStoryOptionsOverride({
|
|
302
|
+
generatedAt: activeSnapshot?.generatedAt,
|
|
303
|
+
stories: next,
|
|
304
|
+
});
|
|
305
|
+
},
|
|
306
|
+
[pjcode, triageStoryOptions, activeSnapshot?.generatedAt],
|
|
307
|
+
);
|
|
308
|
+
|
|
268
309
|
return (
|
|
269
310
|
<main className="console-app">
|
|
270
311
|
{actionQueue.pending !== null && (
|
|
@@ -299,15 +340,23 @@ export const ConsolePage = () => {
|
|
|
299
340
|
onCreateIssue={handleCreateIssue}
|
|
300
341
|
/>
|
|
301
342
|
) : selectedItem === null ? (
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
343
|
+
<>
|
|
344
|
+
{activeTab === 'triage' && triageStoryOptions.length > 0 && (
|
|
345
|
+
<ConsoleStoryReorderPanel
|
|
346
|
+
stories={triageStoryOptions}
|
|
347
|
+
onReorderStory={handleReorderStory}
|
|
348
|
+
/>
|
|
349
|
+
)}
|
|
350
|
+
<ConsoleItemList
|
|
351
|
+
rows={rows}
|
|
352
|
+
storyColors={storyColors}
|
|
353
|
+
activeItemId={null}
|
|
354
|
+
now={now}
|
|
355
|
+
isLoading={isLoading}
|
|
356
|
+
error={error}
|
|
357
|
+
onSelectItem={(item) => navigation.openItem(item.projectItemId)}
|
|
358
|
+
/>
|
|
359
|
+
</>
|
|
311
360
|
) : (
|
|
312
361
|
<div className="console-detail-screen" ref={detailScreenRef}>
|
|
313
362
|
<ConsoleItemDetailContainer
|