From 77ba64664ffb8568e1e24a449cc4e051500d7aed Mon Sep 17 00:00:00 2001 From: bskjon Date: Tue, 1 Apr 2025 22:17:50 +0200 Subject: [PATCH] Added missing files --- .../table/grouped/expandableTable.tsx | 6 + .../src/app/features/table/groupedTable.tsx | 33 +++++ apps/ui/web/src/app/features/table/table.tsx | 117 ++++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 apps/ui/web/src/app/features/table/grouped/expandableTable.tsx create mode 100644 apps/ui/web/src/app/features/table/groupedTable.tsx create mode 100644 apps/ui/web/src/app/features/table/table.tsx diff --git a/apps/ui/web/src/app/features/table/grouped/expandableTable.tsx b/apps/ui/web/src/app/features/table/grouped/expandableTable.tsx new file mode 100644 index 00000000..f5efeb30 --- /dev/null +++ b/apps/ui/web/src/app/features/table/grouped/expandableTable.tsx @@ -0,0 +1,6 @@ + + +export default function ExpandableTable() { + return <> +} // ExpandableTable +// ExpandableTable \ No newline at end of file diff --git a/apps/ui/web/src/app/features/table/groupedTable.tsx b/apps/ui/web/src/app/features/table/groupedTable.tsx new file mode 100644 index 00000000..4b35efde --- /dev/null +++ b/apps/ui/web/src/app/features/table/groupedTable.tsx @@ -0,0 +1,33 @@ +import { useEffect, useState } from "react"; + +import { ExpandableRender } from "./expandableTable"; +import { DefaultTableContainer, SortByAccessor, TableCellCustomizer, TablePropetyConfig, TableRowActionEvents, TableRowGroupedItem } from "./table"; +import { useTheme } from "@mui/material"; + +export interface GroupedTableProps, U> { + items: Array; + columns: Array; + cellCustomizer?: TableCellCustomizer; + onRowClickedEvent?: TableRowActionEvents; + defaultSort?: SortByAccessor; + +} + + +export default function GroupedTable, U>({ items, columns, cellCustomizer: customizer, onRowClickedEvent }: GroupedTableProps) { + const muiTheme = useTheme(); + + const [order, setOrder] = useState<'asc' | 'desc'>('asc'); + const [orderBy, setOrderBy] = useState(''); + const [selectedRowId, setSelectedRowId] = useState(null); + + const handleSort = (property: string) => { + const isAsc = orderBy === property && order === 'asc'; + setOrder(isAsc ? 'desc' : 'asc'); + setOrderBy(property); + }; + + return ( + <> + ); +} \ No newline at end of file diff --git a/apps/ui/web/src/app/features/table/table.tsx b/apps/ui/web/src/app/features/table/table.tsx new file mode 100644 index 00000000..b1aa3bfe --- /dev/null +++ b/apps/ui/web/src/app/features/table/table.tsx @@ -0,0 +1,117 @@ +import { Box, TableContainer } from "@mui/material"; + +export interface ITableRow { + rowId: string; + title: string; +} + +export interface TableRowItem extends ITableRow { + rowId: string; + title: string; + item: T; +} + +export interface TableRowGroupedItem extends ITableRow { + rowId: string; + title: string; + items: Array +} + + +export interface TablePropetyConfig { + label: string + accessor: string +} + +export interface TableCellCustomizer { + (accessor: string, data: T): JSX.Element | null +} + +type NullableTableRowActionEvents = TableRowActionEvents | null; +export interface TableRowActionEvents { + click: (row: T) => void; + doubleClick: (row: T) => void; + contextMenu?: (row: T, x: number, y: number) => void; +} + +export type SortBy = 'asc' | 'desc'; + +export interface SortByAccessor { + accessor: string + order: SortBy +} + +export type TableSorter = (a: T, b: T, orderBy: SortBy, accessor: string) => number; + + +export type SortableGroupedTableProps, U> = { + items: Array; + columns: Array; + cellCustomizer?: TableCellCustomizer; + onRowClickedEvent?: NullableTableRowActionEvents; + defaultSort?: SortByAccessor; +} + + +export function DefaultTableContainer({children}: {children?: JSX.Element}) { + return ( + + + {children} + + + ); +} + + +export function KeybasedComparator(a: any, b: any, key: string) { + if (typeof a[key] === 'string') { + return a[key].localeCompare(b[key]); + } else if (typeof a[key] === 'number') { + return a[key] - b[key]; + } + return 0; +} + +export function SortGroupedTableItemsOnRoot, U>( + sortBy: SortByAccessor, + items: Array, +) { + return items.slice().sort((a, b) => { + if (sortBy.order === 'asc') { + return KeybasedComparator(a, b, sortBy.accessor); + } + return KeybasedComparator(b, a, sortBy.accessor); + }); +} + +export function SortGroupedTableItemsOnChilds, U>( + sortBy: SortByAccessor, + items: Array +): Array { + return items.map(item => ({ + ...item, + items: item.items?.slice().sort((a, b) => { + if (sortBy.order === "asc") { + return KeybasedComparator(a, b, sortBy.accessor); + } + return KeybasedComparator(b, a, sortBy.accessor); + }) + })).sort((a, b) => { + if (sortBy.order === "asc") { + return KeybasedComparator(a, b, sortBy.accessor); + } + return KeybasedComparator(b, a, sortBy.accessor); + }); +} +