pipe-kan 0.12.0 → 0.13.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/README.md +1 -1
- package/dist/pipe-kan.js +51 -14
- package/dist/ui/assets/index-DufySLnq.js +55 -0
- package/dist/ui/assets/index-DwlD3Xdl.css +2 -0
- package/dist/ui/index.html +2 -2
- package/package.json +1 -1
- package/dist/ui/assets/index-BIl78HJ0.js +0 -55
- package/dist/ui/assets/index-Cnla0OoQ.css +0 -2
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ First paint is the Fixture. If `jira` is on PATH, the process then Refresh-es fr
|
|
|
16
16
|
|
|
17
17
|
The published CLI is on npm. From a clone: `bun run build && bun dist/pipe-kan.js`.
|
|
18
18
|
|
|
19
|
-
- Left:
|
|
19
|
+
- Left: All stories and All epics. Center: Cards (one Column per status in the payload). Right: Open URL; remote Jira is a link, not an iframe.
|
|
20
20
|
- Drop a Card on a Column to Move (`jira issue move`).
|
|
21
21
|
- Same-Column drop and column reorder do nothing.
|
|
22
22
|
- Theme is stored in `localStorage`.
|
package/dist/pipe-kan.js
CHANGED
|
@@ -27,15 +27,27 @@ function issueType(fields) {
|
|
|
27
27
|
const name = fields?.issuetype?.name ?? fields?.issueType?.name;
|
|
28
28
|
return typeof name === "string" ? name : undefined;
|
|
29
29
|
}
|
|
30
|
+
function asIssueKey(value) {
|
|
31
|
+
if (typeof value === "string") {
|
|
32
|
+
const key = value.trim();
|
|
33
|
+
return /^[A-Za-z][A-Za-z0-9_]*-\d+$/.test(key) ? key : undefined;
|
|
34
|
+
}
|
|
35
|
+
if (value && typeof value === "object" && "key" in value) {
|
|
36
|
+
return asIssueKey(value.key);
|
|
37
|
+
}
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
30
40
|
function epicKey(fields) {
|
|
31
|
-
if (
|
|
32
|
-
return
|
|
33
|
-
const
|
|
34
|
-
if (
|
|
35
|
-
return
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
if (!fields)
|
|
42
|
+
return;
|
|
43
|
+
const named = asIssueKey(fields.parent) ?? asIssueKey(fields.parentEpic) ?? asIssueKey(fields["Epic Link"]);
|
|
44
|
+
if (named)
|
|
45
|
+
return named;
|
|
46
|
+
for (const [name, value] of Object.entries(fields)) {
|
|
47
|
+
if (!name.startsWith("customfield_"))
|
|
48
|
+
continue;
|
|
49
|
+
const key = asIssueKey(value);
|
|
50
|
+
if (key)
|
|
39
51
|
return key;
|
|
40
52
|
}
|
|
41
53
|
return;
|
|
@@ -345,7 +357,7 @@ function createJiraCli(opts = {}) {
|
|
|
345
357
|
"issue",
|
|
346
358
|
"list",
|
|
347
359
|
"-q",
|
|
348
|
-
`parent="${key}" OR "Epic Link"="${key}"`,
|
|
360
|
+
`(parent="${key}" OR "Epic Link"="${key}")`,
|
|
349
361
|
"--raw"
|
|
350
362
|
]);
|
|
351
363
|
if (result.code !== 0) {
|
|
@@ -364,7 +376,7 @@ function createJiraCli(opts = {}) {
|
|
|
364
376
|
"issue",
|
|
365
377
|
"list",
|
|
366
378
|
"-q",
|
|
367
|
-
`parent in (${list}) OR "Epic Link" in (${list})`,
|
|
379
|
+
`(parent in (${list}) OR "Epic Link" in (${list}))`,
|
|
368
380
|
"--raw"
|
|
369
381
|
]);
|
|
370
382
|
if (result.code !== 0) {
|
|
@@ -550,6 +562,24 @@ function stampMissingEpic(board, epic) {
|
|
|
550
562
|
}
|
|
551
563
|
return board;
|
|
552
564
|
}
|
|
565
|
+
function stampRawParent(raw, epic) {
|
|
566
|
+
if (!Array.isArray(raw))
|
|
567
|
+
return [];
|
|
568
|
+
return raw.map((issue) => {
|
|
569
|
+
if (!issue || typeof issue !== "object")
|
|
570
|
+
return issue;
|
|
571
|
+
const current = issue;
|
|
572
|
+
const fields = current.fields;
|
|
573
|
+
if (!fields || typeof fields !== "object" || fields.parent)
|
|
574
|
+
return issue;
|
|
575
|
+
return { ...current, fields: { ...fields, parent: { key: epic } } };
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
function cardsOf(raw) {
|
|
579
|
+
if (!Array.isArray(raw))
|
|
580
|
+
return [];
|
|
581
|
+
return issuesToBoard(raw).columns.flatMap((column) => column.cards);
|
|
582
|
+
}
|
|
553
583
|
function createApp(opts) {
|
|
554
584
|
const cli = opts.cli ?? createStoreCli(opts.store);
|
|
555
585
|
let flags = DEFAULT_FLAGS;
|
|
@@ -603,6 +633,14 @@ function createApp(opts) {
|
|
|
603
633
|
const keys = listedEpicKeys();
|
|
604
634
|
try {
|
|
605
635
|
childrenRaw = JSON.parse(await cli.listChildren(keys));
|
|
636
|
+
const cards = cardsOf(childrenRaw);
|
|
637
|
+
if (cards.length > 0 && !cards.some((card) => card.epic)) {
|
|
638
|
+
const stamped = [];
|
|
639
|
+
for (const key of keys) {
|
|
640
|
+
stamped.push(...stampRawParent(JSON.parse(await cli.listEpic(key)), key));
|
|
641
|
+
}
|
|
642
|
+
childrenRaw = stamped;
|
|
643
|
+
}
|
|
606
644
|
hasChildrenCache = true;
|
|
607
645
|
} catch (err) {
|
|
608
646
|
hasChildrenCache = false;
|
|
@@ -620,10 +658,9 @@ function createApp(opts) {
|
|
|
620
658
|
epic: card.epic ?? epic
|
|
621
659
|
}))
|
|
622
660
|
]));
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
epics: []
|
|
626
|
-
};
|
|
661
|
+
const columns = Object.entries(cards).filter(([, list]) => list.length).map(([title, list]) => ({ id: title, title, cards: list }));
|
|
662
|
+
if (columns.length)
|
|
663
|
+
return { columns, epics: [] };
|
|
627
664
|
}
|
|
628
665
|
return stampMissingEpic(issuesToBoard(JSON.parse(await cli.listEpic(epic))), epic);
|
|
629
666
|
},
|