new features, bookstack

This commit is contained in:
Matthias Hochmeister
2026-03-03 21:30:38 +01:00
parent 817329db70
commit d3561c1109
32 changed files with 1923 additions and 207 deletions

View File

@@ -40,10 +40,7 @@ import {
DialogTitle,
Divider,
IconButton,
MenuItem,
Paper,
Select,
SelectChangeEvent,
Skeleton,
Stack,
TextField,
@@ -57,8 +54,6 @@ import {
GridRenderCellParams,
GridRowParams,
} from '@mui/x-data-grid';
import { DatePicker, LocalizationProvider } from '@mui/x-date-pickers';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { de } from 'date-fns/locale';
import { format, parseISO } from 'date-fns';
import CloseIcon from '@mui/icons-material/Close';
@@ -66,6 +61,7 @@ import DownloadIcon from '@mui/icons-material/Download';
import FilterAltIcon from '@mui/icons-material/FilterAlt';
import DashboardLayout from '../../components/dashboard/DashboardLayout';
import { api } from '../../services/api';
import { fromGermanDate } from '../../utils/dateInput';
// ---------------------------------------------------------------------------
// Types — mirror the backend AuditLogEntry interface
@@ -106,8 +102,8 @@ interface AuditFilters {
userId?: string;
action?: AuditAction[];
resourceType?: AuditResourceType[];
dateFrom?: Date | null;
dateTo?: Date | null;
dateFrom?: string;
dateTo?: string;
}
// ---------------------------------------------------------------------------
@@ -349,17 +345,23 @@ const FilterPanel: React.FC<FilterPanelProps> = ({ filters, onChange, onReset })
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2 }}>
{/* Date range */}
<DatePicker
<TextField
label="Von"
value={filters.dateFrom ?? null}
onChange={(date) => onChange({ ...filters, dateFrom: date })}
slotProps={{ textField: { size: 'small', sx: { minWidth: 160 } } }}
size="small"
placeholder="TT.MM.JJJJ"
value={filters.dateFrom ?? ''}
onChange={(e) => onChange({ ...filters, dateFrom: e.target.value })}
sx={{ minWidth: 160 }}
InputLabelProps={{ shrink: true }}
/>
<DatePicker
<TextField
label="Bis"
value={filters.dateTo ?? null}
onChange={(date) => onChange({ ...filters, dateTo: date })}
slotProps={{ textField: { size: 'small', sx: { minWidth: 160 } } }}
size="small"
placeholder="TT.MM.JJJJ"
value={filters.dateTo ?? ''}
onChange={(e) => onChange({ ...filters, dateTo: e.target.value })}
sx={{ minWidth: 160 }}
InputLabelProps={{ shrink: true }}
/>
{/* Action multi-select */}
@@ -416,8 +418,8 @@ const FilterPanel: React.FC<FilterPanelProps> = ({ filters, onChange, onReset })
const DEFAULT_FILTERS: AuditFilters = {
action: [],
resourceType: [],
dateFrom: null,
dateTo: null,
dateFrom: '',
dateTo: '',
};
const AuditLog: React.FC = () => {
@@ -460,8 +462,14 @@ const AuditLog: React.FC = () => {
pageSize: String(pagination.pageSize),
};
if (f.dateFrom) params.dateFrom = f.dateFrom.toISOString();
if (f.dateTo) params.dateTo = f.dateTo.toISOString();
if (f.dateFrom) {
const iso = fromGermanDate(f.dateFrom);
if (iso) params.dateFrom = new Date(iso).toISOString();
}
if (f.dateTo) {
const iso = fromGermanDate(f.dateTo);
if (iso) params.dateTo = new Date(iso + 'T23:59:59').toISOString();
}
if (f.action && f.action.length > 0) {
params.action = f.action.join(',');
}
@@ -513,8 +521,14 @@ const AuditLog: React.FC = () => {
setExporting(true);
try {
const params: Record<string, string> = {};
if (appliedFilters.dateFrom) params.dateFrom = appliedFilters.dateFrom.toISOString();
if (appliedFilters.dateTo) params.dateTo = appliedFilters.dateTo.toISOString();
if (appliedFilters.dateFrom) {
const iso = fromGermanDate(appliedFilters.dateFrom);
if (iso) params.dateFrom = new Date(iso).toISOString();
}
if (appliedFilters.dateTo) {
const iso = fromGermanDate(appliedFilters.dateTo);
if (iso) params.dateTo = new Date(iso + 'T23:59:59').toISOString();
}
if (appliedFilters.action && appliedFilters.action.length > 0) {
params.action = appliedFilters.action.join(',');
}
@@ -637,8 +651,7 @@ const AuditLog: React.FC = () => {
// -------------------------------------------------------------------------
return (
<LocalizationProvider dateAdapter={AdapterDateFns} adapterLocale={de}>
<DashboardLayout>
<DashboardLayout>
<Container maxWidth="xl">
{/* Header */}
<Stack
@@ -726,7 +739,6 @@ const AuditLog: React.FC = () => {
/>
</Container>
</DashboardLayout>
</LocalizationProvider>
);
};