Skip to content

Grid Notes

HTMLRevoGridElement (Extended from @revolist/revogrid)

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

AdditionalData (Extended from @revolist/revogrid)

Section titled “AdditionalData (Extended from @revolist/revogrid)”
interface AdditionalData {
/** @deprecated Use `grid.gridNotes`. */
gridNotes?: GridNotesConfig
}

HTMLRevoGridElementEventMap (Extended from global)

Section titled “HTMLRevoGridElementEventMap (Extended from global)”
interface HTMLRevoGridElementEventMap {
gridnotechange: GridNoteChangeEvent;
gridnotemention: GridNoteMentionEvent;
gridnoteconflict: GridNoteConflictError;
gridnoteerror: GridNoteErrorEvent;
gridnotefilterchange: GridNoteFilterChangeEvent
}
export type GridNoteSeverity = 'none' | 'info' | 'warning' | 'blocker' | 'resolved';

export type GridNotePermissionAction = 'view' | 'create' | 'edit' | 'delete' | 'restore';

export type GridNoteTarget =
| { readonly kind: 'row'; readonly rowKey: string }
| { readonly kind: 'cell'; readonly rowKey: string; readonly colProp: ColumnProp };

interface GridNoteUser {
readonly id: string;
readonly name: string;
readonly email?: string;
readonly avatarUrl?: string;
readonly color?: string
}

interface GridNoteMention {
readonly userId: string;
readonly label: string;
readonly start: number;
readonly end: number
}

interface GridNoteSummary {
readonly id: string;
readonly target: GridNoteTarget;
readonly severity: GridNoteSeverity;
readonly excerpt: string;
readonly author: GridNoteUser;
readonly createdAt: string;
readonly updatedAt: string;
readonly version: number;
readonly versionCount: number;
readonly pending?: boolean
}

interface GridNote {
readonly body: string;
readonly mentions: readonly GridNoteMention[]
}

interface GridNoteVersion {
readonly id: string;
readonly noteId: string;
readonly version: number;
readonly body: string;
readonly severity: GridNoteSeverity;
readonly mentions: readonly GridNoteMention[];
readonly author: GridNoteUser;
readonly createdAt: string;
readonly changeSummary: string;
readonly restoredFromVersionId?: string
}

interface GridNotePage {
readonly items: readonly T[];
readonly nextCursor?: string
}

interface GridNoteMutationInput {
readonly target: GridNoteTarget;
readonly body: string;
readonly severity: GridNoteSeverity;
readonly mentions: readonly GridNoteMention[];
readonly actor: GridNoteUser;
readonly expectedVersion?: number;
readonly mutationId: string;
readonly signal?: AbortSignal
}

interface GridNoteUpsertInput {
readonly target: GridNoteTarget;
readonly body: string;
readonly severity: GridNoteSeverity;
readonly mentions?: readonly GridNoteMention[];
readonly expectedVersion?: number
}

interface GridNoteStorageAdapter {
init?(): void | Promise<void>;
destroy?(): void | Promise<void>;
loadSummaries(input: { rowKeys: readonly string[]; signal?: AbortSignal }): Promise<readonly GridNoteSummary[]>;
getNote(input: { target: GridNoteTarget; signal?: AbortSignal }): Promise<GridNote | undefined>;
listVersions(input: { noteId: string; cursor?: string; limit: number; signal?: AbortSignal }): Promise<GridNotePage<GridNoteVersion>>;
upsert(input: GridNoteMutationInput): Promise<GridNote>;
delete(input: { target: GridNoteTarget; actor: GridNoteUser; expectedVersion?: number; mutationId: string; signal?: AbortSignal }): Promise<void>;
restoreVersion(input: { noteId: string; versionId: string; actor: GridNoteUser; expectedVersion: number; mutationId: string; signal?: AbortSignal }): Promise<GridNote>;
queryRowKeysBySeverity(input: { severities: readonly GridNoteSeverity[]; signal?: AbortSignal }): Promise<readonly string[]>;
listNotes(input: { cursor?: string; limit: number; signal?: AbortSignal }): Promise<GridNotePage<GridNote>>
}

interface GridNotePermissionContext {
readonly action: GridNotePermissionAction;
readonly target: GridNoteTarget;
readonly row?: T;
readonly note?: GridNote;
readonly user: GridNoteUser
}

interface GridNotesLabels {
addNote: string;
addCell: string;
editCell: string;
addRow: string;
editRow: string;
filter: string;
clearFilter: string;
save: string;
cancel: string;
edit: string;
close: string;
history: string;
restore: string;
delete: string;
color: string;
none: string;
info: string;
warning: string;
blocker: string;
resolved: string;
alsoOnRow: string
}

interface GridNotesConfig {
readonly adapter: GridNoteStorageAdapter;
readonly getRowId: (row: T, context: { rowIndex: number; rowType: DimensionRows }) => string | number | undefined;
readonly getCurrentUser: () => GridNoteUser | Promise<GridNoteUser>;
readonly can?: (context: GridNotePermissionContext<T>) => boolean | Promise<boolean>;
readonly mentions?: { search(query: string, signal?: AbortSignal): Promise<readonly GridNoteUser[]> };
readonly prefetchRows?: number;
readonly coalesceMs?: number;
readonly historyPageSize?: number;
readonly draftStorageKey?: string;
readonly retryMaxDelayMs?: number;
readonly confirmDiscard?: (message: string) => boolean | Promise<boolean>;
readonly confirmDelete?: (message: string) => boolean | Promise<boolean>;
readonly labels?: Partial<GridNotesLabels>;
readonly severityColors?: Partial<Record<GridNoteSeverity, string>>;
readonly excel?: { readonly includeNotesSheet?: boolean; readonly sheetName?: string }
}

