gitscope
← marzneshin / v0.7.2 / dashboard/src/libs/entity-table/entity-table.tsx
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/libs/entity-table/entity-table.tsx · TypeScript
Blame Raw
  1import { useMemo } from "react";
  2import { Button } from "@marzneshin/common/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    usePrimaryFiltering,
 11    usePagination,
 12    useEntityTable,
 13    useVisibility,
 14    useSorting,
 15    type UseRowSelectionReturn,
 16    type FetchEntityReturn,
 17    type QueryKey,
 18    type EntityQueryKeyType,
 19    useFilters,
 20} from "./hooks";
 21
 22export interface EntityTableProps<T> {
 23    columns: ColumnDef<T>[];
 24    primaryFilter: string;
 25    entityKey: string;
 26    rowSelection?: UseRowSelectionReturn;
 27    fetchEntity: ({ queryKey }: EntityQueryKeyType) => FetchEntityReturn<T>;
 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
 48    const query: QueryKey = [
 49        entityKey,
 50        {
 51            page: pageIndex,
 52            size: pageSize,
 53        },
 54        columnPrimaryFilter.columnFilters,
 55        {
 56            sortBy: sorting.sorting[0]?.id || "created_at",
 57            desc: sorting.sorting[0]?.desc || true,
 58        },
 59        { filters: filters.columnsFilter }
 60    ];
 61
 62    const { data, isFetching } = useQuery({
 63        queryFn: fetchEntity,
 64        queryKey: query,
 65        initialData: { entities: [], 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.entities, primaryFilter: columnPrimaryFilter, filters, isLoading: isFetching }),
 81        [table, data.entities, filters, columnPrimaryFilter, isFetching],
 82    );
 83
 84    return (
 85        <EntityTableContext.Provider value={contextValue}>
 86            <div className="flex w-full 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                    <TableSearch />
 97                </div>
 98                <div className="w-full rounded-md border">
 99                    <EntityDataTable columns={columns} onRowClick={onOpen} />
100                    <DataTablePagination table={table} />
101                </div>
102            </div>
103        </EntityTableContext.Provider>
104    );
105}