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