eat(ausruestung): allow create role to view full list, add Mitglieder pagination, add admin reset for persoenliche Ausruestung

This commit is contained in:
Matthias Hochmeister
2026-04-16 07:52:36 +02:00
parent 3f8c4d151d
commit dac0b79b3b
7 changed files with 46 additions and 11 deletions

View File

@@ -45,6 +45,7 @@ const RESET_SECTIONS: ResetSection[] = [
{ key: 'reset-buchhaltung-transaktionen', label: 'Buchhaltung: Transaktionen loeschen', description: 'Alle Buchungen und Transaktionen loeschen und Nummerierung zuruecksetzen. Konten und Haushaltsjahre bleiben erhalten.' },
{ key: 'reset-buchhaltung-konten', label: 'Buchhaltung: Konten loeschen', description: 'Alle Konten und alle zugehoerigen Transaktionen loeschen und Nummerierung zuruecksetzen. Haushaltsjahre bleiben erhalten.' },
{ key: 'reset-buchhaltung-bankkonten', label: 'Buchhaltung: Bankkonten loeschen', description: 'Alle Bankkonten loeschen und Nummerierung zuruecksetzen.' },
{ key: 'reset-persoenliche-ausruestung', label: 'Persoenliche Ausruestung zuruecksetzen', description: 'Alle persoenlichen Ausruestungszuweisungen loeschen. Zuordnungen in Anfragen werden zurueckgesetzt.' },
];
interface SectionState {

View File

@@ -344,6 +344,22 @@ function Mitglieder() {
paginationEnabled={false}
stickyHeader
/>
<TablePagination
component="div"
count={total}
page={page}
onPageChange={(_e, newPage) => setPage(newPage)}
rowsPerPage={pageSize}
rowsPerPageOptions={[25, 50, 100, { value: -1, label: 'Alle' }]}
onRowsPerPageChange={(e) => {
setPageSize(parseInt(e.target.value, 10));
setPage(0);
}}
labelRowsPerPage="Einträge pro Seite:"
labelDisplayedRows={({ from, to, count }) =>
`${from}${to} von ${count !== -1 ? count : `mehr als ${to}`}`
}
/>
</Paper>
</Container>

View File

@@ -37,6 +37,7 @@ function PersoenlicheAusruestungPage() {
const canViewAll = hasPermission('persoenliche_ausruestung:view_all');
const canCreate = hasPermission('persoenliche_ausruestung:create');
const canSeeAll = canViewAll || canCreate;
const canApprove = hasPermission('ausruestungsanfrage:approve');
const [activeTab, setActiveTab] = useState(0);
@@ -47,7 +48,7 @@ function PersoenlicheAusruestungPage() {
// Data queries
const { data: items, isLoading } = useQuery({
queryKey: ['persoenliche-ausruestung', 'all'],
queryFn: () => canViewAll ? personalEquipmentApi.getAll() : personalEquipmentApi.getMy(),
queryFn: () => canSeeAll ? personalEquipmentApi.getAll() : personalEquipmentApi.getMy(),
staleTime: 2 * 60 * 1000,
});
@@ -55,7 +56,7 @@ function PersoenlicheAusruestungPage() {
queryKey: ['members-list-compact'],
queryFn: () => membersService.getMembers({ pageSize: 500 }),
staleTime: 5 * 60 * 1000,
enabled: canViewAll,
enabled: canSeeAll,
});
const { data: unassignedPositions, isLoading: unassignedLoading } = useQuery({
@@ -129,7 +130,7 @@ function PersoenlicheAusruestungPage() {
<MenuItem key={key} value={key}>{label}</MenuItem>
))}
</TextField>
{canViewAll && (
{canSeeAll && (
<Autocomplete
size="small"
options={memberOptions}
@@ -176,7 +177,7 @@ function PersoenlicheAusruestungPage() {
<tr>
<th>Bezeichnung</th>
<th>Kategorie</th>
{canViewAll && <th>Benutzer</th>}
{canSeeAll && <th>Benutzer</th>}
<th>Größe</th>
<th>Zustand</th>
<th>Anschaffung</th>
@@ -185,7 +186,7 @@ function PersoenlicheAusruestungPage() {
<tbody>
{isLoading ? (
<tr>
<td colSpan={canViewAll ? 6 : 5}>
<td colSpan={canSeeAll ? 6 : 5}>
<Typography color="text.secondary" sx={{ py: 4, textAlign: 'center' }}>
Lade Daten
</Typography>
@@ -193,7 +194,7 @@ function PersoenlicheAusruestungPage() {
</tr>
) : filtered.length === 0 ? (
<tr>
<td colSpan={canViewAll ? 6 : 5}>
<td colSpan={canSeeAll ? 6 : 5}>
<Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', py: 6 }}>
<CheckroomIcon sx={{ fontSize: 48, color: 'text.disabled', mb: 1 }} />
<Typography color="text.secondary">
@@ -231,7 +232,7 @@ function PersoenlicheAusruestungPage() {
<td>
<Typography variant="body2">{item.kategorie ?? '—'}</Typography>
</td>
{canViewAll && (
{canSeeAll && (
<td>
<Typography variant="body2">
{item.user_display_name ?? item.benutzer_name ?? '—'}

View File

@@ -40,7 +40,7 @@ function buildParams(filters?: MemberFilters): URLSearchParams {
if (filters.search) params.append('search', filters.search);
if (filters.page) params.append('page', String(filters.page));
if (filters.pageSize) params.append('pageSize', String(filters.pageSize));
if (filters.pageSize !== undefined) params.append('pageSize', String(filters.pageSize));
filters.status?.forEach((s) => params.append('status[]', s));
filters.dienstgrad?.forEach((d) => params.append('dienstgrad[]', d));