Last active
January 30, 2019 04:36
-
-
Save paulclarkaranz/d91374714dff731834d86553fef187f8 to your computer and use it in GitHub Desktop.
Install in Tampermonkey
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Dynamics CRM Link To Record | |
// @namespace seequent.com | |
// @version 0.2 | |
// @description Add a copy link to clipboard option to the three dot menu below the ribbon. | |
// @author [email protected] | |
// @match https://*.dynamics.com/* | |
// @grant GM_log | |
// @run-at document-idle | |
// ==/UserScript== | |
var no = function(thing) { return typeof thing === 'undefined' ? true : thing == null ? true : false;}; | |
var main = function() { | |
'use strict'; | |
var observer = new MutationObserver(function(mutations) { | |
for (let mindx = 0; mindx < mutations.length; mindx++) { | |
let mutation = mutations[mindx] | |
if (mutation.target.id === 'formselectorcontainer') { | |
addButtons(mutation.target); | |
//observer.disconnect(); | |
return; | |
} | |
for (var i = 0; i < mutation.addedNodes.length; i++) { | |
let el = mutation.target.querySelector('#formselectorcontainer'); | |
if (!no(el)) { | |
addButtons(el); | |
//observer.disconnect(); | |
return; | |
} | |
} | |
} | |
}); | |
observer.observe(document.body, { childList: true, subtree: true }); | |
}; | |
var addButton = function(text, id, parent, func) { | |
var linkEl = document.createElement('a'); | |
linkEl.innerText = text; | |
linkEl.id = id; | |
linkEl.style = "float: right; padding-left: 1em;" | |
linkEl.addEventListener('click', func); | |
parent.appendChild(linkEl); | |
return linkEl; | |
} | |
var addClipboardElement = function(id, parent) { | |
var copyEl = document.createElement('textarea'); | |
copyEl.style = "position: absolute; left: -10000px; top: -10000px;"; | |
copyEl.id = id; | |
parent.appendChild(copyEl); | |
return copyEl; | |
} | |
var copyToClipboard = function(id) { | |
var copyTextarea = document.querySelector(id); | |
copyTextarea.focus(); | |
copyTextarea.select(); | |
try { | |
var successful = document.execCommand('copy'); | |
var msg = successful ? 'successful' : 'unsuccessful'; | |
console.log('Copying text command was ' + msg); | |
} catch (err) { | |
console.log('Oops, unable to copy'); | |
} | |
} | |
var addCopyButton = function(parent) { | |
var copyElId = "gm-entity-link"; | |
if (parent.querySelector(`#${copyElId}`)) return; | |
var linky = `https://${document.location.host}/main.aspx` + | |
`?pagetype=entityrecord` + | |
`&etn=${Xrm.Page.data.entity.getEntityName()}` + | |
`&id=${Xrm.Page.data.entity.getId()}`; | |
var linkEl = addButton("Copy Link", copyElId+"-btn", parent, function() { | |
copyToClipboard('#'+copyElId); | |
}); | |
var copyEl = addClipboardElement(copyElId, linkEl); | |
copyEl.textContent = linky; | |
GM_log(`${document.location.href}: ${linky}`); | |
} | |
function getEntity(clientUrl, segment, entityId, callback) { | |
entityId = entityId.replace(/[{}]/g, '') | |
var req = new XMLHttpRequest() | |
req.open('GET', clientUrl + '/api/data/v8.2/' + segment + '(' + entityId + ')/', true) | |
req.setRequestHeader('OData-MaxVersion', '4.0') | |
req.setRequestHeader('OData-Version', '4.0') | |
req.setRequestHeader('Accept', 'application/json') | |
req.setRequestHeader('Content-Type', 'application/json; charset=utf-8') | |
req.setRequestHeader('Prefer', 'odata.include-annotations="*"') | |
req.onreadystatechange = function () { | |
if (this.readyState === 4) { | |
req.onreadystatechange = null | |
if (this.status === 200) { | |
var result = JSON.parse(this.response) | |
callback(result, null) | |
} else { | |
callback(null, this.statusText) | |
} | |
} | |
} | |
req.send() | |
} | |
var addAttendeesButton = function(parent) { | |
if (Xrm.Page.data.entity.getEntityName() !== "new_training") | |
return; | |
var copyElId = "gm-attendee-link"; | |
if (parent.querySelector(`#${copyElId}`)) return; | |
var linkEl = addButton("Copy Attendees", copyElId+"-btn", parent, function() { | |
copyToClipboard('#'+copyElId); | |
}); | |
var copyEl = addClipboardElement(copyElId, linkEl); | |
copyEl.textContent = "working..."; | |
getAttendeesText(copyEl) | |
} | |
var getAttendeesText = function(copyEl) { | |
let jobNumber = ''+Xrm.Page.data.entity.attributes.get("new_jobnumber").getValue(); | |
let attendees = []; | |
for (let i=0; i<20; i++) { | |
let suffix = i < 9 ? '0' : ''; | |
let lookup = Xrm.Page.data.entity.attributes.get(`new_attendee${suffix}${i+1}`).getValue(); | |
if (!lookup || lookup.length !== 1) | |
break; | |
attendees[i] = { | |
'id': lookup[0].id.replace(/[{}]/g, ''), | |
}; | |
} | |
let copyToCSV = function() { | |
var copyString = "Job Number,Fullname,Email\n"; | |
for (let i=0; i<attendees.length; i++) { | |
copyString += `${jobNumber},${attendees[i].fullname},${attendees[i].emailaddress1}\n` | |
} | |
copyEl.textContent = copyString; | |
} | |
for (let i=0; i<attendees.length; i++) { | |
let baseUrl = Xrm.Page.context.getClientUrl(); | |
getEntity(baseUrl, 'contacts', attendees[i].id, function(data, error) { | |
if (!data || error) { | |
attendees[i]['fullname'] = "ERROR"; | |
} else { | |
attendees[i] = data; | |
} | |
if (attendees.filter((x) => { return typeof x.fullname === 'undefined' }).length > 0) | |
return; | |
copyToCSV(); | |
}); | |
} | |
} | |
var addButtons = function(title) { | |
if (no(Xrm)) { | |
//GM_log(`no Xrm: ${document.location.href}`); | |
return; | |
} | |
if (no(Xrm.Page)) { | |
//GM_log(`no Xrm.Page: ${document.location.href}`); | |
return; | |
} | |
if (no(Xrm.Page.data)) { | |
//GM_log(`no Xrm.Page.data: ${document.location.href}`); | |
return; | |
} | |
if (no(Xrm.Page.data.entity)) { | |
//GM_log(`no Xrm.Page.data.entity: ${document.location.href}`); | |
return; | |
} | |
//var title = document.getElementById('formselectorcontainer'); | |
if (no(title)) return; | |
addCopyButton(title); | |
addAttendeesButton(title); | |
}; | |
if (document.readyState === "loading") { | |
document.addEventListener("DOMContentLoaded", () => main); | |
} else { | |
main(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment