github-issue-tower-defence-management 1.179.0 → 1.180.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.
- package/CHANGELOG.md +22 -0
- 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/CheckIssueReviewReadinessUseCase.js +2 -1
- package/bin/domain/usecases/CheckIssueReviewReadinessUseCase.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 +2 -1
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js +2 -1
- package/bin/domain/usecases/RevertOrphanedPreparationUseCase.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/TriagerApprovalDispatchUseCase.js +3 -3
- package/bin/domain/usecases/TriagerApprovalDispatchUseCase.js.map +1 -1
- package/bin/domain/usecases/findLastAgentReport.js +2 -3
- package/bin/domain/usecases/findLastAgentReport.js.map +1 -1
- package/bin/domain/usecases/isAgentReportBody.js +43 -0
- package/bin/domain/usecases/isAgentReportBody.js.map +1 -0
- package/bin/domain/usecases/isPullRequestDeclaredUnnecessary.js +2 -2
- package/bin/domain/usecases/isPullRequestDeclaredUnnecessary.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/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/CheckIssueReviewReadinessUseCase.ts +2 -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 +50 -0
- package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +2 -1
- package/src/domain/usecases/RevertOrphanedPreparationUseCase.ts +2 -1
- package/src/domain/usecases/StartPreparationUseCase.ts +5 -3
- package/src/domain/usecases/TriagerApprovalDispatchUseCase.ts +6 -5
- package/src/domain/usecases/findLastAgentReport.test.ts +28 -0
- package/src/domain/usecases/findLastAgentReport.ts +2 -3
- package/src/domain/usecases/isAgentReportBody.test.ts +108 -0
- package/src/domain/usecases/isAgentReportBody.ts +52 -0
- package/src/domain/usecases/isPullRequestDeclaredUnnecessary.ts +2 -2
- package/src/domain/usecases/issueReactivationTriggerIsPending.test.ts +33 -33
- package/src/domain/usecases/issueReactivationTriggerIsPending.ts +6 -4
- 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/CheckIssueReviewReadinessUseCase.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.map +1 -1
- package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/TriagerApprovalDispatchUseCase.d.ts.map +1 -1
- package/types/domain/usecases/findLastAgentReport.d.ts.map +1 -1
- package/types/domain/usecases/isAgentReportBody.d.ts +4 -0
- package/types/domain/usecases/isAgentReportBody.d.ts.map +1 -0
- 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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TriagerApprovalDispatchUseCase = void 0;
|
|
4
|
-
const
|
|
4
|
+
const isAgentReportBody_1 = require("./isAgentReportBody");
|
|
5
5
|
const ensureAgentOptionAndGetId_1 = require("./ensureAgentOptionAndGetId");
|
|
6
6
|
const isAuthorAuthorizedForAutoStatusCheck_1 = require("./isAuthorAuthorizedForAutoStatusCheck");
|
|
7
7
|
const isRecord_1 = require("./isRecord");
|
|
@@ -10,7 +10,7 @@ const normalizeReportBody_1 = require("./normalizeReportBody");
|
|
|
10
10
|
const TRIAGER_AGENT_NAME = 'triager';
|
|
11
11
|
const MAX_COMMENT_FETCHES_PER_CYCLE = 20;
|
|
12
12
|
const parseTriagerProposalBlock = (commentContent) => {
|
|
13
|
-
if (!
|
|
13
|
+
if (!(0, isAgentReportBody_1.isAgentReportBodyFromAgent)(commentContent, TRIAGER_AGENT_NAME)) {
|
|
14
14
|
return null;
|
|
15
15
|
}
|
|
16
16
|
const jsonBlockMatches = [
|
|
@@ -52,7 +52,7 @@ const isApprovalComment = (content, author, allowedIssueAuthors) => {
|
|
|
52
52
|
if (!(0, isAuthorAuthorizedForAutoStatusCheck_1.isAuthorAuthorizedForAutoStatusCheck)(author, allowedIssueAuthors)) {
|
|
53
53
|
return false;
|
|
54
54
|
}
|
|
55
|
-
if (
|
|
55
|
+
if ((0, isAgentReportBody_1.isAgentReportBody)(content)) {
|
|
56
56
|
return false;
|
|
57
57
|
}
|
|
58
58
|
return /^(ok|オーケー|はい[\s\S]*)$/i.test(content.trim());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TriagerApprovalDispatchUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/TriagerApprovalDispatchUseCase.ts"],"names":[],"mappings":";;;AAGA,
|
|
1
|
+
{"version":3,"file":"TriagerApprovalDispatchUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/TriagerApprovalDispatchUseCase.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.findLastAgentReport = void 0;
|
|
4
|
-
const
|
|
4
|
+
const isAgentReportBody_1 = require("./isAgentReportBody");
|
|
5
5
|
const findLastAgentReport = (comments, isTrustedAuthor) => [...comments]
|
|
6
6
|
.reverse()
|
|
7
|
-
.find((comment) => isTrustedAuthor(comment.author) &&
|
|
8
|
-
comment.content.startsWith(agentReportPrefix_1.AGENT_REPORT_PREFIX)) ?? null;
|
|
7
|
+
.find((comment) => isTrustedAuthor(comment.author) && (0, isAgentReportBody_1.isAgentReportBody)(comment.content)) ?? null;
|
|
9
8
|
exports.findLastAgentReport = findLastAgentReport;
|
|
10
9
|
//# sourceMappingURL=findLastAgentReport.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"findLastAgentReport.js","sourceRoot":"","sources":["../../../src/domain/usecases/findLastAgentReport.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"findLastAgentReport.js","sourceRoot":"","sources":["../../../src/domain/usecases/findLastAgentReport.ts"],"names":[],"mappings":";;;AAAA,2DAAwD;AAEjD,MAAM,mBAAmB,GAAG,CAGjC,QAAmB,EACnB,eAA4C,EAC5B,EAAE,CAClB,CAAC,GAAG,QAAQ,CAAC;KACV,OAAO,EAAE;KACT,IAAI,CACH,CAAC,OAAO,EAAE,EAAE,CACV,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAA,qCAAiB,EAAC,OAAO,CAAC,OAAO,CAAC,CACxE,IAAI,IAAI,CAAC;AAXD,QAAA,mBAAmB,uBAWlB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isAgentReportBodyFromAgent = exports.isAgentReportBody = exports.stripLeadingFencedBlocks = void 0;
|
|
4
|
+
const agentReportPrefix_1 = require("./agentReportPrefix");
|
|
5
|
+
const normalizeReportBody_1 = require("./normalizeReportBody");
|
|
6
|
+
const FENCE_OPENING = /^ {0,3}(`{3,}|~{3,})/;
|
|
7
|
+
const isFenceClosingLine = (line, marker) => {
|
|
8
|
+
const trimmed = line.trim();
|
|
9
|
+
return (trimmed.length >= marker.length &&
|
|
10
|
+
[...trimmed].every((character) => character === marker[0]));
|
|
11
|
+
};
|
|
12
|
+
const stripLeadingFencedBlocks = (body) => {
|
|
13
|
+
const lines = (0, normalizeReportBody_1.normalizeReportBody)(body).split('\n');
|
|
14
|
+
let index = 0;
|
|
15
|
+
while (index < lines.length) {
|
|
16
|
+
const line = lines[index];
|
|
17
|
+
if (line.trim() === '') {
|
|
18
|
+
index += 1;
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const opening = FENCE_OPENING.exec(line);
|
|
22
|
+
if (!opening) {
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
const marker = opening[1];
|
|
26
|
+
let closingIndex = index + 1;
|
|
27
|
+
while (closingIndex < lines.length &&
|
|
28
|
+
!isFenceClosingLine(lines[closingIndex], marker)) {
|
|
29
|
+
closingIndex += 1;
|
|
30
|
+
}
|
|
31
|
+
if (closingIndex >= lines.length) {
|
|
32
|
+
return '';
|
|
33
|
+
}
|
|
34
|
+
index = closingIndex + 1;
|
|
35
|
+
}
|
|
36
|
+
return lines.slice(index).join('\n');
|
|
37
|
+
};
|
|
38
|
+
exports.stripLeadingFencedBlocks = stripLeadingFencedBlocks;
|
|
39
|
+
const isAgentReportBody = (body) => (0, exports.stripLeadingFencedBlocks)(body).startsWith(agentReportPrefix_1.AGENT_REPORT_PREFIX);
|
|
40
|
+
exports.isAgentReportBody = isAgentReportBody;
|
|
41
|
+
const isAgentReportBodyFromAgent = (body, agentName) => (0, exports.stripLeadingFencedBlocks)(body).startsWith(`${agentReportPrefix_1.AGENT_REPORT_PREFIX} ${agentName}`);
|
|
42
|
+
exports.isAgentReportBodyFromAgent = isAgentReportBodyFromAgent;
|
|
43
|
+
//# sourceMappingURL=isAgentReportBody.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isAgentReportBody.js","sourceRoot":"","sources":["../../../src/domain/usecases/isAgentReportBody.ts"],"names":[],"mappings":";;;AAAA,2DAA0D;AAC1D,+DAA4D;AAE5D,MAAM,aAAa,GAAG,sBAAsB,CAAC;AAE7C,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAE,MAAc,EAAW,EAAE;IACnE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,OAAO,CACL,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM;QAC/B,CAAC,GAAG,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAC3D,CAAC;AACJ,CAAC,CAAC;AAEK,MAAM,wBAAwB,GAAG,CAAC,IAAY,EAAU,EAAE;IAC/D,MAAM,KAAK,GAAG,IAAA,yCAAmB,EAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACpD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACvB,KAAK,IAAI,CAAC,CAAC;YACX,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,YAAY,GAAG,KAAK,GAAG,CAAC,CAAC;QAC7B,OACE,YAAY,GAAG,KAAK,CAAC,MAAM;YAC3B,CAAC,kBAAkB,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,EAChD,CAAC;YACD,YAAY,IAAI,CAAC,CAAC;QACpB,CAAC;QACD,IAAI,YAAY,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjC,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,KAAK,GAAG,YAAY,GAAG,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC,CAAC;AA3BW,QAAA,wBAAwB,4BA2BnC;AAEK,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAW,EAAE,CACzD,IAAA,gCAAwB,EAAC,IAAI,CAAC,CAAC,UAAU,CAAC,uCAAmB,CAAC,CAAC;AADpD,QAAA,iBAAiB,qBACmC;AAE1D,MAAM,0BAA0B,GAAG,CACxC,IAAY,EACZ,SAAiB,EACR,EAAE,CACX,IAAA,gCAAwB,EAAC,IAAI,CAAC,CAAC,UAAU,CACvC,GAAG,uCAAmB,IAAI,SAAS,EAAE,CACtC,CAAC;AANS,QAAA,0BAA0B,8BAMnC"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.isPullRequestDeclaredUnnecessary = void 0;
|
|
4
|
-
const
|
|
4
|
+
const isAgentReportBody_1 = require("./isAgentReportBody");
|
|
5
5
|
const normalizeReportBody_1 = require("./normalizeReportBody");
|
|
6
6
|
const isPullRequestDeclaredUnnecessary = (comments, isTrustedAuthor) => {
|
|
7
7
|
const lastComment = comments[comments.length - 1];
|
|
8
8
|
if (!lastComment ||
|
|
9
9
|
!isTrustedAuthor(lastComment.author) ||
|
|
10
|
-
!lastComment.content
|
|
10
|
+
!(0, isAgentReportBody_1.isAgentReportBody)(lastComment.content)) {
|
|
11
11
|
return false;
|
|
12
12
|
}
|
|
13
13
|
const reportMatch = (0, normalizeReportBody_1.normalizeReportBody)(lastComment.content).match(/```json\n([\s\S]*?)\n```/);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isPullRequestDeclaredUnnecessary.js","sourceRoot":"","sources":["../../../src/domain/usecases/isPullRequestDeclaredUnnecessary.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"isPullRequestDeclaredUnnecessary.js","sourceRoot":"","sources":["../../../src/domain/usecases/isPullRequestDeclaredUnnecessary.ts"],"names":[],"mappings":";;;AAAA,2DAAwD;AACxD,+DAA4D;AAErD,MAAM,gCAAgC,GAAG,CAC9C,QAA+C,EAC/C,eAA4C,EACnC,EAAE;IACX,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAClD,IACE,CAAC,WAAW;QACZ,CAAC,eAAe,CAAC,WAAW,CAAC,MAAM,CAAC;QACpC,CAAC,IAAA,qCAAiB,EAAC,WAAW,CAAC,OAAO,CAAC,EACvC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,WAAW,GAAG,IAAA,yCAAmB,EAAC,WAAW,CAAC,OAAO,CAAC,CAAC,KAAK,CAChE,0BAA0B,CAC3B,CAAC;IACF,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,UAAmB,CAAC;IACxB,IAAI,CAAC;QACH,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CACV,iEAAiE,EACjE,KAAK,CACN,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QAC1D,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,MAAM,GAA4B,EAAE,GAAG,UAAU,EAAE,CAAC;IAC1D,OAAO,MAAM,CAAC,mBAAmB,KAAK,KAAK,CAAC;AAC9C,CAAC,CAAC;AAjCW,QAAA,gCAAgC,oCAiC3C"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.issueReactivationTriggerIsPending = exports.issueReactivationTriggerStartOfTomorrow = void 0;
|
|
4
|
-
const issueReactivationTriggerStartOfTomorrow = (evaluatedAt) => new Date(evaluatedAt.
|
|
4
|
+
const issueReactivationTriggerStartOfTomorrow = (evaluatedAt) => new Date(Date.UTC(evaluatedAt.getUTCFullYear(), evaluatedAt.getUTCMonth(), evaluatedAt.getUTCDate() + 1));
|
|
5
5
|
exports.issueReactivationTriggerStartOfTomorrow = issueReactivationTriggerStartOfTomorrow;
|
|
6
6
|
const issueReactivationTriggerIsPending = (issue, evaluatedAt) => {
|
|
7
7
|
const startOfTomorrow = (0, exports.issueReactivationTriggerStartOfTomorrow)(evaluatedAt);
|
|
8
8
|
const hasFutureNextActionDate = issue.nextActionDate !== null && issue.nextActionDate >= startOfTomorrow;
|
|
9
9
|
const hasUnreachedNextActionHour = issue.nextActionHour !== null &&
|
|
10
|
-
evaluatedAt.
|
|
10
|
+
evaluatedAt.getUTCHours() < issue.nextActionHour;
|
|
11
11
|
return hasFutureNextActionDate || hasUnreachedNextActionHour;
|
|
12
12
|
};
|
|
13
13
|
exports.issueReactivationTriggerIsPending = issueReactivationTriggerIsPending;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issueReactivationTriggerIsPending.js","sourceRoot":"","sources":["../../../src/domain/usecases/issueReactivationTriggerIsPending.ts"],"names":[],"mappings":";;;AAEO,MAAM,uCAAuC,GAAG,CACrD,WAAiB,EACX,EAAE,CACR,IAAI,IAAI,CACN,
|
|
1
|
+
{"version":3,"file":"issueReactivationTriggerIsPending.js","sourceRoot":"","sources":["../../../src/domain/usecases/issueReactivationTriggerIsPending.ts"],"names":[],"mappings":";;;AAEO,MAAM,uCAAuC,GAAG,CACrD,WAAiB,EACX,EAAE,CACR,IAAI,IAAI,CACN,IAAI,CAAC,GAAG,CACN,WAAW,CAAC,cAAc,EAAE,EAC5B,WAAW,CAAC,WAAW,EAAE,EACzB,WAAW,CAAC,UAAU,EAAE,GAAG,CAAC,CAC7B,CACF,CAAC;AATS,QAAA,uCAAuC,2CAShD;AAEG,MAAM,iCAAiC,GAAG,CAC/C,KAAuD,EACvD,WAAiB,EACR,EAAE;IACX,MAAM,eAAe,GAAG,IAAA,+CAAuC,EAAC,WAAW,CAAC,CAAC;IAC7E,MAAM,uBAAuB,GAC3B,KAAK,CAAC,cAAc,KAAK,IAAI,IAAI,KAAK,CAAC,cAAc,IAAI,eAAe,CAAC;IAC3E,MAAM,0BAA0B,GAC9B,KAAK,CAAC,cAAc,KAAK,IAAI;QAC7B,WAAW,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC,cAAc,CAAC;IACnD,OAAO,uBAAuB,IAAI,0BAA0B,CAAC;AAC/D,CAAC,CAAC;AAXW,QAAA,iCAAiC,qCAW5C"}
|
package/package.json
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
handleComment,
|
|
13
13
|
handleCreateIssue,
|
|
14
14
|
handleIntmux,
|
|
15
|
+
handleReorderStory,
|
|
15
16
|
handleReview,
|
|
16
17
|
handleReviewComment,
|
|
17
18
|
handleTriage,
|
|
@@ -110,6 +111,7 @@ describe('consoleOperationApi', () => {
|
|
|
110
111
|
isPjcodeConfigured: (pjcode: string) => pjcode === 'acme',
|
|
111
112
|
consoleDataOutputDir: baseDir,
|
|
112
113
|
issueAttachmentRepository: null,
|
|
114
|
+
updateStoryList: null,
|
|
113
115
|
};
|
|
114
116
|
});
|
|
115
117
|
|
|
@@ -122,6 +124,7 @@ describe('consoleOperationApi', () => {
|
|
|
122
124
|
isPjcodeConfigured: (pjcode: string) => pjcode === 'acme',
|
|
123
125
|
consoleDataOutputDir: baseDir,
|
|
124
126
|
issueAttachmentRepository: null,
|
|
127
|
+
updateStoryList: null,
|
|
125
128
|
});
|
|
126
129
|
|
|
127
130
|
afterEach(() => {
|
|
@@ -864,6 +867,7 @@ describe('consoleOperationApi', () => {
|
|
|
864
867
|
isPjcodeConfigured: (pjcode: string) => pjcode === 'acme',
|
|
865
868
|
consoleDataOutputDir: baseDir,
|
|
866
869
|
issueAttachmentRepository: null,
|
|
870
|
+
updateStoryList: null,
|
|
867
871
|
};
|
|
868
872
|
});
|
|
869
873
|
|
|
@@ -1109,6 +1113,7 @@ describe('consoleOperationApi', () => {
|
|
|
1109
1113
|
pjcode === 'acme' || pjcode === 'globex',
|
|
1110
1114
|
consoleDataOutputDir: baseDir,
|
|
1111
1115
|
issueAttachmentRepository: null,
|
|
1116
|
+
updateStoryList: null,
|
|
1112
1117
|
};
|
|
1113
1118
|
const response = await handleTriage(multiContext, {
|
|
1114
1119
|
pjcode: 'globex',
|
|
@@ -1677,4 +1682,229 @@ describe('consoleOperationApi', () => {
|
|
|
1677
1682
|
});
|
|
1678
1683
|
});
|
|
1679
1684
|
});
|
|
1685
|
+
|
|
1686
|
+
describe('handleReorderStory', () => {
|
|
1687
|
+
const projectWithOrderedStories = (): Project => ({
|
|
1688
|
+
...project,
|
|
1689
|
+
story: {
|
|
1690
|
+
name: 'Story',
|
|
1691
|
+
fieldId: 'storyField',
|
|
1692
|
+
databaseId: 1,
|
|
1693
|
+
stories: [
|
|
1694
|
+
{ id: 'opt_a', name: 'Alpha', color: 'BLUE', description: '' },
|
|
1695
|
+
{ id: 'opt_b', name: 'Beta', color: 'GREEN', description: '' },
|
|
1696
|
+
{ id: 'opt_c', name: 'Gamma', color: 'RED', description: '' },
|
|
1697
|
+
],
|
|
1698
|
+
workflowManagementStory: { id: 'wms', name: 'workflow' },
|
|
1699
|
+
},
|
|
1700
|
+
});
|
|
1701
|
+
|
|
1702
|
+
const contextWithUpdateStoryList = (
|
|
1703
|
+
updateStoryList: ConsoleOperationContext['updateStoryList'],
|
|
1704
|
+
baseProject: Project = projectWithOrderedStories(),
|
|
1705
|
+
): ConsoleOperationContext => ({
|
|
1706
|
+
...contextForProject(baseProject),
|
|
1707
|
+
updateStoryList,
|
|
1708
|
+
});
|
|
1709
|
+
|
|
1710
|
+
it('returns 400 when pjcode is missing', async () => {
|
|
1711
|
+
const response = await handleReorderStory(context, {
|
|
1712
|
+
storyOptionId: 'opt_b',
|
|
1713
|
+
direction: 'up',
|
|
1714
|
+
});
|
|
1715
|
+
expect(response).toEqual({
|
|
1716
|
+
statusCode: 400,
|
|
1717
|
+
body: { error: 'pjcode is required' },
|
|
1718
|
+
});
|
|
1719
|
+
});
|
|
1720
|
+
|
|
1721
|
+
it('returns 400 when storyOptionId is missing', async () => {
|
|
1722
|
+
const response = await handleReorderStory(context, {
|
|
1723
|
+
pjcode: 'acme',
|
|
1724
|
+
direction: 'up',
|
|
1725
|
+
});
|
|
1726
|
+
expect(response).toEqual({
|
|
1727
|
+
statusCode: 400,
|
|
1728
|
+
body: { error: 'storyOptionId is required' },
|
|
1729
|
+
});
|
|
1730
|
+
});
|
|
1731
|
+
|
|
1732
|
+
it('returns 400 when direction is not "up" or "down"', async () => {
|
|
1733
|
+
const response = await handleReorderStory(context, {
|
|
1734
|
+
pjcode: 'acme',
|
|
1735
|
+
storyOptionId: 'opt_b',
|
|
1736
|
+
direction: 'left',
|
|
1737
|
+
});
|
|
1738
|
+
expect(response).toEqual({
|
|
1739
|
+
statusCode: 400,
|
|
1740
|
+
body: { error: 'direction must be "up" or "down"' },
|
|
1741
|
+
});
|
|
1742
|
+
});
|
|
1743
|
+
|
|
1744
|
+
it('returns 400 when project is not found', async () => {
|
|
1745
|
+
const response = await handleReorderStory(
|
|
1746
|
+
contextWithUpdateStoryList(jest.fn()),
|
|
1747
|
+
{
|
|
1748
|
+
pjcode: 'unknown',
|
|
1749
|
+
storyOptionId: 'opt_b',
|
|
1750
|
+
direction: 'up',
|
|
1751
|
+
},
|
|
1752
|
+
);
|
|
1753
|
+
expect(response).toEqual({
|
|
1754
|
+
statusCode: 400,
|
|
1755
|
+
body: { error: 'no project configured for pjcode "unknown"' },
|
|
1756
|
+
});
|
|
1757
|
+
});
|
|
1758
|
+
|
|
1759
|
+
it('returns 400 when story option is not found', async () => {
|
|
1760
|
+
const response = await handleReorderStory(
|
|
1761
|
+
contextWithUpdateStoryList(jest.fn()),
|
|
1762
|
+
{
|
|
1763
|
+
pjcode: 'acme',
|
|
1764
|
+
storyOptionId: 'opt_nonexistent',
|
|
1765
|
+
direction: 'up',
|
|
1766
|
+
},
|
|
1767
|
+
);
|
|
1768
|
+
expect(response).toEqual({
|
|
1769
|
+
statusCode: 400,
|
|
1770
|
+
body: { error: 'story option not found' },
|
|
1771
|
+
});
|
|
1772
|
+
});
|
|
1773
|
+
|
|
1774
|
+
it('returns 400 when direction is "up" and the option is already first', async () => {
|
|
1775
|
+
const response = await handleReorderStory(
|
|
1776
|
+
contextWithUpdateStoryList(jest.fn()),
|
|
1777
|
+
{
|
|
1778
|
+
pjcode: 'acme',
|
|
1779
|
+
storyOptionId: 'opt_a',
|
|
1780
|
+
direction: 'up',
|
|
1781
|
+
},
|
|
1782
|
+
);
|
|
1783
|
+
expect(response).toEqual({
|
|
1784
|
+
statusCode: 400,
|
|
1785
|
+
body: { error: 'cannot move in that direction' },
|
|
1786
|
+
});
|
|
1787
|
+
});
|
|
1788
|
+
|
|
1789
|
+
it('returns 400 when direction is "down" and the option is already last', async () => {
|
|
1790
|
+
const response = await handleReorderStory(
|
|
1791
|
+
contextWithUpdateStoryList(jest.fn()),
|
|
1792
|
+
{
|
|
1793
|
+
pjcode: 'acme',
|
|
1794
|
+
storyOptionId: 'opt_c',
|
|
1795
|
+
direction: 'down',
|
|
1796
|
+
},
|
|
1797
|
+
);
|
|
1798
|
+
expect(response).toEqual({
|
|
1799
|
+
statusCode: 400,
|
|
1800
|
+
body: { error: 'cannot move in that direction' },
|
|
1801
|
+
});
|
|
1802
|
+
});
|
|
1803
|
+
|
|
1804
|
+
it('returns 400 when updateStoryList is not configured', async () => {
|
|
1805
|
+
const response = await handleReorderStory(
|
|
1806
|
+
contextWithUpdateStoryList(null),
|
|
1807
|
+
{
|
|
1808
|
+
pjcode: 'acme',
|
|
1809
|
+
storyOptionId: 'opt_b',
|
|
1810
|
+
direction: 'up',
|
|
1811
|
+
},
|
|
1812
|
+
);
|
|
1813
|
+
expect(response).toEqual({
|
|
1814
|
+
statusCode: 400,
|
|
1815
|
+
body: { error: 'updateStoryList is not configured' },
|
|
1816
|
+
});
|
|
1817
|
+
});
|
|
1818
|
+
|
|
1819
|
+
it('swaps the target option with its neighbor, calls updateStoryList with reordered list, and returns 200', async () => {
|
|
1820
|
+
const updateStoryList = jest.fn().mockResolvedValue([]);
|
|
1821
|
+
const response = await handleReorderStory(
|
|
1822
|
+
contextWithUpdateStoryList(updateStoryList),
|
|
1823
|
+
{
|
|
1824
|
+
pjcode: 'acme',
|
|
1825
|
+
storyOptionId: 'opt_b',
|
|
1826
|
+
direction: 'up',
|
|
1827
|
+
},
|
|
1828
|
+
);
|
|
1829
|
+
expect(response).toEqual({ statusCode: 200, body: { ok: true } });
|
|
1830
|
+
expect(updateStoryList).toHaveBeenCalledTimes(1);
|
|
1831
|
+
expect(updateStoryList).toHaveBeenCalledWith(
|
|
1832
|
+
expect.objectContaining({ id: projectWithOrderedStories().id }),
|
|
1833
|
+
[
|
|
1834
|
+
expect.objectContaining({ id: 'opt_b' }),
|
|
1835
|
+
expect.objectContaining({ id: 'opt_a' }),
|
|
1836
|
+
expect.objectContaining({ id: 'opt_c' }),
|
|
1837
|
+
],
|
|
1838
|
+
);
|
|
1839
|
+
});
|
|
1840
|
+
|
|
1841
|
+
it('returns 400 when project does not have a story field', async () => {
|
|
1842
|
+
const projectWithoutStory = {
|
|
1843
|
+
...projectWithOrderedStories(),
|
|
1844
|
+
story: null,
|
|
1845
|
+
};
|
|
1846
|
+
const response = await handleReorderStory(
|
|
1847
|
+
contextWithUpdateStoryList(jest.fn(), projectWithoutStory),
|
|
1848
|
+
{
|
|
1849
|
+
pjcode: 'acme',
|
|
1850
|
+
storyOptionId: 'opt_b',
|
|
1851
|
+
direction: 'up',
|
|
1852
|
+
},
|
|
1853
|
+
);
|
|
1854
|
+
expect(response).toEqual({
|
|
1855
|
+
statusCode: 400,
|
|
1856
|
+
body: { error: 'project does not have a story field' },
|
|
1857
|
+
});
|
|
1858
|
+
});
|
|
1859
|
+
|
|
1860
|
+
it('passes the full story list including GRAY options to updateStoryList', async () => {
|
|
1861
|
+
const projectWithGray = {
|
|
1862
|
+
...projectWithOrderedStories(),
|
|
1863
|
+
story: {
|
|
1864
|
+
name: 'Story',
|
|
1865
|
+
fieldId: 'storyField',
|
|
1866
|
+
databaseId: 1,
|
|
1867
|
+
stories: [
|
|
1868
|
+
{
|
|
1869
|
+
id: 'opt_a',
|
|
1870
|
+
name: 'Alpha',
|
|
1871
|
+
color: 'BLUE' as const,
|
|
1872
|
+
description: '',
|
|
1873
|
+
},
|
|
1874
|
+
{
|
|
1875
|
+
id: 'opt_gray',
|
|
1876
|
+
name: 'Archived',
|
|
1877
|
+
color: 'GRAY' as const,
|
|
1878
|
+
description: '',
|
|
1879
|
+
},
|
|
1880
|
+
{
|
|
1881
|
+
id: 'opt_b',
|
|
1882
|
+
name: 'Beta',
|
|
1883
|
+
color: 'GREEN' as const,
|
|
1884
|
+
description: '',
|
|
1885
|
+
},
|
|
1886
|
+
],
|
|
1887
|
+
workflowManagementStory: { id: 'wms', name: 'workflow' },
|
|
1888
|
+
},
|
|
1889
|
+
};
|
|
1890
|
+
const updateStoryList = jest.fn().mockResolvedValue([]);
|
|
1891
|
+
const response = await handleReorderStory(
|
|
1892
|
+
contextWithUpdateStoryList(updateStoryList, projectWithGray),
|
|
1893
|
+
{
|
|
1894
|
+
pjcode: 'acme',
|
|
1895
|
+
storyOptionId: 'opt_b',
|
|
1896
|
+
direction: 'up',
|
|
1897
|
+
},
|
|
1898
|
+
);
|
|
1899
|
+
expect(response).toEqual({ statusCode: 200, body: { ok: true } });
|
|
1900
|
+
expect(updateStoryList).toHaveBeenCalledWith(
|
|
1901
|
+
expect.objectContaining({ id: projectWithGray.id }),
|
|
1902
|
+
[
|
|
1903
|
+
expect.objectContaining({ id: 'opt_a' }),
|
|
1904
|
+
expect.objectContaining({ id: 'opt_b' }),
|
|
1905
|
+
expect.objectContaining({ id: 'opt_gray' }),
|
|
1906
|
+
],
|
|
1907
|
+
);
|
|
1908
|
+
});
|
|
1909
|
+
});
|
|
1680
1910
|
});
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
PullRequestReviewCommentSide,
|
|
4
4
|
} from '../../../domain/usecases/adapter-interfaces/IssueRepository';
|
|
5
5
|
import { IssueAttachmentRepository } from '../../../domain/usecases/adapter-interfaces/IssueAttachmentRepository';
|
|
6
|
-
import { Project } from '../../../domain/entities/Project';
|
|
6
|
+
import { FieldOption, Project } from '../../../domain/entities/Project';
|
|
7
7
|
import { Issue } from '../../../domain/entities/Issue';
|
|
8
8
|
import {
|
|
9
9
|
recordDoneProjectItemIdAcrossTabs,
|
|
@@ -38,6 +38,9 @@ export type ConsoleOperationContext = {
|
|
|
38
38
|
isPjcodeConfigured: ConsolePjcodeValidator;
|
|
39
39
|
consoleDataOutputDir: string | null;
|
|
40
40
|
issueAttachmentRepository: IssueAttachmentRepository | null;
|
|
41
|
+
updateStoryList:
|
|
42
|
+
| ((project: Project, stories: FieldOption[]) => Promise<FieldOption[]>)
|
|
43
|
+
| null;
|
|
41
44
|
};
|
|
42
45
|
|
|
43
46
|
export type ConsoleOperationResponse = {
|
|
@@ -722,3 +725,47 @@ export const handleIntmux = async (
|
|
|
722
725
|
recordDoneForStatusChange(context, pjcode, projectItemId);
|
|
723
726
|
return ok();
|
|
724
727
|
};
|
|
728
|
+
|
|
729
|
+
export const handleReorderStory = async (
|
|
730
|
+
context: ConsoleOperationContext,
|
|
731
|
+
body: Record<string, unknown>,
|
|
732
|
+
): Promise<ConsoleOperationResponse> => {
|
|
733
|
+
const pjcode = body.pjcode;
|
|
734
|
+
const storyOptionId = body.storyOptionId;
|
|
735
|
+
const direction = body.direction;
|
|
736
|
+
if (!isNonEmptyString(pjcode)) {
|
|
737
|
+
return badRequest('pjcode is required');
|
|
738
|
+
}
|
|
739
|
+
if (!isNonEmptyString(storyOptionId)) {
|
|
740
|
+
return badRequest('storyOptionId is required');
|
|
741
|
+
}
|
|
742
|
+
if (direction !== 'up' && direction !== 'down') {
|
|
743
|
+
return badRequest('direction must be "up" or "down"');
|
|
744
|
+
}
|
|
745
|
+
const binding = await context.resolveProject(pjcode);
|
|
746
|
+
if (binding === null) {
|
|
747
|
+
return badRequest(`no project configured for pjcode "${pjcode}"`);
|
|
748
|
+
}
|
|
749
|
+
const { project } = binding;
|
|
750
|
+
if (project.story === null) {
|
|
751
|
+
return badRequest('project does not have a story field');
|
|
752
|
+
}
|
|
753
|
+
if (context.updateStoryList === null) {
|
|
754
|
+
return badRequest('updateStoryList is not configured');
|
|
755
|
+
}
|
|
756
|
+
const stories = project.story.stories;
|
|
757
|
+
const index = stories.findIndex((s) => s.id === storyOptionId);
|
|
758
|
+
if (index === -1) {
|
|
759
|
+
return badRequest('story option not found');
|
|
760
|
+
}
|
|
761
|
+
const swapIndex = index + (direction === 'up' ? -1 : 1);
|
|
762
|
+
if (swapIndex < 0 || swapIndex >= stories.length) {
|
|
763
|
+
return badRequest('cannot move in that direction');
|
|
764
|
+
}
|
|
765
|
+
const reordered = [...stories];
|
|
766
|
+
const temp = reordered[index];
|
|
767
|
+
reordered[index] = reordered[swapIndex];
|
|
768
|
+
reordered[swapIndex] = temp;
|
|
769
|
+
await context.updateStoryList(project, reordered);
|
|
770
|
+
return ok();
|
|
771
|
+
};
|
|
@@ -395,3 +395,39 @@ test('creates an issue for a story when the add-task button and form are used',
|
|
|
395
395
|
'npm-cli-github-issue-tower-defence-management',
|
|
396
396
|
);
|
|
397
397
|
});
|
|
398
|
+
|
|
399
|
+
test('reorders stories on the triage tab with up/down buttons', async ({
|
|
400
|
+
page,
|
|
401
|
+
}) => {
|
|
402
|
+
await page.goto(harness.appRootUrl);
|
|
403
|
+
|
|
404
|
+
await tabByLabel(page, 'Triage').click();
|
|
405
|
+
|
|
406
|
+
const reorderPanel = page.locator('.console-story-reorder-panel');
|
|
407
|
+
await expect(reorderPanel).toBeVisible();
|
|
408
|
+
|
|
409
|
+
const rows = reorderPanel.locator('.console-story-reorder-row');
|
|
410
|
+
await expect(rows).toHaveCount(3);
|
|
411
|
+
|
|
412
|
+
await expect(rows.nth(0)).toContainText('TDPM Console port');
|
|
413
|
+
await expect(rows.nth(1)).toContainText('Publish product documentation site');
|
|
414
|
+
await expect(rows.nth(2)).toContainText('regular / WORKFLOW BLOCKER');
|
|
415
|
+
|
|
416
|
+
await rows.nth(0).locator('[aria-label="Move down"]').click();
|
|
417
|
+
|
|
418
|
+
await expect
|
|
419
|
+
.poll(() => harness.reorderStoryCalls.length, { timeout: 5000 })
|
|
420
|
+
.toBe(1);
|
|
421
|
+
|
|
422
|
+
await expect(rows.nth(0)).toContainText('Publish product documentation site');
|
|
423
|
+
await expect(rows.nth(1)).toContainText('TDPM Console port');
|
|
424
|
+
|
|
425
|
+
await rows.nth(1).locator('[aria-label="Move up"]').click();
|
|
426
|
+
|
|
427
|
+
await expect
|
|
428
|
+
.poll(() => harness.reorderStoryCalls.length, { timeout: 5000 })
|
|
429
|
+
.toBe(2);
|
|
430
|
+
|
|
431
|
+
await expect(rows.nth(0)).toContainText('TDPM Console port');
|
|
432
|
+
await expect(rows.nth(1)).toContainText('Publish product documentation site');
|
|
433
|
+
});
|
|
@@ -3,7 +3,10 @@ import type * as http from 'node:http';
|
|
|
3
3
|
import * as os from 'node:os';
|
|
4
4
|
import * as path from 'node:path';
|
|
5
5
|
import type { Issue } from '../../../../../domain/entities/Issue';
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
FieldOption,
|
|
8
|
+
Project,
|
|
9
|
+
} from '../../../../../domain/entities/Project';
|
|
7
10
|
import type {
|
|
8
11
|
IssueComment,
|
|
9
12
|
IssueRepository,
|
|
@@ -611,6 +614,10 @@ const createStubIssueRepository = (
|
|
|
611
614
|
setIssueAgentField: async (): Promise<void> => undefined,
|
|
612
615
|
});
|
|
613
616
|
|
|
617
|
+
export type ConsoleE2eReorderStoryCall = {
|
|
618
|
+
storyOptionIds: string[];
|
|
619
|
+
};
|
|
620
|
+
|
|
614
621
|
export type ConsoleE2eHarness = {
|
|
615
622
|
baseUrl: string;
|
|
616
623
|
appUrl: string;
|
|
@@ -619,6 +626,7 @@ export type ConsoleE2eHarness = {
|
|
|
619
626
|
reviewCommentCalls: ConsoleE2eReviewCommentCall[];
|
|
620
627
|
requestChangesCalls: ConsoleE2eRequestChangesCall[];
|
|
621
628
|
createIssueCalls: ConsoleE2eCreateIssueCall[];
|
|
629
|
+
reorderStoryCalls: ConsoleE2eReorderStoryCall[];
|
|
622
630
|
stop: () => Promise<void>;
|
|
623
631
|
};
|
|
624
632
|
|
|
@@ -640,6 +648,7 @@ export const startConsoleE2eHarness = async (): Promise<ConsoleE2eHarness> => {
|
|
|
640
648
|
const reviewCommentCalls: ConsoleE2eReviewCommentCall[] = [];
|
|
641
649
|
const requestChangesCalls: ConsoleE2eRequestChangesCall[] = [];
|
|
642
650
|
const createIssueCalls: ConsoleE2eCreateIssueCall[] = [];
|
|
651
|
+
const reorderStoryCalls: ConsoleE2eReorderStoryCall[] = [];
|
|
643
652
|
|
|
644
653
|
const server = await startWebServer({
|
|
645
654
|
accessToken: CONSOLE_E2E_TOKEN,
|
|
@@ -650,6 +659,20 @@ export const startConsoleE2eHarness = async (): Promise<ConsoleE2eHarness> => {
|
|
|
650
659
|
requestChangesCalls,
|
|
651
660
|
createIssueCalls,
|
|
652
661
|
),
|
|
662
|
+
projectRepository: {
|
|
663
|
+
updateStoryList: async (_updatedProject, stories) => {
|
|
664
|
+
reorderStoryCalls.push({
|
|
665
|
+
storyOptionIds: stories
|
|
666
|
+
.map((s) => s.id)
|
|
667
|
+
.filter((id): id is string => id !== null),
|
|
668
|
+
});
|
|
669
|
+
const result = stories as FieldOption[];
|
|
670
|
+
if (project.story !== null) {
|
|
671
|
+
project.story.stories = result;
|
|
672
|
+
}
|
|
673
|
+
return result;
|
|
674
|
+
},
|
|
675
|
+
},
|
|
653
676
|
resolveProject,
|
|
654
677
|
isPjcodeConfigured,
|
|
655
678
|
issueTitleStateCache: new IssueTitleStateCache(),
|
|
@@ -679,6 +702,7 @@ export const startConsoleE2eHarness = async (): Promise<ConsoleE2eHarness> => {
|
|
|
679
702
|
reviewCommentCalls,
|
|
680
703
|
requestChangesCalls,
|
|
681
704
|
createIssueCalls,
|
|
705
|
+
reorderStoryCalls,
|
|
682
706
|
stop: async (): Promise<void> => {
|
|
683
707
|
await closeServer(server);
|
|
684
708
|
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { ConsoleStoryReorderPanel } from './ConsoleStoryReorderPanel';
|
|
3
|
+
|
|
4
|
+
const stories = [
|
|
5
|
+
{ id: '1491051e', name: 'TDPM Console port', color: 'BLUE' as const },
|
|
6
|
+
{
|
|
7
|
+
id: 'f7cd5cbc',
|
|
8
|
+
name: 'Publish product documentation site',
|
|
9
|
+
color: 'GREEN' as const,
|
|
10
|
+
},
|
|
11
|
+
{ id: 'a3b9c4d2', name: 'regular / WORKFLOW BLOCKER', color: 'RED' as const },
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
const meta: Meta<typeof ConsoleStoryReorderPanel> = {
|
|
15
|
+
title: 'Console/ConsoleStoryReorderPanel',
|
|
16
|
+
component: ConsoleStoryReorderPanel,
|
|
17
|
+
args: { onReorderStory: () => Promise.resolve() },
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export default meta;
|
|
21
|
+
|
|
22
|
+
type Story = StoryObj<typeof ConsoleStoryReorderPanel>;
|
|
23
|
+
|
|
24
|
+
export const Default: Story = {
|
|
25
|
+
args: { stories },
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const SingleStory: Story = {
|
|
29
|
+
args: { stories: [stories[0]] },
|
|
30
|
+
};
|