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