Dashboards
Dashboards are custom HTML pages defined by the application and can reference typical web content such as JavaScript and CSS files. These custom HTML pages may be shown all the time in a custom tab, shown in a tab which is shown or hidden depending upon user interaction, or shown via code as a custom popup dialog. Each dashboard, when shown, is rendered within an <iframe />
element.
Dashboards must be defined within the application manifest and given a unique ID. In the example below the ID of the dashboard is defined to be my-dashboard
, and the HTML for the dashboard is contained within index.html
:
<dashboards>
<dashboard id="my-dashboard">
<content>index.html</content>
</dashboard>
</dashboards>
Dashboard files are standard HTML files which will be rendered by the browser.
Bootstrapping the Dashboard
The Dashboard HTML file (e.g. index.html
; the actual file name can be any valid filename) typically must contain code that reacts when the dashboard is shown, to gather data to render from either the supplied parameters (CustomData
), or from elsewhere in the UI or vault.
When the dashboard is shown and ready to use, the framework will automatically locate and execute a function called OnNewDashboard
. There must be only one function in the dashboard called this, but the function can be held within the HTML file directly or within a referenced JavaScript file. This method will be passed a single argument - named below as newDashboard
- which is of type IDashboard:
// Dashboard bootstrap function
function OnNewDashboard(newDashboard) {
// TODO: React when the dashboard is shown.
}
Boostrapping the Dashboard in React Application
In a React + TypeScript application you can bootstrap the Dashboard using following pattern.
(window as any).OnNewDashboard = (newDashboard: IDashboard) => {
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<App dashboard={newDashboard} />
</React.StrictMode>
);
};
Showing a dashboard from within your application
Simply declaring a dashboard does not show it within the user interface. Instead: the dashboard must be rendered either by creating a new tab and rendering it within that tab, or by showing the dashboard within a popup dialog.
Open a new Dashboard using the Tab
Opening a new tab requires a Dashboard ID, which is defined in you Application Manifest -file. This will create a new instance of Dashboard which lives inside IFRAME as long as the Tab is finally removed.
Opening too many tabs can affect your application performance.
Open a Popup Dashboard
Opening the popup dashboard is done using the ShowPopupDashboard
method, which accepts also third parameter, which is the
title of the Dialog.
shellFrame.ShowPopupDashboard(
'my-dashboard',
{
message: 'Some Custom Data Here',
},
'Dashboard Title',
)
Passing data to and from dashboards
Passing Custom data to the Dashboard
The Dashboard can also be passed a custom data, which is visible in the Dashboards CustomData
property.
myTab.ShowDashboard('my-dashboard', {
msg: 'Sample Message to the Dashboard',
})
myTab.Select()
The Dashboard which was opened using ShowDashboard
can retrieve the data from CustomData
property.
// Dashboard bootstrap function
function OnNewDashboard(newDashboard) {
const data = newDashboard.CustomData // has the data which is passed in ShowDashboard second param
}
The Custom Data can include only data which can be serialized using the Structured Cloning Algorithm. This means that you can not pass callback functions inside that data to send responses from the new Dashboard back to the opener. However, you can send custom command ID values and custom commands can be given a data parameter.
Passing updated data to the Dashboard
It is also possible to pass updated data to the dashboard using the IDashboard.UpdateCustomData
method. There is a detailed example of how to do this on the UpdateCustomData method page:
// Create the tab and show some default custom data.
const myTab = await shellFrame.RightPane.AddTab("my-test-tab", "My Dashboard", "_last");
const myDashboard = await myTab.ShowDashboard("mydb",
{
timeNow: "INITIAL_DATA, 5 second refresh interval!"
});
// Every 5 seconds call the UpdateCustomData method.
setInterval( () => {
myDashboard.UpdateCustomData({
timeNow: ( new Date() ).toISOString() // Pass the current time.
})
}, 5000)
Passing Custom data from the Dashboard to the opener
You can create a custom command which is used to send data back to the opener. As the command is not added to any menu structure it is not visible, but can be executed from code.
From the opener:
const callbackCommandId = await shellFrame.Commands.CreateCustomCommand(name)
// Listen for the custom commands.
shellFrame.Commands.Events.Register(
// Listen for the CustomCommand events.
MFiles.Event.CustomCommand,
// Each command has ID and optional data provided with it.
(commandId, data) => {
// Short-circuit if this is called for a command we don't care about.
if (commandId !== callbackCommandId) return
// Show something from the data.
alert('The name is: ' + data.name)
},
)
myTab.ShowDashboard('my-dashboard', {
callbackId: callbackCommandId,
})
myTab.Select()
From the dashboard we can then return data back to the caller using ExecuteCommand
// Dashboard bootstrap function
function OnNewDashboard( newDashboard ) {
// Get the command ID
const commandId = newDashboard.CustomData.callbackId;
// Send data back to the caller, in this case object { name: "ExampleObject" }
await shellFrame.Commands.ExecuteCommand(commandId, {
name: "Example Object"
});
}
Closing the Dashboard
You can close the Dashboard using the associated Window
object which has Close
method
newDashboard.Window.Close()