mirror of
https://github.com/idanoo/autobrr
synced 2025-07-24 01:09:13 +00:00
feat(logs): improve log search with regex (#920)
* improve log search with regex * show empty log if regex invalid * show red icon if regex is invalid
This commit is contained in:
parent
759b17c9f0
commit
8347d6ded1
1 changed files with 33 additions and 21 deletions
|
@ -23,6 +23,7 @@ import { baseUrl } from "@utils";
|
||||||
import { RingResizeSpinner } from "@components/Icons";
|
import { RingResizeSpinner } from "@components/Icons";
|
||||||
import { toast } from "react-hot-toast";
|
import { toast } from "react-hot-toast";
|
||||||
import Toast from "@components/notifications/Toast";
|
import Toast from "@components/notifications/Toast";
|
||||||
|
import { ExclamationCircleIcon } from "@heroicons/react/24/solid";
|
||||||
|
|
||||||
|
|
||||||
type LogEvent = {
|
type LogEvent = {
|
||||||
|
@ -48,7 +49,9 @@ export const Logs = () => {
|
||||||
|
|
||||||
const [logs, setLogs] = useState<LogEvent[]>([]);
|
const [logs, setLogs] = useState<LogEvent[]>([]);
|
||||||
const [searchFilter, setSearchFilter] = useState("");
|
const [searchFilter, setSearchFilter] = useState("");
|
||||||
|
const [regexPattern, setRegexPattern] = useState<RegExp | null>(null);
|
||||||
const [filteredLogs, setFilteredLogs] = useState<LogEvent[]>([]);
|
const [filteredLogs, setFilteredLogs] = useState<LogEvent[]>([]);
|
||||||
|
const [isInvalidRegex, setIsInvalidRegex] = useState(false);
|
||||||
|
|
||||||
const scrollToBottom = () => {
|
const scrollToBottom = () => {
|
||||||
messagesEndRef.current?.scrollIntoView({ behavior: "smooth", block: "end", inline: "end" });
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth", block: "end", inline: "end" });
|
||||||
|
@ -71,16 +74,21 @@ export const Logs = () => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!searchFilter.length) {
|
if (!searchFilter.length) {
|
||||||
setFilteredLogs(logs);
|
setFilteredLogs(logs);
|
||||||
|
setIsInvalidRegex(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newLogs: LogEvent[] = [];
|
try {
|
||||||
logs.forEach((log) => {
|
const pattern = new RegExp(searchFilter, "i");
|
||||||
if (log.message.indexOf(searchFilter) !== -1)
|
setRegexPattern(pattern);
|
||||||
newLogs.push(log);
|
const newLogs = logs.filter(log => pattern.test(log.message));
|
||||||
});
|
|
||||||
|
|
||||||
setFilteredLogs(newLogs);
|
setFilteredLogs(newLogs);
|
||||||
|
setIsInvalidRegex(false);
|
||||||
|
} catch (error) {
|
||||||
|
// Handle regex errors by showing nothing when the regex pattern is invalid
|
||||||
|
setFilteredLogs([]);
|
||||||
|
setIsInvalidRegex(true);
|
||||||
|
}
|
||||||
}, [logs, searchFilter]);
|
}, [logs, searchFilter]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -104,17 +112,21 @@ export const Logs = () => {
|
||||||
<DebounceInput
|
<DebounceInput
|
||||||
minLength={2}
|
minLength={2}
|
||||||
debounceTimeout={200}
|
debounceTimeout={200}
|
||||||
onChange={(event) => setSearchFilter(event.target.value.toLowerCase().trim())}
|
onChange={(event) => {
|
||||||
id="filter"
|
const inputValue = event.target.value.toLowerCase().trim();
|
||||||
type="text"
|
setSearchFilter(inputValue);
|
||||||
autoComplete="off"
|
}}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"focus:ring-blue-500 dark:focus:ring-blue-500 focus:border-blue-500 dark:focus:border-blue-500 border-gray-300 dark:border-gray-700",
|
"focus:ring-blue-500 dark:focus:ring-blue-500 focus:border-blue-500 dark:focus:border-blue-500 border-gray-300 dark:border-gray-700",
|
||||||
"block w-full dark:bg-gray-900 shadow-sm dark:text-gray-100 sm:text-sm rounded-md"
|
"block w-full dark:bg-gray-900 shadow-sm dark:text-gray-100 sm:text-sm rounded-md"
|
||||||
)}
|
)}
|
||||||
placeholder="Enter a string to filter logs by..."
|
placeholder="Enter a regex pattern to filter logs by..."
|
||||||
/>
|
/>
|
||||||
|
{isInvalidRegex && (
|
||||||
|
<div className="absolute mt-1.5 right-14 items-center text-xs text-red-500">
|
||||||
|
<ExclamationCircleIcon className="h-6 w-6 inline mr-1" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<LogsDropdown />
|
<LogsDropdown />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue