gitscope
← marzneshin / v0.5.3 / dashboard/src/features/entity-table/entity-table.tsx
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/features/entity-table/entity-table.tsx · TypeScript
Blame Raw
  1import { useMemo } from "react";
  2import { Button, DataTableViewOptions } from "@marzneshin/components";
  3import { useTranslation } from "react-i18next";
  4import { useQuery } from "@tanstack/react-query";
  5import { ColumnDef } from "@tanstack/react-table";
  6import { EntityTableContext } from "./contexts";
  7import { TableFiltering, DataTablePagination, EntityDataTable } from "./components";
  8import {
  9    type UseRowSelectionReturn,
 10    useFiltering,
 11    usePagination,
 12    type FetchEntityReturn,
 13    useEntityTable,
 14    useVisibility,
 15    useSorting,
 16    type SortableQueryKey,
 17    type QueryKey,
 18    type EntityQueryKeyType,
 19} from "./hooks";
 20
 21export interface EntityTableProps<T> {
 22    fetchEntity: ({ queryKey }: EntityQueryKeyType) => FetchEntityReturn<T>;
 23    columns: ColumnDef<T>[];
 24    filteredColumn: string;
 25    entityKey: string;
 26    rowSelection?: UseRowSelectionReturn;
 27    manualSorting?: boolean;
 28    onCreate: () => void;
 29    onOpen: (entity: any) => void;
 30}
 31
 32export function EntityTable<T>({
 33    fetchEntity,
 34    columns,
 35    filteredColumn,
 36    rowSelection,
 37    entityKey,
 38    manualSorting = false,
 39    onCreate,
 40    onOpen,
 41}: EntityTableProps<T>) {
 42    const { t } = useTranslation();
 43    const filtering = useFiltering({ column: filteredColumn });
 44    const sorting = useSorting();
 45    const visibility = useVisibility();
 46    const { onPaginationChange, pageIndex, pageSize } = usePagination();
 47    const sortedQuery: SortableQueryKey = [
 48        entityKey,
 49        pageIndex,
 50        pageSize,
 51        filtering.columnFilters,
 52        sorting.sorting[0]?.id ? sorting.sorting[0].id : "created_at",
 53        sorting.sorting[0]?.desc,
 54    ];
 55    const query: QueryKey = [
 56        entityKey,
 57        pageIndex,
 58        pageSize,
 59        filtering.columnFilters,
 60    ];
 61
 62    const { data, isFetching } = useQuery({
 63        queryFn: fetchEntity,
 64        queryKey: manualSorting ? sortedQuery : query,
 65        initialData: { entity: [], pageCount: 1 },
 66    });
 67
 68    const table = useEntityTable({
 69        data,
 70        columns,
 71        pageSize,
 72        pageIndex,
 73        rowSelection,
 74        visibility,
 75        sorting,
 76        onPaginationChange,
 77    });
 78
 79    const contextValue = useMemo(
 80        () => ({ table, data: data.entity, filtering, isLoading: isFetching }),
 81        [table, data.entity, filtering, isFetching],
 82    );
 83
 84    return (
 85        <EntityTableContext.Provider value={contextValue}>
 86            <div className="flex flex-col">
 87                <div className="flex flex-col md:flex-row-reverse items-center py-4 gap-2 w-full">
 88                    <div className="flex flex-row items-center w-full">
 89                        <DataTableViewOptions table={table} />
 90                        {onCreate && (
 91                            <Button aria-label={`create-${entityKey}`} onClick={onCreate}>
 92                                {t("create")}
 93                            </Button>
 94                        )}
 95                    </div>
 96                    <TableFiltering />
 97                </div>
 98                <div className="w-full rounded-md border">
 99                    <EntityDataTable columns={columns} onRowClick={onOpen} />
100                    <DataTablePagination />
101                </div>
102            </div>
103        </EntityTableContext.Provider>
104    );
105}