Skip to content

Commit d67ee41

Browse files
ita-alibbAndrea Aliberti
andauthored
Highlight feature (#35)
New prop to highlight certain rows based on conditions. ex of highlight: const highlight: HighlightInterface = { compareField: "contactPlanningNextDate", operation: "!=", compareValue: new Date() } --------- Co-authored-by: Andrea Aliberti <andrea.aliberti@neolution.ch>
1 parent 4250cfc commit d67ee41

5 files changed

Lines changed: 79 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- the prop `rowHighlight` to all tables. Check `RowHighlightInterface` for prop definition. Set condition for which a row should be highlighted. Possibility to set custom style for highlights
13+
1014
## [2.3.2] - 2023-03-08
1115

1216
### Added

src/lib/DataTable/DataTable.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export function DataTableStaticRouted<T, TRouteNames>({
2525
possiblePageItemCounts,
2626
predefinedItemsPerPage,
2727
rowStyle,
28+
rowHighlight,
2829
showPaging = false,
2930
tableTitle,
3031
hideIfEmpty = false,
@@ -45,6 +46,7 @@ export function DataTableStaticRouted<T, TRouteNames>({
4546
possiblePageItemCounts={possiblePageItemCounts}
4647
predefinedItemsPerPage={predefinedItemsPerPage}
4748
rowStyle={rowStyle}
49+
rowHighlight={rowHighlight}
4850
showPaging={showPaging}
4951
tableClassName={tableClassName}
5052
tableStyle={tableStyle}
@@ -62,6 +64,7 @@ export function DataTableStatic<T>({
6264
possiblePageItemCounts,
6365
predefinedItemsPerPage,
6466
rowStyle,
67+
rowHighlight,
6568
showPaging = false,
6669
tableTitle,
6770
hideIfEmpty = false,
@@ -82,6 +85,7 @@ export function DataTableStatic<T>({
8285
possiblePageItemCounts={possiblePageItemCounts}
8386
predefinedItemsPerPage={predefinedItemsPerPage}
8487
rowStyle={rowStyle}
88+
rowHighlight={rowHighlight}
8589
showPaging={showPaging}
8690
tableClassName={tableClassName}
8791
tableStyle={tableStyle}
@@ -101,6 +105,7 @@ export function DataTable<T, TFilter>({
101105
predefinedItemsPerPage,
102106
query,
103107
rowStyle,
108+
rowHighlight,
104109
showPaging = true,
105110
predefinedFilter = undefined,
106111
handlers,
@@ -121,6 +126,7 @@ export function DataTable<T, TFilter>({
121126
possiblePageItemCounts={possiblePageItemCounts}
122127
predefinedItemsPerPage={predefinedItemsPerPage}
123128
rowStyle={rowStyle}
129+
rowHighlight={rowHighlight}
124130
showPaging={showPaging}
125131
predefinedFilter={predefinedFilter}
126132
handlers={handlers}

src/lib/DataTable/DataTableInterfaces.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
1-
/* eslint max-lines: ["error", 250] */ // Increased max-lines due to the addition of definitions going above the predefined limit.
1+
/* eslint max-lines: ["error", 260] */ // Increased max-lines due to the addition of definitions going above the predefined limit.
2+
import { CSSProperties } from "react";
23
import { ActionsPosition, CellFunction, ColumnFilterType, ListSortDirection, QueryFunction, RouteParams } from "./DataTableTypes";
34
import { IconProp } from "@fortawesome/fontawesome-svg-core";
45

56
export type RowStyleType<T> = (key: any, record: T) => React.CSSProperties;
67

8+
export interface RowHighlightInterface<T> {
9+
compareField: Extract<keyof T, string>;
10+
operation: "<" | ">" | "==" | "!=";
11+
compareValue: number | Date;
12+
customStyle?: CSSProperties;
13+
}
14+
715
export interface CommonDataTableProps<T> {
816
rowStyle?: RowStyleType<T>;
917
tableClassName?: string;
1018
tableStyle?: React.CSSProperties;
19+
rowHighlight?: RowHighlightInterface<T>;
1120
}
1221

1322
export interface DataTableRoutedProps<T, TFilter, TRouteName> extends CommonDataTableProps<T> {

src/lib/DataTable/DataTableRouted.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export function DataTableRouted<T, TFilter, TRouteNames>({
3333
tableStyle,
3434
asc = true,
3535
orderBy,
36+
rowHighlight,
3637
}: DataTableRoutedProps<T, TFilter, TRouteNames>) {
3738
const [queryResult, setQueryResult] = useState<TableQueryResult<T>>(data);
3839
const [filterState, setFilterState] = useState<FilterPageState>({
@@ -171,6 +172,7 @@ export function DataTableRouted<T, TFilter, TRouteNames>({
171172
actions={actions}
172173
key={getDeepValue(record, keyField)}
173174
rowStyle={rowStyle}
175+
rowHighlight={rowHighlight}
174176
actionsPosition={actionsPosition}
175177
/>
176178
))

src/lib/DataTableHeader/DataTableRow.tsx

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable complexity */
2-
import React, { useState } from "react";
2+
import React, { CSSProperties, useState } from "react";
33
import { DateHandler } from "@neolution-ch/react-pattern-ui";
4-
import { DataTableColumnDescription, DataTableRoutedActions, RowStyleType } from "../DataTable/DataTableInterfaces";
4+
import { DataTableColumnDescription, DataTableRoutedActions, RowHighlightInterface, RowStyleType } from "../DataTable/DataTableInterfaces";
55
import { getDeepValue } from "../Utils/DeepValue";
66
import { ActionsCell } from "../DataTable/Actions/ActionsCell";
77
import { ActionsPosition } from "../DataTable/DataTableTypes";
@@ -12,6 +12,7 @@ interface DataTableRowProps<T, TRouteNames> {
1212
columns: DataTableColumnDescription<T>[];
1313
actions?: DataTableRoutedActions<T, TRouteNames>;
1414
rowStyle?: RowStyleType<T>;
15+
rowHighlight?: RowHighlightInterface<T>;
1516
actionsPosition?: ActionsPosition;
1617
}
1718

@@ -22,14 +23,62 @@ export function DataTableRow<T, TRouteNames>({
2223
columns,
2324
actions,
2425
rowStyle,
26+
rowHighlight,
2527
actionsPosition,
2628
}: DataTableRowProps<T, TRouteNames>) {
2729
const keyValue = getDeepValue(record, keyField);
2830
const [collapsed, setCollapsed] = useState(true);
2931

32+
const operator_table = {
33+
">": function (a: number | Date, b: number | Date) {
34+
return a > b;
35+
},
36+
"<": function (a: number | Date, b: number | Date) {
37+
return a < b;
38+
},
39+
"==": function (a: number | Date, b: number | Date) {
40+
return a == b;
41+
},
42+
"!=": function (a: number | Date, b: number | Date) {
43+
return a != b;
44+
},
45+
};
46+
47+
function getStyle(rowObjectT: T, rowHighlight?: RowHighlightInterface<T>): CSSProperties | undefined {
48+
const defaultStyle: CSSProperties = {
49+
backgroundColor: "rgba(255,0,0,0.7)",
50+
color: "white",
51+
};
52+
53+
if (!rowHighlight) {
54+
return undefined;
55+
}
56+
57+
let selectedValue: number | Date | undefined;
58+
if (typeof rowObjectT[rowHighlight.compareField] == "number") {
59+
selectedValue = rowObjectT[rowHighlight.compareField] as unknown as number;
60+
} else if (typeof rowObjectT[rowHighlight.compareField] == "string") {
61+
selectedValue = new Date(rowObjectT[rowHighlight.compareField] as unknown as string);
62+
}
63+
64+
if (selectedValue == null) {
65+
return undefined;
66+
}
67+
68+
if (typeof selectedValue != "number" && isNaN(selectedValue?.getDate())) {
69+
return undefined;
70+
}
71+
72+
if (operator_table[rowHighlight.operation](selectedValue, rowHighlight.compareValue)) {
73+
return rowHighlight.customStyle ?? defaultStyle;
74+
}
75+
76+
return undefined;
77+
}
78+
3079
return (
3180
<React.Fragment>
32-
<tr key={`${keyValue}_row`} style={rowStyle ? rowStyle(keyValue, record) : undefined}>
81+
<tr key={`${keyValue}_row`} style={{ ...(rowStyle ? rowStyle(keyValue, record) : undefined) }}>
3382
{actionsPosition === ActionsPosition.Left && (
3483
<ActionsCell collapsed={collapsed} setCollapsed={setCollapsed} actions={actions} keyValue={keyValue} record={record} />
3584
)}
@@ -42,23 +91,23 @@ export function DataTableRow<T, TRouteNames>({
4291
column.cellStyle instanceof Function
4392
? column.cellStyle({ key: keyValue, row: record, value: deepValue })
4493
: column.cellStyle ?? undefined;
45-
94+
const cellStyle = { ...getStyle(record, rowHighlight), ...style };
4695
if (column.enumValues && !Number.isNaN(deepValueInt) && column.enumValues.filter((c) => c.value === deepValueInt).length > 0)
4796
return (
48-
<td key={key} style={style}>
97+
<td key={key} style={cellStyle}>
4998
{column.enumValues.filter((c) => c.value === deepValueInt)[0].text}
5099
</td>
51100
);
52101

53102
if (column.formatter)
54103
return (
55-
<td key={key} style={style}>
104+
<td key={key} style={cellStyle}>
56105
{column.formatter({ key: keyValue, row: record, value: deepValue })}
57106
</td>
58107
);
59108

60109
return (
61-
<td key={key} style={style}>
110+
<td key={key} style={cellStyle}>
62111
{column.dateTimeFormat ? DateHandler.getDateFormattedWithDefault(deepValue, column.dateTimeFormat, "-") : deepValue}
63112
</td>
64113
);
@@ -74,6 +123,7 @@ export function DataTableRow<T, TRouteNames>({
74123
<DataTableRow
75124
key={`${keyValue}_subrow_${getDeepValue(subRow, keyField)}`}
76125
keyField={keyField}
126+
rowHighlight={rowHighlight}
77127
columns={actions?.collapse?.columns || columns}
78128
record={subRow}
79129
actionsPosition={actionsPosition}

0 commit comments

Comments
 (0)