Users can
concurrently work on the same record in Dynamics CRM and simultaneously make
changes. This can cause some changes to be overwritten or missed. The users also
have no way of knowing who else is working on a record, when they open it. To
address these issue, we will use PubNub as a secure message transportation
platform to keep users notified of any changes to record that they are currently
viewing.
1.) Signup for a free account at http://www.pubnub.com.
For this proof of concept, we can use the free sandbox account.
2.) Login to the admin portal and note down the keys.
3.) We will be using requirejs
to load the dependent scripts. There are two scripts to load: the form script
and the pubnub script. Create new web resources to store these scripts.
4.) We will be using the main.js to start the loading process. This is the script that has to be added to the form along with requirejs.
4.) We will be using the main.js to start the loading process. This is the script that has to be added to the form along with requirejs.
Below is the sourcecode for
main.js, the loading script. We are loading pubnub from CDN. The local
webresource is only used for fallback, if there is any issue with the CDN.
///(function () { var webResourceVersionNumber = ''; //get the url for the script, so that we can extract the guid to prefix [].forEach.call(document.querySelectorAll('script'), function (element) { if (element.src.indexOf('main.js') > -1) { webResourceVersionNumber = element.src; } }); webResourceVersionNumber = webResourceVersionNumber.replace(Xrm.Page.context.getClientUrl(), '').substr(1, 24); var defaultConfig = { //could also use undocumented WEB_RESOURCE_ORG_VERSION_NUMBER baseUrl: '/' + webResourceVersionNumber + '/WebResources/scripts_/form', shim: { 'pubnub': { exports: 'PUBNUB' } }, deps: ['pubnub', 'form_script'], callback: function () { console.log('callback before requirejs has been loaded'); }, paths: { pubnub: ['https://cdn.pubnub.com/pubnub.min', '../library/pubnub.min'] }, onError: function (err) { console.log(err.requireType); if (err.requireType === 'timeout') { console.log('modules: ' + err.requireModules); } throw err; } }; if (!window['require']) { window['require'] = defaultConfig; } else { defaultConfig.callback = function () { console.log('callback after requirejs has been loaded'); }; require.config(defaultConfig); } })();
Below is the sourcecode for
form_script.js.Here is what the form displays when another user has
opened the same record.
///define(['pubnub'], function(PUBNUB) { var pubnub = PUBNUB.secure({ publish_key: '<PUBLISH KEY> ', subscribe_key: '<SUBSCRIBE KEY> ', ssl: true, cipher_key: '<CIPHER KEY> ' }), pageContext = Xrm.Page.context, entity = Xrm.Page.data.entity, userName = pageContext.getUserName(), entityName = entity.getEntityName(), entityId = entity.getId(), userId = pageContext.getUserId(), FormState = { OPEN: 'opened', CLOSE: 'updated and closed', UPDATE: 'updated' }, FormSaveType = { SAVE: 1, SAVEANDCLOSE: 2, SAVEANDNEW: 59, AUTOSAVE: 70 }, FormType = { CREATE: 1, UPDATE: 2, READONLY: 3, DISABLED: 4, QUICKCREATE: 5, BULKEDIT: 6, READOPTIMISED: 11 }; if (Xrm.Page.ui.getFormType() === FormType.UPDATE) { pubnub.subscribe({ channel: "form_events", message: function (m) { if (m.userId !== userId) { var now = new Date(); var message = now.toLocaleString('en-GB') + ': ' + m.userName + ' ' + m.operation + ' this record'; Xrm.Page.ui.setFormNotification(message, 'INFO'); if (m.operation === FormState.UPDATE) { Xrm.Utility.confirmDialog('This form has been updated by ' + m.userName + ' at ' + now.toLocaleString('en-GB') + '. Do you want to reload the form to see the latest changes?', function() { Xrm.Page.data.refresh(false); }); } } } }); pubnub.publish({ channel: "form_events", message: { userName: userName, userId: userId, entityName: entityName, entityId: entityId, operation: FormState.OPEN, uuid: notifications.uuid } }); Xrm.Page.data.entity.addOnSave(function onSave(context) { pubnub.publish({ channel: "form_events", message: { userName: userName, userId: userId, entityName: entityName, entityId: entityId, operation: FormState.UPDATE, uuid: notifications.uuid } }); }); } });
Here is what the form displays when another user has opened the same record.
Here is what that form displays when another user has made changes and saved the record.
No comments:
Post a Comment