49 lines
2.9 KiB
TypeScript
49 lines
2.9 KiB
TypeScript
import { useBoard } from "../api/queries.ts";
|
||
import { fmtStamp } from "../board/model/util.ts";
|
||
import { Button, IconButton, IconRefresh } from "../ui/index.ts";
|
||
import { useJiraRefresh } from "./refresh.ts";
|
||
import { refreshText } from "./refreshStatus.ts";
|
||
|
||
const HINT = "Поставить в хаб пакет «обновление по базовой JQL» и дождаться его: агент перечитает задачи из Jira";
|
||
|
||
// состояние данных: агент, время последнего полного обновления, кнопка «Обновить из Jira» и ход пакета;
|
||
// compact — свёрнутая боковая панель: кнопка-значок с точкой агента, тексты в подсказке (#69, design 3)
|
||
export function DataStatus({ project, compact = false }: { project: string | null; compact?: boolean }) {
|
||
const refresh = useJiraRefresh();
|
||
const board = useBoard(project);
|
||
const ls = board.data?.last_sync ?? null;
|
||
const agent = refresh.agent;
|
||
const rt = refresh.event ? refreshText(refresh.event) : null;
|
||
const seen = agent?.last_seen_at ? `последний выход на связь: ${fmtStamp(agent.last_seen_at)}` : "выхода на связь ещё не было";
|
||
const agentText = agent ? (agent.online ? "агент на связи" : "агент офлайн") : null;
|
||
const syncText = board.data ? (ls ? `данные на ${fmtStamp(ls.finished_at)}` : "полного обновления не было") : null;
|
||
const event = <span className={`data-status__event${rt ? ` data-status__event--${rt.tone}` : ""}${compact ? " visually-hidden" : ""}`}
|
||
role="status" title={rt?.text}>{rt?.text}</span>;
|
||
if (compact) {
|
||
const title = ["Обновить из Jira", agentText, syncText, rt?.text].filter(Boolean).join(" · ");
|
||
return (
|
||
<div className="data-status data-status--compact">
|
||
<IconButton label="Обновить из Jira" title={title} disabled={refresh.busy} aria-busy={refresh.busy ? "true" : undefined}
|
||
icon={refresh.busy ? <span className="ui-spinner" aria-hidden="true" /> : <IconRefresh />} onClick={() => void refresh.start()} />
|
||
{agent && <span className={"data-status__dot" + (agent.online ? " is-online" : "")} aria-hidden="true" />}
|
||
{event}
|
||
</div>
|
||
);
|
||
}
|
||
return (
|
||
<div className="data-status">
|
||
{agent && (
|
||
<span className="data-status__agent" title={seen}>
|
||
<span className={"data-status__dot" + (agent.online ? " is-online" : "")} aria-hidden="true" />
|
||
{agentText}
|
||
</span>
|
||
)}
|
||
{syncText && <span className="data-status__sync">{syncText}</span>}
|
||
<Button variant="primary" icon={<IconRefresh />} loading={refresh.busy} onClick={() => void refresh.start()} title={HINT}>
|
||
Обновить из Jira
|
||
</Button>
|
||
{event}
|
||
</div>
|
||
);
|
||
}
|