Integrate the approval center into a model driven app/Dynamics 365 CE

Power Automate provides a standard solution to manage approvals in a Dataverse environment. Approval requests can be easily generated from cloud flows. Users have the ability to view and respond to approval requests from email, teams or the approval center which is accessible from the power automate website only.

Today, I will present a way to respond to approvals from a model driven app directly. Also, the approval requester will be able to cancel his request from the MDA in one click.

The approver can approve, reject, or assign the approval to a new approver in the organization:

The approval requestor can cancel his or her own approval request:

To implement this, we just need to use the widgets provided by the MsFlow js SDK. Yes, there is an SDK that allows us to generate some cool widgets. The approval center is one of them. Please refer to the documentation.

As the image above shows, I managed to integrate the approval center that is accessible from the power automate web app into a model driven app dashboard. Practically, my dashboard contains an HTML web resource. On this web page, I use the msflow js sdk to display my widget. This is the source code used

<title>Flow JS SDK Sample</title>
.flowContainer iframe {
border: none;
width: 100%;
height: 100%;
<script type="text/javascript" src=""></script>
<script src=""></script>
<body onfocusout="parent.setEmailRange();" style="overflow-wrap: break-word;">
<!–<button id="signOut" onclick="signOut()">SignOut</button>–>
<div id="flowsDiv" class="flowContainer"></div>
const msalConfig = {
auth: {
clientId: "e7c3a75a-a8ef-4406-b235-eb794e0d2c1c",
authority: ";,
redirectUri: ";,
cache: {
cacheLocation: "sessionStorage",
storeAuthStateInCookie: true
flowScopes: [";, ";, ";, ";]
var flowAccessToken;
var currentAccount;
const msalInstance = new msal.PublicClientApplication(msalConfig);
msalInstance.handleRedirectPromise().then(handleResponse).catch(err => {
function handleResponse(resp) {
if (resp !== null) {
username = resp.account.username;
currentAccount = resp.account;
} else {
const currentAccounts = msalInstance.getAllAccounts();
if (currentAccounts.length == 0) {
} else if (currentAccounts.length > 1) {
// Add choose account code here
console.warn("Multiple accounts detected.");
} else if (currentAccounts.length === 1) {
username = currentAccounts[0].username;
currentAccount = currentAccounts[0]
function signIn() {
var loginRequest = {
scopes: msalConfig.flowScopes
msalInstance.loginPopup(loginRequest).then(handleResponse).catch(error => {
function signOut() {
function acquireTokenPopupAndLoadFlowsWidget() {
const accessTokenRequest = {
scopes: msalConfig.flowScopes,
account: currentAccount
msalInstance.acquireTokenSilent(accessTokenRequest).then(function (accessToken) {
}, function (error) {
if (error.indexOf("consent_required") !== 1 || error.indexOf("interaction_required") !== 1 || error.indexOf("login_required") !== 1) {
msalInstance.acquireTokenPopup(msalConfig.flowScopes).then(function (accessToken) {
}, function (error) {
function flowAccessTokenAcquired(accessToken) {
flowAccessToken = accessToken.accessToken;
function loadApprovalsWidget(accessToken) {
var sdk = new window.MsFlowSdk({ hostName: window.location.origin, locale: 'en-us', hostId: window.WellKnownHostIds.WIDGETTEST });
var widget = sdk.renderWidget('approvalCenter', {
container: 'flowsDiv',
enableRegionalPortal: true,
enableOnBehalfOfTokens: true,
environmentId: '43391dad-6733-4eff-9765-027bedf0b244',
approvalCenterSettings: {
autoNavigateToDetails: true,
hideFlowCreation: true,
hideInfoPaneCloseButton: true,
hideLink: true,
showSimpleEmptyPage: true
widget.listen("GET_ACCESS_TOKEN", function (requestParam, widgetDoneCallback) {
widgetDoneCallback(null, {
token: flowAccessToken
widget.listen("WIDGET_READY", function () {
console.log("The flow widget is now ready.");
function resetWidgetContainer() {
var container = document.getElementById("flowsDiv");
while (container.firstChild) {

The Azure Active Directory App configuration:

Hope it helps…

9 thoughts on “Integrate the approval center into a model driven app/Dynamics 365 CE

  1. Hi Mehdi!

    Where did you get the “EnvironmentID” from listed at line: 106 in the code?
    As well as the authority id at the end of the URL at line: 23?

    Thanks for the help!


    1. Hi Johan,

      You will find your EnvironmentID by going through the following steps:

      Navigate to, then choose your environment. Now your URL will look like this:{EnvironmentID}/home

      the authority ID at the end of the URL at line: 23 is your tenantId


  2. Hi Mehdi
    I followed your instructions and it works very well for me in powerapps from the browser on my computer, but when I enter from the powerapps application on my phone, the widget does not seem to load, at least everything is blank, I am not sure if it has to do with authentication, it could be because not being a browser can not open the authentication popup
    Could you tell me if it is normal that I do not load in powerapps from the phone? or I may have done something wrong, thank you very much for the excellent article.
    Kind regards,


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s