@nova-ui/dashboards
Version:
Nova Dashboards is a framework designed to provide feature developers with a common solution for presenting data coming from various sources within a single view, as well as a set of predefined widget visualizations that are 100% configuration-driven and
110 lines • 16 kB
JavaScript
// © 2022 SolarWinds Worldwide, LLC. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import isArray from "lodash/isArray";
import some from "lodash/some";
import union from "lodash/union";
/**
* This function takes a source object with a prioritized list of changes. Goes through and detects the changes on every one of these structures and builds
* a new object that respects immutability and updates object references only where necessary. This is used to merge lasagna overlays into a component state
* that maintains its immutability and high performance of change detection.
*
* @param result
* @param changes
*/
export function mergeChanges(result, ...changes) {
const validChanges = changes.filter((c) => typeof c.previousValue !== "undefined" ||
typeof c.currentValue !== "undefined");
// there were no changes in the provided values, so just return the input object
if (!some(validChanges, (c) => c.currentValue !== c.previousValue)) {
return result;
}
// if there is only one layer of change just return the currentValue to preserve references
if (validChanges.length === 1) {
return validChanges[0].currentValue;
}
// first we need to determine the value type
const valueType = findType(validChanges);
// if it's a primitive type or an array, then we don't go further and we take a new value with the highest priority
if (!["object", "object[]"].includes(valueType)) {
// we take the value with the last priority
return takeHighestPriorityValue(validChanges);
}
// collect all the keys of all the objects in given changes
const keys = union(...validChanges.map((c) => typeof c.currentValue === "object"
? Object.keys(c.currentValue || {})
: []));
const accTemplate = valueType === "object[]" ? [] : {};
const ret = keys.reduce((acc, key) => {
const checkedResult = typeof result === "undefined" ||
result === null ||
typeof result[key] === "undefined"
? undefined
: result[key];
const nestedChanges = validChanges.map((c) => ({
previousValue: typeof c.previousValue === "undefined" ||
c.previousValue == null
? undefined
: c.previousValue[key],
currentValue: typeof c.currentValue === "undefined" || c.currentValue == null
? undefined
: c.currentValue[key],
}));
// recursively execute this method for given property
acc[key] = mergeChanges(checkedResult, ...nestedChanges);
return acc;
}, accTemplate);
return ret;
}
/**
* Take current value from given changes with highest priority - the last one wins
*
* @param changes
*/
function takeHighestPriorityValue(changes) {
for (let i = changes.length - 1; i >= 0; i--) {
const value = changes[i].currentValue;
if (typeof value !== "undefined") {
return value;
}
}
return undefined;
}
function findType(changes) {
for (const c of changes) {
const type = typeof c.currentValue;
if (type !== "undefined" && c.currentValue != null) {
if (isArray(c.currentValue)) {
const arrElemType = typeof c.currentValue[0];
if (arrElemType === "object") {
return "object[]";
}
else {
return "array";
}
}
if (c.currentValue.constructor !== Object) {
return "advanced";
}
return type;
}
}
return typeof undefined;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVyZ2UtY2hhbmdlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvZnVuY3Rpb25zL21lcmdlLWNoYW5nZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEseURBQXlEO0FBQ3pELEVBQUU7QUFDRiwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLDREQUE0RDtBQUM1RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLHVEQUF1RDtBQUN2RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLDRFQUE0RTtBQUM1RSwrRUFBK0U7QUFDL0UsMEVBQTBFO0FBQzFFLGlGQUFpRjtBQUNqRiw2RUFBNkU7QUFDN0UsaUJBQWlCO0FBRWpCLE9BQU8sT0FBTyxNQUFNLGdCQUFnQixDQUFDO0FBQ3JDLE9BQU8sSUFBSSxNQUFNLGFBQWEsQ0FBQztBQUMvQixPQUFPLEtBQUssTUFBTSxjQUFjLENBQUM7QUFPakM7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQUksTUFBUyxFQUFFLEdBQUcsT0FBdUI7SUFDakUsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FDL0IsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUNGLE9BQU8sQ0FBQyxDQUFDLGFBQWEsS0FBSyxXQUFXO1FBQ3RDLE9BQU8sQ0FBQyxDQUFDLFlBQVksS0FBSyxXQUFXLENBQzVDLENBQUM7SUFFRixnRkFBZ0Y7SUFDaEYsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxZQUFZLEtBQUssQ0FBQyxDQUFDLGFBQWEsQ0FBQyxFQUFFO1FBQ2hFLE9BQU8sTUFBTSxDQUFDO0tBQ2pCO0lBRUQsMkZBQTJGO0lBQzNGLElBQUksWUFBWSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7UUFDM0IsT0FBTyxZQUFZLENBQUMsQ0FB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QUFDLENBQUMsWUFBWSxDQUFDLEVBQUU7Z0JBQ3pCLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDN0MsSUFBSSxXQUFXLEtBQUssUUFBUSxFQUFFO29CQUMxQixPQUFPLFVBQVUsQ0FBQztpQkFDckI7cUJBQU07b0JBQ0gsT0FBTyxPQUFPLENBQUM7aUJBQ2xCO2FBQ0o7WUFDRCxJQUFJLENBQUMsQ0FBQyxZQUFZLENBQUMsV0FBVyxLQUFLLE1BQU0sRUFBRTtnQkFDdkMsT0FBTyxVQUFVLENBQUM7YUFDckI7WUFFRCxPQUFPLElBQUksQ0FBQztTQUNmO0tBQ0o7SUFDRCxPQUFPLE9BQU8sU0FBUyxDQUFDO0FBQzVCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyDCqSAyMDIyIFNvbGFyV2luZHMgV29ybGR3aWRlLCBMTEMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXG4vLyAgZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbi8vICByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Jcbi8vICBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vICBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyAgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyAgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyAgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IGlzQXJyYXkgZnJvbSBcImxvZGFzaC9pc0FycmF5XCI7XG5pbXBvcnQgc29tZSBmcm9tIFwibG9kYXNoL3NvbWVcIjtcbmltcG9ydCB1bmlvbiBmcm9tIFwibG9kYXNoL3VuaW9uXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVZhbHVlQ2hhbmdlIHtcbiAgICBwcmV2aW91c1ZhbHVlOiBhbnk7XG4gICAgY3VycmVudFZhbHVlOiBhbnk7XG59XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiB0YWtlcyBhIHNvdXJjZSBvYmplY3Qgd2l0aCBhIHByaW9yaXRpemVkIGxpc3Qgb2YgY2hhbmdlcy4gR29lcyB0aHJvdWdoIGFuZCBkZXRlY3RzIHRoZSBjaGFuZ2VzIG9uIGV2ZXJ5IG9uZSBvZiB0aGVzZSBzdHJ1Y3R1cmVzIGFuZCBidWlsZHNcbiAqIGEgbmV3IG9iamVjdCB0aGF0IHJlc3BlY3RzIGltbXV0YWJpbGl0eSBhbmQgdXBkYXRlcyBvYmplY3QgcmVmZXJlbmNlcyBvbmx5IHdoZXJlIG5lY2Vzc2FyeS4gVGhpcyBpcyB1c2VkIHRvIG1lcmdlIGxhc2FnbmEgb3ZlcmxheXMgaW50byBhIGNvbXBvbmVudCBzdGF0ZVxuICogdGhhdCBtYWludGFpbnMgaXRzIGltbXV0YWJpbGl0eSBhbmQgaGlnaCBwZXJmb3JtYW5jZSBvZiBjaGFuZ2UgZGV0ZWN0aW9uLlxuICpcbiAqIEBwYXJhbSByZXN1bHRcbiAqIEBwYXJhbSBjaGFuZ2VzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUNoYW5nZXM8VD4ocmVzdWx0OiBULCAuLi5jaGFuZ2VzOiBJVmFsdWVDaGFuZ2VbXSk6IFQge1xuICAgIGNvbnN0IHZhbGlkQ2hhbmdlcyA9IGNoYW5nZXMuZmlsdGVyKFxuICAgICAgICAoYykgPT5cbiAgICAgICAgICAgIHR5cGVvZiBjLnByZXZpb3VzVmFsdWUgIT09IFwidW5kZWZpbmVkXCIgfHxcbiAgICAgICAgICAgIHR5cGVvZiBjLmN1cnJlbnRWYWx1ZSAhPT0gXCJ1bmRlZmluZWRcIlxuICAgICk7XG5cbiAgICAvLyB0aGVyZSB3ZXJlIG5vIGNoYW5nZXMgaW4gdGhlIHByb3ZpZGVkIHZhbHVlcywgc28ganVzdCByZXR1cm4gdGhlIGlucHV0IG9iamVjdFxuICAgIGlmICghc29tZSh2YWxpZENoYW5nZXMsIChjKSA9PiBjLmN1cnJlbnRWYWx1ZSAhPT0gYy5wcmV2aW91c1ZhbHVlKSkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8vIGlmIHRoZXJlIGlzIG9ubHkgb25lIGxheWVyIG9mIGNoYW5nZSBqdXN0IHJldHVybiB0aGUgY3VycmVudFZhbHVlIHRvIHByZXNlcnZlIHJlZmVyZW5jZXNcbiAgICBpZiAodmFsaWRDaGFuZ2VzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICByZXR1cm4gdmFsaWRDaGFuZ2VzWzBdLmN1cnJlbnRWYWx1ZTtcbiAgICB9XG5cbiAgICAvLyBmaXJzdCB3ZSBuZWVkIHRvIGRldGVybWluZSB0aGUgdmFsdWUgdHlwZVxuICAgIGNvbnN0IHZhbHVlVHlwZSA9IGZpbmRUeXBlKHZhbGlkQ2hhbmdlcyk7XG4gICAgLy8gaWYgaXQncyBhIHByaW1pdGl2ZSB0eXBlIG9yIGFuIGFycmF5LCB0aGVuIHdlIGRvbid0IGdvIGZ1cnRoZXIgYW5kIHdlIHRha2UgYSBuZXcgdmFsdWUgd2l0aCB0aGUgaGlnaGVzdCBwcmlvcml0eVxuICAgIGlmICghW1wib2JqZWN0XCIsIFwib2JqZWN0W11cIl0uaW5jbHVkZXModmFsdWVUeXBlKSkge1xuICAgICAgICAvLyB3ZSB0YWtlIHRoZSB2YWx1ZSB3aXRoIHRoZSBsYXN0IHByaW9yaXR5XG4gICAgICAgIHJldHVybiB0YWtlSGlnaGVzdFByaW9yaXR5VmFsdWUodmFsaWRDaGFuZ2VzKTtcbiAgICB9XG5cbiAgICAvLyBjb2xsZWN0IGFsbCB0aGUga2V5cyBvZiBhbGwgdGhlIG9iamVjdHMgaW4gZ2l2ZW4gY2hhbmdlc1xuICAgIGNvbnN0IGtleXM6IHN0cmluZ1tdID0gdW5pb24oXG4gICAgICAgIC4uLnZhbGlkQ2hhbmdlcy5tYXAoKGMpID0+XG4gICAgICAgICAgICB0eXBlb2YgYy5jdXJyZW50VmFsdWUgPT09IFwib2JqZWN0XCJcbiAgICAgICAgICAgICAgICA/IE9iamVjdC5rZXlzKGMuY3VycmVudFZhbHVlIHx8IHt9KVxuICAgICAgICAgICAgICAgIDogW11cbiAgICAgICAgKVxuICAgICk7XG5cbiAgICBjb25zdCBhY2NUZW1wbGF0ZSA9IHZhbHVlVHlwZSA9PT0gXCJvYmplY3RbXVwiID8gW10gOiB7fTtcblxuICAgIGNvbnN0IHJldCA9IGtleXMucmVkdWNlKChhY2M6IFJlY29yZDxzdHJpbmcsIGFueT4sIGtleSkgPT4ge1xuICAgICAgICBjb25zdCBjaGVja2VkUmVzdWx0ID1cbiAgICAgICAgICAgIHR5cGVvZiByZXN1bHQgPT09IFwidW5kZWZpbmVkXCIgfHxcbiAgICAgICAgICAgIHJlc3VsdCA9PT0gbnVsbCB8fFxuICAgICAgICAgICAgdHlwZW9mICg8UmVjb3JkPHN0cmluZywgYW55Pj5yZXN1bHQpW2tleV0gPT09IFwidW5kZWZpbmVkXCJcbiAgICAgICAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIDogKDxSZWNvcmQ8c3RyaW5nLCBhbnk+PnJlc3VsdClba2V5XTtcbiAgICAgICAgY29uc3QgbmVzdGVkQ2hhbmdlcyA9IHZhbGlkQ2hhbmdlcy5tYXAoKGMpID0+ICh7XG4gICAgICAgICAgICBwcmV2aW91c1ZhbHVlOlxuICAgICAgICAgICAgICAgIHR5cGVvZiBjLnByZXZpb3VzVmFsdWUgPT09IFwidW5kZWZpbmVkXCIgfHxcbiAgICAgICAgICAgICAgICBjLnByZXZpb3VzVmFsdWUgPT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA6IGMucHJldmlvdXNWYWx1ZVtrZXldLFxuICAgICAgICAgICAgY3VycmVudFZhbHVlOlxuICAgICAgICAgICAgICAgIHR5cGVvZiBjLmN1cnJlbnRWYWx1ZSA9PT0gXCJ1bmRlZmluZWRcIiB8fCBjLmN1cnJlbnRWYWx1ZSA9PSBudWxsXG4gICAgICAgICAgICAgICAgICAgID8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgIDogYy5jdXJyZW50VmFsdWVba2V5XSxcbiAgICAgICAgfSkpO1xuXG4gICAgICAgIC8vIHJlY3Vyc2l2ZWx5IGV4ZWN1dGUgdGhpcyBtZXRob2QgZm9yIGdpdmVuIHByb3BlcnR5XG4gICAgICAgIGFjY1trZXldID0gbWVyZ2VDaGFuZ2VzKFxuICAgICAgICAgICAgY2hlY2tlZFJlc3VsdCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgICAgICAgICAgLi4ubmVzdGVkQ2hhbmdlc1xuICAgICAgICApO1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgIH0sIGFjY1RlbXBsYXRlKTtcblxuICAgIHJldHVybiByZXQgYXMgVDtcbn1cblxuLyoqXG4gKiBUYWtlIGN1cnJlbnQgdmFsdWUgZnJvbSBnaXZlbiBjaGFuZ2VzIHdpdGggaGlnaGVzdCBwcmlvcml0eSAtIHRoZSBsYXN0IG9uZSB3aW5zXG4gKlxuICogQHBhcmFtIGNoYW5nZXNcbiAqL1xuZnVuY3Rpb24gdGFrZUhpZ2hlc3RQcmlvcml0eVZhbHVlKGNoYW5nZXM6IElWYWx1ZUNoYW5nZVtdKSB7XG4gICAgZm9yIChsZXQgaSA9IGNoYW5nZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBjaGFuZ2VzW2ldLmN1cnJlbnRWYWx1ZTtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGZpbmRUeXBlKGNoYW5nZXM6IElWYWx1ZUNoYW5nZVtdKTogc3RyaW5nIHtcbiAgICBmb3IgKGNvbnN0IGMgb2YgY2hhbmdlcykge1xuICAgICAgICBjb25zdCB0eXBlID0gdHlwZW9mIGMuY3VycmVudFZhbHVlO1xuICAgICAgICBpZiAodHlwZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBjLmN1cnJlbnRWYWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoaXNBcnJheShjLmN1cnJlbnRWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhcnJFbGVtVHlwZSA9IHR5cGVvZiBjLmN1cnJlbnRWYWx1ZVswXTtcbiAgICAgICAgICAgICAgICBpZiAoYXJyRWxlbVR5cGUgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0W11cIjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJhcnJheVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjLmN1cnJlbnRWYWx1ZS5jb25zdHJ1Y3RvciAhPT0gT2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiYWR2YW5jZWRcIjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHR5cGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHR5cGVvZiB1bmRlZmluZWQ7XG59XG4iXX0=