Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kie-issues#1547: DMN Editor: Render evaluation highlights in the Boxed Expression Editor #2681

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export interface BoxedExpressionEditorProps {
isReadOnly?: boolean;
/** PMML models available to use on Boxed PMML Function */
pmmlDocuments?: PmmlDocument[];
evaluationHitsCountPerId?: Map<string, number>;
/** The containing HTMLElement which is scrollable */
scrollableParentRef: React.RefObject<HTMLElement>;
/** Parsed variables used for syntax coloring and auto-complete */
Expand All @@ -79,6 +80,7 @@ export function BoxedExpressionEditor({
isResetSupportedOnRootExpression,
scrollableParentRef,
pmmlDocuments,
evaluationHitsCountPerId,
onRequestFeelVariables,
widthsById,
onWidthsChange,
Expand All @@ -103,6 +105,7 @@ export function BoxedExpressionEditor({
isReadOnly={isReadOnly}
dataTypes={dataTypes}
pmmlDocuments={pmmlDocuments}
evaluationHitsCountPerId={evaluationHitsCountPerId}
onRequestFeelVariables={onRequestFeelVariables}
widthsById={widthsById}
hideDmn14BoxedExpressions={hideDmn14BoxedExpressions}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface BoxedExpressionEditorContextType {
pmmlDocuments?: PmmlDocument[];
dataTypes: DmnDataType[];
isReadOnly?: boolean;
evaluationHitsCountPerId?: Map<string, number>;

// State
currentlyOpenContextMenu: string | undefined;
Expand Down Expand Up @@ -74,6 +75,7 @@ export function BoxedExpressionEditorContextProvider({
beeGwtService,
children,
pmmlDocuments,
evaluationHitsCountPerId,
scrollableParentRef,
onRequestFeelVariables,
widthsById,
Expand Down Expand Up @@ -114,6 +116,7 @@ export function BoxedExpressionEditorContextProvider({
dataTypes,
isReadOnly,
pmmlDocuments,
evaluationHitsCountPerId,

//state // FIXME: Move to a separate context (https://github.com/apache/incubator-kie-issues/issues/168)
currentlyOpenContextMenu,
Expand Down
4 changes: 4 additions & 0 deletions packages/boxed-expression-component/src/api/BeeTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ export interface BeeTableProps<R extends object> {
shouldShowColumnsInlineControls: boolean;
resizerStopBehavior: ResizerStopBehavior;
lastColumnMinWidth?: number;
/** Index of the column, where the evaluation hits count should be displayed. If not set, evaluation hits count number is not shown. */
evaluationHitsCountColumnIndex?: number;
/** Method should return true for table rows, that can display evaluation hits count, false otherwise. If not set, BeeTableBody defaults to false. */
getEvaluationHitsCountSupportedByRow?: (row: ReactTable.Row<R>) => boolean;
}

/** Possible status for the visibility of the Table's Header */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,14 @@ export function ConditionalExpression({
[setExpression]
);

const getRowKey = useCallback((row: ReactTable.Row<ROWTYPE>) => {
return row.original.part["@_id"];
}, []);

const getEvaluationHitsCountSupportedByRow = useCallback((row: ReactTable.Row<ROWTYPE>) => {
return row.original.label !== "if";
}, []);

return (
<NestedExpressionContainerContext.Provider value={nestedExpressionContainerValue}>
<div data-testid={"kie-tools--boxed-expression-component---conditional"}>
Expand All @@ -234,6 +242,7 @@ export function ConditionalExpression({
isEditableHeader={!isReadOnly}
resizerStopBehavior={ResizerStopBehavior.SET_WIDTH_WHEN_SMALLER}
tableId={id}
getRowKey={getRowKey}
headerLevelCountForAppendingRowIndexColumn={1}
headerVisibility={headerVisibility}
cellComponentByColumnAccessor={cellComponentByColumnAccessor}
Expand All @@ -247,6 +256,8 @@ export function ConditionalExpression({
shouldRenderRowIndexColumn={false}
shouldShowRowsInlineControls={false}
shouldShowColumnsInlineControls={false}
evaluationHitsCountColumnIndex={1}
getEvaluationHitsCountSupportedByRow={getEvaluationHitsCountSupportedByRow}
/>
</div>
</NestedExpressionContainerContext.Provider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1045,6 +1045,10 @@ export function DecisionTableExpression({
[beeTableRows.length]
);

const getEvaluationHitsCountSupportedByRow = useCallback((row: ReactTable.Row<ROWTYPE>) => {
return true;
}, []);

return (
<div className={`decision-table-expression ${decisionTableExpression["@_id"]}`}>
<BeeTable<ROWTYPE>
Expand Down Expand Up @@ -1073,6 +1077,8 @@ export function DecisionTableExpression({
shouldRenderRowIndexColumn={true}
shouldShowRowsInlineControls={true}
shouldShowColumnsInlineControls={true}
evaluationHitsCountColumnIndex={0}
getEvaluationHitsCountSupportedByRow={getEvaluationHitsCountSupportedByRow}
// lastColumnMinWidth={lastColumnMinWidth} // FIXME: Check if this is a good strategy or not when doing https://github.com/apache/incubator-kie-issues/issues/181
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,46 @@
border: 0;
}

.expression-container .table-component tr.evaluation-hits-count-row-overlay > td:first-child::before {
content: "";
position: absolute;
background-color: rgb(215, 201, 255, 0.5);
left: 0;
top: 0;
width: 100%;
height: 100%;
}

.evaluation-hits-count-badge-non-colored::before {
content: attr(data-evaluation-hits-count);
font-size: 0.8em;
text-align: left;
color: white;
background-color: var(--pf-global--palette--black-600);
position: absolute;
top: 0px;
left: 0px;
height: 40px;
width: 40px;
clip-path: polygon(0% 100%, 100% 0%, 0% 0%);
padding-left: 0.2em;
}

.evaluation-hits-count-badge-colored::before {
content: attr(data-evaluation-hits-count);
font-size: 0.8em;
text-align: left;
color: white;
background-color: rgb(134, 106, 212);
position: absolute;
top: 0px;
left: 0px;
height: 40px;
width: 40px;
clip-path: polygon(0% 100%, 100% 0%, 0% 0%);
padding-left: 0.2em;
}

.expression-container .table-component table tbody tr td.row-index-cell-column {
padding: 1.1em 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ export function BeeTableInternal<R extends object>({
resizerStopBehavior,
lastColumnMinWidth,
rowWrapper,
evaluationHitsCountColumnIndex,
getEvaluationHitsCountSupportedByRow,
}: BeeTableProps<R> & {
selectionRef?: React.RefObject<BeeTableSelectionRef>;
}) {
Expand Down Expand Up @@ -657,6 +659,8 @@ export function BeeTableInternal<R extends object>({
onDataCellKeyUp={onDataCellKeyUp}
lastColumnMinWidth={lastColumnMinWidth}
isReadOnly={isReadOnly}
evaluationHitsCountColumnIndex={evaluationHitsCountColumnIndex}
getEvaluationHitsCountSupportedByRow={getEvaluationHitsCountSupportedByRow}
/>
</table>
<BeeTableContextMenuHandler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import { BeeTableTd } from "./BeeTableTd";
import { BeeTableCoordinatesContextProvider } from "../../selection/BeeTableSelectionContext";
import { ResizerStopBehavior } from "../../resizing/ResizingWidthsContext";
import { useBoxedExpressionEditor } from "../../BoxedExpressionEditorContext";

export interface BeeTableBodyProps<R extends object> {
/** Table instance */
Expand Down Expand Up @@ -55,6 +56,10 @@
rowWrapper?: React.FunctionComponent<React.PropsWithChildren<{ row: R; rowIndex: number }>>;

isReadOnly: boolean;
/** See BeeTable.ts */
evaluationHitsCountColumnIndex?: number;
/** See BeeTable.ts */
getEvaluationHitsCountSupportedByRow?: (row: ReactTable.Row<R>) => boolean;
}

export function BeeTableBody<R extends object>({
Expand All @@ -72,15 +77,29 @@
lastColumnMinWidth,
rowWrapper,
isReadOnly,
evaluationHitsCountColumnIndex,
getEvaluationHitsCountSupportedByRow,
}: BeeTableBodyProps<R>) {
const { evaluationHitsCountPerId } = useBoxedExpressionEditor();

const renderRow = useCallback(
(row: ReactTable.Row<R>, rowIndex: number) => {
reactTableInstance.prepareRow(row);

const rowKey = getRowKey(row);
const isEvalationHitsCountSupportedByRow: boolean = getEvaluationHitsCountSupportedByRow?.(row) ?? false;
const rowEvaluationHitsCount = evaluationHitsCountPerId ? evaluationHitsCountPerId?.get(rowKey) ?? 0 : undefined;
const canDisplayEvaluationHitsCountRowOverlay =
rowEvaluationHitsCount !== undefined && isEvalationHitsCountSupportedByRow === true;
const rowClassName = canDisplayEvaluationHitsCountRowOverlay
? rowKey + (rowEvaluationHitsCount > 0 ? " evaluation-hits-count-row-overlay" : "")
: rowKey;
const renderTr = () => (
<tr className={rowKey} key={rowKey} data-testid={`kie-tools--bee--expression-row-${rowIndex}`}>
<tr className={rowClassName} key={rowKey} data-testid={`kie-tools--bee--expression-row-${rowIndex}`}>
{row.cells.map((cell, cellIndex) => {
const columnKey = getColumnKey(reactTableInstance.allColumns[cellIndex]);
const canDisplayEvaluationHitsCountBadge =
canDisplayEvaluationHitsCountRowOverlay && cellIndex === evaluationHitsCountColumnIndex;
return (
<React.Fragment key={columnKey}>
{((cell.column.isRowIndexColumn && shouldRenderRowIndexColumn) || !cell.column.isRowIndexColumn) && (
Expand All @@ -104,6 +123,8 @@
cellIndex === reactTableInstance.allColumns.length - 1 ? lastColumnMinWidth : undefined
}
isReadOnly={isReadOnly}
canDisplayEvaluationHitsCountBadge={canDisplayEvaluationHitsCountBadge}
evaluationHitsCount={rowEvaluationHitsCount}
/>
)}
</React.Fragment>
Expand All @@ -114,8 +135,6 @@

const RowWrapper = rowWrapper;

const rowKey = getRowKey(row);

return (
<React.Fragment key={rowKey}>
{RowWrapper ? (
Expand All @@ -128,7 +147,7 @@
</React.Fragment>
);
},
[

Check warning on line 150 in packages/boxed-expression-component/src/table/BeeTable/BeeTableBody.tsx

View workflow job for this annotation

GitHub Actions / run (ubuntu-latest, 2)

React Hook useCallback has missing dependencies: 'evaluationHitsCountColumnIndex', 'evaluationHitsCountPerId', and 'getEvaluationHitsCountSupportedByRow'. Either include them or remove the dependency array. If 'getEvaluationHitsCountSupportedByRow' changes too often, find the parent component that defines it and wrap that definition in useCallback

Check warning on line 150 in packages/boxed-expression-component/src/table/BeeTable/BeeTableBody.tsx

View workflow job for this annotation

GitHub Actions / run (windows-latest, 2)

React Hook useCallback has missing dependencies: 'evaluationHitsCountColumnIndex', 'evaluationHitsCountPerId', and 'getEvaluationHitsCountSupportedByRow'. Either include them or remove the dependency array. If 'getEvaluationHitsCountSupportedByRow' changes too often, find the parent component that defines it and wrap that definition in useCallback
reactTableInstance,
rowWrapper,
getRowKey,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ export interface BeeTableTdProps<R extends object> {
onDataCellClick?: (columnID: string) => void;
onDataCellKeyUp?: (columnID: string) => void;
isReadOnly: boolean;
/** True means the table cell can display evaluation hits count. False means evaluation hits count is not displayed in the table cell. */
canDisplayEvaluationHitsCountBadge?: boolean;
/** Actuall evaluation hits count number that will be displayed in the table cell if 'canDisplayEvaluationHitsCountBadge' is set to true. */
evaluationHitsCount?: number;
}

export type HoverInfo =
Expand All @@ -73,6 +77,8 @@ export function BeeTableTd<R extends object>({
onDataCellClick,
onDataCellKeyUp,
isReadOnly,
canDisplayEvaluationHitsCountBadge,
evaluationHitsCount,
}: BeeTableTdProps<R>) {
const [isResizing, setResizing] = useState(false);
const [hoverInfo, setHoverInfo] = useState<HoverInfo>({ isHovered: false });
Expand Down Expand Up @@ -225,6 +231,12 @@ export function BeeTableTd<R extends object>({
return onDataCellKeyUp?.(column.id);
}, [column.id, onDataCellKeyUp]);

const evaluationHitsCountBadgeClassName = canDisplayEvaluationHitsCountBadge
? (evaluationHitsCount ?? 0) > 0
? "evaluation-hits-count-badge-colored"
: "evaluation-hits-count-badge-non-colored"
: "";

return (
<BeeTableCoordinatesContextProvider coordinates={coordinates}>
<td
Expand All @@ -246,9 +258,11 @@ export function BeeTableTd<R extends object>({
}}
>
{column.isRowIndexColumn ? (
<>{rowIndexLabel}</>
<div className={evaluationHitsCountBadgeClassName} data-evaluation-hits-count={evaluationHitsCount}>
{rowIndexLabel}
</div>
) : (
<>
<div className={evaluationHitsCountBadgeClassName} data-evaluation-hits-count={evaluationHitsCount}>
{tdContent}

{!isReadOnly && shouldRenderResizer && (
Expand All @@ -262,7 +276,7 @@ export function BeeTableTd<R extends object>({
setResizing={setResizing}
/>
)}
</>
</div>
)}

{!isReadOnly &&
Expand Down
Loading