Skip to content

Instantly share code, notes, and snippets.

@johandanforth
Last active February 23, 2021 21:10
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 johandanforth/4a16dd5e47b06ded78cbe510cde58243 to your computer and use it in GitHub Desktop.
Save johandanforth/4a16dd5e47b06ded78cbe510cde58243 to your computer and use it in GitHub Desktop.
name: Visa workitem (bootstrap 4)
description: ''
host: OUTLOOK
api_set: {}
script:
content: "\"use strict\";\n\nvar itemId = null;\nvar item = null;\n\n(function() {\n Office.onReady(function() {\n // Office is ready\n $(document).ready(function() {\n enableTabs();\n run();\n });\n });\n})();\n\nfunction enableTabs() {}\n\n//TODO: get projects - show project name\n\nasync function updateView(workItem) {\n let d1 = loadData(item.subject);\n let d2 = loadData(item.start);\n let d3 = loadData(item.end);\n\n const [subject, start, end] = await Promise.all([d1, d2, d3]);\n\n if (workItem.Name === null || workItem.Name === \"\") {\n console.log(1);\n console.log(subject.toString());\n $(\"#Name\").val(subject.toString());\n } else $(\"#Name\").val(workItem.Name);\n $(\"#Comment\").text(workItem.Comment);\n $(\"#ProjectId\").text(workItem.ProjectId);\n $(\"#InvoiceTime\").attr(\"checked\", workItem.InvoiceTime === \"true\" ? \"checked\" : \"\");\n}\n\nfunction loadData(prop) {\n return new Promise((resolve, reject) => {\n prop.getAsync((res) => {\n resolve(res.value);\n });\n });\n}\n\nfunction run() {\n item = Office.context.mailbox.item;\n\n item.getItemIdAsync((result) => {\n itemId = result.value;\n\n Office.context.mailbox.getCallbackTokenAsync({ isRest: true }, function(asyncResult) {\n getCurrentItem(asyncResult.value);\n });\n });\n}\n\nfunction getCurrentItem(accessToken) {\n var itemId = getItemRestId();\n var getMessageUrl = Office.context.mailbox.restUrl + \"/v2.0/me/events/\" + itemId + \"?expand=attachments\";\n console.log(\"Calling \" + Office.context.mailbox.restUrl + \"/v2.0/me/events/\");\n $.ajax({\n url: getMessageUrl,\n dataType: \"json\",\n headers: { Authorization: \"Bearer \" + accessToken }\n })\n .done(function(item) {\n if (item.Attachments.length > 0) {\n let att = item.Attachments[0];\n var raw = window.atob(att.ContentBytes);\n //console.log(raw);\n let dom = new DOMParser().parseFromString(raw, \"text/xml\");\n let json = xml2json(dom, \"\");\n let workitem = JSON.parse(json);\n console.log(workitem.WorkItem);\n updateView(workitem.WorkItem);\n }\n })\n .fail(function(error) {\n console.error(error);\n });\n}\n\nfunction getItemRestId() {\n if (Office.context.mailbox.diagnostics.hostName === \"OutlookIOS\") {\n // itemId is already REST-formatted.\n return itemId;\n //return Office.context.mailbox.item.itemId;\n } else {\n // Convert to an item ID for API v2.0.\n return Office.context.mailbox.convertToRestId(\n itemId,\n //Office.context.mailbox.item.itemId,\n Office.MailboxEnums.RestVersion.v2_0\n );\n }\n}\n\n// function getAttachment(itemId, attachmentId, accessToken) {\n// var getMessageUrl = Office.context.mailbox.restUrl + \"/v2.0/me/events/\" + itemId + \"/attachments/\" + attachmentId;\n\n// $.ajax({\n// url: getMessageUrl,\n// dataType: \"json\",\n// headers: { Authorization: \"Bearer \" + accessToken }\n// })\n// .done(function(item) {\n// console.log(item);\n// })\n// .fail(function(error) {\n// console.error(error);\n// });\n// }\n\n/*\tThis work is licensed under Creative Commons GNU LGPL License.\n\n\tLicense: http://creativecommons.org/licenses/LGPL/2.1/\n Version: 0.9\n\tAuthor: Stefan Goessner/2006\n\tWeb: http://goessner.net/ \n*/\nfunction xml2json(xml, tab) {\n var X = {\n toObj: function(xml) {\n var o = {};\n if (xml.nodeType == 1) {\n // element node ..\n if (xml.attributes.length)\n // element with attributes ..\n for (var i = 0; i < xml.attributes.length; i++)\n o[\"@\" + xml.attributes[i].nodeName] = (xml.attributes[i].nodeValue || \"\").toString();\n if (xml.firstChild) {\n // element has child nodes ..\n var textChild = 0,\n cdataChild = 0,\n hasElementChild = false;\n for (var n = xml.firstChild; n; n = n.nextSibling) {\n if (n.nodeType == 1) hasElementChild = true;\n else if (n.nodeType == 3 && n.nodeValue.match(/[^ \\f\\n\\r\\t\\v]/)) textChild++;\n // non-whitespace text\n else if (n.nodeType == 4) cdataChild++; // cdata section node\n }\n if (hasElementChild) {\n if (textChild < 2 && cdataChild < 2) {\n // structured element with evtl. a single text or/and cdata node ..\n X.removeWhite(xml);\n for (var n = xml.firstChild; n; n = n.nextSibling) {\n if (n.nodeType == 3)\n // text node\n o[\"#text\"] = X.escape(n.nodeValue);\n else if (n.nodeType == 4)\n // cdata node\n o[\"#cdata\"] = X.escape(n.nodeValue);\n else if (o[n.nodeName]) {\n // multiple occurence of element ..\n if (o[n.nodeName] instanceof Array) o[n.nodeName][o[n.nodeName].length] = X.toObj(n);\n else o[n.nodeName] = [o[n.nodeName], X.toObj(n)];\n } // first occurence of element..\n else o[n.nodeName] = X.toObj(n);\n }\n } else {\n // mixed content\n if (!xml.attributes.length) o = X.escape(X.innerXml(xml));\n else o[\"#text\"] = X.escape(X.innerXml(xml));\n }\n } else if (textChild) {\n // pure text\n if (!xml.attributes.length) o = X.escape(X.innerXml(xml));\n else o[\"#text\"] = X.escape(X.innerXml(xml));\n } else if (cdataChild) {\n // cdata\n if (cdataChild > 1) o = X.escape(X.innerXml(xml));\n else for (var n = xml.firstChild; n; n = n.nextSibling) o[\"#cdata\"] = X.escape(n.nodeValue);\n }\n }\n if (!xml.attributes.length && !xml.firstChild) o = null;\n } else if (xml.nodeType == 9) {\n // document.node\n o = X.toObj(xml.documentElement);\n } else alert(\"unhandled node type: \" + xml.nodeType);\n return o;\n },\n toJson: function(o, name, ind) {\n var json = name ? '\"' + name + '\"' : \"\";\n if (o instanceof Array) {\n for (var i = 0, n = o.length; i < n; i++) o[i] = X.toJson(o[i], \"\", ind + \"\\t\");\n json +=\n (name ? \":[\" : \"[\") +\n (o.length > 1 ? \"\\n\" + ind + \"\\t\" + o.join(\",\\n\" + ind + \"\\t\") + \"\\n\" + ind : o.join(\"\")) +\n \"]\";\n } else if (o == null) json += (name && \":\") + \"null\";\n else if (typeof o == \"object\") {\n var arr = [];\n for (var m in o) arr[arr.length] = X.toJson(o[m], m, ind + \"\\t\");\n json +=\n (name ? \":{\" : \"{\") +\n (arr.length > 1 ? \"\\n\" + ind + \"\\t\" + arr.join(\",\\n\" + ind + \"\\t\") + \"\\n\" + ind : arr.join(\"\")) +\n \"}\";\n } else if (typeof o == \"string\") json += (name && \":\") + '\"' + o.toString() + '\"';\n else json += (name && \":\") + o.toString();\n return json;\n },\n innerXml: function(node) {\n var s = \"\";\n if (\"innerHTML\" in node) s = node.innerHTML;\n else {\n var asXml = function(n) {\n var s = \"\";\n if (n.nodeType == 1) {\n s += \"<\" + n.nodeName;\n for (var i = 0; i < n.attributes.length; i++)\n s += \" \" + n.attributes[i].nodeName + '=\"' + (n.attributes[i].nodeValue || \"\").toString() + '\"';\n if (n.firstChild) {\n s += \">\";\n for (var c = n.firstChild; c; c = c.nextSibling) s += asXml(c);\n s += \"</\" + n.nodeName + \">\";\n } else s += \"/>\";\n } else if (n.nodeType == 3) s += n.nodeValue;\n else if (n.nodeType == 4) s += \"<![CDATA[\" + n.nodeValue + \"]]>\";\n return s;\n };\n for (var c = node.firstChild; c; c = c.nextSibling) s += asXml(c);\n }\n return s;\n },\n escape: function(txt) {\n return txt\n .replace(/[\\\\]/g, \"\\\\\\\\\")\n .replace(/[\\\"]/g, '\\\\\"')\n .replace(/[\\n]/g, \"\\\\n\")\n .replace(/[\\r]/g, \"\\\\r\");\n },\n removeWhite: function(e) {\n e.normalize();\n for (var n = e.firstChild; n; ) {\n if (n.nodeType == 3) {\n // text node\n if (!n.nodeValue.match(/[^ \\f\\n\\r\\t\\v]/)) {\n // pure whitespace text node\n var nxt = n.nextSibling;\n e.removeChild(n);\n n = nxt;\n } else n = n.nextSibling;\n } else if (n.nodeType == 1) {\n // element node\n X.removeWhite(n);\n n = n.nextSibling;\n } // any other node\n else n = n.nextSibling;\n }\n return e;\n }\n };\n if (xml.nodeType == 9)\n // document node\n xml = xml.documentElement;\n var json = X.toJson(X.toObj(X.removeWhite(xml)), xml.nodeName, \"\\t\");\n return \"{\\n\" + tab + (tab ? json.replace(/\\t/g, tab) : json.replace(/\\t|\\n/g, \"\")) + \"\\n}\";\n}\n"
language: typescript
template:
content: "<div class=\"row\">\n\n\t<div class=\"col-12\">\n\t\t<input id=\"Name\" class=\"form-control form-control-lg\">\n\t</div>\n\n\t</div>\n\n\t<div class=\"row\">\n\n\t\t<div class=\"col-12\">\n\t\t\t<ul class=\"nav nav-tabs\" id=\"myTab\" role=\"tablist\">\n\t\t\t\t<li class=\"nav-item\" role=\"presentation\">\n\t\t\t\t\t<a class=\"nav-link active\" id=\"Tidrapport-tab\" data-toggle=\"tab\" href=\"#Tidrapport\" role=\"tab\"\n\t\t\t\t\t\taria-controls=\"Tidrapport\" aria-selected=\"true\">Tidrapport</a>\n\t\t\t\t</li>\n\t\t\t\t<li class=\"nav-item\" role=\"presentation\">\n\t\t\t\t\t<a class=\"nav-link\" id=\"Resa-tab\" data-toggle=\"tab\" href=\"#Resa\" role=\"tab\"\n\t\t\t\t\t\taria-controls=\"Resa\" aria-selected=\"false\">Resa</a>\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t\t<div class=\"tab-content\" id=\"myTabContent\">\n\t\t\t\t<div class=\"tab-pane fade show active\" id=\"Tidrapport\" role=\"tabpanel\" aria-labelledby=\"Tidrapport-tab\">\n\n\t\t\t\t\t<div class=\"row\">\n\t\t\t\t\t\t<div class=\"col-6 bold\">Projekt:</div>\n\t\t\t\t\t\t<div class=\"col-6\"><select class=\"form-control\" id=\"Projects\"></select></div>\n\n\t\t\t\t\t\t<div class=\"col-6 bold\">Aktivitet:</div>\n\t\t\t\t\t\t<div class=\"col-6\"><select class=\"form-control\" id=\"Activities\"></select></div>\n\n\t\t\t\t\t\t<div class=\"col-6 bold\">Fakturera tid:</div>\n\t\t\t\t\t\t<div class=\"col-6\" id=\"InvoiceTime\"><input type=\"checkbox\" checked /></div>\n\n\t\t\t\t\t\t\t<div class=\"col-12 bold\">Kommentar:</div>\n\t\t\t\t\t\t\t<div class=\"col-12\"><textarea id=\"Comment\" class=\"form-control\" ></textarea></div>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"tab-pane fade\" id=\"Resa\" role=\"tabpanel\" aria-labelledby=\"Resa-tab\">\n\n-resa-\n\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t</div>\n\t\t</div>"
language: html
style:
content: |-
body {
font-size: normal;
font-weight: 100;
margin: 4px;
}
section.samples {
margin-top: 20px;
}
section.samples .ms-Button, section.setup .ms-Button {
display: block;
margin-bottom: 5px;
margin-left: 20px;
min-width: 80px;
}
.bold {
font-weight: bold;
}
.header {
padding-top: 3px;
margin-left: 5px;
border-top: 2px solid white;
background: #0173C7;
color: white;
}
.note {
color: gray;
font-size: smaller;
}
#Name {
margin-bottom: 5px;
}
language: css
libraries: |+
https://appsforoffice.microsoft.com/lib/1/hosted/office.js
@types/office-js
office-ui-fabric-js@1.4.0/dist/css/fabric.min.css
office-ui-fabric-js@1.4.0/dist/css/fabric.components.min.css
core-js@2.4.1/client/core.min.js
@types/core-js
jquery@3.1.1
@types/jquery@3.3.1
https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css
https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js
@types/bootstrap@4.6.0/index.d.ts
@types/bootstrap@4.6.0/package.json
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment