Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added docs/images/working-set-check.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions docs/native-embedding-architecture/apply-filter.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,25 @@ To apply selections on an Attribute/Metric selector inside a page, you can use t
}
```

##### Value parameter filter

To apply values for a value parameter filter, you can use the following input:

```js
try {
await mstrDossier.applyFilter({
key: "W76",
currentSelection: {
value: "Profit",
},
});
} catch (error) {
// Your own error handling code
}
```

Then the value parameter's value changes, which affects all the visualizations that use the related value parameter.

#### Visualizations used as filters

- Select attribute elements of the visualization
Expand Down
35 changes: 23 additions & 12 deletions docs/native-embedding-architecture/mstr-environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,24 @@ The instance of this class is the object returned from the `microstrategy.embedd

#### Function

`async loadDossier(props)`
`async loadDossier(props, options)`

#### Input Parameters

| Parameter Name | Data Type | Description | Is Required |
| ------------------- | --------- | -------------------------------------------------------------------------------------------------------- | ----------- |
| props.projectId | String | The project ID, which must be a GUID. | true |
| props.objectId | String | The dashboard ID, which must be valid. If the ID is a document, report, or bot ID, an error is reported. | true |
| props.instanceId | String | The dashboard instance ID, if it already exists. | false |
| props.applicationId | String | the dashboard application ID, if not specified, the default application will be used | false |
| Parameter Name | Data Type | Description | Is Required |
| ------------------------------ | --------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------- |
| props.projectId | String | The project ID, which must be a GUID. | true |
| props.objectId | String | The dashboard ID, which must be valid. If the ID is a document, report, or bot ID, an error is reported. | true |
| props.instanceId | String | The dashboard instance ID, if it already exists. | false |
| props.bookmarkId | String | The ID of a bookmark that is owned by this dossier, if it is provided. | false |
| props.applicationId | String | the dashboard application ID, if not specified, the default application will be used | false |
| options.forceCreateNewInstance | Boolean | Whether to create a new dossier instance forcefully if the other MstrDossier object is already created based on this dossier | false |

The `projectId` + `objectId` is used as the dashboard identifier. If the function is called twice with the same parameter, the same `MstrDossier` object is returned in the callback.
The `projectId` + `objectId` is used as the dashboard identifier.
If the function is called twice with the same the dashboard identifier:

- If `options.forceCreateNewInstance` is not set or false, the same `MstrDossier` object is returned in the callback.
- If `options.forceCreateNewInstance` is true, a new `MstrDossier` object that holds a new instance is returned in the callback.

#### Response

