2026-04-03
Matrix Widget: Formula Rows and Columns (Phases 1 & 2)
Implemented custom formula rows and columns for Matrix widgets to allow cross-row or cross-column calculated cells.
Decisions & Solutions
- Extended basic type definitions (
MatrixRowandMatrixConfiginform-element-config.types.ts) to supportformulatypes alongside regular inputs. - Enhanced
FormulaBuilderComponent(formula-builder.component.ts&.html) with an optionalmatrixFormulaMode('row'or'col') to adapt placeholders based on context.
Matrix Formula Rows/Cols: Phase 3 (Right Panel TS helpers)
Added TS helper methods for configuring formula rows and a formula column within the Matrix builder UI.
Decisions & Solutions
right-panel-static.component.ts:- Added
getMatrixRowReferenceFieldsto build@Row.Npseudo-fields. - Added
getMatrixColReferenceFieldsto build@Col.Npseudo-fields. - Added
onRowTypeChange(item, row, newType)to switch row types. - Added
onFormulaRowFormulaChange,onToggleFormulaColumn, andonFormulaColumnFormulaChangefor state management and persistence.
- Added
right-panel-static.component.html:- Replaced 2-column row list loop with a 4-column card layout to include the "Type" dropdown (Regular / Formula).
- Conditionally display
<app-formula-builder>forrow.type === 'formula'and for the newly introduced formula column toggle.
Matrix Formula Rows/Cols: UX Improvement (Right Panel Reference Labels)
Improved formula builder UX by displaying meaningful labels for @Row.N and @Col.N matrix references.
Decisions & Solutions
- Updated
getMatrixRowReferenceFieldsto output labels in the format:Row N — <User Label or Key>. - Updated
getMatrixColReferenceFieldsto output labels in the format:Col N — <User Label or Key>. - Internal formula value remains unchanged (e.g.
@Row.1).
Matrix Formula Rows/Cols: Formula Builder Bug Fixes
Resolved two critical issues with formula builder matrix logic.
Decisions & Solutions
- Problem 1 (Validation Failure): API rejected
@Row.1. Fixed inonValidateFormulaby momentarily sanitizing strings (e.g., toRow_1) for the/validateAPI payload to bypass identifiers validation. - Problem 2 (Display Reversion): Existing formula builder text rendered
@Row.1directly. Fixed the regex intoLabelFormulausing explicit negative lookarounds(?<![\w])and(?![\w])as@wasn't matched properly by word boundary\b.
Matrix Formula Rows/Cols: Center Panel Preview UI
Rendered the matrix formula column within the central canvas preview area so that the configuration is visible during form building.
Decisions & Solutions
- Updated
center-panel.component.htmlby adding conditional<th>elements tied to*ngIf="item.useFormulaColumn"for both Simple and Group modes. - Appended conditional
<td>placeholder cells to all row bodies. Greyed-out read-only styling deferred to Phase 4.
Matrix Formula Phase 4: Renderer Integration
Implemented formula row and formula column evaluation inside the matrix renderer, hooking into the /evaluate API on every value change.
Decisions & Solutions
matrix.component.ts:- Registered
FormControlentries for formula column cells (matrixKey_rowKey_formulaColKey). - Added
evaluateFormulaRows()mapping@Row.Nrelative inputs to the genericevaluateFormula()API. - Added
evaluateFormulaColumn()mapping@Col.N. - Re-used
FormControlkeys for evaluated cells, writing results back with{ emitEvent: false }.
- Registered
matrix.component.html:- Renders readonly input for formula rows with a grey
#F3F4F6background style. - Adds formula column headers and td logic spanning grouped/simple variations and placeholders in summary rows.
- Renders readonly input for formula rows with a grey
Matrix Formula Phase 4: Performance Optimizations & Intersection Handling
Resolved efficiency issues with the matrix /evaluate API integration and corrected intersection cell computation for Formula Rows × Formula Columns.
Decisions & Solutions
- Debouncing: Setup a
formulaSubjectwith RxJSdebounceTime(300)on value changes to prevent rapid single-keystroke API spam. Basic matrix sums remain instant. - Evaluation Chaining: Refactored
evaluateFormulasso that columns evaluate first with aforkJoin, and only upon.subscribe()completion are rows computed to ensure valid sequential dependency resolutions. - Intersection logic: Populated directly via sequential logic, utilizing
getFormulaColControl()of preceding columns. - API Payloads: Mapped variables out of
@Row.Nsyntax into engine-friendly variables likerNandcN.