DashboardSpecHelper.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. 'use strict';
  2. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  3. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4. /**
  5. * Licensed Materials - Property of IBM
  6. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2018, 2020
  7. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  8. */
  9. define(['underscore', '../../app/util/GlassUtil', 'text!../schema/schemaDefs.json', 'text!../schema/schemaMappings.json', 'text!../schema/nameSchema.json', 'text!../schema/layoutSchema.json', 'text!../schema/layoutFragmentSchema.json', 'text!../schema/themeSchema.json', 'text!../schema/versionSchema.json', 'text!../schema/eventGroupsSchema.json', 'text!../schema/drillThroughSchema.json', 'text!../schema/propertiesSchema.json', 'text!../schema/pageContextSchema.json', 'text!../schema/widgetsSchema.json', 'text!../schema/widgetsFragmentSchema.json', 'text!../schema/widgetsTemplateSchema.json', 'jquery'], function (_, GlassUtil, SchemaDefs, SchemaMappings, NameSchema, LayoutSchema, LayoutFragmentSchema, ThemeSchema, VersionSchema, EventGroupsSchema, DrillThroughSchema, PropertiesSchema, PageContextSchema, WidgetsSchema, WidgetsFragmentSchema, WidgetsTemplateSchema, $) {
  10. var findObj = function findObj(ary, id) {
  11. return _.find(ary, function (ele) {
  12. return id === ele.id;
  13. });
  14. };
  15. var DashboardSpecHelper = function () {
  16. /**
  17. * Gets the spec content of a selected widget
  18. * @param {object} controller - the interaction controller (either a interaction/Controller or interaction/BaseController
  19. * from which the spec content is derived
  20. */
  21. function DashboardSpecHelper(controller) {
  22. _classCallCheck(this, DashboardSpecHelper);
  23. // TODO lifecycle_cleanup -- removethe controller dependency here
  24. this.controller = controller;
  25. this.dashboardApi = controller.dashboardApi;
  26. this.glassContext = controller.glassContext;
  27. this.logger = this.glassContext && this.glassContext.getCoreSvc ? this.glassContext.getCoreSvc('.Logger') : null;
  28. }
  29. /**
  30. * Gets the spec content of a widget
  31. * @param {boolean} pinning - indicates if the call was triggered from pinning. If so, get more content
  32. * @param {ContentAPI} content - ContentApi object to get the contentSpec from (Used through api when content is not from selection)
  33. * @returns returns the spec content for each selected node as an array element
  34. */
  35. DashboardSpecHelper.prototype.getContents = function getContents(pinning, content) {
  36. var _this = this;
  37. var specContents = [];
  38. var selectedContent = [];
  39. var internalAPI = this.dashboardApi.getFeature('internal');
  40. var boardModel = internalAPI.getBoardModel();
  41. var specVersion = boardModel.version;
  42. if (content) {
  43. selectedContent = [content];
  44. } else {
  45. selectedContent = this.dashboardApi.getCanvas().getSelectedContentList();
  46. }
  47. selectedContent.forEach(function (selectedContent) {
  48. var layoutModel = selectedContent.getFeature('Models.internal').getLayoutModel();
  49. var layoutWidgetIds = layoutModel.listWidgets([layoutModel.id]);
  50. var layoutWidgets = [];
  51. var nonMergedWidgets = [];
  52. var timelineEpisodes = [];
  53. var sourceIds = [];
  54. var errMsg = void 0;
  55. // ALERT! WARNING! DANGER! `widgetModel` is set in the loop below, and the last-instance of it is consumed
  56. // when setting specContent.drillThrough. Screwy javascript scoping rules for `var` types hid this,
  57. // but it's almost certianly a bug in some context?
  58. var widgetModel = void 0;
  59. for (var j = 0; j < layoutWidgetIds.length; j++) {
  60. var widgetContent = _this.dashboardApi.getCanvas().getContent(layoutWidgetIds[j]) || selectedContent.getContent(layoutWidgetIds[j]) || selectedContent;
  61. var internalModels = widgetContent.getFeature('Models.internal');
  62. widgetModel = internalModels.getWidgetModel();
  63. var mergedModel = _this._addFilterToWidgetModel(widgetModel);
  64. // Copy scenario, but don't copy filter widgets since filters are not supported
  65. if (!pinning) {
  66. if (widgetModel.type !== 'filter') {
  67. nonMergedWidgets.push(widgetModel);
  68. layoutWidgets.push(mergedModel);
  69. } else {
  70. errMsg = 'filterWidgetCopyWarn';
  71. }
  72. } else {
  73. layoutWidgets.push(mergedModel);
  74. }
  75. var timelineEpisodeForPinning = _this._getTimeLineEpisodeForPinning(boardModel, layoutWidgetIds[j]);
  76. if (timelineEpisodeForPinning) {
  77. timelineEpisodes.push(timelineEpisodeForPinning);
  78. }
  79. var viz = widgetContent.getFeature('Visualization');
  80. if (viz) {
  81. var dataSource = viz.getDataSource();
  82. var sourceId = dataSource ? dataSource.getId() : null;
  83. if (sourceId && sourceIds.indexOf(sourceId) === -1) {
  84. sourceIds.push(sourceId);
  85. }
  86. }
  87. }
  88. var dataSources = _this._getDataSources(sourceIds, boardModel.dataSources);
  89. var specContent = {
  90. specVersion: specVersion,
  91. layout: layoutModel,
  92. widgets: layoutWidgets,
  93. dataSources: dataSources,
  94. dashboardID: '',
  95. errMsg: errMsg,
  96. nodeCopied: true
  97. };
  98. if (errMsg) {
  99. specContent.nodeCopied = false;
  100. }
  101. // make this consistent with specContent.widgets
  102. specContent.nonMergedWidgets = nonMergedWidgets;
  103. if (selectedContent.getContainer()) {
  104. specContent.parentID = selectedContent.getContainer().getId();
  105. }
  106. if (boardModel.drillThrough && typeof boardModel.drillThrough.getModels === 'function') {
  107. var drillThroughService = _this.dashboardApi.getDashboardCoreSvc('DrillThroughService');
  108. // ALERT! WARNING! DANGER! (see above)
  109. specContent.drillThrough = drillThroughService.getDrillThroughByWidgetAndGroups(widgetModel);
  110. }
  111. if (boardModel.properties && boardModel.properties.customColors) {
  112. specContent.properties = {
  113. customColors: {
  114. colors: boardModel.properties.customColors.colors
  115. }
  116. };
  117. }
  118. if (boardModel.fredIsRed) {
  119. specContent.fredIsRed = boardModel.fredIsRed;
  120. }
  121. // TODO: instead of stripping out a known attribute, we should ignore anything runtime/transient attribute (eg. runtimeOnly flag) in the model.
  122. // When explicitScale is set to truthy, the VIDA normalization is not set; hence we does not want this property
  123. if (layoutModel.content && layoutModel.content.properties) {
  124. var contentProperties = Object.keys(layoutModel.content && layoutModel.content.properties);
  125. if (contentProperties.indexOf('explicitScale') !== -1) {
  126. delete specContent.layout.content.properties['explicitScale'];
  127. }
  128. }
  129. // Time Line model exists
  130. if (timelineEpisodes.length > 0) {
  131. specContent.episodes = timelineEpisodes;
  132. }
  133. // pageContext only needs to be added once
  134. if (specContents.length === 0) {
  135. var pageContext = _this._getPageContext(boardModel.pageContext);
  136. if (pageContext && pageContext.length) {
  137. specContent.pageContext = pageContext;
  138. // also add dashboard id, top level of the layout (needed to determine if pasting in the same DB)
  139. if (_this.controller.layoutController.topLayoutModel.id) {
  140. specContent.dashboardID = _this.controller.layoutController.topLayoutModel.id;
  141. }
  142. }
  143. }
  144. specContents.push(specContent);
  145. });
  146. return specContents;
  147. };
  148. /**
  149. * Gets all the filters applied on the widget
  150. * @param {Object} widgetModel - the widget associated inside the spec
  151. * @returns returns the widget obj adding the filters if any
  152. */
  153. DashboardSpecHelper.prototype._addFilterToWidgetModel = function _addFilterToWidgetModel(widgetModel) {
  154. var content = this.dashboardApi.getCanvas().getContent(widgetModel.id);
  155. var legacyVisualization = content && content.getFeature('Visualization.legacy');
  156. if (legacyVisualization) {
  157. var widgetModelClone = $.extend(true, {}, widgetModel);
  158. var portableFilters = legacyVisualization.getLegacyManagers().visFilterSupport.getAllFiltersAsLocalFiltersForPinning();
  159. if (portableFilters) {
  160. widgetModelClone.localFilters = portableFilters;
  161. delete widgetModelClone.filters;
  162. }
  163. return widgetModelClone;
  164. } else {
  165. return widgetModel;
  166. }
  167. };
  168. /**
  169. * Gets the spec content of a widget as JSON, it assumes that no pinning content is needed
  170. * @param {ContentAPI} content (Optional - if undefined, the selected content list will be used instead)
  171. * @returns {Object} Returns an object which contains the spec content represented as JSON, use property `spec` to access the spec JSON string
  172. */
  173. DashboardSpecHelper.prototype.getContentsToJSONSpec = function getContentsToJSONSpec(content) {
  174. var JSONcontent = {};
  175. var JSONSpec = void 0;
  176. var specContents = this.getContents(false, content);
  177. var assets = _.countBy(specContents, function (content) {
  178. return content.nodeCopied ? 'copied' : 'notCopied';
  179. });
  180. specContents = this._removeErrorsFromSpec(specContents, JSONcontent);
  181. if (specContents.length) {
  182. if (specContents[0].specVersion) {
  183. JSONcontent.specVersion = specContents[0].specVersion;
  184. }
  185. JSONcontent.layout = _.map(specContents, function (content) {
  186. return content.layout.toJSON();
  187. });
  188. JSONcontent.parentID = _.map(specContents, function (content) {
  189. return content.parentID;
  190. });
  191. JSONcontent.pageContext = _.map(specContents[0].pageContext, function (content) {
  192. return content.toJSON();
  193. });
  194. JSONcontent.dashboardID = specContents[0].dashboardID;
  195. JSONcontent.widgets = _.chain(specContents).map(function (content) {
  196. return content.widgets;
  197. }).flatten().map(function (widget) {
  198. return widget.toJSON();
  199. }).value();
  200. JSONcontent.nonMergedWidgets = _.chain(specContents).map(function (content) {
  201. return content.nonMergedWidgets;
  202. }).flatten().map(function (widget) {
  203. return widget.toJSON();
  204. }).value();
  205. JSONcontent.dataSources = {};
  206. JSONcontent.dataSources.version = specContents[0].dataSources.version;
  207. JSONcontent.dataSources.sources = [];
  208. var resultDrillThroughDefinitions = [];
  209. _.each(specContents, function (content) {
  210. _.each(content.dataSources.sources, function (source) {
  211. var idx = -1;
  212. // if the dataSource is already there, don't add it again
  213. if (JSONcontent.dataSources.sources.length > 0) {
  214. idx = JSONcontent.dataSources.sources.findIndex(function (ele) {
  215. return ele.id === source.id;
  216. });
  217. }
  218. if (idx < 0) {
  219. var sourceJSON = source.toJSON();
  220. // if the datasource is saved as an embedded module, the embedded module is saved
  221. // as an attachment to the original dashboard object in CM. Sharing the embedded module
  222. // can lead to side effects which was not intended from the original dashboard, which
  223. // leads to a stale datasource.
  224. // Remove the embeddedModuleId so that the target dashboard does not share the embedded module
  225. // with the source dashboard, but rather builds its own embedded module.
  226. if (sourceJSON && sourceJSON.shaping && sourceJSON.shaping.embeddedModuleId) {
  227. delete sourceJSON.shaping.embeddedModuleId;
  228. delete sourceJSON.shaping.embeddedModuleName;
  229. sourceJSON.shaping.embeddedModuleUpToDate = false;
  230. }
  231. JSONcontent.dataSources.sources.push(sourceJSON);
  232. }
  233. });
  234. // Add drill through definitions from selected widget without duplicates.
  235. if (content.drillThrough && content.drillThrough.length) {
  236. content.drillThrough.forEach(function (drillDefinition) {
  237. var definitionExists = _.find(resultDrillThroughDefinitions, function (resultDefinition) {
  238. return resultDefinition.id === drillDefinition.id;
  239. });
  240. if (!definitionExists) {
  241. resultDrillThroughDefinitions.push(drillDefinition.toJSON());
  242. }
  243. });
  244. }
  245. });
  246. if (specContents[0].properties) {
  247. JSONcontent.properties = specContents[0].properties;
  248. }
  249. if (specContents[0].fredIsRed) {
  250. JSONcontent.fredIsRed = specContents[0].fredIsRed;
  251. }
  252. if (resultDrillThroughDefinitions.length) {
  253. JSONcontent.drillThrough = resultDrillThroughDefinitions;
  254. }
  255. var episodes = _.chain(specContents).map(function (content) {
  256. return content.episodes;
  257. }).flatten().filter(Boolean).map(function (episode) {
  258. return episode.toJSON();
  259. }).value();
  260. if (episodes.length) {
  261. JSONcontent.episodes = episodes;
  262. }
  263. }
  264. if (JSONcontent) {
  265. JSONSpec = JSON.stringify(JSONcontent, null, 4);
  266. }
  267. return {
  268. spec: JSONSpec,
  269. count: assets.copied,
  270. errMsg: JSONcontent.errMsg
  271. };
  272. };
  273. /**
  274. * Validates a dashboard JSON spec
  275. * @param {string} spec - spec to validate
  276. * @param {array} retErrors - (optional), if present, all errors are added to it and not shown in the Dashboard.
  277. * The object is {schema,schemaCondition,schemaKeyword,schemaDataPath,data,msg};
  278. * @returns returns the JSON objects of the valid spec, otherwise null if validation fails
  279. */
  280. DashboardSpecHelper.prototype.validateDashboardSpec = function validateDashboardSpec(spec, retErrors) {
  281. var _this2 = this;
  282. return Promise.resolve().then(function () {
  283. var defaultSchema = 'noSchema';
  284. var defaultSchemaCondition = 'noSchemaCondition';
  285. var defaultSchemaKeyword = 'noSchemaKeyword';
  286. var defaultSchemaDataPath = 'noSchemaDataPath';
  287. var defaultData = 'noData';
  288. var defaultMsg = 'noMsg';
  289. var errorObj = {
  290. 'schema': defaultSchema,
  291. 'schemaCondition': defaultSchemaCondition,
  292. 'schemaKeyword': defaultSchemaKeyword,
  293. 'schemaDataPath': defaultSchemaDataPath,
  294. 'data': defaultData,
  295. 'msg': defaultMsg
  296. };
  297. var outSpec = void 0;
  298. try {
  299. outSpec = JSON.parse(spec);
  300. } catch (err) {
  301. var msg = 'Invalid JSON provided';
  302. if (_this2.logger) {
  303. _this2.logger.error(msg, err, _this2);
  304. }
  305. if (retErrors !== undefined && retErrors !== null && _.isArray(retErrors)) {
  306. var errObj = Object.create(errorObj);
  307. errObj.data = err;
  308. errObj.msg = msg;
  309. retErrors.push(errObj);
  310. return null;
  311. } else {
  312. throw new Error('invalidJSONResponse');
  313. }
  314. }
  315. // finds a widget
  316. function findWidget(id, type, widgetIds) {
  317. if (type === 'widget') {
  318. var widget = findObj(outSpec.widgets, id);
  319. if (!widget) {
  320. // if widget can not be found, save layout id
  321. widgetIds.push(id);
  322. }
  323. }
  324. }
  325. // recursively finds widgets
  326. function findWidgets(items, widgetIds) {
  327. _.each(items, function (item) {
  328. return item.items ? findWidgets(item.items, widgetIds) : findWidget(item.id, item.type, widgetIds);
  329. });
  330. }
  331. var errors = [];
  332. // check for empty spec
  333. var specFragment = false;
  334. if (!outSpec || Object.keys(outSpec).length === undefined || Object.keys(outSpec).length === 0) {
  335. // signal error
  336. var _msg = 'Spec is empty';
  337. if (retErrors !== undefined && retErrors !== null && _.isArray(retErrors)) {
  338. var _errObj = Object.create(errorObj);
  339. _errObj.msg = _msg;
  340. retErrors.push(_errObj);
  341. return null;
  342. } else {
  343. throw new Error(_msg);
  344. }
  345. } else if (Array.isArray(outSpec.layout)) {
  346. // spec fragment since the only other choice is an array
  347. specFragment = true;
  348. }
  349. // if in production, do not validate the spec against schemas
  350. if (!GlassUtil.isDevMode(_this2.glassContext)) {
  351. return outSpec;
  352. }
  353. return _this2._getAjv().then(function (ajv) {
  354. // use key/value pair to determine which schema to use with a spec key
  355. var shmaMappings = JSON.parse(SchemaMappings);
  356. // validate all of the spec, accumulate errors if any
  357. Object.keys(outSpec).forEach(function (specKey) {
  358. var keySchema = shmaMappings[specKey];
  359. if (specFragment && specKey === 'layout') {
  360. keySchema = shmaMappings['layoutFragment'];
  361. }
  362. if (specFragment && specKey === 'widgets') {
  363. keySchema = shmaMappings['widgetsFragment'];
  364. }
  365. var specValue = outSpec[specKey];
  366. if (keySchema) {
  367. var validate = ajv.getSchema(keySchema);
  368. if (validate) {
  369. if (!validate(specValue)) {
  370. // each call to validate destroys any previous errors so much save them
  371. validate.errors.forEach(function (error) {
  372. var errObj = Object.create(errorObj);
  373. errObj.schema = error.schemaPath;
  374. errObj.schemaCondition = error.parentSchema;
  375. errObj.schemaKeyword = error.keyword;
  376. errObj.schemaDataPath = error.dataPath;
  377. errObj.data = error.data;
  378. errObj.msg = error.message;
  379. errors.push(errObj);
  380. });
  381. }
  382. }
  383. }
  384. // NOTE: for now leave this commented out since we don't have schemas for all spec keys
  385. // else {
  386. // generate error, invalid key
  387. // errors.push( {
  388. // 'msg': 'Spec Key: ' + specKey + ' does not exists in schema mapping definition'
  389. // });
  390. // }
  391. });
  392. // semantic checks
  393. // 1. check widget id in layout to make sure there is a widget in the spec for it. If any widget ids are returned,
  394. // then there is no widget object for it
  395. var widgetIds = [];
  396. if (outSpec.widgets) {
  397. if (outSpec.layout.items) {
  398. findWidgets(outSpec.layout.items, widgetIds);
  399. } else {
  400. findWidgets(outSpec.layout, widgetIds);
  401. }
  402. if (widgetIds.length) {
  403. var _errObj2 = Object.create(errorObj);
  404. _errObj2.schema = defaultSchema;
  405. _errObj2.schemaDataPath = defaultSchemaDataPath;
  406. _errObj2.schemaKeyword = defaultSchemaKeyword;
  407. _errObj2.data = defaultData;
  408. _errObj2.schemaCondition = 'semantic layout widget id check';
  409. _errObj2.msg = 'No widget objects in the specification for layout ids ' + widgetIds.toString();
  410. errors.push(_errObj2);
  411. }
  412. }
  413. if (errors.length) {
  414. outSpec = null;
  415. if (retErrors !== undefined && retErrors !== null && _.isArray(retErrors)) {
  416. retErrors.push(errors);
  417. } else {
  418. // log all errors
  419. if (_this2.logger) {
  420. _.each(errors, function (err) {
  421. var msg = void 0;
  422. if (err.msg !== defaultMsg) {
  423. msg = ' error: ' + err.msg;
  424. }
  425. if (err.data !== defaultData) {
  426. msg += ' data: ' + err.data;
  427. }
  428. if (err.schema !== defaultSchema) {
  429. msg += ' schema: ' + err.schema;
  430. }
  431. if (err.schemaCondition !== defaultSchemaCondition) {
  432. msg += ' schema defn: ' + err.schemaCondition.$id;
  433. }
  434. _this2.logger.error('schema validation error:', msg, _this2);
  435. });
  436. }
  437. throw new Error('schema validation errors logged above');
  438. }
  439. }
  440. return outSpec;
  441. });
  442. });
  443. };
  444. DashboardSpecHelper.prototype._getAjv = function _getAjv() {
  445. var _this3 = this;
  446. if (this.ajv) {
  447. return Promise.resolve(this.ajv);
  448. } else {
  449. return new Promise(function (resolve, reject) {
  450. require(['ajv'], function (Ajv) {
  451. try {
  452. var shmaDefs = JSON.parse(SchemaDefs);
  453. // let shma = JSON.parse(Schema);
  454. var nameShma = JSON.parse(NameSchema);
  455. var layoutSchema = _this3._getLayoutSchema();
  456. var layoutFragmentShma = JSON.parse(LayoutFragmentSchema);
  457. var themeShma = JSON.parse(ThemeSchema);
  458. var versionShma = JSON.parse(VersionSchema);
  459. var evtGrpsShma = JSON.parse(EventGroupsSchema);
  460. var drillThroughShma = JSON.parse(DrillThroughSchema);
  461. var propertiesShma = JSON.parse(PropertiesSchema);
  462. var pageContextShma = JSON.parse(PageContextSchema);
  463. var widgetsShma = JSON.parse(WidgetsSchema);
  464. var widgetsFragmentShma = JSON.parse(WidgetsFragmentSchema);
  465. var widgetsTemplateSchema = JSON.parse(WidgetsTemplateSchema);
  466. _this3.ajv = new Ajv({ allErrors: true, verbose: true, schemas: [shmaDefs, nameShma, layoutSchema, layoutFragmentShma, themeShma, versionShma, evtGrpsShma, drillThroughShma, propertiesShma, pageContextShma, widgetsShma, widgetsFragmentShma, widgetsTemplateSchema] });
  467. resolve(_this3.ajv);
  468. } catch (err) {
  469. reject(err);
  470. }
  471. }, reject);
  472. });
  473. }
  474. };
  475. /**
  476. * get layout schema, it will add the registered types to the layoutType.enum
  477. * @returns the layout schema
  478. */
  479. DashboardSpecHelper.prototype._getLayoutSchema = function _getLayoutSchema() {
  480. var layoutSchema = JSON.parse(LayoutSchema);
  481. var contentTypeRegistry = this.dashboardApi.getFeature('ContentTypeRegistry');
  482. var layoutTypeEnum = layoutSchema.definitions.layoutType.enum;
  483. layoutSchema.definitions.layoutType.enum = layoutTypeEnum.concat(contentTypeRegistry.getRegisteredTypes());
  484. return layoutSchema;
  485. };
  486. /**
  487. * Creates an datasource spec object
  488. * @param {array} sourceIds - array of data source ids
  489. * @param {object} dataSources - array of datasources
  490. * @returns returns an object containing the datasource version and source objects
  491. */
  492. DashboardSpecHelper.prototype._getDataSources = function _getDataSources(sourceIds, dataSources) {
  493. var copiedInfo = {
  494. version: '0.0',
  495. sources: []
  496. };
  497. if (dataSources && (typeof dataSources === 'undefined' ? 'undefined' : _typeof(dataSources)) === 'object') {
  498. copiedInfo.version = dataSources.version;
  499. var sources = copiedInfo.sources;
  500. sourceIds.forEach(function (id) {
  501. sources.push(dataSources.get('sources').get(id));
  502. });
  503. }
  504. return copiedInfo;
  505. };
  506. /**
  507. * @param boardModel the boardModel
  508. * @param layoutWidgetId The layout id for the widget being processed.
  509. * @returns the timelineEpisode for widget which is attached to the pin for this layoutWidgetId. or null if there is none.
  510. * The model is returned from the board spec.
  511. *
  512. */
  513. DashboardSpecHelper.prototype._getTimeLineEpisodeForPinning = function _getTimeLineEpisodeForPinning(boardModel, layoutWidgetId) {
  514. if (boardModel.timeline && typeof this.controller.boardModel.timeline.get === 'function') {
  515. return boardModel.timeline.episodes.get(layoutWidgetId);
  516. }
  517. return null;
  518. };
  519. /**
  520. * Get current tab and global pageContexts
  521. * @param {array} pageContext - pageContext objects
  522. */
  523. DashboardSpecHelper.prototype._getPageContext = function _getPageContext(pageContext) {
  524. if (pageContext && pageContext.getModels().length) {
  525. var pageCxt = [];
  526. var tabId = this.controller.layoutController.getCurrentSubViewId();
  527. _.each(pageContext.getModels(), function (pc) {
  528. if (pc.getScope() === tabId || pc.getScope() === 'global') {
  529. pageCxt.push(pc);
  530. }
  531. });
  532. return pageCxt;
  533. }
  534. };
  535. /**
  536. * checks spec contents object for filter widget (denoted by errMsg being defined) and removes that element from the array
  537. * @param {array} specContents - content objects
  538. * @param {object} jsonContent - content to be converted to json object
  539. */
  540. DashboardSpecHelper.prototype._removeErrorsFromSpec = function _removeErrorsFromSpec(specContents, jsonContent) {
  541. jsonContent.errMsg = _.first(_.compact(_.map(specContents, function (content) {
  542. return content.errMsg;
  543. })));
  544. if (jsonContent.errMsg) {
  545. // keep the widget(s) that are not in error
  546. return _.filter(specContents, function (content) {
  547. return content.errMsg === undefined;
  548. });
  549. }
  550. return specContents;
  551. };
  552. return DashboardSpecHelper;
  553. }();
  554. return DashboardSpecHelper;
  555. });
  556. //# sourceMappingURL=DashboardSpecHelper.js.map