Expand All @@ -41,10 +47,15 @@ try {
},
});
// Begin here
const dossier = await environment.loadDossier({
projectId: "B19DEDCC11D4E0EFC000EB9495D0F44F",
objectId: "D9AB379D11EC92C1D9DC0080EFD415BB",
});
const dossier = await environment.loadDossier(
{
projectId: "B19DEDCC11D4E0EFC000EB9495D0F44F",
objectId: "D9AB379D11EC92C1D9DC0080EFD415BB",
},
{
forceCreateNewInstance: true,
}
);
} catch (error) {
// Your own error handling logic
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
---
title: Create multiple instances for one dashboard
description: The user can use Native Embedding SDK API to create multiple instances for one dashboard.
---

<Available since="Strategy ONE December 2025"/>

### One dashboard owns only one instance

In the normal case, the Native Embedding SDK only creates one `MstrDossier` object for one dashboard object. That is, if you write code like this:

```js
const mstrEnvironment = await microstrategy.embeddingComponent.environments.create({
serverUrl: configs.serverUrl,
getAuthToken,
});
const mstrDossierA = await mstrEnvironment.loadDossier({
projectId: configs.projectId,
objectId: configs.objectId,
});
// mstrDossierB === mstrDossierA
const mstrDossierB = await mstrEnvironment.loadDossier({
projectId: configs.projectId,
objectId: configs.objectId,
});
```

Then `mstrDossierB` will be the same as `mstrDossierA`. They are exactly the same object and share the same dashboard instance. For one dashboard instance, if it renders the visualizations from different pages, like:

```js
await mstrDossierA.refresh([
{
key: "K52", // Page 1, viz 1
container: document.getElementById("container1"),
},
{
key: "W63", // Page 1, viz 2
container: document.getElementById("container2"),
},
{
key: "W64", // Page 2, viz 3
container: document.getElementById("container3"),
},
{
key: "R85", // Page 2, viz 4
container: document.getElementById("container4"),
},
]);
```

The dashboard will first fetch the page 1 data, render the visualization 1 and 2, and then fetch the page 2 data and render visualization 3 and 4.

This brings a problem: If the user renders the visualizations from many different pages, the visualizations on different pages will render sequentially, which downgrades the performance.

### One dashboard owns only multiple instances

In Strategy ONE December 2025, we support one dossier to have multiple instances, which can render the visualizations from different pages in parallel, and accelerate the rendering speed. The point is, for each page, we can create a `MstrDossier` object that owns an independent dashboard instance, and these instances can be created and fetched data simultaneously.

We need to use a new param `forceCreateNewInstance` in the [loadDossier()](./mstr-environment#the-load-dashboard-api) function to do this:

```js
const environment = await microstrategy.embeddingComponent.environments.create({
serverUrl,
getAuthToken,
});

async function refreshDossier(vizAndContainers) {
const mstrDossier = await environment.loadDossier(
{
projectId,
objectId,
},
{
forceCreateNewInstance: true,
}
);
await mstrDossier.refresh(vizAndContainers);
return mstrDossier;
}

// Here mstrDossierA !== mstrDossierB
const [mstrDossierA, mstrDossierB] = await Promise.all([
refreshDossier([
{
key: "K52", // Page 1, viz 1
container: document.getElementById("container1"),
},
{
key: "W63", // Page 1, viz 2
container: document.getElementById("container2"),
},
]),
refreshDossier([
{
key: "W64", // Page 2, viz 1
container: document.getElementById("container3"),
},
{
key: "R85", // Page 2, viz 2
container: document.getElementById("container4"),
},
]),
]);
```

Here `mstrDossierA !== mstrDossierB`. The 2 `refreshDossier()` functions can be executed in parallel, which improves the rendering speed.

### Change the working set limit

On the Strategy iServer, the dashboard instance count limit for each user session is 10 by default. So if the embedding SDK user creates too many dashboard instances on a web page, the former instances might be expired or deleted.

To solve this problem, the user can change the working set limit to a larger number. This could be done by assigning this limit by `workingSet` parameter in the [login API](https://demo.microstrategy.com/MicroStrategyLibrary/api-docs/index.html#/Authentication/postLogin) like:

```js
const mstrEnvironment = await microstrategy.embeddingComponent.environments.create({
serverUrl: configs.serverUrl,
getAuthToken: () => {
const options = {
method: "POST",
credentials: "include",
mode: "cors",
headers: { "content-type": "application/json" },
body: JSON.stringify({
loginMode: 1,
username: "XXX",
password: "YYY",
// Enlarge the working set limit
workingSet: 50,
}),
};
return fetch(`${configs.serverUrl}/api/auth/login`, options)
.then((response) => {
if (response.ok) {
console.log("A new standard login session has been created successfully, logging in");
return response.headers.get("x-mstr-authtoken");
}
return response.json().then((json) => console.log(json));
})
.catch((error) => console.error("Failed Standard Login with error:", error));
},
});
```

For the other type of authentication methods, like OIDC, you can set the `workingSet` number in the URL query parameter.

### Verify whether the working set limit change succeeds

If you want to check whether your working set limit change is successful, you can open the dev tool and check the GET /api/sessions REST API result:
![workingSet](../images/working-set-check.png)
If the `workingSet` number in the REST API response is the same as the number you set, you setting works in the current session.
Loading