Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 26 additions & 44 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@
"globals": "^17.6.0",
"vite": "^8.1.3",
"vite-plugin-pwa": "^1.3.0"
},
"overrides": {
"@babel/core": "7.29.6"
}
}
3 changes: 2 additions & 1 deletion frontend/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
STALE_WARNING_MS,
STALE_CRITICAL_MS,
} from "./lib/constants";
import { ViewProvider, useView } from "./contexts/ViewContext";
import { ViewProvider } from "./contexts/ViewContext";
import { useView } from "./contexts/use-view";
import StatusBanner from "./components/StatusBanner";
import IncidentSection from "./components/IncidentSection";
import MaintenanceBanner from "./components/MaintenanceBanner";
Expand Down
1 change: 0 additions & 1 deletion frontend/src/components/MaintenanceBanner.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export default function MaintenanceBanner({ data }) {

const maintenances = data.upcoming_maintenances;
const visible = expanded ? maintenances : maintenances.slice(0, 3);
const remaining = maintenances.length - 3;

return (
<div className="rounded-lg bg-bg-surface border border-border px-4 py-3">
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/StatusBanner.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function StatusBanner({ data, loading }) {
);
}

const { overall_status, active_incidents, total_services = 0, healthy_count, unknown_count = 0 } = data;
const { overall_status, active_incidents, total_services = 0, unknown_count = 0 } = data;
const hasIncidents = active_incidents && active_incidents.length > 0;
const monitored = total_services - unknown_count;
const manual = unknown_count;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/ViewToggle.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useView } from "../contexts/ViewContext";
import { useView } from "../contexts/use-view";

const VIEWS = [
{ id: "engineer", label: "Engineer" },
Expand Down
10 changes: 2 additions & 8 deletions frontend/src/contexts/ViewContext.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createContext, useContext, useState, useEffect } from "react";
import { useState, useEffect } from "react";
import { ViewContext } from "./view-context";

const ViewContext = createContext();
const STORAGE_KEY = "pulse-view-mode";

export function ViewProvider({ children }) {
Expand All @@ -26,9 +26,3 @@ export function ViewProvider({ children }) {
</ViewContext.Provider>
);
}

export function useView() {
const ctx = useContext(ViewContext);
if (!ctx) throw new Error("useView must be used inside ViewProvider");
return ctx;
}
8 changes: 8 additions & 0 deletions frontend/src/contexts/use-view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useContext } from "react";
import { ViewContext } from "./view-context";

export function useView() {
const ctx = useContext(ViewContext);
if (!ctx) throw new Error("useView must be used inside ViewProvider");
return ctx;
}
3 changes: 3 additions & 0 deletions frontend/src/contexts/view-context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { createContext } from "react";

export const ViewContext = createContext();
21 changes: 13 additions & 8 deletions frontend/src/hooks/use-polling.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@ export function usePolling(url, intervalMs = 30000) {
const lastJsonRef = useRef(null);
const urlRef = useRef(url);

// Reset on URL change
if (url !== urlRef.current) {
urlRef.current = url;
lastJsonRef.current = null;
}
useEffect(() => {
if (url !== urlRef.current) {
urlRef.current = url;
lastJsonRef.current = null;
}
}, [url]);

const fetchData = useCallback(
async (signal) => {
if (!url) return;
setLoading((current) => (lastJsonRef.current === null ? true : current));
try {
const result = await get(url, signal);
const json = JSON.stringify(result);
Expand All @@ -43,11 +45,14 @@ export function usePolling(url, intervalMs = 30000) {

useEffect(() => {
const controller = new AbortController();
setLoading(data === null);
fetchData(controller.signal);
const runFetch = () => {
Promise.resolve().then(() => fetchData(controller.signal));
};

runFetch();

const interval = setInterval(() => {
fetchData(controller.signal);
runFetch();
}, intervalMs);

return () => {
Expand Down
Loading