MetaDataListView.js 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842
  1. "use strict";
  2. /**
  3. * Licensed Materials - Property of IBM
  4. * IBM Cognos Products: admin
  5. * Copyright IBM Corp. 2015, 2018
  6. * US Government Users Restricted Rights
  7. * Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  8. */
  9. define(['bi/admin/common/ui/GenericListView', 'doT', 'underscore', 'bi/admin/nls/StringResource', 'bi/admin/datasource/ActionHandler', 'bacontentnav/utils/WidgetNavigator', 'bacontentnav/ui/dialogs/SaveAsDialog', 'bi/commons/ui/dialogs/ConfirmationDialog', 'bi/commons/ui/content/dialog/SignOnDialog', 'bi/commons/ui/properties/PropertyUIControl', 'bi/commons/utils/ContentFormatter', 'bi/admin/common/utils/AJAXUtils', 'bi/moser/moser.min', 'bi/admin/datasource/App', 'bi/commons/utils/Utils', 'bi/admin/common/ui/MagicWand'], function (View, dot, _, StringResource, ActionHandler, WidgetNavigator, SaveAsDialog, ConfirmationDialog, SignOnDialog, PropertyUIControl, ContentFormatter, AJAXUtils, MoserJS, App, Utils, MagicWand) {
  10. 'use strict'; //NOSONAR: meant to be strict
  11. var MetaDataListView = View.extend({
  12. showSystemSchemas: false,
  13. retryCount: 5,
  14. itemDisplayedCount: 0,
  15. ITEM_QUEUE: 50,
  16. init: function init(options) {
  17. MetaDataListView.inherited('init', this, arguments);
  18. _.extend(this, options);
  19. this.conn = options.objectInfo;
  20. this._runningMetadataTasks = [];
  21. this.connectionList = [];
  22. },
  23. _getConnections: function _getConnections(objectInfo) {
  24. var options = {
  25. contentType: 'application/json; charset=utf-8',
  26. dataType: 'json'
  27. };
  28. var url = AJAXUtils.getAJAXURL('datasources') + '/' + objectInfo.dataSourceId + '/connections' + '?' + encodeURIComponent('fields') + '=' + encodeURIComponent('defaultName,disabled,permissions,owner.defaultName,hidden,capabilities,hasChildren,searchPath,modificationTime,creationTime,ancestors,defaultDescription,connectionString');
  29. return this.glassContext.services.fetch.get(url, options);
  30. },
  31. _getListHtmlNewConn: function _getListHtmlNewConn() {
  32. return this._getConnections(this.objectInfo).then(function (response) {
  33. if (response.data.data.length > 0) {
  34. _.forEach(response.data.data, function (data) {
  35. if (data.defaultName === this.objectInfo.defaultName) {
  36. this.objectInfo = data;
  37. }
  38. }.bind(this));
  39. }
  40. this.conn = this.objectInfo;
  41. }.bind(this)).then(this._requestSchemaInfo.bind(this));
  42. },
  43. _getListHtml: function _getListHtml(refresh) {
  44. //Check if it's a new connection
  45. if (!this.objectInfo.ancestors) {
  46. return this._getListHtmlNewConn();
  47. } else {
  48. if (!this.items || refresh) {
  49. // in the future, can check for a refresh call as well
  50. return this._requestSchemaInfo();
  51. } else {
  52. // already have the schema items, just re-render (ie. sort)
  53. return Promise.resolve(this._generateListHTMLStr());
  54. }
  55. }
  56. },
  57. _renderListView: function _renderListView(refresh) {
  58. return this._renderPane().then(this._renderMetaDataList.bind(this, refresh));
  59. },
  60. _renderMetaDataList: function _renderMetaDataList(refresh) {
  61. return this._getListHtml(refresh).then(this._renderSchemaListItems.bind(this, refresh));
  62. },
  63. _renderPane: function _renderPane() {
  64. return Promise.try(function () {
  65. if (!this._$loadingAnimationContainer) {
  66. this._$loadingAnimationContainer = $('<div/>', {
  67. 'class': 'metaDataListLoading'
  68. });
  69. this._$loadingAnimationContainer.append(Utils.getLoadingAnimation(1));
  70. this.$el.append(this._$loadingAnimationContainer);
  71. }
  72. if (!this._$metadataList) {
  73. this._$metadataList = $('<div/>', {
  74. 'class': 'metaDataList',
  75. 'style': 'visibility: hidden'
  76. });
  77. this._$metadataList.append(this._generatePaneHTMLStr());
  78. this._$metadataList.find('.bi-admin-list-headertext').parent().on('primaryaction', function (event) {
  79. this._sortItems(event.currentTarget.className, true);
  80. this.displayItems = this.items.slice(0, this.itemDisplayedCount);
  81. this._renderSchemaListItems(true, this._generateListHTMLStr());
  82. }.bind(this));
  83. this._$metadataListTable = this._$metadataList.find('table.bi-admin-list-table').last();
  84. this._$metadataListTable.parent().scroll(this._onScroll.bind(this));
  85. this.$el.append(this._$metadataList);
  86. return this._renderSearch();
  87. }
  88. }.bind(this));
  89. },
  90. _resetFilteredDisplayList: function _resetFilteredDisplayList() {
  91. this.filteredDisplayList = this.items.slice(0);
  92. },
  93. _renderSearch: function _renderSearch() {
  94. return MagicWand.searchInput(this.$el).then(function (widgets) {
  95. if (widgets.length === 1) {
  96. this._searchInput = widgets[0];
  97. this._searchInput.options.hint = StringResource.get('filterTips');
  98. this._searchInput.on('changed', function (e) {
  99. if (e.text.length === 0) {
  100. this._resetFilteredDisplayList();
  101. } else {
  102. var trimmed = e.text.trim();
  103. if (trimmed.length > 0) {
  104. this.filteredDisplayList = _.filter(this.items, function (item) {
  105. return item.defaultName.toLowerCase().indexOf(trimmed.toLowerCase()) > -1;
  106. });
  107. }
  108. }
  109. var htmlstr = this._processFilter(this.filteredDisplayList);
  110. return this._renderSchemaListItems(true, htmlstr);
  111. }.bind(this));
  112. }
  113. }.bind(this));
  114. },
  115. _onScroll: function _onScroll(evt) {
  116. var $target = $(evt.target);
  117. if ($target.scrollTop() + $target.innerHeight() >= $target[0].scrollHeight - 20) {
  118. this.displayItems = this.filteredDisplayList.slice(this.itemDisplayedCount, this.itemDisplayedCount + this.ITEM_QUEUE);
  119. this.itemDisplayedCount = this.itemDisplayedCount + this.ITEM_QUEUE < this.filteredDisplayList.length ? this.itemDisplayedCount + this.ITEM_QUEUE : this.filteredDisplayList.length;
  120. this._renderMetaDataList(false);
  121. }
  122. },
  123. _setHeights: function _setHeights() {
  124. var windowHeight = $(window).height();
  125. var toggleElement = this.$el.find("#admin_showSystemSchemas");
  126. var tableCont = this._$metadataListTable.parent();
  127. var headerElementsHeight = tableCont.offset().top;
  128. var updatedListHeight = windowHeight - toggleElement.height() - headerElementsHeight - 20;
  129. tableCont.height(updatedListHeight);
  130. },
  131. _updateConnectionSignonInfo: function _updateConnectionSignonInfo(connections) {
  132. var connection = {
  133. 'datasource': this.conn.ancestors[this.conn.ancestors.length - 1].defaultName
  134. };
  135. if (connections && connections.length > 0) {
  136. connection.connection = connections[0].connection;
  137. connection.signon = connections[0].signon;
  138. } else if (this.connectionList && this.connectionList.length > 0 && this.connectionList[0].connection) {
  139. connection.connection = this.connectionList[0].connection;
  140. connection.signon = this.connectionList[0].signon;
  141. }
  142. if (!connection.connection) {
  143. connection.connection = this.conn.defaultName;
  144. }
  145. if (connection.connection && connection.signon) {
  146. if (this.connectionList.length > 0) {
  147. //clear array
  148. this.connectionList.splice(0, 1);
  149. }
  150. this.connectionList.push(connection);
  151. }
  152. return connection;
  153. },
  154. _extractConnectionInfoFromResolver: function _extractConnectionInfoFromResolver() {
  155. var connInfo = {};
  156. if (this.connectionResolver.datasourceConnectionCache && this.connectionResolver.datasourceConnectionCache.datasources) {
  157. var key = _.keys(this.connectionResolver.datasourceConnectionCache.datasources)[0];
  158. var info = this.connectionResolver.datasourceConnectionCache.datasources[key];
  159. if (info) {
  160. connInfo.datasource = info.name;
  161. if (info.connection) {
  162. connInfo.connection = info.connection;
  163. }
  164. if (info.signon) {
  165. connInfo.signon = info.signon;
  166. }
  167. } else {
  168. return null;
  169. }
  170. }
  171. return connInfo;
  172. },
  173. _sendSchemaInfoRequest: function _sendSchemaInfoRequest(connections) {
  174. var connection;
  175. if (this.connectionResolver) {
  176. connection = this._extractConnectionInfoFromResolver();
  177. if (!connection) {
  178. connection = this._updateConnectionSignonInfo(connections);
  179. }
  180. } else {
  181. connection = this._updateConnectionSignonInfo(connections);
  182. }
  183. if (this.connectionList.length === 0 && connection) {
  184. this.connectionList.push(connection);
  185. }
  186. var connObj = {
  187. connections: this.connectionList
  188. };
  189. var connectionSpec = "connectionSpec=" + encodeURIComponent(JSON.stringify(connObj));
  190. return this._sendSchemas(connectionSpec, 0);
  191. },
  192. _sendSchemas: function _sendSchemas(connectionSpec, count) {
  193. var url = 'v1/metadata/sources/' + encodeURIComponent(this.conn.ancestors[2].id) + '/schemas';
  194. var ajaxOptions = {
  195. 'dataType': 'json',
  196. 'type': 'GET',
  197. 'url': url,
  198. 'data': connectionSpec
  199. };
  200. return this.glassContext.getCoreSvc('.Ajax').ajax(ajaxOptions).fail(function (error) {
  201. if (error.jqXHR.responseJSON) {
  202. return this.handleErrorResponse(error, count, connectionSpec);
  203. }
  204. }.bind(this));
  205. },
  206. _handle803ErrorResponse: function _handle803ErrorResponse(connectionSpec, count) {
  207. count++;
  208. if (count < this.retryCount) {
  209. return this._getSelectedSignonFromPrompt().then(this._sendSchemas.bind(this, connectionSpec, count)).then(function (dataRetrieved) {
  210. var htmlStr = this._processDataHandling(dataRetrieved);
  211. if (htmlStr) {
  212. this._renderSchemaListItems(true, htmlStr);
  213. }
  214. }.bind(this));
  215. } else {
  216. var msg = StringResource.get('dataserverFailedLoginAttempts');
  217. var info = '<span class="msg">' + _.escape(StringResource.get('dataserverFailedLoginAttempts')) + '</span>';
  218. this.glassContext.appController.showErrorMessage(msg, StringResource.get('error'));
  219. this.$el.html('<span class="blank-content"><i class="wft_bee"></i>' + info + '</span>');
  220. return Promise.reject();
  221. }
  222. },
  223. handleErrorResponse: function handleErrorResponse(error, count, connectionSpec) {
  224. if (error.jqXHR.responseJSON.errors) {
  225. var errors = error.jqXHR.responseJSON.errors;
  226. var theError = errors.length > 0 ? errors[0] : null;
  227. if (!theError) {
  228. return;
  229. }
  230. if (theError.code === 'CQE-803') {
  231. return this._handle803ErrorResponse(connectionSpec, count);
  232. } else {
  233. throw error.jqXHR.responseJSON;
  234. }
  235. } else {
  236. throw error.jqXHR.responseJSON;
  237. }
  238. },
  239. _processDataHandling: function _processDataHandling(dataRetrieved) {
  240. if (dataRetrieved && dataRetrieved.data) {
  241. var htmlStr;
  242. var response = dataRetrieved.data;
  243. if (response.data && response.data.length > 0) {
  244. this.items = _.map(response.data, this._buildItems.bind(this));
  245. this._sortItems(this._metaDataColName);
  246. this._resetFilteredDisplayList();
  247. this.itemDisplayedCount = this.ITEM_QUEUE < this.items.length ? this.ITEM_QUEUE : this.items.length;
  248. this.displayItems = this.items.slice(0, this.itemDisplayedCount);
  249. this.sortField = '';
  250. htmlStr = this._generateListHTMLStr();
  251. } else {
  252. htmlStr = '<span class="blank-content"><i class="wft_bee"></i><span class="msg">' + StringResource.get('noEntries') + '</span></span>';
  253. }
  254. return htmlStr;
  255. }
  256. },
  257. _processFilter: function _processFilter(filteredList) {
  258. var htmlStr;
  259. if (filteredList && filteredList.length > 0) {
  260. this.itemDisplayedCount = this.ITEM_QUEUE < this.items.length ? this.ITEM_QUEUE : this.items.length;
  261. this._sortItems(this._metaDataColName);
  262. this.displayItems = filteredList.slice(0, this.itemDisplayedCount);
  263. this.sortField = '';
  264. htmlStr = this._generateListHTMLStr();
  265. } else {
  266. htmlStr = '<span class="blank-content"><i class="wft_bee"></i><span class="msg">' + StringResource.get('noEntries') + '</span></span>';
  267. }
  268. return htmlStr;
  269. },
  270. _getNewSignOnDialog: function _getNewSignOnDialog(options) {
  271. return new SignOnDialog(options);
  272. },
  273. _getSelectedSignonFromPrompt: function _getSelectedSignonFromPrompt() {
  274. return new Promise(function (resolve, reject) {
  275. var signonPrompt = this._getNewSignOnDialog({
  276. 'dataSourceName': this.conn.ancestors[this.conn.ancestors.length - 1].defaultName,
  277. 'dataSourceConnectionName': this.conn.defaultName,
  278. 'glassContext': this.glassContext,
  279. 'displayErrMsg': true,
  280. 'canSaveCredentials': false,
  281. 'onSubmit': function () {
  282. var creds = signonPrompt.view.getCredentialsInfo();
  283. resolve({
  284. credentialsEx: {
  285. username: creds.userID,
  286. password: creds.password
  287. }
  288. });
  289. }.bind(this),
  290. 'onCancel': function () {
  291. var info = '<span class="msg">' + _.escape(StringResource.get('cancelled')) + '</span>';
  292. this.$el.html('<span class="blank-content"><i class="wft_bee"></i>' + info + '</span>');
  293. reject();
  294. }.bind(this)
  295. });
  296. signonPrompt.view.canSaveCredentials = false;
  297. signonPrompt.open();
  298. }.bind(this));
  299. },
  300. _requestSchemaInfo: function _requestSchemaInfo() {
  301. return Promise.try(function () {
  302. return this.glassContext.getSvc('.DataConnectionServiceFactory').then(function (connectionResolverFactory) {
  303. return connectionResolverFactory.getDataConnectionResolver();
  304. }.bind(this)).then(function (connectionResolver) {
  305. return connectionResolver.execute(this._sendSchemaInfoRequest.bind(this), 'ADMIN_KEY');
  306. }.bind(this)).then(this._processDataHandling.bind(this), function (error) {
  307. var info;
  308. if (error) {
  309. if (error.reason === 'cancel') {
  310. info = '<span class="msg">' + _.escape(StringResource.get('cancelled')) + '</span>';
  311. this.$el.html('<span class="blank-content"><i class="wft_bee"></i>' + info + '</span>');
  312. } else {
  313. this.glassContext.appController.showErrorMessage(error.msg, StringResource.get('error'));
  314. info = '<span class="msg">' + _.escape(error.msg) + '</span>';
  315. if (error.exceptionMsg) {
  316. info += '<span class="msg">' + _.escape(error.exceptionMsg) + '</span>';
  317. }
  318. this.$el.html('<span class="blank-content"><i class="wft_bee"></i>' + info + '</span>');
  319. }
  320. } else {
  321. this.glassContext.appController.showToast(StringResource.get('cancelLogin'), {
  322. type: 'warning'
  323. });
  324. info = '<span class="msg">' + _.escape(StringResource.get('cancelLogin')) + '</span>';
  325. this.$el.html('<span class="blank-content"><i class="wft_bee"></i>' + info + '</span>');
  326. }
  327. }.bind(this));
  328. }.bind(this));
  329. },
  330. _generateListHTMLStr: function _generateListHTMLStr() {
  331. var listData = {
  332. items: this.displayItems,
  333. strings: {
  334. 'contextMenuTips': StringResource.get('moreInContext'),
  335. 'moreActionsLabel': StringResource.get('contextMenuLabel')
  336. },
  337. showSystemSchemas: this.showSystemSchemas
  338. };
  339. return dot.template(this._template)(listData);
  340. },
  341. _generatePaneHTMLStr: function _generatePaneHTMLStr() {
  342. var listData = {
  343. strings: {
  344. 'status': StringResource.get('status'),
  345. 'colName': StringResource.get(this._metaDataColName),
  346. 'loadInformation': StringResource.get('loadInformation'),
  347. 'contextMenuTips': StringResource.get('moreInContext')
  348. }
  349. };
  350. return dot.template(this._paneTemplate)(listData);
  351. },
  352. _listHasSystemSchemas: function _listHasSystemSchemas(items) {
  353. return _.find(items, function (item) {
  354. return item.schemaType === 'system';
  355. }) !== undefined;
  356. },
  357. _renderSchemaListItems: function _renderSchemaListItems(refresh, htmlStr) {
  358. if (refresh) {
  359. this._$metadataListTable.html(htmlStr);
  360. } else {
  361. this._$metadataListTable.append(htmlStr);
  362. }
  363. $.each(this.$el.find('.bi-admin-link.groupListFocusable'), function (index, value) {
  364. ContentFormatter.middleShortenString(value);
  365. });
  366. this.$el.find('.bi-admin-list-sortable-header').toggleClass('bi-admin-list-sortable-selected', false);
  367. if (this.sortField) {
  368. var blueHighlight = this.$el.find('[class*=' + this.sortField + '] > .bi-admin-list-headertext');
  369. blueHighlight.addClass('bi-admin-list-sortable-selected');
  370. }
  371. this._addSystemSchemaToggle();
  372. this.widgetKeyController = new WidgetNavigator({
  373. $el: this.$el.find(".groupList-table"),
  374. focusClass: "groupListFocusable",
  375. fCallBack: function fCallBack() {}
  376. });
  377. this._bindEvents();
  378. this._$loadingAnimationContainer.css('display', 'none');
  379. this._$metadataList.css('visibility', 'visible');
  380. this._setHeights();
  381. return Promise.resolve();
  382. },
  383. _addSystemSchemaToggle: function _addSystemSchemaToggle() {
  384. if (this._listHasSystemSchemas(this.items)) {
  385. var $toggleButtonDiv = this._$metadataList.find("#admin_showSystemSchemas");
  386. if ($toggleButtonDiv.children().length === 0) {
  387. var configProps = [];
  388. configProps.push({
  389. 'type': 'CheckBox',
  390. 'label': StringResource.get('showSystemSchemas'),
  391. 'name': 'showSystemSchemas',
  392. 'checked': this.showSystemSchemas,
  393. 'onChange': this._setShowSystemSchemas.bind(this)
  394. });
  395. this._oPropertyUIControl = new PropertyUIControl({
  396. 'glassContext': this.glassContext,
  397. 'el': $toggleButtonDiv,
  398. 'items': configProps
  399. });
  400. this._oPropertyUIControl.render().then(function () {
  401. this._setHeights();
  402. }.bind(this));
  403. }
  404. }
  405. },
  406. _setShowSystemSchemas: function _setShowSystemSchemas() {
  407. var modProp = this._oPropertyUIControl.getModifiedProperties();
  408. if (modProp) {
  409. //hide or show system schemas in list
  410. var systemSchemaList = this.$el.find(".bi-admin-list-item.system-schema");
  411. if (modProp.showSystemSchemas === true) {
  412. systemSchemaList.removeClass("hidden");
  413. systemSchemaList.show();
  414. this.showSystemSchemas = true;
  415. } else {
  416. systemSchemaList.hide();
  417. this.showSystemSchemas = false;
  418. }
  419. }
  420. },
  421. _getNewActionHandler: function _getNewActionHandler() {
  422. return new ActionHandler();
  423. },
  424. _handleBaseModuleError: function _handleBaseModuleError(task) {
  425. var msg = task.response ? task.response.entity.msg : task.errorMessage;
  426. this.glassContext.appController.showErrorMessage(msg, StringResource.get('error'));
  427. },
  428. _isBaseModuleDone: function _isBaseModuleDone(id, response) {
  429. var task = response.data;
  430. this._updateStatus(id, task);
  431. var bDone = false;
  432. if (task.state === 'NOT_AVAILABLE') {
  433. bDone = true;
  434. } else if (task.state === 'ERROR') {
  435. this._handleBaseModuleError(task);
  436. bDone = true;
  437. } else if (task.state === 'SUCCESS') {
  438. if (this._displayLoadingToast) {
  439. this.glassContext.appController.showToast(StringResource.get('refreshSuccess'), {
  440. 'type': 'success'
  441. });
  442. }
  443. bDone = true;
  444. }
  445. return bDone;
  446. },
  447. _getBaseModule: function _getBaseModule(id, xCaAffinity, response) {
  448. return new Promise(function (resolve, reject) {
  449. var taskId = response.data.taskID;
  450. var getTaskUrl = 'v1/metadata/tasks/' + taskId;
  451. this._runningMetadataTasks.push({
  452. id: id,
  453. task: taskId,
  454. xCaAffinity: xCaAffinity
  455. });
  456. var int;
  457. var options = {
  458. contentType: 'application/json; charset=utf-8',
  459. dataType: 'json'
  460. };
  461. if (xCaAffinity) {
  462. options.headers = {
  463. Accept: 'application/json',
  464. 'x-ca-affinity': xCaAffinity
  465. };
  466. }
  467. var func = function () {
  468. this.glassContext.services.fetch.get(getTaskUrl, options).then(function (response) {
  469. if (this._isBaseModuleDone(id, response)) {
  470. clearInterval(int);
  471. this._removeRunningTask(id);
  472. if (response.data.state === 'SUCCESS') {
  473. resolve(response.data.response);
  474. } else {
  475. reject();
  476. }
  477. }
  478. }.bind(this), reject);
  479. }.bind(this);
  480. int = setInterval(func, 1000);
  481. }.bind(this));
  482. },
  483. RefreshMetadata: function RefreshMetadata(id) {
  484. var connectionSpec;
  485. var url;
  486. if (this.connectionList.length > 0) {
  487. var connList = [];
  488. connList.push(this.connectionList[0]);
  489. var connObj = {
  490. connections: connList
  491. };
  492. connectionSpec = 'connectionSpec=' + encodeURIComponent(JSON.stringify(connObj));
  493. url = 'v1/metadata/base_modules/' + encodeURIComponent(id) + '?async=true&' + connectionSpec;
  494. } else {
  495. url = 'v1/metadata/base_modules/' + encodeURIComponent(id) + '?async=true';
  496. }
  497. if (this._displayLoadingToast) {
  498. this.glassContext.appController.showToast(StringResource.get('refreshStart'), {
  499. 'type': 'info'
  500. });
  501. }
  502. return this.glassContext.getCoreSvc('.Ajax').ajax({
  503. contentType: 'application/json; charset=utf-8',
  504. type: 'POST',
  505. dataType: 'json',
  506. url: url
  507. }).then(function (resp) {
  508. var xCaAffinity = resp.jqXHR.getResponseHeader('X-CA-Affinity');
  509. return this._getBaseModule(id, xCaAffinity, resp).then(function (module) {
  510. return this.render(true).then(function () {
  511. return module;
  512. }, function (err) {
  513. if (this.logger) {
  514. this.logger.error(err);
  515. }
  516. return module;
  517. }.bind(this));
  518. }.bind(this), function (err) {
  519. if (err && err.toString) {
  520. this.glassContext.appController.showErrorMessage(err.toString(), StringResource.get('error'));
  521. }
  522. throw err;
  523. }.bind(this)).catch(function (e) {
  524. this.render(true);
  525. throw e;
  526. }.bind(this));
  527. }.bind(this));
  528. },
  529. _isLoadingStatusCheck: function _isLoadingStatusCheck(id, status) {
  530. var stat = status;
  531. var runningTasks = _.find(this._runningMetadataTasks, function (task) {
  532. return task.id === id;
  533. });
  534. if (runningTasks) {
  535. stat = 'loading';
  536. }
  537. return stat;
  538. },
  539. _getLocationFromSelection: function _getLocationFromSelection(selection) {
  540. var location = selection.url.substr(0, selection.url.length - 6);
  541. location = location.substr(location.indexOf('objects') + 8);
  542. return location;
  543. },
  544. createModule: function createModule(data) {
  545. return new Promise(function (resolve, reject) {
  546. var saveAsDialog = new SaveAsDialog({
  547. glassContext: this.glassContext,
  548. defaultFileName: data[0].defaultName,
  549. service: {
  550. save: function (service, selection, name) {
  551. saveAsDialog.hide();
  552. var location = this._getLocationFromSelection(selection);
  553. return this.loadSchemaAction(data).then(this._saveModule.bind(this, name, location)).then(function () {
  554. this.glassContext.appController.showToast(StringResource.get('savedSuccess', {
  555. name: name
  556. }), {
  557. type: 'success'
  558. });
  559. }.bind(this), function (err) {
  560. if (err.jqXHR) {
  561. var errorRespText = null;
  562. if (err.jqXHR.responseText) {
  563. var errorRespJson = JSON.parse(err.jqXHR.responseText);
  564. errorRespText = errorRespJson.msg ? errorRespJson.msg : err.jqXHR.responseText;
  565. } else {
  566. errorRespText = err.toString();
  567. }
  568. var errorMessage = err.jqXHR.responseJSON ? err.jqXHR.responseJSON.msg : errorRespText;
  569. this.glassContext.appController.showErrorMessage(errorMessage, StringResource.get('error'));
  570. } else {
  571. this.glassContext.appController.showErrorMessage(err.toString(), StringResource.get('error'));
  572. }
  573. }.bind(this)).then(resolve, resolve);
  574. }.bind(this)
  575. }
  576. });
  577. saveAsDialog.open();
  578. }.bind(this));
  579. },
  580. _saveModule: function _saveModule(name, location, baseModules) {
  581. var objFactory = MoserJS.default.createObjectFactory();
  582. var module = MoserJS.default.ModuleUtils.createModule(objFactory, name, 'en-us');
  583. baseModules.forEach(function (baseModule) {
  584. MoserJS.default.ModuleUtils.addSource(module, MoserJS.default.UseSpecType.LW_OLAP, baseModule.id, null, objFactory, true);
  585. });
  586. var url = 'v1/metadata/modules/?location=' + location;
  587. return this.glassContext.services.fetch.post(url, {
  588. contentType: 'application/json; charset=utf-8',
  589. processData: false,
  590. dataType: 'text',
  591. data: JSON.stringify(module.toJSON())
  592. });
  593. },
  594. loadSchemaAction: function loadSchemaAction(data) {
  595. var aData = data;
  596. if (data.constructor !== Array) {
  597. aData = [data];
  598. }
  599. var aDfd = _.map(aData, this._loadSchema.bind(this));
  600. return Promise.all(aDfd);
  601. },
  602. _loadSchema: function _loadSchema(data) {
  603. if (data.status === 'not_loaded') {
  604. return App.CreateSchema(data, this).then(function (resp) {
  605. var location = resp.getResponseHeader('location');
  606. var storeId = location.substring(location.lastIndexOf('/') + 1, location.length);
  607. return this.render(true).then(function () {
  608. return this.RefreshMetadata(storeId);
  609. }.bind(this));
  610. }.bind(this));
  611. } else {
  612. return this.RefreshMetadata(data.id);
  613. }
  614. },
  615. confirmClearSchemaAction: function confirmClearSchemaAction(data) {
  616. return new Promise(function (resolve, reject) {
  617. var oDialog = this._getNewConfirmationDialog('confirmDelete', StringResource.get('confirmClearMetaData'), StringResource.get('confirmClearMetaDataMessage'));
  618. oDialog.confirm(function () {
  619. this._clearSchemaAction(data).then(resolve, reject);
  620. }.bind(this));
  621. }.bind(this));
  622. },
  623. _getNewConfirmationDialog: function _getNewConfirmationDialog(type, title, message) {
  624. return new ConfirmationDialog(type, title, message);
  625. },
  626. _clearSchemaAction: function _clearSchemaAction(data) {
  627. var aData = data;
  628. if (data.constructor !== Array) {
  629. aData = [data];
  630. }
  631. return Promise.all(this._clearSchemaActionHelper(aData)).then(function () {
  632. return this.render(true);
  633. }.bind(this), function (e) {
  634. this.glassContext.appController.showErrorMessage(e, StringResource.get('error'));
  635. }.bind(this));
  636. },
  637. _clearSchemaActionHelper: function _clearSchemaActionHelper(aData) {
  638. var aDfd = [];
  639. _.forEach(aData, function (d) {
  640. if (d.status === 'loaded' || d.status === 'loading' || d.status === 'pending' || d.status === 'error') {
  641. aDfd.push(App.ClearSchema(d)); //Cancel polling task
  642. if (d.status === 'loading' || d.status === 'pending') {
  643. aDfd.push(this.CancelSchema(d));
  644. }
  645. }
  646. }.bind(this));
  647. return aDfd;
  648. },
  649. cancelSchemaAction: function cancelSchemaAction(data) {
  650. var aData = data;
  651. if (data.constructor !== Array) {
  652. aData = [data];
  653. }
  654. var promises = _.map(aData, function (d) {
  655. var status = this._isLoadingStatusCheck(d.id, d.status);
  656. if (status === 'pending' || status === 'executing' || status === 'loading') {
  657. return this.CancelSchema(d);
  658. } else {
  659. return Promise.resolve();
  660. }
  661. }.bind(this));
  662. return Promise.all(promises).then(function () {
  663. return this.render(true);
  664. }.bind(this), function (e) {
  665. this.glassContext.appController.showErrorMessage(e, StringResource.get('error'));
  666. }.bind(this));
  667. },
  668. CancelSchema: function CancelSchema(item) {
  669. var task = _.find(this._runningMetadataTasks, function (task) {
  670. return item.id === task.id;
  671. });
  672. var taskId = task ? task.task : null;
  673. var xCaAffinity = task ? task.xCaAffinity : null;
  674. if (taskId) {
  675. return App.CancelTask(taskId, xCaAffinity).then(this._removeRunningTask.bind(this, item.id));
  676. } else {
  677. return Promise.resolve();
  678. }
  679. },
  680. _removeRunningTask: function _removeRunningTask(itemId) {
  681. for (var i = 0; i < this._runningMetadataTasks.length; i++) {
  682. if (this._runningMetadataTasks[i].id === itemId) {
  683. this._runningMetadataTasks.splice(i, 1);
  684. break;
  685. }
  686. }
  687. },
  688. _getSchemaLoadPercentageComplete: function _getSchemaLoadPercentageComplete(moserResponse) {
  689. var loadInfo = '';
  690. if (moserResponse) {
  691. var percentComplete = MoserJS.default.ModuleUtils.taskPercentage(moserResponse);
  692. loadInfo = StringResource.get('schemaPercentageLoaded', {
  693. percentLoaded: percentComplete
  694. });
  695. }
  696. return loadInfo;
  697. },
  698. _escapeId: function _escapeId(id) {
  699. return '#' + id.replace(/(:|\.|\[|\]|,|=)/g, '\\$1');
  700. },
  701. ShowSchemaLoadOptions: function ShowSchemaLoadOptions(items, tabName) {
  702. var slideoutId = _.map(items, function (item) {
  703. return item.id;
  704. }).join('_');
  705. var loSlideout = this.glassContext.appController.showSlideOut({
  706. 'parent': this.slideout,
  707. 'width': '300px',
  708. 'onHide': function () {
  709. if (loSlideout && loSlideout.contentView && loSlideout.contentView.onHide) {
  710. loSlideout.contentView.onHide();
  711. }
  712. }.bind(this),
  713. 'content': {
  714. 'id': slideoutId,
  715. 'title': items.length === 1 ? items[0].defaultName : StringResource.get('numberOfSchemas', {
  716. 'number': items.length
  717. }),
  718. 'module': 'bi/admin/datasource/slideout/LoadOptionsPane',
  719. 'parentView': this,
  720. 'items': items,
  721. 'selectedTabName': tabName,
  722. 'signonAndConnection': this.connectionList,
  723. 'glassContext': this.glassContext
  724. }
  725. });
  726. return Promise.resolve();
  727. }
  728. });
  729. return MetaDataListView;
  730. });