mirror of
https://github.com/Dictionarry-Hub/profilarr.git
synced 2026-01-22 10:51:02 +01:00
feat: implement dynamic log type filtering and selection in LogContainer and LogMenu components
This commit is contained in:
@@ -4,15 +4,10 @@ import {Logs} from '@api/logs';
|
||||
import LogMenu from './LogMenu';
|
||||
import LogViewer from './LogViewer';
|
||||
|
||||
const guessLogType = filename => {
|
||||
if (filename.startsWith('importarr')) return 'Importarr';
|
||||
if (filename.startsWith('profilarr')) return 'General';
|
||||
return 'Other';
|
||||
};
|
||||
|
||||
const LogContainer = () => {
|
||||
const [allLogFiles, setAllLogFiles] = useState([]);
|
||||
const [logType, setLogType] = useState('General');
|
||||
const [logTypes, setLogTypes] = useState(new Set());
|
||||
const [selectedType, setSelectedType] = useState('');
|
||||
const [filteredFiles, setFilteredFiles] = useState([]);
|
||||
const [selectedFile, setSelectedFile] = useState('');
|
||||
const [filters, setFilters] = useState({lines: '', level: '', search: ''});
|
||||
@@ -26,17 +21,43 @@ const LogContainer = () => {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const matched = allLogFiles
|
||||
.filter(f => guessLogType(f.filename) === logType)
|
||||
.sort((a, b) => b.last_modified - a.last_modified);
|
||||
setFilteredFiles(matched);
|
||||
if (matched.length) {
|
||||
setSelectedFile(matched[0].filename);
|
||||
} else {
|
||||
setSelectedFile('');
|
||||
setLogContent([]);
|
||||
if (allLogFiles.length > 0) {
|
||||
// Extract unique log types from filenames
|
||||
const types = new Set(
|
||||
allLogFiles.map(f => {
|
||||
const match = f.filename.match(/^([a-zA-Z]+)/);
|
||||
return match ? match[1].toLowerCase() : 'other';
|
||||
})
|
||||
);
|
||||
setLogTypes(types);
|
||||
|
||||
// Set initial type if not already set
|
||||
if (!selectedType && types.size > 0) {
|
||||
setSelectedType(Array.from(types)[0]);
|
||||
}
|
||||
}
|
||||
}, [logType, allLogFiles]);
|
||||
}, [allLogFiles]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedType) {
|
||||
const matched = allLogFiles
|
||||
.filter(f => {
|
||||
const fileType =
|
||||
f.filename.match(/^([a-zA-Z]+)/)?.[1].toLowerCase() ||
|
||||
'other';
|
||||
return fileType === selectedType;
|
||||
})
|
||||
.sort((a, b) => b.last_modified - a.last_modified);
|
||||
|
||||
setFilteredFiles(matched);
|
||||
if (matched.length) {
|
||||
setSelectedFile(matched[0].filename);
|
||||
} else {
|
||||
setSelectedFile('');
|
||||
setLogContent([]);
|
||||
}
|
||||
}
|
||||
}, [selectedType, allLogFiles]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedFile) {
|
||||
@@ -95,8 +116,9 @@ const LogContainer = () => {
|
||||
return (
|
||||
<div className='h-full flex flex-col space-y-4'>
|
||||
<LogMenu
|
||||
logType={logType}
|
||||
setLogType={setLogType}
|
||||
logTypes={Array.from(logTypes)}
|
||||
selectedType={selectedType}
|
||||
setSelectedType={setSelectedType}
|
||||
selectedFile={selectedFile}
|
||||
setSelectedFile={setSelectedFile}
|
||||
filteredFiles={filteredFiles}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
// LogMenu.jsx
|
||||
import React from 'react';
|
||||
import {Search} from 'lucide-react';
|
||||
|
||||
const LogMenu = ({
|
||||
logType,
|
||||
setLogType,
|
||||
logTypes,
|
||||
selectedType,
|
||||
setSelectedType,
|
||||
selectedFile,
|
||||
setSelectedFile,
|
||||
filteredFiles,
|
||||
@@ -13,20 +15,25 @@ const LogMenu = ({
|
||||
const selectStyles =
|
||||
'bg-gray-900 text-sm text-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500';
|
||||
|
||||
const formatLogType = type => {
|
||||
return type.charAt(0).toUpperCase() + type.slice(1);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='bg-gray-800 rounded-lg border border-gray-700 shadow-xl p-4'>
|
||||
<div className='space-y-4'>
|
||||
{/* Top Row Filters */}
|
||||
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4'>
|
||||
{/* Log Type Selection */}
|
||||
<div className='relative'>
|
||||
<select
|
||||
className={`w-full px-3 py-1.5 rounded-md appearance-none cursor-pointer ${selectStyles}`}
|
||||
value={logType}
|
||||
onChange={e => setLogType(e.target.value)}>
|
||||
<option value='General'>Type: General</option>
|
||||
<option value='Importarr'>Type: Importarr</option>
|
||||
<option value='Other'>Type: Other</option>
|
||||
value={selectedType}
|
||||
onChange={e => setSelectedType(e.target.value)}>
|
||||
{logTypes.map(type => (
|
||||
<option key={type} value={type}>
|
||||
Type: {formatLogType(type)}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<div className='absolute inset-y-0 right-0 flex items-center px-2 pointer-events-none'>
|
||||
<svg
|
||||
@@ -38,7 +45,6 @@ const LogMenu = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Log File Selection */}
|
||||
<div className='relative'>
|
||||
<select
|
||||
className={`w-full px-3 py-1.5 rounded-md appearance-none cursor-pointer ${selectStyles}`}
|
||||
@@ -60,7 +66,6 @@ const LogMenu = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Lines Filter */}
|
||||
<input
|
||||
type='number'
|
||||
className={`w-full px-3 py-1.5 rounded-md ${selectStyles}`}
|
||||
@@ -69,7 +74,6 @@ const LogMenu = ({
|
||||
placeholder='Lines: last N lines...'
|
||||
/>
|
||||
|
||||
{/* Log Level Filter */}
|
||||
<div className='relative'>
|
||||
<select
|
||||
className={`w-full px-3 py-1.5 rounded-md appearance-none cursor-pointer ${selectStyles}`}
|
||||
@@ -94,7 +98,6 @@ const LogMenu = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Search Bar - Full Width */}
|
||||
<div className='relative'>
|
||||
<div className='absolute inset-y-0 left-3 flex items-center pointer-events-none'>
|
||||
<Search size={16} className='text-gray-400' />
|
||||
|
||||
@@ -74,7 +74,7 @@ const LogViewer = ({
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className='h-[calc(100vh-28rem)] overflow-y-auto p-4'
|
||||
className='h-[calc(100vh-28rem)] overflow-y-auto p-4 scrollable'
|
||||
style={{fontSize: `${zoom}rem`}}>
|
||||
{loading && (
|
||||
<div className='flex items-center justify-center p-4 text-gray-400'>
|
||||
|
||||
Reference in New Issue
Block a user