Skip to content

Instantly share code, notes, and snippets.

@melamriD365
Last active August 3, 2021 10:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save melamriD365/2191a16c7eae837e81859abeb94ed249 to your computer and use it in GitHub Desktop.
Save melamriD365/2191a16c7eae837e81859abeb94ed249 to your computer and use it in GitHub Desktop.
Integrate the approval center into a model driven app/Dynamics 365 CE
<html>
<head>
<title>Flow JS SDK Sample</title>
<style>
.flowContainer iframe {
border: none;
width: 100%;
height: 100%;
}
</style>
<script type="text/javascript" src="https://alcdn.msauth.net/browser/2.3.0/js/msal-browser.js"></script>
<script src="https://flow.microsoft.com/Content/msflowsdk-1.1.js"></script>
</head>
<body onfocusout="parent.setEmailRange();" style="overflow-wrap: break-word;">
<!--<button id="signOut" onclick="signOut()">SignOut</button>-->
<div id="flowsDiv" class="flowContainer"></div>
<script>
const msalConfig = {
auth: {
clientId: "e7c3a75a-a8ef-4406-b235-eb794e0d2c1c",
authority: "https://login.microsoftonline.com/4b63d104-ee12-4f0a-bb30-7a94a90f3103",
redirectUri: "https://yourOrg.crm4.dynamics.com/WebResources/mea_/Pages/FlowWidgetSPA.html",
},
cache: {
cacheLocation: "sessionStorage",
storeAuthStateInCookie: true
},
flowScopes: ["https://service.flow.microsoft.com//Flows.Read.All", "https://service.flow.microsoft.com//Flows.Manage.All", "https://service.flow.microsoft.com//Approvals.Manage.All", "https://service.flow.microsoft.com//Approvals.Read.All"]
};
var flowAccessToken;
var currentAccount;
const msalInstance = new msal.PublicClientApplication(msalConfig);
msalInstance.handleRedirectPromise().then(handleResponse).catch(err => {
console.error(err);
});
function handleResponse(resp) {
if (resp !== null) {
username = resp.account.username;
currentAccount = resp.account;
acquireTokenPopupAndLoadFlowsWidget();
} else {
const currentAccounts = msalInstance.getAllAccounts();
if (currentAccounts.length == 0) {
signIn();
} else if (currentAccounts.length > 1) {
// Add choose account code here
console.warn("Multiple accounts detected.");
} else if (currentAccounts.length === 1) {
username = currentAccounts[0].username;
console.log(currentAccounts[0]);
currentAccount = currentAccounts[0]
acquireTokenPopupAndLoadFlowsWidget();
}
}
}
function signIn() {
var loginRequest = {
scopes: msalConfig.flowScopes
}
msalInstance.loginPopup(loginRequest).then(handleResponse).catch(error => {
console.error(error);
});
}
function signOut() {
msalInstance.logout();
}
function acquireTokenPopupAndLoadFlowsWidget() {
const accessTokenRequest = {
scopes: msalConfig.flowScopes,
account: currentAccount
}
msalInstance.acquireTokenSilent(accessTokenRequest).then(function (accessToken) {
flowAccessTokenAcquired(accessToken);
}, function (error) {
console.log(error);
if (error.indexOf("consent_required") !== -1 || error.indexOf("interaction_required") !== -1 || error.indexOf("login_required") !== -1) {
msalInstance.acquireTokenPopup(msalConfig.flowScopes).then(function (accessToken) {
flowAccessTokenAcquired(accessToken);
}, function (error) {
console.log(error);
});
}
});
}
function flowAccessTokenAcquired(accessToken) {
flowAccessToken = accessToken.accessToken;
console.log(accessToken.accessToken);
loadApprovalsWidget();
}
function loadApprovalsWidget(accessToken) {
resetWidgetContainer();
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) {
container.removeChild(container.firstChild);
}
}
</script>
</body>
</html>
@Akuma-U1
Copy link

Akuma-U1 commented Aug 3, 2021

Hi!
Did you get the integration of the approval center to work in your application?

I downloaded the sample from this link to integrate the approval center in to a SPA, but the sample is not working. The sample code looks very similar to the code you have here, but with some major differences, such as the environment id and your authority URL. Any tips on how to get these values would be highly appreciated.

@melamriD365
Copy link
Author

@Akuma-U1
Copy link

Akuma-U1 commented Aug 3, 2021

Will check it out. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment