diff --git a/web/src/App.tsx b/web/src/App.tsx
index c5c022c..34645c9 100644
--- a/web/src/App.tsx
+++ b/web/src/App.tsx
@@ -3,6 +3,7 @@ import { useState } from "react";
import { createBrowserRouter, RouterProvider } from "react-router";
import { makeQueryClient } from "./api/queryClient.ts";
import { AuthGate } from "./auth/AuthGate.tsx";
+import { RefreshProvider } from "./shell/RefreshProvider.tsx";
import { routes } from "./routes.tsx";
import "./styles/tokens.css";
import "./styles/base.css";
@@ -15,7 +16,7 @@ export function App({ router }: { router?: Router }) {
const [r] = useState(() => router ?? createBrowserRouter(routes, { basename: "/app" }));
return (
-
+
);
}
diff --git a/web/src/board/BoardPage.tsx b/web/src/board/BoardPage.tsx
index 8ad3c78..a075816 100644
--- a/web/src/board/BoardPage.tsx
+++ b/web/src/board/BoardPage.tsx
@@ -67,9 +67,9 @@ export function BoardPage({ project }: { project: string }) {
return (
-
void src.refreshFromJira()} onFile={onFile}
+ tableOpen={prefs.table} onReload={src.reload} onFile={onFile}
onProblems={() => prefs.toggle("problems")} onExport={onExport} onTable={() => prefs.toggle("table")}
onSnap={() => prefs.toggle("snap")} onReset={prefs.resetLayout} />
diff --git a/web/src/board/components/Toolbar.tsx b/web/src/board/components/Toolbar.tsx
index 5609b66..f367126 100644
--- a/web/src/board/components/Toolbar.tsx
+++ b/web/src/board/components/Toolbar.tsx
@@ -1,4 +1,6 @@
import { useEffect, useState } from "react";
+import { useJiraRefresh } from "../../shell/refresh.ts";
+import { refreshText } from "../../shell/refreshStatus.ts";
import { applyTheme, readTheme, saveTheme, THEME_NAMES, THEMES, type Theme } from "../../shell/theme.ts";
import { statusText, type BoardStatus } from "../status.ts";
import type { BoardModel, Visible } from "../types.ts";
@@ -6,9 +8,9 @@ import { NOT_IN_HUB } from "../constants.ts";
import { Dropdown } from "../../ui/index.ts";
interface ToolbarProps {
- label: string; title: string; status: BoardStatus | null; refreshing: boolean; byDate: boolean; snap: boolean;
+ label: string; title: string; status: BoardStatus | null; byDate: boolean; snap: boolean;
model: BoardModel; vis: Visible; problemCount: number; problemsOpen: boolean; tableOpen: boolean;
- onReload(): void; onRefresh(): void; onFile(name: string, text: string): void; onProblems(): void;
+ onReload(): void; onFile(name: string, text: string): void; onProblems(): void;
onExport(): void; onTable(): void; onSnap(): void; onReset(): void;
}
@@ -16,7 +18,9 @@ export function Toolbar(p: ToolbarProps) {
const [theme, setTheme] = useState(readTheme);
const [confirm, setConfirm] = useState(false);
useEffect(() => { if (!confirm) return; const t = setTimeout(() => setConfirm(false), 8000); return () => clearTimeout(t); }, [confirm]);
- const st = p.status ? statusText(p.status) : null;
+ const refresh = useJiraRefresh(); // кнопка и ход пакета временно здесь; в верхней панели — с Task 5
+ const rt = refresh.event ? refreshText(refresh.event) : null;
+ const st = p.status ? statusText(p.status) : rt ? { text: rt.text, warn: rt.tone === "error" || rt.tone === "warning" } : null;
const m = p.model, v = p.vis, r = v.removed;
const coreShown = v.nodes.filter((n) => !n.dim).length, ctxShown = v.nodes.length - coreShown;
const nextTheme = () => { const t = THEMES[(THEMES.indexOf(theme) + 1) % THEMES.length]; setTheme(t); saveTheme(t); applyTheme(t); };
@@ -26,7 +30,7 @@ export function Toolbar(p: ToolbarProps) {
{p.label}
-