fix: logs filter

This commit is contained in:
2026-04-05 00:13:09 +03:00
parent bcca8fa298
commit 43ea41f633
5 changed files with 59 additions and 24 deletions
@@ -1,6 +1,6 @@
import { create } from "zustand"; import { create } from "zustand";
export type LogLevel = "INFO" | "WARNING" | "ERROR" | "FATAL"; export type LogLevel = "info" | "warning" | "error" | "fatal";
interface LogFilterState { interface LogFilterState {
searchQuery: string; searchQuery: string;
@@ -22,7 +22,7 @@ interface LogFilterState {
setOffset: (offset: number) => void; setOffset: (offset: number) => void;
resetFilters: () => void; resetFilters: () => void;
getFilters: () => { getFilters: () => {
level?: string; level?: string | string[];
service?: string; service?: string;
agent?: string; agent?: string;
date_from?: string; date_from?: string;
@@ -36,7 +36,7 @@ export const useLogFilterStore = create<LogFilterState>((set, get) => ({
searchQuery: "", searchQuery: "",
startDate: null, startDate: null,
endDate: null, endDate: null,
selectedLogLevels: ["INFO", "WARNING", "ERROR", "FATAL"], selectedLogLevels: ["info", "warning", "error", "fatal"],
selectedService: "", selectedService: "",
selectedAgent: "", selectedAgent: "",
limit: 100, limit: 100,
@@ -63,7 +63,7 @@ export const useLogFilterStore = create<LogFilterState>((set, get) => ({
searchQuery: "", searchQuery: "",
startDate: null, startDate: null,
endDate: null, endDate: null,
selectedLogLevels: ["INFO", "WARNING", "ERROR", "FATAL"], selectedLogLevels: ["info", "warning", "error", "fatal"],
selectedService: "", selectedService: "",
selectedAgent: "", selectedAgent: "",
limit: 100, limit: 100,
@@ -72,9 +72,17 @@ export const useLogFilterStore = create<LogFilterState>((set, get) => ({
}, },
getFilters: () => { getFilters: () => {
const { selectedLogLevels, selectedService, selectedAgent, startDate, endDate, limit, offset } = get(); const {
selectedLogLevels,
selectedService,
selectedAgent,
startDate,
endDate,
limit,
offset,
} = get();
return { return {
level: selectedLogLevels.length > 0 ? selectedLogLevels.join(",") : undefined, level: selectedLogLevels.length > 0 ? selectedLogLevels : undefined,
service: selectedService || undefined, service: selectedService || undefined,
agent: selectedAgent || undefined, agent: selectedAgent || undefined,
date_from: startDate ? startDate.toISOString() : undefined, date_from: startDate ? startDate.toISOString() : undefined,
@@ -62,7 +62,7 @@ export interface InsertLogsRequest {
} }
export interface LogFilters { export interface LogFilters {
level?: string; level?: string | string[];
service?: string; service?: string;
agent?: string; agent?: string;
date_from?: string; date_from?: string;
+6 -6
View File
@@ -13,22 +13,22 @@ const logLevelColors: Record<
LogLevel, LogLevel,
{ bg: string; text: string; border: string } { bg: string; text: string; border: string }
> = { > = {
INFO: { info: {
bg: "var(--info-bg)", bg: "var(--info-bg)",
text: "var(--info-text)", text: "var(--info-text)",
border: "var(--info-border)", border: "var(--info-border)",
}, },
WARNING: { warning: {
bg: "var(--warning-bg)", bg: "var(--warning-bg)",
text: "var(--warning-text)", text: "var(--warning-text)",
border: "var(--warning-border)", border: "var(--warning-border)",
}, },
ERROR: { error: {
bg: "var(--error-bg)", bg: "var(--error-bg)",
text: "var(--error-text)", text: "var(--error-text)",
border: "var(--error-border)", border: "var(--error-border)",
}, },
FATAL: { fatal: {
bg: "var(--fatal-bg)", bg: "var(--fatal-bg)",
text: "var(--fatal-text)", text: "var(--fatal-text)",
border: "var(--fatal-border)", border: "var(--fatal-border)",
@@ -272,7 +272,7 @@ export const LogFilters: React.FC<LogFiltersProps> = ({
</span> </span>
</div> </div>
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
{(["INFO", "WARNING", "ERROR", "FATAL"] as LogLevel[]).map( {(["info", "warning", "error", "fatal"] as LogLevel[]).map(
(level) => { (level) => {
const isSelected = selectedLogLevels.includes(level); const isSelected = selectedLogLevels.includes(level);
const colors = logLevelColors[level]; const colors = logLevelColors[level];
@@ -291,7 +291,7 @@ export const LogFilters: React.FC<LogFiltersProps> = ({
{isSelected && ( {isSelected && (
<FiCheck size={10} className="inline mr-1" /> <FiCheck size={10} className="inline mr-1" />
)} )}
{level} {level.toUpperCase()}
</button> </button>
); );
}, },
+10 -10
View File
@@ -15,32 +15,32 @@ import {
} from "react-icons/fi"; } from "react-icons/fi";
const logLevelIcons: Record<string, React.ReactNode> = { const logLevelIcons: Record<string, React.ReactNode> = {
INFO: <FiInfo size={14} />, info: <FiInfo size={14} />,
WARNING: <FiAlertTriangle size={14} />, warning: <FiAlertTriangle size={14} />,
ERROR: <FiAlertCircle size={14} />, error: <FiAlertCircle size={14} />,
FATAL: <FiXOctagon size={14} />, fatal: <FiXOctagon size={14} />,
}; };
const logLevelColors: Record< const logLevelColors: Record<
string, string,
{ bg: string; text: string; border: string } { bg: string; text: string; border: string }
> = { > = {
INFO: { info: {
bg: "var(--info-bg)", bg: "var(--info-bg)",
text: "var(--info-text)", text: "var(--info-text)",
border: "var(--info-border)", border: "var(--info-border)",
}, },
WARNING: { warning: {
bg: "var(--warning-bg)", bg: "var(--warning-bg)",
text: "var(--warning-text)", text: "var(--warning-text)",
border: "var(--warning-border)", border: "var(--warning-border)",
}, },
ERROR: { error: {
bg: "var(--error-bg)", bg: "var(--error-bg)",
text: "var(--error-text)", text: "var(--error-text)",
border: "var(--error-border)", border: "var(--error-border)",
}, },
FATAL: { fatal: {
bg: "var(--fatal-bg)", bg: "var(--fatal-bg)",
text: "var(--fatal-text)", text: "var(--fatal-text)",
border: "var(--fatal-border)", border: "var(--fatal-border)",
@@ -306,9 +306,9 @@ export const LogsPage: React.FC = () => {
</thead> </thead>
<tbody> <tbody>
{logs.map((log, index) => { {logs.map((log, index) => {
const level = log.level || "INFO"; const level = log.level?.toLowerCase() || "info";
const colors = const colors =
logLevelColors[level] || logLevelColors.INFO; logLevelColors[level] || logLevelColors.info;
return ( return (
<tr <tr
key={index} key={index}
+28 -1
View File
@@ -16,7 +16,7 @@ class ApiClient {
constructor() { constructor() {
this.axiosInstance = axios.create({ this.axiosInstance = axios.create({
baseURL: "http://10.97.147.99:8080/api/v1", baseURL: "http://213.165.213.170:8080/api/v1",
timeout: 10000, timeout: 10000,
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@@ -24,6 +24,33 @@ class ApiClient {
validateStatus: (status) => { validateStatus: (status) => {
return status >= 200 && status < 400; return status >= 200 && status < 400;
}, },
// Добавляем кастомный сериализатор параметров
paramsSerializer: {
serialize: (params) => {
const parts: string[] = [];
Object.entries(params).forEach(([key, value]) => {
if (value === undefined || value === null) return;
if (Array.isArray(value)) {
// Преобразуем массив в множественные параметры: level=info&level=warning
value.forEach((item) => {
if (item !== undefined && item !== null) {
parts.push(
`${encodeURIComponent(key)}=${encodeURIComponent(item)}`,
);
}
});
} else {
parts.push(
`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`,
);
}
});
return parts.join("&");
},
},
}); });
this.setupInterceptors(); this.setupInterceptors();