interface GridNoteOpenOptions {
readonly mode?: 'read' | 'edit';
readonly anchor?: HTMLElement;
readonly row?: DataType
}

interface GridNoteChangeEvent {
readonly type: 'upsert' | 'delete' | 'restore';
readonly target: GridNoteTarget;
readonly note?: GridNote;
readonly pending?: boolean
}

interface GridNoteMentionEvent {
readonly note: GridNote;
readonly users: readonly GridNoteUser[]
}

interface GridNoteFilterChangeEvent {
readonly severities: readonly GridNoteSeverity[]
}

interface GridNoteErrorEvent {
readonly phase: string;
readonly error: unknown;
readonly target?: GridNoteTarget
}

class GridNoteConflictError {}

export function gridNoteTargetKey(target: GridNoteTarget): string;

export function gridNoteExcerpt(body: string): string;

export function toGridNoteSummary(note: GridNote, pending = note.pending): GridNoteSummary;

export function cloneGridNote<T extends GridNote | GridNoteSummary>(note: T): T;

export function createGridNoteId(prefix: string): string;

export function diffGridNoteMentionUserIds(
previous: readonly { userId: string }[],
next: readonly { userId: string }[],
): string[];

GRID_NOTE_EXCERPT_LENGTH: 120;

export type GridNoteStoreListener = (rowKeys: readonly string[]) => void;

class GridNoteStore {
subscribe(listener: GridNoteStoreListener): () => void;
get(target: GridNoteTarget): GridNoteSummary | undefined;
getRow(rowKey: string): GridNoteSummary[];
set(note: GridNote | GridNoteSummary): void;
remove(target: GridNoteTarget): void;
markPending(target: GridNoteTarget, pending: boolean): void;
queueRows(rowKeys: readonly string[], force = false): Promise<void>;
async flushRows(signal?: AbortSignal): Promise<void>;
getNote(target: GridNoteTarget, signal?: AbortSignal): Promise<GridNote | undefined>;
listVersions(noteId: string, cursor: string | undefined, limit: number, signal?: AbortSignal): Promise<GridNotePage<GridNoteVersion>>;
queryRowKeysBySeverity(severities: readonly GridNoteSeverity[], signal?: AbortSignal): Promise<readonly string[]>;
clear(): void;
destroy(): void;
}

class InMemoryGridNoteAdapter {
async loadSummaries({ rowKeys, signal }: { rowKeys: readonly string[]; signal?: AbortSignal }): Promise<readonly GridNoteSummary[]>;
async getNote({ target, signal }: { target: GridNoteTarget; signal?: AbortSignal }): Promise<GridNote | undefined>;
async listVersions({ noteId, cursor, limit, signal }: { noteId: string; cursor?: string; limit: number; signal?: AbortSignal }): Promise<GridNotePage<GridNoteVersion>>;
async upsert(input: GridNoteMutationInput): Promise<GridNote>;
async delete(input: { target: GridNoteTarget; actor: GridNoteUser; expectedVersion?: number; mutationId: string; signal?: AbortSignal }): Promise<void>;
async restoreVersion(input: { noteId: string; versionId: string; actor: GridNoteUser; expectedVersion: number; mutationId: string; signal?: AbortSignal }): Promise<GridNote>;
async queryRowKeysBySeverity({ severities, signal }: { severities: readonly GridNoteSeverity[]; signal?: AbortSignal }): Promise<readonly string[]>;
async listNotes({ cursor, limit, signal }: { cursor?: string; limit: number; signal?: AbortSignal }): Promise<GridNotePage<GridNote>>;
}

export function createGridNotesWorksheet(
notes: readonly GridNote[],
getColumnLabel: (prop: ColumnProp) => string,
sheetName = 'Notes',
): ExcelExportWorksheetDescriptor;

Cell and row notes backed by a host adapter and stable authored row ids.

  • Auto-installed ContextMenuPlugin: Adds cell, row, and severity-filter commands to the shared low-level context menu.
  • Event integration ExportExcelPlugin: Appends a Notes worksheet when Excel export is installed and notes-sheet export is enabled.
  • Auto-installed TooltipPlugin: Shows note excerpts over pseudo-element marker hit areas without adding cell DOM.
class GridNotesPlugin {
async openNote(target: GridNoteTarget, options: GridNoteOpenOptions = {}): Promise<void>;
getNote(target: GridNoteTarget, signal?: AbortSignal): Promise<GridNote | undefined>;
async upsertNote(input: GridNoteUpsertInput): Promise<GridNote>;
async removeNote(target: GridNoteTarget): Promise<void>;
async refreshNotes(rowKeys?: readonly string[]): Promise<void>;
getSeverityFilter(): readonly GridNoteSeverity[];
async setSeverityFilter(severities: readonly GridNoteSeverity[]): Promise<void>;
destroy(): void;
}