import type { ChangeEvent } from 'react'; import { useContext, useEffect } from 'react'; import { NavLink } from 'react-router-dom'; import tw from 'twin.macro'; import type { Filters } from '@/api/admin/nodes/allocations/getAllocations'; import getAllocations, { Context as AllocationsContext } from '@/api/admin/nodes/allocations/getAllocations'; import AdminCheckbox from '@/components/admin/AdminCheckbox'; import AdminTable, { ContentWrapper, Loading, NoItems, Pagination, TableBody, TableHead, TableHeader, useTableHooks, } from '@/components/admin/AdminTable'; import DeleteAllocationButton from '@/components/admin/nodes/allocations/DeleteAllocationButton'; import CopyOnClick from '@/components/elements/CopyOnClick'; import useFlash from '@/plugins/useFlash'; import { AdminContext } from '@/state/admin'; function RowCheckbox({ id }: { id: number }) { const isChecked = AdminContext.useStoreState(state => state.allocations.selectedAllocations.indexOf(id) >= 0); const appendSelectedAllocation = AdminContext.useStoreActions( actions => actions.allocations.appendSelectedAllocation, ); const removeSelectedAllocation = AdminContext.useStoreActions( actions => actions.allocations.removeSelectedAllocation, ); return ( ) => { if (e.currentTarget.checked) { appendSelectedAllocation(id); } else { removeSelectedAllocation(id); } }} /> ); } interface Props { nodeId: number; filters?: Filters; } function AllocationsTable({ nodeId, filters }: Props) { const { clearFlashes, clearAndAddHttpError } = useFlash(); const { page, setPage, setFilters, sort, setSort, sortDirection } = useContext(AllocationsContext); const { data: allocations, error, isValidating, mutate } = getAllocations(nodeId, ['server']); const length = allocations?.items?.length || 0; const setSelectedAllocations = AdminContext.useStoreActions(actions => actions.allocations.setSelectedAllocations); const selectedAllocationLength = AdminContext.useStoreState(state => state.allocations.selectedAllocations.length); const onSelectAllClick = (e: ChangeEvent) => { setSelectedAllocations( e.currentTarget.checked ? allocations?.items?.map?.(allocation => allocation.id) || [] : [], ); }; const onSearch = (query: string): Promise => { return new Promise(resolve => { if (query.length < 2) { setFilters(filters || null); } else { setFilters({ ...filters, ip: query }); } return resolve(); }); }; useEffect(() => { setSelectedAllocations([]); }, [page]); useEffect(() => { if (!error) { clearFlashes('allocations'); return; } clearAndAddHttpError({ key: 'allocations', error }); }, [error]); return (
setSort('ip')} /> setSort('port')} /> {allocations !== undefined && !error && !isValidating && length > 0 && allocations.items.map(allocation => ( {allocation.alias !== null ? ( ) : ( {allocation.relations.server !== undefined ? ( ) : ( ))}
{allocation.ip} {allocation.alias} )} {allocation.port} {allocation.relations.server.name} )} { await mutate(allocations => ({ pagination: allocations!.pagination, items: allocations!.items.filter( a => a.id === allocation.id, ), })); // Go back a page if no more items will exist on the current page. if (allocations?.items.length - (1 % 10) === 0) { setPage(p => p - 1); } }} />
{allocations === undefined || (error && isValidating) ? ( ) : length < 1 ? ( ) : null}
); } export default (props: Props) => { const hooks = useTableHooks(props.filters); return ( ); };