The confirm dialog an agent's Request* tool opened, or null. The user, not the agent, saves or pins.
Why the AI pane has no agent, or null. The pane then shows this instead of the chat.
The agent the AI pane talks to: the Dashboards application's default agent. Null until it resolves.
The name of that agent, which the AI pane shows in its header.
The shell's app context snapshot, as the chat area's AppContext input takes it. The agent reads it.
ReadonlyChatThe application the AI pane's conversations belong to, and whose default agent answers in it.
The AI pane's conversation, from the moment its first message created it.
The ID of the AI pane's conversation.
True until the first message creates the AI pane's conversation.
True while the AI pane shows beside the dashboard.
The files attached to the first message, sent with it.
The first message, which the chat area sends once it has created the conversation. Null after it is sent.
The Config dashboard the editor shows. Null for a Code dashboard, the Data Explorer, or none.
The element that holds a Code dashboard or the Data Explorer.
True while the AI pane takes its largest width (CopilotMaxPct).
ReadonlyCopilotThe largest width of the AI pane, in percent of the tab's width.
ReadonlyCopilotThe smallest width of the AI pane, in percent of the tab's width.
The AI pane's width, in percent of the tab's width.
Protecteddestroy$Technical error details (shown in expandable section)
Error message to display when dashboard fails to load
The dashboard's width while the AI pane is open, in percent of the tab's width.
ProtectednavigationTab ID for query param notification scoping. Set by resource wrappers that render child dashboards, so the child knows which tab it belongs to. If not set, falls back to Data.Configuration.tabId.
If specified, this provider will be used for communication and for all metadata purposes. By default, if not provided, the Metadata and RunView classes are used for this and the default GraphQLDataProvider is used which is connected to the same back-end MJAPI instance as the Metadata and RunView classes. If you want to have this component connect to a different MJAPI back-end, create an instance of a ProviderBase sub-class like GraphQLDataProvider/etc, and configure it as appropriate to connect to the MJAPI back-end you want to use, and then pass it in here.
True while the dialog that asks before a voice session ends with the AI pane is open.
Whether the share dialog is visible
StaticɵdirStaticɵfacTrue when the user may share the dashboard the editor shows.
The environment of the AI pane's conversations and of the artifacts the agent searches: the tab's, else the default.
Use ConfigDashboard.
The Config dashboard the editor shows, or null (a Code dashboard, the Data Explorer, or none).
Use ContainerElement.
Use ErrorDetails.
Use IsEditMode.
True while the editor is in edit mode.
True when the open Config dashboard is pinned to Home.
Returns either the default Metadata provider or the one specified in the Provider property, if it was specified
Wired by the tab container. true means the hosted form just entered edit
mode; the shell PROMOTES (pins) a records preview tab on that edge so the
record is never replaced by the next plain open — VS Code's
promote-on-modify. false is informational; promotion is sticky.
Returns either the default RunQuery provider or the one specified in the Provider property, if it was specified
Returns either the default RunView provider or the one specified in the Provider property, if it was specified
Use ShowShareDialog.
Closes the AI pane. Its conversation stays, so the pane shows it again when it opens. Closing the pane ends a voice session, so while one runs the user confirms first (OnCloseChatConfirmed).
Use CloseShareDialog.
Close the share dialog
ProtectedGetRead current query params from tab configuration. Use in initDashboard() / ngOnInit() to get initial URL state.
The tab title: the dashboard's name from the DashboardEngine cache, else its record name from the server, else the given name. A Data Explorer tab keeps the name of the app it belongs to.
Get this component's tab ID. Checks ParentTabId input first (set by resource wrappers for child dashboards), then falls back to Data.Configuration.tabId.
True when this resource holds in-progress user edits that a silent replacement would destroy.
Since #4345 the PRIMARY protection is promotion: the shell pins a records
preview tab on the ResourceEditModeChangedEvent(true) edge. This read
remains as the fallback the pool predicate consults for resources that
report edit state without raising that event, so such a tab still leaves
the consumption pool while editing.
Default false: most resources are read-only surfaces with nothing to lose. Resources that host an editable form override it.
ProtectedloadA callback method that performs custom clean-up, invoked immediately before a directive, pipe, or service instance is destroyed.
A callback method that is invoked immediately after the default change detector has checked the directive's data-bound properties for the first time, and before any of the view or content children have been checked. It is invoked only once when the directive is instantiated.
ProtectedNotifyAsk the host shell to close/dismiss this resource (typically: close the tab). Called by subclasses that hosted a form that emitted a 'dismiss' navigation event — most often, a brand-new record where the user clicked Discard. The record was never saved, the form is empty, and leaving it open serves no purpose. The tab-container listens for this and closes the workspace tab.
ProtectedNotifyCall this to notify the tab system that the resource's display name has changed. The tab container will update the tab title and browser title accordingly.
ProtectedNotifyTell the host shell the hosted form's edit mode changed. Subclasses that host an editable form call this from the form's EditModeChanged output.
ProtectedNotifyProtectedNotifyTakes the user's answer to the agent's confirm dialog. Does nothing when no dialog is open.
The chat area created the AI pane's conversation for the first message. The pane keeps the conversation and gives the message back to the chat area, which then sends it in that conversation.
Opens the app page that an artifact in the chat asks for. An app the metadata does not name opens the page in the current app.
Opens a record that the chat links to.
The chat area sent the first message. The pane drops it, so the chat area does not send it again.
A voice call started before any message, so the server created the AI pane's conversation. When the
call ends, the pane adopts that conversation, so the chat area shows the call's transcript and the
next message goes to it. The start of the call reports the same conversation without select; the
pane leaves the chat area alone until the call ends, as the Conversations app does.
The user keeps the AI pane open, and the voice session with it.
The user confirmed: the AI pane closes, and the voice session ends with it.
Keeps the widths the user dragged the split to, in this tab and in the user's settings. The AI pane then has that width, not its largest one. Sizes that are not two numbers change nothing.
The editor's parts or layout changed: the tab reports the panels to the agent when they changed.
The editor entered or left edit mode: the tab reports it to the agent.
The user starred or unstarred the dashboard in the editor.
The editor shows the dashboard and its layout is ready. The loading screen goes, the tab takes an edit-mode request (a new dashboard, or a card's Edit action) when it has one, and the agent gets its tools and the dashboard. NavigationService removes the request when the tab takes it, so a later load of the tab opens for viewing.
The editor could not show the dashboard: the tab shows why, and the loading screen goes.
The dashboard's saved name changed, by a save here or elsewhere. The tab takes the name as its title and keeps its dashboard ID: ResourceRecordSaved would rewrite the record ID in a form the tab configuration does not have, and the tab would reload on each Save.
A part of the dashboard asked to open something: a record, another dashboard, a query.
The editor rebuilt the saved layout after a save elsewhere: the rebuild reports nothing to the agent.
ProtectedOnCalled by the framework when query params change from an external source (browser back/forward, deep link navigation). Override in subclasses to react to query param changes.
The new query params from the URL
'popstate' for back/forward, 'deeplink' for external URL entry
Handle share dialog result. After a save the editor reads the user's permissions again, since sharing can change them.
ProtectedonA cache reattach moves this wrapper to another tab without recreating the dashboard inside it. A child resource component (a Code dashboard, the Data Explorer) has its own tab stamp, taken when we created it, and it has to move too. Without this the dashboard keeps reading and writing the params of the tab it was born in, from inside a tab it no longer belongs to. The editor has no tab of its own. The new tab can hold an edit-mode request (a card's Edit action reopens a closed tab this way), so the tab takes it here, where no load will.
Use OpenShareDialog.
Open the share dialog for this dashboard
Pins the open dashboard to Home as a card, then adds a thumbnail of it in the background.
Re-home this component to a different tab (cache reattach across tab ids). Replaces the reactive param subscription with one bound to the new tab and resets the duplicate-delivery key so the new tab's CURRENT params apply as a fresh mount would — the replay-on-subscribe delivers them immediately.
ProtectedRefreshMarks this component's view (and its ancestors) as needing change detection and schedules a tick — the reliable way for a resource component to re-render after updating state from async work (RunView/RunQuery continuations, timers, websocket pushes, RxJS subscriptions).
WHY THIS EXISTS: the Explorer shell hosts resource components dynamically — createComponent()
ApplicationRef.attachView() — because tab content mounts into Golden Layout / cached DOM
containers, not into an Angular template. Since Angular 18's change-detection scheduler
rework (Explorer is on Angular 21), ApplicationRef.tick() only refreshes attached views
that are FLAGGED dirty; a root-level attached view whose component mutates plain fields from
an async continuation is never flagged, so the view silently never re-renders — even though
the component uses default (non-OnPush) change detection (issue #3106).The framework calls this automatically from NotifyLoadStarted() / NotifyLoadComplete(), so the standard load lifecycle re-renders without any subclass action. Call it yourself after any LATER async state change that must reach the DOM outside those signals.
ProtectedrehomeRe-homes a child this component created to tabId.
The ParentTabId stamp is cleared FIRST and deliberately: getTabId() prefers it over the
rebound id, so leaving the old stamp in place would make the child's own RebindTabId a
no-op — it early-returns when getTabId() already matches — and the child would keep
answering with the tab it was born in. Clearing it lets the rebind be the authority, and the
child re-delivers the NEW tab's current params exactly as a fresh mount would.
ProtectedResourceOpens the AI pane with the widths the user saved, or closes it as CloseChat does.
Gives the AI pane its largest width, or its own width again.
ProtectedUpdatePush query param changes to the URL. Creates a browser history entry. Safe to call during OnQueryParamsChanged — auto-suppressed to prevent loops.
The write is ALWAYS scoped to this component's own tab. A component that cannot identify its tab does not write at all — see the guard below.
Dashboard Resource Wrapper - displays a single dashboard in a tab Extends BaseResourceComponent to work with the resource type system Dynamically routes between code-based and config-based dashboards based on dashboard type: a Config dashboard shows in the shared dashboard editor (
mj-dashboard-editor) with the AI pane beside it, and a Code dashboard or the Data Explorer shows in the tab's own container.