130 lines
3.3 KiB
TypeScript
130 lines
3.3 KiB
TypeScript
import { create } from "zustand";
|
|
import { apiService } from "@/shared/api/api.service";
|
|
import type { MetricData } from "../types";
|
|
|
|
interface DashboardState {
|
|
chartData: MetricData[];
|
|
loading: boolean;
|
|
error: string | null;
|
|
fetchMetrics: (
|
|
isLatest: boolean,
|
|
token: string,
|
|
queryParams?: string,
|
|
extraParams?: Record<string, string>,
|
|
) => Promise<void>;
|
|
clearData: () => void;
|
|
}
|
|
|
|
export const useDashboardStore = create<DashboardState>((set, get) => {
|
|
const convertPrimaryData = (response: any) => {
|
|
set((state) => {
|
|
if (!response.intervals || !Array.isArray(response.intervals))
|
|
return { chartData: state.chartData };
|
|
|
|
const newData = [...state.chartData];
|
|
|
|
response.intervals.forEach((interval: any) => {
|
|
const newPoint: MetricData = {
|
|
timestamp: new Date(interval.timestamp).toLocaleTimeString(),
|
|
};
|
|
|
|
if (interval.group_by && Array.isArray(interval.group_by)) {
|
|
interval.group_by.forEach((item: any) => {
|
|
newPoint[item.value] = item.count;
|
|
});
|
|
}
|
|
|
|
newData.push(newPoint);
|
|
});
|
|
|
|
return { chartData: newData.slice(-20) };
|
|
});
|
|
};
|
|
|
|
const convertSingleData = (response: any) => {
|
|
set((state) => {
|
|
const newPoint: MetricData = {
|
|
timestamp: new Date().toLocaleTimeString(),
|
|
};
|
|
|
|
if (Array.isArray(response)) {
|
|
response.forEach((item: any) => {
|
|
newPoint[item.value] = item.count;
|
|
});
|
|
} else if (response.groupBy && Array.isArray(response.groupBy)) {
|
|
response.groupBy.forEach((item: any) => {
|
|
newPoint[item.value] = item.count;
|
|
});
|
|
}
|
|
|
|
const updatedData = [...state.chartData, newPoint].slice(-20);
|
|
return { chartData: updatedData };
|
|
});
|
|
};
|
|
|
|
const fetchMetrics = async (
|
|
isLatest: boolean,
|
|
token: string,
|
|
queryParams?: string,
|
|
extraParams?: Record<string, string>,
|
|
) => {
|
|
set({ loading: true, error: null });
|
|
|
|
try {
|
|
let endpoint = isLatest
|
|
? "logs/aggregations/latest"
|
|
: "logs/aggregations";
|
|
|
|
// Если есть queryParams, добавляем его к эндпоинту
|
|
if (queryParams && queryParams.trim() !== "") {
|
|
endpoint = `${endpoint}?${queryParams}`;
|
|
}
|
|
|
|
const params: Record<string, string> = {
|
|
agg: "count",
|
|
groupby: "level",
|
|
...extraParams,
|
|
};
|
|
|
|
const result = await apiService.get<any>(endpoint, {
|
|
params,
|
|
headers: {
|
|
Authorization: `bearer ${token}`,
|
|
},
|
|
});
|
|
|
|
if (result) {
|
|
if (isLatest) {
|
|
convertSingleData(result);
|
|
} else {
|
|
convertPrimaryData(result);
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error(
|
|
`Failed to fetch ${isLatest ? "latest" : "primary"} metrics:`,
|
|
error,
|
|
);
|
|
set({
|
|
error: error instanceof Error ? error.message : "Ошибка запроса",
|
|
});
|
|
} finally {
|
|
set({ loading: false });
|
|
}
|
|
};
|
|
|
|
const clearData = () => {
|
|
set({ chartData: [], error: null });
|
|
};
|
|
|
|
return {
|
|
chartData: [],
|
|
loading: false,
|
|
error: null,
|
|
fetchMetrics,
|
|
clearData,
|
|
setChartData: (data: MetricData[]) =>
|
|
set({ chartData: data, loading: false }),
|
|
};
|
|
});
|