Table fix
This commit is contained in:
parent
48b7a0d2ad
commit
8bd9c9e121
@ -20,7 +20,6 @@ import FolderIcon from '@mui/icons-material/Folder';
|
||||
import QueueIcon from '@mui/icons-material/Queue';
|
||||
import AppsIcon from '@mui/icons-material/Apps';
|
||||
import ConstructionIcon from '@mui/icons-material/Construction';
|
||||
import ProcesserTasksPage from './app/page/ProcesserTasksPage';
|
||||
import DashboardIcon from '@mui/icons-material/Dashboard';
|
||||
import GraphicEqIcon from '@mui/icons-material/GraphicEq';
|
||||
import HomeRepairServiceIcon from '@mui/icons-material/HomeRepairService';
|
||||
@ -110,7 +109,6 @@ function App() {
|
||||
}}>
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route path='/tasks' element={<ProcesserTasksPage />} />
|
||||
<Route path='/processer' element={<EventsPage />} />
|
||||
<Route path='/unprocessed' element={<UnprocessedFilesPage />} />
|
||||
<Route path='/files' element={<ExplorePage />} />
|
||||
|
||||
@ -1,37 +1,28 @@
|
||||
import { Box, TableContainer, Table, TableHead, TableRow, TableCell, Typography, TableBody, useTheme } from "@mui/material";
|
||||
import { useState, useEffect, useMemo } from "react";
|
||||
import { TablePropetyConfig, TableCellCustomizer, TableRowActionEvents } from "./table";
|
||||
import { TablePropetyConfig, TableCellCustomizer, TableRowActionEvents, SortByAccessor, TableRowItem, DefaultTableContainer, ITableRow, SortBy, TableSorter } from "./table";
|
||||
import IconArrowUp from '@mui/icons-material/ArrowUpward';
|
||||
import IconArrowDown from '@mui/icons-material/ArrowDownward';
|
||||
|
||||
export interface ExpandableItem<T> {
|
||||
tag: string;
|
||||
expandElement: JSX.Element | null;
|
||||
}
|
||||
|
||||
export type ExpandableRender<T> = (item: T) => ExpandableItem<T> | null;
|
||||
export interface ExpandableTableItem {
|
||||
rowId: string
|
||||
}
|
||||
export type ExpandableRender<T> = (item: T) => JSX.Element | null;
|
||||
|
||||
export interface SortByAccessor {
|
||||
accessor: string
|
||||
order: 'asc' | 'desc'
|
||||
}
|
||||
|
||||
export default function ExpandableTable<T extends ExpandableTableItem>({ items, columns, cellCustomizer: customizer, expandableRender, onRowClickedEvent, defaultSort}: { items: Array<T>, columns: Array<TablePropetyConfig>, cellCustomizer?: TableCellCustomizer<T>, expandableRender: ExpandableRender<T>, onRowClickedEvent?: TableRowActionEvents<T>, defaultSort?: SortByAccessor }) {
|
||||
export default function ExpandableTable<R extends ITableRow<U>, U>({ items, columns, cellCustomizer: customizer, expandableRender, onRowClickedEvent, defaultSort, sorter }: { items: Array<R>, columns: Array<TablePropetyConfig>, cellCustomizer?: TableCellCustomizer<R>, expandableRender: ExpandableRender<R>, onRowClickedEvent?: TableRowActionEvents<R>, defaultSort?: SortByAccessor, sorter?: TableSorter<R> }) {
|
||||
const muiTheme = useTheme();
|
||||
|
||||
const [order, setOrder] = useState<'asc' | 'desc'>('asc');
|
||||
const [orderBy, setOrderBy] = useState<string>('');
|
||||
const [order, setOrder] = useState<'asc' | 'desc'>(defaultSort?.order ?? 'asc');
|
||||
const [orderBy, setOrderBy] = useState<string>(defaultSort?.accessor ?? columns[0].accessor ?? '');
|
||||
const [expandedRowIds, setExpandedRowIds] = useState<Set<string>>(new Set());
|
||||
const [selectedRow, setSelectedRow] = useState<T | null>(null);
|
||||
const [selectedRow, setSelectedRow] = useState<R | null>(null);
|
||||
const [selectedRowId, setSelectedRowId] = useState<string | null>(null);
|
||||
|
||||
const tableRowSingleClicked = (row: T | null) => {
|
||||
const tableRowSingleClicked = (row: R | null) => {
|
||||
console.log("tableRowSingleClicked", row)
|
||||
if (row != null && 'rowId' in row) {
|
||||
setExpandedRowIds(prev => {
|
||||
const newExpandedRows = new Set(prev);
|
||||
console.log("newExpandedRows", newExpandedRows)
|
||||
if (newExpandedRows.has(row.rowId)) {
|
||||
newExpandedRows.delete(row.rowId);
|
||||
} else {
|
||||
@ -53,27 +44,23 @@ export default function ExpandableTable<T extends ExpandableTableItem>({ items,
|
||||
}
|
||||
|
||||
}
|
||||
const tableRowDoubleClicked = (row: T | null) => {
|
||||
const tableRowDoubleClicked = (row: R | null) => {
|
||||
setSelectedRow(row);
|
||||
if (row && onRowClickedEvent) {
|
||||
onRowClickedEvent.doubleClick(row);
|
||||
}
|
||||
}
|
||||
|
||||
const tableRowContextMenu = (e: React.MouseEvent<HTMLTableRowElement, MouseEvent> , row: T | null) => {
|
||||
const tableRowContextMenu = (e: React.MouseEvent<HTMLTableRowElement, MouseEvent> , row: R | null) => {
|
||||
if (row && onRowClickedEvent && onRowClickedEvent.contextMenu) {
|
||||
e.preventDefault()
|
||||
onRowClickedEvent.contextMenu(row, e.pageX, e.pageY)
|
||||
}
|
||||
}
|
||||
|
||||
const handleSort = (property: string) => {
|
||||
const isAsc = orderBy === property && order === 'asc';
|
||||
setOrder(isAsc ? 'desc' : 'asc');
|
||||
setOrderBy(property);
|
||||
};
|
||||
|
||||
const compareValues = (a: any, b: any, orderBy: string) => {
|
||||
console.log("compareValues", a, b, orderBy)
|
||||
if (typeof a[orderBy] === 'string') {
|
||||
return a[orderBy].localeCompare(b[orderBy]);
|
||||
} else if (typeof a[orderBy] === 'number') {
|
||||
@ -84,22 +71,19 @@ export default function ExpandableTable<T extends ExpandableTableItem>({ items,
|
||||
|
||||
|
||||
const sortedData = useMemo(() => {
|
||||
return items.slice().sort((a, b) => {
|
||||
return [...items].sort((a, b) => {
|
||||
if (sorter) {
|
||||
return sorter(a, b, order, orderBy);
|
||||
} else {
|
||||
if (order === 'asc') {
|
||||
return compareValues(a, b, orderBy);
|
||||
} else {
|
||||
return compareValues(b, a, orderBy);
|
||||
}
|
||||
});
|
||||
}, [items, order, orderBy]);
|
||||
|
||||
useEffect(() => {
|
||||
handleSort(columns[0].accessor)
|
||||
if (defaultSort) {
|
||||
setOrder(defaultSort.order);
|
||||
setOrderBy(defaultSort.accessor);
|
||||
}
|
||||
}, [defaultSort])
|
||||
}
|
||||
);
|
||||
}, [items, order, orderBy]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedRowId) {
|
||||
@ -113,19 +97,16 @@ export default function ExpandableTable<T extends ExpandableTableItem>({ items,
|
||||
}
|
||||
}, [items, selectedRowId]);
|
||||
|
||||
|
||||
const handleSort = (property: string) => {
|
||||
const isAsc = orderBy === property && order === 'asc';
|
||||
setOrder(isAsc ? 'desc' : 'asc');
|
||||
setOrderBy(property);
|
||||
console.log("handleSort", property, isAsc ? 'desc' : 'asc')
|
||||
};
|
||||
|
||||
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
|
||||
}}>
|
||||
<DefaultTableContainer>
|
||||
<Table>
|
||||
<TableHead sx={{
|
||||
position: "sticky",
|
||||
@ -150,7 +131,7 @@ export default function ExpandableTable<T extends ExpandableTableItem>({ items,
|
||||
<TableBody sx={{
|
||||
overflowY: "scroll"
|
||||
}}>
|
||||
{sortedData?.map((row: T, rowIndex: number) => [
|
||||
{sortedData?.map((row: R, rowIndex: number) => [
|
||||
<TableRow key={row.rowId}
|
||||
onClick={() => tableRowSingleClicked(row)}
|
||||
onDoubleClick={() => tableRowDoubleClicked(row)}
|
||||
@ -172,7 +153,7 @@ export default function ExpandableTable<T extends ExpandableTableItem>({ items,
|
||||
(<TableRow key={row.rowId + "-expanded"}>
|
||||
<TableCell colSpan={columns.length}>
|
||||
{
|
||||
expandableRender(row)?.expandElement
|
||||
expandableRender(row)
|
||||
}
|
||||
</TableCell>
|
||||
</TableRow>): null
|
||||
@ -180,7 +161,6 @@ export default function ExpandableTable<T extends ExpandableTableItem>({ items,
|
||||
])}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Box>
|
||||
</DefaultTableContainer>
|
||||
)
|
||||
}
|
||||
@ -4,16 +4,12 @@ import { RootState } from "../../store";
|
||||
import IconArrowUp from '@mui/icons-material/ArrowUpward';
|
||||
import IconArrowDown from '@mui/icons-material/ArrowDownward';
|
||||
import { Table, TableHead, TableRow, TableCell, TableBody, Typography, Box, useTheme, TableContainer, IconButton } from "@mui/material";
|
||||
import { TablePropetyConfig, TableCellCustomizer, TableRowActionEvents } from "./table";
|
||||
import { TablePropetyConfig, TableCellCustomizer, TableRowActionEvents, TableRowGroupedItem, DefaultTableContainer } from "./table";
|
||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
||||
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
|
||||
|
||||
export interface TableItemGroup<T> {
|
||||
title: string
|
||||
items: Array<T>
|
||||
}
|
||||
|
||||
export default function SortableGroupedTable<T>({ items, columns, customizer, onRowClickedEvent }: { items: Array<TableItemGroup<T>>, columns: Array<TablePropetyConfig>, customizer?: TableCellCustomizer<T>, onRowClickedEvent?: TableRowActionEvents<T> }) {
|
||||
export default function SortableGroupedTable<T extends TableRowGroupedItem<T>>({ items, columns, customizer, onRowClickedEvent }: { items: Array<T>, columns: Array<TablePropetyConfig>, customizer?: TableCellCustomizer<T>, onRowClickedEvent?: TableRowActionEvents<T> }) {
|
||||
const muiTheme = useTheme();
|
||||
|
||||
const [order, setOrder] = useState<'asc' | 'desc'>('asc');
|
||||
@ -45,7 +41,7 @@ export default function SortableGroupedTable<T>({ items, columns, customizer, on
|
||||
}
|
||||
}
|
||||
|
||||
const tableRowContextMenu = (e: React.MouseEvent<HTMLTableRowElement, MouseEvent> , row: T | null) => {
|
||||
const tableRowContextMenu = (e: React.MouseEvent<HTMLTableRowElement, MouseEvent>, row: T | null) => {
|
||||
if (row && onRowClickedEvent && onRowClickedEvent.contextMenu) {
|
||||
e.preventDefault()
|
||||
onRowClickedEvent.contextMenu(row, e.pageX, e.pageY)
|
||||
@ -67,7 +63,11 @@ export default function SortableGroupedTable<T>({ items, columns, customizer, on
|
||||
return 0;
|
||||
};
|
||||
|
||||
const sortedData: Array<TableItemGroup<T>> = items.map((item: TableItemGroup<T>) => {
|
||||
/*const sortedData: Array<RowTableItem<T>> = items.map((item: RowTableItem<T>) => {
|
||||
if (items.length === 0 || !item.items) {
|
||||
console.log(item);
|
||||
return item; // Return the item as is if there are no items to sort
|
||||
}
|
||||
return {
|
||||
title: item.title,
|
||||
items: item.items.slice().sort((a, b) => {
|
||||
@ -78,8 +78,20 @@ export default function SortableGroupedTable<T>({ items, columns, customizer, on
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
});*/
|
||||
|
||||
const sortedData: Array<TableRowGroupedItem<T>> = items.map((item: TableRowGroupedItem<T>) => {
|
||||
return {
|
||||
...item,
|
||||
items: item.items?.slice().sort((a, b) => {
|
||||
if (order === 'asc') {
|
||||
return compareValues(a, b, orderBy);
|
||||
} else {
|
||||
return compareValues(b, a, orderBy);
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
@ -88,18 +100,7 @@ export default function SortableGroupedTable<T>({ items, columns, customizer, on
|
||||
|
||||
|
||||
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
|
||||
}}>
|
||||
<DefaultTableContainer>
|
||||
<Table>
|
||||
<TableHead sx={{
|
||||
position: "sticky",
|
||||
@ -167,7 +168,6 @@ export default function SortableGroupedTable<T>({ items, columns, customizer, on
|
||||
))}
|
||||
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Box>
|
||||
</DefaultTableContainer>
|
||||
)
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
@ -3,4 +3,4 @@ export interface CoordinatorOperationRequest {
|
||||
file: string;
|
||||
source: string;
|
||||
mode: "FLOW" | "MANUAL";
|
||||
}
|
||||
}
|
||||
@ -9,10 +9,12 @@ import { Box, Button, Typography, useTheme } from "@mui/material";
|
||||
import { Tree } from "react-d3-tree";
|
||||
import { EventChain, EventGroup, EventGroups, set } from "../store/chained-events-slice";
|
||||
import { toUnixTimestamp, UnixTimestamp } from "../features/UxTc";
|
||||
import { TableCellCustomizer, TablePropetyConfig } from "../features/table/table";
|
||||
import ExpandableTable, { ExpandableItem } from "../features/table/expandableTable";
|
||||
import { TableCellCustomizer, TablePropetyConfig, TableRowGroupedItem } from "../features/table/table";
|
||||
import ExpandableTable from "../features/table/expandableTable";
|
||||
import { CustomNodeElementProps } from 'react-d3-tree';
|
||||
|
||||
export type ExpandableItemRow = TableRowGroupedItem<EventChain> & EventGroup
|
||||
|
||||
|
||||
interface RawNodeDatum {
|
||||
name: string;
|
||||
@ -37,12 +39,8 @@ const transformEventChain = (eventChain: EventChain): RawNodeDatum => ({
|
||||
});
|
||||
|
||||
// Transformasjonsfunksjon for EventGroups
|
||||
const transformEventGroups = (group: EventGroup): RawNodeDatum[] => {
|
||||
return group.events.map(transformEventChain);
|
||||
}
|
||||
|
||||
interface EventGroupToTreeView extends EventGroup {
|
||||
underView: JSX.Element
|
||||
const transformEventGroups = (group: ExpandableItemRow): RawNodeDatum[] => {
|
||||
return group.items.map(transformEventChain);
|
||||
}
|
||||
|
||||
export default function EventsChainPage() {
|
||||
@ -51,12 +49,25 @@ export default function EventsChainPage() {
|
||||
const client = useStompClient();
|
||||
const cursor = useSelector((state: RootState) => state.chained)
|
||||
const [useReferenceId, setUseReferenceId] = useState<string | null>(null);
|
||||
const [treeData, setTreeData] = useState<RawNodeDatum[] | null>(null);
|
||||
const [tableItems, setTableItems] = useState<Array<ExpandableItemRow>>([]);
|
||||
|
||||
useWsSubscription<Array<EventGroup>>("/topic/chained/all", (response) => {
|
||||
dispatch(set(response))
|
||||
console.log(response)
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const items = cursor.groups.map((group: EventGroup) => {
|
||||
return {
|
||||
rowId: group.referenceId,
|
||||
title: group.fileName ?? group.referenceId,
|
||||
items: group.events,
|
||||
referenceId: group.referenceId,
|
||||
} as ExpandableItemRow
|
||||
});
|
||||
setTableItems(items);
|
||||
console.log("tableItems", items)
|
||||
}, [cursor]);
|
||||
|
||||
useEffect(() => {
|
||||
client?.publish({
|
||||
@ -67,23 +78,10 @@ export default function EventsChainPage() {
|
||||
const onRefresh = () => {
|
||||
client?.publish({
|
||||
"destination": "/app/chained/all",
|
||||
"body": "Potato"
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (useReferenceId) {
|
||||
const eventGroup = cursor.groups.find((group) => group.referenceId === useReferenceId);
|
||||
if (eventGroup) {
|
||||
const data = transformEventGroups(eventGroup);
|
||||
console.log({
|
||||
"info": "Tree data",
|
||||
"data": data
|
||||
})
|
||||
setTreeData(data);
|
||||
}
|
||||
}
|
||||
}, [useReferenceId, cursor])
|
||||
|
||||
|
||||
const createTableCell: TableCellCustomizer<EventGroup> = (accessor, data) => {
|
||||
switch (accessor) {
|
||||
@ -101,7 +99,7 @@ export default function EventsChainPage() {
|
||||
|
||||
const columns: Array<TablePropetyConfig> = [
|
||||
{ label: "ReferenceId", accessor: "referenceId" },
|
||||
{ label: "File", accessor: "fileName" },
|
||||
{ label: "File", accessor: "title" },
|
||||
{ label: "Created", accessor: "created" },
|
||||
];
|
||||
|
||||
@ -144,10 +142,8 @@ export default function EventsChainPage() {
|
||||
</>);
|
||||
}
|
||||
|
||||
function renderExpandableItem(item: EventGroup): ExpandableItem<EventGroup> | null {
|
||||
return {
|
||||
tag: item.referenceId,
|
||||
expandElement: (() => {
|
||||
function renderExpandableItem(item: ExpandableItemRow): JSX.Element | null {
|
||||
console.log(item);
|
||||
const data = transformEventGroups(item);
|
||||
return (
|
||||
<>
|
||||
@ -163,8 +159,6 @@ export default function EventsChainPage() {
|
||||
) : <Typography>Tree data not available</Typography>}
|
||||
</>
|
||||
);
|
||||
})()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -185,7 +179,7 @@ export default function EventsChainPage() {
|
||||
position: "absolute",
|
||||
width: "100%"
|
||||
}}>
|
||||
<ExpandableTable items={cursor?.groups ?? []} columns={columns} cellCustomizer={createTableCell} expandableRender={renderExpandableItem} />
|
||||
<ExpandableTable items={tableItems ?? []} columns={columns} cellCustomizer={createTableCell} expandableRender={renderExpandableItem} />
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
|
||||
@ -17,10 +17,10 @@ import AutoAwesomeMotionIcon from '@mui/icons-material/AutoAwesomeMotion';
|
||||
import { client } from "stompjs";
|
||||
import { useStompClient } from "react-stomp-hooks";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { ContentEventState, ProcesserEventInfo, Status, update, updateEncodeProgress, WorkStatus } from "../store/work-slice";
|
||||
import ExpandableTable, { ExpandableItem } from "../features/table/expandableTable";
|
||||
import { ContentEventState, ContentEventStateItems, ProcesserEventInfo, Status, update, updateEncodeProgress, WorkStatus } from "../store/work-slice";
|
||||
import ExpandableTable from "../features/table/expandableTable";
|
||||
import { RootState } from "../store";
|
||||
import { TableCellCustomizer, TablePropetyConfig } from "../features/table/table";
|
||||
import { KeybasedComparator, SortBy, TableCellCustomizer, TablePropetyConfig, TableRowItem } from "../features/table/table";
|
||||
import SimpleTable from "../features/table/sortableTable";
|
||||
import { UnixTimestamp } from "../features/UxTc";
|
||||
import ProgressbarWithLabel from "../features/components/ProgressbarWithLabel";
|
||||
@ -169,12 +169,24 @@ const transformToSteps = (state: ContentEventState): RawNodeDatum => ({
|
||||
]
|
||||
});
|
||||
|
||||
export type ExpandableItemRow = TableRowItem<ContentEventState>
|
||||
|
||||
export default function EventsPage() {
|
||||
const client = useStompClient();
|
||||
const dispatch = useDispatch();
|
||||
const events = useSelector((state: RootState) => state.work);
|
||||
const events: ContentEventStateItems = useSelector((state: RootState) => state.work);
|
||||
const [tableItems, setTableItems] = useState<Array<ExpandableItemRow>>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const items = events.items.map((event: ContentEventState) => {
|
||||
return {
|
||||
rowId: event.referenceId,
|
||||
title: event.referenceId,
|
||||
item: event
|
||||
} as ExpandableItemRow
|
||||
});
|
||||
setTableItems(items);
|
||||
}, [events]);
|
||||
|
||||
useWsSubscription<Array<ContentEventState>>("/topic/tasks/all", (response) => {
|
||||
console.log(response)
|
||||
@ -192,7 +204,7 @@ export default function EventsPage() {
|
||||
})
|
||||
}, [client]);
|
||||
|
||||
const createCellTable: TableCellCustomizer<ContentEventState> = (accessor, data) => {
|
||||
const createCellTable: TableCellCustomizer<ExpandableItemRow> = (accessor, data) => {
|
||||
switch (accessor) {
|
||||
case "runners": {
|
||||
return (<>
|
||||
@ -206,7 +218,7 @@ export default function EventsPage() {
|
||||
x: 24,
|
||||
y: 24
|
||||
}}
|
||||
data={transformToSteps(data)}
|
||||
data={transformToSteps(data.item)}
|
||||
orientation="horizontal"
|
||||
separation={{
|
||||
nonSiblings: 1,
|
||||
@ -226,8 +238,8 @@ export default function EventsPage() {
|
||||
</>)
|
||||
};
|
||||
case "created": {
|
||||
if (typeof data[accessor] === "number") {
|
||||
return UnixTimestamp({ timestamp: data[accessor] });
|
||||
if (typeof data.item[accessor] === "number") {
|
||||
return UnixTimestamp({ timestamp: data.item[accessor] });
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -235,33 +247,36 @@ export default function EventsPage() {
|
||||
}
|
||||
};
|
||||
|
||||
function renderExpandableItem(item: ContentEventState): ExpandableItem<ContentEventState> | null {
|
||||
const progress = item.encodeWork?.progress?.progress ?? undefined;
|
||||
const showProgressbar = [WorkStatus.Pending, WorkStatus.Started, WorkStatus.Working, WorkStatus.Completed].includes(item?.encodeWork?.status)
|
||||
const sorter = (a: ExpandableItemRow, b: ExpandableItemRow, orderBy: SortBy, accessor: string) => {
|
||||
if (orderBy === "asc") {
|
||||
return KeybasedComparator(a.item, b.item, "created")
|
||||
} else {
|
||||
return KeybasedComparator(b.item, a.item, "created")
|
||||
}
|
||||
}
|
||||
|
||||
const processer = item.encodeWork // events.encodeWork[item.referenceId];
|
||||
function renderExpandableItem(item: ExpandableItemRow): JSX.Element | null {
|
||||
const data = item.item;
|
||||
const progress = data.encodeWork?.progress?.progress ?? undefined;
|
||||
const showProgressbar = [WorkStatus.Pending, WorkStatus.Started, WorkStatus.Working, WorkStatus.Completed].includes(data?.encodeWork?.status)
|
||||
|
||||
const processer = data.encodeWork // events.encodeWork[item.referenceId];
|
||||
const showIndeterminate = processer?.status in [WorkStatus.Pending, WorkStatus.Started] || processer?.progress?.progress <= 0
|
||||
console.log({
|
||||
type: "info",
|
||||
processer: processer,
|
||||
showIndeterminate: showIndeterminate,
|
||||
showProgressbar: showProgressbar,
|
||||
isWorking: item.encodeWork?.status == WorkStatus.Working
|
||||
isWorking: data.encodeWork?.status == WorkStatus.Working
|
||||
});
|
||||
return {
|
||||
tag: item.referenceId,
|
||||
expandElement: (() => {
|
||||
//const data = transformEventGroups(item);
|
||||
return (
|
||||
<>
|
||||
<Typography>{item.encodeWork?.progress?.timeLeft}</Typography>
|
||||
<Typography>{data.encodeWork?.progress?.timeLeft}</Typography>
|
||||
{(showProgressbar) ?
|
||||
<ProgressbarWithLabel indeterminateText={"Waiting"} progress={progress} /> : null
|
||||
}
|
||||
</>
|
||||
);
|
||||
})()
|
||||
};
|
||||
}
|
||||
|
||||
const columns: Array<TablePropetyConfig> = [
|
||||
@ -279,10 +294,10 @@ export default function EventsPage() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<ExpandableTable items={events.items} columns={columns} cellCustomizer={createCellTable} expandableRender={renderExpandableItem} defaultSort={{
|
||||
<ExpandableTable items={tableItems} columns={columns} cellCustomizer={createCellTable} expandableRender={renderExpandableItem} defaultSort={{
|
||||
order: 'desc',
|
||||
accessor: "created"
|
||||
}} />
|
||||
}} sorter={sorter} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
@ -1,102 +0,0 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useStompClient } from "react-stomp-hooks";
|
||||
import { Box, Button, Grid, TextField, Typography, useTheme } from '@mui/material';
|
||||
import { ExplorerItem } from "../../types";
|
||||
import { ContextMenuItem } from "../features/ContextMenu";
|
||||
import { RootState } from "../store";
|
||||
import { useWsSubscription } from "../ws/subscriptions";
|
||||
import SimpleTable from "../features/table/sortableTable";
|
||||
import { TableCellCustomizer, TablePropetyConfig } from "../features/table/table";
|
||||
import MultiListSortedTable from "../features/table/multiListSortedTable";
|
||||
import { TableTaskGroup, Task, TaskGroup, update } from "../store/tasks-slice";
|
||||
import SortableGroupedTable from "../features/table/sortableGroupedTable";
|
||||
import { UnixTimestamp } from "../features/UxTc";
|
||||
|
||||
const columns: Array<TablePropetyConfig> = [
|
||||
{ label: "Name", accessor: "data.inputFile" },
|
||||
{ label: "Task", accessor: "task" },
|
||||
{ label: "Status", accessor: "status" },
|
||||
{ label: "Created", accessor: "created" },
|
||||
];
|
||||
|
||||
const createTableCell: TableCellCustomizer<Task> = (accessor, data) => {
|
||||
switch (accessor) {
|
||||
case "created": {
|
||||
if (typeof data[accessor] === "string") {
|
||||
return UnixTimestamp({ timestamp: Date.parse(data[accessor]) });
|
||||
}
|
||||
return null;
|
||||
}
|
||||
case "data.inputFile": {
|
||||
const parts = data.data?.inputFile.split("/") ?? [];
|
||||
return <Typography>{parts[parts?.length - 1]}</Typography>
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export default function ProcesserTasksPage() {
|
||||
const muiTheme = useTheme();
|
||||
const dispatch = useDispatch();
|
||||
const client = useStompClient();
|
||||
const taskGroups = useSelector((state: RootState) => state.tasks);
|
||||
|
||||
useWsSubscription<Array<TaskGroup>>("/topic/tasks/all", (response) => {
|
||||
console.log(response)
|
||||
dispatch(update(response))
|
||||
});
|
||||
|
||||
useWsSubscription<any>("/topic/processer/encode/progress", (response) => {
|
||||
console.log(response)
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
client?.publish({
|
||||
destination: "/app/tasks/all"
|
||||
});
|
||||
}, [client, dispatch]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box display="block">
|
||||
<Grid container sx={{
|
||||
height: 50,
|
||||
width: "100%",
|
||||
maxHeight: "100%",
|
||||
overflow: "hidden",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
backgroundColor: muiTheme.palette.background.paper
|
||||
}}>
|
||||
<Grid item xs={2}>
|
||||
<Typography variant="h6">Tasks</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={10}>
|
||||
<TextField
|
||||
hiddenLabel
|
||||
placeholder="Search"
|
||||
fullWidth={true}
|
||||
id="search-field"
|
||||
variant="filled"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
|
||||
<Box sx={{
|
||||
display: "block",
|
||||
height: "calc(100% - 120px)",
|
||||
overflow: "hidden",
|
||||
position: "absolute",
|
||||
width: "100%"
|
||||
}}>
|
||||
<SortableGroupedTable items={taskGroups.items ?? []} columns={columns} customizer={createTableCell} />
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
@ -1,10 +1,9 @@
|
||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit"
|
||||
import { ExpandableTableItem } from "../features/table/expandableTable";
|
||||
|
||||
export interface EventGroup extends ExpandableTableItem {
|
||||
export interface EventGroup {
|
||||
referenceId: string,
|
||||
created: number,
|
||||
fileName: string|null,
|
||||
fileName?: string,
|
||||
events: EventChain[]
|
||||
}
|
||||
|
||||
|
||||
@ -66,6 +66,7 @@ export interface TaskGroupList {
|
||||
}
|
||||
|
||||
export interface TableTaskGroup extends TableItemGroup<Task> {
|
||||
referenceId: string
|
||||
title: string
|
||||
items: Array<Task>
|
||||
}
|
||||
@ -84,6 +85,7 @@ const tasksSlice = createSlice({
|
||||
reducers: {
|
||||
update(state, action: PayloadAction<Array<TaskGroup>>) {
|
||||
state.items = action.payload.map((value) => ({
|
||||
referenceId: value.referenceId,
|
||||
title: value.referenceId,
|
||||
items: value.tasks
|
||||
})) ?? []
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit"
|
||||
import { ExpandableTableItem } from "../features/table/expandableTable"
|
||||
|
||||
export enum WorkStatus {
|
||||
Pending = "Pending",
|
||||
@ -38,7 +37,7 @@ export enum Status {
|
||||
|
||||
|
||||
|
||||
export interface ContentEventState extends ExpandableTableItem {
|
||||
export interface ContentEventState {
|
||||
referenceId: string
|
||||
title: string
|
||||
encode: Status
|
||||
|
||||
@ -29,8 +29,8 @@ root.render(
|
||||
<StompSessionProvider url={wsUrl()} connectHeaders={{}} logRawCommunication={true}
|
||||
debug={(str) => {
|
||||
if (str === "Opening Web Socket...") {
|
||||
console.log("Connecting with Web Socket...")
|
||||
}
|
||||
console.log(str);
|
||||
}}
|
||||
onUnhandledMessage={(val) => {
|
||||
console.log("Unhandled message", val)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user