diff --git a/packages/boxed-expression-component/src/BoxedExpressionEditor.tsx b/packages/boxed-expression-component/src/BoxedExpressionEditor.tsx index 920e4110257..261f91fb877 100644 --- a/packages/boxed-expression-component/src/BoxedExpressionEditor.tsx +++ b/packages/boxed-expression-component/src/BoxedExpressionEditor.tsx @@ -59,6 +59,7 @@ export interface BoxedExpressionEditorProps { isReadOnly?: boolean; /** PMML models available to use on Boxed PMML Function */ pmmlDocuments?: PmmlDocument[]; + evaluationHitsCountPerId?: Map; /** The containing HTMLElement which is scrollable */ scrollableParentRef: React.RefObject; /** Parsed variables used for syntax coloring and auto-complete */ @@ -79,6 +80,7 @@ export function BoxedExpressionEditor({ isResetSupportedOnRootExpression, scrollableParentRef, pmmlDocuments, + evaluationHitsCountPerId, onRequestFeelVariables, widthsById, onWidthsChange, @@ -103,6 +105,7 @@ export function BoxedExpressionEditor({ isReadOnly={isReadOnly} dataTypes={dataTypes} pmmlDocuments={pmmlDocuments} + evaluationHitsCountPerId={evaluationHitsCountPerId} onRequestFeelVariables={onRequestFeelVariables} widthsById={widthsById} hideDmn14BoxedExpressions={hideDmn14BoxedExpressions} diff --git a/packages/boxed-expression-component/src/BoxedExpressionEditorContext.tsx b/packages/boxed-expression-component/src/BoxedExpressionEditorContext.tsx index ce879f8808c..14b760e9b05 100644 --- a/packages/boxed-expression-component/src/BoxedExpressionEditorContext.tsx +++ b/packages/boxed-expression-component/src/BoxedExpressionEditorContext.tsx @@ -34,6 +34,7 @@ export interface BoxedExpressionEditorContextType { pmmlDocuments?: PmmlDocument[]; dataTypes: DmnDataType[]; isReadOnly?: boolean; + evaluationHitsCountPerId?: Map; // State currentlyOpenContextMenu: string | undefined; @@ -74,6 +75,7 @@ export function BoxedExpressionEditorContextProvider({ beeGwtService, children, pmmlDocuments, + evaluationHitsCountPerId, scrollableParentRef, onRequestFeelVariables, widthsById, @@ -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, diff --git a/packages/boxed-expression-component/src/api/BeeTable.ts b/packages/boxed-expression-component/src/api/BeeTable.ts index 68c662f4ba2..8d35e0aa387 100644 --- a/packages/boxed-expression-component/src/api/BeeTable.ts +++ b/packages/boxed-expression-component/src/api/BeeTable.ts @@ -97,6 +97,10 @@ export interface BeeTableProps { 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) => boolean; } /** Possible status for the visibility of the Table's Header */ diff --git a/packages/boxed-expression-component/src/expressions/ConditionalExpression/ConditionalExpression.tsx b/packages/boxed-expression-component/src/expressions/ConditionalExpression/ConditionalExpression.tsx index ab9871d81e8..de44afdc6b1 100644 --- a/packages/boxed-expression-component/src/expressions/ConditionalExpression/ConditionalExpression.tsx +++ b/packages/boxed-expression-component/src/expressions/ConditionalExpression/ConditionalExpression.tsx @@ -226,6 +226,14 @@ export function ConditionalExpression({ [setExpression] ); + const getRowKey = useCallback((row: ReactTable.Row) => { + return row.original.part["@_id"]; + }, []); + + const getEvaluationHitsCountSupportedByRow = useCallback((row: ReactTable.Row) => { + return row.original.label !== "if"; + }, []); + return (
@@ -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} @@ -247,6 +256,8 @@ export function ConditionalExpression({ shouldRenderRowIndexColumn={false} shouldShowRowsInlineControls={false} shouldShowColumnsInlineControls={false} + evaluationHitsCountColumnIndex={1} + getEvaluationHitsCountSupportedByRow={getEvaluationHitsCountSupportedByRow} />
diff --git a/packages/boxed-expression-component/src/expressions/DecisionTableExpression/DecisionTableExpression.tsx b/packages/boxed-expression-component/src/expressions/DecisionTableExpression/DecisionTableExpression.tsx index e22e1da0ce0..e1fe29c0794 100644 --- a/packages/boxed-expression-component/src/expressions/DecisionTableExpression/DecisionTableExpression.tsx +++ b/packages/boxed-expression-component/src/expressions/DecisionTableExpression/DecisionTableExpression.tsx @@ -1045,6 +1045,10 @@ export function DecisionTableExpression({ [beeTableRows.length] ); + const getEvaluationHitsCountSupportedByRow = useCallback((row: ReactTable.Row) => { + return true; + }, []); + return (
@@ -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 />
diff --git a/packages/boxed-expression-component/src/table/BeeTable/BeeTable.css b/packages/boxed-expression-component/src/table/BeeTable/BeeTable.css index 7f18dc54aab..2c4c2839784 100644 --- a/packages/boxed-expression-component/src/table/BeeTable/BeeTable.css +++ b/packages/boxed-expression-component/src/table/BeeTable/BeeTable.css @@ -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; } diff --git a/packages/boxed-expression-component/src/table/BeeTable/BeeTable.tsx b/packages/boxed-expression-component/src/table/BeeTable/BeeTable.tsx index 6bd456c9f80..f06360b56d4 100644 --- a/packages/boxed-expression-component/src/table/BeeTable/BeeTable.tsx +++ b/packages/boxed-expression-component/src/table/BeeTable/BeeTable.tsx @@ -103,6 +103,8 @@ export function BeeTableInternal({ resizerStopBehavior, lastColumnMinWidth, rowWrapper, + evaluationHitsCountColumnIndex, + getEvaluationHitsCountSupportedByRow, }: BeeTableProps & { selectionRef?: React.RefObject; }) { @@ -657,6 +659,8 @@ export function BeeTableInternal({ onDataCellKeyUp={onDataCellKeyUp} lastColumnMinWidth={lastColumnMinWidth} isReadOnly={isReadOnly} + evaluationHitsCountColumnIndex={evaluationHitsCountColumnIndex} + getEvaluationHitsCountSupportedByRow={getEvaluationHitsCountSupportedByRow} /> { /** Table instance */ @@ -55,6 +56,10 @@ export interface BeeTableBodyProps { rowWrapper?: React.FunctionComponent>; isReadOnly: boolean; + /** See BeeTable.ts */ + evaluationHitsCountColumnIndex?: number; + /** See BeeTable.ts */ + getEvaluationHitsCountSupportedByRow?: (row: ReactTable.Row) => boolean; } export function BeeTableBody({ @@ -72,15 +77,29 @@ export function BeeTableBody({ lastColumnMinWidth, rowWrapper, isReadOnly, + evaluationHitsCountColumnIndex, + getEvaluationHitsCountSupportedByRow, }: BeeTableBodyProps) { + const { evaluationHitsCountPerId } = useBoxedExpressionEditor(); + const renderRow = useCallback( (row: ReactTable.Row, 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 = () => ( - + {row.cells.map((cell, cellIndex) => { const columnKey = getColumnKey(reactTableInstance.allColumns[cellIndex]); + const canDisplayEvaluationHitsCountBadge = + canDisplayEvaluationHitsCountRowOverlay && cellIndex === evaluationHitsCountColumnIndex; return ( {((cell.column.isRowIndexColumn && shouldRenderRowIndexColumn) || !cell.column.isRowIndexColumn) && ( @@ -104,6 +123,8 @@ export function BeeTableBody({ cellIndex === reactTableInstance.allColumns.length - 1 ? lastColumnMinWidth : undefined } isReadOnly={isReadOnly} + canDisplayEvaluationHitsCountBadge={canDisplayEvaluationHitsCountBadge} + evaluationHitsCount={rowEvaluationHitsCount} /> )} @@ -114,8 +135,6 @@ export function BeeTableBody({ const RowWrapper = rowWrapper; - const rowKey = getRowKey(row); - return ( {RowWrapper ? ( diff --git a/packages/boxed-expression-component/src/table/BeeTable/BeeTableTd.tsx b/packages/boxed-expression-component/src/table/BeeTable/BeeTableTd.tsx index b9a0a71da04..b9615b7df01 100644 --- a/packages/boxed-expression-component/src/table/BeeTable/BeeTableTd.tsx +++ b/packages/boxed-expression-component/src/table/BeeTable/BeeTableTd.tsx @@ -49,6 +49,10 @@ export interface BeeTableTdProps { 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 = @@ -73,6 +77,8 @@ export function BeeTableTd({ onDataCellClick, onDataCellKeyUp, isReadOnly, + canDisplayEvaluationHitsCountBadge, + evaluationHitsCount, }: BeeTableTdProps) { const [isResizing, setResizing] = useState(false); const [hoverInfo, setHoverInfo] = useState({ isHovered: false }); @@ -225,6 +231,12 @@ export function BeeTableTd({ 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 ( ({ }} > {column.isRowIndexColumn ? ( - <>{rowIndexLabel} +
+ {rowIndexLabel} +
) : ( - <> +
{tdContent} {!isReadOnly && shouldRenderResizer && ( @@ -262,7 +276,7 @@ export function BeeTableTd({ setResizing={setResizing} /> )} - +
)} {!isReadOnly &&