Skip to content

Commit fb61432

Browse files
committed
fix: various fixes again
1 parent 9ac68e3 commit fb61432

2 files changed

Lines changed: 91 additions & 83 deletions

File tree

packages/diracx-web-components/src/components/JobMonitor/JobMonitor.tsx

Lines changed: 33 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {
4444
jobMonitorReducer,
4545
defaultColumnVisibility,
4646
defaultPagination,
47+
useJobMonitorContext,
4748
} from "./JobMonitorContext";
4849

4950
// Static sx props extracted to avoid new object references on every render
@@ -120,7 +121,6 @@ function loadInitialState(appId: string): JobMonitorState {
120121
*/
121122
export default function JobMonitor() {
122123
const appId = useApplicationId();
123-
const theme = useTheme();
124124
const diracxUrl = useDiracxUrl();
125125

126126
const [state, dispatch] = useReducer(
@@ -198,49 +198,6 @@ export default function JobMonitor() {
198198
[],
199199
);
200200

201-
// Precompute status colors adjusted for theme mode
202-
const statusBackgroundColors: Record<string, string> = useMemo(() => {
203-
const adjust =
204-
theme.palette.mode === "light"
205-
? (c: string) => darken(c, 0.1)
206-
: (c: string) => lighten(c, 0.1);
207-
const result: Record<string, string> = {};
208-
for (const [key, value] of Object.entries(statusColors)) {
209-
result[key] = adjust(value);
210-
}
211-
return result;
212-
}, [theme.palette.mode, statusColors]);
213-
214-
const defaultStatusColor = useMemo(
215-
() =>
216-
theme.palette.mode === "light"
217-
? darken(brown[500], 0.1)
218-
: lighten(brown[500], 0.1),
219-
[theme.palette.mode],
220-
);
221-
222-
/**
223-
* Renders the status cell with colors
224-
*/
225-
const renderStatusCell = useCallback(
226-
(status: string) => (
227-
<span
228-
style={{
229-
display: "inline-block",
230-
borderRadius: "10px",
231-
padding: "1px 8px",
232-
fontSize: "0.75rem",
233-
backgroundColor: statusBackgroundColors[status] ?? defaultStatusColor,
234-
color: "white",
235-
fontWeight: "bold",
236-
}}
237-
>
238-
{status}
239-
</span>
240-
),
241-
[statusBackgroundColors, defaultStatusColor],
242-
);
243-
244201
const columnHelper = useMemo(() => createColumnHelper<Job>(), []);
245202

246203
/**
@@ -256,7 +213,7 @@ export default function JobMonitor() {
256213
columnHelper.accessor("Status", {
257214
id: "Status",
258215
header: "Status",
259-
cell: (info) => renderStatusCell(info.getValue()),
216+
cell: (info) => <StatusCell status={info.getValue()} />,
260217
meta: {
261218
type: CategoryType.STRING,
262219
values: Object.keys(statusColors).sort(),
@@ -335,7 +292,7 @@ export default function JobMonitor() {
335292
meta: { type: CategoryType.NUMBER },
336293
}),
337294
],
338-
[columnHelper, renderStatusCell, statusColors],
295+
[columnHelper, statusColors],
339296
);
340297

341298
// Handle the application of filters
@@ -470,6 +427,36 @@ export default function JobMonitor() {
470427
);
471428
}
472429

430+
/**
431+
* Renders a status badge with theme-aware colors.
432+
* Defined outside JobMonitor so the column definition stays stable across theme toggles.
433+
*/
434+
function StatusCell({ status }: { status: string }) {
435+
const theme = useTheme();
436+
const { statusColors } = useJobMonitorContext();
437+
const baseColor = statusColors[status] ?? brown[500];
438+
const bg =
439+
theme.palette.mode === "light"
440+
? darken(baseColor, 0.1)
441+
: lighten(baseColor, 0.1);
442+
443+
return (
444+
<span
445+
style={{
446+
display: "inline-block",
447+
borderRadius: "10px",
448+
padding: "1px 8px",
449+
fontSize: "0.75rem",
450+
backgroundColor: bg,
451+
color: "white",
452+
fontWeight: "bold",
453+
}}
454+
>
455+
{status}
456+
</span>
457+
);
458+
}
459+
473460
/**
474461
* This function validates and converts the state of the application
475462
* It ensure that the state is in the correct format

packages/diracx-web-components/src/components/shared/DataTable/DataTable.tsx

Lines changed: 58 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"use client";
2-
import React, { useCallback, useMemo, useRef, useState } from "react";
2+
import React, { memo, useCallback, useMemo, useRef, useState } from "react";
33
import Box from "@mui/material/Box";
44
import Table from "@mui/material/Table";
55
import TableBody from "@mui/material/TableBody";
@@ -30,6 +30,24 @@ import { DataTableToolbar } from "./DataTableToolbar";
3030
import { DataTableHeader } from "./DataTableHeader";
3131
import type { ToolbarAction } from "./SplitActionButton";
3232

33+
// Static styles for virtualized row cells
34+
const checkboxCellStyle: React.CSSProperties = {
35+
position: "sticky",
36+
left: 0,
37+
zIndex: 1,
38+
};
39+
40+
const unpinnedCellStyle: React.CSSProperties = {
41+
overflow: "hidden",
42+
textOverflow: "ellipsis",
43+
whiteSpace: "nowrap",
44+
};
45+
46+
const paddingCellStyle: React.CSSProperties = {
47+
padding: 0,
48+
border: "none",
49+
};
50+
3351
/**
3452
* Menu item
3553
*/
@@ -76,7 +94,9 @@ export interface DataTableProps<T extends Record<string, unknown>> {
7694
*
7795
* @returns a DataTable component
7896
*/
79-
export function DataTable<T extends Record<string, unknown>>({
97+
export const DataTable = memo(function DataTable<
98+
T extends Record<string, unknown>,
99+
>({
80100
title,
81101
table,
82102
totalRows,
@@ -166,19 +186,16 @@ export function DataTable<T extends Record<string, unknown>>({
166186
[table, checkboxWidth],
167187
);
168188

189+
const checkboxCellWithWidth = useMemo<React.CSSProperties>(
190+
() => ({ ...checkboxCellStyle, width: checkboxWidth }),
191+
[checkboxWidth],
192+
);
193+
169194
const itemContent = useCallback(
170195
(_index: number, row: Row<T>) => (
171196
<>
172197
{!disableCheckbox && (
173-
<TableCell
174-
padding="checkbox"
175-
style={{
176-
position: "sticky",
177-
left: 0,
178-
zIndex: 1,
179-
width: checkboxWidth,
180-
}}
181-
>
198+
<TableCell padding="checkbox" style={checkboxCellWithWidth}>
182199
<Checkbox
183200
size="small"
184201
name={`select-row-${row.id}`}
@@ -188,29 +205,33 @@ export function DataTable<T extends Record<string, unknown>>({
188205
/>
189206
</TableCell>
190207
)}
191-
{row.getVisibleCells().map((cell) => (
192-
<TableCell
193-
key={cell.id}
194-
style={{
195-
position: cell.column.getIsPinned() ? "sticky" : "static",
196-
left:
197-
cell.column.getIsPinned() === "left"
198-
? getLeftOffsetForColumn(cell.column)
199-
: undefined,
200-
right: cell.column.getIsPinned() === "right" ? 0 : undefined,
201-
zIndex: cell.column.getIsPinned() ? 1 : 0,
202-
width: cell.column.getSize(),
203-
overflow: "hidden",
204-
textOverflow: "ellipsis",
205-
whiteSpace: "nowrap",
206-
}}
207-
>
208-
{flexRender(cell.column.columnDef.cell, cell.getContext())}
209-
</TableCell>
210-
))}
208+
{row.getVisibleCells().map((cell) => {
209+
const isPinned = cell.column.getIsPinned();
210+
const style: React.CSSProperties = isPinned
211+
? {
212+
...unpinnedCellStyle,
213+
position: "sticky",
214+
left:
215+
isPinned === "left"
216+
? getLeftOffsetForColumn(cell.column)
217+
: undefined,
218+
right: isPinned === "right" ? 0 : undefined,
219+
zIndex: 1,
220+
width: cell.column.getSize(),
221+
}
222+
: {
223+
...unpinnedCellStyle,
224+
width: cell.column.getSize(),
225+
};
226+
return (
227+
<TableCell key={cell.id} style={style}>
228+
{flexRender(cell.column.columnDef.cell, cell.getContext())}
229+
</TableCell>
230+
);
231+
})}
211232
</>
212233
),
213-
[disableCheckbox, checkboxWidth, getLeftOffsetForColumn],
234+
[disableCheckbox, checkboxCellWithWidth, getLeftOffsetForColumn],
214235
);
215236

216237
const selectedRows = table.getSelectedRowModel().rows;
@@ -377,9 +398,8 @@ export function DataTable<T extends Record<string, unknown>>({
377398
<tr>
378399
<td
379400
style={{
401+
...paddingCellStyle,
380402
height: rowVirtualizer.getVirtualItems()[0].start,
381-
padding: 0,
382-
border: "none",
383403
}}
384404
/>
385405
</tr>
@@ -408,11 +428,10 @@ export function DataTable<T extends Record<string, unknown>>({
408428
<tr>
409429
<td
410430
style={{
431+
...paddingCellStyle,
411432
height:
412433
rowVirtualizer.getTotalSize() -
413434
(rowVirtualizer.getVirtualItems().at(-1)?.end ?? 0),
414-
padding: 0,
415-
border: "none",
416435
}}
417436
/>
418437
</tr>
@@ -464,4 +483,6 @@ export function DataTable<T extends Record<string, unknown>>({
464483
)}
465484
</Box>
466485
);
467-
}
486+
}) as <T extends Record<string, unknown>>(
487+
props: DataTableProps<T>,
488+
) => React.ReactElement;

0 commit comments

Comments
 (0)