feat(ui): metrikleri odaklanma ve gezinme durumunda yenile
Metriklerin güncel kalması için pencere odaklanıldığında ve sayfa gezinildiğinde verilerin yeniden yüklenmesi eklendi. Backend deployment servisinde tip tanımları güncellendi.
This commit is contained in:
@@ -88,6 +88,10 @@ router.get("/env-examples", async (req, res) => {
|
|||||||
|
|
||||||
router.get("/metrics/summary", async (req, res) => {
|
router.get("/metrics/summary", async (req, res) => {
|
||||||
authMiddleware(req, res, async () => {
|
authMiddleware(req, res, async () => {
|
||||||
|
const deploymentCount = await DeploymentProject.countDocuments();
|
||||||
|
if (deploymentCount === 0) {
|
||||||
|
await deploymentService.bootstrapFromFilesystem();
|
||||||
|
}
|
||||||
const since = new Date();
|
const since = new Date();
|
||||||
since.setDate(since.getDate() - 7);
|
since.setDate(since.getDate() - 7);
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ router.get("/", async (_req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.get("/metrics/summary", async (_req, res) => {
|
router.get("/metrics/summary", async (_req, res) => {
|
||||||
|
const jobCount = await Job.countDocuments();
|
||||||
|
if (jobCount === 0) {
|
||||||
|
await jobService.bootstrapFromFilesystem();
|
||||||
|
}
|
||||||
const since = new Date();
|
const since = new Date();
|
||||||
since.setDate(since.getDate() - 7);
|
since.setDate(since.getDate() - 7);
|
||||||
|
|
||||||
|
|||||||
@@ -385,7 +385,7 @@ class DeploymentService {
|
|||||||
this.io.except(`deployment:${deploymentId}`).emit("deployment:log", { deploymentId, line });
|
this.io.except(`deployment:${deploymentId}`).emit("deployment:log", { deploymentId, line });
|
||||||
}
|
}
|
||||||
|
|
||||||
private emitRun(deploymentId: string, run: DeploymentRun) {
|
private emitRun(deploymentId: string, run: DeploymentRunDocument) {
|
||||||
if (!this.io) return;
|
if (!this.io) return;
|
||||||
this.io.to(`deployment:${deploymentId}`).emit("deployment:run", {
|
this.io.to(`deployment:${deploymentId}`).emit("deployment:run", {
|
||||||
deploymentId,
|
deploymentId,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import {
|
import {
|
||||||
Line,
|
Line,
|
||||||
LineChart,
|
LineChart,
|
||||||
@@ -18,6 +18,7 @@ import { JobStatusBadge } from "../components/JobStatusBadge";
|
|||||||
import { RepoIcon } from "../components/RepoIcon";
|
import { RepoIcon } from "../components/RepoIcon";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faClockRotateLeft, faListCheck, faFlaskVial, faRocket } from "@fortawesome/free-solid-svg-icons";
|
import { faClockRotateLeft, faListCheck, faFlaskVial, faRocket } from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import { useAuth } from "../providers/auth-provider";
|
||||||
|
|
||||||
function formatDuration(ms?: number) {
|
function formatDuration(ms?: number) {
|
||||||
if (!ms || Number.isNaN(ms)) return "-";
|
if (!ms || Number.isNaN(ms)) return "-";
|
||||||
@@ -41,9 +42,14 @@ export function HomePage() {
|
|||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const { jobStreams } = useLiveData();
|
const { jobStreams } = useLiveData();
|
||||||
|
const { token } = useAuth();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const location = useLocation();
|
||||||
|
|
||||||
useEffect(() => {
|
const loadMetrics = useCallback(() => {
|
||||||
|
if (!token) return;
|
||||||
|
setLoading(true);
|
||||||
|
setError(null);
|
||||||
Promise.allSettled([fetchJobMetrics(), fetchDeploymentMetrics()])
|
Promise.allSettled([fetchJobMetrics(), fetchDeploymentMetrics()])
|
||||||
.then(([jobResult, deployResult]) => {
|
.then(([jobResult, deployResult]) => {
|
||||||
if (jobResult.status === "fulfilled") {
|
if (jobResult.status === "fulfilled") {
|
||||||
@@ -65,7 +71,25 @@ export function HomePage() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.finally(() => setLoading(false));
|
.finally(() => setLoading(false));
|
||||||
}, []);
|
}, [token]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadMetrics();
|
||||||
|
}, [loadMetrics, location.key]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleFocus = () => {
|
||||||
|
if (document.visibilityState === "visible") {
|
||||||
|
loadMetrics();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.addEventListener("focus", handleFocus);
|
||||||
|
document.addEventListener("visibilitychange", handleFocus);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener("focus", handleFocus);
|
||||||
|
document.removeEventListener("visibilitychange", handleFocus);
|
||||||
|
};
|
||||||
|
}, [loadMetrics]);
|
||||||
|
|
||||||
const chartData = useMemo(() => {
|
const chartData = useMemo(() => {
|
||||||
if (!metrics) {
|
if (!metrics) {
|
||||||
|
|||||||
Reference in New Issue
Block a user