diff --git a/src/components/FormGenerator/FormGeneratorTable/FormGeneratorTable.tsx b/src/components/FormGenerator/FormGeneratorTable/FormGeneratorTable.tsx index ef353ca..82858e6 100644 --- a/src/components/FormGenerator/FormGeneratorTable/FormGeneratorTable.tsx +++ b/src/components/FormGenerator/FormGeneratorTable/FormGeneratorTable.tsx @@ -531,6 +531,10 @@ export function FormGeneratorTable>({ // Debounce search term for backend calls const [debouncedSearchTerm, setDebouncedSearchTerm] = useState(searchTerm); + + // Bumped by the refresh button so the backend-refetch useEffect re-runs even + // when no other state (page/filters/sort/search) changed. + const [refreshNonce, setRefreshNonce] = useState(0); useEffect(() => { const timer = setTimeout(() => { @@ -608,7 +612,7 @@ export function FormGeneratorTable>({ console.error('❌ FormGeneratorTable: Backend refetch failed:', error); }); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [debouncedSearchTerm, filters, sortConfigs, currentPage, currentPageSize, supportsBackendPagination]); + }, [debouncedSearchTerm, filters, sortConfigs, currentPage, currentPageSize, supportsBackendPagination, refreshNonce]); // Refs for action buttons containers to detect clicks outside const actionButtonsRefs = useRef>(new Map()); @@ -1920,7 +1924,22 @@ export function FormGeneratorTable>({ }, }; }) : undefined} - onRefresh={onRefresh} + onRefresh={ + // The refresh button resets pagination to page 1, clears any + // optimistic hidden-rows state, and bumps `refreshNonce` so the + // backend-refetch useEffect re-runs (even when no state changed). + // When the table supports backend pagination, the external + // onRefresh is skipped to avoid a double-fetch — the useEffect + // already calls hookData.refetch with the correct pagination. + onRefresh + ? () => { + if (optimisticallyDeletedIds.size > 0) setOptimisticallyDeletedIds(new Set()); + setCurrentPage(1); + setRefreshNonce(n => n + 1); + if (!supportsBackendPagination) onRefresh(); + } + : undefined + } searchable={searchable} selectable={selectable} loading={loading} diff --git a/src/pages/billing/BillingDataView.tsx b/src/pages/billing/BillingDataView.tsx index f03d9a9..d0ca931 100644 --- a/src/pages/billing/BillingDataView.tsx +++ b/src/pages/billing/BillingDataView.tsx @@ -475,7 +475,7 @@ export const BillingDataView: React.FC = () => { { key: 'aicoreProvider', label: t('Anbieter'), type: 'text' as any, sortable: true, filterable: true, width: 120 }, { key: 'aicoreModel', label: t('Modell'), type: 'text' as any, sortable: true, filterable: true, width: 150 }, { key: 'featureCode', label: t('Feature'), type: 'text' as any, sortable: true, filterable: true, width: 120 }, - { key: 'amount', label: t('Betrag (CHF)'), type: 'number' as any, sortable: true, width: 120 }, + { key: 'amount', label: t('Betrag (CHF)'), type: 'number' as any, sortable: true, searchable: true, width: 120 }, ], [t]); const totalBalance = useMemo(() => { @@ -609,7 +609,7 @@ export const BillingDataView: React.FC = () => { fontWeight: chartMode === 'pie' ? 600 : 400, }} > - {t('Pie')} + {t('Kreis')}