@memberjunction/ng-entity-viewer 6.1.4 → 6.2.0-edge.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/aggregate-panel/aggregate-panel.component.d.ts +18 -2
- package/dist/lib/aggregate-panel/aggregate-panel.component.d.ts.map +1 -1
- package/dist/lib/aggregate-panel/aggregate-panel.component.js +47 -18
- package/dist/lib/aggregate-panel/aggregate-panel.component.js.map +1 -1
- package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.d.ts +22 -0
- package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.d.ts.map +1 -1
- package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.js +57 -13
- package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.js.map +1 -1
- package/dist/lib/entity-cards/entity-cards.component.d.ts +68 -5
- package/dist/lib/entity-cards/entity-cards.component.d.ts.map +1 -1
- package/dist/lib/entity-cards/entity-cards.component.js +213 -73
- package/dist/lib/entity-cards/entity-cards.component.js.map +1 -1
- package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts +156 -14
- package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts.map +1 -1
- package/dist/lib/entity-data-grid/entity-data-grid.component.js +432 -138
- package/dist/lib/entity-data-grid/entity-data-grid.component.js.map +1 -1
- package/dist/lib/entity-data-grid/events/grid-events.js +67 -67
- package/dist/lib/entity-data-grid/events/grid-events.js.map +1 -1
- package/dist/lib/entity-record-detail-panel/entity-record-detail-panel.component.d.ts +112 -8
- package/dist/lib/entity-record-detail-panel/entity-record-detail-panel.component.d.ts.map +1 -1
- package/dist/lib/entity-record-detail-panel/entity-record-detail-panel.component.js +255 -69
- package/dist/lib/entity-record-detail-panel/entity-record-detail-panel.component.js.map +1 -1
- package/dist/lib/entity-viewer/entity-viewer.component.d.ts +11 -0
- package/dist/lib/entity-viewer/entity-viewer.component.d.ts.map +1 -1
- package/dist/lib/entity-viewer/entity-viewer.component.js +45 -8
- package/dist/lib/entity-viewer/entity-viewer.component.js.map +1 -1
- package/dist/lib/pill/pill.component.d.ts +13 -3
- package/dist/lib/pill/pill.component.d.ts.map +1 -1
- package/dist/lib/pill/pill.component.js +34 -10
- package/dist/lib/pill/pill.component.js.map +1 -1
- package/dist/lib/quick-save-dialog/quick-save-dialog.component.d.ts +29 -3
- package/dist/lib/quick-save-dialog/quick-save-dialog.component.d.ts.map +1 -1
- package/dist/lib/quick-save-dialog/quick-save-dialog.component.js +173 -114
- package/dist/lib/quick-save-dialog/quick-save-dialog.component.js.map +1 -1
- package/dist/lib/recycle-bin/recycle-bin.component.d.ts +4 -0
- package/dist/lib/recycle-bin/recycle-bin.component.d.ts.map +1 -1
- package/dist/lib/recycle-bin/recycle-bin.component.js +10 -2
- package/dist/lib/recycle-bin/recycle-bin.component.js.map +1 -1
- package/dist/lib/utils/aggregate-field.util.d.ts +21 -0
- package/dist/lib/utils/aggregate-field.util.d.ts.map +1 -0
- package/dist/lib/utils/aggregate-field.util.js +40 -0
- package/dist/lib/utils/aggregate-field.util.js.map +1 -0
- package/dist/lib/utils/highlight.util.d.ts +6 -0
- package/dist/lib/utils/highlight.util.d.ts.map +1 -1
- package/dist/lib/utils/highlight.util.js +23 -11
- package/dist/lib/utils/highlight.util.js.map +1 -1
- package/dist/lib/utils/record.util.d.ts +10 -0
- package/dist/lib/utils/record.util.d.ts.map +1 -1
- package/dist/lib/utils/record.util.js +20 -4
- package/dist/lib/utils/record.util.js.map +1 -1
- package/dist/lib/view-config-panel/view-config-panel.component.d.ts +22 -2
- package/dist/lib/view-config-panel/view-config-panel.component.d.ts.map +1 -1
- package/dist/lib/view-config-panel/view-config-panel.component.js +54 -14
- package/dist/lib/view-config-panel/view-config-panel.component.js.map +1 -1
- package/dist/lib/view-selector/view-selector.component.js +2 -2
- package/dist/lib/view-types/renderers/cards-view-renderer.component.d.ts +15 -3
- package/dist/lib/view-types/renderers/cards-view-renderer.component.d.ts.map +1 -1
- package/dist/lib/view-types/renderers/cards-view-renderer.component.js +33 -5
- package/dist/lib/view-types/renderers/cards-view-renderer.component.js.map +1 -1
- package/dist/lib/view-types/renderers/grid-view-renderer.component.d.ts +160 -5
- package/dist/lib/view-types/renderers/grid-view-renderer.component.d.ts.map +1 -1
- package/dist/lib/view-types/renderers/grid-view-renderer.component.js +576 -36
- package/dist/lib/view-types/renderers/grid-view-renderer.component.js.map +1 -1
- package/dist/lib/view-types/renderers/map-view-renderer.component.d.ts +16 -2
- package/dist/lib/view-types/renderers/map-view-renderer.component.d.ts.map +1 -1
- package/dist/lib/view-types/renderers/map-view-renderer.component.js +37 -9
- package/dist/lib/view-types/renderers/map-view-renderer.component.js.map +1 -1
- package/dist/lib/view-types/view-type.contracts.js.map +1 -1
- package/dist/lib/view-workspace/view-workspace.component.d.ts +235 -24
- package/dist/lib/view-workspace/view-workspace.component.d.ts.map +1 -1
- package/dist/lib/view-workspace/view-workspace.component.js +600 -174
- package/dist/lib/view-workspace/view-workspace.component.js.map +1 -1
- package/dist/module.d.ts +5 -4
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +8 -1
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +1 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +21 -20
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid-view-renderer.component.js","sourceRoot":"","sources":["../../../../src/lib/view-types/renderers/grid-view-renderer.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, ViewEncapsulation, ViewChild, ChangeDetectorRef, inject } from '@angular/core';\nimport { EntityInfo, RunViewParams, LogError, CompositeKey } from '@memberjunction/core';\nimport { ExportColumn } from '@memberjunction/export-engine';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { PageChangeEvent } from '@memberjunction/ng-pagination';\nimport { ListManagementDialogConfig, ListManagementResult } from '@memberjunction/ng-list-management';\nimport { IViewRenderer, ViewDataRequest, ViewRelatedRecordNavigation } from '../view-type.contracts';\nimport { ViewGridState } from '../../types';\nimport { GridSelectionMode, GridToolbarConfig, ForeignKeyClickEvent } from '../../entity-data-grid/models/grid-types';\nimport { AfterRowClickEventArgs, AfterRowDoubleClickEventArgs, AfterSortEventArgs } from '../../entity-data-grid/events/grid-events';\nimport { GridStateChangedEvent } from '../../types';\nimport { buildPkString, buildCompositeKey } from '../../utils/record.util';\nimport { EntityDataGridComponent } from '../../entity-data-grid/entity-data-grid.component';\n\n/**\n * Opaque per-view configuration for the Grid view type.\n * -----------------------------------------------------\n * This is the blob the host persists verbatim against the active `ViewTypeID` and never\n * inspects (see {@link IViewRenderer.configChanged}). The renderer seeds the\n * `<mj-entity-data-grid>` bindings from these fields, applying sensible defaults when a\n * field is absent (see {@link GridViewRendererComponent}). It is intentionally a plain,\n * fully-serializable shape — every field is optional so an empty `{}` is a valid config.\n */\nexport interface GridViewConfig {\n /**\n * Persisted grid state (columns/widths/order/sort) from a User View. Mutated in place when\n * the grid emits sort or generic grid-state changes, then surfaced via `configChanged` so the\n * host persists it. Fed straight into `[GridState]`.\n */\n gridState?: ViewGridState;\n /** Whether the grid's own toolbar is shown. Defaults to `true` when absent. */\n showToolbar?: boolean;\n /** The grid toolbar configuration. Fed into `[ToolbarConfig]`. */\n toolbarConfig?: GridToolbarConfig;\n /** Row selection mode. Defaults to `'checkbox'` when absent. */\n selectionMode?: GridSelectionMode;\n /** Whether the \"Add to List\" button is shown. Defaults to `true` when absent. */\n showAddToListButton?: boolean;\n /** Whether the pager is shown. Defaults to `true` when absent. */\n showPager?: boolean;\n /** Page size for the grid's pager. Falls back to the `pageSize` input when absent. */\n pageSize?: number;\n /**\n * Explicit RunViewParams for the grid's data source. When absent the renderer builds a minimal\n * dynamic-view params object from {@link entity}. Fed into `[Params]`.\n */\n params?: RunViewParams;\n}\n\n/**\n * GridViewRendererComponent\n * -------------------------\n * The Grid **view type** renderer — a fully self-contained {@link IViewRenderer} adapter that hosts\n * the existing {@link EntityDataGridComponent} (`<mj-entity-data-grid>`) inside the entity-viewer's\n * pluggable view-type system. It is the dynamic-mounted plug-in that the `GridViewType` descriptor\n * points at.\n *\n * **Architectural intent — the container knows nothing about grids, and grid *features* never bubble\n * up.** The host (entity-viewer) binds only the generic {@link IViewRenderer} surface: the core\n * inputs (`entity` / `provider` / `records` / `selectedRecordId` / `filterText` / `config`), the\n * generic data-context inputs (`totalRecordCount` / `page` / `pageSize` / `isLoading`), and a small\n * set of generic outputs. There is **no opaque `hostAction` channel** — everything a grid does is\n * resolved through one of these three categories:\n *\n * 1. **Self-contained (owned end-to-end — never bubbles up):**\n * - **Export** → owned entirely by `<mj-entity-data-grid>` itself (its `onExportClick` opens its\n * OWN export dialog with format/sampling via `ExportService`). This wrapper does NOT host an\n * export dialog — doing so produced two stacked dialogs.\n * - **Add to List** → hosts `<mj-list-management-dialog>` ({@link ListManagementModule}). On\n * `(AddToListRequested)` the wrapper builds a {@link ListManagementDialogConfig} from the\n * entity + selected records and opens the dialog.\n * - **Delete** → hosts the Generic `<mj-ev-confirm-dialog>` (from {@link EntityViewerModule}).\n * On `(DeleteButtonClick)` the wrapper confirms, deletes via the MJ entity layer, then\n * re-requests data so the host reloads the current page.\n * - **Refresh** → on `(RefreshButtonClick)` the wrapper re-emits {@link dataRequest} so the host\n * reloads. No feature event leaves the wrapper.\n * - **Selection** → kept INTERNAL; it only drives the wrapper's own add-to-list. Never bubbles.\n *\n * 2. **Navigation (the ONLY legitimate upward signals — routing lives in the outer app):**\n * - Row double-click → {@link recordOpened}.\n * - Foreign-key cell click `(ForeignKeyClick)` → {@link openRelatedRecordRequested}.\n * - New button `(NewButtonClick)` → {@link createRecordRequested}.\n *\n * 3. **Container ↔ plug-in generic coordination (NOT outer-app signals):**\n * - Sort `(AfterSort)` → {@link dataRequest} (`sort`) + persisted into `config.gridState` via\n * {@link configChanged}.\n * - Pager `(PageChange)` → {@link dataRequest} (`page` / `pageSize`).\n * - Generic grid-state `(GridStateChanged)` → merged into `config.gridState` + {@link configChanged}.\n *\n * **Seeding the grid from `config` with defaults:** absent config fields fall back to sensible\n * defaults so a brand-new view (`config === {}`) renders a fully-functional grid — toolbar on,\n * checkbox selection, add-to-list on, pager on. The grid never loads its own data\n * (`[AllowLoad]=\"false\"`) — the host owns the fetch.\n *\n * This is an NgModule-declared (`standalone: false`) component, declared in `EntityViewerModule`.\n * It renders `<mj-entity-data-grid>` + the Generic `<mj-list-management-dialog>` / `<mj-ev-confirm-dialog>`\n * straight from the module's compilation scope (the module imports `ListManagementModule` and declares\n * the grid + confirm dialog; the grid component brings its own export dialog) — so there's\n * no `imports` array and, crucially, no self-import of `EntityViewerModule`: the module loads the\n * view-type descriptors, which reference these wrappers, so a wrapper importing the module back would\n * form a runtime import cycle (NG0919).\n *\n * Inputs use the camelCase names mandated by the {@link IViewRenderer} contract (the host binds them\n * by those exact names via `setInput`), rather than MJ's usual PascalCase for public members —\n * mirroring the Cards and Cluster renderers.\n */\n@Component({\n standalone: false,\n selector: 'mj-grid-view-renderer',\n encapsulation: ViewEncapsulation.None,\n template: `\n <mj-entity-data-grid\n #grid\n [Provider]=\"Provider\"\n [Data]=\"records\"\n [ExportDataProvider]=\"exportDataProvider\"\n [Params]=\"effectiveParams\"\n [FilterText]=\"filterText ?? ''\"\n [GridState]=\"config.gridState ?? null\"\n [Height]=\"'auto'\"\n [AllowLoad]=\"false\"\n [AutoLoadEntityActions]=\"AutoLoadEntityActions\"\n [ShowToolbar]=\"effectiveShowToolbar\"\n [ShowSearch]=\"effectiveShowSearch\"\n [ToolbarConfig]=\"config.toolbarConfig ?? {}\"\n [SelectionMode]=\"effectiveSelectionMode\"\n [ShowAddToListButton]=\"effectiveShowAddToListButton\"\n [ShowPager]=\"effectiveShowPager\"\n [PageSize]=\"effectivePageSize\"\n [TotalRowCount]=\"totalRecordCount ?? 0\"\n [PagerPageNumber]=\"page ?? 1\"\n (AfterRowClick)=\"onAfterRowClick($event)\"\n (AfterRowDoubleClick)=\"onAfterRowDoubleClick($event)\"\n (AfterSort)=\"onAfterSort($event)\"\n (GridStateChanged)=\"onGridStateChanged($event)\"\n (SelectionChange)=\"onSelectionChange($event)\"\n (NewButtonClick)=\"onNewButtonClick()\"\n (RefreshButtonClick)=\"onRefreshButtonClick()\"\n (DeleteButtonClick)=\"onDeleteButtonClick($event)\"\n (AddToListRequested)=\"onAddToListRequested($event)\"\n (ForeignKeyClick)=\"onForeignKeyClick($event)\"\n (PageChange)=\"onPageChange($event)\"\n (ManageColumnsRequested)=\"configureRequested.emit()\"\n >\n </mj-entity-data-grid>\n\n <!-- NOTE: Export is NOT handled here — mj-entity-data-grid hosts its OWN export dialog\n (its onExportClick opens it with formats/sampling via ExportService). Adding a second\n dialog here produced two stacked export dialogs. The grid owns export self-contained. -->\n\n <!-- Self-contained Add-to-List dialog (Generic) — owned by this wrapper, never bubbles up. -->\n @if (listManagementConfig) {\n <mj-list-management-dialog\n [Provider]=\"Provider\"\n [visible]=\"showListManagementDialog\"\n [config]=\"listManagementConfig\"\n (complete)=\"onListManagementComplete($event)\"\n (cancel)=\"onListManagementCancel()\"\n >\n </mj-list-management-dialog>\n }\n\n <!-- Self-contained Delete confirmation (Generic) — owned by this wrapper, never bubbles up. -->\n <mj-ev-confirm-dialog\n [IsOpen]=\"showDeleteConfirm\"\n Title=\"Delete Records\"\n [Message]=\"deleteConfirmMessage\"\n DetailMessage=\"This action cannot be undone.\"\n ConfirmText=\"Delete\"\n ConfirmStyle=\"danger\"\n Icon=\"fa-solid fa-trash\"\n (Confirmed)=\"onDeleteConfirmed()\"\n (Cancelled)=\"onDeleteCancelled()\"\n >\n </mj-ev-confirm-dialog>\n `,\n styles: [\n `\n :host {\n display: block;\n height: 100%;\n }\n `,\n ],\n})\nexport class GridViewRendererComponent extends BaseAngularComponent implements IViewRenderer<GridViewConfig> {\n /** Change detection ref used to flush dialog visibility toggles driven by grid events. */\n private cdr = inject(ChangeDetectorRef);\n\n // ---- IViewRenderer core inputs (camelCase per the host contract) ----\n\n /** The entity whose records are being rendered. Used to build default params + resolve selection. */\n @Input() entity: EntityInfo | null = null;\n\n /** The records to render (already loaded / filtered / paged by the host). Fed into `[Data]`. */\n @Input() records: Record<string, unknown>[] = [];\n\n /**\n * Optional full-result-set fetcher supplied by the host, forwarded to the grid's ExportDataProvider\n * so exports cover every matching row rather than just the loaded page (bug C1).\n */\n @Input() exportDataProvider: (() => Promise<Record<string, unknown>[]>) | null = null;\n\n /** Primary-key string of the currently selected record, if any. */\n @Input() selectedRecordId: string | null = null;\n\n /** Active filter text — passed through for the grid's cell highlighting. */\n @Input() filterText: string | null = null;\n\n /** Opaque per-view configuration. Seeds the grid bindings; mutated + re-emitted on grid changes. */\n @Input() config: GridViewConfig = {};\n\n /**\n * When true (default), the grid self-loads the entity's active EntityActions and shows them — buttons\n * appear only for entities that actually have actions (data-driven). Actions whose invocation names a\n * `RuntimeUXDriverClass` mount that interactive driver (e.g. the Record Process runner) in-place.\n */\n @Input() AutoLoadEntityActions = true;\n\n // ---- IViewRenderer generic data-context inputs ----\n\n /** Total record count across all pages, for the grid's pager. Fed into `[TotalRowCount]`. */\n @Input() totalRecordCount?: number;\n\n /** One-based current page the host is showing. Fed into `[PagerPageNumber]` (already 1-based). */\n @Input() page?: number;\n\n /** Page size the host is using — fallback when `config.pageSize` is absent. */\n @Input() pageSize?: number;\n\n /** Whether the host is currently (re)loading the record set. Accepted per contract; unused here. */\n @Input() isLoading?: boolean;\n\n // ---- IViewRenderer outputs (generic + navigation channels only) ----\n\n /** Emitted when a row is single-clicked — payload is the raw record object (host builds the key). */\n @Output() recordSelected = new EventEmitter<unknown>();\n\n /** Emitted when a row is double-clicked — payload is the raw record object (host builds the key). */\n @Output() recordOpened = new EventEmitter<unknown>();\n\n /** Emitted when this renderer mutates its opaque {@link config} (sort / grid-state persistence). */\n @Output() configChanged = new EventEmitter<GridViewConfig>();\n\n /** Generic data-access channel: ask the host to re-load with different sort / page. */\n @Output() dataRequest = new EventEmitter<ViewDataRequest>();\n\n /**\n * Ask the host to open this view's configuration UI. Raised when the grid emits\n * `ManageColumnsRequested` (its \"Manage Columns\" toolbar affordance). Part of the generic\n * {@link IViewRenderer} contract; the container forwards it to the workspace, which opens the\n * config panel (Columns tab) — the canonical column editor.\n */\n @Output() configureRequested = new EventEmitter<void>();\n\n /**\n * NAVIGATION: open a related record on a (possibly different) entity from a foreign-key cell click.\n * Routing lives in the outer app, so this is one of the few signals that legitimately bubbles up.\n */\n @Output() openRelatedRecordRequested = new EventEmitter<ViewRelatedRecordNavigation>();\n\n /** NAVIGATION: create a new record of the current entity (grid \"New\" button). Bubbles up for routing. */\n @Output() createRecordRequested = new EventEmitter<void>();\n\n /**\n * Reference to the hosted grid. Currently only retained for parity / future selection resolution;\n * selection is mapped from the {@link records} input rather than read from the grid, per contract.\n */\n @ViewChild('grid') protected grid?: EntityDataGridComponent;\n\n /**\n * IMPERATIVE export entry point ({@link IViewRenderer.exportRecords}). Lets the host trigger\n * an export programmatically (ultimately for the AI agent) by delegating to the hosted grid's\n * self-contained {@link EntityDataGridComponent.Export} (which downloads the file). The grid's\n * toolbar export button remains the interactive path; this is the no-UI equivalent.\n *\n * @param format optional output format; the grid defaults to 'excel' when omitted.\n * @returns true when the export succeeded, false when the grid isn't ready or the export failed.\n */\n async exportRecords(format?: 'csv' | 'excel' | 'json'): Promise<boolean> {\n if (!this.grid) {\n return false;\n }\n const result = await this.grid.Export(format ? { format } : undefined, true);\n return !!result?.success;\n }\n\n /** The hosted grid's on-screen columns ({@link IViewRenderer.GetExportColumns}); empty before it mounts. */\n GetExportColumns(): ExportColumn[] {\n return this.grid?.GetExportColumns() ?? [];\n }\n\n // ================================================================\n // Self-contained dialog state (never surfaced to the host)\n // ================================================================\n // NOTE: Export has no state here — mj-entity-data-grid owns its export dialog.\n\n /** Whether the add-to-list dialog is visible. Toggled internally by {@link onAddToListRequested}. */\n protected showListManagementDialog = false;\n\n /** Config fed into `<mj-list-management-dialog>`. Built from the entity + selected records. */\n protected listManagementConfig: ListManagementDialogConfig | null = null;\n\n /** Whether the delete-confirmation dialog is visible. Toggled internally by {@link onDeleteButtonClick}. */\n protected showDeleteConfirm = false;\n\n /** Records staged for deletion while the confirm dialog is open. */\n private pendingDeleteRecords: Record<string, unknown>[] = [];\n\n /** Dynamic message for the delete-confirmation dialog (reflects the staged record count). */\n protected deleteConfirmMessage = 'Are you sure you want to delete the selected records?';\n\n // ================================================================\n // Effective binding accessors — seed grid inputs from config + defaults\n // ================================================================\n\n /** Effective toolbar visibility — defaults to `true` when not set in config. */\n get effectiveShowToolbar(): boolean {\n return this.config.showToolbar ?? true;\n }\n\n /**\n * Grid search defaults OFF when hosted in entity-viewer. The container already owns\n * `filterText` (\"Filter records...\"). Opt in with `toolbarConfig.showSearch: true`.\n */\n get effectiveShowSearch(): boolean {\n return this.config.toolbarConfig?.showSearch ?? false;\n }\n\n /** Effective selection mode — defaults to `'checkbox'` when not set in config. */\n get effectiveSelectionMode(): GridSelectionMode {\n return this.config.selectionMode ?? 'checkbox';\n }\n\n /** Effective add-to-list button visibility — defaults to `true` when not set in config. */\n get effectiveShowAddToListButton(): boolean {\n return this.config.showAddToListButton ?? true;\n }\n\n /** Effective pager visibility — defaults to `true` when not set in config. */\n get effectiveShowPager(): boolean {\n return this.config.showPager ?? true;\n }\n\n /** Effective page size — config wins, else the generic `pageSize` input, else the grid's own default. */\n get effectivePageSize(): number {\n return this.config.pageSize ?? this.pageSize ?? 100;\n }\n\n /**\n * Effective RunViewParams for the grid. Uses `config.params` when supplied; otherwise builds a\n * minimal dynamic-view params object from {@link entity}. Returns `null` when no entity is known\n * yet (the grid renders empty until the host provides one).\n */\n get effectiveParams(): RunViewParams | null {\n if (this.config.params) {\n return this.config.params;\n }\n if (this.entity) {\n return { EntityName: this.entity.Name };\n }\n return null;\n }\n\n // ================================================================\n // Navigation + generic coordination output mapping\n // ================================================================\n\n /**\n * Row single-click → {@link recordSelected}. Extracts the raw record (`event.row`) so the host\n * builds the composite key itself, matching the other renderers.\n */\n onAfterRowClick(event: AfterRowClickEventArgs): void {\n if (event.row) {\n this.recordSelected.emit(event.row);\n }\n }\n\n /** Row double-click → {@link recordOpened} (NAVIGATION), emitting the raw record object. */\n onAfterRowDoubleClick(event: AfterRowDoubleClickEventArgs): void {\n if (event.row) {\n this.recordOpened.emit(event.row);\n }\n }\n\n /**\n * Sort change → both generic coordination channels:\n * 1. {@link dataRequest} with the generic `sort` shape so the host re-loads with a new OrderBy.\n * 2. persists the sort into `config.gridState.sortSettings` and emits {@link configChanged} so\n * the grid's sort survives view reloads via the opaque config channel.\n */\n onAfterSort(event: AfterSortEventArgs): void {\n const sort = (event.newSortState ?? []).map((s) => ({ field: s.field, direction: s.direction }));\n this.dataRequest.emit({ sort });\n\n const gridState: ViewGridState = { ...(this.config.gridState ?? {}) };\n gridState.sortSettings = (event.newSortState ?? []).map((s) => ({ field: s.field, dir: s.direction }));\n this.config = { ...this.config, gridState };\n this.configChanged.emit(this.config);\n }\n\n /**\n * Generic grid-state change (column resize / reorder / visibility) → merge the grid's updated\n * {@link ViewGridState} into the opaque config and emit {@link configChanged}; the host persists\n * the blob verbatim. No `dataRequest` here — column changes don't alter the loaded record set.\n */\n onGridStateChanged(event: GridStateChangedEvent): void {\n this.config = { ...this.config, gridState: event.gridState };\n this.configChanged.emit(this.config);\n }\n\n /**\n * Selection change → kept INTERNAL. The grid drives its own add-to-list from the selection, so the\n * wrapper has no need to surface it. We intentionally do not bubble selection anywhere.\n */\n onSelectionChange(_selectedKeys: string[]): void {\n // No-op: selection is internal to the grid + this wrapper's add-to-list. It never bubbles up.\n }\n\n /**\n * Foreign-key link click → {@link openRelatedRecordRequested} (NAVIGATION). Maps the grid's\n * {@link ForeignKeyClickEvent} (which carries the related entity + the FK value) onto the generic\n * {@link ViewRelatedRecordNavigation} the container forwards to the outer app for routing. The\n * related entity name is taken from the event when present, else resolved from the metadata by ID.\n */\n onForeignKeyClick(event: ForeignKeyClickEvent): void {\n const entityName = event.relatedEntityName ?? this.resolveEntityNameById(event.relatedEntityId);\n if (!entityName) {\n return;\n }\n this.openRelatedRecordRequested.emit({ entityName, recordKey: event.recordId });\n }\n\n /** New button → {@link createRecordRequested} (NAVIGATION) — opening the create form is routing. */\n onNewButtonClick(): void {\n this.createRecordRequested.emit();\n }\n\n /**\n * Pager navigation → generic {@link dataRequest}. Maps the grid's {@link PageChangeEvent}\n * (`PageNumber` is already 1-based, `PageSize`) onto the generic `{ page, pageSize }` shape the\n * host honors against its own RunView.\n */\n onPageChange(event: PageChangeEvent): void {\n this.dataRequest.emit({ page: event.PageNumber, pageSize: event.PageSize });\n }\n\n // ================================================================\n // Self-contained: Refresh\n // ================================================================\n\n /**\n * Refresh button → re-emit {@link dataRequest} so the host reloads the current page. This is\n * generic container ↔ plug-in coordination (a data-access request), NOT a feature event surfaced\n * to the outer app.\n */\n onRefreshButtonClick(): void {\n this.dataRequest.emit(this.currentPageDataRequest());\n }\n\n // ================================================================\n // Export: handled entirely by mj-entity-data-grid (its onExportClick opens its own export dialog\n // via ExportService). This wrapper intentionally does NOT host an export dialog — doing so produced\n // two stacked dialogs. Nothing to do here.\n // ================================================================\n\n // ================================================================\n // Self-contained: Add to List (hosts <mj-list-management-dialog>)\n // ================================================================\n\n /**\n * Add-to-list button → build a {@link ListManagementDialogConfig} from the entity + the records the\n * grid supplied, then open the Generic list-management dialog. The dialog persists membership\n * changes itself — nothing bubbles up. Mirrors the config construction the legacy host did in\n * `data-explorer-dashboard`'s `onAddToListRequested()`.\n */\n onAddToListRequested(event: { entityInfo: EntityInfo; records: Record<string, unknown>[]; recordIds: string[] }): void {\n const entity = event.entityInfo ?? this.entity;\n if (!entity || !event.records || event.records.length === 0) {\n return;\n }\n\n const recordDisplayNames = event.records.map((record) => this.getRecordDisplayName(record, entity));\n const recordIds = this.buildRawRecordIds(event.records, entity);\n if (recordIds.length === 0) {\n return;\n }\n\n const recordCount = event.records.length;\n const dialogTitle = recordCount === 1 ? `Manage Lists for \"${recordDisplayNames[0]}\"` : `Add ${recordCount} Records to List`;\n\n this.listManagementConfig = {\n mode: 'manage',\n entityId: entity.ID,\n entityName: entity.Name,\n recordIds,\n recordDisplayNames,\n allowCreate: true,\n allowRemove: recordCount === 1,\n showMembership: recordCount === 1,\n dialogTitle,\n };\n this.showListManagementDialog = true;\n this.cdr.detectChanges();\n }\n\n /** List-management dialog completed (membership changes applied) → tear down state. */\n onListManagementComplete(_result: ListManagementResult): void {\n this.showListManagementDialog = false;\n this.listManagementConfig = null;\n this.cdr.detectChanges();\n }\n\n /** List-management dialog cancelled → tear down state. */\n onListManagementCancel(): void {\n this.showListManagementDialog = false;\n this.listManagementConfig = null;\n this.cdr.detectChanges();\n }\n\n /**\n * Resolve a human-friendly display name for a record using the entity's NameField, falling back to\n * the composite-key string. Mirrors the legacy host's display-name resolution.\n */\n private getRecordDisplayName(record: Record<string, unknown>, entity: EntityInfo): string {\n if (entity.NameField) {\n const nameValue = record[entity.NameField.Name];\n if (nameValue != null) {\n return String(nameValue);\n }\n }\n return buildPkString(record, entity) || 'Unknown';\n }\n\n /**\n * Build the record-id strings used by list membership matching, in the compact form `MJ: List Details`\n * stores in `RecordID`: the bare value for a single-column primary key (whatever the column is called),\n * or the full `Field1|Value1||Field2|Value2` segment for a composite key. The entity is arbitrary, so the\n * key is built from all of its primary-key columns rather than assuming a single `ID`.\n */\n private buildRawRecordIds(records: Record<string, unknown>[], entity: EntityInfo): string[] {\n if (entity.PrimaryKeys.length === 0) {\n return [];\n }\n return records\n .map((record) => CompositeKey.FromEntityRecord(entity, record).ToCompactURLSegment())\n .filter((id) => id !== '');\n }\n\n // ================================================================\n // Self-contained: Delete (hosts <mj-ev-confirm-dialog> + MJ entity layer)\n // ================================================================\n\n /**\n * Delete button → stage the records and open the Generic confirm dialog. The actual delete happens\n * in {@link onDeleteConfirmed} after the user confirms — nothing bubbles up.\n */\n onDeleteButtonClick(records: Record<string, unknown>[]): void {\n if (!records || records.length === 0) {\n return;\n }\n this.pendingDeleteRecords = records;\n const count = records.length;\n this.deleteConfirmMessage = count === 1 ? 'Are you sure you want to delete this record?' : `Are you sure you want to delete these ${count} records?`;\n this.showDeleteConfirm = true;\n this.cdr.detectChanges();\n }\n\n /**\n * Delete confirmed → delete each staged record through the MJ entity layer\n * (`ProviderToUse.GetEntityObject(name, compositeKey, user)` → `Delete`), checking the boolean\n * result and surfacing failures via {@link LogError}. After deletion, re-request the current page\n * so the host reloads. Self-contained — no feature event leaves the wrapper.\n */\n async onDeleteConfirmed(): Promise<void> {\n this.showDeleteConfirm = false;\n const entity = this.entity;\n const records = this.pendingDeleteRecords;\n this.pendingDeleteRecords = [];\n\n if (!entity || records.length === 0) {\n return;\n }\n\n let anyDeleted = false;\n const provider = this.ProviderToUse;\n const user = provider.CurrentUser;\n\n for (const record of records) {\n const key = buildCompositeKey(record, entity);\n try {\n // The (name, key, user) overload instantiates AND loads in one call (throws if it can't load).\n const obj = await provider.GetEntityObject(entity.Name, key, user);\n const deleted = await obj.Delete();\n if (deleted) {\n anyDeleted = true;\n } else {\n LogError(`Delete failed: ${obj.LatestResult?.CompleteMessage ?? 'unknown error'}`);\n }\n } catch (err) {\n LogError(`Delete failed for ${entity.Name} (${key.ToString()}): ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n if (anyDeleted) {\n // Re-request the current page so the host reloads the (now smaller) record set.\n this.dataRequest.emit(this.currentPageDataRequest());\n }\n this.cdr.detectChanges();\n }\n\n /** Delete cancelled → discard the staged records and close the confirm dialog. */\n onDeleteCancelled(): void {\n this.showDeleteConfirm = false;\n this.pendingDeleteRecords = [];\n this.cdr.detectChanges();\n }\n\n // ================================================================\n // Helpers\n // ================================================================\n\n /** Build a {@link ViewDataRequest} that re-requests the host's current page/pageSize, if known. */\n private currentPageDataRequest(): ViewDataRequest {\n const req: ViewDataRequest = {};\n if (this.page != null) {\n req.page = this.page;\n }\n const ps = this.config.pageSize ?? this.pageSize;\n if (ps != null) {\n req.pageSize = ps;\n }\n return req;\n }\n\n /**\n * Resolve an entity's name from its ID via the active provider's metadata. Used when a foreign-key\n * click event omits the related entity name and only carries its ID.\n */\n private resolveEntityNameById(entityId: string): string | null {\n if (!entityId) {\n return null;\n }\n const match = this.ProviderToUse.Entities.find((e) => UUIDsEqual(e.ID, entityId));\n return match ? match.Name : null;\n }\n}\n\n/**\n * Tree-shaking guard. Force-references this renderer so bundlers (ESBuild/Vite) don't drop the\n * component in builds that only mount it dynamically via the ClassFactory/descriptor. Mirrors the\n * Cards/Cluster renderers' load guards; the parent wires this into a barrel/module load path.\n */\nexport function LoadGridViewRenderer(): void {\n // no-op; presence prevents tree-shaking of this component\n}\n"]}
|
|
1
|
+
{"version":3,"file":"grid-view-renderer.component.js","sourceRoot":"","sources":["../../../../src/lib/view-types/renderers/grid-view-renderer.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, ViewEncapsulation, ViewChild, ChangeDetectorRef, OnDestroy, inject } from '@angular/core';\nimport { EntityInfo, RunViewParams, LogError, CompositeKey, RunView, RecordMergeRequest } from '@memberjunction/core';\nimport { ExportColumn } from '@memberjunction/export-engine';\nimport {\n RecordComparisonService,\n type FieldComparison,\n type MergeConfig,\n type MergeConfirmedEvent,\n} from '@memberjunction/ng-record-merge';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { PageChangeEvent } from '@memberjunction/ng-pagination';\nimport { ListManagementDialogConfig, ListManagementResult } from '@memberjunction/ng-list-management';\nimport { IViewRenderer, ViewDataRequest, ViewRelatedRecordNavigation } from '../view-type.contracts';\nimport { ViewGridState } from '../../types';\nimport { GridSelectionMode, GridToolbarConfig, ForeignKeyClickEvent } from '../../entity-data-grid/models/grid-types';\nimport { AfterRowClickEventArgs, AfterRowDoubleClickEventArgs, AfterSortEventArgs } from '../../entity-data-grid/events/grid-events';\nimport { GridStateChangedEvent } from '../../types';\nimport { BuildPkString, BuildCompositeKey } from '../../utils/record.util';\nimport { EntityDataGridComponent } from '../../entity-data-grid/entity-data-grid.component';\n\n/**\n * Opaque per-view configuration for the Grid view type.\n * -----------------------------------------------------\n * This is the blob the host persists verbatim against the active `ViewTypeID` and never\n * inspects (see {@link IViewRenderer.configChanged}). The renderer seeds the\n * `<mj-entity-data-grid>` bindings from these fields, applying sensible defaults when a\n * field is absent (see {@link GridViewRendererComponent}). It is intentionally a plain,\n * fully-serializable shape — every field is optional so an empty `{}` is a valid config.\n */\nexport interface GridViewConfig {\n /**\n * Persisted grid state (columns/widths/order/sort) from a User View. Mutated in place when\n * the grid emits sort or generic grid-state changes, then surfaced via `configChanged` so the\n * host persists it. Fed straight into `[GridState]`.\n */\n gridState?: ViewGridState;\n /** Whether the grid's own toolbar is shown. Defaults to `true` when absent. */\n showToolbar?: boolean;\n /** The grid toolbar configuration. Fed into `[ToolbarConfig]`. */\n toolbarConfig?: GridToolbarConfig;\n /** Row selection mode. Defaults to `'checkbox'` when absent. */\n selectionMode?: GridSelectionMode;\n /** Whether the \"Add to List\" button is shown. Defaults to `true` when absent. */\n showAddToListButton?: boolean;\n /** Whether the pager is shown. Defaults to `true` when absent. */\n showPager?: boolean;\n /** Page size for the grid's pager. Falls back to the `pageSize` input when absent. */\n pageSize?: number;\n /**\n * Explicit RunViewParams for the grid's data source. When absent the renderer builds a minimal\n * dynamic-view params object from {@link entity}. Fed into `[Params]`.\n */\n params?: RunViewParams;\n}\n\n/**\n * GridViewRendererComponent\n * -------------------------\n * The Grid **view type** renderer — a fully self-contained {@link IViewRenderer} adapter that hosts\n * the existing {@link EntityDataGridComponent} (`<mj-entity-data-grid>`) inside the entity-viewer's\n * pluggable view-type system. It is the dynamic-mounted plug-in that the `GridViewType` descriptor\n * points at.\n *\n * **Architectural intent — the container knows nothing about grids, and grid *features* never bubble\n * up.** The host (entity-viewer) binds only the generic {@link IViewRenderer} surface: the core\n * inputs (`entity` / `provider` / `records` / `selectedRecordId` / `filterText` / `config`), the\n * generic data-context inputs (`totalRecordCount` / `page` / `pageSize` / `isLoading`), and a small\n * set of generic outputs. There is **no opaque `hostAction` channel** — everything a grid does is\n * resolved through one of these three categories:\n *\n * 1. **Self-contained (owned end-to-end — never bubbles up):**\n * - **Export** → owned entirely by `<mj-entity-data-grid>` itself (its `onExportClick` opens its\n * OWN export dialog with format/sampling via `ExportService`). This wrapper does NOT host an\n * export dialog — doing so produced two stacked dialogs.\n * - **Add to List** → hosts `<mj-list-management-dialog>` ({@link ListManagementModule}). On\n * `(AddToListRequested)` the wrapper builds a {@link ListManagementDialogConfig} from the\n * entity + selected records and opens the dialog.\n * - **Delete** → hosts the Generic `<mj-ev-confirm-dialog>` (from {@link EntityViewerModule}).\n * On `(DeleteButtonClick)` the wrapper confirms, deletes via the MJ entity layer, then\n * re-requests data so the host reloads the current page.\n * - **Refresh** → on `(RefreshButtonClick)` the wrapper re-emits {@link dataRequest} so the host\n * reloads. No feature event leaves the wrapper.\n * - **Selection** → kept INTERNAL; it only drives the wrapper's own add-to-list. Never bubbles.\n *\n * 2. **Navigation (the ONLY legitimate upward signals — routing lives in the outer app):**\n * - Row double-click → {@link recordOpened}.\n * - Foreign-key cell click `(ForeignKeyClick)` → {@link openRelatedRecordRequested}.\n * - New button `(NewButtonClick)` → {@link createRecordRequested}.\n *\n * 3. **Container ↔ plug-in generic coordination (NOT outer-app signals):**\n * - Sort `(AfterSort)` → {@link dataRequest} (`sort`) + persisted into `config.gridState` via\n * {@link configChanged}.\n * - Pager `(PageChange)` → {@link dataRequest} (`page` / `pageSize`).\n * - Generic grid-state `(GridStateChanged)` → merged into `config.gridState` + {@link configChanged}.\n *\n * **Seeding the grid from `config` with defaults:** absent config fields fall back to sensible\n * defaults so a brand-new view (`config === {}`) renders a fully-functional grid — toolbar on,\n * checkbox selection, add-to-list on, pager on. The grid never loads its own data\n * (`[AllowLoad]=\"false\"`) — the host owns the fetch.\n *\n * This is an NgModule-declared (`standalone: false`) component, declared in `EntityViewerModule`.\n * It renders `<mj-entity-data-grid>` + the Generic `<mj-list-management-dialog>` / `<mj-ev-confirm-dialog>`\n * straight from the module's compilation scope (the module imports `ListManagementModule` and declares\n * the grid + confirm dialog; the grid component brings its own export dialog) — so there's\n * no `imports` array and, crucially, no self-import of `EntityViewerModule`: the module loads the\n * view-type descriptors, which reference these wrappers, so a wrapper importing the module back would\n * form a runtime import cycle (NG0919).\n *\n * Inputs use the camelCase names mandated by the {@link IViewRenderer} contract (the host binds them\n * by those exact names via `setInput`), rather than MJ's usual PascalCase for public members —\n * mirroring the Cards and Cluster renderers.\n */\n@Component({\n standalone: false,\n selector: 'mj-grid-view-renderer',\n encapsulation: ViewEncapsulation.None,\n template: `\n <mj-entity-data-grid\n #grid\n [Provider]=\"Provider\"\n [Data]=\"records\"\n [ExportDataProvider]=\"exportDataProvider\"\n [Params]=\"effectiveParams\"\n [FilterText]=\"filterText ?? ''\"\n [GridState]=\"config.gridState ?? null\"\n [Height]=\"'auto'\"\n [AllowLoad]=\"false\"\n [AutoLoadEntityActions]=\"AutoLoadEntityActions\"\n [ShowToolbar]=\"effectiveShowToolbar\"\n [ShowSearch]=\"effectiveShowSearch\"\n [ToolbarConfig]=\"config.toolbarConfig ?? {}\"\n [SelectionMode]=\"effectiveSelectionMode\"\n [ShowAddToListButton]=\"effectiveShowAddToListButton\"\n [ShowPager]=\"effectiveShowPager\"\n [PageSize]=\"effectivePageSize\"\n [TotalRowCount]=\"totalRecordCount ?? 0\"\n [PagerPageNumber]=\"page ?? 1\"\n (AfterRowClick)=\"onAfterRowClick($event)\"\n (AfterRowDoubleClick)=\"onAfterRowDoubleClick($event)\"\n (AfterSort)=\"onAfterSort($event)\"\n (GridStateChanged)=\"onGridStateChanged($event)\"\n (SelectionChange)=\"onSelectionChange($event)\"\n (NewButtonClick)=\"onNewButtonClick()\"\n (RefreshButtonClick)=\"onRefreshButtonClick()\"\n (DeleteButtonClick)=\"onDeleteButtonClick($event)\"\n (AddToListRequested)=\"onAddToListRequested($event)\"\n (ForeignKeyClick)=\"onForeignKeyClick($event)\"\n (PageChange)=\"onPageChange($event)\"\n (ManageColumnsRequested)=\"configureRequested.emit()\"\n [ShowMergeButton]=\"effectiveShowMergeButton\"\n (MergeRecordsRequested)=\"onMergeRequested($event)\"\n >\n </mj-entity-data-grid>\n\n <!-- NOTE: Export is NOT handled here — mj-entity-data-grid hosts its OWN export dialog\n (its onExportClick opens it with formats/sampling via ExportService). Adding a second\n dialog here produced two stacked export dialogs. The grid owns export self-contained. -->\n\n <!-- Self-contained Add-to-List dialog (Generic) — owned by this wrapper, never bubbles up. -->\n @if (listManagementConfig) {\n <mj-list-management-dialog\n [Provider]=\"Provider\"\n [visible]=\"showListManagementDialog\"\n [config]=\"listManagementConfig\"\n (complete)=\"onListManagementComplete($event)\"\n (cancel)=\"onListManagementCancel()\"\n >\n </mj-list-management-dialog>\n }\n\n <!-- Self-contained Delete confirmation (Generic) — owned by this wrapper, never bubbles up. -->\n <mj-ev-confirm-dialog\n [IsOpen]=\"showDeleteConfirm\"\n Title=\"Delete Records\"\n [Message]=\"deleteConfirmMessage\"\n DetailMessage=\"This action cannot be undone.\"\n ConfirmText=\"Delete\"\n ConfirmStyle=\"danger\"\n Icon=\"fa-solid fa-trash\"\n (Confirmed)=\"onDeleteConfirmed()\"\n (Cancelled)=\"onDeleteCancelled()\"\n >\n </mj-ev-confirm-dialog>\n\n <!-- Self-contained merge panel (Generic) — owned by this wrapper, never bubbles up.\n Lives inside the @if so the panel rebuilds its comparison (ngOnInit) per request. -->\n @if (mergeState) {\n <mj-dialog [Visible]=\"true\" Size=\"lg\" [Closeable]=\"!mergeState.IsMerging\" (Close)=\"onMergeCancelled()\">\n <div class=\"mj-ev-merge-survivor\" role=\"radiogroup\" aria-label=\"Record to keep\">\n <span>Keep</span>\n <button type=\"button\" mjButton size=\"sm\" role=\"radio\"\n [variant]=\"mergeState.Config.SurvivorSide === 'left' ? 'primary' : 'secondary'\"\n [attr.aria-checked]=\"mergeState.Config.SurvivorSide === 'left'\"\n [disabled]=\"mergeState.IsMerging\"\n (click)=\"onSurvivorChange('left')\">{{ mergeState.Config.LeftLabel }}</button>\n <button type=\"button\" mjButton size=\"sm\" role=\"radio\"\n [variant]=\"mergeState.Config.SurvivorSide === 'right' ? 'primary' : 'secondary'\"\n [attr.aria-checked]=\"mergeState.Config.SurvivorSide === 'right'\"\n [disabled]=\"mergeState.IsMerging\"\n (click)=\"onSurvivorChange('right')\">{{ mergeState.Config.RightLabel }}</button>\n <span class=\"mj-ev-merge-survivor-note\">{{ mergeLoserLabel }} will be deleted; its linked records move to the record you keep.</span>\n </div>\n <mj-record-merge-panel\n [Fields]=\"mergeState.Fields\"\n [Config]=\"mergeState.Config\"\n [MergeEnabled]=\"!mergeState.IsMerging\"\n [IsMerging]=\"mergeState.IsMerging\"\n (MergeConfirmed)=\"onMergeConfirmed($event)\"\n (MergeCancelled)=\"onMergeCancelled()\"\n >\n </mj-record-merge-panel>\n @if (mergeState.DependencyNote) {\n <p class=\"mj-ev-merge-deps\">{{ mergeState.DependencyNote }}</p>\n }\n </mj-dialog>\n }\n @if (mergeNotice) {\n <div class=\"mj-ev-merge-notice\" role=\"status\">\n <span class=\"mj-ev-merge-notice-text\">{{ mergeNotice }}</span>\n <button type=\"button\" class=\"mj-ev-merge-notice-dismiss\" (click)=\"onDismissMergeNotice()\" title=\"Dismiss\" aria-label=\"Dismiss\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n `,\n styles: [\n `\n :host {\n display: block;\n height: 100%;\n }\n\n .mj-ev-merge-survivor {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n }\n\n .mj-ev-merge-survivor-note {\n color: var(--mj-text-muted);\n }\n\n .mj-ev-merge-deps {\n margin: 0;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n }\n\n .mj-ev-merge-notice {\n position: fixed;\n bottom: 16px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 1001;\n padding: 8px 14px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-elevated);\n color: var(--mj-text-primary);\n font-size: var(--mj-text-sm);\n box-shadow: var(--mj-shadow-md);\n display: flex;\n align-items: center;\n gap: 10px;\n }\n\n .mj-ev-merge-notice-dismiss {\n flex-shrink: 0;\n background: none;\n border: none;\n padding: 0 2px;\n cursor: pointer;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n line-height: 1;\n }\n\n .mj-ev-merge-notice-dismiss:hover {\n color: var(--mj-text-primary);\n }\n `,\n ],\n})\nexport class GridViewRendererComponent extends BaseAngularComponent implements IViewRenderer<GridViewConfig>, OnDestroy {\n /** Change detection ref used to flush dialog visibility toggles driven by grid events. */\n private cdr = inject(ChangeDetectorRef);\n\n // ---- IViewRenderer core inputs (camelCase per the host contract) ----\n\n /** The entity whose records are being rendered. Used to build default params + resolve selection. */\n @Input() entity: EntityInfo | null = null;\n\n /** The records to render (already loaded / filtered / paged by the host). Fed into `[Data]`. */\n @Input() records: Record<string, unknown>[] = [];\n\n /**\n * Optional full-result-set fetcher supplied by the host, forwarded to the grid's ExportDataProvider\n * so exports cover every matching row rather than just the loaded page (bug C1).\n */\n @Input() ExportDataProvider: (() => Promise<Record<string, unknown>[]>) | null = null;\n\n /** @deprecated Use {@link ExportDataProvider}. */\n @Input() set exportDataProvider(value: (() => Promise<Record<string, unknown>[]>) | null) {\n this.ExportDataProvider = value;\n }\n /** @deprecated Use {@link ExportDataProvider}. */\n get exportDataProvider(): (() => Promise<Record<string, unknown>[]>) | null {\n return this.ExportDataProvider;\n }\n\n /** Primary-key string of the currently selected record, if any. */\n @Input() selectedRecordId: string | null = null;\n\n /** Active filter text — passed through for the grid's cell highlighting. */\n @Input() filterText: string | null = null;\n\n /** Opaque per-view configuration. Seeds the grid bindings; mutated + re-emitted on grid changes. */\n @Input() config: GridViewConfig = {};\n\n /**\n * When true (default), the grid self-loads the entity's active EntityActions and shows them — buttons\n * appear only for entities that actually have actions (data-driven). Actions whose invocation names a\n * `RuntimeUXDriverClass` mount that interactive driver (e.g. the Record Process runner) in-place.\n */\n @Input() AutoLoadEntityActions = true;\n\n // ---- IViewRenderer generic data-context inputs ----\n\n /** Total record count across all pages, for the grid's pager. Fed into `[TotalRowCount]`. */\n @Input() totalRecordCount?: number;\n\n /** One-based current page the host is showing. Fed into `[PagerPageNumber]` (already 1-based). */\n @Input() page?: number;\n\n /** Page size the host is using — fallback when `config.pageSize` is absent. */\n @Input() pageSize?: number;\n\n /** Whether the host is currently (re)loading the record set. Accepted per contract; unused here. */\n @Input() isLoading?: boolean;\n\n // ---- IViewRenderer outputs (generic + navigation channels only) ----\n\n /** Emitted when a row is single-clicked — payload is the raw record object (host builds the key). */\n @Output() recordSelected = new EventEmitter<unknown>();\n\n /** Emitted when a row is double-clicked — payload is the raw record object (host builds the key). */\n @Output() recordOpened = new EventEmitter<unknown>();\n\n /** Emitted when this renderer mutates its opaque {@link config} (sort / grid-state persistence). */\n @Output() configChanged = new EventEmitter<GridViewConfig>();\n\n /** Generic data-access channel: ask the host to re-load with different sort / page. */\n @Output() dataRequest = new EventEmitter<ViewDataRequest>();\n\n /**\n * Ask the host to open this view's configuration UI. Raised when the grid emits\n * `ManageColumnsRequested` (its \"Manage Columns\" toolbar affordance). Part of the generic\n * {@link IViewRenderer} contract; the container forwards it to the workspace, which opens the\n * config panel (Columns tab) — the canonical column editor.\n */\n @Output() configureRequested = new EventEmitter<void>();\n\n /**\n * NAVIGATION: open a related record on a (possibly different) entity from a foreign-key cell click.\n * Routing lives in the outer app, so this is one of the few signals that legitimately bubbles up.\n */\n @Output() openRelatedRecordRequested = new EventEmitter<ViewRelatedRecordNavigation>();\n\n /** NAVIGATION: create a new record of the current entity (grid \"New\" button). Bubbles up for routing. */\n @Output() createRecordRequested = new EventEmitter<void>();\n\n /**\n * Reference to the hosted grid. Currently only retained for parity / future selection resolution;\n * selection is mapped from the {@link records} input rather than read from the grid, per contract.\n */\n @ViewChild('grid') protected grid?: EntityDataGridComponent;\n\n /**\n * IMPERATIVE export entry point ({@link IViewRenderer.exportRecords}). Lets the host trigger\n * an export programmatically (ultimately for the AI agent) by delegating to the hosted grid's\n * self-contained {@link EntityDataGridComponent.Export} (which downloads the file). The grid's\n * toolbar export button remains the interactive path; this is the no-UI equivalent.\n *\n * @param format optional output format; the grid defaults to 'excel' when omitted.\n * @returns true when the export succeeded, false when the grid isn't ready or the export failed.\n */\n async exportRecords(format?: 'csv' | 'excel' | 'json'): Promise<boolean> {\n if (!this.grid) {\n return false;\n }\n const result = await this.grid.Export(format ? { format } : undefined, true);\n return !!result?.success;\n }\n\n /** The hosted grid's on-screen columns ({@link IViewRenderer.GetExportColumns}); empty before it mounts. */\n GetExportColumns(): ExportColumn[] {\n return this.grid?.GetExportColumns() ?? [];\n }\n\n // ================================================================\n // Self-contained dialog state (never surfaced to the host)\n // ================================================================\n // NOTE: Export has no state here — mj-entity-data-grid owns its export dialog.\n\n /** Whether the add-to-list dialog is visible. Toggled internally by {@link onAddToListRequested}. */\n protected showListManagementDialog = false;\n\n /** Config fed into `<mj-list-management-dialog>`. Built from the entity + selected records. */\n protected listManagementConfig: ListManagementDialogConfig | null = null;\n\n /** Whether the delete-confirmation dialog is visible. Toggled internally by {@link onDeleteButtonClick}. */\n protected showDeleteConfirm = false;\n\n /** Records staged for deletion while the confirm dialog is open. */\n private pendingDeleteRecords: Record<string, unknown>[] = [];\n\n /** Dynamic message for the delete-confirmation dialog (reflects the staged record count). */\n protected deleteConfirmMessage = 'Are you sure you want to delete the selected records?';\n\n // ================================================================\n // Effective binding accessors — seed grid inputs from config + defaults\n // ================================================================\n\n /** Effective toolbar visibility — defaults to `true` when not set in config. */\n get EffectiveShowToolbar(): boolean {\n return this.config.showToolbar ?? true;\n }\n\n /** @deprecated Use {@link EffectiveShowToolbar}. */\n get effectiveShowToolbar(): boolean {\n return this.EffectiveShowToolbar;\n }\n\n /**\n * Grid search defaults OFF when hosted in entity-viewer. The container already owns\n * `filterText` (\"Filter records...\"). Opt in with `toolbarConfig.showSearch: true`.\n */\n get EffectiveShowSearch(): boolean {\n return this.config.toolbarConfig?.showSearch ?? false;\n }\n\n /** @deprecated Use {@link EffectiveShowSearch}. */\n get effectiveShowSearch(): boolean {\n return this.EffectiveShowSearch;\n }\n\n /** Effective selection mode — defaults to `'checkbox'` when not set in config. */\n get EffectiveSelectionMode(): GridSelectionMode {\n return this.config.selectionMode ?? 'checkbox';\n }\n\n /** @deprecated Use {@link EffectiveSelectionMode}. */\n get effectiveSelectionMode(): GridSelectionMode {\n return this.EffectiveSelectionMode;\n }\n\n /** Effective add-to-list button visibility — defaults to `true` when not set in config. */\n get EffectiveShowAddToListButton(): boolean {\n return this.config.showAddToListButton ?? true;\n }\n\n /** @deprecated Use {@link EffectiveShowAddToListButton}. */\n get effectiveShowAddToListButton(): boolean {\n return this.EffectiveShowAddToListButton;\n }\n\n /** Effective pager visibility — defaults to `true` when not set in config. */\n get EffectiveShowPager(): boolean {\n return this.config.showPager ?? true;\n }\n\n /** @deprecated Use {@link EffectiveShowPager}. */\n get effectiveShowPager(): boolean {\n return this.EffectiveShowPager;\n }\n\n /** Effective page size — config wins, else the generic `pageSize` input, else the grid's own default. */\n get EffectivePageSize(): number {\n return this.config.pageSize ?? this.pageSize ?? 100;\n }\n\n /** @deprecated Use {@link EffectivePageSize}. */\n get effectivePageSize(): number {\n return this.EffectivePageSize;\n }\n\n /**\n * Effective RunViewParams for the grid. Uses `config.params` when supplied; otherwise builds a\n * minimal dynamic-view params object from {@link entity}. Returns `null` when no entity is known\n * yet (the grid renders empty until the host provides one).\n */\n get EffectiveParams(): RunViewParams | null {\n if (this.config.params) {\n return this.config.params;\n }\n if (this.entity) {\n return { EntityName: this.entity.Name };\n }\n return null;\n }\n\n /** @deprecated Use {@link EffectiveParams}. */\n get effectiveParams(): RunViewParams | null {\n return this.EffectiveParams;\n }\n\n // ================================================================\n // Navigation + generic coordination output mapping\n // ================================================================\n\n /**\n * Row single-click → {@link recordSelected}. Extracts the raw record (`event.row`) so the host\n * builds the composite key itself, matching the other renderers.\n */\n OnAfterRowClick(event: AfterRowClickEventArgs): void {\n if (event.row) {\n this.recordSelected.emit(event.row);\n }\n }\n\n /** @deprecated Use {@link OnAfterRowClick}. */\n onAfterRowClick(event: AfterRowClickEventArgs): void {\n return this.OnAfterRowClick(event);\n }\n\n /** Row double-click → {@link recordOpened} (NAVIGATION), emitting the raw record object. */\n OnAfterRowDoubleClick(event: AfterRowDoubleClickEventArgs): void {\n if (event.row) {\n this.recordOpened.emit(event.row);\n }\n }\n\n /** @deprecated Use {@link OnAfterRowDoubleClick}. */\n onAfterRowDoubleClick(event: AfterRowDoubleClickEventArgs): void {\n return this.OnAfterRowDoubleClick(event);\n }\n\n /**\n * Sort change → both generic coordination channels:\n * 1. {@link dataRequest} with the generic `sort` shape so the host re-loads with a new OrderBy.\n * 2. persists the sort into `config.gridState.sortSettings` and emits {@link configChanged} so\n * the grid's sort survives view reloads via the opaque config channel.\n */\n OnAfterSort(event: AfterSortEventArgs): void {\n const sort = (event.newSortState ?? []).map((s) => ({ field: s.field, direction: s.direction }));\n this.dataRequest.emit({ sort });\n\n const gridState: ViewGridState = { ...(this.config.gridState ?? {}) };\n gridState.sortSettings = (event.newSortState ?? []).map((s) => ({ field: s.field, dir: s.direction }));\n this.config = { ...this.config, gridState };\n this.configChanged.emit(this.config);\n }\n\n /** @deprecated Use {@link OnAfterSort}. */\n onAfterSort(event: AfterSortEventArgs): void {\n return this.OnAfterSort(event);\n }\n\n /**\n * Generic grid-state change (column resize / reorder / visibility) → merge the grid's updated\n * {@link ViewGridState} into the opaque config and emit {@link configChanged}; the host persists\n * the blob verbatim. No `dataRequest` here — column changes don't alter the loaded record set.\n */\n OnGridStateChanged(event: GridStateChangedEvent): void {\n this.config = { ...this.config, gridState: event.gridState };\n this.configChanged.emit(this.config);\n }\n\n /** @deprecated Use {@link OnGridStateChanged}. */\n onGridStateChanged(event: GridStateChangedEvent): void {\n return this.OnGridStateChanged(event);\n }\n\n /**\n * Selection change → kept INTERNAL. The grid drives its own add-to-list from the selection, so the\n * wrapper has no need to surface it. We intentionally do not bubble selection anywhere.\n */\n OnSelectionChange(_selectedKeys: string[]): void {\n // No-op: selection is internal to the grid + this wrapper's add-to-list. It never bubbles up.\n }\n\n /** @deprecated Use {@link OnSelectionChange}. */\n onSelectionChange(_selectedKeys: string[]): void {\n return this.OnSelectionChange(_selectedKeys);\n }\n\n /**\n * Foreign-key link click → {@link openRelatedRecordRequested} (NAVIGATION). Maps the grid's\n * {@link ForeignKeyClickEvent} (which carries the related entity + the FK value) onto the generic\n * {@link ViewRelatedRecordNavigation} the container forwards to the outer app for routing. The\n * related entity name is taken from the event when present, else resolved from the metadata by ID.\n */\n OnForeignKeyClick(event: ForeignKeyClickEvent): void {\n const entityName = event.relatedEntityName ?? this.resolveEntityNameById(event.relatedEntityId);\n if (!entityName) {\n return;\n }\n this.openRelatedRecordRequested.emit({ entityName, recordKey: event.recordId });\n }\n\n /** @deprecated Use {@link OnForeignKeyClick}. */\n onForeignKeyClick(event: ForeignKeyClickEvent): void {\n return this.OnForeignKeyClick(event);\n }\n\n /** New button → {@link createRecordRequested} (NAVIGATION) — opening the create form is routing. */\n OnNewButtonClick(): void {\n this.createRecordRequested.emit();\n }\n\n /** @deprecated Use {@link OnNewButtonClick}. */\n onNewButtonClick(): void {\n return this.OnNewButtonClick();\n }\n\n /**\n * Pager navigation → generic {@link dataRequest}. Maps the grid's {@link PageChangeEvent}\n * (`PageNumber` is already 1-based, `PageSize`) onto the generic `{ page, pageSize }` shape the\n * host honors against its own RunView.\n */\n OnPageChange(event: PageChangeEvent): void {\n this.dataRequest.emit({ page: event.PageNumber, pageSize: event.PageSize });\n }\n\n /** @deprecated Use {@link OnPageChange}. */\n onPageChange(event: PageChangeEvent): void {\n return this.OnPageChange(event);\n }\n\n // ================================================================\n // Self-contained: Refresh\n // ================================================================\n\n /**\n * Refresh button → re-emit {@link dataRequest} so the host reloads the current page. This is\n * generic container ↔ plug-in coordination (a data-access request), NOT a feature event surfaced\n * to the outer app.\n */\n OnRefreshButtonClick(): void {\n this.dataRequest.emit(this.currentPageDataRequest());\n }\n\n /** @deprecated Use {@link OnRefreshButtonClick}. */\n onRefreshButtonClick(): void {\n return this.OnRefreshButtonClick();\n }\n\n // ================================================================\n // Export: handled entirely by mj-entity-data-grid (its onExportClick opens its own export dialog\n // via ExportService). This wrapper intentionally does NOT host an export dialog — doing so produced\n // two stacked dialogs. Nothing to do here.\n // ================================================================\n\n // ================================================================\n // Self-contained: Add to List (hosts <mj-list-management-dialog>)\n // ================================================================\n\n /**\n * Add-to-list button → build a {@link ListManagementDialogConfig} from the entity + the records the\n * grid supplied, then open the Generic list-management dialog. The dialog persists membership\n * changes itself — nothing bubbles up. Mirrors the config construction the legacy host did in\n * `data-explorer-dashboard`'s `onAddToListRequested()`.\n */\n OnAddToListRequested(event: { entityInfo: EntityInfo; records: Record<string, unknown>[]; recordIds: string[] }): void {\n const entity = event.entityInfo ?? this.entity;\n if (!entity || !event.records || event.records.length === 0) {\n return;\n }\n\n const recordDisplayNames = event.records.map((record) => this.getRecordDisplayName(record, entity));\n const recordIds = this.buildRawRecordIds(event.records, entity);\n if (recordIds.length === 0) {\n return;\n }\n\n const recordCount = event.records.length;\n const dialogTitle = recordCount === 1 ? `Manage Lists for \"${recordDisplayNames[0]}\"` : `Add ${recordCount} Records to List`;\n\n this.listManagementConfig = {\n mode: 'manage',\n entityId: entity.ID,\n entityName: entity.Name,\n recordIds,\n recordDisplayNames,\n allowCreate: true,\n allowRemove: recordCount === 1,\n showMembership: recordCount === 1,\n dialogTitle,\n };\n this.showListManagementDialog = true;\n this.cdr.detectChanges();\n }\n\n /** @deprecated Use {@link OnAddToListRequested}. */\n onAddToListRequested(event: { entityInfo: EntityInfo; records: Record<string, unknown>[]; recordIds: string[] }): void {\n return this.OnAddToListRequested(event);\n }\n\n /** List-management dialog completed (membership changes applied) → tear down state. */\n OnListManagementComplete(_result: ListManagementResult): void {\n this.showListManagementDialog = false;\n this.listManagementConfig = null;\n this.cdr.detectChanges();\n }\n\n /** @deprecated Use {@link OnListManagementComplete}. */\n onListManagementComplete(_result: ListManagementResult): void {\n return this.OnListManagementComplete(_result);\n }\n\n /** List-management dialog cancelled → tear down state. */\n OnListManagementCancel(): void {\n this.showListManagementDialog = false;\n this.listManagementConfig = null;\n this.cdr.detectChanges();\n }\n\n /** @deprecated Use {@link OnListManagementCancel}. */\n onListManagementCancel(): void {\n return this.OnListManagementCancel();\n }\n\n /**\n * Resolve a human-friendly display name for a record using the entity's NameField, falling back to\n * the composite-key string. Mirrors the legacy host's display-name resolution.\n */\n private getRecordDisplayName(record: Record<string, unknown>, entity: EntityInfo): string {\n if (entity.NameField) {\n const nameValue = record[entity.NameField.Name];\n if (nameValue != null) {\n return String(nameValue);\n }\n }\n return BuildPkString(record, entity) || 'Unknown';\n }\n\n /**\n * Build the record-id strings used by list membership matching, in the compact form `MJ: List Details`\n * stores in `RecordID`: the bare value for a single-column primary key (whatever the column is called),\n * or the full `Field1|Value1||Field2|Value2` segment for a composite key. The entity is arbitrary, so the\n * key is built from all of its primary-key columns rather than assuming a single `ID`.\n */\n private buildRawRecordIds(records: Record<string, unknown>[], entity: EntityInfo): string[] {\n if (entity.PrimaryKeys.length === 0) {\n return [];\n }\n return records\n .map((record) => CompositeKey.FromEntityRecord(entity, record).ToCompactURLSegment())\n .filter((id) => id !== '');\n }\n\n // ================================================================\n // Self-contained: Delete (hosts <mj-ev-confirm-dialog> + MJ entity layer)\n // ================================================================\n\n /**\n * Delete button → stage the records and open the Generic confirm dialog. The actual delete happens\n * in {@link onDeleteConfirmed} after the user confirms — nothing bubbles up.\n */\n OnDeleteButtonClick(records: Record<string, unknown>[]): void {\n if (!records || records.length === 0) {\n return;\n }\n this.pendingDeleteRecords = records;\n const count = records.length;\n this.deleteConfirmMessage = count === 1 ? 'Are you sure you want to delete this record?' : `Are you sure you want to delete these ${count} records?`;\n this.showDeleteConfirm = true;\n this.cdr.detectChanges();\n }\n\n /** @deprecated Use {@link OnDeleteButtonClick}. */\n onDeleteButtonClick(records: Record<string, unknown>[]): void {\n return this.OnDeleteButtonClick(records);\n }\n\n /**\n * Delete confirmed → delete each staged record through the MJ entity layer\n * (`ProviderToUse.GetEntityObject(name, compositeKey, user)` → `Delete`), checking the boolean\n * result and surfacing failures via {@link LogError}. After deletion, re-request the current page\n * so the host reloads. Self-contained — no feature event leaves the wrapper.\n */\n async OnDeleteConfirmed(): Promise<void> {\n this.showDeleteConfirm = false;\n const entity = this.entity;\n const records = this.pendingDeleteRecords;\n this.pendingDeleteRecords = [];\n\n if (!entity || records.length === 0) {\n return;\n }\n\n let anyDeleted = false;\n const provider = this.ProviderToUse;\n const user = provider.CurrentUser;\n\n for (const record of records) {\n const key = BuildCompositeKey(record, entity);\n try {\n // The (name, key, user) overload instantiates AND loads in one call (throws if it can't load).\n const obj = await provider.GetEntityObject(entity.Name, key, user);\n const deleted = await obj.Delete();\n if (deleted) {\n anyDeleted = true;\n } else {\n LogError(`Delete failed: ${obj.LatestResult?.CompleteMessage ?? 'unknown error'}`);\n }\n } catch (err) {\n LogError(`Delete failed for ${entity.Name} (${key.ToString()}): ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n if (anyDeleted) {\n // Re-request the current page so the host reloads the (now smaller) record set.\n this.dataRequest.emit(this.currentPageDataRequest());\n }\n this.cdr.detectChanges();\n }\n\n /** @deprecated Use {@link OnDeleteConfirmed}. */\n async onDeleteConfirmed(): Promise<void> {\n return this.OnDeleteConfirmed();\n }\n\n /** Delete cancelled → discard the staged records and close the confirm dialog. */\n OnDeleteCancelled(): void {\n this.showDeleteConfirm = false;\n this.pendingDeleteRecords = [];\n this.cdr.detectChanges();\n }\n\n /** @deprecated Use {@link OnDeleteCancelled}. */\n onDeleteCancelled(): void {\n return this.OnDeleteCancelled();\n }\n\n // ================================================================\n // Record merge\n // ================================================================\n\n /**\n * The in-flight merge, or null when the panel is closed. Holds everything the panel needs\n * plus the dependency preview, so the panel itself stays a pure presentation component.\n */\n protected mergeState: {\n Config: MergeConfig;\n Fields: FieldComparison[];\n IsMerging: boolean;\n DependencyNote: string | null;\n /** The entity and the two records' real keys — the Config only carries their serialized form. */\n Entity: EntityInfo;\n Keys: [CompositeKey, CompositeKey];\n } | null = null;\n\n /** A one-line status shown under the grid — why a merge was refused, or how one ended. */\n protected mergeNotice: string | null = null;\n\n /** Auto-dismiss timer for {@link mergeNotice}; cleared whenever the notice is replaced. */\n private mergeNoticeTimer: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * How long a merge notice stays up before dismissing itself. The banner is fixed-position over\n * the whole application, so leaving it until the next merge pins it across navigation and every\n * other record the user visits afterwards.\n */\n private static readonly MERGE_NOTICE_TIMEOUT_MS = 8000;\n\n private readonly comparison = inject(RecordComparisonService);\n\n ngOnDestroy(): void {\n // The notice's auto-dismiss outlives the view otherwise, and fires detectChanges on a\n // destroyed component.\n if (this.mergeNoticeTimer) {\n clearTimeout(this.mergeNoticeTimer);\n this.mergeNoticeTimer = null;\n }\n }\n\n /** Dismiss the merge notice from its own close button. */\n OnDismissMergeNotice(): void {\n this.setMergeNotice(null);\n this.cdr.detectChanges();\n }\n\n /** @deprecated Use {@link OnDismissMergeNotice}. */\n onDismissMergeNotice(): void {\n return this.OnDismissMergeNotice();\n }\n\n /**\n * Set (or clear) the merge notice, replacing any pending auto-dismiss. Every write to\n * `mergeNotice` goes through here so a notice cannot outlive its timer or strand an old one.\n */\n private setMergeNotice(message: string | null): void {\n if (this.mergeNoticeTimer) {\n clearTimeout(this.mergeNoticeTimer);\n this.mergeNoticeTimer = null;\n }\n this.mergeNotice = message;\n if (message) {\n this.mergeNoticeTimer = setTimeout(() => {\n this.mergeNoticeTimer = null;\n this.mergeNotice = null;\n this.cdr.detectChanges();\n }, GridViewRendererComponent.MERGE_NOTICE_TIMEOUT_MS);\n }\n }\n\n /**\n * Show the Merge button only where merging can actually succeed: the entity opts in and the\n * user can both update the survivor and delete the loser.\n */\n protected get effectiveShowMergeButton(): boolean {\n const entity = this.entity;\n const user = this.ProviderToUse?.CurrentUser;\n if (!entity?.AllowRecordMerge || !user) return false;\n const permissions = entity.GetUserPermisions(user);\n return !!permissions && permissions.CanUpdate && permissions.CanDelete;\n }\n\n /** The record that will be deleted, named so the user sees the choice before confirming. */\n protected get mergeLoserLabel(): string {\n const config = this.mergeState?.Config;\n if (!config) return '';\n return config.SurvivorSide === 'left' ? config.RightLabel : config.LeftLabel;\n }\n\n /**\n * The grid asked to merge the selected rows. Compare them, preview what will move, and open\n * the panel — nothing is written until the user confirms.\n */\n async OnMergeRequested(event: { entityInfo: EntityInfo; records: Record<string, unknown>[] }): Promise<void> {\n this.setMergeNotice(null);\n try {\n await this.prepareMerge(event);\n } catch (err) {\n // A transport failure in any pre-flight query must not leave the user with nothing.\n this.setMergeNotice(`Could not prepare the merge: ${err instanceof Error ? err.message : String(err)}`);\n this.cdr.detectChanges();\n }\n }\n\n /** @deprecated Use {@link OnMergeRequested}. */\n async onMergeRequested(event: { entityInfo: EntityInfo; records: Record<string, unknown>[] }): Promise<void> {\n return this.OnMergeRequested(event);\n }\n\n /** The user chose which record survives; differing fields default to that record's values. */\n OnSurvivorChange(side: 'left' | 'right'): void {\n if (!this.mergeState || this.mergeState.IsMerging) return;\n this.mergeState.Config = { ...this.mergeState.Config, SurvivorSide: side };\n for (const field of this.mergeState.Fields) {\n if (!field.IsReadOnly) field.SelectedSide = side;\n }\n this.cdr.detectChanges();\n }\n\n /** @deprecated Use {@link OnSurvivorChange}. */\n onSurvivorChange(side: 'left' | 'right'): void {\n return this.OnSurvivorChange(side);\n }\n\n private async prepareMerge(event: { entityInfo: EntityInfo; records: Record<string, unknown>[] }): Promise<void> {\n const entity = event.entityInfo ?? this.entity;\n if (!entity) return;\n\n // The merge panel is two-sided by construction, so n > 2 has nowhere to render.\n if (event.records.length !== 2) {\n this.setMergeNotice('Select exactly two records to merge.');\n this.cdr.detectChanges();\n return;\n }\n\n // Composite-key safe: the grid renders arbitrary entities, so never assume one key column.\n const keys = event.records.map(r => CompositeKey.FromEntityRecord(entity, r)) as [CompositeKey, CompositeKey];\n if (keys.some(k => k.KeyValuePairs.length === 0 || k.KeyValuePairs.some(kv => kv.Value == null || kv.Value === ''))) {\n this.setMergeNotice('Could not read the primary key of the selected records.');\n this.cdr.detectChanges();\n return;\n }\n // The merge panel's config is string-keyed, so keys travel through it as compact segments.\n const [left, right] = keys.map(k => k.ToCompactURLSegment());\n\n // Subtype records: the merge re-points only the keys that target this entity, then the loser's\n // delete follows the shared key into the parent row, whose own references never moved.\n if (entity.ParentID) {\n this.setMergeNotice(`${entity.DisplayName} records extend a parent type; merging subtype records is not supported yet.`);\n this.cdr.detectChanges();\n return;\n }\n const childRows = await this.hasIsAChildRows(entity, keys);\n if (childRows === null) {\n this.setMergeNotice('Could not verify whether the selected records have subtype rows, so the merge was not started.');\n this.cdr.detectChanges();\n return;\n }\n if (childRows) {\n this.setMergeNotice(\n `${entity.DisplayName} records that another app extends (shared-key subtype rows) cannot be merged yet — ` +\n 'the merge would collide on the shared key. Merge them from the extending app instead.',\n );\n this.cdr.detectChanges();\n return;\n }\n\n const result = await this.comparison.GetRecordComparison(\n {\n EntityName: entity.Name,\n Keys: keys.map(k => ({\n KeyValuePairs: k.KeyValuePairs.map(kv => ({ FieldName: kv.FieldName, Value: String(kv.Value) })),\n })),\n },\n this.ProviderToUse,\n );\n if (!result.Success || !result.Output) {\n this.setMergeNotice(result.ErrorMessage ?? 'Could not compare the selected records.');\n this.cdr.detectChanges();\n return;\n }\n\n this.mergeState = {\n Config: {\n EntityName: entity.Name,\n LeftRecordID: left,\n RightRecordID: right,\n SurvivorSide: 'left',\n LeftLabel: this.labelFor(event.records[0], entity, keys[0]),\n RightLabel: this.labelFor(event.records[1], entity, keys[1]),\n },\n Fields: result.Output.Fields.map(delta => ({\n FieldName: delta.FieldName,\n DisplayLabel: delta.DisplayName,\n LeftValue: delta.Cells[0]?.Value,\n RightValue: delta.Cells[1]?.Value,\n HasConflict: delta.Differs,\n SelectedSide: 'left' as const,\n // What the ORM will refuse to write — keys, AllowUpdateAPI = 0, timestamps. A field the\n // metadata does not know cannot be written either.\n IsReadOnly: entity.FieldByName(delta.FieldName)?.ReadOnly ?? true,\n DataType: 'string',\n })),\n IsMerging: false,\n DependencyNote: await this.describeDependencies(entity, keys),\n Entity: entity,\n Keys: keys,\n };\n this.cdr.detectChanges();\n }\n\n /** The user confirmed: merge, then reload the page so the loser disappears from the grid. */\n async OnMergeConfirmed(event: MergeConfirmedEvent): Promise<void> {\n if (!this.mergeState) return;\n this.mergeState.IsMerging = true;\n this.cdr.detectChanges();\n\n const survivorIsLeft = event.Config.SurvivorSide === 'left';\n const [leftKey, rightKey] = this.mergeState.Keys;\n const survivor = survivorIsLeft ? leftKey : rightKey;\n const loser = survivorIsLeft ? rightKey : leftKey;\n\n const request = new RecordMergeRequest();\n request.EntityName = event.Config.EntityName;\n request.SurvivingRecordCompositeKey = survivor;\n request.RecordsToMerge = [loser];\n request.FieldMap = this.buildFieldMap(event, survivorIsLeft);\n\n try {\n const result = await this.ProviderToUse.MergeRecords(request);\n this.mergeState = null;\n this.setMergeNotice(result.Success ? 'Records merged.' : `Merge failed: ${result.OverallStatus}`);\n if (result.Success) {\n this.dataRequest.emit(this.currentPageDataRequest());\n }\n } catch (err) {\n this.mergeState = null;\n this.setMergeNotice(`Merge failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n this.cdr.detectChanges();\n }\n\n /** @deprecated Use {@link OnMergeConfirmed}. */\n async onMergeConfirmed(event: MergeConfirmedEvent): Promise<void> {\n return this.OnMergeConfirmed(event);\n }\n\n /** Merge cancelled → close the panel, write nothing. */\n OnMergeCancelled(): void {\n this.mergeState = null;\n this.cdr.detectChanges();\n }\n\n /** @deprecated Use {@link OnMergeCancelled}. */\n onMergeCancelled(): void {\n return this.OnMergeCancelled();\n }\n\n /**\n * Fields whose resolution has to travel, and only those: the survivor already holds the value\n * for any field resolved to its own side.\n *\n * The distinction that matters is \"the user did not change this\" versus \"the user chose the\n * blank side\". Both arrive as an absent value, so deciding from the value alone drops a real\n * resolution — the survivor silently keeps its old value on the one operation where someone is\n * reconciling two records field by field, and the loser is gone afterwards. So the skip is\n * decided from WHICH SIDE was chosen, and a chosen blank is written through as null.\n */\n private buildFieldMap(event: MergeConfirmedEvent, survivorIsLeft: boolean): { FieldName: string; Value: unknown }[] {\n const map: { FieldName: string; Value: unknown }[] = [];\n for (const field of event.ResolvedFields) {\n if (field.IsReadOnly || !field.HasConflict) continue;\n // Resolved to the survivor's own side — nothing to write, whatever the value is.\n if (field.SelectedSide !== 'custom' && (field.SelectedSide === 'left') === survivorIsLeft) continue;\n const chosen =\n field.SelectedSide === 'custom'\n ? field.CustomValue\n : (survivorIsLeft ? field.RightValue : field.LeftValue);\n // A chosen blank is a clear, not a no-op. Normalize undefined to null so the transport\n // carries an explicit value rather than an absent one.\n map.push({ FieldName: field.FieldName, Value: chosen === undefined ? null : chosen });\n }\n return map;\n }\n\n /**\n * True when any of these records has a row in an IS-A child entity, null when that could not be\n * determined (a child view the user cannot read answers `Success: false`, which must not pass\n * for \"no rows\"). `MergeRecords` has no subtype handling: the child rows share the parent's key,\n * so merging would collide. Refuse rather than half-merge.\n */\n private async hasIsAChildRows(entity: EntityInfo, keys: ReadonlyArray<CompositeKey>): Promise<boolean | null> {\n const children = entity.ChildEntities;\n if (children.length === 0) return false;\n\n // An IS-A child shares its parent's key SEMANTICALLY; nothing requires it to share the column\n // NAME. `CompositeKey.ToWhereClause()` emits the parent's names, so filtering a child view\n // with it fails wherever the names differ — and a failed probe refuses the merge, which would\n // disable merge for that entity permanently. Pair each key's values onto the child's own PK\n // columns instead, the way the platform's own child discovery does\n // (SQLServerDataProvider.BuildChildDiscoverySQL).\n const probes = children\n .map(child => ({ child, filter: this.buildChildKeyFilter(child, keys) }))\n .filter((probe): probe is { child: EntityInfo; filter: string } => probe.filter !== null);\n if (probes.length === 0) return false;\n\n const results = await RunView.FromMetadataProvider(this.ProviderToUse).RunViews(\n probes.map(({ child, filter }) => ({\n EntityName: child.Name,\n ExtraFilter: filter,\n Fields: child.PrimaryKeys.map(f => f.Name),\n ResultType: 'simple' as const,\n MaxRows: 1,\n })),\n );\n if (results.some(r => !r.Success)) return null;\n return results.some(r => r.Results.length > 0);\n }\n\n /**\n * `(childPk = v1) OR (childPk = v2)` against one child entity, built from the parent's key\n * VALUES and the child's own key COLUMN NAMES, paired positionally because an IS-A child shares\n * its parent's key by design. Null when the child's key arity differs, which means it does not\n * share the key and cannot hold a subtype row for these records.\n */\n private buildChildKeyFilter(child: EntityInfo, keys: ReadonlyArray<CompositeKey>): string | null {\n const childPkFields = child.PrimaryKeys;\n if (childPkFields.length === 0 || keys.some(k => k.KeyValuePairs.length !== childPkFields.length)) {\n return null;\n }\n const clauses = keys.map(key =>\n childPkFields\n .map((field, i) => `[${field.Name}] = '${String(key.KeyValuePairs[i].Value ?? '').replace(/'/g, \"''\")}'`)\n .join(' AND '),\n );\n return clauses.map(c => `(${c})`).join(' OR ');\n }\n\n /**\n * How many linked records will move to the survivor — the thing users most want to know.\n *\n * Indexes `counts[0]` / `counts[1]` directly: `onMergeRequested` refuses anything other than\n * exactly two records before reaching here, and the merge panel's config is two-sided by\n * construction, so this is only ever called with a pair. Widen both together.\n */\n private async describeDependencies(entity: EntityInfo, keys: ReadonlyArray<CompositeKey>): Promise<string | null> {\n try {\n const counts = await Promise.all(\n keys.map(key => this.ProviderToUse.GetRecordDependencies(entity.Name, key)),\n );\n return `Linked records that would move to the survivor: ${counts[0].length} on the left, ${counts[1].length} on the right.`;\n } catch (err) {\n LogError(`Could not load merge dependencies for ${entity.Name}: ${err instanceof Error ? err.message : String(err)}`);\n return null;\n }\n }\n\n /** A human label for a row — its name field when it has one, else its key. */\n private labelFor(row: Record<string, unknown>, entity: EntityInfo, key: CompositeKey): string {\n const nameField = entity.NameField?.Name;\n const name = nameField ? String(row[nameField] ?? '') : '';\n return name || key.ToCompactURLSegment();\n }\n\n // ================================================================\n // Helpers\n // ================================================================\n\n /** Build a {@link ViewDataRequest} that re-requests the host's current page/pageSize, if known. */\n private currentPageDataRequest(): ViewDataRequest {\n const req: ViewDataRequest = {};\n if (this.page != null) {\n req.page = this.page;\n }\n const ps = this.config.pageSize ?? this.pageSize;\n if (ps != null) {\n req.pageSize = ps;\n }\n return req;\n }\n\n /**\n * Resolve an entity's name from its ID via the active provider's metadata. Used when a foreign-key\n * click event omits the related entity name and only carries its ID.\n */\n private resolveEntityNameById(entityId: string): string | null {\n if (!entityId) {\n return null;\n }\n const match = this.ProviderToUse.Entities.find((e) => UUIDsEqual(e.ID, entityId));\n return match ? match.Name : null;\n }\n}\n\n/**\n * Tree-shaking guard. Force-references this renderer so bundlers (ESBuild/Vite) don't drop the\n * component in builds that only mount it dynamically via the ClassFactory/descriptor. Mirrors the\n * Cards/Cluster renderers' load guards; the parent wires this into a barrel/module load path.\n */\nexport function LoadGridViewRenderer(): void {\n // no-op; presence prevents tree-shaking of this component\n}\n"]}
|
|
@@ -101,9 +101,17 @@ export declare class MapViewRendererComponent extends BaseAngularComponent imple
|
|
|
101
101
|
*/
|
|
102
102
|
dataRequest: EventEmitter<ViewDataRequest>;
|
|
103
103
|
/** The render mode bound to `<mj-map-view>`, derived from {@link config} (defaults to `'point'`). */
|
|
104
|
-
|
|
104
|
+
ActiveRenderMode: MapRenderMode;
|
|
105
|
+
/** @deprecated Use {@link ActiveRenderMode}. */
|
|
106
|
+
get activeRenderMode(): MapRenderMode;
|
|
107
|
+
/** @deprecated Use {@link ActiveRenderMode}. */
|
|
108
|
+
set activeRenderMode(value: MapRenderMode);
|
|
105
109
|
/** The display state bound to `<mj-map-view>`, derived from {@link config} (null when unset). */
|
|
106
|
-
|
|
110
|
+
ActiveDisplayState: Partial<MapDisplayState> | null;
|
|
111
|
+
/** @deprecated Use {@link ActiveDisplayState}. */
|
|
112
|
+
get activeDisplayState(): Partial<MapDisplayState> | null;
|
|
113
|
+
/** @deprecated Use {@link ActiveDisplayState}. */
|
|
114
|
+
set activeDisplayState(value: Partial<MapDisplayState> | null);
|
|
107
115
|
ngOnInit(): void;
|
|
108
116
|
/** Re-derive the map's render mode + display state from the current opaque {@link config}. */
|
|
109
117
|
private applyConfig;
|
|
@@ -111,17 +119,23 @@ export declare class MapViewRendererComponent extends BaseAngularComponent imple
|
|
|
111
119
|
* Relay `<mj-map-view>`'s marker click, normalizing to the raw record the host expects (the host
|
|
112
120
|
* builds the composite key itself from the record + entity).
|
|
113
121
|
*/
|
|
122
|
+
OnMarkerClick(event: MapMarkerClickEvent): void;
|
|
123
|
+
/** @deprecated Use {@link OnMarkerClick}. */
|
|
114
124
|
onMarkerClick(event: MapMarkerClickEvent): void;
|
|
115
125
|
/**
|
|
116
126
|
* Persist a render-mode change into the opaque {@link config} and notify the host. The host
|
|
117
127
|
* stores the blob verbatim; it has no knowledge that `renderMode` means anything map-specific.
|
|
118
128
|
*/
|
|
129
|
+
OnRenderModeChange(mode: MapRenderMode): void;
|
|
130
|
+
/** @deprecated Use {@link OnRenderModeChange}. */
|
|
119
131
|
onRenderModeChange(mode: MapRenderMode): void;
|
|
120
132
|
/**
|
|
121
133
|
* Persist a display-state change (pan / zoom / clustering / choropleth options) into the opaque
|
|
122
134
|
* {@link config} and notify the host. This fires continuously as the user pans/zooms; that's
|
|
123
135
|
* fine — the host debounces persistence of the config blob.
|
|
124
136
|
*/
|
|
137
|
+
OnDisplayStateChange(state: MapDisplayState): void;
|
|
138
|
+
/** @deprecated Use {@link OnDisplayStateChange}. */
|
|
125
139
|
onDisplayStateChange(state: MapDisplayState): void;
|
|
126
140
|
static ɵfac: i0.ɵɵFactoryDeclaration<MapViewRendererComponent, never>;
|
|
127
141
|
static ɵcmp: i0.ɵɵComponentDeclaration<MapViewRendererComponent, "mj-map-view-renderer", never, { "entity": { "alias": "entity"; "required": false; }; "records": { "alias": "records"; "required": false; }; "selectedRecordId": { "alias": "selectedRecordId"; "required": false; }; "filterText": { "alias": "filterText"; "required": false; }; "config": { "alias": "config"; "required": false; }; "totalRecordCount": { "alias": "totalRecordCount"; "required": false; }; "page": { "alias": "page"; "required": false; }; "pageSize": { "alias": "pageSize"; "required": false; }; "isLoading": { "alias": "isLoading"; "required": false; }; }, { "recordSelected": "recordSelected"; "recordOpened": "recordOpened"; "configChanged": "configChanged"; "dataRequest": "dataRequest"; }, never, never, false, never>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map-view-renderer.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/view-types/renderers/map-view-renderer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAqB,MAAM,EAAE,MAAM,eAAe,CAAC;AAClG,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAEL,aAAa,EACb,eAAe,EACf,mBAAmB,EACpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;;AAExE;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,uHAAuH;IACvH,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,6FAA6F;IAC7F,YAAY,CAAC,EAAE,eAAe,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAqCa,wBAAyB,SAAQ,oBAAqB,YAAW,aAAa,CAAC,aAAa,CAAC,EAAE,MAAM;IAGhH,+GAA+G;IACtG,MAAM,EAAE,UAAU,GAAG,IAAI,CAAQ;IAE1C,0EAA0E;IACjE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAM;IAEjD,iGAAiG;IACxF,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEhD,mGAAmG;IAC1F,UAAU,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE1C,OAAO,CAAC,OAAO,CAAqB;IACpC;;;OAGG;IACH,IACI,MAAM,CAAC,KAAK,EAAE,aAAa,EAG9B;IACD,IAAI,MAAM,IAAI,aAAa,CAE1B;IAED;;;OAGG;IACM,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAEnC,qGAAqG;IAC5F,IAAI,CAAC,EAAE,MAAM,CAAC;IAEvB,2DAA2D;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,8FAA8F;IACrF,SAAS,CAAC,EAAE,OAAO,CAAC;IAI7B,oGAAoG;IAC1F,cAAc,wBAA+B;IAEvD;;;OAGG;IACO,YAAY,wBAA+B;IAErD;;;OAGG;IACO,aAAa,8BAAqC;IAE5D;;;;OAIG;IACO,WAAW,gCAAuC;IAI5D,qGAAqG;IAC9F,gBAAgB,EAAE,aAAa,CAAW;IAEjD,iGAAiG;IAC1F,kBAAkB,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAAQ;IAElE,QAAQ,IAAI,IAAI;IAOhB,8FAA8F;IAC9F,OAAO,CAAC,WAAW;IAKnB;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAI/C;;;OAGG;IACH,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAM7C;;;;OAIG;IACH,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"map-view-renderer.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/view-types/renderers/map-view-renderer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAqB,MAAM,EAAE,MAAM,eAAe,CAAC;AAClG,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAEL,aAAa,EACb,eAAe,EACf,mBAAmB,EACpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;;AAExE;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,uHAAuH;IACvH,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,6FAA6F;IAC7F,YAAY,CAAC,EAAE,eAAe,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAqCa,wBAAyB,SAAQ,oBAAqB,YAAW,aAAa,CAAC,aAAa,CAAC,EAAE,MAAM;IAGhH,+GAA+G;IACtG,MAAM,EAAE,UAAU,GAAG,IAAI,CAAQ;IAE1C,0EAA0E;IACjE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAM;IAEjD,iGAAiG;IACxF,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEhD,mGAAmG;IAC1F,UAAU,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE1C,OAAO,CAAC,OAAO,CAAqB;IACpC;;;OAGG;IACH,IACI,MAAM,CAAC,KAAK,EAAE,aAAa,EAG9B;IACD,IAAI,MAAM,IAAI,aAAa,CAE1B;IAED;;;OAGG;IACM,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAEnC,qGAAqG;IAC5F,IAAI,CAAC,EAAE,MAAM,CAAC;IAEvB,2DAA2D;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,8FAA8F;IACrF,SAAS,CAAC,EAAE,OAAO,CAAC;IAI7B,oGAAoG;IAC1F,cAAc,wBAA+B;IAEvD;;;OAGG;IACO,YAAY,wBAA+B;IAErD;;;OAGG;IACO,aAAa,8BAAqC;IAE5D;;;;OAIG;IACO,WAAW,gCAAuC;IAI5D,qGAAqG;IAC9F,gBAAgB,EAAE,aAAa,CAAW;IAEjD,gDAAgD;IAChD,IAAW,gBAAgB,IAAI,aAAa,CAE3C;IACD,gDAAgD;IAChD,IAAW,gBAAgB,CAAC,KAAK,EAAE,aAAa,EAE/C;IAED,iGAAiG;IAC1F,kBAAkB,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAAQ;IAElE,kDAAkD;IAClD,IAAW,kBAAkB,IAAI,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAE/D;IACD,kDAAkD;IAClD,IAAW,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,EAEnE;IAED,QAAQ,IAAI,IAAI;IAOhB,8FAA8F;IAC9F,OAAO,CAAC,WAAW;IAKnB;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAI/C,6CAA6C;IAC7C,aAAa,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAI/C;;;OAGG;IACH,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAM7C,kDAAkD;IAClD,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAI7C;;;;OAIG;IACH,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAMlD,oDAAoD;IACpD,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;yCAnJvC,wBAAwB;2CAAxB,wBAAwB;CAsJpC;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
|
|
@@ -105,9 +105,25 @@ export class MapViewRendererComponent extends BaseAngularComponent {
|
|
|
105
105
|
dataRequest = new EventEmitter();
|
|
106
106
|
// ---- Render state (seeded from config) ----
|
|
107
107
|
/** The render mode bound to `<mj-map-view>`, derived from {@link config} (defaults to `'point'`). */
|
|
108
|
-
|
|
108
|
+
ActiveRenderMode = 'point';
|
|
109
|
+
/** @deprecated Use {@link ActiveRenderMode}. */
|
|
110
|
+
get activeRenderMode() {
|
|
111
|
+
return this.ActiveRenderMode;
|
|
112
|
+
}
|
|
113
|
+
/** @deprecated Use {@link ActiveRenderMode}. */
|
|
114
|
+
set activeRenderMode(value) {
|
|
115
|
+
this.ActiveRenderMode = value;
|
|
116
|
+
}
|
|
109
117
|
/** The display state bound to `<mj-map-view>`, derived from {@link config} (null when unset). */
|
|
110
|
-
|
|
118
|
+
ActiveDisplayState = null;
|
|
119
|
+
/** @deprecated Use {@link ActiveDisplayState}. */
|
|
120
|
+
get activeDisplayState() {
|
|
121
|
+
return this.ActiveDisplayState;
|
|
122
|
+
}
|
|
123
|
+
/** @deprecated Use {@link ActiveDisplayState}. */
|
|
124
|
+
set activeDisplayState(value) {
|
|
125
|
+
this.ActiveDisplayState = value;
|
|
126
|
+
}
|
|
111
127
|
ngOnInit() {
|
|
112
128
|
// Maps need the complete record set, not a single page. Request it through the generic
|
|
113
129
|
// data-access channel — the container honors `{ loadAll: true }` without any map-specific
|
|
@@ -116,35 +132,47 @@ export class MapViewRendererComponent extends BaseAngularComponent {
|
|
|
116
132
|
}
|
|
117
133
|
/** Re-derive the map's render mode + display state from the current opaque {@link config}. */
|
|
118
134
|
applyConfig() {
|
|
119
|
-
this.
|
|
120
|
-
this.
|
|
135
|
+
this.ActiveRenderMode = this._config.renderMode ?? 'point';
|
|
136
|
+
this.ActiveDisplayState = this._config.displayState ?? null;
|
|
121
137
|
}
|
|
122
138
|
/**
|
|
123
139
|
* Relay `<mj-map-view>`'s marker click, normalizing to the raw record the host expects (the host
|
|
124
140
|
* builds the composite key itself from the record + entity).
|
|
125
141
|
*/
|
|
126
|
-
|
|
142
|
+
OnMarkerClick(event) {
|
|
127
143
|
this.recordSelected.emit(event.Record);
|
|
128
144
|
}
|
|
145
|
+
/** @deprecated Use {@link OnMarkerClick}. */
|
|
146
|
+
onMarkerClick(event) {
|
|
147
|
+
return this.OnMarkerClick(event);
|
|
148
|
+
}
|
|
129
149
|
/**
|
|
130
150
|
* Persist a render-mode change into the opaque {@link config} and notify the host. The host
|
|
131
151
|
* stores the blob verbatim; it has no knowledge that `renderMode` means anything map-specific.
|
|
132
152
|
*/
|
|
133
|
-
|
|
153
|
+
OnRenderModeChange(mode) {
|
|
134
154
|
this._config = { ...this._config, renderMode: mode };
|
|
135
|
-
this.
|
|
155
|
+
this.ActiveRenderMode = mode;
|
|
136
156
|
this.configChanged.emit(this._config);
|
|
137
157
|
}
|
|
158
|
+
/** @deprecated Use {@link OnRenderModeChange}. */
|
|
159
|
+
onRenderModeChange(mode) {
|
|
160
|
+
return this.OnRenderModeChange(mode);
|
|
161
|
+
}
|
|
138
162
|
/**
|
|
139
163
|
* Persist a display-state change (pan / zoom / clustering / choropleth options) into the opaque
|
|
140
164
|
* {@link config} and notify the host. This fires continuously as the user pans/zooms; that's
|
|
141
165
|
* fine — the host debounces persistence of the config blob.
|
|
142
166
|
*/
|
|
143
|
-
|
|
167
|
+
OnDisplayStateChange(state) {
|
|
144
168
|
this._config = { ...this._config, displayState: state };
|
|
145
|
-
this.
|
|
169
|
+
this.ActiveDisplayState = state;
|
|
146
170
|
this.configChanged.emit(this._config);
|
|
147
171
|
}
|
|
172
|
+
/** @deprecated Use {@link OnDisplayStateChange}. */
|
|
173
|
+
onDisplayStateChange(state) {
|
|
174
|
+
return this.OnDisplayStateChange(state);
|
|
175
|
+
}
|
|
148
176
|
static ɵfac = /*@__PURE__*/ (() => { let ɵMapViewRendererComponent_BaseFactory; return function MapViewRendererComponent_Factory(__ngFactoryType__) { return (ɵMapViewRendererComponent_BaseFactory || (ɵMapViewRendererComponent_BaseFactory = i0.ɵɵgetInheritedFactory(MapViewRendererComponent)))(__ngFactoryType__ || MapViewRendererComponent); }; })();
|
|
149
177
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MapViewRendererComponent, selectors: [["mj-map-view-renderer"]], inputs: { entity: "entity", records: "records", selectedRecordId: "selectedRecordId", filterText: "filterText", config: "config", totalRecordCount: "totalRecordCount", page: "page", pageSize: "pageSize", isLoading: "isLoading" }, outputs: { recordSelected: "recordSelected", recordOpened: "recordOpened", configChanged: "configChanged", dataRequest: "dataRequest" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [[3, "Entity", "Records", "TotalRecordCount", "RenderMode", "DisplayState"], ["Icon", "fa-solid fa-map-location-dot", "Title", "No entity selected to map.", 1, "map-view-renderer-empty-fill"], [3, "MarkerClick", "RenderModeChange", "DisplayStateChange", "Entity", "Records", "TotalRecordCount", "RenderMode", "DisplayState"]], template: function MapViewRendererComponent_Template(rf, ctx) { if (rf & 1) {
|
|
150
178
|
i0.ɵɵconditionalCreate(0, MapViewRendererComponent_Conditional_0_Template, 1, 5, "mj-map-view", 0)(1, MapViewRendererComponent_Conditional_1_Template, 1, 0, "mj-empty-state", 1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map-view-renderer.component.js","sourceRoot":"","sources":["../../../../src/lib/view-types/renderers/map-view-renderer.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, ViewEncapsulation, OnInit } from '@angular/core';\nimport { EntityInfo } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport {\n MapViewComponent,\n MapRenderMode,\n MapDisplayState,\n MapMarkerClickEvent,\n} from '@memberjunction/ng-map-view';\nimport { IViewRenderer, ViewDataRequest } from '../view-type.contracts';\n\n/**\n * Opaque per-view configuration for the Map view type.\n *\n * The host stores and round-trips this blob verbatim against the active `ViewTypeID` and never\n * inspects it — only this renderer reads/writes it. It carries the two pieces of map state that\n * should persist with the view: the render mode (point / boundary / choropleth / heatmap) and the\n * last display state (zoom / center / clustering / choropleth options). Both are optional so a\n * freshly-created Map view starts from sensible defaults.\n */\nexport interface MapViewConfig {\n /** The map's render mode. Defaults to `'point'` when unset (see {@link MapViewRendererComponent.activeRenderMode}). */\n renderMode?: MapRenderMode;\n /** The map's last persisted display state (zoom, center, clustering, choropleth options). */\n displayState?: MapDisplayState;\n}\n\n/**\n * MapViewRendererComponent\n * ------------------------\n * The Map **view type** renderer — a thin {@link IViewRenderer} adapter that hosts the existing\n * {@link MapViewComponent} (`<mj-map-view>`) inside the entity-viewer's pluggable view-type system.\n *\n * **The container has ZERO knowledge of maps.** The host feeds this renderer only the generic\n * {@link IViewRenderer} surface (`entity` / `records` / `totalRecordCount` / `config` / …) and\n * listens only to the generic outputs (`recordSelected` / `configChanged` / `dataRequest` / …).\n * Everything map-specific is encapsulated here:\n *\n * - The map's **render mode + display state** live inside the opaque {@link MapViewConfig} blob.\n * The host persists that blob verbatim against the active `ViewTypeID` and never reads it; this\n * renderer seeds `<mj-map-view>` from it and writes changes back via `configChanged`.\n * - The \"maps need the full record set\" requirement is expressed through the **generic\n * {@link IViewRenderer.dataRequest} channel** as `{ loadAll: true }` — the container honors the\n * request (loads all records up to its safety cap) without knowing it came from a map.\n *\n * **Why import `MapViewModule` rather than `MapViewComponent` directly:** {@link MapViewComponent}\n * is an NgModule-declared (`standalone: false`) component, so Angular forbids placing it directly\n * in a standalone component's `imports` array (NG6008). The supported way for a standalone\n * component to consume a non-standalone component is to import the NgModule that exports it — here\n * {@link MapViewModule}. {@link MapViewComponent} is still imported above so its `@Input`/`@Output`\n * types stay referenced and the file documents exactly which component it adapts. This mirrors the\n * sibling `CardsViewRendererComponent`'s approach.\n *\n * **Marker → record mapping:** `<mj-map-view>` emits the rich {@link MapMarkerClickEvent}\n * (`{ RecordID, Latitude, Longitude, Record }`), but the host's dynamic renderer handler expects\n * the **raw record** and builds the composite key itself. This adapter therefore extracts\n * `.Record` and re-emits just that object via `recordSelected`, matching the other plug-in\n * renderers (Cards/Cluster emit raw record objects).\n *\n * Inputs use the camelCase names mandated by the {@link IViewRenderer} contract (the host binds\n * them by those exact names), rather than MJ's usual PascalCase for public members — mirroring the\n * Cards and Cluster renderers.\n */\n@Component({\n standalone: false,\n selector: 'mj-map-view-renderer',\n encapsulation: ViewEncapsulation.None,\n template: `\n @if (entity) {\n <mj-map-view\n [Entity]=\"entity\"\n [Records]=\"records\"\n [TotalRecordCount]=\"totalRecordCount ?? 0\"\n [RenderMode]=\"activeRenderMode\"\n [DisplayState]=\"activeDisplayState\"\n (MarkerClick)=\"onMarkerClick($event)\"\n (RenderModeChange)=\"onRenderModeChange($event)\"\n (DisplayStateChange)=\"onDisplayStateChange($event)\"\n >\n </mj-map-view>\n } @else {\n <mj-empty-state\n class=\"map-view-renderer-empty-fill\"\n Icon=\"fa-solid fa-map-location-dot\"\n Title=\"No entity selected to map.\" />\n }\n `,\n styles: [\n `\n :host {\n display: block;\n height: 100%;\n }\n /* Fill the map area (the host centers its content but does not grow). */\n .map-view-renderer-empty-fill {\n height: 100%;\n }\n `,\n ],\n})\nexport class MapViewRendererComponent extends BaseAngularComponent implements IViewRenderer<MapViewConfig>, OnInit {\n // ---- IViewRenderer inputs (camelCase per the host contract) ----\n\n /** The entity whose records are being mapped. The map requires an entity; when null an empty state renders. */\n @Input() entity: EntityInfo | null = null;\n\n /** The records to render as map markers (loaded/filtered by the host). */\n @Input() records: Record<string, unknown>[] = [];\n\n /** Primary-key string of the currently selected record, if any. Unused by the map view today. */\n @Input() selectedRecordId: string | null = null;\n\n /** Active filter text. Unused by the map view today (records are already filtered by the host). */\n @Input() filterText: string | null = null;\n\n private _config: MapViewConfig = {};\n /**\n * The opaque per-view configuration. Setting it re-derives the {@link activeRenderMode} and\n * {@link activeDisplayState} that seed `<mj-map-view>`.\n */\n @Input()\n set config(value: MapViewConfig) {\n this._config = value ?? {};\n this.applyConfig();\n }\n get config(): MapViewConfig {\n return this._config;\n }\n\n /**\n * The total number of records the host's query would return — bound to `<mj-map-view>`'s\n * `TotalRecordCount` so the map can convey when markers are a capped subset.\n */\n @Input() totalRecordCount?: number;\n\n /** One-based current page of {@link records} when the host is paginating. Unused by the map view. */\n @Input() page?: number;\n\n /** Page size the host is using. Unused by the map view. */\n @Input() pageSize?: number;\n\n /** Whether the host is currently (re)loading the record set. Unused by the map view today. */\n @Input() isLoading?: boolean;\n\n // ---- IViewRenderer outputs ----\n\n /** Emitted when a marker is clicked — payload is the raw record object (the marker's `.Record`). */\n @Output() recordSelected = new EventEmitter<unknown>();\n\n /**\n * Required by {@link IViewRenderer}; the map view has no distinct \"open\" gesture, so this never\n * emits. Declared so the host's uniform output subscription is satisfied.\n */\n @Output() recordOpened = new EventEmitter<unknown>();\n\n /**\n * Emitted when the user changes the render mode or pans/zooms the map. The host persists the\n * updated {@link MapViewConfig} blob verbatim against the active `ViewTypeID`.\n */\n @Output() configChanged = new EventEmitter<MapViewConfig>();\n\n /**\n * The generic data-access channel. On init this emits `{ loadAll: true }` so the container loads\n * the full record set — maps need every record to plot, not a single page — requested without the\n * container knowing it came from a map.\n */\n @Output() dataRequest = new EventEmitter<ViewDataRequest>();\n\n // ---- Render state (seeded from config) ----\n\n /** The render mode bound to `<mj-map-view>`, derived from {@link config} (defaults to `'point'`). */\n public activeRenderMode: MapRenderMode = 'point';\n\n /** The display state bound to `<mj-map-view>`, derived from {@link config} (null when unset). */\n public activeDisplayState: Partial<MapDisplayState> | null = null;\n\n ngOnInit(): void {\n // Maps need the complete record set, not a single page. Request it through the generic\n // data-access channel — the container honors `{ loadAll: true }` without any map-specific\n // branching. Done after inputs are wired (the host sets inputs via setInput before ngOnInit).\n this.dataRequest.emit({ loadAll: true });\n }\n\n /** Re-derive the map's render mode + display state from the current opaque {@link config}. */\n private applyConfig(): void {\n this.activeRenderMode = this._config.renderMode ?? 'point';\n this.activeDisplayState = this._config.displayState ?? null;\n }\n\n /**\n * Relay `<mj-map-view>`'s marker click, normalizing to the raw record the host expects (the host\n * builds the composite key itself from the record + entity).\n */\n onMarkerClick(event: MapMarkerClickEvent): void {\n this.recordSelected.emit(event.Record);\n }\n\n /**\n * Persist a render-mode change into the opaque {@link config} and notify the host. The host\n * stores the blob verbatim; it has no knowledge that `renderMode` means anything map-specific.\n */\n onRenderModeChange(mode: MapRenderMode): void {\n this._config = { ...this._config, renderMode: mode };\n this.activeRenderMode = mode;\n this.configChanged.emit(this._config);\n }\n\n /**\n * Persist a display-state change (pan / zoom / clustering / choropleth options) into the opaque\n * {@link config} and notify the host. This fires continuously as the user pans/zooms; that's\n * fine — the host debounces persistence of the config blob.\n */\n onDisplayStateChange(state: MapDisplayState): void {\n this._config = { ...this._config, displayState: state };\n this.activeDisplayState = state;\n this.configChanged.emit(this._config);\n }\n}\n\n/**\n * Tree-shaking guard. Force-references this renderer so bundlers (ESBuild/Vite) don't drop the\n * component in builds that only mount it dynamically via the ClassFactory/descriptor. Mirrors the\n * Cards and Cluster renderers' load guards; the parent wires this into a barrel/module load path.\n */\nexport function LoadMapViewRenderer(): void {\n // no-op; presence prevents tree-shaking of this component\n}\n"]}
|
|
1
|
+
{"version":3,"file":"map-view-renderer.component.js","sourceRoot":"","sources":["../../../../src/lib/view-types/renderers/map-view-renderer.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, ViewEncapsulation, OnInit } from '@angular/core';\nimport { EntityInfo } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport {\n MapViewComponent,\n MapRenderMode,\n MapDisplayState,\n MapMarkerClickEvent,\n} from '@memberjunction/ng-map-view';\nimport { IViewRenderer, ViewDataRequest } from '../view-type.contracts';\n\n/**\n * Opaque per-view configuration for the Map view type.\n *\n * The host stores and round-trips this blob verbatim against the active `ViewTypeID` and never\n * inspects it — only this renderer reads/writes it. It carries the two pieces of map state that\n * should persist with the view: the render mode (point / boundary / choropleth / heatmap) and the\n * last display state (zoom / center / clustering / choropleth options). Both are optional so a\n * freshly-created Map view starts from sensible defaults.\n */\nexport interface MapViewConfig {\n /** The map's render mode. Defaults to `'point'` when unset (see {@link MapViewRendererComponent.activeRenderMode}). */\n renderMode?: MapRenderMode;\n /** The map's last persisted display state (zoom, center, clustering, choropleth options). */\n displayState?: MapDisplayState;\n}\n\n/**\n * MapViewRendererComponent\n * ------------------------\n * The Map **view type** renderer — a thin {@link IViewRenderer} adapter that hosts the existing\n * {@link MapViewComponent} (`<mj-map-view>`) inside the entity-viewer's pluggable view-type system.\n *\n * **The container has ZERO knowledge of maps.** The host feeds this renderer only the generic\n * {@link IViewRenderer} surface (`entity` / `records` / `totalRecordCount` / `config` / …) and\n * listens only to the generic outputs (`recordSelected` / `configChanged` / `dataRequest` / …).\n * Everything map-specific is encapsulated here:\n *\n * - The map's **render mode + display state** live inside the opaque {@link MapViewConfig} blob.\n * The host persists that blob verbatim against the active `ViewTypeID` and never reads it; this\n * renderer seeds `<mj-map-view>` from it and writes changes back via `configChanged`.\n * - The \"maps need the full record set\" requirement is expressed through the **generic\n * {@link IViewRenderer.dataRequest} channel** as `{ loadAll: true }` — the container honors the\n * request (loads all records up to its safety cap) without knowing it came from a map.\n *\n * **Why import `MapViewModule` rather than `MapViewComponent` directly:** {@link MapViewComponent}\n * is an NgModule-declared (`standalone: false`) component, so Angular forbids placing it directly\n * in a standalone component's `imports` array (NG6008). The supported way for a standalone\n * component to consume a non-standalone component is to import the NgModule that exports it — here\n * {@link MapViewModule}. {@link MapViewComponent} is still imported above so its `@Input`/`@Output`\n * types stay referenced and the file documents exactly which component it adapts. This mirrors the\n * sibling `CardsViewRendererComponent`'s approach.\n *\n * **Marker → record mapping:** `<mj-map-view>` emits the rich {@link MapMarkerClickEvent}\n * (`{ RecordID, Latitude, Longitude, Record }`), but the host's dynamic renderer handler expects\n * the **raw record** and builds the composite key itself. This adapter therefore extracts\n * `.Record` and re-emits just that object via `recordSelected`, matching the other plug-in\n * renderers (Cards/Cluster emit raw record objects).\n *\n * Inputs use the camelCase names mandated by the {@link IViewRenderer} contract (the host binds\n * them by those exact names), rather than MJ's usual PascalCase for public members — mirroring the\n * Cards and Cluster renderers.\n */\n@Component({\n standalone: false,\n selector: 'mj-map-view-renderer',\n encapsulation: ViewEncapsulation.None,\n template: `\n @if (entity) {\n <mj-map-view\n [Entity]=\"entity\"\n [Records]=\"records\"\n [TotalRecordCount]=\"totalRecordCount ?? 0\"\n [RenderMode]=\"activeRenderMode\"\n [DisplayState]=\"activeDisplayState\"\n (MarkerClick)=\"onMarkerClick($event)\"\n (RenderModeChange)=\"onRenderModeChange($event)\"\n (DisplayStateChange)=\"onDisplayStateChange($event)\"\n >\n </mj-map-view>\n } @else {\n <mj-empty-state\n class=\"map-view-renderer-empty-fill\"\n Icon=\"fa-solid fa-map-location-dot\"\n Title=\"No entity selected to map.\" />\n }\n `,\n styles: [\n `\n :host {\n display: block;\n height: 100%;\n }\n /* Fill the map area (the host centers its content but does not grow). */\n .map-view-renderer-empty-fill {\n height: 100%;\n }\n `,\n ],\n})\nexport class MapViewRendererComponent extends BaseAngularComponent implements IViewRenderer<MapViewConfig>, OnInit {\n // ---- IViewRenderer inputs (camelCase per the host contract) ----\n\n /** The entity whose records are being mapped. The map requires an entity; when null an empty state renders. */\n @Input() entity: EntityInfo | null = null;\n\n /** The records to render as map markers (loaded/filtered by the host). */\n @Input() records: Record<string, unknown>[] = [];\n\n /** Primary-key string of the currently selected record, if any. Unused by the map view today. */\n @Input() selectedRecordId: string | null = null;\n\n /** Active filter text. Unused by the map view today (records are already filtered by the host). */\n @Input() filterText: string | null = null;\n\n private _config: MapViewConfig = {};\n /**\n * The opaque per-view configuration. Setting it re-derives the {@link activeRenderMode} and\n * {@link activeDisplayState} that seed `<mj-map-view>`.\n */\n @Input()\n set config(value: MapViewConfig) {\n this._config = value ?? {};\n this.applyConfig();\n }\n get config(): MapViewConfig {\n return this._config;\n }\n\n /**\n * The total number of records the host's query would return — bound to `<mj-map-view>`'s\n * `TotalRecordCount` so the map can convey when markers are a capped subset.\n */\n @Input() totalRecordCount?: number;\n\n /** One-based current page of {@link records} when the host is paginating. Unused by the map view. */\n @Input() page?: number;\n\n /** Page size the host is using. Unused by the map view. */\n @Input() pageSize?: number;\n\n /** Whether the host is currently (re)loading the record set. Unused by the map view today. */\n @Input() isLoading?: boolean;\n\n // ---- IViewRenderer outputs ----\n\n /** Emitted when a marker is clicked — payload is the raw record object (the marker's `.Record`). */\n @Output() recordSelected = new EventEmitter<unknown>();\n\n /**\n * Required by {@link IViewRenderer}; the map view has no distinct \"open\" gesture, so this never\n * emits. Declared so the host's uniform output subscription is satisfied.\n */\n @Output() recordOpened = new EventEmitter<unknown>();\n\n /**\n * Emitted when the user changes the render mode or pans/zooms the map. The host persists the\n * updated {@link MapViewConfig} blob verbatim against the active `ViewTypeID`.\n */\n @Output() configChanged = new EventEmitter<MapViewConfig>();\n\n /**\n * The generic data-access channel. On init this emits `{ loadAll: true }` so the container loads\n * the full record set — maps need every record to plot, not a single page — requested without the\n * container knowing it came from a map.\n */\n @Output() dataRequest = new EventEmitter<ViewDataRequest>();\n\n // ---- Render state (seeded from config) ----\n\n /** The render mode bound to `<mj-map-view>`, derived from {@link config} (defaults to `'point'`). */\n public ActiveRenderMode: MapRenderMode = 'point';\n\n /** @deprecated Use {@link ActiveRenderMode}. */\n public get activeRenderMode(): MapRenderMode {\n return this.ActiveRenderMode;\n }\n /** @deprecated Use {@link ActiveRenderMode}. */\n public set activeRenderMode(value: MapRenderMode) {\n this.ActiveRenderMode = value;\n }\n\n /** The display state bound to `<mj-map-view>`, derived from {@link config} (null when unset). */\n public ActiveDisplayState: Partial<MapDisplayState> | null = null;\n\n /** @deprecated Use {@link ActiveDisplayState}. */\n public get activeDisplayState(): Partial<MapDisplayState> | null {\n return this.ActiveDisplayState;\n }\n /** @deprecated Use {@link ActiveDisplayState}. */\n public set activeDisplayState(value: Partial<MapDisplayState> | null) {\n this.ActiveDisplayState = value;\n }\n\n ngOnInit(): void {\n // Maps need the complete record set, not a single page. Request it through the generic\n // data-access channel — the container honors `{ loadAll: true }` without any map-specific\n // branching. Done after inputs are wired (the host sets inputs via setInput before ngOnInit).\n this.dataRequest.emit({ loadAll: true });\n }\n\n /** Re-derive the map's render mode + display state from the current opaque {@link config}. */\n private applyConfig(): void {\n this.ActiveRenderMode = this._config.renderMode ?? 'point';\n this.ActiveDisplayState = this._config.displayState ?? null;\n }\n\n /**\n * Relay `<mj-map-view>`'s marker click, normalizing to the raw record the host expects (the host\n * builds the composite key itself from the record + entity).\n */\n OnMarkerClick(event: MapMarkerClickEvent): void {\n this.recordSelected.emit(event.Record);\n }\n\n /** @deprecated Use {@link OnMarkerClick}. */\n onMarkerClick(event: MapMarkerClickEvent): void {\n return this.OnMarkerClick(event);\n }\n\n /**\n * Persist a render-mode change into the opaque {@link config} and notify the host. The host\n * stores the blob verbatim; it has no knowledge that `renderMode` means anything map-specific.\n */\n OnRenderModeChange(mode: MapRenderMode): void {\n this._config = { ...this._config, renderMode: mode };\n this.ActiveRenderMode = mode;\n this.configChanged.emit(this._config);\n }\n\n /** @deprecated Use {@link OnRenderModeChange}. */\n onRenderModeChange(mode: MapRenderMode): void {\n return this.OnRenderModeChange(mode);\n }\n\n /**\n * Persist a display-state change (pan / zoom / clustering / choropleth options) into the opaque\n * {@link config} and notify the host. This fires continuously as the user pans/zooms; that's\n * fine — the host debounces persistence of the config blob.\n */\n OnDisplayStateChange(state: MapDisplayState): void {\n this._config = { ...this._config, displayState: state };\n this.ActiveDisplayState = state;\n this.configChanged.emit(this._config);\n }\n\n /** @deprecated Use {@link OnDisplayStateChange}. */\n onDisplayStateChange(state: MapDisplayState): void {\n return this.OnDisplayStateChange(state);\n }\n}\n\n/**\n * Tree-shaking guard. Force-references this renderer so bundlers (ESBuild/Vite) don't drop the\n * component in builds that only mount it dynamically via the ClassFactory/descriptor. Mirrors the\n * Cards and Cluster renderers' load guards; the parent wires this into a barrel/module load path.\n */\nexport function LoadMapViewRenderer(): void {\n // no-op; presence prevents tree-shaking of this component\n}\n"]}
|