MD.OFFICE
FAL

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 (MatrixRow and MatrixConfig in form-element-config.types.ts) to support formula types alongside regular inputs.
  • Enhanced FormulaBuilderComponent (formula-builder.component.ts & .html) with an optional matrixFormulaMode ('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 getMatrixRowReferenceFields to build @Row.N pseudo-fields.
    • Added getMatrixColReferenceFields to build @Col.N pseudo-fields.
    • Added onRowTypeChange(item, row, newType) to switch row types.
    • Added onFormulaRowFormulaChange, onToggleFormulaColumn, and onFormulaColumnFormulaChange for state management and persistence.
  • 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> for row.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 getMatrixRowReferenceFields to output labels in the format: Row N — <User Label or Key>.
  • Updated getMatrixColReferenceFields to 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 in onValidateFormula by momentarily sanitizing strings (e.g., to Row_1) for the /validate API payload to bypass identifiers validation.
  • Problem 2 (Display Reversion): Existing formula builder text rendered @Row.1 directly. Fixed the regex in toLabelFormula using 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.html by 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 FormControl entries for formula column cells (matrixKey_rowKey_formulaColKey).
    • Added evaluateFormulaRows() mapping @Row.N relative inputs to the generic evaluateFormula() API.
    • Added evaluateFormulaColumn() mapping @Col.N.
    • Re-used FormControl keys for evaluated cells, writing results back with { emitEvent: false }.
  • matrix.component.html:
    • Renders readonly input for formula rows with a grey #F3F4F6 background style.
    • Adds formula column headers and td logic spanning grouped/simple variations and placeholders in summary rows.

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 formulaSubject with RxJS debounceTime(300) on value changes to prevent rapid single-keystroke API spam. Basic matrix sums remain instant.
  • Evaluation Chaining: Refactored evaluateFormulas so that columns evaluate first with a forkJoin, 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.N syntax into engine-friendly variables like rN and cN.