Skip to content

Audit History

HTMLRevoGridElement (Extended from @revolist/revogrid)

Section titled “HTMLRevoGridElement (Extended from @revolist/revogrid)”
interface HTMLRevoGridElement {
auditHistory?: AuditHistoryConfig
}

AdditionalData (Extended from @revolist/revogrid)

Section titled “AdditionalData (Extended from @revolist/revogrid)”
interface AdditionalData {
/**
* @deprecated Use the direct `grid.auditHistory` property instead.
*/
auditHistory?: AuditHistoryConfig
}

HTMLRevoGridElementEventMap (Extended from global)

Section titled “HTMLRevoGridElementEventMap (Extended from global)”
interface HTMLRevoGridElementEventMap {
auditrecord: AuditRecord;
auditrecordsloaded: AuditRecord[];
auditerror: AuditHistoryError;
beforeauditrestore: AuditRestoreEvent;
auditrestore: AuditRestoreEvent
}
export function createLocalStorageAuditHistoryAdapter(storageKey = DEFAULT_STORAGE_KEY): AuditHistoryStorageAdapter;

  • Required EventManagerPlugin: Requires EventManagerPlugin to receive normalized edit and paste events.
  • Auto-installed HistoryPlugin: Auto-installs or reuses HistoryPlugin for undo/redo shortcuts and replay integration.
