DashboardPinningService.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. 'use strict';
  2. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  4. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  5. /**
  6. * Licensed Materials - Property of IBM
  7. * IBM Cognos Products: BI
  8. * (C) Copyright IBM Corp. 2018, 2020
  9. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  10. */
  11. define(['../../../lib/@waca/core-client/js/core-client/ui/core/Events', '../../../app/nls/StringResources', 'underscore', '../../../lib/@waca/core-client/js/core-client/i18n/Formatter', 'moment-timezone'], function (Events, StringResources, _, Formatter, moment) {
  12. var DashboardPinningService = function (_Events) {
  13. _inherits(DashboardPinningService, _Events);
  14. function DashboardPinningService() {
  15. _classCallCheck(this, DashboardPinningService);
  16. var _this = _possibleConstructorReturn(this, _Events.call(this, arguments));
  17. _this.PIN_VERSION = '3';
  18. _this.PIN_URL = 'v1/users/~/pins';
  19. _this._pinIdsToUpgradeInCM = [];
  20. _this._timeframePinBuckets = null;
  21. _this._timeframePinBucketNames = ['all', 'today', 'yesterday', 'pastWeek', 'pastMonth', 'earlier'];
  22. _this._pinIdMap = {};
  23. return _this;
  24. }
  25. DashboardPinningService.prototype.initialize = function initialize(_ref) {
  26. var _this2 = this;
  27. var appController = _ref.appController;
  28. this._glassContext = appController.glassContext;
  29. return this._glassContext.getSvc('.UpgradeService').then(function (upgrades) {
  30. _this2._latestDashboardSpecVersion = upgrades.getLatestDashboardSpecVersion();
  31. // Do some work ahead of time to figure out our time buckets
  32. var userProfileService = _this2._glassContext.getCoreSvc('.UserProfile');
  33. _this2._timezone = userProfileService.preferences.timeZoneID || 'America/New_York';
  34. _this2._today = moment().tz(_this2._timezone).startOf('day');
  35. _this2._yesterday = _this2._today.clone().subtract(1, 'days');
  36. _this2._pastWeek = _this2._today.clone().subtract(7, 'days');
  37. _this2._pastMonth = _this2._today.clone().subtract(31, 'days');
  38. });
  39. };
  40. /**
  41. * Used by search UI to get the cached pins. This UI only renders after we've queried for the pins,
  42. * so we return without a promise here which is what the search logic needs.
  43. * @param {String} timeframe
  44. */
  45. DashboardPinningService.prototype.getCachedPins = function getCachedPins() {
  46. var timeframe = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'all';
  47. return this._timeframePinBuckets[timeframe] || [];
  48. };
  49. /**
  50. * Get the list of pins from the server
  51. * @param {String} timeframe - Must be one of the following 'all', 'today', 'yesterday', 'pastWeek', 'pastMonth', 'earlier'
  52. */
  53. DashboardPinningService.prototype.getPins = function getPins() {
  54. var _this3 = this;
  55. var timeframe = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'all';
  56. if (this._timeframePinBuckets) {
  57. return Promise.resolve(this._timeframePinBuckets[timeframe]);
  58. }
  59. return this._glassContext.getCoreSvc('.Ajax').ajax({
  60. url: this.PIN_URL,
  61. type: 'GET',
  62. contentType: 'application/json; charset=utf-8',
  63. dataType: 'json'
  64. }).then(function () {
  65. var response = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  66. _this3._timeframePinBuckets = { all: [], today: [], yesterday: [], pastWeek: [], pastMonth: [], earlier: [] };
  67. // Upgrade the pins locally (on the client) before returning them. We'll update the pins on the server lazilly
  68. return _this3._upgradePinsLocally(response.data);
  69. }).then(function (upgradedPins) {
  70. var pins = _this3._sortPins(upgradedPins);
  71. _this3._prepPinsForUI(pins);
  72. _this3._cachePinsInAppropriateTimeFrameBuckets(pins);
  73. // No need to wait for this to finish before the UI can render
  74. _this3._slowlySaveUpgradedPinsInCM();
  75. return _this3._timeframePinBuckets[timeframe];
  76. }).catch(function (result) {
  77. _this3._glassContext.getCoreSvc('.Logger').error('Failed to get pins', result);
  78. var message = _this3._retrieveErrorMessage({
  79. result: result,
  80. defaultMessage: StringResources.get('pinRetrieveError')
  81. });
  82. _this3._glassContext.appController.showErrorMessage(message, StringResources.get('pinErrorTitle'));
  83. return [];
  84. });
  85. };
  86. /**
  87. * Get the pin for the given ID
  88. * @param {String} pinId
  89. */
  90. DashboardPinningService.prototype.getPin = function getPin(pinId) {
  91. if (this._pinIdMap[pinId]) {
  92. return Promise.resolve(this._pinIdMap[pinId]);
  93. }
  94. // We should never ask for a specific pin before querying all of them.. safe guard in case we do for some odd reason.
  95. return this.getPins().then(function (pins) {
  96. return _.find(pins, function (pin) {
  97. return pin.id === pinId;
  98. });
  99. });
  100. };
  101. /**
  102. * Saves a pin in CM
  103. * @param {Object} pin Pin object to save
  104. */
  105. DashboardPinningService.prototype.addPin = function addPin(pin) {
  106. var _this4 = this;
  107. pin.version = this.PIN_VERSION;
  108. var pinJSON = JSON.stringify(pin);
  109. return this._glassContext.getCoreSvc('.Ajax').ajax({
  110. type: 'POST',
  111. url: this.PIN_URL,
  112. contentType: 'application/json; charset=utf-8',
  113. dataType: 'json',
  114. data: pinJSON
  115. }).then(function () {
  116. var result = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  117. var newPin = result.data;
  118. _this4._prepPinsForUI([newPin]);
  119. _this4._addPinToCache(newPin, ['all', 'today', 'pastWeek', 'pastMonth'], true);
  120. _this4.trigger('pin:created', newPin);
  121. return newPin;
  122. }).catch(function (result) {
  123. var message = _this4._retrieveErrorMessage({
  124. result: result,
  125. defaultMessage: StringResources.get('contentPinFailOld')
  126. });
  127. var error = new Error(message);
  128. _this4._glassContext.getCoreSvc('.Logger').error('addPin error', error);
  129. throw error;
  130. });
  131. };
  132. /**
  133. * Removes the pin locally and shows a toast. Once the toast goes away (can no longer undo)
  134. * we complete the delete by deleting it from CM
  135. * @param {String} pinId
  136. */
  137. DashboardPinningService.prototype.deletePin = function deletePin(pinId) {
  138. var _this5 = this;
  139. return new Promise(function (resolve, reject) {
  140. try {
  141. if (_this5._glassContext.getCoreSvc('.UserProfile').preferences.accessibilityFeatures) {
  142. _this5._glassContext.appController.showMessage(StringResources.get('deletePinConfirmationMessage'), StringResources.get('deletePinConfirm'), 'info', ['ok', 'cancel'], undefined, function (evt) {
  143. if (evt.btn === 'ok') {
  144. _this5._removePinFromCache(pinId);
  145. _this5.trigger('pin:fakeDeleted', pinId);
  146. _this5._completePinDelete(pinId);
  147. }
  148. resolve();
  149. });
  150. } else {
  151. var removedInfo = _this5._removePinFromCache(pinId);
  152. if (!removedInfo.removedPin) {
  153. _this5._glassContext.getCoreSvc('.Logger').error('Trying to remove a pin that is not in our array', pinId, _this5);
  154. }
  155. _this5.trigger('pin:fakeDeleted', pinId);
  156. var undidDelete = false;
  157. _this5._glassContext.appController.showToast(StringResources.get('pinDeletedToast'), {
  158. type: 'info',
  159. btnLabel: StringResources.get('undo'),
  160. callback: function callback() {
  161. undidDelete = true;
  162. _this5._addPinToCache(removedInfo.removedPin, removedInfo.timeframeBucketNames, false, true);
  163. _this5.trigger('pin:undoDeletion', pinId);
  164. },
  165. newestOnTop: true,
  166. preventDuplicates: false,
  167. timeOut: 6000,
  168. extendedTimeOut: 1000,
  169. onHidden: function onHidden() {
  170. if (!undidDelete) {
  171. _this5._completePinDelete(pinId);
  172. }
  173. resolve();
  174. }
  175. });
  176. }
  177. } catch (error) {
  178. reject(error);
  179. }
  180. });
  181. };
  182. /**
  183. * The toast message is gone so it's safe to delete the pin from CM
  184. */
  185. DashboardPinningService.prototype._completePinDelete = function _completePinDelete(pinId) {
  186. var _this6 = this;
  187. // If the pin we've just deleted is still in the queue to update in CM then remove it from the queue
  188. this._pinIdsToUpgradeInCM = this._pinIdsToUpgradeInCM.filter(function (id) {
  189. return id !== pinId;
  190. });
  191. return this._glassContext.getCoreSvc('.Ajax').ajax({
  192. type: 'DELETE',
  193. url: this.PIN_URL + '/' + pinId,
  194. contentType: 'application/json; charset=utf-8',
  195. dataType: 'json'
  196. }).then(function () {
  197. var result = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  198. _this6.trigger('pin:deleted', pinId);
  199. return result;
  200. }).catch(function (result) {
  201. var message = _this6._retrieveErrorMessage({
  202. result: result,
  203. defaultMessage: StringResources.get('pinDeleteErrorOld')
  204. });
  205. var error = new Error(message);
  206. _this6._glassContext.appController.showErrorMessage(message, StringResources.get('pinErrorTitle'));
  207. _this6._glassContext.getCoreSvc('.Logger').error('deletePin error', error);
  208. throw error;
  209. });
  210. };
  211. /**
  212. * Go through the upgraded pins one by one and push the upgraded spec to CM. Only
  213. * send one PUT request at a time to not hurt performance for the user.
  214. */
  215. DashboardPinningService.prototype._slowlySaveUpgradedPinsInCM = function _slowlySaveUpgradedPinsInCM() {
  216. var _this7 = this;
  217. var pinId = this._pinIdsToUpgradeInCM.shift();
  218. if (pinId) {
  219. return this.getPin(pinId).then(function (pin) {
  220. _this7._glassContext.getCoreSvc('.Logger').info('Updating upgraded pin spec in CM', pin);
  221. return _this7._glassContext.getCoreSvc('.Ajax').ajax({
  222. type: 'PUT',
  223. url: _this7.PIN_URL + '/' + pinId,
  224. contentType: 'application/json; charset=utf-8',
  225. dataType: 'json',
  226. data: JSON.stringify(pin)
  227. }).then(function () {
  228. return _this7._slowlySaveUpgradedPinsInCM();
  229. }).catch(function (error) {
  230. // Stop trying to save the upgrades on the first error. Possible timeout or logged off.
  231. _this7._glassContext.getCoreSvc('.Logger').error('Pin upgrade failed to save in CM.', error);
  232. });
  233. });
  234. }
  235. return Promise.resolve();
  236. };
  237. /**
  238. * Removes a pin from our caches
  239. * @param {String} pinId
  240. */
  241. DashboardPinningService.prototype._removePinFromCache = function _removePinFromCache(pinId) {
  242. var _this8 = this;
  243. if (this._pinIdMap) {
  244. delete this._pinIdMap[pinId];
  245. }
  246. // Need to keep track of the timeframe buckets this pin was in case the user undoes the delete
  247. var timeframeBucketNames = [];
  248. var removedPin = null;
  249. if (this._timeframePinBuckets) {
  250. var filterOutPin = function filterOutPin(pin, timeframeBucketName) {
  251. if (pin.id === pinId) {
  252. removedPin = pin;
  253. timeframeBucketNames.push(timeframeBucketName);
  254. return false;
  255. }
  256. return true;
  257. };
  258. this._timeframePinBucketNames.forEach(function (bucketName) {
  259. _this8._timeframePinBuckets[bucketName] = _this8._timeframePinBuckets[bucketName].filter(function (pin) {
  260. return filterOutPin(pin, bucketName);
  261. });
  262. });
  263. }
  264. return {
  265. removedPin: removedPin,
  266. timeframeBucketNames: timeframeBucketNames
  267. };
  268. };
  269. /**
  270. * Adds a pin to our caches
  271. * @param {Object} pin - the pin to add
  272. * @param {[String]} buckets - the list of buckets to add the pin to
  273. * @param {Boolean} addToBeginning - Should the pin get added to the beginning of the list
  274. * @param {Boolean} sortPins - should the timeframe bucket be sorted after the pin gets added.
  275. */
  276. DashboardPinningService.prototype._addPinToCache = function _addPinToCache(pin) {
  277. var buckets = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this._timeframePinBucketNames;
  278. var _this9 = this;
  279. var addToBeginning = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  280. var sortPins = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
  281. // If we haven't queried for all the pins yet then no need to add the pin. We'll grab them
  282. // all when the pin panel is open.
  283. if (!this._timeframePinBuckets) {
  284. return;
  285. }
  286. this._pinIdMap[pin.id] = pin;
  287. buckets.forEach(function (bucket) {
  288. if (addToBeginning) {
  289. _this9._timeframePinBuckets[bucket].unshift(pin);
  290. } else {
  291. _this9._timeframePinBuckets[bucket].push(pin);
  292. }
  293. // Currently only true when we undo a delete. We need to resort the buckets once the pin is placed back
  294. if (sortPins) {
  295. _this9._sortPins(_this9._timeframePinBuckets[bucket]);
  296. }
  297. });
  298. };
  299. DashboardPinningService.prototype._retrieveErrorMessage = function _retrieveErrorMessage(input) {
  300. input = input || {};
  301. var message = input.defaultMessage;
  302. try {
  303. var text = JSON.parse(input.result.responseText);
  304. message = text.error;
  305. } catch (e) {
  306. // ignore JSON parsing errors
  307. }
  308. return message;
  309. };
  310. /**
  311. * Convert properties from the pin object to the required values for the UI
  312. */
  313. DashboardPinningService.prototype._prepPinsForUI = function _prepPinsForUI(pins) {
  314. var _this10 = this;
  315. var dashboardApi = this._getCurrentContentViewDashboardApi();
  316. var smartNamingService = dashboardApi.getDashboardCoreSvc('.SmartNamingSvc');
  317. pins.forEach(function (pin) {
  318. // process pin date
  319. if (pin.timestamp) {
  320. pin.pinAge = Formatter.formatDateTime(pin.timestamp, {
  321. type: 'datetime',
  322. formatLength: 'short',
  323. timezone: _this10._timezone
  324. });
  325. }
  326. // smart name
  327. pin.displayName = smartNamingService.getPinName(pin);
  328. // check for pin image
  329. if (!pin.thumbUri) {
  330. pin.defaultImage = 'wfg_pin';
  331. }
  332. });
  333. };
  334. /**
  335. * Caches the pins into their timeframe buckets
  336. */
  337. DashboardPinningService.prototype._cachePinsInAppropriateTimeFrameBuckets = function _cachePinsInAppropriateTimeFrameBuckets(pins) {
  338. var _this11 = this;
  339. pins.forEach(function (pin) {
  340. var timestamp = moment.tz(pin.timestamp, _this11._timezone);
  341. _this11._timeframePinBuckets.all.push(pin);
  342. var timeframeBucketNames = null;
  343. if (timestamp.isSame(_this11._today, 'day')) {
  344. timeframeBucketNames = ['today', 'pastWeek', 'pastMonth'];
  345. } else if (timestamp.isSame(_this11._yesterday, 'day')) {
  346. timeframeBucketNames = ['yesterday', 'pastWeek', 'pastMonth'];
  347. } else if (timestamp.isAfter(_this11._pastWeek)) {
  348. timeframeBucketNames = ['pastWeek', 'pastMonth'];
  349. } else if (timestamp.isAfter(_this11._pastMonth)) {
  350. timeframeBucketNames = ['pastMonth'];
  351. } else {
  352. timeframeBucketNames = ['earlier'];
  353. }
  354. _this11._addPinToCache(pin, timeframeBucketNames);
  355. });
  356. };
  357. /**
  358. * Sorts the given array of pins by modified date, with the newest first in the list.
  359. */
  360. DashboardPinningService.prototype._sortPins = function _sortPins(pins) {
  361. return pins.sort(function (a, b) {
  362. var aTime = a.timestamp;
  363. var bTime = b.timestamp;
  364. return aTime > bTime ? -1 : aTime < bTime ? 1 : 0;
  365. });
  366. };
  367. /**
  368. * Upgrade the pin specs but do not push the upgraded specs to CM yet. We'll do that slowly once we render the Pins panel
  369. * @param {*} pins
  370. */
  371. DashboardPinningService.prototype._upgradePinsLocally = function _upgradePinsLocally() {
  372. var _this12 = this;
  373. var pins = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  374. //const upgradePromises = [];
  375. var upgradeOptions = {
  376. ajaxSvc: this._glassContext.getCoreSvc('.Ajax'),
  377. services: this._getCurrentContentViewServices(),
  378. logger: this._glassContext.getCoreSvc('.Logger'),
  379. pinUpgrade: true,
  380. glassContext: this._glassContext,
  381. dashboardApi: this._getCurrentContentViewDashboardApi(),
  382. showErrorToast: false
  383. };
  384. var pinsToUpgrade = [];
  385. return this._glassContext.getSvc('.UpgradeService').then(function (upgradeService) {
  386. pins.forEach(function (pin) {
  387. if (pin.content && pin.content.specVersion !== _this12._latestDashboardSpecVersion) {
  388. pinsToUpgrade.push(pin);
  389. }
  390. });
  391. if (pinsToUpgrade.length > 0) {
  392. console.log(pinsToUpgrade.length + ' pins to upgrade.');
  393. }
  394. /**
  395. * Our upgrade service uses static upgrade classes and some of those keep state during the upgrade process.
  396. * For this reason we have to run the upgrades in sequence instead of in parallel. Use the reduce method
  397. * to programatically chain promises
  398. */
  399. return new Promise(function (resolve) {
  400. var upgradePromise = pinsToUpgrade.reduce(function (currentPromise, pin) {
  401. return currentPromise.then(function () {
  402. try {
  403. return _this12._upgradePinSpec(pin, upgradeService, upgradeOptions).then(function () {
  404. _this12._pinIdsToUpgradeInCM.push(pin.id);
  405. }).catch(function (error) {
  406. // if one pin fails, omit it from the list and move on
  407. _this12._glassContext.getCoreSvc('.Logger').error('Unable to upgrade pin:', pin, 'Failed with error: ', error);
  408. });
  409. } catch (error) {
  410. // if one pin fails, omit it from the list and move on
  411. _this12._glassContext.getCoreSvc('.Logger').error('Unable to upgrade pin:', pin, 'Failed with error: ', error);
  412. }
  413. });
  414. }, Promise.resolve([]));
  415. upgradePromise.then(function () {
  416. resolve(pins);
  417. });
  418. });
  419. });
  420. };
  421. DashboardPinningService.prototype._upgradePinSpec = function _upgradePinSpec(pinSpec, upgradeService, upgradeOptions) {
  422. var _this13 = this;
  423. // assuming the board spec version is 6 if there is no version attribute
  424. var boardSpec = {
  425. version: pinSpec.version ? pinSpec.content.specVersion : 6,
  426. layout: pinSpec.content.layout,
  427. widgets: this._getObjectFromArrayById(pinSpec.content.widgets)
  428. };
  429. // Old pin specs used datasetShapings while every other part of the code uses datasetShaping
  430. if (pinSpec.content.datasetShapings) {
  431. boardSpec.datasetShaping = this._getObjectFromArrayById(pinSpec.content.datasetShapings);
  432. } else if (pinSpec.content.datasetShaping) {
  433. boardSpec.datasetShaping = this._getObjectFromArrayById(pinSpec.content.datasetShaping);
  434. }
  435. if (pinSpec.content.dataSources) {
  436. boardSpec.dataSources = pinSpec.content.dataSources;
  437. }
  438. if (pinSpec.content.episodes) {
  439. boardSpec.timeline = {
  440. episodes: this._getObjectFromArrayById(pinSpec.content.episodes)
  441. };
  442. }
  443. // save the original version
  444. var upgrades = pinSpec.content.upgrades || [];
  445. var original = boardSpec.version;
  446. if (upgrades.indexOf(original) === -1) {
  447. upgrades.push(original);
  448. pinSpec.content.upgrades = upgrades;
  449. } else {
  450. this._glassContext.getCoreSvc('.Logger').warn('Pin spec with id "' + pinSpec.id + '" and board spec version "' + pinSpec.content.specVersion + '" being upgraded to an previously upgraded spec version: ', original);
  451. }
  452. return upgradeService.upgrade(boardSpec, null /*means latest*/, upgradeOptions).then(function (upgradedBoardSpec) {
  453. // TODO the logic to create a pin spec from a board spec should be put in one place
  454. // currently it is here and in PinAction. See Work Item 187395
  455. var upgradedPinContent = {
  456. layout: upgradedBoardSpec.layout,
  457. widgets: _.toArray(upgradedBoardSpec.widgets),
  458. specVersion: upgradedBoardSpec.version,
  459. upgrades: upgrades
  460. };
  461. if (upgradedBoardSpec.dataSources) {
  462. upgradedPinContent.dataSources = upgradedBoardSpec.dataSources;
  463. }
  464. if (pinSpec.content.episodes) {
  465. upgradedPinContent.episodes = _.toArray(upgradedBoardSpec.timeline.episodes);
  466. }
  467. // if for some reason the spec did not upgrade fully it may still
  468. // contain datasetShaping
  469. if (upgradedBoardSpec.datasetShaping) {
  470. upgradedPinContent.datasetShaping = _.toArray(upgradedBoardSpec.datasetShaping);
  471. }
  472. pinSpec.content = upgradedPinContent;
  473. // we should be the newest pin version now
  474. pinSpec.version = _this13.PIN_VERSION;
  475. return pinSpec;
  476. }).catch(function (error) {
  477. // IF we have an error.obj then the upgrade had some succefull steps, return that spec
  478. if (error.obj) {
  479. _this13._glassContext.getCoreSvc('.Logger').warn('Pin spec did not fully upgrade', error, pinSpec);
  480. return error.obj;
  481. }
  482. throw error;
  483. });
  484. };
  485. DashboardPinningService.prototype._getObjectFromArrayById = function _getObjectFromArrayById(array) {
  486. return _.object(_.map(array, function (item) {
  487. return [item.id, item];
  488. }));
  489. };
  490. /**
  491. * Yuck yuck yuck.. look away. This is really only needed since the pin service (glass service) needs access to
  492. * some dashboard specific services when querying/adding pins. In the long run a lot of these services should
  493. * be moved to glass services since they can be shared accross dashboards.
  494. */
  495. DashboardPinningService.prototype._getCurrentContentViewDashboardApi = function _getCurrentContentViewDashboardApi() {
  496. try {
  497. return this._glassContext.appController.currentAppView.currentContentView.getDashboardApi();
  498. } catch (e) {
  499. this._glassContext.getCoreSvc('.Logger').error('Trying to use the pinning service outside of a dashboard.', e);
  500. }
  501. };
  502. /**
  503. * Yuck yuck yuck.. look away. This is really only needed since the pin service (glass service) needs access to
  504. * some dashboard specific services when querying/adding pins. In the long run a lot of these services should
  505. * be moved to glass services since they can be shared accross dashboards.
  506. */
  507. DashboardPinningService.prototype._getCurrentContentViewServices = function _getCurrentContentViewServices() {
  508. try {
  509. return this._glassContext.appController.currentAppView.currentContentView.services;
  510. } catch (e) {
  511. this._glassContext.getCoreSvc('.Logger').error('Trying to use the pinning service outside of a dashboard.', e);
  512. }
  513. };
  514. return DashboardPinningService;
  515. }(Events);
  516. return DashboardPinningService;
  517. });
  518. //# sourceMappingURL=DashboardPinningService.js.map