bookr-cli
Version:
A terminal-based CLI tool to book time in Jira using the Tempo plugin by parsing your current Git branch name
99 lines • 5.5 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 SprintWorklogs = () => {
const [state, setState] = useState('loading');
const [worklogs, setWorklogs] = useState([]);
const [error, setError] = useState(null);
const [sprintInfo, setSprintInfo] = useState(null);
useEffect(() => {
async function fetchSprintWorklogs() {
try {
const client = createClient();
const tempoClient = createTempoClient();
// Get current sprint
const sprint = await client.getCurrentSprint();
if (!sprint.startDate || !sprint.endDate) {
setState('no-sprint');
return;
}
const startDate = new Date(sprint.startDate);
const endDate = new Date(sprint.endDate);
const fromISO = startDate.toISOString().slice(0, 10);
const toISO = endDate.toISOString().slice(0, 10);
setSprintInfo({
name: sprint.name,
startDate: fromISO,
endDate: toISO,
});
const user = await client.getCurrentUser();
const tempoWorklogsResponse = await tempoClient.getWorklogsForUser(user.accountId, fromISO, toISO);
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 = worklog.timeSpentSeconds || 0;
const issueId = worklog.issue?.id || '';
const issueInfo = issueMap.get(issueId) || {};
const issueKey = issueInfo.key || '';
const summary = issueInfo.summary || worklog.description || '';
const tempoId = worklog.tempoWorklogId ? String(worklog.tempoWorklogId) : '';
const jiraId = worklog.tempoWorklogId ? String(worklog.tempoWorklogId) : String(worklog.id || '');
return {
tempoId,
jiraId,
issueKey,
timeSpentSeconds,
summary,
};
});
setWorklogs(formattedWorklogs);
setState('success');
}
catch (error) {
setError(error instanceof Error ? error.message : 'Unknown error');
setState('error');
}
}
fetchSprintWorklogs();
}, []);
if (state === 'loading') {
return (_jsx(Box, { flexDirection: "column", padding: 1, children: _jsx(Text, { children: "\u23F3 Loading sprint worklogs..." }) }));
}
if (state === 'error') {
return (_jsx(Box, { flexDirection: "column", padding: 1, children: _jsxs(Text, { color: "red", children: ["\u274C Error: ", error] }) }));
}
if (state === 'no-sprint') {
return (_jsx(Box, { flexDirection: "column", padding: 1, children: _jsx(Text, { color: "yellow", children: "\u274C Current sprint does not have valid start or end dates." }) }));
}
if (state === 'no-worklogs') {
return (_jsx(Box, { flexDirection: "column", padding: 1, children: _jsx(Text, { color: "yellow", children: "\uD83D\uDCED No worklogs found for this sprint period." }) }));
}
if (!sprintInfo) {
return (_jsx(Box, { flexDirection: "column", padding: 1, children: _jsx(Text, { color: "red", children: "\u274C No sprint information available." }) }));
}
return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Text, { color: "cyan", bold: true, children: ["\uD83C\uDFC3 Sprint: ", sprintInfo.name] }), _jsxs(Text, { color: "gray", children: ["\uD83D\uDCC5 ", sprintInfo.startDate, " to ", sprintInfo.endDate] }), _jsx(Box, { marginTop: 1, children: _jsx(WorklogTable, { worklogs: worklogs, title: "\uD83D\uDCCA Sprint Worklogs", showTempoId: false, showJiraId: true }) })] }));
};
//# sourceMappingURL=SprintWorklogs.js.map