demo D109
Data Masking and Column Redaction in Angular
Masking values a viewer must not see
grid.redaction
This masks the contents of specific cells from a viewer while leaving the row and column structure intact. It lets someone work with sensitive records, scanning a customer list, without ever rendering the card or ID number underneath.
This is the Angular version. A standalone component takes the whole configuration through one config input, surfaces grid events as outputs, and exposes the live grid on a getter for anything the inputs do not cover.
The configuration
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { createGrid } from '@toclocoinc/lattice-grid';
import '@toclocoinc/lattice-grid/css';
import { LatticeGridComponent, provideLattice } from '@toclocoinc/lattice-grid/angular';
@Component({
selector: 'app-root',
standalone: true,
imports: [LatticeGridComponent],
template: '<lattice-grid [config]="grid" style="display:block;height:540px"></lattice-grid>',
})
export class AppComponent {
grid = {
rowKey: 'id',
selection: 'multiple',
toolPanel: { side: 'left', panels: ['columns', 'filters', 'views', 'quick'], actions: ['undo', 'redo', 'export', 'restore', 'maximise'], exportName: 'lattice-demo' },
// Redaction is grid state: it travels in a saved view and undoes like
// any other change rather than being a switch outside the model.
state: { version: 1, redaction: ['monthlyCost', 'budget'] },
columns: [
{ field: 'service', title: 'Service', layout: { pin: 'start', width: 160 } },
{ field: 'team', title: 'Team', filter: { type: 'set' } },
{ field: 'owner', title: 'Owner', filter: { type: 'set' } },
{ field: 'region', title: 'Region', filter: { type: 'set' } },
{ field: 'headcount', title: 'Headcount', type: 'number', total: 'sum' },
{ field: 'monthlyCost', title: 'Monthly cost', type: 'number', format: { style: 'currency', currency: 'USD' }, total: 'sum' },
{ field: 'budget', title: 'Budget', type: 'number', format: { style: 'currency', currency: 'USD' }, total: 'sum' },
],
rows: [/* service records */],
};
}
bootstrapApplication(AppComponent, {
providers: [provideLattice({ createGrid })],
});
Masking values a viewer must not see
Redaction hides the contents of specific cells from a viewer while leaving the row and column structure intact, so a support agent can scan customer records without ever rendering the card number or national insurance number underneath the mask. It sits below permissions in the access model: permissions decide whether a role can see a column at all, while redaction handles the case where a role can see that a value exists but not the value itself. A developer reaches for it wherever regulation or internal policy demands that data be visible to some sessions and masked for others without shipping two different views of the same JavaScript data grid. Lattice Grid exposes this through grid.redaction, which a host wires to its own entitlement check per cell so the masking decision is made once per render pass rather than recomputed on every scroll event. Masked cells still occupy their row height and column width, so a viewer’s layout does not shift when a value is hidden, and screen readers announce the mask state rather than reading a blank cell as empty data. Because the check runs against the currently rendered viewport, applying or lifting a redaction rule across thousands of rows costs a lookup per visible cell, not a pass over every record in the grid.
How do you mask sensitive data in a JavaScript data grid?
Data masking in Lattice Grid runs through grid.redaction, which a host application uses to mark specific cells as hidden from the current session based on its own entitlement logic. The grid renders a mask in place of the value, preserves the row and column layout, and reports the mask state to assistive technology, so a viewer without clearance sees that a field exists without ever receiving its contents.