fix: logs filter adaptive
ci-front / build (push) Successful in 2m30s

This commit is contained in:
2026-04-04 07:11:41 +03:00
parent eedc9c9b62
commit dd921e5892
+134 -35
View File
@@ -9,11 +9,30 @@ import {
} from "react-icons/fi"; } from "react-icons/fi";
import { useLogFilterStore, type LogLevel } from "../store/logFilter.store"; import { useLogFilterStore, type LogLevel } from "../store/logFilter.store";
const logLevelColors: Record<LogLevel, { bg: string; text: string; border: string }> = { const logLevelColors: Record<
INFO: { bg: "var(--info-bg)", text: "var(--info-text)", border: "var(--info-border)" }, LogLevel,
WARNING: { bg: "var(--warning-bg)", text: "var(--warning-text)", border: "var(--warning-border)" }, { bg: string; text: string; border: string }
ERROR: { bg: "var(--error-bg)", text: "var(--error-text)", border: "var(--error-border)" }, > = {
FATAL: { bg: "var(--fatal-bg)", text: "var(--fatal-text)", border: "var(--fatal-border)" }, INFO: {
bg: "var(--info-bg)",
text: "var(--info-text)",
border: "var(--info-border)",
},
WARNING: {
bg: "var(--warning-bg)",
text: "var(--warning-text)",
border: "var(--warning-border)",
},
ERROR: {
bg: "var(--error-bg)",
text: "var(--error-text)",
border: "var(--error-border)",
},
FATAL: {
bg: "var(--fatal-bg)",
text: "var(--fatal-text)",
border: "var(--fatal-border)",
},
}; };
interface LogFiltersProps { interface LogFiltersProps {
@@ -22,7 +41,11 @@ interface LogFiltersProps {
availableAgents: string[]; availableAgents: string[];
} }
export const LogFilters: React.FC<LogFiltersProps> = ({ onApply, availableServices, availableAgents }) => { export const LogFilters: React.FC<LogFiltersProps> = ({
onApply,
availableServices,
availableAgents,
}) => {
const { const {
searchQuery, searchQuery,
startDate, startDate,
@@ -72,7 +95,14 @@ export const LogFilters: React.FC<LogFiltersProps> = ({ onApply, availableServic
setSelectedService(localService); setSelectedService(localService);
setSelectedAgent(localAgent); setSelectedAgent(localAgent);
onApply(); onApply();
}, [localSearchQuery, localStartDate, localEndDate, localService, localAgent, onApply]); }, [
localSearchQuery,
localStartDate,
localEndDate,
localService,
localAgent,
onApply,
]);
const handleReset = useCallback(() => { const handleReset = useCallback(() => {
setLocalSearchQuery(""); setLocalSearchQuery("");
@@ -130,7 +160,10 @@ export const LogFilters: React.FC<LogFiltersProps> = ({ onApply, availableServic
<div className="flex items-center justify-between mb-4"> <div className="flex items-center justify-between mb-4">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<FiFilter size={14} style={{ color: "var(--accent)" }} /> <FiFilter size={14} style={{ color: "var(--accent)" }} />
<h3 className="text-sm font-semibold" style={{ color: "var(--text-primary)" }}> <h3
className="text-sm font-semibold"
style={{ color: "var(--text-primary)" }}
>
Фильтры логов Фильтры логов
</h3> </h3>
</div> </div>
@@ -140,7 +173,7 @@ export const LogFilters: React.FC<LogFiltersProps> = ({ onApply, availableServic
</div> </div>
{/* Filters Grid */} {/* Filters Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3 mb-4"> <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3 mb-4">
{/* Search */} {/* Search */}
<div className="relative"> <div className="relative">
<FiSearch <FiSearch
@@ -195,17 +228,31 @@ export const LogFilters: React.FC<LogFiltersProps> = ({ onApply, availableServic
<div className="flex gap-2"> <div className="flex gap-2">
<input <input
type="date" type="date"
value={localStartDate ? localStartDate.toISOString().split("T")[0] : ""} value={
onChange={(e) => setLocalStartDate(e.target.value ? new Date(e.target.value) : null)} localStartDate ? localStartDate.toISOString().split("T")[0] : ""
style={inputStyle} }
onChange={(e) =>
setLocalStartDate(
e.target.value ? new Date(e.target.value) : null,
)
}
style={{ ...inputStyle, minWidth: 0 }}
placeholder="Дата от" placeholder="Дата от"
className="flex-1 min-w-0"
/> />
<input <input
type="date" type="date"
value={localEndDate ? localEndDate.toISOString().split("T")[0] : ""} value={
onChange={(e) => setLocalEndDate(e.target.value ? new Date(e.target.value) : null)} localEndDate ? localEndDate.toISOString().split("T")[0] : ""
style={inputStyle} }
onChange={(e) =>
setLocalEndDate(
e.target.value ? new Date(e.target.value) : null,
)
}
style={{ ...inputStyle, minWidth: 0 }}
placeholder="Дата до" placeholder="Дата до"
className="flex-1 min-w-0"
/> />
</div> </div>
</div> </div>
@@ -214,7 +261,10 @@ export const LogFilters: React.FC<LogFiltersProps> = ({ onApply, availableServic
<div className="mb-4"> <div className="mb-4">
<div className="flex items-center gap-2 mb-2"> <div className="flex items-center gap-2 mb-2">
<FiTag size={12} style={{ color: "var(--text-secondary)" }} /> <FiTag size={12} style={{ color: "var(--text-secondary)" }} />
<span className="text-xs font-medium" style={{ color: "var(--text-secondary)" }}> <span
className="text-xs font-medium"
style={{ color: "var(--text-secondary)" }}
>
Уровни логов Уровни логов
</span> </span>
<span className="text-xs" style={{ color: "var(--text-muted)" }}> <span className="text-xs" style={{ color: "var(--text-muted)" }}>
@@ -222,36 +272,42 @@ export const LogFilters: React.FC<LogFiltersProps> = ({ onApply, availableServic
</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((level) => { {(["INFO", "WARNING", "ERROR", "FATAL"] as LogLevel[]).map(
(level) => {
const isSelected = selectedLogLevels.includes(level); const isSelected = selectedLogLevels.includes(level);
const colors = logLevelColors[level]; const colors = logLevelColors[level];
return ( return (
<button <button
key={level} key={level}
onClick={() => toggleLogLevel(level)} onClick={() => toggleLogLevel(level)}
className="px-3 py-1.5 rounded-lg text-xs font-medium transition-all border" className="px-3 py-2 rounded-lg text-xs font-medium transition-all border flex-shrink-0"
style={{ style={{
backgroundColor: isSelected ? colors.bg : "transparent", backgroundColor: isSelected ? colors.bg : "transparent",
color: isSelected ? colors.text : "var(--text-secondary)", color: isSelected ? colors.text : "var(--text-secondary)",
borderColor: isSelected ? colors.border : "var(--border)", borderColor: isSelected ? colors.border : "var(--border)",
minHeight: "36px",
}} }}
> >
{isSelected && <FiCheck size={10} className="inline mr-1" />} {isSelected && (
<FiCheck size={10} className="inline mr-1" />
)}
{level} {level}
</button> </button>
); );
})} },
)}
</div> </div>
</div> </div>
{/* Action Buttons */} {/* Action Buttons */}
<div className="flex gap-2"> <div className="flex flex-col sm:flex-row gap-2">
<button <button
onClick={handleApply} onClick={handleApply}
className="flex-1 flex items-center justify-center gap-2 px-4 py-2 rounded-lg transition-all text-sm font-medium" className="flex-1 flex items-center justify-center gap-2 px-4 py-2.5 rounded-lg transition-all text-sm font-medium"
style={{ style={{
backgroundColor: "var(--button-primary)", backgroundColor: "var(--button-primary)",
color: "var(--button-primary-text)", color: "var(--button-primary-text)",
minHeight: "44px",
}} }}
> >
<FiCheck size={14} /> <FiCheck size={14} />
@@ -259,23 +315,31 @@ export const LogFilters: React.FC<LogFiltersProps> = ({ onApply, availableServic
</button> </button>
<button <button
onClick={handleReset} onClick={handleReset}
className="px-4 py-2 rounded-lg transition-all text-sm font-medium border" className="flex items-center justify-center gap-2 px-4 py-2.5 rounded-lg transition-all text-sm font-medium border"
style={{ style={{
backgroundColor: "transparent", backgroundColor: "transparent",
color: "var(--text-secondary)", color: "var(--text-secondary)",
borderColor: "var(--border)", borderColor: "var(--border)",
minHeight: "44px",
}} }}
> >
<FiX size={14} /> <FiX size={14} />
Сбросить
</button> </button>
</div> </div>
{/* Active Filters Display */} {/* Active Filters Display */}
{activeFiltersCount > 0 && ( {activeFiltersCount > 0 && (
<div className="mt-4 pt-4 border-t" style={{ borderColor: "var(--border)" }}> <div
className="mt-4 pt-4 border-t"
style={{ borderColor: "var(--border)" }}
>
<div className="flex items-center gap-2 mb-2"> <div className="flex items-center gap-2 mb-2">
<FiFilter size={10} style={{ color: "var(--accent)" }} /> <FiFilter size={10} style={{ color: "var(--accent)" }} />
<span className="text-xs" style={{ color: "var(--text-secondary)" }}> <span
className="text-xs"
style={{ color: "var(--text-secondary)" }}
>
Активные фильтры: Активные фильтры:
</span> </span>
</div> </div>
@@ -289,14 +353,21 @@ export const LogFilters: React.FC<LogFiltersProps> = ({ onApply, availableServic
}} }}
> >
<FiSearch size={10} /> <FiSearch size={10} />
<span style={{ color: "var(--text-primary)" }}>Поиск: {searchQuery}</span> <span style={{ color: "var(--text-primary)" }}>
Поиск: {searchQuery}
</span>
<button <button
onClick={() => { onClick={() => {
setLocalSearchQuery(""); setLocalSearchQuery("");
setSearchQuery(""); setSearchQuery("");
onApply(); onApply();
}} }}
style={{ background: "none", border: "none", cursor: "pointer", color: "var(--text-muted)" }} style={{
background: "none",
border: "none",
cursor: "pointer",
color: "var(--text-muted)",
}}
> >
<FiX size={10} /> <FiX size={10} />
</button> </button>
@@ -311,14 +382,21 @@ export const LogFilters: React.FC<LogFiltersProps> = ({ onApply, availableServic
}} }}
> >
<FiTag size={10} /> <FiTag size={10} />
<span style={{ color: "var(--text-primary)" }}>Сервис: {selectedService}</span> <span style={{ color: "var(--text-primary)" }}>
Сервис: {selectedService}
</span>
<button <button
onClick={() => { onClick={() => {
setLocalService(""); setLocalService("");
setSelectedService(""); setSelectedService("");
onApply(); onApply();
}} }}
style={{ background: "none", border: "none", cursor: "pointer", color: "var(--text-muted)" }} style={{
background: "none",
border: "none",
cursor: "pointer",
color: "var(--text-muted)",
}}
> >
<FiX size={10} /> <FiX size={10} />
</button> </button>
@@ -333,14 +411,21 @@ export const LogFilters: React.FC<LogFiltersProps> = ({ onApply, availableServic
}} }}
> >
<FiTag size={10} /> <FiTag size={10} />
<span style={{ color: "var(--text-primary)" }}>Агент: {selectedAgent}</span> <span style={{ color: "var(--text-primary)" }}>
Агент: {selectedAgent}
</span>
<button <button
onClick={() => { onClick={() => {
setLocalAgent(""); setLocalAgent("");
setSelectedAgent(""); setSelectedAgent("");
onApply(); onApply();
}} }}
style={{ background: "none", border: "none", cursor: "pointer", color: "var(--text-muted)" }} style={{
background: "none",
border: "none",
cursor: "pointer",
color: "var(--text-muted)",
}}
> >
<FiX size={10} /> <FiX size={10} />
</button> </button>
@@ -355,14 +440,21 @@ export const LogFilters: React.FC<LogFiltersProps> = ({ onApply, availableServic
}} }}
> >
<FiCalendar size={10} /> <FiCalendar size={10} />
<span style={{ color: "var(--text-primary)" }}>С: {formatDate(startDate)}</span> <span style={{ color: "var(--text-primary)" }}>
С: {formatDate(startDate)}
</span>
<button <button
onClick={() => { onClick={() => {
setLocalStartDate(null); setLocalStartDate(null);
setStartDate(null); setStartDate(null);
onApply(); onApply();
}} }}
style={{ background: "none", border: "none", cursor: "pointer", color: "var(--text-muted)" }} style={{
background: "none",
border: "none",
cursor: "pointer",
color: "var(--text-muted)",
}}
> >
<FiX size={10} /> <FiX size={10} />
</button> </button>
@@ -377,14 +469,21 @@ export const LogFilters: React.FC<LogFiltersProps> = ({ onApply, availableServic
}} }}
> >
<FiCalendar size={10} /> <FiCalendar size={10} />
<span style={{ color: "var(--text-primary)" }}>По: {formatDate(endDate)}</span> <span style={{ color: "var(--text-primary)" }}>
По: {formatDate(endDate)}
</span>
<button <button
onClick={() => { onClick={() => {
setLocalEndDate(null); setLocalEndDate(null);
setEndDate(null); setEndDate(null);
onApply(); onApply();
}} }}
style={{ background: "none", border: "none", cursor: "pointer", color: "var(--text-muted)" }} style={{
background: "none",
border: "none",
cursor: "pointer",
color: "var(--text-muted)",
}}
> >
<FiX size={10} /> <FiX size={10} />
</button> </button>