@kud/jira-ink 0.1.0 → 0.2.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/dist/index.d.ts +23 -2
- package/dist/index.js +52 -28
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { MarkdownTheme } from '@kud/ink-markdown';
|
|
4
|
+
import { Hint } from '@kud/ink-ui';
|
|
2
5
|
import { LocatedAttachment, JiraClient } from '@kud/jira';
|
|
3
6
|
|
|
4
7
|
/**
|
|
@@ -53,8 +56,23 @@ type IssueDetailViewProps = {
|
|
|
53
56
|
onComment?: () => void;
|
|
54
57
|
onAssign?: () => void;
|
|
55
58
|
onOpenBrowser?: () => void;
|
|
59
|
+
/**
|
|
60
|
+
* A host that draws its own chrome — a bordered drill frame with the title
|
|
61
|
+
* on top and the hints pinned at the foot — takes the screen in parts and
|
|
62
|
+
* places them. The view then draws neither its title line nor its footer,
|
|
63
|
+
* so nothing appears twice. `height` is still the whole area the host has
|
|
64
|
+
* given the body, frame excluded.
|
|
65
|
+
*/
|
|
66
|
+
frame?: (parts: {
|
|
67
|
+
title: string;
|
|
68
|
+
subtitle: string;
|
|
69
|
+
hints: Hint[];
|
|
70
|
+
body: ReactNode;
|
|
71
|
+
}) => ReactNode;
|
|
72
|
+
/** Colours for the Markdown body; a host passes its own tokens so links, code and headings sit in its palette. */
|
|
73
|
+
theme?: MarkdownTheme;
|
|
56
74
|
};
|
|
57
|
-
declare const IssueDetailView: ({ issue, height, width, onBack, onTransition, onComment, onAssign, onOpenBrowser, }: IssueDetailViewProps) => react.JSX.Element;
|
|
75
|
+
declare const IssueDetailView: ({ issue, height, width, onBack, onTransition, onComment, onAssign, onOpenBrowser, frame, theme, }: IssueDetailViewProps) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react.JSX.Element | null | undefined;
|
|
58
76
|
|
|
59
77
|
type IssueBodyProps = {
|
|
60
78
|
client: JiraClient;
|
|
@@ -65,6 +83,9 @@ type IssueBodyProps = {
|
|
|
65
83
|
/** Override the terminal-derived size when the host draws inside a frame. */
|
|
66
84
|
width?: number;
|
|
67
85
|
height?: number;
|
|
86
|
+
/** The host's chrome around the screen — see `IssueDetailView`. */
|
|
87
|
+
frame?: IssueDetailViewProps["frame"];
|
|
88
|
+
theme?: IssueDetailViewProps["theme"];
|
|
68
89
|
};
|
|
69
90
|
/**
|
|
70
91
|
* The issue screen as a host mounts it: hand it a client and a key, and it
|
|
@@ -76,6 +97,6 @@ type IssueBodyProps = {
|
|
|
76
97
|
* `IssueDetailView` for jira-cli's own TUI, which owns the prompts they need;
|
|
77
98
|
* here they are simply not wired, so the hint row does not offer them.
|
|
78
99
|
*/
|
|
79
|
-
declare const IssueBody: ({ client, baseUrl, issueKey, onExit, width, height, }: IssueBodyProps) => react.JSX.Element;
|
|
100
|
+
declare const IssueBody: ({ client, baseUrl, issueKey, onExit, width, height, frame, theme, }: IssueBodyProps) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react.JSX.Element | null | undefined;
|
|
80
101
|
|
|
81
102
|
export { IssueBody, type IssueBodyProps, type IssueDetail, IssueDetailView, type IssueDetailViewProps, type Transition, issueDetailOf, transitionsOf };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MarkdownViewport } from '@kud/ink-markdown';
|
|
2
|
-
import { useTabs, KeyValue, Badge, Tabs, FooterHints,
|
|
2
|
+
import { useTabs, KeyValue, Badge, Tabs, FooterHints, StatusMessage, LoadingScreen } from '@kud/ink-ui';
|
|
3
3
|
import { useInput, Box, Text, useStdout } from 'ink';
|
|
4
4
|
import { useState, useEffect } from 'react';
|
|
5
5
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
@@ -36,7 +36,9 @@ var IssueDetailView = ({
|
|
|
36
36
|
onTransition,
|
|
37
37
|
onComment,
|
|
38
38
|
onAssign,
|
|
39
|
-
onOpenBrowser
|
|
39
|
+
onOpenBrowser,
|
|
40
|
+
frame,
|
|
41
|
+
theme
|
|
40
42
|
}) => {
|
|
41
43
|
const tabs = [
|
|
42
44
|
{ value: "description", label: "Description" },
|
|
@@ -50,7 +52,7 @@ var IssueDetailView = ({
|
|
|
50
52
|
const { active } = useTabs(tabs, { initial: "description" });
|
|
51
53
|
const [scroll, setScroll] = useState(0);
|
|
52
54
|
useInput((input, key) => {
|
|
53
|
-
if (key.escape
|
|
55
|
+
if (key.escape) return onBack();
|
|
54
56
|
if (input === "t" && onTransition) return onTransition();
|
|
55
57
|
if (input === "c" && onComment) return onComment();
|
|
56
58
|
if (input === "a" && onAssign) return onAssign();
|
|
@@ -59,7 +61,8 @@ var IssueDetailView = ({
|
|
|
59
61
|
if (key.upArrow || input === "k") setScroll((s) => Math.max(0, s - 1));
|
|
60
62
|
});
|
|
61
63
|
const source = active === "comments" ? commentsAsMarkdown(issue) : active === "attachments" ? attachmentsAsMarkdown(issue) : issue.description || "_No description._";
|
|
62
|
-
const
|
|
64
|
+
const chromeLines = frame ? 8 : 12;
|
|
65
|
+
const bodyHeight = Math.max(3, height - chromeLines);
|
|
63
66
|
const hints = [
|
|
64
67
|
["\u2190\u2192", "section"],
|
|
65
68
|
["\u2191\u2193", "scroll"],
|
|
@@ -69,13 +72,8 @@ var IssueDetailView = ({
|
|
|
69
72
|
...onOpenBrowser ? [["o", "browser"]] : [],
|
|
70
73
|
["esc", "back"]
|
|
71
74
|
];
|
|
72
|
-
|
|
73
|
-
/* @__PURE__ */ jsxs(
|
|
74
|
-
issue.key,
|
|
75
|
-
" ",
|
|
76
|
-
issue.summary
|
|
77
|
-
] }),
|
|
78
|
-
/* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
|
|
75
|
+
const body = /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
76
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
79
77
|
issue.parent && /* @__PURE__ */ jsx(
|
|
80
78
|
KeyValue,
|
|
81
79
|
{
|
|
@@ -84,7 +82,7 @@ var IssueDetailView = ({
|
|
|
84
82
|
}
|
|
85
83
|
),
|
|
86
84
|
/* @__PURE__ */ jsx(KeyValue, { label: "status", value: /* @__PURE__ */ jsx(Badge, { children: issue.status }) }),
|
|
87
|
-
/* @__PURE__ */ jsx(KeyValue, { label: "type", value: issue.type }),
|
|
85
|
+
frame ? null : /* @__PURE__ */ jsx(KeyValue, { label: "type", value: issue.type }),
|
|
88
86
|
/* @__PURE__ */ jsx(KeyValue, { label: "assignee", value: issue.assignee }),
|
|
89
87
|
/* @__PURE__ */ jsx(KeyValue, { label: "reporter", value: issue.reporter }),
|
|
90
88
|
issue.labels.length > 0 && /* @__PURE__ */ jsx(KeyValue, { label: "labels", value: issue.labels.join(", ") })
|
|
@@ -96,9 +94,25 @@ var IssueDetailView = ({
|
|
|
96
94
|
source,
|
|
97
95
|
width: Math.max(20, width - 2),
|
|
98
96
|
height: bodyHeight,
|
|
99
|
-
scrollOffset: scroll
|
|
97
|
+
scrollOffset: scroll,
|
|
98
|
+
theme
|
|
100
99
|
}
|
|
101
|
-
) })
|
|
100
|
+
) })
|
|
101
|
+
] });
|
|
102
|
+
if (frame)
|
|
103
|
+
return frame({
|
|
104
|
+
title: `${issue.key} \xB7 ${issue.type}`,
|
|
105
|
+
subtitle: issue.summary,
|
|
106
|
+
hints,
|
|
107
|
+
body
|
|
108
|
+
});
|
|
109
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
110
|
+
/* @__PURE__ */ jsxs(Text, { bold: true, children: [
|
|
111
|
+
issue.key,
|
|
112
|
+
" ",
|
|
113
|
+
issue.summary
|
|
114
|
+
] }),
|
|
115
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: body }),
|
|
102
116
|
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(FooterHints, { hints }) })
|
|
103
117
|
] });
|
|
104
118
|
};
|
|
@@ -157,7 +171,9 @@ var IssueBody = ({
|
|
|
157
171
|
issueKey,
|
|
158
172
|
onExit,
|
|
159
173
|
width,
|
|
160
|
-
height
|
|
174
|
+
height,
|
|
175
|
+
frame,
|
|
176
|
+
theme
|
|
161
177
|
}) => {
|
|
162
178
|
const term = useTermSize();
|
|
163
179
|
const [state, setState] = useState({ phase: "loading" });
|
|
@@ -174,20 +190,26 @@ var IssueBody = ({
|
|
|
174
190
|
live = false;
|
|
175
191
|
};
|
|
176
192
|
}, [client, baseUrl, issueKey]);
|
|
177
|
-
useInput(
|
|
178
|
-
(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
193
|
+
useInput((input, key) => {
|
|
194
|
+
if (input === "q") return onExit();
|
|
195
|
+
if (key.escape && state.phase !== "ready") onExit();
|
|
196
|
+
});
|
|
197
|
+
const framed = (body) => frame ? frame({
|
|
198
|
+
title: issueKey,
|
|
199
|
+
subtitle: "",
|
|
200
|
+
hints: [["esc", "back"]],
|
|
201
|
+
body
|
|
202
|
+
}) : body;
|
|
183
203
|
if (state.phase === "loading")
|
|
184
|
-
return /* @__PURE__ */ jsx(LoadingScreen, { label: `Loading ${issueKey}\u2026` });
|
|
204
|
+
return framed(/* @__PURE__ */ jsx(LoadingScreen, { label: `Loading ${issueKey}\u2026` }));
|
|
185
205
|
if (state.phase === "error")
|
|
186
|
-
return
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
206
|
+
return framed(
|
|
207
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: /* @__PURE__ */ jsxs(StatusMessage, { variant: "error", children: [
|
|
208
|
+
issueKey,
|
|
209
|
+
": ",
|
|
210
|
+
state.message
|
|
211
|
+
] }) })
|
|
212
|
+
);
|
|
191
213
|
return /* @__PURE__ */ jsx(
|
|
192
214
|
IssueDetailView,
|
|
193
215
|
{
|
|
@@ -195,7 +217,9 @@ var IssueBody = ({
|
|
|
195
217
|
width: width ?? term.cols,
|
|
196
218
|
height: height ?? term.rows,
|
|
197
219
|
onBack: onExit,
|
|
198
|
-
onOpenBrowser: () => openInBrowser(state.issue.url)
|
|
220
|
+
onOpenBrowser: () => openInBrowser(state.issue.url),
|
|
221
|
+
frame,
|
|
222
|
+
theme
|
|
199
223
|
}
|
|
200
224
|
);
|
|
201
225
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kud/jira-ink",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Ink components for viewing Jira issues: the issue detail screen, shared by jira-cli's TUI and cockpit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@kud/ink-ui": "0.25.0",
|
|
33
|
-
"@kud/ink-markdown": "0.
|
|
33
|
+
"@kud/ink-markdown": "0.3.0",
|
|
34
34
|
"@kud/jira": "0.3.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|