github-issue-tower-defence-management 1.89.0 → 1.91.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/.github/CODEOWNERS +1 -2
- package/CHANGELOG.md +14 -0
- package/README.md +15 -2
- package/bin/adapter/entry-points/cli/index.js +16 -12
- package/bin/adapter/entry-points/cli/index.js.map +1 -1
- package/bin/adapter/entry-points/cli/projectConfig.js +2 -0
- package/bin/adapter/entry-points/cli/projectConfig.js.map +1 -1
- package/bin/adapter/entry-points/console/consoleOperationApi.js +54 -27
- package/bin/adapter/entry-points/console/consoleOperationApi.js.map +1 -1
- package/bin/adapter/entry-points/console/consoleProjectResolver.js +38 -0
- package/bin/adapter/entry-points/console/consoleProjectResolver.js.map +1 -0
- package/bin/adapter/entry-points/console/consoleServer.js +43 -17
- package/bin/adapter/entry-points/console/consoleServer.js.map +1 -1
- package/bin/adapter/entry-points/console/ui-dist/assets/index-BU6p3cGU.css +1 -0
- package/bin/adapter/entry-points/console/ui-dist/assets/index-BvuSQN9s.js +100 -0
- package/bin/adapter/entry-points/console/ui-dist/index.html +2 -2
- package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js +16 -0
- package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js.map +1 -1
- package/jest.config.js +57 -9
- package/package.json +17 -13
- package/src/adapter/entry-points/cli/index.test.ts +12 -2
- package/src/adapter/entry-points/cli/index.ts +30 -12
- package/src/adapter/entry-points/cli/projectConfig.ts +3 -0
- package/src/adapter/entry-points/console/consoleOperationApi.test.ts +129 -15
- package/src/adapter/entry-points/console/consoleOperationApi.ts +83 -28
- package/src/adapter/entry-points/console/consoleProjectResolver.test.ts +96 -0
- package/src/adapter/entry-points/console/consoleProjectResolver.ts +50 -0
- package/src/adapter/entry-points/console/consoleServer.test.ts +86 -4
- package/src/adapter/entry-points/console/consoleServer.ts +53 -23
- package/src/adapter/entry-points/console/ui/jest.setup.ts +1 -0
- package/src/adapter/entry-points/console/ui/jest.styleMock.js +1 -0
- package/src/adapter/entry-points/console/ui/src/features/console/colors.test.ts +34 -0
- package/src/adapter/entry-points/console/ui/src/features/console/colors.ts +73 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleChangedFileList.stories.tsx +28 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleChangedFileList.test.tsx +42 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleChangedFileList.tsx +55 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleCloseButtonGroup.stories.tsx +14 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleCloseButtonGroup.test.tsx +23 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleCloseButtonGroup.tsx +26 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleCommentList.stories.tsx +29 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleCommentList.test.tsx +55 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleCommentList.tsx +66 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleCommitList.stories.tsx +25 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleCommitList.test.tsx +53 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleCommitList.tsx +53 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleItemDetail.stories.tsx +79 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleItemDetail.test.tsx +81 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleItemDetail.tsx +226 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleItemIcon.stories.tsx +82 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleItemIcon.test.tsx +52 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleItemIcon.tsx +32 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleListItemRow.stories.tsx +25 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleListItemRow.test.tsx +43 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleListItemRow.tsx +34 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleListView.stories.tsx +22 -6
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleListView.test.tsx +87 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleListView.tsx +36 -32
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleMarkdownView.stories.tsx +27 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleMarkdownView.test.tsx +36 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleMarkdownView.tsx +50 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleMermaidDiagram.stories.tsx +22 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleMermaidDiagram.test.tsx +38 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleMermaidDiagram.tsx +65 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleNextActionDateGroup.stories.tsx +20 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleNextActionDateGroup.test.tsx +42 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleNextActionDateGroup.tsx +28 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleOperationBar.stories.tsx +55 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleOperationBar.test.tsx +85 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleOperationBar.tsx +55 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsolePanel.stories.tsx +26 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsolePanel.test.tsx +32 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsolePanel.tsx +36 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleProjectHeader.stories.tsx +29 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleProjectHeader.test.tsx +14 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleProjectHeader.tsx +14 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsolePullRequestReviewGroup.stories.tsx +14 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsolePullRequestReviewGroup.test.tsx +33 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsolePullRequestReviewGroup.tsx +34 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsolePullRequestSection.stories.tsx +31 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsolePullRequestSection.test.tsx +40 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsolePullRequestSection.tsx +88 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleStatusButtonGroup.stories.tsx +17 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleStatusButtonGroup.test.tsx +49 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleStatusButtonGroup.tsx +63 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleStoryButtonGroup.stories.tsx +17 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleStoryButtonGroup.test.tsx +45 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleStoryButtonGroup.tsx +42 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleStoryGroupHeader.stories.tsx +27 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleStoryGroupHeader.test.tsx +24 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleStoryGroupHeader.tsx +28 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleTabBar.stories.tsx +41 -5
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleTabBar.test.tsx +59 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/ConsoleTabBar.tsx +28 -19
- package/src/adapter/entry-points/console/ui/src/features/console/fileStatus.test.ts +35 -0
- package/src/adapter/entry-points/console/ui/src/features/console/fileStatus.ts +21 -0
- package/src/adapter/entry-points/console/ui/src/features/console/fixtures.ts +206 -9
- package/src/adapter/entry-points/console/ui/src/features/console/grouping.test.ts +91 -0
- package/src/adapter/entry-points/console/ui/src/features/console/grouping.ts +79 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleCaches.test.ts +22 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleCaches.ts +42 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleItemDetailData.test.ts +126 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleItemDetailData.ts +167 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOperations.test.ts +198 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOperations.ts +243 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOverlay.test.ts +40 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOverlay.ts +71 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsolePjcode.test.ts +24 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsolePjcode.ts +17 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleResource.test.ts +41 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleResource.ts +57 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleTabData.test.ts +63 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleTabData.ts +129 -0
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleToken.test.ts +41 -0
- package/src/adapter/entry-points/console/ui/src/features/console/itemIcons.test.ts +97 -0
- package/src/adapter/entry-points/console/ui/src/features/console/itemIcons.ts +95 -0
- package/src/adapter/entry-points/console/ui/src/features/console/lib/consoleApi.test.ts +155 -0
- package/src/adapter/entry-points/console/ui/src/features/console/lib/consoleApi.ts +187 -0
- package/src/adapter/entry-points/console/ui/src/features/console/lib/markdown.test.ts +76 -0
- package/src/adapter/entry-points/console/ui/src/features/console/lib/markdown.ts +73 -0
- package/src/adapter/entry-points/console/ui/src/features/console/lib/mermaidLoader.test.ts +27 -0
- package/src/adapter/entry-points/console/ui/src/features/console/lib/mermaidLoader.ts +71 -0
- package/src/adapter/entry-points/console/ui/src/features/console/lib/resourceCache.test.ts +56 -0
- package/src/adapter/entry-points/console/ui/src/features/console/lib/resourceCache.ts +51 -0
- package/src/adapter/entry-points/console/ui/src/features/console/operations.test.ts +37 -0
- package/src/adapter/entry-points/console/ui/src/features/console/operations.ts +35 -0
- package/src/adapter/entry-points/console/ui/src/features/console/overlay.test.ts +124 -0
- package/src/adapter/entry-points/console/ui/src/features/console/overlay.ts +101 -0
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.test.tsx +79 -0
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.tsx +109 -0
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.test.tsx +74 -0
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.tsx +137 -7
- package/src/adapter/entry-points/console/ui/src/features/console/relativeTime.test.ts +52 -0
- package/src/adapter/entry-points/console/ui/src/features/console/relativeTime.ts +51 -0
- package/src/adapter/entry-points/console/ui/src/features/console/types.ts +73 -1
- package/src/adapter/entry-points/console/ui/src/index.css +352 -2
- package/src/adapter/entry-points/console/ui/tsconfig.json +3 -1
- package/src/adapter/entry-points/console/ui/vite.config.ts +6 -1
- package/src/adapter/entry-points/console/ui-dist/assets/index-BU6p3cGU.css +1 -0
- package/src/adapter/entry-points/console/ui-dist/assets/index-BvuSQN9s.js +100 -0
- package/src/adapter/entry-points/console/ui-dist/index.html +2 -2
- package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts +25 -0
- package/src/domain/usecases/adapter-interfaces/IssueRepository.ts +4 -0
- package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
- package/types/adapter/entry-points/cli/projectConfig.d.ts +1 -0
- package/types/adapter/entry-points/cli/projectConfig.d.ts.map +1 -1
- package/types/adapter/entry-points/console/consoleOperationApi.d.ts +6 -2
- package/types/adapter/entry-points/console/consoleOperationApi.d.ts.map +1 -1
- package/types/adapter/entry-points/console/consoleProjectResolver.d.ts +6 -0
- package/types/adapter/entry-points/console/consoleProjectResolver.d.ts.map +1 -0
- package/types/adapter/entry-points/console/consoleServer.d.ts +3 -3
- package/types/adapter/entry-points/console/consoleServer.d.ts.map +1 -1
- package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts +1 -0
- package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts.map +1 -1
- package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts +1 -0
- package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts.map +1 -1
- package/bin/adapter/entry-points/console/ui-dist/assets/index-DFxrSRH4.css +0 -1
- package/bin/adapter/entry-points/console/ui-dist/assets/index-DcOZ02ON.js +0 -49
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleList.ts +0 -65
- package/src/adapter/entry-points/console/ui-dist/assets/index-DFxrSRH4.css +0 -1
- package/src/adapter/entry-points/console/ui-dist/assets/index-DcOZ02ON.js +0 -49
|
@@ -69,12 +69,21 @@ describe('consoleOperationApi', () => {
|
|
|
69
69
|
};
|
|
70
70
|
context = {
|
|
71
71
|
issueRepository,
|
|
72
|
-
|
|
72
|
+
resolveProject: async (pjcode: string) =>
|
|
73
|
+
pjcode === 'umino' ? { pjcode, project } : null,
|
|
73
74
|
consoleDataOutputDir: baseDir,
|
|
74
|
-
pjcode: 'umino',
|
|
75
75
|
};
|
|
76
76
|
});
|
|
77
77
|
|
|
78
|
+
const contextForProject = (
|
|
79
|
+
nextProject: Project,
|
|
80
|
+
): ConsoleOperationContext => ({
|
|
81
|
+
issueRepository,
|
|
82
|
+
resolveProject: async (pjcode: string) =>
|
|
83
|
+
pjcode === 'umino' ? { pjcode, project: nextProject } : null,
|
|
84
|
+
consoleDataOutputDir: baseDir,
|
|
85
|
+
});
|
|
86
|
+
|
|
78
87
|
afterEach(() => {
|
|
79
88
|
fs.rmSync(baseDir, { recursive: true, force: true });
|
|
80
89
|
});
|
|
@@ -90,6 +99,7 @@ describe('consoleOperationApi', () => {
|
|
|
90
99
|
describe('handleReview', () => {
|
|
91
100
|
it('approves and sets Awaiting workspace then records done', async () => {
|
|
92
101
|
const response = await handleReview(context, {
|
|
102
|
+
pjcode: 'umino',
|
|
93
103
|
action: 'approve',
|
|
94
104
|
prUrl: 'https://github.com/o/r/pull/1',
|
|
95
105
|
projectItemId: 'PVTI_a',
|
|
@@ -108,6 +118,7 @@ describe('consoleOperationApi', () => {
|
|
|
108
118
|
|
|
109
119
|
it('requests changes with the inline comment', async () => {
|
|
110
120
|
const response = await handleReview(context, {
|
|
121
|
+
pjcode: 'umino',
|
|
111
122
|
action: 'request_changes',
|
|
112
123
|
prUrl: 'https://github.com/o/r/pull/1',
|
|
113
124
|
projectItemId: 'PVTI_b',
|
|
@@ -127,6 +138,7 @@ describe('consoleOperationApi', () => {
|
|
|
127
138
|
|
|
128
139
|
it('rejects request_changes without a comment body', async () => {
|
|
129
140
|
const response = await handleReview(context, {
|
|
141
|
+
pjcode: 'umino',
|
|
130
142
|
action: 'request_changes',
|
|
131
143
|
prUrl: 'https://github.com/o/r/pull/1',
|
|
132
144
|
projectItemId: 'PVTI_b',
|
|
@@ -139,6 +151,7 @@ describe('consoleOperationApi', () => {
|
|
|
139
151
|
|
|
140
152
|
it('closes a pull request and posts a comment', async () => {
|
|
141
153
|
const response = await handleReview(context, {
|
|
154
|
+
pjcode: 'umino',
|
|
142
155
|
action: 'close',
|
|
143
156
|
prUrl: 'https://github.com/o/r/pull/1',
|
|
144
157
|
projectItemId: 'PVTI_c',
|
|
@@ -157,6 +170,7 @@ describe('consoleOperationApi', () => {
|
|
|
157
170
|
|
|
158
171
|
it('rejects an unknown review action', async () => {
|
|
159
172
|
const response = await handleReview(context, {
|
|
173
|
+
pjcode: 'umino',
|
|
160
174
|
action: 'frobnicate',
|
|
161
175
|
prUrl: 'https://github.com/o/r/pull/1',
|
|
162
176
|
projectItemId: 'PVTI_c',
|
|
@@ -166,6 +180,7 @@ describe('consoleOperationApi', () => {
|
|
|
166
180
|
|
|
167
181
|
it('rejects a missing prUrl', async () => {
|
|
168
182
|
const response = await handleReview(context, {
|
|
183
|
+
pjcode: 'umino',
|
|
169
184
|
action: 'approve',
|
|
170
185
|
projectItemId: 'PVTI_c',
|
|
171
186
|
});
|
|
@@ -174,6 +189,7 @@ describe('consoleOperationApi', () => {
|
|
|
174
189
|
|
|
175
190
|
it('rejects a missing action', async () => {
|
|
176
191
|
const response = await handleReview(context, {
|
|
192
|
+
pjcode: 'umino',
|
|
177
193
|
prUrl: 'https://github.com/o/r/pull/1',
|
|
178
194
|
projectItemId: 'PVTI_c',
|
|
179
195
|
});
|
|
@@ -182,6 +198,7 @@ describe('consoleOperationApi', () => {
|
|
|
182
198
|
|
|
183
199
|
it('rejects a missing projectItemId', async () => {
|
|
184
200
|
const response = await handleReview(context, {
|
|
201
|
+
pjcode: 'umino',
|
|
185
202
|
action: 'approve',
|
|
186
203
|
prUrl: 'https://github.com/o/r/pull/1',
|
|
187
204
|
});
|
|
@@ -191,6 +208,7 @@ describe('consoleOperationApi', () => {
|
|
|
191
208
|
it('returns 400 when the issue cannot be loaded during approve', async () => {
|
|
192
209
|
issueRepository.get.mockResolvedValue(null);
|
|
193
210
|
const response = await handleReview(context, {
|
|
211
|
+
pjcode: 'umino',
|
|
194
212
|
action: 'approve',
|
|
195
213
|
prUrl: 'https://github.com/o/r/pull/1',
|
|
196
214
|
projectItemId: 'PVTI_c',
|
|
@@ -200,14 +218,12 @@ describe('consoleOperationApi', () => {
|
|
|
200
218
|
});
|
|
201
219
|
|
|
202
220
|
it('returns 400 when the Awaiting workspace status is absent', async () => {
|
|
203
|
-
const contextWithoutStatus
|
|
204
|
-
...
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
status: { name: 'Status', fieldId: 'f', statuses: [] },
|
|
208
|
-
},
|
|
209
|
-
};
|
|
221
|
+
const contextWithoutStatus = contextForProject({
|
|
222
|
+
...project,
|
|
223
|
+
status: { name: 'Status', fieldId: 'f', statuses: [] },
|
|
224
|
+
});
|
|
210
225
|
const response = await handleReview(contextWithoutStatus, {
|
|
226
|
+
pjcode: 'umino',
|
|
211
227
|
action: 'approve',
|
|
212
228
|
prUrl: 'https://github.com/o/r/pull/1',
|
|
213
229
|
projectItemId: 'PVTI_c',
|
|
@@ -219,6 +235,7 @@ describe('consoleOperationApi', () => {
|
|
|
219
235
|
describe('handleTriage', () => {
|
|
220
236
|
it('sets the status by name', async () => {
|
|
221
237
|
const response = await handleTriage(context, {
|
|
238
|
+
pjcode: 'umino',
|
|
222
239
|
action: 'set_status',
|
|
223
240
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
224
241
|
projectItemId: 'PVTI_d',
|
|
@@ -235,6 +252,7 @@ describe('consoleOperationApi', () => {
|
|
|
235
252
|
|
|
236
253
|
it('rejects an unknown status name', async () => {
|
|
237
254
|
const response = await handleTriage(context, {
|
|
255
|
+
pjcode: 'umino',
|
|
238
256
|
action: 'set_status',
|
|
239
257
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
240
258
|
projectItemId: 'PVTI_d',
|
|
@@ -246,6 +264,7 @@ describe('consoleOperationApi', () => {
|
|
|
246
264
|
|
|
247
265
|
it('sets the story option', async () => {
|
|
248
266
|
const response = await handleTriage(context, {
|
|
267
|
+
pjcode: 'umino',
|
|
249
268
|
action: 'set_story',
|
|
250
269
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
251
270
|
projectItemId: 'PVTI_e',
|
|
@@ -262,6 +281,7 @@ describe('consoleOperationApi', () => {
|
|
|
262
281
|
|
|
263
282
|
it('snoozes for one day via updateNextActionDate', async () => {
|
|
264
283
|
const response = await handleTriage(context, {
|
|
284
|
+
pjcode: 'umino',
|
|
265
285
|
action: 'snooze_1day',
|
|
266
286
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
267
287
|
projectItemId: 'PVTI_f',
|
|
@@ -277,6 +297,7 @@ describe('consoleOperationApi', () => {
|
|
|
277
297
|
|
|
278
298
|
it('snoozes for one week via updateNextActionDate', async () => {
|
|
279
299
|
const response = await handleTriage(context, {
|
|
300
|
+
pjcode: 'umino',
|
|
280
301
|
action: 'snooze_1week',
|
|
281
302
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
282
303
|
projectItemId: 'PVTI_g',
|
|
@@ -286,16 +307,18 @@ describe('consoleOperationApi', () => {
|
|
|
286
307
|
expectRecordedAcrossTabs('PVTI_g');
|
|
287
308
|
});
|
|
288
309
|
|
|
289
|
-
it('closes via the triage close action', async () => {
|
|
310
|
+
it('closes an issue as completed via the triage close action', async () => {
|
|
290
311
|
const response = await handleTriage(context, {
|
|
312
|
+
pjcode: 'umino',
|
|
291
313
|
action: 'close',
|
|
292
314
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
293
315
|
projectItemId: 'PVTI_h',
|
|
294
316
|
commentBody: 'duplicate',
|
|
295
317
|
});
|
|
296
318
|
expect(response.statusCode).toBe(200);
|
|
297
|
-
expect(issueRepository.
|
|
319
|
+
expect(issueRepository.closeIssueByUrl).toHaveBeenCalledWith(
|
|
298
320
|
'https://github.com/o/r/issues/1',
|
|
321
|
+
'completed',
|
|
299
322
|
);
|
|
300
323
|
expect(issueRepository.createCommentByUrl).toHaveBeenCalledWith(
|
|
301
324
|
'https://github.com/o/r/issues/1',
|
|
@@ -304,8 +327,24 @@ describe('consoleOperationApi', () => {
|
|
|
304
327
|
expectRecordedAcrossTabs('PVTI_h');
|
|
305
328
|
});
|
|
306
329
|
|
|
330
|
+
it('closes an issue as not planned via the triage close_not_planned action', async () => {
|
|
331
|
+
const response = await handleTriage(context, {
|
|
332
|
+
pjcode: 'umino',
|
|
333
|
+
action: 'close_not_planned',
|
|
334
|
+
issueUrl: 'https://github.com/o/r/issues/2',
|
|
335
|
+
projectItemId: 'PVTI_np',
|
|
336
|
+
});
|
|
337
|
+
expect(response.statusCode).toBe(200);
|
|
338
|
+
expect(issueRepository.closeIssueByUrl).toHaveBeenCalledWith(
|
|
339
|
+
'https://github.com/o/r/issues/2',
|
|
340
|
+
'not_planned',
|
|
341
|
+
);
|
|
342
|
+
expectRecordedAcrossTabs('PVTI_np');
|
|
343
|
+
});
|
|
344
|
+
|
|
307
345
|
it('rejects an unknown triage action', async () => {
|
|
308
346
|
const response = await handleTriage(context, {
|
|
347
|
+
pjcode: 'umino',
|
|
309
348
|
action: 'unknown',
|
|
310
349
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
311
350
|
projectItemId: 'PVTI_h',
|
|
@@ -315,6 +354,7 @@ describe('consoleOperationApi', () => {
|
|
|
315
354
|
|
|
316
355
|
it('rejects set_status without a status name', async () => {
|
|
317
356
|
const response = await handleTriage(context, {
|
|
357
|
+
pjcode: 'umino',
|
|
318
358
|
action: 'set_status',
|
|
319
359
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
320
360
|
projectItemId: 'PVTI_h',
|
|
@@ -324,6 +364,7 @@ describe('consoleOperationApi', () => {
|
|
|
324
364
|
|
|
325
365
|
it('rejects set_story without a story option id', async () => {
|
|
326
366
|
const response = await handleTriage(context, {
|
|
367
|
+
pjcode: 'umino',
|
|
327
368
|
action: 'set_story',
|
|
328
369
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
329
370
|
projectItemId: 'PVTI_h',
|
|
@@ -332,11 +373,12 @@ describe('consoleOperationApi', () => {
|
|
|
332
373
|
});
|
|
333
374
|
|
|
334
375
|
it('rejects set_story when the project has no story field', async () => {
|
|
335
|
-
const contextWithoutStory
|
|
336
|
-
...
|
|
337
|
-
|
|
338
|
-
};
|
|
376
|
+
const contextWithoutStory = contextForProject({
|
|
377
|
+
...project,
|
|
378
|
+
story: null,
|
|
379
|
+
});
|
|
339
380
|
const response = await handleTriage(contextWithoutStory, {
|
|
381
|
+
pjcode: 'umino',
|
|
340
382
|
action: 'set_story',
|
|
341
383
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
342
384
|
projectItemId: 'PVTI_h',
|
|
@@ -348,6 +390,7 @@ describe('consoleOperationApi', () => {
|
|
|
348
390
|
|
|
349
391
|
it('rejects a missing issueUrl', async () => {
|
|
350
392
|
const response = await handleTriage(context, {
|
|
393
|
+
pjcode: 'umino',
|
|
351
394
|
action: 'set_status',
|
|
352
395
|
projectItemId: 'PVTI_h',
|
|
353
396
|
statusName: 'Todo',
|
|
@@ -358,6 +401,7 @@ describe('consoleOperationApi', () => {
|
|
|
358
401
|
it('returns 400 when the issue cannot be loaded for set_story', async () => {
|
|
359
402
|
issueRepository.get.mockResolvedValue(null);
|
|
360
403
|
const response = await handleTriage(context, {
|
|
404
|
+
pjcode: 'umino',
|
|
361
405
|
action: 'set_story',
|
|
362
406
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
363
407
|
projectItemId: 'PVTI_h',
|
|
@@ -370,6 +414,7 @@ describe('consoleOperationApi', () => {
|
|
|
370
414
|
describe('handleIntmux', () => {
|
|
371
415
|
it('sets the In Tmux by human status and records done', async () => {
|
|
372
416
|
const response = await handleIntmux(context, {
|
|
417
|
+
pjcode: 'umino',
|
|
373
418
|
action: 'set_intmux',
|
|
374
419
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
375
420
|
projectItemId: 'PVTI_i',
|
|
@@ -385,6 +430,7 @@ describe('consoleOperationApi', () => {
|
|
|
385
430
|
|
|
386
431
|
it('rejects an unknown intmux action', async () => {
|
|
387
432
|
const response = await handleIntmux(context, {
|
|
433
|
+
pjcode: 'umino',
|
|
388
434
|
action: 'unset_intmux',
|
|
389
435
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
390
436
|
projectItemId: 'PVTI_i',
|
|
@@ -395,6 +441,7 @@ describe('consoleOperationApi', () => {
|
|
|
395
441
|
it('returns 400 when the issue cannot be loaded', async () => {
|
|
396
442
|
issueRepository.get.mockResolvedValue(null);
|
|
397
443
|
const response = await handleIntmux(context, {
|
|
444
|
+
pjcode: 'umino',
|
|
398
445
|
action: 'set_intmux',
|
|
399
446
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
400
447
|
projectItemId: 'PVTI_i',
|
|
@@ -404,6 +451,7 @@ describe('consoleOperationApi', () => {
|
|
|
404
451
|
|
|
405
452
|
it('rejects a missing issueUrl', async () => {
|
|
406
453
|
const response = await handleIntmux(context, {
|
|
454
|
+
pjcode: 'umino',
|
|
407
455
|
action: 'set_intmux',
|
|
408
456
|
projectItemId: 'PVTI_i',
|
|
409
457
|
});
|
|
@@ -412,6 +460,7 @@ describe('consoleOperationApi', () => {
|
|
|
412
460
|
|
|
413
461
|
it('rejects a missing projectItemId', async () => {
|
|
414
462
|
const response = await handleIntmux(context, {
|
|
463
|
+
pjcode: 'umino',
|
|
415
464
|
action: 'set_intmux',
|
|
416
465
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
417
466
|
});
|
|
@@ -420,6 +469,7 @@ describe('consoleOperationApi', () => {
|
|
|
420
469
|
|
|
421
470
|
it('rejects a missing action', async () => {
|
|
422
471
|
const response = await handleIntmux(context, {
|
|
472
|
+
pjcode: 'umino',
|
|
423
473
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
424
474
|
projectItemId: 'PVTI_i',
|
|
425
475
|
});
|
|
@@ -427,6 +477,69 @@ describe('consoleOperationApi', () => {
|
|
|
427
477
|
});
|
|
428
478
|
});
|
|
429
479
|
|
|
480
|
+
describe('per-project resolution', () => {
|
|
481
|
+
it('rejects an operation whose body has no pjcode', async () => {
|
|
482
|
+
const response = await handleTriage(context, {
|
|
483
|
+
action: 'set_status',
|
|
484
|
+
issueUrl: 'https://github.com/o/r/issues/1',
|
|
485
|
+
projectItemId: 'PVTI_k',
|
|
486
|
+
statusName: 'Todo',
|
|
487
|
+
});
|
|
488
|
+
expect(response.statusCode).toBe(400);
|
|
489
|
+
expect(issueRepository.updateStatus).not.toHaveBeenCalled();
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
it('rejects an operation whose pjcode has no configured project', async () => {
|
|
493
|
+
const response = await handleTriage(context, {
|
|
494
|
+
pjcode: 'unknown-project',
|
|
495
|
+
action: 'set_status',
|
|
496
|
+
issueUrl: 'https://github.com/o/r/issues/1',
|
|
497
|
+
projectItemId: 'PVTI_k',
|
|
498
|
+
statusName: 'Todo',
|
|
499
|
+
});
|
|
500
|
+
expect(response.statusCode).toBe(400);
|
|
501
|
+
expect(issueRepository.updateStatus).not.toHaveBeenCalled();
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
it('records the .done exclusion under the resolved pjcode', async () => {
|
|
505
|
+
const otherProject: Project = { ...project, id: 'PVT_other' };
|
|
506
|
+
const multiContext: ConsoleOperationContext = {
|
|
507
|
+
issueRepository,
|
|
508
|
+
resolveProject: async (pjcode: string) => {
|
|
509
|
+
if (pjcode === 'umino') {
|
|
510
|
+
return { pjcode, project };
|
|
511
|
+
}
|
|
512
|
+
if (pjcode === 'xmile') {
|
|
513
|
+
return { pjcode, project: otherProject };
|
|
514
|
+
}
|
|
515
|
+
return null;
|
|
516
|
+
},
|
|
517
|
+
consoleDataOutputDir: baseDir,
|
|
518
|
+
};
|
|
519
|
+
const response = await handleTriage(multiContext, {
|
|
520
|
+
pjcode: 'xmile',
|
|
521
|
+
action: 'set_status',
|
|
522
|
+
issueUrl: 'https://github.com/o/r/issues/1',
|
|
523
|
+
projectItemId: 'PVTI_x',
|
|
524
|
+
statusName: 'Todo',
|
|
525
|
+
});
|
|
526
|
+
expect(response.statusCode).toBe(200);
|
|
527
|
+
expect(issueRepository.updateStatus).toHaveBeenCalledWith(
|
|
528
|
+
otherProject,
|
|
529
|
+
{ ...issue, itemId: 'PVTI_x' },
|
|
530
|
+
'status_todo',
|
|
531
|
+
);
|
|
532
|
+
for (const tab of CONSOLE_DONE_TAB_NAMES) {
|
|
533
|
+
expect(readDoneProjectItemIds(baseDir, 'xmile', tab)).toContain(
|
|
534
|
+
'PVTI_x',
|
|
535
|
+
);
|
|
536
|
+
expect(readDoneProjectItemIds(baseDir, 'umino', tab)).not.toContain(
|
|
537
|
+
'PVTI_x',
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
});
|
|
542
|
+
|
|
430
543
|
describe('done recording skips when storage is not configured', () => {
|
|
431
544
|
it('does not throw when consoleDataOutputDir is null', async () => {
|
|
432
545
|
const noStorageContext: ConsoleOperationContext = {
|
|
@@ -434,6 +547,7 @@ describe('consoleOperationApi', () => {
|
|
|
434
547
|
consoleDataOutputDir: null,
|
|
435
548
|
};
|
|
436
549
|
const response = await handleIntmux(noStorageContext, {
|
|
550
|
+
pjcode: 'umino',
|
|
437
551
|
action: 'set_intmux',
|
|
438
552
|
issueUrl: 'https://github.com/o/r/issues/1',
|
|
439
553
|
projectItemId: 'PVTI_j',
|
|
@@ -6,11 +6,19 @@ import { recordDoneProjectItemIdAcrossTabs } from './consoleDoneStore';
|
|
|
6
6
|
export const AWAITING_WORKSPACE_STATUS_NAME = 'awaiting workspace';
|
|
7
7
|
export const IN_TMUX_BY_HUMAN_STATUS_NAME = 'in tmux by human';
|
|
8
8
|
|
|
9
|
+
export type ConsoleProjectBinding = {
|
|
10
|
+
pjcode: string;
|
|
11
|
+
project: Project;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type ConsoleProjectResolver = (
|
|
15
|
+
pjcode: string,
|
|
16
|
+
) => Promise<ConsoleProjectBinding | null>;
|
|
17
|
+
|
|
9
18
|
export type ConsoleOperationContext = {
|
|
10
19
|
issueRepository: IssueRepository;
|
|
11
|
-
|
|
20
|
+
resolveProject: ConsoleProjectResolver;
|
|
12
21
|
consoleDataOutputDir: string | null;
|
|
13
|
-
pjcode: string | null;
|
|
14
22
|
};
|
|
15
23
|
|
|
16
24
|
export type ConsoleOperationResponse = {
|
|
@@ -43,11 +51,12 @@ const resolveStatusId = (
|
|
|
43
51
|
};
|
|
44
52
|
|
|
45
53
|
const loadIssueWithProjectItemId = async (
|
|
46
|
-
|
|
54
|
+
issueRepository: IssueRepository,
|
|
55
|
+
project: Project,
|
|
47
56
|
issueUrl: string,
|
|
48
57
|
projectItemId: string,
|
|
49
58
|
): Promise<Issue | null> => {
|
|
50
|
-
const issue = await
|
|
59
|
+
const issue = await issueRepository.get(issueUrl, project);
|
|
51
60
|
if (issue === null) {
|
|
52
61
|
return null;
|
|
53
62
|
}
|
|
@@ -56,37 +65,60 @@ const loadIssueWithProjectItemId = async (
|
|
|
56
65
|
|
|
57
66
|
const recordDone = (
|
|
58
67
|
context: ConsoleOperationContext,
|
|
68
|
+
pjcode: string,
|
|
59
69
|
projectItemId: string,
|
|
60
70
|
): void => {
|
|
61
|
-
if (context.consoleDataOutputDir === null
|
|
71
|
+
if (context.consoleDataOutputDir === null) {
|
|
62
72
|
return;
|
|
63
73
|
}
|
|
64
74
|
recordDoneProjectItemIdAcrossTabs(
|
|
65
75
|
context.consoleDataOutputDir,
|
|
66
|
-
|
|
76
|
+
pjcode,
|
|
67
77
|
projectItemId,
|
|
68
78
|
);
|
|
69
79
|
};
|
|
70
80
|
|
|
71
|
-
const
|
|
81
|
+
const resolveBinding = async (
|
|
72
82
|
context: ConsoleOperationContext,
|
|
83
|
+
body: Record<string, unknown>,
|
|
84
|
+
): Promise<ConsoleProjectBinding | ConsoleOperationResponse> => {
|
|
85
|
+
const pjcode = body.pjcode;
|
|
86
|
+
if (!isNonEmptyString(pjcode)) {
|
|
87
|
+
return badRequest('pjcode is required');
|
|
88
|
+
}
|
|
89
|
+
const binding = await context.resolveProject(pjcode);
|
|
90
|
+
if (binding === null) {
|
|
91
|
+
return badRequest(`no project configured for pjcode "${pjcode}"`);
|
|
92
|
+
}
|
|
93
|
+
return binding;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const isOperationResponse = (
|
|
97
|
+
value: ConsoleProjectBinding | ConsoleOperationResponse,
|
|
98
|
+
): value is ConsoleOperationResponse =>
|
|
99
|
+
Object.prototype.hasOwnProperty.call(value, 'statusCode');
|
|
100
|
+
|
|
101
|
+
const updateStatusByName = async (
|
|
102
|
+
issueRepository: IssueRepository,
|
|
103
|
+
project: Project,
|
|
73
104
|
issueUrl: string,
|
|
74
105
|
projectItemId: string,
|
|
75
106
|
statusName: string,
|
|
76
107
|
): Promise<ConsoleOperationResponse | null> => {
|
|
77
|
-
const statusId = resolveStatusId(
|
|
108
|
+
const statusId = resolveStatusId(project, statusName);
|
|
78
109
|
if (statusId === null) {
|
|
79
110
|
return badRequest(`status option "${statusName}" not found in project`);
|
|
80
111
|
}
|
|
81
112
|
const issue = await loadIssueWithProjectItemId(
|
|
82
|
-
|
|
113
|
+
issueRepository,
|
|
114
|
+
project,
|
|
83
115
|
issueUrl,
|
|
84
116
|
projectItemId,
|
|
85
117
|
);
|
|
86
118
|
if (issue === null) {
|
|
87
119
|
return badRequest('issue not found');
|
|
88
120
|
}
|
|
89
|
-
await
|
|
121
|
+
await issueRepository.updateStatus(project, issue, statusId);
|
|
90
122
|
return null;
|
|
91
123
|
};
|
|
92
124
|
|
|
@@ -106,11 +138,17 @@ export const handleReview = async (
|
|
|
106
138
|
if (!isNonEmptyString(projectItemId)) {
|
|
107
139
|
return badRequest('projectItemId is required');
|
|
108
140
|
}
|
|
141
|
+
const binding = await resolveBinding(context, body);
|
|
142
|
+
if (isOperationResponse(binding)) {
|
|
143
|
+
return binding;
|
|
144
|
+
}
|
|
145
|
+
const { project, pjcode } = binding;
|
|
109
146
|
|
|
110
147
|
if (action === 'approve') {
|
|
111
148
|
await context.issueRepository.approvePullRequest(prUrl);
|
|
112
149
|
const failure = await updateStatusByName(
|
|
113
|
-
context,
|
|
150
|
+
context.issueRepository,
|
|
151
|
+
project,
|
|
114
152
|
prUrl,
|
|
115
153
|
projectItemId,
|
|
116
154
|
AWAITING_WORKSPACE_STATUS_NAME,
|
|
@@ -118,7 +156,7 @@ export const handleReview = async (
|
|
|
118
156
|
if (failure !== null) {
|
|
119
157
|
return failure;
|
|
120
158
|
}
|
|
121
|
-
recordDone(context, projectItemId);
|
|
159
|
+
recordDone(context, pjcode, projectItemId);
|
|
122
160
|
return ok();
|
|
123
161
|
}
|
|
124
162
|
|
|
@@ -136,7 +174,8 @@ export const handleReview = async (
|
|
|
136
174
|
commentBody,
|
|
137
175
|
);
|
|
138
176
|
const failure = await updateStatusByName(
|
|
139
|
-
context,
|
|
177
|
+
context.issueRepository,
|
|
178
|
+
project,
|
|
140
179
|
prUrl,
|
|
141
180
|
projectItemId,
|
|
142
181
|
AWAITING_WORKSPACE_STATUS_NAME,
|
|
@@ -144,7 +183,7 @@ export const handleReview = async (
|
|
|
144
183
|
if (failure !== null) {
|
|
145
184
|
return failure;
|
|
146
185
|
}
|
|
147
|
-
recordDone(context, projectItemId);
|
|
186
|
+
recordDone(context, pjcode, projectItemId);
|
|
148
187
|
return ok();
|
|
149
188
|
}
|
|
150
189
|
|
|
@@ -153,7 +192,7 @@ export const handleReview = async (
|
|
|
153
192
|
if (isNonEmptyString(body.commentBody)) {
|
|
154
193
|
await context.issueRepository.createCommentByUrl(prUrl, body.commentBody);
|
|
155
194
|
}
|
|
156
|
-
recordDone(context, projectItemId);
|
|
195
|
+
recordDone(context, pjcode, projectItemId);
|
|
157
196
|
return ok();
|
|
158
197
|
}
|
|
159
198
|
|
|
@@ -176,6 +215,11 @@ export const handleTriage = async (
|
|
|
176
215
|
if (!isNonEmptyString(projectItemId)) {
|
|
177
216
|
return badRequest('projectItemId is required');
|
|
178
217
|
}
|
|
218
|
+
const binding = await resolveBinding(context, body);
|
|
219
|
+
if (isOperationResponse(binding)) {
|
|
220
|
+
return binding;
|
|
221
|
+
}
|
|
222
|
+
const { project, pjcode } = binding;
|
|
179
223
|
|
|
180
224
|
if (action === 'set_status') {
|
|
181
225
|
const statusName = body.statusName;
|
|
@@ -183,7 +227,8 @@ export const handleTriage = async (
|
|
|
183
227
|
return badRequest('statusName is required for set_status');
|
|
184
228
|
}
|
|
185
229
|
const failure = await updateStatusByName(
|
|
186
|
-
context,
|
|
230
|
+
context.issueRepository,
|
|
231
|
+
project,
|
|
187
232
|
issueUrl,
|
|
188
233
|
projectItemId,
|
|
189
234
|
statusName,
|
|
@@ -191,7 +236,7 @@ export const handleTriage = async (
|
|
|
191
236
|
if (failure !== null) {
|
|
192
237
|
return failure;
|
|
193
238
|
}
|
|
194
|
-
recordDone(context, projectItemId);
|
|
239
|
+
recordDone(context, pjcode, projectItemId);
|
|
195
240
|
return ok();
|
|
196
241
|
}
|
|
197
242
|
|
|
@@ -200,11 +245,12 @@ export const handleTriage = async (
|
|
|
200
245
|
if (!isNonEmptyString(storyOptionId)) {
|
|
201
246
|
return badRequest('storyOptionId is required for set_story');
|
|
202
247
|
}
|
|
203
|
-
if (
|
|
248
|
+
if (project.story === null) {
|
|
204
249
|
return badRequest('project does not have a story field');
|
|
205
250
|
}
|
|
206
251
|
const issue = await loadIssueWithProjectItemId(
|
|
207
|
-
context,
|
|
252
|
+
context.issueRepository,
|
|
253
|
+
project,
|
|
208
254
|
issueUrl,
|
|
209
255
|
projectItemId,
|
|
210
256
|
);
|
|
@@ -212,23 +258,26 @@ export const handleTriage = async (
|
|
|
212
258
|
return badRequest('issue not found');
|
|
213
259
|
}
|
|
214
260
|
await context.issueRepository.updateStory(
|
|
215
|
-
{ ...
|
|
261
|
+
{ ...project, story: project.story },
|
|
216
262
|
issue,
|
|
217
263
|
storyOptionId,
|
|
218
264
|
);
|
|
219
|
-
recordDone(context, projectItemId);
|
|
265
|
+
recordDone(context, pjcode, projectItemId);
|
|
220
266
|
return ok();
|
|
221
267
|
}
|
|
222
268
|
|
|
223
|
-
if (action === 'close') {
|
|
224
|
-
await context.issueRepository.closePullRequest(issueUrl);
|
|
269
|
+
if (action === 'close' || action === 'close_not_planned') {
|
|
225
270
|
if (isNonEmptyString(body.commentBody)) {
|
|
226
271
|
await context.issueRepository.createCommentByUrl(
|
|
227
272
|
issueUrl,
|
|
228
273
|
body.commentBody,
|
|
229
274
|
);
|
|
230
275
|
}
|
|
231
|
-
|
|
276
|
+
await context.issueRepository.closeIssueByUrl(
|
|
277
|
+
issueUrl,
|
|
278
|
+
action === 'close_not_planned' ? 'not_planned' : 'completed',
|
|
279
|
+
);
|
|
280
|
+
recordDone(context, pjcode, projectItemId);
|
|
232
281
|
return ok();
|
|
233
282
|
}
|
|
234
283
|
|
|
@@ -237,10 +286,10 @@ export const handleTriage = async (
|
|
|
237
286
|
const target = new Date(Date.now() + days * 24 * 60 * 60 * 1000);
|
|
238
287
|
await context.issueRepository.updateNextActionDate(
|
|
239
288
|
issueUrl,
|
|
240
|
-
|
|
289
|
+
project,
|
|
241
290
|
target,
|
|
242
291
|
);
|
|
243
|
-
recordDone(context, projectItemId);
|
|
292
|
+
recordDone(context, pjcode, projectItemId);
|
|
244
293
|
return ok();
|
|
245
294
|
}
|
|
246
295
|
|
|
@@ -266,8 +315,14 @@ export const handleIntmux = async (
|
|
|
266
315
|
if (!isNonEmptyString(projectItemId)) {
|
|
267
316
|
return badRequest('projectItemId is required');
|
|
268
317
|
}
|
|
318
|
+
const binding = await resolveBinding(context, body);
|
|
319
|
+
if (isOperationResponse(binding)) {
|
|
320
|
+
return binding;
|
|
321
|
+
}
|
|
322
|
+
const { project, pjcode } = binding;
|
|
269
323
|
const failure = await updateStatusByName(
|
|
270
|
-
context,
|
|
324
|
+
context.issueRepository,
|
|
325
|
+
project,
|
|
271
326
|
issueUrl,
|
|
272
327
|
projectItemId,
|
|
273
328
|
IN_TMUX_BY_HUMAN_STATUS_NAME,
|
|
@@ -275,6 +330,6 @@ export const handleIntmux = async (
|
|
|
275
330
|
if (failure !== null) {
|
|
276
331
|
return failure;
|
|
277
332
|
}
|
|
278
|
-
recordDone(context, projectItemId);
|
|
333
|
+
recordDone(context, pjcode, projectItemId);
|
|
279
334
|
return ok();
|
|
280
335
|
};
|