gitscope
← marzneshin / v0.3.0-alpha8 / dashboard/src/components/entity-table/index.tsx
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/components/entity-table/index.tsx · TypeScript
Blame Raw
  1import { FC, useEffect, useState } from "react";
  2import { Button, DataTableViewOptions } from "@marzneshin/components";
  3import { useTranslation } from "react-i18next";
  4import { useQuery } from "@tanstack/react-query";
  5import { EntityTableContext } from "./entity-table-provider";
  6import { EntityDataTable } from "./table"
  7import { DataTablePagination } from "./table-pagination"
  8import { TableFiltering } from "./table-filtering";
  9import {
 10    UseRowSelectionReturn,
 11    UseDialogProps,
 12    useFiltering,
 13    useDialog,
 14    usePagination,
 15    FetchEntityReturn,
 16    useEntityTable,
 17    useVisibility,
 18    useSorting,
 19    SortableQueryKey,
 20    QueryKey,
 21    EntityQueryKeyType,
 22} from "./hooks";
 23
 24interface EntityTableProps<T> {
 25    fetchEntity: ({ queryKey }: EntityQueryKeyType) => FetchEntityReturn<T>;
 26    MutationDialog: FC<UseDialogProps<T>>;
 27    DeleteConfirmationDialog: FC<UseDialogProps<T>>;
 28    SettingsDialog: FC<UseDialogProps<T | any>>;
 29    columnsFn: any;
 30    filteredColumn: string;
 31    entityKey: string
 32    rowSelection?: UseRowSelectionReturn
 33    manualSorting?: boolean
 34}
 35
 36export function EntityTable<T>({
 37    fetchEntity,
 38    MutationDialog,
 39    DeleteConfirmationDialog,
 40    SettingsDialog,
 41    columnsFn,
 42    filteredColumn,
 43    rowSelection,
 44    entityKey,
 45    manualSorting = false
 46}: EntityTableProps<T>) {
 47    const [mutationDialogOpen, setMutationDialogOpen] = useDialog();
 48    const [deleteDialogOpen, setDeleteDialogOpen] = useDialog();
 49    const [settingsDialogOpen, setSettingsDialogOpen] = useDialog();
 50    const [selectedEntity, selectEntity] = useState<T | null>(null);
 51
 52    const onEdit = (entity: T) => {
 53        selectEntity(entity);
 54        setMutationDialogOpen(true);
 55    };
 56
 57    const onDelete = (entity: T) => {
 58        selectEntity(entity);
 59        setDeleteDialogOpen(true);
 60    };
 61
 62    const onCreate = () => {
 63        selectEntity(null);
 64        setMutationDialogOpen(true);
 65    };
 66
 67    const onOpen = (entity: T) => {
 68        selectEntity(entity);
 69        setSettingsDialogOpen(true);
 70    };
 71
 72    const { t } = useTranslation()
 73    const filtering = useFiltering({ column: filteredColumn })
 74    const sorting = useSorting()
 75    const visibility = useVisibility()
 76    const { onPaginationChange, pageIndex, pageSize } = usePagination();
 77    const sortedQuery: SortableQueryKey = [
 78        entityKey,
 79        pageIndex,
 80        pageSize,
 81        filtering.columnFilters,
 82        sorting.sorting[0]?.id ? sorting.sorting[0].id : "created_at",
 83        sorting.sorting[0]?.desc]
 84    const query: QueryKey = [entityKey, pageIndex, pageSize, filtering.columnFilters]
 85
 86    const { data, isLoading } = useQuery({
 87        queryFn: fetchEntity,
 88        queryKey: manualSorting ? sortedQuery : query,
 89        initialData: { entity: [], pageCount: 1 }
 90    });
 91
 92    const columns = columnsFn({ onEdit, onDelete, onOpen })
 93    const table = useEntityTable({
 94        data,
 95        columns,
 96        pageSize,
 97        pageIndex,
 98        rowSelection,
 99        visibility,
100        sorting,
101        onPaginationChange
102    })
103
104    useEffect(() => table.setPageIndex(1), [filtering.columnFilters, table])
105
106    // TODO: Move the selectedEntity to context
107    return (
108        <EntityTableContext.Provider value={{ table, data: data.entity, filtering, isLoading }}>
109            <SettingsDialog
110                open={settingsDialogOpen}
111                onOpenChange={setSettingsDialogOpen}
112                entity={selectedEntity}
113            />
114            <DeleteConfirmationDialog
115                open={deleteDialogOpen}
116                onOpenChange={setDeleteDialogOpen}
117                entity={selectedEntity}
118            />
119            <MutationDialog
120                open={mutationDialogOpen}
121                onOpenChange={setMutationDialogOpen}
122                entity={selectedEntity}
123            />
124            <div className="flex flex-col">
125                <div className="flex items-center py-4">
126                    <TableFiltering />
127                    <DataTableViewOptions table={table} />
128                    {onCreate && (
129                        <Button
130                            aria-label={`create-${entityKey}`}
131                            onClick={onCreate}>
132                            {t('create')}
133                        </Button>
134                    )}
135                </div>
136                <div className="w-full rounded-md border">
137                    <EntityDataTable
138                        columns={columns}
139                        onRowClick={onOpen}
140                    />
141                    <DataTablePagination />
142                </div>
143            </div>
144        </EntityTableContext.Provider>
145    );
146}
147
148export * from './hooks'