Member Junction
    Preparing search index...

    Interface IViewRenderer<TConfig>

    Contract honored by a view renderer component. The host binds these inputs and subscribes to these outputs uniformly across all view types.

    interface IViewRenderer<TConfig = unknown> {
        config: TConfig;
        configChanged: EventEmitter<TConfig>;
        configureRequested?: EventEmitter<void>;
        createRecordRequested?: EventEmitter<void>;
        dataRequest?: EventEmitter<ViewDataRequest>;
        entity: EntityInfo | null;
        filterText: string | null;
        isLoading?: boolean;
        openRelatedRecordRequested?: EventEmitter<ViewRelatedRecordNavigation>;
        page?: number;
        pageSize?: number;
        provider?: IMetadataProvider | null;
        recordOpened: EventEmitter<unknown>;
        records: Record<string, unknown>[];
        recordSelected: EventEmitter<unknown>;
        selectedRecordId: string | null;
        totalRecordCount?: number;
        exportRecords?(format?: "csv" | "excel" | "json"): Promise<boolean>;
    }

    Type Parameters

    • TConfig = unknown

      the shape of this view type's configuration object

    Implemented by

    Index

    Properties

    config: TConfig

    View-type-specific configuration.

    configChanged: EventEmitter<TConfig>

    Emitted when the renderer mutates its own opaque config (e.g. timeline date field, grid columns/sort/widths, map render mode). The container persists the blob verbatim against the active ViewTypeID and never inspects it. (Container ↔ plug-in coordination inside the Generic layer — NOT a signal that drives the outer app.)

    configureRequested?: EventEmitter<void>

    Optional: ask the host to open this view's configuration UI (e.g. the workspace's config panel). Generic — every view type has configurable settings (the descriptor's IViewTypeDescriptor.PropSheetComponent); a plug-in raises this when the user invokes an in-renderer affordance for it (e.g. the grid's "Manage Columns" toolbar item). The container forwards it to the host, which owns the config UI; no per-view-type branching. (Container ↔ plug-in coordination — NOT a signal that drives the outer app.)

    createRecordRequested?: EventEmitter<void>

    Optional: NAVIGATION request to create a new record of the current entity (e.g. a grid's "New" button) — opening the create form is a routing concern owned by the outer app. Bubbles up; the container forwards it without acting on it.

    dataRequest?: EventEmitter<ViewDataRequest>

    Optional: ask the container to (re)load the record set differently. The ONLY data-access channel a plug-in has, fully generic — the container honors the request (sort / page / load-all) without knowing which plug-in asked or why. A grid emits sort/page; a map emits { loadAll: true }; a plug-in happy with the records it's given emits nothing. The container owns the actual RunView; no per-view-type branching. (Container ↔ plug-in coordination — NOT a signal that drives the outer app.)

    entity: EntityInfo | null

    The entity whose records are being rendered.

    filterText: string | null

    Active filter text (for highlighting / client-side concerns).

    isLoading?: boolean

    Whether the host is currently (re)loading the record set.

    openRelatedRecordRequested?: EventEmitter<ViewRelatedRecordNavigation>

    Optional: NAVIGATION request to open a related record on a DIFFERENT entity (e.g. a foreign-key drill-through in a grid cell). Bubbles to the outer app for routing. Generic — the container forwards it without acting on it.

    page?: number

    One-based current page of records when the host is paginating.

    pageSize?: number

    Page size the host is using.

    provider?: IMetadataProvider | null

    Optional: the metadata provider, handed to plug-ins that issue their own data calls (multi-provider safety). Generic — not specific to any one view type.

    recordOpened: EventEmitter<unknown>

    Emitted when THIS entity's record should be opened (double-click / open). Payload is the raw record. This is a NAVIGATION request — the only category of signal that legitimately bubbles to the outer app (routing lives there). Everything else a view does (export, add-to-list, delete, …) is self-contained in the plug-in via Generic dialogs and never bubbles up.

    records: Record<string, unknown>[]

    The records to render (already loaded/filtered by the host).

    recordSelected: EventEmitter<unknown>

    Emitted when a record is selected (single click). Payload is the raw record object.

    selectedRecordId: string | null

    Primary-key string of the currently selected record, if any.

    totalRecordCount?: number

    Optional generic data-context the host supplies alongside records. These are universal "a view of records" concepts (counts, current page, loading) — NOT specific to any view type — so a renderer that paginates or shows a total can read them, and one that doesn't simply ignores them. The host owns the actual data fetch; these describe its current result.

    Methods

    • Optional IMPERATIVE export entry point. A renderer that owns a self-contained export affordance (e.g. the grid's export dialog) may expose this so an external driver — the host's programmatic API, ultimately the AI agent — can trigger an export of the current record set WITHOUT going through the renderer's own toolbar UI. Renderers that don't support export simply don't implement it (the host treats absence as "not exportable").

      This is NOT a navigation/UI-coordination signal — it's a direct method call the host makes on the active renderer, mirroring how export is otherwise self-contained in the plug-in.

      Parameters

      • Optionalformat: "csv" | "excel" | "json"

        optional output format ('csv' | 'excel' | 'json'); the renderer picks a sensible default (typically 'excel') when omitted.

      Returns Promise<boolean>

      true when the export was initiated, false when it couldn't be (no data / unsupported).