Added missing files
This commit is contained in:
parent
8bd9c9e121
commit
77ba64664f
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
export default function ExpandableTable() {
|
||||||
|
return <></>
|
||||||
|
} // ExpandableTable
|
||||||
|
// ExpandableTable
|
||||||
33
apps/ui/web/src/app/features/table/groupedTable.tsx
Normal file
33
apps/ui/web/src/app/features/table/groupedTable.tsx
Normal file
@ -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<R extends TableRowGroupedItem<U>, U> {
|
||||||
|
items: Array<R>;
|
||||||
|
columns: Array<TablePropetyConfig>;
|
||||||
|
cellCustomizer?: TableCellCustomizer<R>;
|
||||||
|
onRowClickedEvent?: TableRowActionEvents<R>;
|
||||||
|
defaultSort?: SortByAccessor;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default function GroupedTable<R extends TableRowGroupedItem<U>, U>({ items, columns, cellCustomizer: customizer, onRowClickedEvent }: GroupedTableProps<R, U>) {
|
||||||
|
const muiTheme = useTheme();
|
||||||
|
|
||||||
|
const [order, setOrder] = useState<'asc' | 'desc'>('asc');
|
||||||
|
const [orderBy, setOrderBy] = useState<string>('');
|
||||||
|
const [selectedRowId, setSelectedRowId] = useState<string | null>(null);
|
||||||
|
|
||||||
|
const handleSort = (property: string) => {
|
||||||
|
const isAsc = orderBy === property && order === 'asc';
|
||||||
|
setOrder(isAsc ? 'desc' : 'asc');
|
||||||
|
setOrderBy(property);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<></>
|
||||||
|
);
|
||||||
|
}
|
||||||
117
apps/ui/web/src/app/features/table/table.tsx
Normal file
117
apps/ui/web/src/app/features/table/table.tsx
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
import { Box, TableContainer } from "@mui/material";
|
||||||
|
|
||||||
|
export interface ITableRow<T> {
|
||||||
|
rowId: string;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TableRowItem<T> extends ITableRow<T> {
|
||||||
|
rowId: string;
|
||||||
|
title: string;
|
||||||
|
item: T;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TableRowGroupedItem<T> extends ITableRow<T> {
|
||||||
|
rowId: string;
|
||||||
|
title: string;
|
||||||
|
items: Array<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface TablePropetyConfig {
|
||||||
|
label: string
|
||||||
|
accessor: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TableCellCustomizer<T> {
|
||||||
|
(accessor: string, data: T): JSX.Element | null
|
||||||
|
}
|
||||||
|
|
||||||
|
type NullableTableRowActionEvents<T> = TableRowActionEvents<T> | null;
|
||||||
|
export interface TableRowActionEvents<T> {
|
||||||
|
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<T> = (a: T, b: T, orderBy: SortBy, accessor: string) => number;
|
||||||
|
|
||||||
|
|
||||||
|
export type SortableGroupedTableProps<R extends TableRowGroupedItem<U>, U> = {
|
||||||
|
items: Array<R>;
|
||||||
|
columns: Array<TablePropetyConfig>;
|
||||||
|
cellCustomizer?: TableCellCustomizer<R>;
|
||||||
|
onRowClickedEvent?: NullableTableRowActionEvents<R>;
|
||||||
|
defaultSort?: SortByAccessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function DefaultTableContainer({children}: {children?: JSX.Element}) {
|
||||||
|
return (
|
||||||
|
<Box sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column", // Bruk column-fleksretning
|
||||||
|
height: "100%",
|
||||||
|
overflow: "hidden"
|
||||||
|
}}>
|
||||||
|
<TableContainer sx={{
|
||||||
|
flex: 1,
|
||||||
|
overflowY: "auto",
|
||||||
|
position: "relative", // Legg til denne linjen for å justere layout
|
||||||
|
maxHeight: "100%" // Legg til denne linjen for å begrense høyden
|
||||||
|
}}>
|
||||||
|
{children}
|
||||||
|
</TableContainer>
|
||||||
|
</Box >
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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<R extends TableRowItem<U>, U>(
|
||||||
|
sortBy: SortByAccessor,
|
||||||
|
items: Array<R>,
|
||||||
|
) {
|
||||||
|
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<R extends TableRowGroupedItem<U>, U>(
|
||||||
|
sortBy: SortByAccessor,
|
||||||
|
items: Array<R>
|
||||||
|
): Array<R> {
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user