/* Xeslint-disable */ ///////////////////////////////// // General utility library // const icons = { image: "$ayiFileImage", pdf: "$ayiFilePdf", word: "$ayiFileWord", powerpoint: "$ayiFilePowerpoint", excel: "$ayiFileExcel", csv: "$ayiFileCsv", audio: "$ayiFileAudio", video: "$ayiFileVidio", archive: "$ayiFileArchive", code: "$ayiFileCode", text: "$ayiFileAlt", file: "$ayiFile" }; const mimeTypes = { "image/gif": icons.image, "image/jpeg": icons.image, "image/png": icons.image, "image/webp": icons.image, "application/pdf": icons.pdf, "application/msword": icons.word, "application/vnd.openxmlformats-officedocument.wordprocessingml.document": icons.word, "application/mspowerpoint": icons.powerpoint, "application/vnd.openxmlformats-officedocument.presentationml.presentation": icons.powerpoint, "application/msexcel": icons.excel, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": icons.excel, "text/csv": icons.csv, "audio/aac": icons.audio, "audio/wav": icons.audio, "audio/mpeg": icons.audio, "audio/mp4": icons.audio, "audio/ogg": icons.audio, "video/x-msvideo": icons.video, "video/mpeg": icons.video, "video/mp4": icons.video, "video/ogg": icons.video, "video/quicktime": icons.video, "video/webm": icons.video, "application/gzip": icons.archive, "application/zip": icons.archive, "application/x-tar": icons.archive, "text/css": icons.code, "text/html": icons.code, "text/javascript": icons.code, "application/javascript": icons.code, "text/plain": icons.text, "text/richtext": icons.text, "text/rtf": icons.text, "application/rtf": icons.text, "application/json": icons.text }; const extensions = { gif: icons.image, jpeg: icons.image, jpg: icons.image, png: icons.image, webp: icons.image, pdf: icons.pdf, doc: icons.word, docx: icons.word, ppt: icons.powerpoint, pptx: icons.powerpoint, xls: icons.excel, xlsx: icons.excel, csv: icons.csv, aac: icons.audio, mp3: icons.audio, ogg: icons.audio, avi: icons.video, flv: icons.video, mkv: icons.video, mp4: icons.video, gz: icons.archive, zip: icons.archive, tar: icons.archive, "7z": icons.archive, css: icons.code, html: icons.code, js: icons.code, txt: icons.text, json: icons.text, rtf: icons.text }; export default { /////////////////////////////// // CLEAN OBJECT // Clear all properties from object without resorting to assigning a new object (o={}) // which can be problematic in some cases (IE bugs, watched data items in forms etc) removeAllPropertiesFromObject: function(o) { for (let variableKey in o) { if (o.hasOwnProperty(variableKey)) { delete o[variableKey]; } } }, /** * Copy a string to clipboard * @param {String} string The string to be copied to clipboard * @return {Boolean} returns a boolean correspondent to the success of the copy operation. * Modified from an example here: https://stackoverflow.com/a/53951634/8939 * Basically a fallback if navigator.clipboard is not available */ copyToClipboard: function(string) { let textarea; let result; if (navigator && navigator.clipboard) { navigator.clipboard.writeText(string); } else { try { textarea = document.createElement("textarea"); textarea.setAttribute("readonly", true); textarea.setAttribute("contenteditable", true); textarea.style.position = "fixed"; // prevent scroll from jumping to the bottom when focus is set. textarea.value = string; document.body.appendChild(textarea); textarea.focus(); textarea.select(); const range = document.createRange(); range.selectNodeContents(textarea); const sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); textarea.setSelectionRange(0, textarea.value.length); result = document.execCommand("copy"); } catch (err) { //console.error(err); result = null; } finally { document.body.removeChild(textarea); } // manual copy fallback using prompt if (!result) { const isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0; const copyHotkey = isMac ? "⌘C" : "CTRL+C"; result = prompt(`Press ${copyHotkey}`, string); if (!result) { return false; } } } return true; }, /////////////////////////////// // CLEAN TAG NAME // Clean up a tag with same rules as server // normalizeTag: function(tagName) { /* SERVER VERSION public static string NormalizeTag(string inObj) { if (string.IsNullOrWhiteSpace(inObj)) return null; //Must be lowercase per rules //This may be naive when we get international cust omers but for now supporting utf-8 and it appears it's safe to do this with unicode inObj = inObj.ToLowerInvariant(); //No spaces in tags, replace with dashes inObj = inObj.Replace(" ", "-"); //Remove multiple dash sequences inObj = System.Text.RegularExpressions.Regex.Replace(inObj, "-+", "-"); //Ensure doesn't start or end with a dash inObj = inObj.Trim('-'); //No longer than 255 characters inObj = StringUtil.MaxLength(inObj, 255); return inObj; } */ //de-lodash //kebab case takes care of all the things we need for tags in one go // tagName = window.$gz. _.kebabCase(tagName); if (!tagName || tagName == "") { return null; } tagName = tagName.toLowerCase(); //spaces to dashes tagName = tagName.replace(/ /gi, "-"); //multiple dashes to single dashes tagName = tagName.replace(/-+/g, "-"); //ensure doesn't start or end with a dash tagName = this.trimSpecific(tagName, "-"); //No longer than 255 characters tagName = tagName.length > 255 ? tagName.substr(0, 255 - 1) : tagName; return tagName; }, /////////////////////////////// // Quick hash for trivial purposes // not cryptographic // https://stackoverflow.com/a/7616484/8939 // quickHash: function(theString) { let hash = 0, i, chr; if (theString.length === 0) return hash; for (i = 0; i < theString.length; i++) { chr = theString.charCodeAt(i); hash = (hash << 5) - hash + chr; hash |= 0; // Convert to 32bit integer } return hash; }, /////////////////////////////// // CONVERT STRING TO BOOLEAN // https://stackoverflow.com/a/1414175/8939 // stringToBoolean: function(string) { switch (string.toLowerCase().trim()) { case "true": case "yes": case "1": return true; case "false": case "no": case "0": case null: return false; default: return Boolean(string); } }, /////////////////////////////// // CONVERT STRING TO FLOAT // https://stackoverflow.com/a/9409894/8939 // stringToFloat: function(string) { //null or empty then zero if (!string) { return 0; } //A number already then parse and return if (this.isNumeric(string)) { if (string === NaN) { return 0; } return parseFloat(string); } //Not a string at all? if (!this.isString(string)) { return 0; } let ret = parseFloat(string.replace(/[^\d.-]/g, "")); if (ret == NaN) { return 0; } return ret; }, /////////////////////////////// // Splice a string //changes the content of a string by removing a range of // characters and/or adding new characters. // // @param {String} source string // @param {number} start Index at which to start changing the string. // @param {number} delCount An integer indicating the number of old chars to remove. // @param {string} newSubStr The String that is spliced in. // @return {string} A new string with the spliced substring. stringSplice: function(source, start, delCount, newSubStr) { if (source == null || source == "") { if (newSubStr) { return newSubStr; } return ""; } return ( source.slice(0, start) + newSubStr + source.slice(start + Math.abs(delCount)) ); }, /////////////////////////////// // Format tags for display // // // @param {String} tags raw from server // @return {string} A new string with the tags formatted or an empty string if no tags formatTags: function(tags) { if (tags && tags.length > 0) { return tags.join(", "); } return ""; }, /////////////////////////////// // ICON FOR *ALL* OBJECT TYPES //(used for search results and event log / history) //NOTE: Any object type could appear in event log, they all need to be supported where possible //CoreBizObject add here iconForType: function(ayaType) { switch (ayaType) { case window.$gz.type.NoType: return "$ayiGenderless"; case window.$gz.type.Global: return "$ayiGlobe"; case window.$gz.type.User: return "$ayiUser"; case window.$gz.type.Widget: return "$ayiVial"; case window.$gz.type.ServerState: return "$ayiDoorOpen"; case window.$gz.type.License: return "$ayiTicket"; case window.$gz.type.LogFile: return "$ayiGlasses"; case window.$gz.type.PickListTemplate: return "$ayiPencilRuler"; case window.$gz.type.ServerJob: return "$ayiRobot"; case window.$gz.type.AyaNova7Import: return "$ayiFileImport"; case window.$gz.type.TrialSeeder: return "$ayiSeedling"; case window.$gz.type.Metrics: return "$ayiFileMedicalAlt"; case window.$gz.type.Translation: return "$ayiLanguage"; case window.$gz.type.UserOptions: return "$ayiUserCog"; case window.$gz.type.FileAttachment: return "$ayiPaperclip"; case window.$gz.type.DataListView: return "$ayiFilter"; case window.$gz.type.FormCustom: return "$ayiCustomize"; default: return null; } }, //https://gist.github.com/colemanw/9c9a12aae16a4bfe2678de86b661d922 iconForFile: function(fileName, mimeType) { // List of official MIME Types: http://www.iana.org/assignments/media-types/media-types.xhtml let extension = null; if (fileName && fileName.includes(".")) { extension = fileName.split(".").pop(); extension = extension.toLowerCase(); } if (!extension && !mimeType) { console.log( "gzutil:iconForFile -> No mime or extension for " + fileName + " " + mimeType ); return "$ayiFile"; } if (!mimeType) { mimeType = ""; } mimeType = mimeType.toLowerCase(); let iconFromExtension = extensions[extension]; let iconFromMIME = mimeTypes[mimeType]; if (iconFromMIME) { return iconFromMIME; } if (iconFromExtension) { return iconFromExtension; } return "$ayiFile"; }, /////////////////////////////////////////////// // attempt to detect image extension name // isImageAttachment: function(fileName, mimeType) { return this.iconForFile(fileName, mimeType) == "$ayiFileImage"; }, /////////////////////////////////////////////// // Sleep async // sleepAsync: function(milliseconds) { // eslint-disable-next-line return new Promise((resolve) => setTimeout(resolve, milliseconds)); }, /////////////////////////////////////////////// // sortByKey lodash "sortBy" replacement // https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_sortby-and-_orderby //usage: // The native sort modifies the array in place. `_.orderBy` and `_.sortBy` do not, so we use `.concat()` to // copy the array, then sort. // fruits.concat().sort(sortBy("name")); // => [{name:"apple", amount: 4}, {name:"banana", amount: 2}, {name:"mango", amount: 1}, {name:"pineapple", amount: 2}] sortByKey: key => { return (a, b) => (a[key] > b[key] ? 1 : b[key] > a[key] ? -1 : 0); }, /////////////////////////////////////////////// // "has" lodash replacement // https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_has // has: function(obj, key) { var keyParts = key.split("."); return ( !!obj && (keyParts.length > 1 ? this.has(obj[key.split(".")[0]], keyParts.slice(1).join(".")) : hasOwnProperty.call(obj, key)) ); }, /////////////////////////////////////////////// // Check if object is empty // objectIsEmpty: function(obj) { //https://stackoverflow.com/a/4994265/8939 return !obj || Object.keys(obj).length === 0; }, /////////////////////////////////////////////// // Trim specific character from start and end // https://stackoverflow.com/a/55292366/8939 // trimSpecific: function trim(str, ch) { var start = 0, end = str.length; while (start < end && str[start] === ch) ++start; while (end > start && str[end - 1] === ch) --end; return start > 0 || end < str.length ? str.substring(start, end) : str; }, /////////////////////////////////////////////// // is numeric replacement for lodash // https://stackoverflow.com/a/52986361/8939 // isNumeric: function(n) { //lodash isNumber returned false if it's a string and that's what the rest of the code expects even though it's parseable to a number return !this.isString(n) && !isNaN(parseFloat(n)) && isFinite(n); }, /////////////////////////////////////////////// // is string replacement for lodash // https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_isString // isString: function(str) { if (str && typeof str.valueOf() === "string") { return true; } return false; }, /////////////////////////////////////////////// // is Boolean replacement for lodash // https://stackoverflow.com/a/43718478/8939 // isBoolean: function(obj) { return obj === true || obj === false || typeof variable === "boolean"; } /** * * */ //new functions above here };