gitscope
← marzneshin / v0.3.0-alpha3 / 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, 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    EntityQueryKeyType,
 17    useEntityTable,
 18    useVisibility,
 19    useSorting
 20} from "./hooks";
 21
 22interface EntityTableProps<T> {
 23    fetchEntity: ({ queryKey }: EntityQueryKeyType) => FetchEntityReturn<T>;
 24    MutationDialog: FC<UseDialogProps<T>>;
 25    DeleteConfirmationDialog: FC<UseDialogProps<T>>;
 26    SettingsDialog: FC<UseDialogProps<T | any>>;
 27    columnsFn: any;
 28    filteredColumn: string;
 29    entityKey: string
 30    rowSelection?: UseRowSelectionReturn
 31}
 32
 33export function EntityTable<T>({
 34    fetchEntity,
 35    MutationDialog,
 36    DeleteConfirmationDialog,
 37    SettingsDialog,
 38    columnsFn,
 39    filteredColumn,
 40    rowSelection,
 41    entityKey,
 42}: EntityTableProps<T>) {
 43    const [mutationDialogOpen, setMutationDialogOpen] = useDialog();
 44    const [deleteDialogOpen, setDeleteDialogOpen] = useDialog();
 45    const [settingsDialogOpen, setSettingsDialogOpen] = useDialog();
 46    const [selectedEntity, selectEntity] = useState<T | null>(null);
 47
 48    const onEdit = (entity: T) => {
 49        selectEntity(entity);
 50        setMutationDialogOpen(true);
 51    };
 52
 53    const onDelete = (entity: T) => {
 54        selectEntity(entity);
 55        setDeleteDialogOpen(true);
 56    };
 57
 58    const onCreate = () => {
 59        selectEntity(null);
 60        setMutationDialogOpen(true);
 61    };
 62
 63    const onOpen = (entity: T) => {
 64        selectEntity(entity);
 65        setSettingsDialogOpen(true);
 66    };
 67
 68    const { t } = useTranslation()
 69    const filtering = useFiltering({ column: filteredColumn })
 70    const sorting = useSorting()
 71    const visibility = useVisibility()
 72    const { onPaginationChange, pageIndex, pageSize } = usePagination();
 73
 74    const { data } = useQuery({
 75        queryFn: fetchEntity,
 76        queryKey: [entityKey, pageIndex, pageSize],
 77        initialData: { entity: [], pageCount: 1 }
 78    });
 79
 80    const columns = columnsFn({ onEdit, onDelete, onOpen })
 81    const table = useEntityTable({
 82        data,
 83        filtering,
 84        columns,
 85        pageSize,
 86        pageIndex,
 87        rowSelection,
 88        visibility,
 89        sorting,
 90        onPaginationChange
 91    })
 92
 93    // TODO: Move the selectedEntity to context
 94    return (
 95        <EntityTableContext.Provider value={{ table, data: data.entity, filtering }}>
 96            <SettingsDialog
 97                open={settingsDialogOpen}
 98                onOpenChange={setSettingsDialogOpen}
 99                entity={selectedEntity}
100            />
101            <DeleteConfirmationDialog
102                open={deleteDialogOpen}
103                onOpenChange={setDeleteDialogOpen}
104                entity={selectedEntity}
105            />
106            <MutationDialog
107                open={mutationDialogOpen}
108                onOpenChange={setMutationDialogOpen}
109                entity={selectedEntity}
110            />
111            <div className="flex flex-col">
112                <div className="flex items-center py-4">
113                    <TableFiltering />
114                    <DataTableViewOptions table={table} />
115                    {onCreate && (
116                        <Button
117                            aria-label={`create-${entityKey}`}
118                            onClick={onCreate}>
119                            {t('create')}
120                        </Button>
121                    )}
122                </div>
123                <div className="w-full rounded-md border">
124                    <EntityDataTable
125                        columns={columns}
126                        onRowClick={onOpen}
127                    />
128                    <DataTablePagination />
129                </div>
130            </div>
131        </EntityTableContext.Provider>
132    );
133}
134
135export * from './hooks'