github-issue-tower-defence-management 1.92.0 → 1.93.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/consoleServer.js +1 -0
- package/bin/adapter/entry-points/console/consoleServer.js.map +1 -1
- package/package.json +1 -1
- package/src/adapter/entry-points/console/consoleServer.test.ts +23 -0
- package/src/adapter/entry-points/console/consoleServer.ts +1 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleChangedFileList.test.tsx +49 -1
- package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleChangedFileList.tsx +36 -20
- package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleFileDiff.stories.tsx +19 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleFileDiff.test.tsx +24 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleFileDiff.tsx +30 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsolePullRequestDetail.tsx +30 -24
- package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleUndoToast.stories.tsx +47 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleUndoToast.test.tsx +54 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleUndoToast.tsx +36 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleActionQueue.test.ts +117 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleActionQueue.ts +105 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleSwipeNavigation.test.ts +115 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleSwipeNavigation.ts +115 -0
- package/src/adapter/entry-points/console/ui/src/features/console/logic/actionToast.test.ts +153 -0
- package/src/adapter/entry-points/console/ui/src/features/console/logic/actionToast.ts +103 -0
- package/src/adapter/entry-points/console/ui/src/features/console/logic/diff.test.ts +81 -0
- package/src/adapter/entry-points/console/ui/src/features/console/logic/diff.ts +61 -0
- package/src/adapter/entry-points/console/ui/src/features/console/logic/navigation.test.ts +53 -0
- package/src/adapter/entry-points/console/ui/src/features/console/logic/navigation.ts +33 -0
- package/src/adapter/entry-points/console/ui/src/features/console/logic/swipe.test.ts +34 -0
- package/src/adapter/entry-points/console/ui/src/features/console/logic/swipe.ts +28 -0
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.test.tsx +9 -1
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.tsx +51 -6
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.test.tsx +263 -17
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.tsx +85 -3
- package/src/adapter/entry-points/console/ui/src/features/console/testing/fixtures.ts +19 -3
- package/src/adapter/entry-points/console/ui/src/index.css +205 -1
- package/src/adapter/entry-points/console/ui-dist/assets/index-C5nxEEOu.css +1 -0
- package/src/adapter/entry-points/console/ui-dist/assets/index-DoJ05EuW.js +101 -0
- package/src/adapter/entry-points/console/ui-dist/index.html +2 -2
- package/types/adapter/entry-points/console/consoleServer.d.ts.map +1 -1
- package/src/adapter/entry-points/console/ui-dist/assets/index-BJixkRxv.css +0 -1
- package/src/adapter/entry-points/console/ui-dist/assets/index-BSNMvjcB.js +0 -100
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { parseUnifiedDiff } from './diff';
|
|
2
|
+
|
|
3
|
+
describe('parseUnifiedDiff', () => {
|
|
4
|
+
it('marks a hunk header with no line numbers', () => {
|
|
5
|
+
const rows = parseUnifiedDiff('@@ -54,7 +54,12 @@ jobs:');
|
|
6
|
+
expect(rows).toEqual([
|
|
7
|
+
{
|
|
8
|
+
kind: 'hunk',
|
|
9
|
+
oldLineNumber: null,
|
|
10
|
+
newLineNumber: null,
|
|
11
|
+
content: '@@ -54,7 +54,12 @@ jobs:',
|
|
12
|
+
},
|
|
13
|
+
]);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('numbers context lines on both sides starting from the hunk header', () => {
|
|
17
|
+
const rows = parseUnifiedDiff(
|
|
18
|
+
['@@ -10,2 +20,2 @@', ' context one', ' context two'].join('\n'),
|
|
19
|
+
);
|
|
20
|
+
expect(rows[1]).toEqual({
|
|
21
|
+
kind: 'ctx',
|
|
22
|
+
oldLineNumber: 10,
|
|
23
|
+
newLineNumber: 20,
|
|
24
|
+
content: ' context one',
|
|
25
|
+
});
|
|
26
|
+
expect(rows[2]).toEqual({
|
|
27
|
+
kind: 'ctx',
|
|
28
|
+
oldLineNumber: 11,
|
|
29
|
+
newLineNumber: 21,
|
|
30
|
+
content: ' context two',
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('numbers added lines only on the new side', () => {
|
|
35
|
+
const rows = parseUnifiedDiff(
|
|
36
|
+
['@@ -1,1 +1,2 @@', ' kept', '+added line'].join('\n'),
|
|
37
|
+
);
|
|
38
|
+
expect(rows[2]).toEqual({
|
|
39
|
+
kind: 'add',
|
|
40
|
+
oldLineNumber: null,
|
|
41
|
+
newLineNumber: 2,
|
|
42
|
+
content: '+added line',
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('numbers removed lines only on the old side', () => {
|
|
47
|
+
const rows = parseUnifiedDiff(
|
|
48
|
+
['@@ -1,2 +1,1 @@', ' kept', '-removed line'].join('\n'),
|
|
49
|
+
);
|
|
50
|
+
expect(rows[2]).toEqual({
|
|
51
|
+
kind: 'del',
|
|
52
|
+
oldLineNumber: 2,
|
|
53
|
+
newLineNumber: null,
|
|
54
|
+
content: '-removed line',
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('keeps the old and new counters independent across a mixed hunk', () => {
|
|
59
|
+
const rows = parseUnifiedDiff(
|
|
60
|
+
[
|
|
61
|
+
'@@ -54,7 +54,12 @@ jobs:',
|
|
62
|
+
' loose-matching: true',
|
|
63
|
+
'- npm install',
|
|
64
|
+
'+ npm ci',
|
|
65
|
+
'+ npm run build',
|
|
66
|
+
' after',
|
|
67
|
+
].join('\n'),
|
|
68
|
+
);
|
|
69
|
+
expect(rows.map((row) => row.kind)).toEqual([
|
|
70
|
+
'hunk',
|
|
71
|
+
'ctx',
|
|
72
|
+
'del',
|
|
73
|
+
'add',
|
|
74
|
+
'add',
|
|
75
|
+
'ctx',
|
|
76
|
+
]);
|
|
77
|
+
const lastContext = rows[5];
|
|
78
|
+
expect(lastContext.oldLineNumber).toBe(56);
|
|
79
|
+
expect(lastContext.newLineNumber).toBe(57);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export type ConsoleDiffLineKind = 'hunk' | 'add' | 'del' | 'ctx';
|
|
2
|
+
|
|
3
|
+
export type ConsoleDiffLine = {
|
|
4
|
+
kind: ConsoleDiffLineKind;
|
|
5
|
+
oldLineNumber: number | null;
|
|
6
|
+
newLineNumber: number | null;
|
|
7
|
+
content: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const HUNK_HEADER = /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/;
|
|
11
|
+
|
|
12
|
+
export const parseUnifiedDiff = (patch: string): ConsoleDiffLine[] => {
|
|
13
|
+
const rows: ConsoleDiffLine[] = [];
|
|
14
|
+
let oldLineNumber = 0;
|
|
15
|
+
let newLineNumber = 0;
|
|
16
|
+
for (const line of patch.split('\n')) {
|
|
17
|
+
if (line.startsWith('@@')) {
|
|
18
|
+
const match = line.match(HUNK_HEADER);
|
|
19
|
+
if (match !== null) {
|
|
20
|
+
oldLineNumber = Number(match[1]);
|
|
21
|
+
newLineNumber = Number(match[2]);
|
|
22
|
+
}
|
|
23
|
+
rows.push({
|
|
24
|
+
kind: 'hunk',
|
|
25
|
+
oldLineNumber: null,
|
|
26
|
+
newLineNumber: null,
|
|
27
|
+
content: line,
|
|
28
|
+
});
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (line.startsWith('+')) {
|
|
32
|
+
rows.push({
|
|
33
|
+
kind: 'add',
|
|
34
|
+
oldLineNumber: null,
|
|
35
|
+
newLineNumber: newLineNumber,
|
|
36
|
+
content: line,
|
|
37
|
+
});
|
|
38
|
+
newLineNumber += 1;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (line.startsWith('-')) {
|
|
42
|
+
rows.push({
|
|
43
|
+
kind: 'del',
|
|
44
|
+
oldLineNumber: oldLineNumber,
|
|
45
|
+
newLineNumber: null,
|
|
46
|
+
content: line,
|
|
47
|
+
});
|
|
48
|
+
oldLineNumber += 1;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
rows.push({
|
|
52
|
+
kind: 'ctx',
|
|
53
|
+
oldLineNumber: oldLineNumber,
|
|
54
|
+
newLineNumber: newLineNumber,
|
|
55
|
+
content: line,
|
|
56
|
+
});
|
|
57
|
+
oldLineNumber += 1;
|
|
58
|
+
newLineNumber += 1;
|
|
59
|
+
}
|
|
60
|
+
return rows;
|
|
61
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {
|
|
2
|
+
nextPendingKeyAfter,
|
|
3
|
+
nextPendingKeyBrowse,
|
|
4
|
+
previousPendingKeyBefore,
|
|
5
|
+
} from './navigation';
|
|
6
|
+
|
|
7
|
+
const keys = ['a', 'b', 'c', 'd'];
|
|
8
|
+
|
|
9
|
+
describe('nextPendingKeyAfter', () => {
|
|
10
|
+
it('returns the key immediately after the acted key', () => {
|
|
11
|
+
expect(nextPendingKeyAfter(keys, 'b')).toBe('c');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('returns null when the acted key is last so the caller returns to the list', () => {
|
|
15
|
+
expect(nextPendingKeyAfter(keys, 'd')).toBeNull();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('falls back to the first key when the acted key is absent', () => {
|
|
19
|
+
expect(nextPendingKeyAfter(keys, 'missing')).toBe('a');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('returns null for an empty list', () => {
|
|
23
|
+
expect(nextPendingKeyAfter([], 'a')).toBeNull();
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('nextPendingKeyBrowse', () => {
|
|
28
|
+
it('returns the next key in display order', () => {
|
|
29
|
+
expect(nextPendingKeyBrowse(keys, 'a')).toBe('b');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('returns null at the end of the list', () => {
|
|
33
|
+
expect(nextPendingKeyBrowse(keys, 'd')).toBeNull();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('returns null when the current key is absent', () => {
|
|
37
|
+
expect(nextPendingKeyBrowse(keys, 'missing')).toBeNull();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('previousPendingKeyBefore', () => {
|
|
42
|
+
it('returns the previous key in display order', () => {
|
|
43
|
+
expect(previousPendingKeyBefore(keys, 'c')).toBe('b');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('returns null at the start of the list', () => {
|
|
47
|
+
expect(previousPendingKeyBefore(keys, 'a')).toBeNull();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('returns null when the current key is absent', () => {
|
|
51
|
+
expect(previousPendingKeyBefore(keys, 'missing')).toBeNull();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export const nextPendingKeyAfter = (
|
|
2
|
+
orderedKeys: string[],
|
|
3
|
+
actedKey: string,
|
|
4
|
+
): string | null => {
|
|
5
|
+
const actedIndex = orderedKeys.indexOf(actedKey);
|
|
6
|
+
if (actedIndex < 0) {
|
|
7
|
+
return orderedKeys.length > 0 ? orderedKeys[0] : null;
|
|
8
|
+
}
|
|
9
|
+
const nextIndex = actedIndex + 1;
|
|
10
|
+
return nextIndex < orderedKeys.length ? orderedKeys[nextIndex] : null;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const nextPendingKeyBrowse = (
|
|
14
|
+
orderedKeys: string[],
|
|
15
|
+
currentKey: string,
|
|
16
|
+
): string | null => {
|
|
17
|
+
const index = orderedKeys.indexOf(currentKey);
|
|
18
|
+
if (index < 0 || index >= orderedKeys.length - 1) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
return orderedKeys[index + 1];
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const previousPendingKeyBefore = (
|
|
25
|
+
orderedKeys: string[],
|
|
26
|
+
currentKey: string,
|
|
27
|
+
): string | null => {
|
|
28
|
+
const index = orderedKeys.indexOf(currentKey);
|
|
29
|
+
if (index <= 0) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return orderedKeys[index - 1];
|
|
33
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isVerticallyDominant,
|
|
3
|
+
resolveSwipeDirection,
|
|
4
|
+
SWIPE_MIN_DISTANCE,
|
|
5
|
+
} from './swipe';
|
|
6
|
+
|
|
7
|
+
describe('resolveSwipeDirection', () => {
|
|
8
|
+
it('reports next for a dominant left swipe', () => {
|
|
9
|
+
expect(resolveSwipeDirection(-120, 10)).toBe('next');
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('reports previous for a dominant right swipe', () => {
|
|
13
|
+
expect(resolveSwipeDirection(120, 10)).toBe('previous');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('ignores a gesture shorter than the minimum distance', () => {
|
|
17
|
+
expect(resolveSwipeDirection(-(SWIPE_MIN_DISTANCE - 1), 0)).toBeNull();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('ignores a gesture that is not horizontally dominant', () => {
|
|
21
|
+
expect(resolveSwipeDirection(-80, 70)).toBeNull();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('isVerticallyDominant', () => {
|
|
26
|
+
it('is true for a clearly vertical drag', () => {
|
|
27
|
+
expect(isVerticallyDominant(10, 80)).toBe(true);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('is false for a small or horizontal drag', () => {
|
|
31
|
+
expect(isVerticallyDominant(80, 10)).toBe(false);
|
|
32
|
+
expect(isVerticallyDominant(5, 15)).toBe(false);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type ConsoleSwipeDirection = 'next' | 'previous' | null;
|
|
2
|
+
|
|
3
|
+
export const SWIPE_MIN_DISTANCE = 60;
|
|
4
|
+
export const SWIPE_HORIZONTAL_DOMINANCE = 1.5;
|
|
5
|
+
|
|
6
|
+
export const resolveSwipeDirection = (
|
|
7
|
+
deltaX: number,
|
|
8
|
+
deltaY: number,
|
|
9
|
+
): ConsoleSwipeDirection => {
|
|
10
|
+
const absDeltaX = Math.abs(deltaX);
|
|
11
|
+
const absDeltaY = Math.abs(deltaY);
|
|
12
|
+
if (absDeltaX < SWIPE_MIN_DISTANCE) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
if (absDeltaX <= absDeltaY * SWIPE_HORIZONTAL_DOMINANCE) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
return deltaX < 0 ? 'next' : 'previous';
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const isVerticallyDominant = (
|
|
22
|
+
deltaX: number,
|
|
23
|
+
deltaY: number,
|
|
24
|
+
): boolean => {
|
|
25
|
+
const absDeltaX = Math.abs(deltaX);
|
|
26
|
+
const absDeltaY = Math.abs(deltaY);
|
|
27
|
+
return absDeltaY > absDeltaX * SWIPE_HORIZONTAL_DOMINANCE && absDeltaY > 20;
|
|
28
|
+
};
|
|
@@ -55,8 +55,9 @@ const buildOperations = (): ConsoleOperationsApi => ({
|
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
describe('ConsoleItemDetailContainer', () => {
|
|
58
|
-
it('
|
|
58
|
+
it('queues the review action and commits it through the operations api for a PR item', async () => {
|
|
59
59
|
const operations = buildOperations();
|
|
60
|
+
const onQueueAction = jest.fn();
|
|
60
61
|
const { getByText } = render(
|
|
61
62
|
<ConsoleItemDetailContainer
|
|
62
63
|
tab="prs"
|
|
@@ -69,12 +70,19 @@ describe('ConsoleItemDetailContainer', () => {
|
|
|
69
70
|
storyName="TDPM Console port"
|
|
70
71
|
overlayStatus={null}
|
|
71
72
|
now={Date.parse('2026-06-19T12:00:00.000Z')}
|
|
73
|
+
onQueueAction={onQueueAction}
|
|
72
74
|
/>,
|
|
73
75
|
);
|
|
74
76
|
await waitFor(() => {
|
|
75
77
|
expect(getByText('Approve')).toBeInTheDocument();
|
|
76
78
|
});
|
|
77
79
|
fireEvent.click(getByText('Approve'));
|
|
80
|
+
expect(onQueueAction).toHaveBeenCalledTimes(1);
|
|
81
|
+
const input = onQueueAction.mock.calls[0][0];
|
|
82
|
+
expect(input.kind).toEqual({ type: 'review', action: 'approve' });
|
|
83
|
+
expect(input.item).toBe(prItem);
|
|
84
|
+
expect(operations.reviewPullRequest).not.toHaveBeenCalled();
|
|
85
|
+
input.commit();
|
|
78
86
|
expect(operations.reviewPullRequest).toHaveBeenCalledWith(
|
|
79
87
|
prItem,
|
|
80
88
|
prItem.url,
|
|
@@ -4,6 +4,7 @@ import { ConsoleOperationMenu } from '../components/operations/ConsoleOperationM
|
|
|
4
4
|
import type { ConsoleCaches } from '../hooks/useConsoleCaches';
|
|
5
5
|
import { useConsoleItemDetailData } from '../hooks/useConsoleItemDetailData';
|
|
6
6
|
import type { ConsoleOperationsApi } from '../hooks/useConsoleOperations';
|
|
7
|
+
import type { ConsoleActionKind } from '../logic/actionToast';
|
|
7
8
|
import { resolveStoryColorEnum } from '../logic/grouping';
|
|
8
9
|
import type { ConsoleOperationHandlers } from '../logic/operations';
|
|
9
10
|
import type {
|
|
@@ -15,6 +16,12 @@ import type {
|
|
|
15
16
|
ConsoleTabName,
|
|
16
17
|
} from '../logic/types';
|
|
17
18
|
|
|
19
|
+
export type ConsoleQueueActionInput = {
|
|
20
|
+
kind: ConsoleActionKind;
|
|
21
|
+
item: ConsoleListItem;
|
|
22
|
+
commit: () => void;
|
|
23
|
+
};
|
|
24
|
+
|
|
18
25
|
export type ConsoleItemDetailContainerProps = {
|
|
19
26
|
tab: ConsoleTabName;
|
|
20
27
|
item: ConsoleListItem;
|
|
@@ -26,6 +33,7 @@ export type ConsoleItemDetailContainerProps = {
|
|
|
26
33
|
storyName: string | null;
|
|
27
34
|
overlayStatus: ConsoleOverlayStatus | null;
|
|
28
35
|
now: number;
|
|
36
|
+
onQueueAction: (input: ConsoleQueueActionInput) => void;
|
|
29
37
|
};
|
|
30
38
|
|
|
31
39
|
export const ConsoleItemDetailContainer = ({
|
|
@@ -39,6 +47,7 @@ export const ConsoleItemDetailContainer = ({
|
|
|
39
47
|
storyName,
|
|
40
48
|
overlayStatus,
|
|
41
49
|
now,
|
|
50
|
+
onQueueAction,
|
|
42
51
|
}: ConsoleItemDetailContainerProps) => {
|
|
43
52
|
const detail = useConsoleItemDetailData(caches, item);
|
|
44
53
|
const hasPullRequest = item.isPr || detail.relatedPullRequests.length > 0;
|
|
@@ -48,22 +57,58 @@ export const ConsoleItemDetailContainer = ({
|
|
|
48
57
|
const prUrl = item.isPr
|
|
49
58
|
? item.url
|
|
50
59
|
: (detail.relatedPullRequests[0]?.pullRequest.url ?? item.url);
|
|
51
|
-
|
|
60
|
+
onQueueAction({
|
|
61
|
+
kind: { type: 'review', action },
|
|
62
|
+
item,
|
|
63
|
+
commit: () => {
|
|
64
|
+
void operations.reviewPullRequest(item, prUrl, action);
|
|
65
|
+
},
|
|
66
|
+
});
|
|
52
67
|
},
|
|
53
68
|
onSetNextActionDate: (action) => {
|
|
54
|
-
|
|
69
|
+
onQueueAction({
|
|
70
|
+
kind: { type: 'next_action_date', action },
|
|
71
|
+
item,
|
|
72
|
+
commit: () => {
|
|
73
|
+
void operations.setNextActionDate(item, action);
|
|
74
|
+
},
|
|
75
|
+
});
|
|
55
76
|
},
|
|
56
77
|
onSetStory: (option: ConsoleFieldOption) => {
|
|
57
|
-
|
|
78
|
+
onQueueAction({
|
|
79
|
+
kind: { type: 'set_story', optionName: option.name },
|
|
80
|
+
item,
|
|
81
|
+
commit: () => {
|
|
82
|
+
void operations.setStory(item, option);
|
|
83
|
+
},
|
|
84
|
+
});
|
|
58
85
|
},
|
|
59
86
|
onSetStatus: (option: ConsoleFieldOption) => {
|
|
60
|
-
|
|
87
|
+
onQueueAction({
|
|
88
|
+
kind: { type: 'set_status', optionName: option.name },
|
|
89
|
+
item,
|
|
90
|
+
commit: () => {
|
|
91
|
+
void operations.setStatus(item, option);
|
|
92
|
+
},
|
|
93
|
+
});
|
|
61
94
|
},
|
|
62
95
|
onSetInTmuxByHuman: (option: ConsoleFieldOption) => {
|
|
63
|
-
|
|
96
|
+
onQueueAction({
|
|
97
|
+
kind: { type: 'set_in_tmux_by_human', optionName: option.name },
|
|
98
|
+
item,
|
|
99
|
+
commit: () => {
|
|
100
|
+
void operations.setInTmuxByHuman(item, option);
|
|
101
|
+
},
|
|
102
|
+
});
|
|
64
103
|
},
|
|
65
104
|
onClose: (action) => {
|
|
66
|
-
|
|
105
|
+
onQueueAction({
|
|
106
|
+
kind: { type: 'close', action },
|
|
107
|
+
item,
|
|
108
|
+
commit: () => {
|
|
109
|
+
void operations.closeIssue(item, action);
|
|
110
|
+
},
|
|
111
|
+
});
|
|
67
112
|
},
|
|
68
113
|
};
|
|
69
114
|
|