PropertiesPageView.js 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  1. "use strict";
  2. /**
  3. * Licensed Materials - Property of IBM
  4. * IBM Cognos Products: admin
  5. * Copyright IBM Corp. 2015, 2019
  6. * US Government Users Restricted Rights - Use, duplication or disclosure
  7. * restricted by GSA ADP Schedule Contract with IBM Corp.
  8. */
  9. define(['underscore', 'bi/content_apps/PropertiesPageView', 'bi/admin/datasource/services/ApiSvc', 'bi/admin/datasource/services/DataSourceListController', 'bi/admin/multitenancy/services/TenantsCustomizationService', 'bi/admin/nls/StringResource', 'text!bi/admin/common/propertiespageview.json', 'bi/admin/common/utils/AJAXUtils', 'bi/admin/datasource/services/ConnectionUtils', 'bi/admin/datasource/services/ConnectionListController', 'bacontentnav/utils/UIHelper', '../ba-graphics/dist/icons-js/custom-visual_16', '../ba-graphics/dist/icons-js/schematic_16', 'bi/admin/common/services/ApiBase', 'jquery'], function (_, BasePropertiesPageView, datasourceApi, DataSourceListController, TenantsController, StringResource, propertiesPageViewDefinitions, AJAXUtils, ConnectionUtils, ConnectionListController, UIHelper, bundleTypeRendererIcon, bundleTypeSchematicIcon, ApiBase, $) {
  10. 'use strict'; //NOSONAR: meant to be strict
  11. var PropertiesPageView = BasePropertiesPageView.extend({
  12. _objectIcons: {
  13. dataSource: {
  14. icon: '#common-data_source',
  15. tooltip: 'datasource'
  16. },
  17. dataSourceConnection: {
  18. icon: '#common-connection',
  19. tooltip: 'connection'
  20. },
  21. dataSourceSignon: {
  22. icon: '#common-password-key',
  23. tooltip: 'signon'
  24. },
  25. tenant: {
  26. icon: '#common-multi_tenant',
  27. tooltip: 'tenant'
  28. },
  29. bundleType_renderer: {
  30. icon: bundleTypeRendererIcon.id || bundleTypeRendererIcon.default.id,
  31. tooltip: StringResource.get('bundleType_renderer')
  32. },
  33. bundleType_schematic: {
  34. icon: bundleTypeSchematicIcon.id || bundleTypeSchematicIcon.default.id,
  35. tooltip: StringResource.get('bundleType_schematic')
  36. }
  37. },
  38. /**
  39. * @param options.$el - JQuery node to append the view onto (either a parent pane or the body)
  40. * @param options.objectInformation {object} - An object that contains the information for the content
  41. *
  42. * @constructor
  43. */
  44. init: function init(options) {
  45. options.objectInformation = options.objectInfo;
  46. PropertiesPageView.inherited('init', this, arguments);
  47. _.extend(this, options);
  48. datasourceApi.glassContext = this.glassContext;
  49. if (options.propertiesPageViewDefinition) {
  50. this._oPropertiesPageViewDefintions = options.propertiesPageViewDefinition;
  51. } else {
  52. this._oPropertiesPageViewDefintions = JSON.parse(propertiesPageViewDefinitions);
  53. }
  54. this.dsController = this._getNewDataSourceListController({
  55. glassContext: this.glassContext
  56. });
  57. this.tenantsController = this._getNewTenantsController({
  58. glassContext: this.glassContext
  59. });
  60. this.apiBase = this._getApiBase({
  61. glassContext: this.glassContext
  62. });
  63. },
  64. _getApiBase: function _getApiBase(options) {
  65. return new ApiBase(options);
  66. },
  67. _getNewDataSourceListController: function _getNewDataSourceListController(options) {
  68. return new DataSourceListController(options);
  69. },
  70. _getNewTenantsController: function _getNewTenantsController(options) {
  71. return new TenantsController(options);
  72. },
  73. reload: function reload() {
  74. this.$el.empty();
  75. this.render();
  76. },
  77. _addTabChangeHandler: function _addTabChangeHandler() {
  78. var tabCon = this._oPropertyUIControl.getProperties()[2];
  79. tabCon.onTabChange = function () {
  80. $(this).trigger('tabChanged');
  81. }.bind(this);
  82. },
  83. cannotEditNSObjects: function cannotEditNSObjects(type) {
  84. var nsObjectTypes = ['namespace', 'namespaceFolder', 'account', 'group', 'role'];
  85. return nsObjectTypes.indexOf(type) !== -1 && this._isExternalNS();
  86. },
  87. _property_name_read_only: function _property_name_read_only() {
  88. var $editIcon = $(this.$el.find('.banner .propertyNameEdit'));
  89. $editIcon.remove();
  90. var $nameInput = $(this.$el.find('.propertiesBannerLabel.v_defaultName'));
  91. $nameInput.attr('readonly', 'true');
  92. $nameInput.css('cursor', 'text');
  93. var $ic = $(this.$el.find('.propertiesBannerIcon'));
  94. $ic.css('cursor', 'text');
  95. },
  96. render: function render() {
  97. return PropertiesPageView.inherited('render', this, arguments).then(function () {
  98. this.$el.addClass('AdminPropPageView');
  99. this._addTabChangeHandler();
  100. if (this.type === 'connection') {
  101. if (this.objectInfo.isNew || this.objectInfo.disabled) {
  102. this._hideExtraTabs();
  103. } else {
  104. this._showExtraTabs();
  105. }
  106. } else if (this.type === 'resourceFolder' || this.cannotEditNSObjects(this.type)) {
  107. this._property_name_read_only();
  108. } else if (this.type === 'visualization') {
  109. var bundle = this._objectIcons['bundleType_' + this.objectInfo.bundleType];
  110. if (bundle) {
  111. // change icon in title banner
  112. var $bundleIcon = this.$el.find('.propertyUIControlBanner .propertiesBannerIcon');
  113. $bundleIcon.attr('title', bundle.tooltip);
  114. if (this.objectInfo.bundleImage) {
  115. var classStr = ' class="' + $bundleIcon.find('svg').attr('class') + '" ';
  116. var srcStr = ' src="' + this.objectInfo.bundleImage + '" ';
  117. $bundleIcon.find('svg').replaceWith('<img ' + classStr + srcStr + '></img>');
  118. } else {
  119. $bundleIcon.find('svg>text').text(bundle.tooltip);
  120. $bundleIcon.find('svg>use').attr('xlink:href', '#' + bundle.icon);
  121. } // change type in first row
  122. var $fileType = this.$el.find('.containerUIControl.propertiesUIControlPageView .propertyRow .propertyDetails .propertyValue.fileType');
  123. $fileType.text(bundle.tooltip);
  124. }
  125. }
  126. }.bind(this)).catch(function (e) {
  127. this.logger.debug(e);
  128. }.bind(this));
  129. },
  130. _hideExtraTabs: function _hideExtraTabs() {
  131. this.slideout.$el.find('.tabNumber2').addClass('disabled').attr('aria-disabled', 'true');
  132. var $disabledIcon = $('<svg role="presentation" class="svgIcon admin-schema-property-icon"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#common-disabled" x="2" y="0" height="12" width="12" style="stroke: #ff0000;"></use></svg>');
  133. this.slideout.$el.find('.tabNumber2>a').append($disabledIcon);
  134. },
  135. _showExtraTabs: function _showExtraTabs() {
  136. this.slideout.$el.find('.tabNumber2').removeClass('disabled').removeAttr('aria-disabled');
  137. this.slideout.$el.find('.tabNumber2>a>svg').remove();
  138. },
  139. _getObjectType: function _getObjectType() {
  140. if (!this.objectInformation.ancestors || this.objectInformation.ancestors.length === 0) {
  141. return this.objectInformation.type;
  142. }
  143. if (this.objectInformation.ancestors[0].type === 'capability') {
  144. return this.objectInformation.ancestors[0].type;
  145. }
  146. return this.objectInformation.type;
  147. },
  148. _invalidDataAccount: function _invalidDataAccount(data) {
  149. var errKey;
  150. if (this.type === 'account') {
  151. if (data.password && !/^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/.test(data.password)) {
  152. errKey = 'passwordInvalidErrorMsg';
  153. } else if (data.surname !== undefined && $.trim(data.surname) === '') {
  154. errKey = 'surnameInvalidErrorMsg';
  155. } else if (data.email && !/^([a-zA-Z0-9]+[_|-|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|-|.]?)*[a-zA-Z0-9]+.[a-zA-Z]{2,3}$/.test(data.email)) {
  156. errKey = 'emailInvalidErrorMsg';
  157. }
  158. if (errKey) {
  159. this.glassContext.appController.showErrorMessage(StringResource.get(errKey), StringResource.get('error'));
  160. }
  161. }
  162. return errKey !== undefined;
  163. },
  164. _invalidData: function _invalidData(data) {
  165. // Glass always calls hide() on open and close of the slideout. This causes the save request to be done multiple
  166. // times. To avoid this, the _isSaved flag is used to indicate that save is already done, so not to do another one.
  167. return this._isSaved || !this.objectInfo.isNew && _.size(data) === 0 || this._invalidDataAccount(data);
  168. },
  169. _isBasicType: function _isBasicType() {
  170. return this.type === 'account' || this.type === 'group' || this.type === 'namespaceFolder' || this.type === 'role';
  171. },
  172. _reloadAfterUpdate: function _reloadAfterUpdate() {
  173. if (this.onUpdate) {
  174. this.onUpdate();
  175. }
  176. if (this.type === 'namespace') {
  177. _.each(this.parentView.listView.dataAdaptor._accountExplorer._nameSpaces, function (item, index) {
  178. if (item.id === this.objectInformation.id) {
  179. this.parentView.listView.dataAdaptor._accountExplorer._nameSpaces[index] = this.objectInformation;
  180. }
  181. }.bind(this));
  182. }
  183. if (this.parentView.refresh) {
  184. this.parentView.refresh();
  185. }
  186. },
  187. _isCorDL: function _isCorDL() {
  188. return this.type === 'contact' || this.type === 'distributionList';
  189. },
  190. update: function update() {
  191. var data;
  192. var dataDefault = this.objectInformation.defaultName;
  193. if (this.objectInformation.contactUpdate) {
  194. data = this.objectInformation.contactUpdate;
  195. delete this.objectInformation.contactUpdate;
  196. } else {
  197. data = this._oPropertyUIControl ? this._oPropertyUIControl.getModifiedProperties() : '';
  198. }
  199. if (this._invalidData(data)) {
  200. return Promise.resolve();
  201. }
  202. if (this._isBasicType()) {
  203. this._convertOptions(data);
  204. } else if (this.type === 'securedFeature' || this.type === 'securedFunction' || this.type === 'productCapability' || this.type === 'resourceFolder' || this.type === 'cosConnection' || this.type === 'cosLocation') {
  205. this.objectInformation = _.extend(this.objectInformation, data);
  206. } else if (this.type !== 'visualization' && this.type !== 'dataSource' && this.type !== 'connection' && this.type !== 'tenant' && !this._isCorDL()) {
  207. this.parentView.listView.dataAdaptor.sortChanged = true;
  208. this.objectInformation = _.extend(this.objectInformation, data);
  209. }
  210. if (data.defaultName === '') {
  211. data.defaultName = dataDefault + '_defaultNameWasEmpty';
  212. }
  213. return this._save(data).then(this._reloadAfterUpdate.bind(this));
  214. },
  215. _getActualValue: function _getActualValue(data, item, val) {
  216. var temp = _.find(this.objectInformation.options, function (opIt) {
  217. return opIt.name === item.name;
  218. });
  219. var actualValue;
  220. if (data[val] !== undefined) {
  221. actualValue = data[val];
  222. } else if (this.objectInformation.options && temp) {
  223. actualValue = temp.value;
  224. } else {
  225. actualValue = item.value;
  226. }
  227. return actualValue;
  228. },
  229. _convertOptionsHelper: function _convertOptionsHelper(data, item) {
  230. var val = item.name;
  231. var sBidiEnumURL = 'http://developer.cognos.com/ceba/constants/biDirectionalOptionEnum#';
  232. if (val.indexOf(sBidiEnumURL) === 0) {
  233. val = val.substring(sBidiEnumURL.length);
  234. }
  235. if (this.objectInformation.options) {
  236. var actualValue = this._getActualValue(data, item, val);
  237. if (_.isString(actualValue) && actualValue.indexOf(sBidiEnumURL) === 0) {
  238. this.objectInformation[val] = actualValue.substring(actualValue.lastIndexOf('#') + 1);
  239. } else {
  240. this.objectInformation[val] = actualValue;
  241. }
  242. item.value = actualValue;
  243. }
  244. },
  245. _convertOptions: function _convertOptions(data) {
  246. var newOptions = [{
  247. 'name': 'http://developer.cognos.com/ceba/constants/biDirectionalOptionEnum#baseTextDirection',
  248. 'type': 'genericOptionAnyURI',
  249. 'value': 'http://developer.cognos.com/ceba/constants/biDirectionalOptionEnum#biDirectionalFeaturesEnabled#RTL'
  250. }, {
  251. 'name': 'http://developer.cognos.com/ceba/constants/biDirectionalOptionEnum#biDirectionalFeaturesEnabled',
  252. 'type': 'genericOptionBoolean',
  253. 'value': false
  254. }, {
  255. 'name': 'showHiddenObjects',
  256. 'type': 'portalOptionBoolean',
  257. 'value': false
  258. }, {
  259. 'name': 'http:\/\/developer.cognos.com\/ceba\/constants\/systemOptionEnum#accessibilityFeatures',
  260. 'type': 'genericOptionBoolean',
  261. 'value': false
  262. }, {
  263. 'name': 'showHints',
  264. 'type': 'portalOptionString',
  265. 'value': 'showAll'
  266. }];
  267. _.extend(this.objectInformation, data);
  268. newOptions.forEach(this._convertOptionsHelper.bind(this, data));
  269. this.objectInformation.options = newOptions;
  270. },
  271. onHide: function onHide() {
  272. if (!this._oPropertyUIControl) {
  273. return Promise.resolve();
  274. } else {
  275. if (this.type === 'connection') {
  276. //in this case we want to make sure we delete the settings tab
  277. //as that is taken care of for us
  278. var tabCon = this._oPropertyUIControl.getProperties()[2];
  279. if (tabCon && tabCon._tabs) {
  280. tabCon._tabs.splice(1, 1);
  281. }
  282. }
  283. this.update().then(function () {
  284. this._oPropertyUIControl.remove();
  285. if (this.parentView.slideout && this.parentView.slideout.content && this.parentView.slideout.parent.parent && this.parentView.slideout.content.module.indexOf('bi/admin/datasource/slideout') > -1) {
  286. this.parentView.slideout.remove();
  287. }
  288. }.bind(this));
  289. return Promise.resolve(true);
  290. }
  291. },
  292. _handleError: function _handleError(err) {
  293. if (AJAXUtils.isNamingConflictErrorMsg(err) || err.status === 409) {
  294. this.glassContext.appController.showErrorMessage(StringResource.get('nameConflictErrorMsg'), StringResource.get('error'));
  295. } else {
  296. this.glassContext.appController.showErrorMessage(err.responseJSON.messages.join('\n'), StringResource.get('error'));
  297. }
  298. },
  299. _updateAccountObject: function _updateAccountObject() {
  300. var userPrefURL;
  301. switch (this.type) {
  302. case 'group':
  303. userPrefURL = AJAXUtils.getPath('updateGroup', this.objectInformation.id);
  304. break;
  305. case 'role':
  306. userPrefURL = AJAXUtils.getPath('updateRole', this.objectInformation.id);
  307. break;
  308. case 'user':
  309. userPrefURL = AJAXUtils.getPath('updateUser', this.objectInformation.id);
  310. break;
  311. case 'namespaceFolder':
  312. userPrefURL = AJAXUtils.getPath('updateNamespaceFolder', this.objectInformation.id);
  313. break;
  314. case 'namespace':
  315. case 'contact':
  316. case 'distributionList':
  317. userPrefURL = AJAXUtils.getPath('updateNamespace', this.objectInformation.id);
  318. break;
  319. case 'securedFeature':
  320. case 'securedFunction':
  321. case 'productCapability':
  322. userPrefURL = 'v1/objects/' + this.objectInformation.id;
  323. break;
  324. default:
  325. userPrefURL = '';
  326. break;
  327. }
  328. var options = {
  329. dataType: 'json',
  330. contentType: 'application/json; charset=utf-8',
  331. type: 'PUT',
  332. data: JSON.stringify(this.objectInformation.updatedData),
  333. url: userPrefURL,
  334. cache: false
  335. };
  336. return this.glassContext.services.ajax.ajax(options);
  337. },
  338. _updateUserPreferences: function _updateUserPreferences() {
  339. var userPrefURL = AJAXUtils.getPath('getUserPreference', this.objectInformation.id);
  340. var options = {
  341. dataType: 'json',
  342. type: 'PUT',
  343. contentType: 'application/json; charset=utf-8',
  344. data: JSON.stringify(this.objectInformation),
  345. url: userPrefURL,
  346. cache: false
  347. };
  348. return this.glassContext.services.ajax.ajax(options);
  349. },
  350. _save: function _save(data) {
  351. this._isSaved = true;
  352. var toastName = data.defaultName ? data.defaultName : this.objectInformation.defaultName;
  353. if (data.defaultName && data.defaultName.includes('_defaultNameWasEmpty')) {
  354. this.type = 'error';
  355. }
  356. var dfd;
  357. switch (this.type) {
  358. case 'account':
  359. this._setObjectInformationForAccounts(data);
  360. dfd = this._updateUserPreferences().then(this._showToastHelper.bind(this, toastName));
  361. break;
  362. case 'group':
  363. case 'role':
  364. case 'namespaceFolder':
  365. dfd = this._getPropertiesInfo().then(function () {
  366. this._dataHelper(data);
  367. return this._updateAccountObject();
  368. }.bind(this)).then(this._showToastHelper.bind(this, toastName));
  369. break;
  370. case 'dataSource':
  371. dfd = this._saveDataSource(data, toastName);
  372. break;
  373. case 'connection':
  374. dfd = this._saveConnection(data);
  375. break;
  376. case 'visualization':
  377. this._dataHelper(data);
  378. dfd = this._saveVisualization().then(this._showToastHelper.bind(this, toastName), function (arg, err) {
  379. this._handleError(err);
  380. }.bind(this));
  381. break;
  382. case 'namespace':
  383. case 'contact':
  384. case 'distributionList':
  385. case 'securedFeature':
  386. case 'securedFunction':
  387. case 'productCapability':
  388. this._dataHelper(data);
  389. dfd = this._updateAccountObject().then(this._showToastHelper.bind(this, toastName), function (arg, err) {
  390. this._handleError(err);
  391. }.bind(this));
  392. break;
  393. case 'tenant':
  394. dfd = this._updateTenant(data);
  395. break;
  396. case 'resourceFolder':
  397. dfd = this.apiBase.updateResourceFolder(this.objectInformation, data);
  398. break;
  399. case 'cosConnection':
  400. dfd = this.apiBase.updateCOSConnection(this.objectInformation, data);
  401. break;
  402. case 'cosLocation':
  403. dfd = this.apiBase.updateCOSLocation(this.objectInformation, data);
  404. break;
  405. default:
  406. this.logger.error('do not know how to handle objects of type ' + this.type);
  407. dfd = Promise.resolve().then(this._showToastHelper.bind(this, toastName));
  408. }
  409. return dfd;
  410. },
  411. _setObjectInformationForAccounts: function _setObjectInformationForAccounts(data) {
  412. if (this.objectInformation.skin) {
  413. this.objectInformation.skin = this.objectInformation.skin.charAt(0).toUpperCase() + this.objectInformation.skin.slice(1);
  414. }
  415. if (this.objectInformation.password) {
  416. this.objectInformation.password = btoa(this.objectInformation.password);
  417. }
  418. if (!this._isAnonymous(this.objectInformation)) {
  419. this.objectInformation.defaultName = this.objectInformation.givenName + ' ' + this.objectInformation.surname;
  420. }
  421. },
  422. _dataHelper: function _dataHelper(data) {
  423. this.objectInformation.updatedData = data;
  424. this.objectInformation.updatedData.type = this.type;
  425. if (this.type === 'securedFeature' || this.type === 'securedFunction' || this.type === 'productCapability') {
  426. this.objectInformation.updatedData.type = this.objectInformation.type;
  427. }
  428. },
  429. _saveDataSource: function _saveDataSource(data, toastName) {
  430. var propertyInfo = {
  431. 'disabled': this.objectInformation.disabled,
  432. 'hidden': this.objectInformation.hidden,
  433. 'hasChildren': this.objectInformation.hasChildren
  434. };
  435. $.extend(propertyInfo, data);
  436. return datasourceApi.dataSources.update(this.objectInformation.id, propertyInfo).then(this._showToastHelper.bind(this, toastName), function (arg, err) {
  437. this._handleError(err);
  438. }.bind(this)).then(function () {
  439. $(this.slideout).trigger('updateObject', this.objectInfo);
  440. }.bind(this));
  441. },
  442. _saveConnection: function _saveConnection(data) {
  443. $.extend(this.objectInfo, data);
  444. if (!this.objectInfo.isNew) {
  445. this._saveExistingConnection();
  446. }
  447. return Promise.resolve();
  448. },
  449. _saveVisualization: function _saveVisualization() {
  450. var userPrefURL = AJAXUtils.getPath('updateVisualization', this.objectInformation.id); // visualizations id saved to CM defaultName field.
  451. // visualizations name saved to CM defaultScreenTip field.
  452. this.objectInformation.updatedData.defaultScreenTip = this.objectInformation.updatedData.defaultName;
  453. delete this.objectInformation.updatedData.defaultName;
  454. var options = {
  455. dataType: 'json',
  456. contentType: 'application/json; charset=utf-8',
  457. type: 'PUT',
  458. data: JSON.stringify(this.objectInformation.updatedData),
  459. url: userPrefURL,
  460. cache: false
  461. };
  462. return this.glassContext.getCoreSvc('.Ajax').ajax(options);
  463. },
  464. _showToastHelper: function _showToastHelper(toastName, newData) {
  465. if (toastName.includes('_defaultNameWasEmpty')) {
  466. var sText = StringResource.get('toastUpdateFailedMsg', {
  467. 'name': toastName.substring(0, toastName.length - 20)
  468. });
  469. this.glassContext.appController.showToast(sText, {
  470. type: 'info'
  471. });
  472. } else {
  473. var sText = StringResource.get('toastUpdateMsg', {
  474. 'name': toastName
  475. });
  476. this.glassContext.appController.showToast(sText, {
  477. type: 'success'
  478. });
  479. }
  480. return newData;
  481. },
  482. setFocus: function setFocus() {
  483. if (this.objectInfo.isNew) {
  484. var nameEl = this.$el.find('.v_defaultName');
  485. $(nameEl).focus();
  486. $(nameEl).select();
  487. } else {
  488. PropertiesPageView.inherited('setFocus', this, arguments);
  489. }
  490. },
  491. _getIdFromLocationHeader: function _getIdFromLocationHeader(response) {
  492. var location = response.getResponseHeader('location');
  493. return location.split('/').pop();
  494. },
  495. _updateTenant: function _updateTenant(data) {
  496. var tenantName = data.defaultName !== undefined ? data.defaultName : this.objectInfo.defaultName;
  497. return this.tenantsController.updateTenant(this.objectInfo.tenantID, data).then(function () {
  498. this.glassContext.appController.showToast(StringResource.get('multitenancySuccessUpdate', {
  499. 'tenantName': tenantName
  500. }));
  501. }.bind(this), function (ajaxOptions, error) {
  502. this.glassContext.appController.showErrorMessage(StringResource.get('multitenacyFailedUpdate', {
  503. 'tenantName': tenantName
  504. }) + ', ' + AJAXUtils.buildErrorMessage(error.responseJSON.errors));
  505. }.bind(this));
  506. },
  507. _saveExistingConnection: function _saveExistingConnection() {
  508. ConnectionUtils.saveConnection(this.glassContext.getCoreSvc('.Ajax'), this.objectInfo, this.connectionSignons, this.removedSignons).then(function () {
  509. var sText = StringResource.get('datasourceConnectionToastUpdateMsg', {
  510. 'name': this.objectInfo.defaultName
  511. });
  512. this.glassContext.appController.showToast(sText, {
  513. type: 'success'
  514. });
  515. if (this.connectionSignons) {
  516. this.connectionSignons.forEach(function (signon) {
  517. delete signon.isNew;
  518. });
  519. }
  520. this.removedSignons = [];
  521. $(this.slideout).trigger('updateObject', this.objectInfo);
  522. }.bind(this), function () {
  523. var sText = StringResource.get('datasourceConnectionToastUpdateFailedMsg', {
  524. 'name': this.objectInfo.defaultName
  525. });
  526. this.glassContext.appController.showToast(sText, {
  527. 'type': 'error'
  528. });
  529. }.bind(this));
  530. },
  531. _getPropertiesInfoForAccount: function _getPropertiesInfoForAccount() {
  532. if (!_.isUndefined(this.accountExplorer)) {
  533. return new Promise(function (resolve, reject) {
  534. this.accountExplorer.getAccount(this.objectInformation).then(function (newData) {
  535. resolve(newData.data[0]);
  536. }, reject);
  537. }.bind(this));
  538. } else {
  539. return Promise.resolve(this.objectInfo);
  540. }
  541. },
  542. _getPropertiesInfoForConnection: function _getPropertiesInfoForConnection() {
  543. if (!this.objectInfo.isNew) {
  544. var conControl = new ConnectionListController({
  545. glassContext: this.glassContext
  546. });
  547. return conControl.getConnection(this.objectInformation.id, this.objectInformation.connId).then(function (newData) {
  548. newData.dataSourceId = this.objectInfo.dataSourceId;
  549. return newData;
  550. }.bind(this));
  551. } else {
  552. return Promise.resolve(this.objectInfo);
  553. }
  554. },
  555. _getPropertiesInfoForGroupRoleFolderNS: function _getPropertiesInfoForGroupRoleFolderNS() {
  556. if (!_.isUndefined(this.accountExplorer)) {
  557. return new Promise(function (resolve, reject) {
  558. this.accountExplorer.getItem(this.objectInformation).then(function (newData) {
  559. resolve(newData.data[0]);
  560. }, reject);
  561. }.bind(this));
  562. } else {
  563. return Promise.resolve(this.objectInfo);
  564. }
  565. },
  566. _getPropertiesInfoForDataSource: function _getPropertiesInfoForDataSource() {
  567. return new Promise(function (resolve, reject) {
  568. this.dsController.getDataSource(this.objectInformation.id).then(function (newData) {
  569. resolve(newData.data[0]);
  570. }, reject);
  571. }.bind(this));
  572. },
  573. _getPropertiesInfoForTenant: function _getPropertiesInfoForTenant() {
  574. return new Promise(function (resolve, reject) {
  575. this.tenantsController.getTenant(this.objectInformation.tenantID).then(function (tenant) {
  576. resolve(tenant.data[0]);
  577. }, reject);
  578. }.bind(this));
  579. },
  580. // visualizations id saved to CM defaultName field.
  581. // visualizations name saved to CM defaultScreenTip field.
  582. _getPropertiesInfoForvisualization: function _getPropertiesInfoForvisualization() {
  583. return this.glassContext.getCoreSvc('.Ajax').ajax({
  584. dataType: 'json',
  585. type: 'GET',
  586. url: 'v1/objects/' + encodeURIComponent(this.objectInformation.id) + '?fields=defaultScreenTip,disabled,hidden,permissions,creationTime,owner.defaultName,hidden,disabled,tenantID,defaultDescription,email,searchPath,ancestors,format,locale,timeZoneID,givenName,surname'
  587. }).then(function (resp) {
  588. resp.data.data[0].defaultName = resp.data.data[0].defaultScreenTip;
  589. return resp.data.data[0];
  590. }).catch(function (err) {
  591. this.logger.error(err);
  592. }.bind(this));
  593. },
  594. _getPropertiesInfoCM: function _getPropertiesInfoCM() {
  595. return this.glassContext.getCoreSvc('.Ajax').ajax({
  596. dataType: 'json',
  597. type: 'GET',
  598. url: 'v1/objects/' + encodeURIComponent(this.objectInformation.id) + '?fields=defaultName,disabled,hidden,permissions,creationTime,owner.defaultName,hidden,disabled,tenantID,defaultDescription,email,searchPath,ancestors,format,locale,timeZoneID,givenName,surname'
  599. }).then(function (resp) {
  600. return resp.data.data[0];
  601. }).catch(function (err) {
  602. this.logger.error(err);
  603. }.bind(this));
  604. },
  605. _getPropertiesInfoForCapability: function _getPropertiesInfoForCapability() {
  606. return this.glassContext.getCoreSvc('.Ajax').ajax({
  607. dataType: 'json',
  608. type: 'GET',
  609. url: 'v1/objects/' + encodeURIComponent(this.objectInformation.id) + '?fields=ancestors,disabled,hidden,permissions,creationTime,owner.defaultName,defaultDescription,parent,defaultName,userCapability,policies,hasChildren,searchPath'
  610. }).then(function (resp) {
  611. return resp.data.data[0];
  612. }).catch(function (err) {
  613. this.logger.error(err);
  614. }.bind(this));
  615. },
  616. _getPropertiesInfoByType: function _getPropertiesInfoByType() {
  617. var dfd;
  618. switch (this.type) {
  619. case 'account':
  620. dfd = this._getPropertiesInfoForAccount();
  621. break;
  622. case 'role':
  623. case 'group':
  624. case 'namespace':
  625. case 'namespaceFolder':
  626. dfd = this._getPropertiesInfoForGroupRoleFolderNS();
  627. break;
  628. case 'dataSource':
  629. dfd = this._getPropertiesInfoForDataSource();
  630. break;
  631. case 'connection':
  632. dfd = this._getPropertiesInfoForConnection();
  633. break;
  634. case 'tenant':
  635. dfd = this._getPropertiesInfoForTenant();
  636. break;
  637. case 'visualization':
  638. dfd = this._getPropertiesInfoForvisualization();
  639. break;
  640. case 'contact':
  641. case 'distributionList':
  642. dfd = this._getPropertiesInfoCM();
  643. break;
  644. case 'securedFeature':
  645. case 'securedFunction':
  646. case 'productCapability':
  647. dfd = this._getPropertiesInfoForCapability();
  648. break;
  649. default:
  650. dfd = Promise.resolve(this.objectInfo);
  651. }
  652. return dfd;
  653. },
  654. _getPropertiesInfo: function _getPropertiesInfo() {
  655. return this._getPropertiesInfoByType().then(function (anObj) {
  656. this.objectInformation = anObj;
  657. }.bind(this));
  658. },
  659. _isExternalNS: function _isExternalNS() {
  660. var allowed = ['CAMID(":', 'CAMID("CognosEx:'];
  661. var isAllowed = _.find(allowed, function (aKey) {
  662. return this.objectInfo.searchPath.indexOf(aKey) >= 0;
  663. }.bind(this));
  664. return this.objectInfo && this.objectInfo.searchPath && !isAllowed;
  665. },
  666. _getFileType: function _getFileType() {
  667. var objectType = this.objectInformation.type;
  668. if (objectType) {
  669. return StringResource.get('type_' + objectType.toLowerCase());
  670. } else {
  671. return StringResource.get('unknown');
  672. }
  673. },
  674. _isAnonymous: function _isAnonymous(objectInformation) {
  675. if (objectInformation) {
  676. return objectInformation.searchPath.indexOf('CAMID("::Anonymous') >= 0;
  677. } else {
  678. return false;
  679. }
  680. },
  681. _getSvgIcon: function _getSvgIcon(objInfo) {
  682. var icon = PropertiesPageView.inherited('_getSvgIcon', this, arguments);
  683. if (icon === null) {
  684. if (this._objectIcons[objInfo.type]) {
  685. icon = this._objectIcons[objInfo.type].icon;
  686. } else {
  687. return '#common-question-mark';
  688. }
  689. }
  690. return icon;
  691. },
  692. _getSvgTooltip: function _getSvgTooltip(objInfo) {
  693. var tooltip = PropertiesPageView.inherited('_getSvgTooltip', this, arguments);
  694. if (_.isUndefined(tooltip)) {
  695. tooltip = this._objectIcons[objInfo.type].tooltip;
  696. }
  697. return tooltip;
  698. },
  699. _getTabItems: function _getTabItems() {
  700. var tabs = this._oPropertiesPageViewDefintions.tabs;
  701. var currentObjTabs = tabs[this._getObjectType()] || tabs['unknown'] || [];
  702. return _.map(_.filter(currentObjTabs, this._isTabVisible.bind(this)), this._getTabSpec.bind(this));
  703. },
  704. _getTabSpec: function _getTabSpec(tab) {
  705. return {
  706. 'name': StringResource.get(tab.name),
  707. 'module': tab.module,
  708. 'objectInfo': this.objectInformation,
  709. 'glassContext': this.glassContext,
  710. 'slideout': this.slideout,
  711. 'accountExplorer': this.accountExplorer,
  712. 'selected': this.selectedTabModule === tab.module,
  713. 'connectionResolver': this.connectionResolver
  714. };
  715. },
  716. _isTabVisible: function _isTabVisible(tab) {
  717. var isVisible = true;
  718. if (this._isDevOnlyTab(tab) || !this._tabHasCapabilities(tab) || !this._tabHasPermissions(tab) || this._isExternalNameSpaceRole(tab) || this._dataSourceConnShowSchemasCubes(tab) || this._isCQdataServConn(tab) || this._isOIDCNameSpaceGroup(tab)) {
  719. isVisible = false;
  720. }
  721. return isVisible;
  722. },
  723. _dataSourceConnShowSchemasCubes: function _dataSourceConnShowSchemasCubes(tab) {
  724. var hideTab = false;
  725. if (this._getObjectType() === 'dataSourceConnection' && tab.connectionClass) {
  726. hideTab = tab.connectionClass !== ConnectionUtils.getConnectionClass(this.objectInformation);
  727. }
  728. return hideTab;
  729. },
  730. _isCQdataServConn: function _isCQdataServConn(tab) {
  731. var hideTab = false;
  732. if (this.objectInformation.isNew) {
  733. return hideTab;
  734. }
  735. if (this._getObjectType() === 'dataSourceConnection' && tab && (tab.name === 'connection_details' || tab.name === 'schemas')) {
  736. var connectionStringParseResult = ConnectionUtils.parseConnectionString(this.objectInformation);
  737. if (!connectionStringParseResult.metadata) {
  738. hideTab = true;
  739. }
  740. }
  741. return hideTab;
  742. },
  743. _isOIDCNameSpaceGroup: function _isOIDCNameSpaceGroup(tab) {
  744. return tab.name === 'members' && this.type === 'group' && this.accountExplorer && this.accountExplorer.isOidcNamespace && this.accountExplorer.isOidcNamespace();
  745. },
  746. _isExternalNameSpaceRole: function _isExternalNameSpaceRole(tab) {
  747. return tab.name === 'customization' && this.type === 'role' && this.accountExplorer && !this.accountExplorer.isBuiltinNamespace();
  748. },
  749. _tabHasPermissions: function _tabHasPermissions(tab) {
  750. return !tab.requiredPermissions || UIHelper.hasPermissions(this.objectInformation.permissions, tab.requiredPermissions);
  751. },
  752. _isDevOnlyTab: function _isDevOnlyTab(tab) {
  753. return !this.glassContext.isDevInstall() && tab.devMode === true;
  754. },
  755. _tabHasCapabilities: function _tabHasCapabilities(tab) {
  756. var hasRequiredCapabilities = true;
  757. if (tab.requiredCapabilities) {
  758. hasRequiredCapabilities = _.find(tab.requiredCapabilities, function (capability) {
  759. return this.glassContext.hasCapability(capability) === false;
  760. }.bind(this)) === undefined;
  761. }
  762. return hasRequiredCapabilities;
  763. }
  764. });
  765. return PropertiesPageView;
  766. });