CreateAuthoredView.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. 'use strict';
  2. /**
  3. * Licensed Materials - Property of IBM
  4. *
  5. * "Restricted Materials of IBM"
  6. *
  7. * 5746-SM2
  8. *
  9. * (C) Copyright IBM Corp. 2014, 2020
  10. *
  11. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  12. */
  13. define(['./BaseView', '../../app/nls/StringResources', 'underscore', '../../lib/@waca/core-client/js/core-client/utils/BidiUtil', '../layouts/TabLayout', '../layouts/CustomLayout', '../layouts/InfographicsLayout', '../layouts/SinglePageLayout', '../views/NavigationPickerView', 'text!../templates/CreateAuthoredView.html', '../../lib/@waca/core-client/js/core-client/utils/UniqueId', './util/InstrumentationUtil', '../../features/dashboard/dashboardTemplates/api/impl/DashboardTemplatesImpl', '../../lib/@waca/dashboard-common/dist/lib/@ba-ui-toolkit/ba-graphics/dist/icons-js/template_32', '../../app/util/DeepClone' // TODO: Remove the use of DeepClone for something else
  14. ], function (PageView, stringResources, _, BidiUtil, TabLayout, CustomLayout, InfographicsLayout, SinglePageLayout, NavigationPickerView, template, UniqueId, InstrumentationUtil, DashboardTemplatesImpl, customTemplateIcon) {
  15. var CreateAuthoredView = PageView.extend({
  16. templateString: template,
  17. boardName: '',
  18. events: {
  19. 'input .editNameInput': 'onBoardNameChange',
  20. 'primaryaction .okButton': 'onSelectedLayout',
  21. 'primaryaction .cancelButton': 'onCancelClick'
  22. },
  23. $navPicker: null,
  24. /**
  25. * Map of available navigation layouts
  26. *
  27. * For the moment, these also force the widget layout
  28. *
  29. **/
  30. _navigationLayouts: {
  31. tab: TabLayout,
  32. infographics: InfographicsLayout,
  33. singlePage: SinglePageLayout,
  34. custom: CustomLayout
  35. },
  36. init: function init(options, appView) {
  37. this.sources = options.sources;
  38. this.ui_appbar = options.ui_appbar !== false;
  39. this.containerAppOptions = options.containerAppOptions;
  40. this._appView = appView;
  41. CreateAuthoredView.inherited('init', this, arguments);
  42. this._featureChecker = this.glassContext.getCoreSvc('.FeatureChecker');
  43. this._dashboardTemplatesEnabled = options.dashboardTemplates && !this._featureChecker.checkValue('dashboard', 'dashboardTemplates', 'disabled');
  44. var _dashboardTemplates = new DashboardTemplatesImpl({
  45. getContentSvc: this.glassContext.getSvc('.Content'),
  46. logger: this.glassContext.getSvc('.Logger'),
  47. featureChecker: this.glassContext.getCoreSvc('.FeatureChecker')
  48. });
  49. this.dashboardTemplatesApi = _dashboardTemplates.getAPI();
  50. this.boardName = stringResources.get('defaultName');
  51. },
  52. _updateOptions: function _updateOptions() {
  53. if (this._appView && this._appView.content) {
  54. this.sources = this._appView.content.sources;
  55. this.ui_appbar = this._appView.content.ui_appbar !== false;
  56. this.containerAppOptions = this._appView.content.containerAppOptions;
  57. }
  58. },
  59. render: function render() {
  60. var _this = this;
  61. var dashboardTemplatesPromise = Promise.resolve();
  62. if (this._dashboardTemplatesEnabled) {
  63. dashboardTemplatesPromise = this.dashboardTemplatesApi.listTemplates().then(function (templates) {
  64. _this._customTemplates = templates;
  65. return _this.glassContext.getSvc('.Content').then(function (contentService) {
  66. return templates.map(function (template) {
  67. template.location = contentService.getLocation(template);
  68. });
  69. });
  70. });
  71. }
  72. return dashboardTemplatesPromise.then(this._render.bind(this)).then(this._registerEvents.bind(this));
  73. },
  74. _getNavPickerOptions: function _getNavPickerOptions() {
  75. var _this2 = this;
  76. var excludedTemplates = ['NoTemplate'];
  77. var logger = this.glassContext.getCoreSvc('.Logger');
  78. var tabNavModel = {
  79. dataId: 'tab',
  80. css: 'tabTemplate',
  81. label: stringResources.get('createAvTabLabel'),
  82. icon: 'wfg_tabbed'
  83. };
  84. var infographicNavModel = {
  85. dataId: 'infographics',
  86. css: 'infographicsTemplate',
  87. label: stringResources.get('createAvInfographicsLabel'),
  88. icon: 'wfg_infographic'
  89. };
  90. var singlePageModel = {
  91. dataId: 'singlePage',
  92. css: 'singlepageTemplate',
  93. label: stringResources.get('createAvSinglepageLabel'),
  94. icon: 'wfg_single_page'
  95. };
  96. var knownTemplates = {
  97. 'tab': tabNavModel,
  98. 'infographic': infographicNavModel,
  99. 'singlePage': singlePageModel
  100. };
  101. var navTemplates = [{
  102. label: stringResources.get('createAvDashboardLabel'),
  103. navModels: []
  104. }];
  105. return this.glassContext.appController.findCollection('com.ibm.bi.dashboard.templates').then(function (templateItems) {
  106. if (Array.isArray(templateItems) && templateItems.length > 0) {
  107. templateItems.forEach(function (template) {
  108. if (knownTemplates[template.dataId]) {
  109. navTemplates[0].navModels.push(knownTemplates[template.dataId]);
  110. if (Array.isArray(template.excludedTemplates)) {
  111. excludedTemplates = excludedTemplates.concat(template.excludedTemplates);
  112. }
  113. } else {
  114. logger.error('Unknown template provided in collections');
  115. }
  116. });
  117. } else {
  118. navTemplates[0].navModels.push(tabNavModel, infographicNavModel, singlePageModel);
  119. }
  120. if (_this2._customTemplates && _this2._customTemplates.length) {
  121. navTemplates[0].navModels.push({
  122. dataId: 'custom',
  123. css: 'tabTemplate',
  124. label: stringResources.get('createAvCustomLabel'),
  125. icon: customTemplateIcon.default.id
  126. });
  127. }
  128. return {
  129. action: _this2.createAuthoredView.bind(_this2),
  130. navTemplates: navTemplates,
  131. customTemplates: _this2._customTemplates,
  132. showContextMenu: _this2._showContextMenu.bind(_this2),
  133. dashboardTemplatesApi: _this2.dashboardTemplatesApi,
  134. defaultTemplate: 'tab',
  135. layoutPickerOptions: {
  136. excludeTemplates: excludedTemplates
  137. }
  138. };
  139. });
  140. },
  141. _render: function _render() {
  142. var _this3 = this;
  143. this.$el.empty();
  144. this._handleAppAndNavBarVisiblity();
  145. var html = this.dotTemplate({
  146. selectTemplateLabel: stringResources.get('selectTemplateLabel'),
  147. okButton: stringResources.get('createButton'),
  148. cancelButton: stringResources.get('cancelButton'),
  149. boardName: this.getBoardName()
  150. });
  151. this.$el.html(html).css('visibility', 'hidden');
  152. if (this.navigationPickerView) {
  153. this.navigationPickerView.remove();
  154. }
  155. return this._getNavPickerOptions().then(function (navigationPickerOptions) {
  156. _this3.navigationPickerView = new NavigationPickerView(navigationPickerOptions);
  157. _this3.navigationPickerView.render();
  158. _this3.$('.content').append(_this3.navigationPickerView.el);
  159. _this3.$el.css('visibility', 'visible');
  160. BidiUtil.initElementForBidi(_this3.$('.editNameInput')[0]);
  161. });
  162. },
  163. _showContextMenu: function _showContextMenu(template, pageX, pageY) {
  164. this.glassContext.appController.showContextMenu({
  165. position: {
  166. pageX: pageX,
  167. pageY: pageY
  168. },
  169. menuId: 'com.ibm.bi.dashboard.templateMenu',
  170. activeObject: {
  171. // Mocking a list control object expected by showContextMenu
  172. oListControl: {
  173. contentView: {
  174. isEnabledAction: function isEnabledAction() {
  175. return true;
  176. }
  177. },
  178. getSelectedRows: function getSelectedRows() {
  179. return [template];
  180. },
  181. removeSelectedRows: function removeSelectedRows() {}
  182. },
  183. aSelectedContext: [template]
  184. },
  185. options: [{
  186. id: template.name
  187. }]
  188. });
  189. },
  190. _registerEvents: function _registerEvents() {
  191. this.glassContext.getCoreSvc('.Events').on('deleteAction:done', this.onDeleteActionDone, this);
  192. },
  193. _unregisterEvents: function _unregisterEvents() {
  194. this.glassContext.getCoreSvc('.Events').off('deleteAction:done', this.onDeleteActionDone, this);
  195. },
  196. onDeleteActionDone: function onDeleteActionDone(selectedContext) {
  197. var deletedItem = selectedContext && selectedContext.length && selectedContext[0];
  198. if (deletedItem && deletedItem.tags && deletedItem.tags.indexOf('dashboard_template') !== -1) {
  199. this.navigationPickerView.onDeleteActionDone(deletedItem.id);
  200. }
  201. },
  202. setFocus: function setFocus() {
  203. var selectedTemplate = this.navigationPickerView.layoutPickerView.getSelectedTemplate();
  204. if (selectedTemplate.length) {
  205. selectedTemplate.focus();
  206. } else {
  207. CreateAuthoredView.inherited('setFocus', this, arguments);
  208. }
  209. },
  210. _handleAppAndNavBarVisiblity: function _handleAppAndNavBarVisiblity() {
  211. if (this.containerAppOptions) {
  212. this.glassContext.appController.currentAppView.$('.navbar').css('display', 'none');
  213. this.glassContext.appController.currentAppView.$('.appbar').css('display', 'none');
  214. }
  215. },
  216. /**
  217. * This function cleans up the events and DOM before removing the view
  218. * @public
  219. **/
  220. remove: function remove() {
  221. if (this.navigationPickerView) {
  222. this._unregisterEvents();
  223. this.navigationPickerView.remove();
  224. this.navigationPickerView = null;
  225. }
  226. CreateAuthoredView.inherited('remove', this, arguments);
  227. },
  228. getUrl: function getUrl() {
  229. return null;
  230. },
  231. getIcon: function getIcon() {
  232. return 'common-dashboard_24';
  233. },
  234. getTitle: function getTitle() {
  235. return stringResources.get('createDashboardTitle');
  236. },
  237. // Handler for ok button
  238. onSelectedLayout: function onSelectedLayout() {
  239. this.navigationPickerView.onSelectNavModel();
  240. },
  241. // Handler for cancel button
  242. onCancelClick: function onCancelClick() {
  243. this._updateOptions();
  244. if (this.containerAppOptions && this.containerAppOptions.callbacks) {
  245. this.containerAppOptions.callbacks.reject('CREATE_CANCELLED');
  246. }
  247. this.close();
  248. },
  249. // Are the following four methods still used?
  250. onBoardNameChange: function onBoardNameChange() {
  251. this.setBoardName(this.$('.editNameInput').val());
  252. },
  253. getBoardName: function getBoardName() {
  254. return this.boardName;
  255. },
  256. setBoardName: function setBoardName(value) {
  257. this.boardName = value;
  258. if (!this.boardName) {
  259. this.$('.okButton').prop('disabled', true);
  260. } else {
  261. this.$('.okButton').prop('disabled', false);
  262. }
  263. },
  264. changeBoardName: function changeBoardName() {
  265. /* NO-OP */
  266. },
  267. /**
  268. * @returns {Promise}
  269. */
  270. createAuthoredView: function createAuthoredView(layoutSpec, layoutShim, navModel) {
  271. var _this4 = this;
  272. InstrumentationUtil.track(this.glassContext, 'created', {
  273. objectType: 'dashboard',
  274. sources: this.sources,
  275. type: 'Created Object'
  276. });
  277. this._selectedNavTemplate = this._navigationLayouts[navModel];
  278. if (navModel === 'custom') {
  279. return this.dashboardTemplatesApi.getTemplate(layoutSpec.name, true).then(function (template) {
  280. return _this4._createBoard(Object.assign(template.specification, { name: _this4.boardName }));
  281. });
  282. }
  283. var navTemplate = this._createNavTemplate(layoutSpec);
  284. var spec = this._createBoardSpec(navTemplate);
  285. return this._createBoard(spec);
  286. },
  287. _createNavTemplate: function _createNavTemplate(pageLayout) {
  288. var navTemplate = _.deepClone(this._selectedNavTemplate);
  289. if (!navTemplate.layout.items) {
  290. // the navigation layout is a single page
  291. var pageSize = navTemplate.layout.pageSize;
  292. var layoutPositioning = navTemplate.layout.layoutPositioning;
  293. var showGrid = navTemplate.layout.showGrid;
  294. var snapGrid = navTemplate.layout.snapGrid;
  295. var snapObjects = navTemplate.layout.snapObjects;
  296. navTemplate.layout = _.deepClone(pageLayout);
  297. if (pageSize) {
  298. navTemplate.layout.pageSize = _.deepClone(pageSize);
  299. }
  300. if (layoutPositioning) {
  301. navTemplate.layout.layoutPositioning = _.deepClone(layoutPositioning);
  302. }
  303. navTemplate.layout.showGrid = showGrid === true;
  304. navTemplate.layout.snapGrid = snapGrid === true;
  305. navTemplate.layout.snapObjects = snapObjects === true;
  306. } else {
  307. var navLayout = navTemplate.layout;
  308. var newItems = [];
  309. _.each(navLayout.items, function (item) {
  310. var newItem = _.deepClone(pageLayout);
  311. newItem.title = item.title;
  312. newItem.data = item.data;
  313. newItems.push(newItem);
  314. });
  315. navLayout.items = newItems;
  316. }
  317. return navTemplate;
  318. },
  319. _createBoardSpec: function _createBoardSpec(navLayout) {
  320. var spec = {
  321. name: this.boardName,
  322. layout: navLayout.layout,
  323. theme: 'defaultTheme'
  324. };
  325. return spec;
  326. },
  327. /**
  328. * @returns {Promise}
  329. */
  330. _createBoard: function _createBoard(spec) {
  331. spec._meta = {
  332. bundleID: null
  333. };
  334. return this._openBoard(spec);
  335. },
  336. _openBoard: function _openBoard(spec) {
  337. var _this5 = this;
  338. var id = spec._meta.bundleID;
  339. this._updateOptions();
  340. return this.glassContext.appController.openAppView(this._getDashboardPerspectiveName(), {
  341. content: {
  342. id: UniqueId.get('dashboard_'),
  343. boardId: id,
  344. boardSpec: spec,
  345. isAuthoringMode: true,
  346. ui_appbar: this.ui_appbar,
  347. containerAppOptions: this.containerAppOptions,
  348. sources: this.sources
  349. }
  350. }).then(function (view) {
  351. return view.onViewRendered();
  352. }).then(function (view) {
  353. view.currentContentView.openDatasetpane();
  354. _this5.glassContext.appController.closeAppView('createBoard');
  355. });
  356. },
  357. _getDashboardPerspectiveName: function _getDashboardPerspectiveName() {
  358. return 'dashboard';
  359. },
  360. // This is a temporary hack until the back function can be done properly in the glass.
  361. close: function close() {
  362. var _this6 = this;
  363. window.history.back();
  364. return new Promise(function (resolve, reject) {
  365. try {
  366. setTimeout(function () {
  367. _this6.glassContext.appController.closeAppView('createBoard').then(function () {
  368. resolve();
  369. });
  370. }, 1000);
  371. } catch (error) {
  372. reject(error);
  373. }
  374. });
  375. }
  376. });
  377. return CreateAuthoredView;
  378. });
  379. //# sourceMappingURL=CreateAuthoredView.js.map