@gooddata/gooddata-js
Version:
GoodData JavaScript SDK
409 lines (408 loc) • 22 kB
JavaScript
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// (C) 2020 GoodData Corporation
var metadata_1 = require("./metadata");
var user_1 = require("./user");
var cloneDeepWith_1 = __importDefault(require("lodash/cloneDeepWith"));
var isEmpty_1 = __importDefault(require("lodash/isEmpty"));
var compact_1 = __importDefault(require("lodash/compact"));
var omit_1 = __importDefault(require("lodash/omit"));
function createTranslator(kpiMap, visWidgetMap) {
return function (oldUri) {
var kpiMatch = kpiMap.get(oldUri);
var visWidgetMatch = visWidgetMap.get(oldUri);
if (kpiMatch) {
return kpiMatch;
}
else if (visWidgetMatch) {
return visWidgetMatch;
}
else {
return oldUri;
}
};
}
exports.createTranslator = createTranslator;
/**
* Updates content of the dashboard
*
* @param {string} dashboardUri uri of dashboard
* @param {UriTranslator} uriTranslator gets updated widgets and kpis uri
* @param {string} filterContext updated filter context uri
* @experimental
*/
function updateContent(analyticalDashboard, uriTranslator, filterContext) {
return cloneDeepWith_1.default(__assign({}, analyticalDashboard.content, { filterContext: filterContext, widgets: analyticalDashboard.content.widgets.map(function (uri) {
return uriTranslator(uri);
}) }), function (value) {
var uri = value.uri;
if (!uri) {
return;
}
return __assign({}, value, { uri: uriTranslator(uri) });
});
}
exports.updateContent = updateContent;
var MetadataModuleExt = /** @class */ (function () {
function MetadataModuleExt(xhr) {
this.xhr = xhr;
this.metadataModule = new metadata_1.MetadataModule(xhr);
this.userModule = new user_1.UserModule(xhr);
}
/**
* @param {string} projectId id of the project
* @param {string} dashboardUri uri of the dashboard
* @param {ICopyDashboardOptions} options object with options:
* - default {} dashboard is cloned with new kpi reference and visualization widget is cloned with new
* visualization object reference
* - copyKpi {boolean} choose whether dashboard is cloned with new Kpi reference
* - copyVisObj {boolean} choose whether visualization widget is cloned with new visualization object reference
* - name {string} optional - choose name, default value is "Copy of (old title of the dashboard)"
* @returns {string} uri of cloned dashboard
* @experimental
*/
MetadataModuleExt.prototype.saveDashboardAs = function (projectId, dashboardUri, options) {
return __awaiter(this, void 0, void 0, function () {
var objectsFromDashboard, dashboardDetails, analyticalDashboard, allCreatedObjUris, visWidgetUris, filterContext, kpiMap, visWidgetMap, translator, updatedContent, dashboardTitle, dashboardSummary, duplicateDashboard, duplicateDashboardUri, err_1;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getObjectsFromDashboard(projectId, dashboardUri)];
case 1:
objectsFromDashboard = _a.sent();
return [4 /*yield*/, this.metadataModule.getObjectDetails(dashboardUri)];
case 2:
dashboardDetails = _a.sent();
analyticalDashboard = dashboardDetails.analyticalDashboard;
allCreatedObjUris = [];
visWidgetUris = [];
_a.label = 3;
case 3:
_a.trys.push([3, 8, , 14]);
return [4 /*yield*/, this.duplicateFilterContext(projectId, objectsFromDashboard, options)];
case 4:
filterContext = _a.sent();
allCreatedObjUris.push(filterContext);
return [4 /*yield*/, this.duplicateOrKeepKpis(projectId, objectsFromDashboard, options)];
case 5:
kpiMap = _a.sent();
if (this.shouldCopyKpi(options)) {
allCreatedObjUris.push.apply(allCreatedObjUris, Array.from(kpiMap.values()));
}
return [4 /*yield*/, this.duplicateWidgets(projectId, objectsFromDashboard, options)];
case 6:
visWidgetMap = _a.sent();
visWidgetUris.push.apply(visWidgetUris, Array.from(visWidgetMap.values()));
translator = createTranslator(kpiMap, visWidgetMap);
updatedContent = updateContent(analyticalDashboard, translator, filterContext);
dashboardTitle = this.getDashboardName(analyticalDashboard.meta.title, options.name);
dashboardSummary = this.getDashboardSummary(analyticalDashboard.meta.summary, options.summary);
duplicateDashboard = __assign({}, dashboardDetails, { analyticalDashboard: __assign({}, dashboardDetails.analyticalDashboard, { content: this.getDashboardDetailObject(updatedContent, filterContext), meta: __assign({}, this.getSanitizedMeta(dashboardDetails.analyticalDashboard.meta, options), { title: dashboardTitle, summary: dashboardSummary }) }) });
return [4 /*yield*/, this.metadataModule.createObject(projectId, duplicateDashboard)];
case 7:
duplicateDashboardUri = (_a.sent()).analyticalDashboard.meta.uri;
return [2 /*return*/, duplicateDashboardUri];
case 8:
err_1 = _a.sent();
if (!this.shouldCopyVisObj(options)) return [3 /*break*/, 10];
return [4 /*yield*/, Promise.all(visWidgetUris.map(function (uri) { return _this.cascadingDelete(projectId, uri); }))];
case 9:
_a.sent();
return [3 /*break*/, 12];
case 10: return [4 /*yield*/, Promise.all(visWidgetUris.map(function (uri) { return _this.metadataModule.deleteObject(uri); }))];
case 11:
_a.sent();
_a.label = 12;
case 12: return [4 /*yield*/, Promise.all(allCreatedObjUris.map(function (uri) { return _this.cascadingDelete(projectId, uri); }))];
case 13:
_a.sent();
return [2 /*return*/, dashboardUri];
case 14: return [2 /*return*/];
}
});
});
};
/**
* Deletes dashboard and its objects
* (only the author of the dashboard can delete the dashboard and its objects)
*
* @method deleteAllObjects
* @param {string} projectId Project identifier
* @param {string} dashboardUri Uri of a dashboard to be deleted
* @experimental
*/
MetadataModuleExt.prototype.cascadingDelete = function (projectID, dashboardUri) {
return __awaiter(this, void 0, void 0, function () {
var objects, currentUser, objectsToBeDeleted;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.metadataModule.getObjectUsing(projectID, dashboardUri)];
case 1:
objects = _a.sent();
return [4 /*yield*/, this.userModule.getAccountInfo()];
case 2:
currentUser = (_a.sent()).profileUri;
objectsToBeDeleted = objects
.filter(function (object) { return object.author === currentUser; })
.map(function (object) {
return object.link;
});
return [2 /*return*/, this.xhr.post("/gdc/md/" + projectID + "/objects/delete", {
body: {
delete: {
items: [dashboardUri].concat(objectsToBeDeleted),
mode: "cascade",
},
},
})];
}
});
});
};
MetadataModuleExt.prototype.getDashboardDetailObject = function (updatedContent, filterContext) {
var layout = updatedContent.layout;
return __assign({}, updatedContent, { filterContext: filterContext, widgets: updatedContent.widgets.slice() }, (isEmpty_1.default(layout) ? {} : { layout: layout }));
};
MetadataModuleExt.prototype.getDashboardName = function (originalName, newName) {
if (newName !== undefined) {
return newName;
}
return "Copy of " + originalName;
};
MetadataModuleExt.prototype.getDashboardSummary = function (originalSummary, newSummary) {
if (newSummary !== undefined) {
return newSummary;
}
else if (originalSummary !== undefined) {
return originalSummary;
}
return "";
};
MetadataModuleExt.prototype.duplicateOrKeepKpis = function (projectId, objsFromDashboard, options) {
return __awaiter(this, void 0, void 0, function () {
var uriMap;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
uriMap = new Map();
if (!this.shouldCopyKpi(options)) return [3 /*break*/, 2];
return [4 /*yield*/, Promise.all(objsFromDashboard
.filter(function (obj) { return _this.unwrapObj(obj).meta.category === "kpi"; })
.map(function (kpiWidget) { return __awaiter(_this, void 0, void 0, function () {
var kpi, toSave, newUriKpiObj;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
kpi = kpiWidget.kpi;
toSave = {
kpi: {
meta: this.getSanitizedMeta(kpi.meta, options),
content: __assign({}, kpi.content),
},
};
return [4 /*yield*/, this.metadataModule.createObject(projectId, toSave)];
case 1:
newUriKpiObj = (_a.sent()).kpi.meta.uri;
uriMap.set(kpi.meta.uri, newUriKpiObj);
return [2 /*return*/];
}
});
}); }))];
case 1:
_a.sent();
_a.label = 2;
case 2: return [2 /*return*/, uriMap];
}
});
});
};
MetadataModuleExt.prototype.duplicateWidgets = function (projectId, objsFromDashboard, options) {
return __awaiter(this, void 0, void 0, function () {
var uriMap;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
uriMap = new Map();
return [4 /*yield*/, Promise.all(objsFromDashboard
.filter(function (obj) { return _this.unwrapObj(obj).meta.category === "visualizationWidget"; })
.map(function (visWidget) { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, this.createAndUpdateWidgets(projectId, visWidget, options, uriMap)];
});
}); }))];
case 1:
_a.sent();
return [2 /*return*/, uriMap];
}
});
});
};
MetadataModuleExt.prototype.createAndUpdateWidgets = function (projectId, visWidget, options, uriMap) {
return __awaiter(this, void 0, void 0, function () {
var visualizationWidget, visObj, toSave, newUriVisObj, updatedVisWidget, visUri, updatedVisWidget, visualizationWidget_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
visualizationWidget = visWidget.visualizationWidget;
if (!this.shouldCopyVisObj(options)) return [3 /*break*/, 4];
return [4 /*yield*/, this.metadataModule.getObjectDetails(visualizationWidget.content.visualization)];
case 1:
visObj = _a.sent();
toSave = {
visualizationObject: {
meta: this.getSanitizedMeta(visObj.visualizationObject.meta, options),
content: __assign({}, visObj.visualizationObject.content),
},
};
return [4 /*yield*/, this.metadataModule.createObject(projectId, toSave)];
case 2:
newUriVisObj = (_a.sent())
.visualizationObject.meta.uri;
updatedVisWidget = __assign({}, visWidget, { visualizationWidget: {
meta: this.getSanitizedMeta(visWidget.visualizationWidget.meta, options),
content: __assign({}, visWidget.visualizationWidget.content, { visualization: newUriVisObj }),
} });
return [4 /*yield*/, this.metadataModule.createObject(projectId, updatedVisWidget)];
case 3:
visUri = (_a.sent())
.visualizationWidget.meta.uri;
uriMap.set(visualizationWidget.meta.uri, visUri);
return [3 /*break*/, 6];
case 4:
updatedVisWidget = __assign({}, visWidget, { visualizationWidget: {
meta: this.getSanitizedMeta(visWidget.visualizationWidget.meta, options),
content: __assign({}, visWidget.visualizationWidget.content),
} });
return [4 /*yield*/, this.metadataModule.createObject(projectId, updatedVisWidget)];
case 5:
visualizationWidget_1 = (_a.sent()).visualizationWidget;
uriMap.set(visWidget.visualizationWidget.meta.uri, visualizationWidget_1.meta.uri);
_a.label = 6;
case 6: return [2 /*return*/];
}
});
});
};
MetadataModuleExt.prototype.duplicateFilterContext = function (projectId, objsFromDashboard, options) {
return __awaiter(this, void 0, void 0, function () {
var originalFilterContext, toSave, filterContext;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
originalFilterContext = objsFromDashboard.filter(function (obj) { return _this.unwrapObj(obj).meta.category === "filterContext"; })[0];
toSave = {
filterContext: {
meta: this.getSanitizedMeta(originalFilterContext.filterContext.meta, options),
content: __assign({}, originalFilterContext.filterContext.content),
},
};
return [4 /*yield*/, this.metadataModule.createObject(projectId, toSave)];
case 1:
filterContext = (_a.sent()).filterContext;
return [2 /*return*/, filterContext.meta.uri];
}
});
});
};
MetadataModuleExt.prototype.getSanitizedMeta = function (originalMeta, options) {
return omit_1.default(originalMeta, compact_1.default([
"identifier",
"uri",
"author",
"created",
"updated",
"contributor",
options && options.clearLockedFlag && "locked",
]));
};
MetadataModuleExt.prototype.getObjectsFromDashboard = function (projectId, dashboardUri) {
return __awaiter(this, void 0, void 0, function () {
var uris;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getObjectsUrisInDashboard(projectId, dashboardUri)];
case 1:
uris = _a.sent();
return [2 /*return*/, this.metadataModule.getObjects(projectId, uris)];
}
});
});
};
MetadataModuleExt.prototype.getObjectsUrisInDashboard = function (projectId, dashboardUri) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.metadataModule.getObjectUsing(projectId, dashboardUri, {
types: ["kpi", "visualizationWidget", "filterContext"],
})];
case 1: return [2 /*return*/, (_a.sent()).map(function (obj) {
return obj.link;
})];
}
});
});
};
MetadataModuleExt.prototype.unwrapObj = function (obj) {
return obj[Object.keys(obj)[0]];
};
MetadataModuleExt.prototype.shouldCopyVisObj = function (options) {
return !!(options.copyVisObj || typeof options.copyVisObj === "undefined");
};
MetadataModuleExt.prototype.shouldCopyKpi = function (options) {
return !!(options.copyKpi || typeof options.copyKpi === "undefined");
};
return MetadataModuleExt;
}());
exports.MetadataModuleExt = MetadataModuleExt;