Files
raven-client/ayanova/src/api/gzutil.js
2020-10-08 17:12:33 +00:00

496 lines
14 KiB
JavaScript

/* 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,
"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,
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
? 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 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
};