class AuditHistoryPlugin {
getRecords(filter?: AuditHistoryFilter): AuditRecord[];
getCellHistory(rowId: string | number, column: ColumnProp): AuditRecord[];
getRowHistory(rowId: string | number): AuditRecord[];
getRecord(id: string): AuditRecord | undefined;
getTransaction(transactionId: string): AuditRecord[];
getLastChange(rowId: string | number, column?: ColumnProp): AuditChange | undefined;
getStats(filter?: AuditHistoryFilter): AuditHistoryStats;
getRowIdentity(row: DataType | undefined, rowIndex: number, rowType: DimensionRows): string | undefined;
clear(): boolean;
replaceRecords(records: AuditRecord[], options:;
recordEvent(input: AuditRecordEventInput): AuditRecord | undefined;
createSnapshot(label: string, options: AuditSnapshotOptions =;
restoreSnapshot(recordOrId: AuditRecord | string): boolean;
async refreshRecords(options:;
exportRecords(options: AuditHistoryExportOptions =;
canRestoreRecord(context: AuditHistoryRestoreContext): boolean;
restoreCell(change: AuditChange): boolean;
restoreRow(recordOrRowId: AuditRecord | string | number): boolean;
restoreTransaction(transactionId: string): boolean;
}

export type AuditUser = {
id: string;
name?: string;
email?: string;
};

export type BuiltInAuditActionType =
| 'cell-change'
| 'bulk-paste'
| 'row-added'
| 'row-deleted'
| 'row-restored'
| 'undo'
| 'redo'
| 'restore-cell'
| 'restore-row'
| 'restore-transaction'
| 'api-sync'
| 'formula-update'
| 'snapshot-created'
| 'snapshot-restored';

export type AuditActionType = BuiltInAuditActionType | (string & {});

export type AuditHistorySource =
| 'manual'
| 'paste'
| 'api'
| 'formula'
| 'restore'
| 'snapshot'
| 'system';

export type AuditRecordPresentation = {
source?: AuditHistorySource;
verb?: string;
targetLabel?: string;
detailLabel?: string;
rangeLabel?: string;
avatarLabel?: string;
avatarIndex?: number;
avatarColor?: string;
accent?: boolean;
};

export type AuditChangePresentation = {
cellLabel?: string;
columnLabel?: string;
};

export type AuditChange = {
id: string;
rowId?: string;
rowIndex?: number;
rowType: DimensionRows;
column?: ColumnProp;
oldValue?: unknown;
newValue?: unknown;
oldRow?: DataType;
newRow?: DataType;
metadata?: Record<string, unknown>;
presentation?: AuditChangePresentation;
};

export type AuditRecord = {
id: string;
transactionId: string;
type: AuditActionType;
changedAt: string;
changedBy: AuditUser;
changes: AuditChange[];
metadata?: Record<string, unknown>;
presentation?: AuditRecordPresentation;
};

export type AuditHistoryFilter = {
rowId?: string | number;
column?: ColumnProp;
userId?: string;
userEmail?: string;
actionType?: AuditActionType;
transactionId?: string;
dateFrom?: string | Date;
dateTo?: string | Date;
};

export type AuditHistoryStorageAdapter = {
load?: () => AuditRecord[] | Promise<AuditRecord[]>;
save?: (records: AuditRecord[]) => void | Promise<void>;
append?: (record: AuditRecord, records: AuditRecord[]) => void | Promise<void>;
clear?: () => void | Promise<void>;
};

export type AuditHistoryError = {
phase:
| 'get-current-user'
| 'metadata'
| 'sanitize'
| 'storage-load'
| 'storage-save'
| 'storage-append'
| 'storage-clear'
| 'on-record'
| 'restore'
| 'export'
| 'replace-records'
| 'record-event'
| 'track-record'
| 'snapshot';
error: unknown;
record?: AuditRecord;
};

export type AuditHistoryRestoreContext = {
type: AuditRestoreType;
record?: AuditRecord;
change?: AuditChange;
transactionId?: string;
};

export type AuditHistoryStats = {
totalRecords: number;
totalChanges: number;
firstChangedAt?: string;
lastChangedAt?: string;
byType: Partial<Record<AuditActionType, number>>;
byUser: Record<string, number>;
};

export type AuditHistoryExportFormat = 'json' | 'csv';

export type AuditHistoryExportOptions = {
format?: AuditHistoryExportFormat;
filter?: AuditHistoryFilter;
includeMetadata?: boolean;
};

export type AuditRecordTrackContext = {
type: AuditActionType;
changes: AuditChange[];
source?: AuditHistorySource;
metadata?: Record<string, unknown>;
record: AuditRecord;
event?: unknown;
};

export type AuditHistoryConfig = {
getCurrentUser?: () => AuditUser;
getMetadata?: (context: { type: AuditActionType; changes: AuditChange[] }) => Record<string, unknown> | undefined;
rowIdProp?: string;
getRowId?: (
row: DataType,
context: { rowIndex: number; rowType: DimensionRows },
) => string | number | undefined;
sanitizeValue?: (
value: unknown,
context: {
rowId?: string;
rowIndex?: number;
rowType: DimensionRows;
column?: ColumnProp;
direction: 'old' | 'new';
},
) => unknown;
shouldTrackChange?: (
change: Omit<AuditChange, 'id'>,
context: { type: AuditActionType },
) => boolean;
shouldTrackRecord?: (context: AuditRecordTrackContext) => boolean;
trackedActionTypes?: AuditActionType[];
ignoredActionTypes?: AuditActionType[];
ignoredColumns?: ColumnProp[] | ((context: { column?: ColumnProp; rowType: DimensionRows; rowId?: string }) => boolean);
captureSourceUpdates?: boolean;
immutable?: boolean;
canRestore?: (context: AuditHistoryRestoreContext) => boolean;
storage?: 'memory' | 'localStorage' | 'custom';
storageKey?: string;
storageAdapter?: AuditHistoryStorageAdapter;
storageProviders?: AuditHistoryStorageAdapter[];
mergeStorageProviders?: boolean;
records?: AuditRecord[];
maxRecords?: number;
disabled?: boolean;
onAuditRecord?: (record: AuditRecord) => void | Promise<void>;
onAuditError?: (error: AuditHistoryError) => void;
onRecordsLoaded?: (records: AuditRecord[]) => void;
};

AuditEventChangeInput (Extended from index.ts)

Section titled “AuditEventChangeInput (Extended from index.ts)”
export type AuditEventChangeInput = Omit<AuditChange, 'id'> & { id?: string };

export type AuditRecordEventInput = {
type: AuditActionType;
changes?: AuditEventChangeInput[];
changedAt?: string;
changedBy?: AuditUser;
transactionId?: string;
metadata?: Record<string, unknown>;
presentation?: AuditRecordPresentation;
allowEmpty?: boolean;
};

export type AuditSnapshotOptions = {
rowType?: DimensionRows;
rows?: DataType[];
metadata?: Record<string, unknown>;
presentation?: AuditRecordPresentation;
};

export type AuditRestoreType = 'cell' | 'row' | 'transaction' | 'snapshot';

export type AuditRestoreEvent = {
type: AuditRestoreType;
record?: AuditRecord;
change?: AuditChange;
transactionId?: string;
};

Renders the Audit History panel into el for the given RevoGrid element.

The grid must have AuditHistoryPlugin installed.

export function defineAuditHistoryPanel(el: HTMLElement, grid: HTMLRevoGridElement, options: AuditHistoryPanelOptions =;

export type AuditHistoryPanelDateFormatContext = {
mode: 'time' | 'day' | 'filter';
record?: AuditRecord;
};

export type AuditHistoryPanelEvents = {
beforeRecordSelect?: (context: AuditHistoryPanelRecordContext) => boolean | void;
beforeCompareOpen?: (context: AuditHistoryPanelRecordContext) => boolean | void;
beforeJumpToCell?: (context: AuditHistoryPanelJumpContext) => boolean | void;
beforeRestore?: (context: AuditHistoryPanelRestoreContext) => boolean | void;
beforeExport?: (context: AuditHistoryPanelExportContext) => boolean | void;
};

export type AuditHistoryPanelExportContext = {
format: AuditHistoryExportFormat;
};

export type AuditHistoryPanelJumpContext = {
record: AuditRecord;
change: AuditChange;
};

export type AuditHistoryPanelLabels = {
title: string;
liveStatus: string;
recordsSummary: (count: number) => string;
changesSummary: (count: number) => string;
allTab: string;
rowTab: string;
cellTab: string;
tableTab: string;
selectedCell: (rowId: string, column: ColumnProp) => string;
selectedRow: (rowId: string) => string;
export: string;
exportCsv: string;
exportJson: string;
exportCsvTitle: string;
exportJsonTitle: string;
close: string;
openPanel: string;
searchPlaceholder: string;
searchAriaLabel: string;
searchShortcut: string;
userPlaceholder: string;
userAriaLabel: string;
columnAriaLabel: string;
actionAriaLabel: string;
dateFromAriaLabel: string;
dateToAriaLabel: string;
allColumns: string;
allActions: string;
clearFilters: string;
addFilter: string;
removeFilter: (label: string) => string;
noRecords: string;
noComparableRecord: string;
scopedRecordCount: (visibleChanges: number, totalChanges: number) => string;
changedBy: (changedAt: string, user: string) => string;
rowTarget: (rowId: string | undefined, column: ColumnProp | undefined) => string;
cellValues: (oldValue: string, newValue: string) => string;
rowSnapshotAvailable: string;
rowRemoved: string;
restoreCell: string;
restoreRow: string;
restoreTransaction: string;
restoreSnapshot: string;
jumpToCell: string;
revertAll: string;
moreActions: string;
compare: string;
compareTitle: string;
compareBefore: string;
compareAfter: string;
closeCompare: string;
compareEmpty: string;
viewChanges: (count: number) => string;
previousPage: string;
nextPage: string;
pageStatus: (currentPage: number, pageCount: number) => string;
dayToday: string;
dayYesterday: string;
sourceLabels: Record<AuditHistorySource, string>;
actions: Partial<Record<AuditActionType, string>>;
actionVerbs: Partial<Record<AuditActionType, string>>;
};

AuditHistoryPanelLabelsOptions (Extended from index.ts)

Section titled “AuditHistoryPanelLabelsOptions (Extended from index.ts)”
export type AuditHistoryPanelLabelsOptions = Partial<Omit<AuditHistoryPanelLabels, 'actions' | 'actionVerbs' | 'sourceLabels'>> & {
actions?: Partial<Record<AuditActionType, string>>;
actionVerbs?: Partial<Record<AuditActionType, string>>;
sourceLabels?: Partial<Record<AuditHistorySource, string>>;
};

export type AuditHistoryPanelHandle = {
destroy: () => void;
setPlacement: (placement: AuditHistoryPanelPlacement) => void;
refresh: () => Promise<void>;
};

export type AuditHistoryPanelOptions = {
pageSize?: number;
allowExport?: boolean;
allowCompare?: boolean | ((context: AuditHistoryPanelRecordContext) => boolean);
allowClose?: boolean;
miniOnClose?: boolean;
restoreActions?: false | AuditRestoreType[] | ((context: AuditHistoryPanelRestoreContext) => boolean);
formatDate?: (value: string, context: AuditHistoryPanelDateFormatContext) => string;
events?: AuditHistoryPanelEvents;
placement?: AuditHistoryPanelPlacement;
tooltips?: false | Partial<Record<AuditHistoryPanelTooltipKey, string | false>>;
labels?: AuditHistoryPanelLabelsOptions;
};

export type AuditHistoryPanelRecordContext = {
record: AuditRecord;
changes: AuditChange[];
};

export type AuditHistoryPanelRestoreContext = {
type: AuditRestoreType;
record?: AuditRecord;
change?: AuditChange;
transactionId?: string;
};

export type AuditHistoryPanelPlacement = 'right' | 'left' | 'top' | 'bottom' | 'none';

export type AuditHistoryPanelTooltipKey =
| 'totalRecords'
| 'totalChanges'
| 'selectedScope'
| 'searchFilter'
| 'userFilter'
| 'columnFilter'
| 'actionFilter'
| 'dateFromFilter'
| 'dateToFilter'
| 'clearFilters';

AUDIT_HISTORY_STORAGE_KEY: string;

export function cloneValue<T>(value: T): T;

export function cloneChange(change: AuditChange): AuditChange;

export function cloneRecord(record: AuditRecord): AuditRecord;

export function normalizeRowId(rowId: string | number | undefined): string | undefined;

export function toTime(value: string | Date | undefined, fallback: number);

export function shouldIncludeRecord(record: AuditRecord, filter?: AuditHistoryFilter);

export function trimRecords(records: AuditRecord[], maxRecords: number): AuditRecord[];

export function mergeRecords(current: AuditRecord[], next: AuditRecord[]): AuditRecord[];

export function createAuditStats(records: AuditRecord[], filter?: AuditHistoryFilter): AuditHistoryStats;

export function stringifyExportValue(value: unknown): string;

export function exportAuditRecords(records: AuditRecord[], options: AuditHistoryExportOptions =;