bookr-cli
Version:
A terminal-based CLI tool to book time in Jira using the Tempo plugin by parsing your current Git branch name
80 lines • 4.96 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Box, Text } from 'ink';
import { useEffect, useState } from 'react';
import { createClient } from '../api/jira-client.js';
import { createTempoClient } from '../api/tempo-client.js';
import { parallelMapLimit } from '../utils/concurrency.js';
import { WorklogTable } from './WorklogTable.js';
export const UndoWorklogs = () => {
const [state, setState] = useState('loading');
const [worklogs, setWorklogs] = useState([]);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchUndoWorklogs() {
try {
const client = createClient();
const tempoClient = createTempoClient();
const user = await client.getCurrentUser();
const todayISO = new Date().toISOString().slice(0, 10);
const tempoWorklogsResponse = await tempoClient.getWorklogsForUser(user.accountId, todayISO, todayISO);
const tempoWorklogs = (tempoWorklogsResponse && typeof tempoWorklogsResponse === 'object' && Array.isArray(tempoWorklogsResponse.results))
? tempoWorklogsResponse.results
: Array.isArray(tempoWorklogsResponse) ? tempoWorklogsResponse : [];
if (!tempoWorklogs.length) {
setState('no-worklogs');
return;
}
// Collect unique issue IDs
const uniqueIssueIds = Array.from(new Set(tempoWorklogs.map((w) => w.issue?.id).filter(Boolean)));
// Fetch all issues in parallel (limit concurrency to 5)
const issueMap = new Map();
await parallelMapLimit(uniqueIssueIds, 5, async (id) => {
try {
const issue = await client.getIssue(String(id));
issueMap.set(id, { key: issue.key, summary: issue.fields.summary });
}
catch {
// If not found, skip
}
});
// Transform worklogs to our format
const formattedWorklogs = tempoWorklogs.map((worklog) => {
const timeSpentSeconds = typeof worklog.timeSpentSeconds === 'number' ? worklog.timeSpentSeconds : 0;
const issueId = worklog.issue?.id || '';
const issueInfo = issueMap.get(issueId) || {};
const issueKey = issueInfo.key || '';
const summary = (issueInfo.summary || worklog.description || '').slice(0, 50);
const tempoId = worklog.tempoWorklogId ? String(worklog.tempoWorklogId) : '';
const jiraId = worklog.tempoWorklogId ? String(worklog.tempoWorklogId) : String(worklog.id || '');
const source = worklog.tempoWorklogId ? 'tempo' : 'jira';
return {
tempoId,
jiraId,
issueKey,
timeSpentSeconds,
summary,
source,
};
});
setWorklogs(formattedWorklogs);
setState('success');
}
catch (error) {
setError(error instanceof Error ? error.message : 'Unknown error');
setState('error');
}
}
fetchUndoWorklogs();
}, []);
if (state === 'loading') {
return (_jsx(Box, { flexDirection: "column", padding: 1, children: _jsx(Text, { children: "\u23F3 Loading worklogs for undo..." }) }));
}
if (state === 'error') {
return (_jsx(Box, { flexDirection: "column", padding: 1, children: _jsxs(Text, { color: "red", children: ["\u274C Error: ", error] }) }));
}
if (state === 'no-worklogs') {
return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { color: "yellow", children: "\uD83D\uDCED No worklogs found for today." }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: "\uD83D\uDCA1 You can undo any worklog by its ID: bookr undo <WORKLOG_ID>" }) })] }));
}
return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(WorklogTable, { worklogs: worklogs, title: "\uD83D\uDDD1\uFE0F Worklogs Available for Undo", showTempoId: true, showJiraId: true, showSource: true }), _jsxs(Box, { marginTop: 2, flexDirection: "column", children: [_jsx(Text, { color: "cyan", children: "\uD83D\uDCA1 To undo a specific worklog, run: bookr undo <WORKLOG_ID>" }), _jsx(Text, { color: "cyan", children: "\uD83D\uDCA1 You can undo ANY worklog that you have permission to delete" }), _jsx(Text, { color: "red", bold: true, children: "\u26A0\uFE0F Warning: This will permanently delete the worklog from Tempo!" })] })] }));
};
//# sourceMappingURL=UndoWorklogs.js.map