ActivitiesPane.js 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544
  1. "use strict";
  2. /**
  3. * Licensed Materials - Property of IBM
  4. * IBM Cognos Products: Manage
  5. * Copyright IBM Corp. 2015, 2021
  6. * US Government Users Restricted Rights
  7. * Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  8. */
  9. define(['q', 'rave2', 'bi/admin/common/slideout/BasePane', 'bi/admin/common/ui/MagicWand', 'bi/admin/status/services/ApiSvc', 'bi/admin/common/visualizations/VizBar', 'bi/admin/common/visualizations/VizStackedBar', 'bi/commons/ui/widgets/DatePicker', 'bi/admin/common/ui/listview/ListView', 'bi/admin/status/services/ActivitiesAdaptor', 'bi/admin/common/utils/CapabilityHelper', 'bi/admin/nls/StringResource', 'text!bi/admin/status/templates/ActivitiesPaneTemplate.html', 'moment-timezone', 'bi/commons/utils/Utils', 'bacontentnav/utils/ContentStoreObject', 'react', 'react-dom', 'ba-react-admin/ba-react-admin.min', 'underscore', 'doT', 'text!bi/admin/status/templates/updateSchedules.xml', 'bi/content_apps/utils/C10Utils'], function (Q, rave, BasePane, MagicWand, Api, VizBar, VizStackedBar, DateNavigator, ListView, ActivitiesAdaptor, CapabilityHelper, StringResource, paneTemplate, moment, Utils, ContentStoreObject, React, ReactDOM, AdminReact, _, doT, UpdateSchedulesRequestTemplate, C10Utils) {
  10. //NOSONAR: needed for amd
  11. function buildContextMenuItemListFnMap() {
  12. var map = {};
  13. function getStatus(data) {
  14. var status = data[0].statusValue && data[0].statusValue.toLocaleLowerCase();
  15. return status || '';
  16. }
  17. map[Api.ActivityType.SCHEDULE] = function (data) {
  18. var isSingleSelect = data.length === 1;
  19. var itemList = ['useMyCredentials'];
  20. var status = getStatus(data);
  21. var isSubscription = data[0].isSubscription;
  22. if (isSingleSelect) {
  23. itemList.push('runOnce', 'versions');
  24. if (CapabilityHelper.checkCapabilities('canUseSchedulingPriority', this.glassContext)) {
  25. itemList.push('setPriority');
  26. }
  27. }
  28. if (!isSubscription) {
  29. itemList.push('removeSchedule', status === 'enabled' ? 'disableSchedule' : 'enableSchedule');
  30. if (isSingleSelect) {
  31. itemList.push('update_schedule', 'setProperties');
  32. }
  33. } else {
  34. itemList.push('removeSubscription', status === 'enabled' ? 'disableSubscription' : 'enableSubscription');
  35. if (isSingleSelect) {
  36. itemList.push('update_subscription');
  37. }
  38. }
  39. return itemList;
  40. };
  41. map[Api.ActivityType.UPCOMING] = function (data) {
  42. var isSingleSelect = data.length === 1;
  43. var status = getStatus(data);
  44. var itemList = [status === 'suspended' ? 'release' : 'suspend'];
  45. if (isSingleSelect && CapabilityHelper.checkCapabilities('canUseSchedulingPriority', this.glassContext)) {
  46. itemList.push('setPriority');
  47. }
  48. if (status !== 'cancelled') {
  49. itemList.push('activity-cancel');
  50. }
  51. return itemList;
  52. };
  53. map[Api.ActivityType.CURRENT] = function (data) {
  54. var isSingleSelect = data.length === 1;
  55. var status = getStatus(data);
  56. var itemList = [status === 'suspended' ? 'release' : 'suspend'];
  57. if (isSingleSelect) {
  58. itemList.push('versions');
  59. if (CapabilityHelper.checkCapabilities('canUseSchedulingPriority', this.glassContext)) {
  60. itemList.push('setPriority');
  61. }
  62. }
  63. if (status !== 'cancelled') {
  64. itemList.push('activity-cancel');
  65. }
  66. return itemList;
  67. };
  68. map[Api.ActivityType.PAST] = function (data) {
  69. return ['versions', 'runDetail', 'runOnce'];
  70. };
  71. return map;
  72. }
  73. var ActivitiesPane = BasePane.extend({
  74. chartMode: 'stacked',
  75. template: null,
  76. activityType: Api.ActivityType.SCHEDULE,
  77. groupBy: Api.GroupBy.HOUR,
  78. filter: {},
  79. _contextMenuItemListFnMap: buildContextMenuItemListFnMap(),
  80. init: function init(options) {
  81. ActivitiesPane.inherited('init', this, arguments);
  82. $.extend(this, options);
  83. Api.glassContext = this.glassContext; //glassContext may not be set yet and is required by some of the bacontentnav panels (ie. VersionView)
  84. ContentStoreObject.setGlassContext(this.glassContext);
  85. var listDataAdaptor = this.listDataAdaptor = this._getNewActivitiesAdaptor({
  86. glassContext: this.glassContext,
  87. isMyActivities: this.isMyActivities,
  88. checkboxSelection: true
  89. }); //check for ajax service as not to break unit tests
  90. if (this.glassContext && this.glassContext.services && this.glassContext.services.ajax && !this.isMyActivities) {
  91. Api.getDispatcherNameMap().then(function (data) {
  92. listDataAdaptor.dispatcherNameMap = data;
  93. });
  94. }
  95. },
  96. _getNewActivitiesAdaptor: function _getNewActivitiesAdaptor(options) {
  97. return new ActivitiesAdaptor(options);
  98. },
  99. onToggleMenuChanged: function onToggleMenuChanged(name, value) {
  100. if (name === 'activityType') {
  101. if (value === Api.ActivityType.CURRENT) {
  102. var $background = this.$body.find('#background input');
  103. var checked = $background.is(':checked');
  104. value = checked ? Api.ActivityType.CURRENT : Api.ActivityType.INTERACTIVE;
  105. }
  106. this._changeActivityType(value);
  107. this.$el.find('.menu-label').parent().focus();
  108. }
  109. },
  110. _openFilterPane: function _openFilterPane() {
  111. var valueBag = {
  112. status: Api.Status[this.activityType],
  113. priority: Api.SchedulePriorities,
  114. objectClass: Api.ScheduleObjectClasses
  115. };
  116. this._openSlideout({
  117. width: '330px',
  118. content: {
  119. filter: this.filter,
  120. valueBag: valueBag,
  121. isMyActivities: this.isMyActivities,
  122. activityType: this.activityType,
  123. parentView: this,
  124. module: 'bi/admin/status/slideout/FilterPane'
  125. }
  126. });
  127. },
  128. onHeaderButtonClicked: function onHeaderButtonClicked(id) {
  129. ActivitiesPane.inherited('onHeaderButtonClicked', this, arguments);
  130. if (id === 'filterButton') {
  131. if (this.slideout && this.slideout.child) {
  132. this.slideout.child.hide();
  133. } else {
  134. this._openFilterPane();
  135. }
  136. }
  137. },
  138. onHeaderChecked: function onHeaderChecked(id, checked) {
  139. if (id === 'chartMode') {
  140. var chartMode = checked ? 'stacked' : 'grouped';
  141. if (this.vizChart) {
  142. this.vizChart.changeMode(chartMode);
  143. }
  144. this.chartMode = chartMode;
  145. } else {
  146. if (id === 'background') {
  147. this._changeActivityType(checked ? Api.ActivityType.CURRENT : Api.ActivityType.INTERACTIVE);
  148. }
  149. }
  150. },
  151. _getNewDateNavigator: function _getNewDateNavigator(options) {
  152. return new DateNavigator(options);
  153. },
  154. renderBody: function renderBody($body) {
  155. $body.html(paneTemplate);
  156. var deferred = Q.defer();
  157. this._initCheckboxSelection($body);
  158. var $header = $body.find('.bi-admin-statuspane-header');
  159. var $leading = $header.find('.bi-admin-leading');
  160. this.$viewType = $('<div id="type_toggle" class="toggle-filter" role="menubar">');
  161. $leading.append(this.$viewType);
  162. var mainTypes = _.clone(Api.ActivityType);
  163. delete mainTypes.INTERACTIVE;
  164. this.renderToggleMenu(this.$viewType, 'activityType', mainTypes, this.activityType, true);
  165. this.$viewType.find('.dropdown-menu').addClass('activityDropDownFilter');
  166. var $spans = this.$viewType.find('span');
  167. $spans.parent().css('padding-bottom', '0px');
  168. var $center = $header.find('.bi-admin-center');
  169. var dnElement = $('<div class="datenav-container bi-admin-toolbaritem" role="menubar">');
  170. $center.append(dnElement);
  171. this.dateNav = this._getNewDateNavigator({
  172. $el: $(dnElement[0]),
  173. timezone: this.glassContext.services.userProfile.preferences.timeZoneID,
  174. locale: this.glassContext.services.userProfile.preferences.contentLocale,
  175. attributes: {
  176. inputFieldDate: new Date()
  177. },
  178. onChange: this._renderActivities.bind(this, true)
  179. });
  180. this.dateNav.render();
  181. $(this.dateNav.el).find('#datepicker').attr('aria-label', StringResource.get('datePicker'));
  182. var $buttonBar = $header.find('div.bi-admin-trailing .bi-admin-buttonbar');
  183. var $items = $buttonBar.find('td');
  184. var $filterButton = this._createButton('filterButton', 'common-filter', StringResource.get('filter'), 'bi-admin-toolbaritem');
  185. $filterButton.css('white-space', 'nowrap');
  186. $filterButton.appendTo($items[2]);
  187. var $label = $('<span class="bi-admin-menu-label">');
  188. $label.text(StringResource.get('all'));
  189. $label.appendTo($filterButton);
  190. var $chartMode = this._createCheckbox('chartMode', StringResource.get('stacked'), this.chartMode === 'stacked');
  191. $chartMode.appendTo($items[1]);
  192. var $background = this._createCheckbox('background', StringResource.get('background'), true);
  193. $background.appendTo($items[0]);
  194. MagicWand.checkBox($buttonBar);
  195. var $filterBar = $body.find('.bi-admin-filterbar');
  196. MagicWand.searchInput($filterBar).then(function (widgets) {
  197. if (widgets.length === 1) {
  198. this._filterInput = widgets[0];
  199. this._filterInput.options.hint = StringResource.get('findByName');
  200. this._filterInput.on('changed', function (e) {
  201. var trimmed = e.text.trim();
  202. if (trimmed.length > 0 || e.text === '') {
  203. this.listView.filter(trimmed);
  204. }
  205. }.bind(this));
  206. }
  207. }.bind(this)).then(function () {
  208. this._renderActivities().then(function () {
  209. deferred.resolve();
  210. }, function () {
  211. deferred.resolve();
  212. });
  213. }.bind(this));
  214. return deferred.promise;
  215. },
  216. _getDateRange: function _getDateRange() {
  217. var range = {};
  218. if (this.activityType === Api.ActivityType.UPCOMING) {
  219. range.minDate = new Date();
  220. } else {
  221. if (this.activityType === Api.ActivityType.PAST) {
  222. range.maxDate = new Date();
  223. }
  224. }
  225. return range;
  226. },
  227. _changeActivityType: function _changeActivityType(type) {
  228. if (this.activityType !== type) {
  229. this.activityType = type;
  230. if (this.filter) {
  231. delete this.filter.status;
  232. if (this.activityType === Api.ActivityType.PAST) {
  233. delete this.filter.priority;
  234. }
  235. }
  236. if (this.activityType === Api.ActivityType.UPCOMING || this.activityType === Api.ActivityType.PAST) {
  237. this.dateNav.setDate(new Date());
  238. this.dateNav.onChange(); //do not need to renderActivities in this case as the change in the date
  239. //will trigger a _renderActivities
  240. } else {
  241. this._renderActivities(true);
  242. }
  243. }
  244. },
  245. _getTimeFilters: function _getTimeFilters() {
  246. var selDate = this.dateNav.getDateObj();
  247. var filters = {};
  248. if (this.activityType === Api.ActivityType.UPCOMING || this.activityType === Api.ActivityType.PAST) {
  249. var timezone = this.glassContext.services.userProfile.preferences.timeZoneID;
  250. var locale = this.glassContext.services.userProfile.preferences.contentLocale;
  251. var st = moment(selDate).locale(locale).tz(timezone).startOf('day');
  252. var et = st.clone().endOf('day');
  253. filters.startTime = st.toDate();
  254. filters.endTime = et.toDate();
  255. }
  256. return filters;
  257. },
  258. _getAdvancedFilters: function _getAdvancedFilters(timeFilters) {
  259. var filters = timeFilters || this._getTimeFilters();
  260. if (this.filter) {
  261. filters = _.extend(filters, _.pick(this.filter, Api.AdvancedFilterItems));
  262. if (this.filter.user) {
  263. filters.user = this.filter.user.id;
  264. }
  265. if (this.filter.owner) {
  266. filters.owner = this.filter.owner.id;
  267. }
  268. if (this.filter.scheduleType) {
  269. filters.scheduleType = this.filter.scheduleType;
  270. }
  271. }
  272. return filters;
  273. },
  274. _renderActivities: function _renderActivities(forceCreate) {
  275. if (this.listView) {
  276. this.listView._clearRows(true);
  277. }
  278. var deferred = Q.defer();
  279. this._updateUIState();
  280. var timeFilters = this._getTimeFilters();
  281. var filters = this._getAdvancedFilters(timeFilters);
  282. this._renderActivityList(filters, forceCreate).then(function () {
  283. if (this._isIE()) {
  284. this._renderChart(this.listDataAdaptor.summary);
  285. this._updateTableHeight();
  286. } else {
  287. this._fixTableBodyHeight();
  288. this._renderChart(this.listDataAdaptor.summary);
  289. }
  290. deferred.resolve();
  291. }.bind(this));
  292. return deferred.promise;
  293. },
  294. _updateUIState: function _updateUIState() {
  295. var $chartMode = this.$body.find('#chartMode');
  296. switch (this.activityType) {
  297. case Api.ActivityType.SCHEDULE:
  298. case Api.ActivityType.CURRENT:
  299. case Api.ActivityType.INTERACTIVE:
  300. $chartMode.hide();
  301. break;
  302. case Api.ActivityType.UPCOMING:
  303. case Api.ActivityType.PAST:
  304. $chartMode.show();
  305. break;
  306. default:
  307. }
  308. var $background = this.$body.find('#background');
  309. if (!this.isMyActivities && (this.activityType === Api.ActivityType.CURRENT || this.activityType === Api.ActivityType.INTERACTIVE)) {
  310. $background.show();
  311. this._hideDatePicker();
  312. } else {
  313. $background.hide();
  314. }
  315. if (this.activityType === Api.ActivityType.UPCOMING || this.activityType === Api.ActivityType.PAST) {
  316. this._showDatePicker();
  317. } else {
  318. this._hideDatePicker();
  319. }
  320. this._renderFilterSummary(this.filter);
  321. },
  322. _updateFilterButtonState: function _updateFilterButtonState(filter, clear) {
  323. var $filterButton = this.$body.find('#filterButton');
  324. var $filterLabel = $filterButton.find('span');
  325. if (clear && this.filter && !this._isFilterEmpty(filter)) {
  326. $filterButton.addClass('bi-admin-state-info');
  327. $filterButton.attr('aria-pressed', 'true');
  328. $filterLabel.text(StringResource.get('applied'));
  329. } else {
  330. $filterButton.removeClass('bi-admin-state-info');
  331. $filterButton.removeAttr('aria-pressed');
  332. $filterLabel.text(StringResource.get('all'));
  333. }
  334. if (this.activityType === Api.ActivityType.INTERACTIVE) {
  335. $filterButton.hide();
  336. } else {
  337. $filterButton.show();
  338. }
  339. },
  340. // filter is initialized as an object with 1 property 'user' i.e. { user: 'xyz' } so an empty filter either looks like this or {}
  341. _isFilterEmpty: function _isFilterEmpty(filter) {
  342. var keys = _.keys(filter);
  343. if (this.isMyActivities) {
  344. return keys.length === 1 && keys[0] === 'user';
  345. }
  346. return keys.length === 0;
  347. },
  348. _renderFilterSummary: function _renderFilterSummary(filter) {
  349. var buffer = [];
  350. var validFilter = false;
  351. var key;
  352. if (this._checkValidFilter(filter)) {
  353. buffer = this._buildFilterText(filter);
  354. validFilter = true;
  355. }
  356. this._updateFilterButtonState(filter, validFilter);
  357. $('.filter-summary').html(buffer.join(''));
  358. if (buffer.length > 0) {
  359. Utils.setIcon($('.filter-summary'), 'common-filter');
  360. }
  361. },
  362. _buildFilterText: function _buildFilterText(filter) {
  363. var buffer = [];
  364. var key;
  365. for (key in filter) {
  366. var valueText = filter[key];
  367. if (!(this.isMyActivities && (key === 'owner' || key === 'user'))) {
  368. if (key === 'owner' || key === 'user') {
  369. valueText = _.escape(filter[key].defaultName);
  370. }
  371. buffer.push('<span title="' + StringResource.get(key) + ': ' + StringResource.get(valueText) + '" class="filter-summary-item"><b>' + StringResource.get(key) + ':</b> ' + StringResource.get(valueText) + '</span>');
  372. }
  373. }
  374. return buffer;
  375. },
  376. _checkValidFilter: function _checkValidFilter(filter) {
  377. var retVal = true;
  378. if (this.activityType !== Api.ActivityType.SCHEDULE && filter.scheduleType && filter.scheduleType !== '') {
  379. retVal = false;
  380. } //TODO more conditions can likely go here.
  381. return retVal;
  382. },
  383. _hideDatePicker: function _hideDatePicker() {
  384. this.$el.find('.bi_datepicker_div').hide();
  385. },
  386. _showDatePicker: function _showDatePicker() {
  387. this.$el.find('.bi_datepicker_div').show();
  388. },
  389. _renderChart: function _renderChart(result) {
  390. switch (this.activityType) {
  391. case Api.ActivityType.SCHEDULE:
  392. case Api.ActivityType.CURRENT:
  393. case Api.ActivityType.INTERACTIVE:
  394. this._renderBarChart(result);
  395. break;
  396. case Api.ActivityType.UPCOMING:
  397. case Api.ActivityType.PAST:
  398. this._renderStackedBarChart(result);
  399. break;
  400. default:
  401. }
  402. },
  403. _getNewVizBar: function _getNewVizBar(options) {
  404. return new VizBar(options);
  405. },
  406. _renderBarChart: function _renderBarChart(result) {
  407. var $chart = this.$el.find('#chart');
  408. var width = this.$el.width();
  409. $chart.removeClass().addClass('bi-admin-chart bi-admin-barchart bi-admin-chart-' + this.activityType);
  410. $chart.attr('role', 'presentation');
  411. var chartData = this._prepareBarChartData(result);
  412. this.vizChart = this._getNewVizBar({
  413. el: $chart[0],
  414. data: chartData,
  415. parentWidth: width
  416. });
  417. },
  418. _prepareBarChartData: function _prepareBarChartData(result) {
  419. var chartData = _.map(result.data, function (row) {
  420. return {
  421. name: row.name,
  422. value: row.total * 1
  423. };
  424. });
  425. return chartData;
  426. },
  427. _renderStackedBarChart: function _renderStackedBarChart(result) {
  428. var $chart = this.$el.find('#chart');
  429. $chart.removeClass().addClass('bi-admin-chart bi-admin-stackedbarchart ' + this.activityType);
  430. $chart.attr('role', 'presentation');
  431. var chartData = this._prepareStackedBarChartData(result);
  432. this.vizChart = new VizStackedBar({
  433. el: $chart[0],
  434. data: chartData,
  435. chartMode: this.chartMode
  436. });
  437. },
  438. _findGroupValue: function _findGroupValue(items, x) {
  439. var result = _.find(items, function (item) {
  440. var fixedDt = item.use;
  441. if (fixedDt.indexOf('Z') < 0) {
  442. fixedDt += 'Z';
  443. }
  444. var timezone = this.glassContext.services.userProfile.preferences.timeZoneID;
  445. var locale = this.glassContext.services.userProfile.preferences.contentLocale;
  446. var hour = moment(fixedDt).locale(locale).tz(timezone).hour();
  447. return hour === x;
  448. }.bind(this));
  449. return result ? result.display * 1 : 0;
  450. },
  451. _createLayer: function _createLayer(items) {
  452. var range = rave.range(24);
  453. var layer = _.map(range, function (x) {
  454. return {
  455. x: x,
  456. y: this._findGroupValue(items, x)
  457. };
  458. }.bind(this));
  459. return layer;
  460. },
  461. _prepareStackedBarChartData: function _prepareStackedBarChartData(result) {
  462. var chartData = [];
  463. if (this.activityType !== Api.ActivityType.INTERACTIVE) {
  464. chartData = _.map(result.data, function (row) {
  465. return {
  466. name: row.name,
  467. total: row.total,
  468. layer: this._createLayer(row.value),
  469. legendName: this._getStackedBarCharLegendName(row.name)
  470. };
  471. }.bind(this));
  472. }
  473. return chartData;
  474. },
  475. _getStackedBarCharLegendName: function _getStackedBarCharLegendName(name) {
  476. switch (this.activityType) {
  477. case Api.ActivityType.UPCOMING:
  478. return name;
  479. case Api.ActivityType.PAST:
  480. switch (name) {
  481. case 'succeeded':
  482. return 'succeeded';
  483. case 'cancelled':
  484. return 'cancelled';
  485. case 'failed':
  486. return 'failedActivity';
  487. case 'terminated':
  488. return 'terminated';
  489. case 'purged':
  490. return 'purged';
  491. default:
  492. }
  493. break;
  494. default:
  495. }
  496. },
  497. _getNewListView: function _getNewListView(options) {
  498. return new ListView(options);
  499. },
  500. _isIE: function _isIE() {
  501. return this._isIE11orLess() || this._isEdge() ? true : false;
  502. },
  503. _isIE11orLess: function _isIE11orLess() {
  504. var navigatorStr = navigator.userAgent;
  505. return navigatorStr.indexOf('Trident/') > 0 ? true : false;
  506. },
  507. _isEdge: function _isEdge() {
  508. var navigatorStr = navigator.userAgent;
  509. return navigatorStr.indexOf('Edge/') > 0 ? true : false;
  510. },
  511. _fixTableBodyHeight: function _fixTableBodyHeight() {
  512. if (!this.isMyActivities) {
  513. this.$el.find('div.dataTables_scrollBody').css('overflow', 'hidden');
  514. this.$el.find('div.ca-listContainer').css('overflow', 'auto');
  515. this.$el.find('div.dataTables_scrollBody').height('100%');
  516. }
  517. },
  518. _updateTableHeight: function _updateTableHeight() {
  519. var contentHeight = this.$el.find('div.bi-admin-pane-body').height(); // this is height of pane
  520. var topHeight = this.$el.find('div.bi-admin-pane-header').height() + this.$el.find('div.bi-admin-layout-gap').height() + this.$el.find('div.bi-admin-chartbar').height() + this.$el.find('div.bi-admin-filterbar').height(); // this is height of top elements
  521. var totalHeight = contentHeight - topHeight - 90;
  522. if (totalHeight < 10) {
  523. this.$el.find('div.dataTables_scrollBody').height(50);
  524. } else {
  525. this.$el.find('div.dataTables_scrollBody').height(contentHeight - topHeight - 50);
  526. }
  527. this.$el.find('div.dataTables_scrollBody .bi-admin-table-list').width('90%');
  528. this.$el.find('div.dataTables_scrollBody .bi-admin-activities').css({
  529. 'style': '-ms-overflow-style: scrollbar; -ms-overflow-y: auto;'
  530. });
  531. },
  532. _renderActivityList: function _renderActivityList(filters, forceCreate) {
  533. this._hideShowSelectionFooter(this.$el);
  534. forceCreate = forceCreate || !this.listView;
  535. this.listDataAdaptor.setFilters(filters);
  536. if (forceCreate) {
  537. var elList = this.$el.find('#list');
  538. elList.empty();
  539. this.listDataAdaptor.activityType = this.activityType;
  540. this.listView = this._getNewListView({
  541. el: elList,
  542. dataAdaptor: this.listDataAdaptor,
  543. glassContext: this.glassContext,
  544. accessibleLabel: StringResource.get('activities'),
  545. contentView: this,
  546. contextMenuId: 'com.ibm.bi.admin.scheduleMenu',
  547. onSelectionChange: this._onSelectionChange.bind(this)
  548. });
  549. window.onresize = this._redrawListView.bind(this);
  550. this.listView.contextMenuCallback = this._contextMenuHandler.bind(this);
  551. var $con = $(this.$el.find('.bi-admin-activities.pageView'));
  552. $con.addClass('bi-admin-activities-webkit-invisible-scrollbar');
  553. $con.addClass('flyoutPane');
  554. $con.css('width', '100%');
  555. return this.listView.render();
  556. } else {
  557. return this.listView.reload();
  558. }
  559. },
  560. _redrawListView: function _redrawListView() {
  561. this.listDataAdaptor.isResize = true;
  562. this.listView.render();
  563. },
  564. _contextMenuHandler: function _contextMenuHandler(data) {
  565. var args = {
  566. 'position': data.position,
  567. 'menuId': 'com.ibm.bi.admin.scheduleMenu',
  568. 'activeObject': {
  569. handler: this,
  570. data: data.selectedObject
  571. }
  572. };
  573. this.glassContext.appController.showContextMenu(args);
  574. },
  575. getReportProperties: function getReportProperties(id) {
  576. var options = {
  577. method: 'GET',
  578. contentType: 'application/json; charset=utf-8',
  579. dataType: 'json'
  580. };
  581. options.url = 'v1/search_path?searchPath=storeID%28%22' + id + '%22%29/parent::*&fields=base.type,userInterfaces,owner.id,defaultName,disabled,hidden,permissions,runInAdvancedViewer,owner.defaultName,modificationTime,canBurst,iconURI,defaultScreenTip,searchPath,owner.defaultName,modificationTime,tenantID,options';
  582. return this.glassContext.services.ajax.ajax(options);
  583. },
  584. _getReportInfo: function _getReportInfo(id, func) {
  585. this.getReportProperties(id).then(function (result) {
  586. func(result.data[0]);
  587. }.bind(this)).catch(function () {
  588. this._showErrorToast(StringResource.get('activityNotFound'));
  589. }.bind(this));
  590. },
  591. refresh: function refresh() {
  592. if (this.$el) {
  593. var runAs = this.$el.find('.bi-admin-runAsDialog');
  594. if (runAs && runAs[0] && !this.glassContext.isDevInstall()) {
  595. ReactDOM.unmountComponentAtNode(runAs[0]);
  596. }
  597. }
  598. this._renderActivities();
  599. },
  600. _showPropertiesPane: function _showPropertiesPane(object) {
  601. var content = {
  602. 'module': 'bi/content_apps/PropertiesPageView',
  603. 'glassContext': this.glassContext,
  604. 'objectInformation': object,
  605. 'parentView': this
  606. };
  607. this._openSlideout({
  608. 'content': content,
  609. 'width': '400px',
  610. 'enableTabLooping': true,
  611. 'label': StringResource.get('properties'),
  612. 'onHide': function onHide() {
  613. this.contentView.update();
  614. }
  615. });
  616. },
  617. _showVersionsPane: function _showVersionsPane(object) {
  618. var content = {
  619. 'module': 'bi/content_apps/VersionsView',
  620. 'glassContext': this.glassContext,
  621. 'objectInformation': object
  622. };
  623. this._openSlideout({
  624. 'content': content,
  625. 'width': '400px',
  626. 'enableTabLooping': true,
  627. 'label': StringResource.get('schedule_subscription_version_aria_label')
  628. });
  629. },
  630. _showScheduleProperties: function _showScheduleProperties(obj) {
  631. var content = {
  632. 'module': 'bi/schedule/views/SchedulesView',
  633. 'glassContext': this.glassContext,
  634. 'objectInfo': obj
  635. };
  636. this._openSlideout({
  637. 'content': content,
  638. 'width': '400px',
  639. 'enableTabLooping': true,
  640. 'label': 'Schedule'
  641. });
  642. },
  643. _openSlideout: function _openSlideout(opts) {
  644. if (this.isMyActivities) {
  645. opts.position = 'right';
  646. } else {
  647. opts.parent = this.slideout;
  648. }
  649. this.glassContext.appController.showSlideOut(opts);
  650. },
  651. _newRunAsReport: function _newRunAsReport(report) {
  652. var runAsActionView = React.createElement(AdminReact.RunAsAction, {
  653. StringResource: StringResource,
  654. glassContext: this.glassContext,
  655. objectInfo: report,
  656. slideout: this,
  657. runOnce: true
  658. });
  659. var runAs = this.$el.find('.bi-admin-runAsDialog');
  660. ReactDOM.unmountComponentAtNode(runAs[0]);
  661. ReactDOM.render(runAsActionView, runAs[0]);
  662. },
  663. _oldRunAsReport: function _oldRunAsReport(report, module) {
  664. var content = {
  665. 'module': module,
  666. 'glassContext': this.glassContext,
  667. 'objectInformation': report
  668. };
  669. this._openSlideout({
  670. 'content': content,
  671. 'width': '400px',
  672. 'enableTabLooping': true,
  673. 'label': StringResource.get('subscription_header_region')
  674. });
  675. },
  676. _runAsReport: function _runAsReport(report, module) {
  677. if (!this.glassContext.isDevInstall()) {
  678. return this._newRunAsReport(report, module);
  679. } else {
  680. return this._oldRunAsReport(report, module);
  681. }
  682. },
  683. _runOnce: function _runOnce(report, schedule) {
  684. if (schedule.name) {
  685. report.options = schedule.options;
  686. report.parameters = schedule.parameters;
  687. }
  688. var noOpts = ['jupyterNotebook', 'jobDefinition', 'agentDefinition', 'agentDefinitionView'];
  689. if (report.type === 'dataSet2') {
  690. return this._runAsReport(report, 'bi/admin/status/slideout/DSRunAsView');
  691. } else if (noOpts.indexOf(report.type) === -1) {
  692. this._runAsReport(report, 'bi/admin/status/slideout/ScheduleRunAsView');
  693. } else {
  694. return this._runAsReport(report, 'bi/content_apps/RunAsJobOptionsView');
  695. }
  696. },
  697. _showSubscriptionPane: function _showSubscriptionPane(report, sub) {
  698. var content = {
  699. 'module': 'bi/schedule/views/SubscriptionView',
  700. 'glassContext': this.glassContext,
  701. 'descriptor': sub
  702. };
  703. this._openSlideout({
  704. 'content': content,
  705. 'width': '400px',
  706. 'enableTabLooping': true,
  707. 'label': StringResource.get('subscription_header_region')
  708. });
  709. },
  710. newGetSchedule: function newGetSchedule(report) {
  711. return AdminReact.ScheduleAccess.readSchedule(this.glassContext, report.id);
  712. },
  713. oldGetSchedule: function oldGetSchedule(report, data) {
  714. var url = 'v1/reports/' + report.id + '/schedule';
  715. if (data[0].isSubscription) {
  716. url = 'v1/subscriptions/' + report.id;
  717. }
  718. var options = {
  719. method: 'GET',
  720. contentType: 'application/json; charset=utf-8',
  721. dataType: 'json'
  722. };
  723. options.url = url;
  724. return this.glassContext.services.ajax.ajax(options);
  725. },
  726. _getScheduleOptionsForReport: function _getScheduleOptionsForReport(data, func) {
  727. if (data[0] === 'undefined' || data[0].id === 'undefined') {
  728. this._showErrorToast(StringResource.get('activityNotFound'));
  729. return;
  730. }
  731. var isSubssc = data[0].isSubscription;
  732. this._getReportInfo(data[0].id, function (report) {
  733. var schPromise;
  734. if (this.glassContext.isDevInstall() || isSubssc) {
  735. schPromise = this.oldGetSchedule(report, data);
  736. } else {
  737. schPromise = this.newGetSchedule(report);
  738. }
  739. schPromise.then(function (scheduleData) {
  740. var schedule = scheduleData;
  741. if (scheduleData.length) {
  742. //variably the result from the api can either be an array with the schedule
  743. //in the first element or the schedule itself
  744. schedule = schedule[0];
  745. }
  746. if (!schedule.id) {
  747. func(report, schedule);
  748. return;
  749. } //Get the raw options of the schedule that will show if save to cloud was selected
  750. var optionsRequest = {
  751. method: 'GET',
  752. contentType: 'application/json; charset=utf-8',
  753. dataType: 'json',
  754. url: 'v1/objects/' + schedule.id + '?fields=options,parameters'
  755. };
  756. this.glassContext.services.ajax.ajax(optionsRequest).then(function (data) {
  757. if (this.glassContext.isDevInstall() || isSubssc) {
  758. _.extend(report, {
  759. rawOptions: data.data[0].options
  760. });
  761. } else {
  762. if (data.data[0].options) {
  763. report.options = data.data[0].options;
  764. }
  765. if (data.data[0].parameters) {
  766. report.parameters = data.data[0].parameters;
  767. }
  768. }
  769. func(report, schedule);
  770. }.bind(this));
  771. }.bind(this)).catch(function () {
  772. this._showErrorToast(StringResource.get('activityNotFound'));
  773. }.bind(this));
  774. }.bind(this));
  775. },
  776. onContextMenu: function onContextMenu(id, data) {
  777. if (this.slideout && this.slideout.child) {
  778. this.slideout.child.hide();
  779. }
  780. switch (id) {
  781. case 'activity-cancel':
  782. this._cancelActivity(data);
  783. break;
  784. case 'setProperties':
  785. this._getReportInfo(data[0].id, this._showPropertiesPane.bind(this));
  786. break;
  787. case 'runOnce':
  788. this._getScheduleOptionsForReport(data, this._runOnce.bind(this));
  789. break;
  790. case 'update_subscription':
  791. this._getScheduleOptionsForReport(data, this._showSubscriptionPane.bind(this));
  792. break;
  793. case 'update_schedule':
  794. this._getReportInfo(data[0].id, this._showScheduleProperties.bind(this));
  795. break;
  796. case 'versions':
  797. if (this.activityType === Api.ActivityType.PAST || this.activityType === Api.ActivityType.SCHEDULE) {
  798. this._getReportInfo(data[0].id, this._showVersionsPane.bind(this));
  799. } else if (this.activityType === Api.ActivityType.CURRENT) {
  800. this._showVersionsPane(data[0]);
  801. }
  802. break;
  803. case 'useMyCredentials':
  804. // Get credential and update schedule(s). On fail, renew credentials first, then try again.
  805. this._getAndUpdateCredential(data, this._renewGetAndUpdateCredential);
  806. break;
  807. case 'disableSubscription':
  808. case 'disableSchedule':
  809. this._updateScheduleStatus(data, false);
  810. break;
  811. case 'enableSubscription':
  812. case 'enableSchedule':
  813. this._updateScheduleStatus(data, true);
  814. break;
  815. case 'setPriority':
  816. this._openSetPriorityPane(data);
  817. break;
  818. case 'removeSchedule':
  819. this._removeSchedule(data);
  820. break;
  821. case 'removeSubscription':
  822. this._removeSubscription(data);
  823. break;
  824. case 'runDetail':
  825. this._getHistoryDetail(data[0]);
  826. break;
  827. case 'suspend':
  828. this._suspendReleaseSchedule(data, true);
  829. break;
  830. case 'release':
  831. this._suspendReleaseSchedule(data, false);
  832. break;
  833. case 'runHistoryJobDetails':
  834. this._viewRunHistoryDetails(data[0]);
  835. break;
  836. default:
  837. }
  838. },
  839. _viewRunHistoryDetails: function _viewRunHistoryDetails(data) {
  840. C10Utils.openC10MorphletWithParams('portal/history/view_executing_details.xts', this._prepareMorphletRequestForRunHistoryDetails(data));
  841. return true;
  842. },
  843. _prepareMorphletRequestForRunHistoryDetails: function _prepareMorphletRequestForRunHistoryDetails(data) {
  844. var morphletOptions = [{
  845. m_name: data.defaultName
  846. }, {
  847. eventID: data.eventID
  848. }, {
  849. m_class: 'jobDefinition'
  850. }];
  851. return morphletOptions;
  852. },
  853. _suspendReleaseSchedule: function _suspendReleaseSchedule(data, suspending) {
  854. var serviceMethod = suspending ? 'suspendSchedule' : 'releaseSchedule';
  855. var stringKey = suspending ? 'Suspended' : 'Released';
  856. var eventKey = suspending ? 'holdEvents' : 'releaseEvents';
  857. var fail = suspending ? StringResource.get('suspendFailed') : StringResource.get('releaseFailed');
  858. var eventIds = data.map(function (item) {
  859. return {
  860. eventID: item.eventID
  861. };
  862. });
  863. Api[serviceMethod](this.activityType, eventIds).then(function (res) {
  864. if (res[eventKey] == 'success') {
  865. var message = data.length > 1 ? StringResource.get('items' + stringKey, {
  866. num: data.length
  867. }) : StringResource.get('item' + stringKey, {
  868. name: data[0].defaultName
  869. });
  870. this.glassContext.appController.showToast(message, {
  871. type: 'success',
  872. timeOut: 3000
  873. });
  874. setTimeout(function () {
  875. this._renderActivities();
  876. }.bind(this), 500);
  877. } else {
  878. this._showErrorToast(fail);
  879. }
  880. }.bind(this), this._showErrorToast.bind(this, fail));
  881. },
  882. _showErrorToast: function _showErrorToast(msg) {
  883. this.glassContext.appController.showToast(msg, {
  884. type: 'error',
  885. timeOut: 3000
  886. });
  887. setTimeout(function () {
  888. this._renderActivities();
  889. }.bind(this), 500);
  890. },
  891. _cancelActivity: function _cancelActivity(data) {
  892. var eventIds = data.map(function (item) {
  893. return {
  894. eventID: item.eventID
  895. };
  896. });
  897. var fail = StringResource.get('cancelFailed');
  898. Api.cancelActivity(this.activityType, eventIds).then(function (res) {
  899. if (res.cancelEvents == 'success') {
  900. var message = data.length > 1 ? StringResource.get('itemsCancelled', {
  901. num: data.length
  902. }) : StringResource.get('itemCancelled', {
  903. name: data[0].defaultName
  904. });
  905. this.glassContext.appController.showToast(message, {
  906. type: 'success',
  907. timeOut: 3000
  908. });
  909. setTimeout(function () {
  910. this._renderActivities();
  911. }.bind(this), 500);
  912. } else {
  913. this._showErrorToast(fail);
  914. }
  915. }.bind(this), this._showErrorToast.bind(this, fail));
  916. },
  917. _getHistoryDetail: function _getHistoryDetail(data) {
  918. var options = {
  919. method: 'GET',
  920. contentType: 'application/json; charset=utf-8',
  921. dataType: 'json'
  922. };
  923. options.url = 'v1/objects/' + data.id + '?fields=status,actualExecutionTime,actualCompletionTime,requestedExecutionTime';
  924. var historyObj;
  925. var reportObj;
  926. return Promise.try(function () {
  927. return this.glassContext.services.ajax.ajax(options);
  928. }.bind(this)).then(function (historyRes) {
  929. historyObj = historyRes;
  930. return this.getReportProperties(data.id);
  931. }.bind(this)).then(function (reportResult) {
  932. reportObj = reportResult;
  933. options.url = 'v1/objects/' + data.id + '/history_details';
  934. return this.glassContext.services.ajax.ajax(options);
  935. }.bind(this)).then(function (outputObj) {
  936. this._showRunDetailView(outputObj.data, historyObj.data[0], reportObj.data[0]);
  937. }.bind(this));
  938. },
  939. _showRunDetailView: function _showRunDetailView(output, historyInfo, report) {
  940. var content = {
  941. module: 'bi/content_apps/VersionsDetailsView',
  942. parentView: this,
  943. objectInfo: report,
  944. historyInfo: historyInfo,
  945. detailsInfo: output,
  946. glassContext: this.glassContext
  947. };
  948. this._openSlideout({
  949. 'content': content,
  950. 'width': '400px',
  951. 'enableTabLooping': true,
  952. 'label': 'Run details'
  953. });
  954. },
  955. isContextMenuItemVisible: function isContextMenuItemVisible(itemId, data) {
  956. var visible = true;
  957. if (data.length > 1) {
  958. var isShowStatus = true;
  959. _.each(data, function (item) {
  960. if (data[0].statusValue !== item.statusValue) {
  961. isShowStatus = false;
  962. }
  963. }.bind(this));
  964. visible = this._contextMenuItemVisibleHelper(itemId, data);
  965. if ((itemId === 'disableSchedule' || itemId === 'enableSchedule' || itemId === 'disableSubscription' || itemId === 'enableSubscription') && !isShowStatus) {
  966. visible = false;
  967. }
  968. } else if (this.activityType === Api.ActivityType.SCHEDULE) {
  969. if (itemId === 'runDetail' || itemId === 'runHistoryJobDetails' || itemId === 'schedule') {
  970. visible = false;
  971. } else if (itemId === 'runOnce') {
  972. visible = true;
  973. } else if (itemId === 'activity-cancel') {
  974. visible = false;
  975. } else {
  976. visible = this._contextMenuItemVisibleHelper(itemId, data);
  977. }
  978. } else if (this.activityType === Api.ActivityType.PAST) {
  979. if (data[0].type === 'jupyterNotebook') {
  980. visible = itemId === 'runDetail' || itemId === 'runOnce';
  981. } else {
  982. visible = itemId === 'versions' || itemId === 'runDetail' || itemId === 'runOnce';
  983. }
  984. } else if (this.activityType === Api.ActivityType.UPCOMING) {
  985. if (itemId === 'suspend') {
  986. visible = data[0].statusValue.toLocaleLowerCase() === 'scheduled';
  987. } else if (itemId === 'release') {
  988. visible = data[0].statusValue.toLocaleLowerCase() === 'suspended';
  989. } else if (itemId === 'activity-cancel') {
  990. visible = data[0].statusValue.toLocaleLowerCase() !== 'cancelled';
  991. } else {
  992. visible = false;
  993. }
  994. } else if (this.activityType === Api.ActivityType.CURRENT) {
  995. if (itemId === 'suspend') {
  996. visible = data[0].statusValue.toLocaleLowerCase() === 'executing';
  997. } else if (itemId === 'release') {
  998. visible = data[0].statusValue.toLocaleLowerCase() === 'suspended';
  999. } else if (itemId === 'activity-cancel') {
  1000. visible = data[0].statusValue.toLocaleLowerCase() !== 'cancelled';
  1001. } else if (itemId === 'runHistoryJobDetails') {
  1002. visible = data[0].type === 'jobDefinition';
  1003. } else {
  1004. visible = false;
  1005. }
  1006. }
  1007. return visible;
  1008. },
  1009. _contextMenuItemVisibleHelper: function _contextMenuItemVisibleHelper(itemId, data) {
  1010. var invisible = false;
  1011. if (data[0].isSubscription) {
  1012. invisible = invisible || itemId === 'disableSchedule';
  1013. invisible = invisible || itemId === 'enableSchedule';
  1014. invisible = invisible || itemId === 'disableSubscription' && data[0].statusValue.toLocaleLowerCase() === 'disabled';
  1015. invisible = invisible || itemId === 'enableSubscription' && data[0].statusValue.toLocaleLowerCase() === 'enabled';
  1016. } else {
  1017. invisible = invisible || itemId === 'disableSubscription';
  1018. invisible = invisible || itemId === 'enableSubscription';
  1019. invisible = invisible || itemId === 'disableSchedule' && data[0].statusValue.toLocaleLowerCase() === 'disabled';
  1020. invisible = invisible || itemId === 'enableSchedule' && data[0].statusValue.toLocaleLowerCase() === 'enabled';
  1021. }
  1022. if (data[0].type === 'jupyterNotebook') {
  1023. invisible = invisible || itemId === 'versions';
  1024. }
  1025. invisible = invisible || itemId === 'setPriority' && !CapabilityHelper.checkCapabilities('canUseSchedulingPriority', this.glassContext);
  1026. invisible = invisible || itemId === 'runOnce';
  1027. invisible = invisible || itemId === 'setProperties' && data[0].isSubscription;
  1028. invisible = invisible || itemId === 'update_schedule' && data[0].isSubscription;
  1029. invisible = invisible || itemId === 'update_subscription' && !data[0].isSubscription;
  1030. invisible = invisible || itemId === 'removeSubscription' && !data[0].isSubscription;
  1031. invisible = invisible || itemId === 'removeSchedule' && data[0].isSubscription;
  1032. invisible = invisible || itemId === 'useMyCredentials' && this.isMyActivities;
  1033. invisible = invisible || itemId === 'suspend';
  1034. invisible = invisible || itemId === 'release';
  1035. invisible = invisible || itemId === 'runDetail' && this.activityType === Api.ActivityType.SCHEDULE;
  1036. invisible = invisible || itemId === 'activity-cancel' && !(this.activityType === Api.ActivityType.CURRENT || this.activityType === Api.ActivityType.UPCOMING);
  1037. return !invisible;
  1038. },
  1039. _openSetPriorityPane: function _openSetPriorityPane(data) {
  1040. var self = this;
  1041. var opts = {
  1042. width: '200px',
  1043. onHide: function onHide() {
  1044. if (self.setPriorityPane && self.setPriorityPane.contentView && self.setPriorityPane.contentView.onHide) {
  1045. self.setPriorityPane.contentView.onHide();
  1046. }
  1047. },
  1048. content: {
  1049. parentView: self,
  1050. schedule: data,
  1051. module: 'bi/admin/status/slideout/SetPriorityPane'
  1052. }
  1053. };
  1054. if (this.slideout) {
  1055. opts.parent = this.slideout;
  1056. } else {
  1057. opts.position = 'right';
  1058. }
  1059. this.setPriorityPane = this.glassContext.appController.showSlideOut(opts);
  1060. },
  1061. _getAndUpdateCredential: function _getAndUpdateCredential(data, onFail) {
  1062. return Api.getCredential().then(function (credentialResult) {
  1063. if (this._isValidCredentialResult(credentialResult)) {
  1064. this._updateScheduleCredentials(data, credentialResult.data);
  1065. } else {
  1066. onFail.bind(this, data)();
  1067. }
  1068. }.bind(this)).fail(function () {
  1069. onFail.bind(this, data)();
  1070. }.bind(this));
  1071. },
  1072. _renewGetAndUpdateCredential: function _renewGetAndUpdateCredential(data) {
  1073. return Api.renewCredential().done(function () {
  1074. // Get and update user credential and then update schedule(s). On fail, renewing credential didn't work, show error.
  1075. this._getAndUpdateCredential(data, this._showCredentialError);
  1076. }.bind(this)).fail(function () {
  1077. this._showCredentialError();
  1078. }.bind(this));
  1079. },
  1080. _showCredentialError: function _showCredentialError() {
  1081. this._showErrorToast(StringResource.get('internalErrorMsg'));
  1082. },
  1083. _isValidCredentialResult: function _isValidCredentialResult(credentialResults) {
  1084. return credentialResults && credentialResults.data && credentialResults.data.searchPath && credentialResults.data.type && credentialResults.data.type === 'credential';
  1085. },
  1086. _updateScheduleCredentials: function _updateScheduleCredentials(data, credential) {
  1087. var selectedNum = data.length;
  1088. if (data.length > 1) {
  1089. var aPromises = [];
  1090. _.each(data, function (item) {
  1091. var innerDeferred = Q.defer();
  1092. Api.updateScheduleCredentials(item.id, credential).done(function () {
  1093. innerDeferred.resolve();
  1094. }.bind(this));
  1095. aPromises.push(innerDeferred.promise);
  1096. });
  1097. return Q.all(aPromises).then(function () {
  1098. var sText = StringResource.get('multiCredentialsUpdateSuccessful', {
  1099. 'num': selectedNum
  1100. });
  1101. this.glassContext.appController.showToast(sText, {
  1102. type: 'success',
  1103. timeOut: 3000
  1104. });
  1105. setTimeout(function () {
  1106. this._renderActivities();
  1107. }.bind(this), 500);
  1108. }.bind(this));
  1109. } else {
  1110. return Api.updateScheduleCredentials(data[0].id, credential).done(function () {
  1111. this.glassContext.appController.showToast(StringResource.get('credentialsUpdateSuccessful'), {
  1112. type: 'success',
  1113. timeOut: 3000
  1114. });
  1115. setTimeout(function () {
  1116. this._renderActivities();
  1117. }.bind(this), 500);
  1118. }.bind(this));
  1119. }
  1120. },
  1121. _updateScheduleStatus: function _updateScheduleStatus(data, status) {
  1122. var selectedNum = data.length;
  1123. if (data.length > 1) {
  1124. var aPromises = [];
  1125. _.each(data, function (item) {
  1126. var innerDeferred = Q.defer();
  1127. Api.updateScheduleStatus(item.id, status).done(function () {
  1128. innerDeferred.resolve();
  1129. }.bind(this));
  1130. aPromises.push(innerDeferred.promise);
  1131. });
  1132. Q.all(aPromises).then(function (results) {
  1133. var sText = StringResource.get('multiScheduleStatusUpdateSuccessful', {
  1134. 'num': selectedNum
  1135. });
  1136. this.glassContext.appController.showToast(sText, {
  1137. type: 'success'
  1138. });
  1139. setTimeout(function () {
  1140. this._renderActivities(true);
  1141. }.bind(this), 500);
  1142. return Promise.resolve(results);
  1143. }.bind(this));
  1144. } else {
  1145. var scheduleId = data[0].id;
  1146. Api.updateScheduleStatus(scheduleId, status).done(function () {
  1147. this.glassContext.appController.showToast(StringResource.get('scheduleStatusUpdateSuccessful'), {
  1148. type: 'success',
  1149. timeOut: 3000
  1150. });
  1151. setTimeout(function () {
  1152. this._renderActivities(true);
  1153. }.bind(this), 500);
  1154. }.bind(this));
  1155. }
  1156. },
  1157. _removeSubscription: function _removeSubscription(data) {
  1158. function getOptions(id) {
  1159. return {
  1160. method: 'DELETE',
  1161. contentType: 'application/json; charset=utf-8',
  1162. dataType: 'json',
  1163. url: 'v1/subscriptions/' + id
  1164. };
  1165. }
  1166. var deleteSchedule = function deleteSchedule(item) {
  1167. return Promise.resolve(Api.deleteSchedule(item.id));
  1168. };
  1169. var deleteSubscription = function (item) {
  1170. var ajaxService = this.glassContext.getCoreSvc('.Ajax');
  1171. return ajaxService.ajax(getOptions(item.reportId));
  1172. }.bind(this);
  1173. var promises = [];
  1174. var selectedNum = data.length;
  1175. _.each(data, function (item) {
  1176. // Delete Schedule CM object in tandem to prevent a "phantom" entry from appearing temporarily in the Activities pane after parent ReportView object is deleted
  1177. promises.push(deleteSchedule(item).then(deleteSubscription(item)));
  1178. });
  1179. Promise.all(promises).then(function () {
  1180. var message = selectedNum > 1 ? StringResource.get('multiSubscriptionDeleteSuccessful', {
  1181. 'num': selectedNum
  1182. }) : StringResource.get('subscriptionDeleteSuccessful');
  1183. this.glassContext.appController.showToast(message, {
  1184. type: 'success',
  1185. timeOut: 3000
  1186. });
  1187. setTimeout(function () {
  1188. this.listView.reload();
  1189. }.bind(this), 500);
  1190. }.bind(this));
  1191. },
  1192. _removeSchedule: function _removeSchedule(data) {
  1193. var selectedNum = data.length;
  1194. if (data.length > 1) {
  1195. var aPromises = [];
  1196. _.each(data, function (item) {
  1197. var innerDeferred = Q.defer();
  1198. Api.deleteSchedule(item.id).done(function () {
  1199. innerDeferred.resolve();
  1200. }.bind(this));
  1201. aPromises.push(innerDeferred.promise);
  1202. });
  1203. Q.all(aPromises).then(function (results) {
  1204. var sText = StringResource.get('multiScheduleDeleteSuccessful', {
  1205. 'num': selectedNum
  1206. });
  1207. this.glassContext.appController.showToast(sText, {
  1208. type: 'success'
  1209. });
  1210. setTimeout(function () {
  1211. this.listView.reload();
  1212. }.bind(this), 500);
  1213. return deferred.resolve(results);
  1214. }.bind(this));
  1215. } else {
  1216. var scheduleId = data[0].id;
  1217. Api.deleteSchedule(scheduleId).done(function () {
  1218. this.glassContext.appController.showToast(StringResource.get('scheduleDeleteSuccessful'), {
  1219. type: 'success',
  1220. timeOut: 3000
  1221. });
  1222. setTimeout(function () {
  1223. this.listView.reload();
  1224. }.bind(this), 500);
  1225. }.bind(this));
  1226. }
  1227. },
  1228. setFilter: function setFilter(filter) {
  1229. if (!filter) {
  1230. this.filter = {};
  1231. } else {
  1232. var newFilter = _.extend(this.filter, filter);
  1233. _.each(newFilter, function (value, key) {
  1234. if (_.isEmpty(value)) {
  1235. delete newFilter[key];
  1236. }
  1237. });
  1238. this.filter = newFilter;
  1239. }
  1240. this._renderActivities(true);
  1241. },
  1242. _onSelectionChange: function _onSelectionChange() {
  1243. var showEnableSelected = false;
  1244. var showDisableSelected = false;
  1245. if (this.listView._dTable) {
  1246. var selectedRows = this.listView._dTable.rows('tr.selected').data();
  1247. for (var index = 0; index < selectedRows.length && (!showDisableSelected || !showEnableSelected); ++index) {
  1248. if (selectedRows[index].statusValue === 'enabled') {
  1249. showDisableSelected = true;
  1250. } else if (selectedRows[index].statusValue === 'disabled') {
  1251. showEnableSelected = true;
  1252. }
  1253. }
  1254. }
  1255. this.$body.find('#bi-admin-activity-items-selected-enable').css('display', showEnableSelected ? '' : 'none');
  1256. this.$body.find('#bi-admin-activity-items-selected-disable').css('display', showDisableSelected ? '' : 'none');
  1257. var $selectedItems = this.$body.find('#bi-admin-activity-items-selected');
  1258. $selectedItems.text(StringResource.get('jobsSelected', {
  1259. jobsSelected: this.listView.aSelectedRows.length
  1260. }));
  1261. var $activityItemActionSection = this.$body.find('#bi-admin-activity-items-actions');
  1262. $activityItemActionSection.css('opacity', this.listView.aSelectedRows.length > 0 ? 1 : 0);
  1263. },
  1264. _modifySelectedSchedules: function _modifySelectedSchedules(enable) {
  1265. var schedulesToUpdate = [];
  1266. var selectedRows = this.listView._dTable.rows('tr.selected').data();
  1267. for (var index = 0; index < selectedRows.length; ++index) {
  1268. if (!enable && selectedRows[index].statusValue === 'enabled' || enable && selectedRows[index].statusValue === 'disabled') {
  1269. schedulesToUpdate.push({
  1270. id: selectedRows[index].id,
  1271. enable: enable
  1272. });
  1273. }
  1274. }
  1275. if (schedulesToUpdate.length) {
  1276. var updateRequest = doT.template(UpdateSchedulesRequestTemplate)({
  1277. cafContextId: this.glassContext.authInfo.cafContextId,
  1278. schedules: schedulesToUpdate
  1279. });
  1280. return this.glassContext.services.fetch.post('v1/disp', {
  1281. 'headers': {
  1282. 'SOAPAction': 'http://www.ibm.com/xmlns/prod/cognos/contentManagerService/201703/'
  1283. },
  1284. 'contentType': 'text/xml; charset=UTF-8',
  1285. 'data': updateRequest
  1286. }).then(function (response) {
  1287. var sText = StringResource.get('multiScheduleStatusUpdateSuccessful', {
  1288. 'num': schedulesToUpdate.length
  1289. });
  1290. this.glassContext.appController.showToast(sText, {
  1291. type: 'success'
  1292. });
  1293. this._refreshAfterUpdate();
  1294. }.bind(this)).catch(function () {
  1295. this.glassContext.appController.showToast(StringResource.get('error'), {
  1296. type: 'error'
  1297. });
  1298. this._refreshAfterUpdate();
  1299. }.bind(this));
  1300. }
  1301. },
  1302. _refreshAfterUpdate: function _refreshAfterUpdate() {
  1303. setTimeout(function () {
  1304. this._renderActivities(true);
  1305. }.bind(this), 500);
  1306. },
  1307. _hideShowSelectionFooter: function _hideShowSelectionFooter($el) {
  1308. var $activitiesSelectionFooter = $el.find('.admin-activities-selection-footer');
  1309. if (this.activityType === Api.ActivityType.SCHEDULE) {
  1310. $activitiesSelectionFooter.css('display', 'flex');
  1311. } else {
  1312. $activitiesSelectionFooter.css('display', 'none');
  1313. }
  1314. },
  1315. _initCheckboxSelection: function _initCheckboxSelection($body) {
  1316. if (this.listDataAdaptor.checkboxSelection) {
  1317. var $selectedItems = $body.find('#bi-admin-activity-items-selected');
  1318. $selectedItems.text(StringResource.get('jobsSelected', {
  1319. jobsSelected: this.listView ? this.listView.aSelectedRows.length : 0
  1320. }));
  1321. var $enableSelected = $body.find('#bi-admin-activity-items-selected-enable');
  1322. $enableSelected.text(StringResource.get('enableSelected'));
  1323. $enableSelected.click(this._modifySelectedSchedules.bind(this, true));
  1324. var $disableSelected = $body.find('#bi-admin-activity-items-selected-disable');
  1325. $disableSelected.text(StringResource.get('disableSelected'));
  1326. $disableSelected.click(this._modifySelectedSchedules.bind(this, false));
  1327. }
  1328. },
  1329. getSearchTerm: function getSearchTerm() {
  1330. return this._filterInput.$el.val();
  1331. }
  1332. });
  1333. return ActivitiesPane;
  1334. });