jira-dashboard 0.1.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/README.md +219 -0
- package/dist/cli.js +1347 -0
- package/dist/cli.js.map +7 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# jira-dashboard (`jdb`)
|
|
2
|
+
|
|
3
|
+
A full-screen terminal dashboard for Jira Cloud, built with [Ink](https://github.com/vadimdemedes/ink).
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
┌─ last 14 days · 41.5h total ──────┬─ my open tickets (3/12) ─────────────────┐
|
|
7
|
+
│ Tue 28 Jul 7.5h MR-4 │ ▸ MR-3 In Review Fix the flaky test │
|
|
8
|
+
│ Wed 29 Jul 6.0h MR-1, MR-2 │ MR-4 In Progress Add worklog panel │
|
|
9
|
+
├───────────────────────────────────┴──────────────────────────────────────────┤
|
|
10
|
+
│ MR-3 · 5.5h over 14d · 4h = 1 bar │ MR-3 · .../browse/MR-3 │
|
|
11
|
+
│ │ Platform › MR-100 Q3 push › MR-3 │
|
|
12
|
+
│ ██ ██ │ Fix the flaky test │
|
|
13
|
+
│ ▄▄ ██ ▄▄ ██ ██ │ type Bug │
|
|
14
|
+
│ 16 17 18 19 20 21 22 … │ status In Review │
|
|
15
|
+
└───────────────────────────────────┴──────────────────────────────────────────┘
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- **Top left** — hours you logged on each of the last 14 days (oldest first, so today is at the
|
|
19
|
+
bottom), plus the issues you logged against.
|
|
20
|
+
- **Top right** — your open tickets (not done, not cancelled/closed, not in the backlog), selectable
|
|
21
|
+
by keyboard or mouse.
|
|
22
|
+
- **Bottom left** — bar chart of the hours *you* logged on the **selected** ticket, day by day over
|
|
23
|
+
the same 14 days. The scale is fixed so bars are comparable between tickets and between runs: 2h is
|
|
24
|
+
half a row, 4h one row, 8h two rows; anything logged below 2h gets a thin mark so it stays visible.
|
|
25
|
+
- **Bottom right** — preview of the selected ticket: parent breadcrumbs, status, assignee, reporter,
|
|
26
|
+
priority, labels, the hours *you* logged and on which dates, total logged by everyone, and the
|
|
27
|
+
description.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
npm install -g jira-dashboard
|
|
33
|
+
jdb
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Configure
|
|
37
|
+
|
|
38
|
+
Everything comes from the Jira Cloud REST API, authenticated with an
|
|
39
|
+
[API token](https://id.atlassian.com/manage-profile/security/api-tokens).
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
export JIRA_BASE_URL="https://your-team.atlassian.net"
|
|
43
|
+
export JIRA_EMAIL="you@example.com"
|
|
44
|
+
export JIRA_API_TOKEN="…"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or write `~/.config/jira-dashboard/config.json` (environment variables win):
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"baseUrl": "https://your-team.atlassian.net",
|
|
52
|
+
"email": "you@example.com",
|
|
53
|
+
"apiToken": "…",
|
|
54
|
+
"issuesJql": "assignee = currentUser() AND statusCategory != Done AND status NOT IN (\"Cancelled\", \"Closed\", \"Backlog\") ORDER BY updated DESC",
|
|
55
|
+
"worklogDays": 14
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`issuesJql` is worth customising: status names vary per site, and some boards model the backlog
|
|
60
|
+
by sprint rather than by status — in that case append `AND sprint IS NOT EMPTY`.
|
|
61
|
+
|
|
62
|
+
## Keys
|
|
63
|
+
|
|
64
|
+
| Key | Action |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| `↑` `↓` / `j` `k` | Move within the focused panel |
|
|
67
|
+
| `Enter` | Open the selected ticket in your default browser (tickets panel only) |
|
|
68
|
+
| `PgUp` `PgDn` | Page through the focused panel |
|
|
69
|
+
| `Home` / `End` | Jump to the first / last item in the focused panel |
|
|
70
|
+
| `g` / `G` | Jump to first / last ticket |
|
|
71
|
+
| `Tab` / `Shift+Tab` | Cycle panels (worklogs → tickets → preview) |
|
|
72
|
+
| Click | Select a ticket / focus a panel |
|
|
73
|
+
| Wheel | Scroll the panel under the cursor |
|
|
74
|
+
| `r` | Reload both panels |
|
|
75
|
+
| `q` / `Esc` / `Ctrl+C` | Quit |
|
|
76
|
+
|
|
77
|
+
## Development
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
npm install
|
|
81
|
+
npm run dev # run from TypeScript source, no build step
|
|
82
|
+
npm run build # bundle to dist/cli.js with esbuild
|
|
83
|
+
npm run typecheck # tsc --noEmit
|
|
84
|
+
npm run check # lint + typecheck + build; run before publishing
|
|
85
|
+
npm run lint
|
|
86
|
+
npm run lint:fix
|
|
87
|
+
npm run lint:staged # lint-staged, for a pre-commit hook
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
To run `lint:staged` automatically, add a `pre-commit` hook that calls `npm run lint:staged`.
|
|
91
|
+
|
|
92
|
+
### Build
|
|
93
|
+
|
|
94
|
+
`npm run build` bundles `src/cli.tsx` into a single ESM file at `dist/cli.js` and marks it
|
|
95
|
+
executable. The shebang from the entry file is preserved, which is what lets `jdb` run directly.
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
npm run build
|
|
99
|
+
node dist/cli.js --version
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Two properties of the bundle worth knowing:
|
|
103
|
+
|
|
104
|
+
- **Relative imports are written without a `.js` extension.** Node's ESM loader would reject that,
|
|
105
|
+
but esbuild resolves the specifiers at build time and `tsx` does the same in dev. `tsc` is
|
|
106
|
+
typecheck-only (`noEmit`), so it can never emit an unresolvable import.
|
|
107
|
+
- **Runtime dependencies stay external** (`--packages=external`), so only this project's own source
|
|
108
|
+
is bundled; `ink` and `react` are installed normally from `dependencies`.
|
|
109
|
+
|
|
110
|
+
`prepublishOnly` runs `npm run check`, so a publish rebuilds `dist/` and aborts on a lint or type
|
|
111
|
+
error rather than shipping one.
|
|
112
|
+
|
|
113
|
+
### Run it locally as a global command
|
|
114
|
+
|
|
115
|
+
For day-to-day use, symlink the global `jdb` at your working copy:
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
npm link # jdb -> <this repo>/dist/cli.js
|
|
119
|
+
npm run build # after each source change; jdb picks it up immediately
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
To test what users actually get instead — a frozen copy built from the real tarball:
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
npm pack
|
|
126
|
+
npm install -g ./jira-dashboard-0.1.0.tgz
|
|
127
|
+
jdb --version
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Undo either with `npm uninstall -g jira-dashboard` (or `npm unlink -g jira-dashboard`).
|
|
131
|
+
|
|
132
|
+
### Debugging
|
|
133
|
+
|
|
134
|
+
**Never use `console.log`.** Stdout is the UI: writing to it corrupts the frame Ink is drawing.
|
|
135
|
+
Log to stderr and redirect it to a file, then watch that file from another terminal:
|
|
136
|
+
|
|
137
|
+
```sh
|
|
138
|
+
# in the code: process.stderr.write(`selected=${key}\n`);
|
|
139
|
+
jdb 2> /tmp/jdb.log
|
|
140
|
+
tail -f /tmp/jdb.log # in a second terminal
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Readable stack traces.** `dist/cli.js` is a bundle, so traces point at bundle offsets by default.
|
|
144
|
+
The build emits a source map; turn it on to get original file and line numbers:
|
|
145
|
+
|
|
146
|
+
```sh
|
|
147
|
+
node --enable-source-maps dist/cli.js
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Breakpoints.** Attach a debugger and open `chrome://inspect`, or use your editor's Node attach
|
|
151
|
+
config. Run from source so you are stepping through TypeScript rather than the bundle:
|
|
152
|
+
|
|
153
|
+
```sh
|
|
154
|
+
node --inspect-brk --import tsx src/cli.tsx
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Develop without hitting real Jira.** The app talks to nothing but the REST API, so pointing it at a
|
|
158
|
+
local stub is enough to work offline and to exercise edge cases (no worklogs, a ticket with no
|
|
159
|
+
sprint, a 401). Serve JSON for `/rest/api/3/myself`, `/rest/api/3/field`, `/rest/api/3/search/jql`,
|
|
160
|
+
and `/rest/api/3/issue/:key/worklog`, then:
|
|
161
|
+
|
|
162
|
+
```sh
|
|
163
|
+
JIRA_BASE_URL=http://localhost:7311 JIRA_EMAIL=a@b.c JIRA_API_TOKEN=t npm run dev
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Inspect the rendering non-interactively.** Handy in a script or when a layout bug only appears at a
|
|
167
|
+
particular size — `tmux` gives you the finished frame as text:
|
|
168
|
+
|
|
169
|
+
```sh
|
|
170
|
+
tmux new-session -d -s jdb -x 130 -y 40 'jdb'
|
|
171
|
+
sleep 4
|
|
172
|
+
tmux capture-pane -p -t jdb # prints the rendered screen
|
|
173
|
+
tmux kill-session -t jdb
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Common failure modes: if the terminal is left in a broken state after a crash, run `reset`. If panel
|
|
177
|
+
content wraps or the panel title disappears, a fixed-width panel is being flex-shrunk or its content
|
|
178
|
+
is one row taller than its height — see `PanelFrame` and the row-count arithmetic in each panel.
|
|
179
|
+
|
|
180
|
+
## Publishing to npm
|
|
181
|
+
|
|
182
|
+
The package publishes as **`jira-dashboard`** and installs the **`jdb`** command. Only `dist/` and
|
|
183
|
+
`README.md` ship (`files` in `package.json`); source and configs stay out of the tarball.
|
|
184
|
+
|
|
185
|
+
```sh
|
|
186
|
+
# 1. Authenticate (once per machine)
|
|
187
|
+
npm login
|
|
188
|
+
npm whoami
|
|
189
|
+
|
|
190
|
+
# 2. Make sure it is releasable (lint + typecheck + build)
|
|
191
|
+
npm run check
|
|
192
|
+
|
|
193
|
+
# 3. Inspect exactly what will be uploaded — no files are published by this
|
|
194
|
+
npm pack --dry-run
|
|
195
|
+
|
|
196
|
+
# 4. Bump the version (also creates a git tag when this is a git repo;
|
|
197
|
+
# add --no-git-tag-version if it is not, or if you tag separately)
|
|
198
|
+
npm version patch # or: minor | major
|
|
199
|
+
|
|
200
|
+
# 5. Publish. prepublishOnly rebuilds dist/ first.
|
|
201
|
+
npm publish
|
|
202
|
+
|
|
203
|
+
# 6. Verify the published artifact
|
|
204
|
+
npm view jira-dashboard version
|
|
205
|
+
npx --yes jira-dashboard@latest --version
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Notes:
|
|
209
|
+
|
|
210
|
+
- **The name `jira-dashboard` was unclaimed on the public registry as of this writing**, but that can
|
|
211
|
+
change at any time. If `npm publish` fails with `E403`, the name is taken — publish under a scope
|
|
212
|
+
instead (`@yourname/jira-dashboard`), which additionally requires `npm publish --access public`
|
|
213
|
+
since scoped packages default to private.
|
|
214
|
+
- **Publishing is effectively permanent.** Unpublishing is only allowed within 72 hours and a version
|
|
215
|
+
number can never be reused. Prefer `npm deprecate jira-dashboard@1.2.3 "reason"` for a bad release
|
|
216
|
+
and ship a fix as a new version.
|
|
217
|
+
- **`engines` requires Node ≥ 20** (the code uses `AbortSignal.timeout` and built-in `fetch`).
|
|
218
|
+
- To rehearse the whole flow without touching the public registry, publish to a local registry such
|
|
219
|
+
as [Verdaccio](https://verdaccio.org/): `npm publish --registry http://localhost:4873`.
|