PropertiesConnectionTab.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  1. "use strict";
  2. /**
  3. * Licensed Materials - Property of IBM
  4. * IBM Cognos Products: admin
  5. * Copyright IBM Corp. 2017, 2018
  6. * US Government Users Restricted Rights - Use, duplication or disclosure
  7. * restricted by GSA ADP Schedule Contract with IBM Corp.
  8. */
  9. define(['underscore', 'doT', 'bi/content_apps/PropertiesTab', 'bi/admin/nls/StringResource', 'bi/commons/ui/dialogs/ConfirmationDialog', 'bi/admin/datasource/services/ConnectionUtils', 'text!bi/admin/datasource/templates/TestResultTemplate.html', 'react-dom', 'react', 'mobx', 'ba-react-admin/ba-react-admin.min', 'bi/commons/utils/Utils', 'baglass/core-client/js/core-client/utils/BidiUtil', 'bi/commons/ui/content/dialog/SignOnDialog'], function (_, dot, PropertiesTab, StringResource, ConfirmationDialog, ConnectionUtils, TestResultTemplate, ReactDOM, React, mobx, AdminReact, Utils, BidiUtil, SignOnDialog) {
  10. 'use strict'; //NOSONAR: meant to be strict
  11. var PropertiesConnectionTab = PropertiesTab.extend({
  12. init: function init(options) {
  13. PropertiesConnectionTab.inherited('init', this, arguments);
  14. _.extend(this, options);
  15. this.removedSignons = [];
  16. if (this.objectInfo.isNew) {
  17. this.hasChanged = true;
  18. }
  19. if (!this.objectInfo.connId) {
  20. this.objectInfo.connId = this.objectInfo.id;
  21. }
  22. this._setValidateInitialWhiteSpaceInput();
  23. this.selectedSignonFromReact = null;
  24. this.myDSSignon = null;
  25. },
  26. _setValidateInitialWhiteSpaceInput: function _setValidateInitialWhiteSpaceInput() {
  27. var elem = this.slideout.$el.find(".propertiesBannerLabel.v_defaultName");
  28. elem.on("keyup", function () {
  29. if (elem.val() < 1) {
  30. elem.val(elem.val().trim());
  31. }
  32. if (elem[0].value.length === 0) {
  33. elem.on("keydown", function (event) {
  34. if (event.which === 32) {
  35. event.preventDefault();
  36. }
  37. });
  38. } else {
  39. elem.off("keydown");
  40. }
  41. });
  42. this.slideout.$el.end();
  43. },
  44. _getContent: function _getContent() {
  45. return ConnectionUtils.getSignons(this.glassContext.getCoreSvc('.Ajax'), this.objectInfo.dataSourceId, this.objectInfo.id);
  46. },
  47. _getConnectionParamsItems: function _getConnectionParamsItems(items) {
  48. items.push({
  49. 'name': 'connectionInfo',
  50. 'label': StringResource.get('connectionInformation'),
  51. 'value': this.objectInfo.permissions && this.objectInfo.permissions.indexOf("write") === -1 ? StringResource.get('viewConnectionInformation') : StringResource.get('editConnectionInformation'),
  52. 'type': 'SingleLineValue',
  53. 'ellipses': true,
  54. 'editCallback': this._openConnectionInformation.bind(this)
  55. });
  56. items.push({
  57. 'type': 'Separator'
  58. });
  59. },
  60. _resetConnectionInformationSlideout: function _resetConnectionInformationSlideout() {
  61. if (this.connectionEditorSlideout) {
  62. return this.connectionEditorSlideout.hide({
  63. force: true
  64. });
  65. } else {
  66. return Promise.resolve();
  67. }
  68. },
  69. _openConnectionInformation: function _openConnectionInformation() {
  70. if (this.connectionEditorSlideout) {
  71. //the slide out is already opened
  72. return;
  73. }
  74. this.hasChanged = this.objectInfo.permissions && this.objectInfo.permissions.indexOf("write") !== -1;
  75. this.connectionEditorSlideout = this.glassContext.appController.showSlideOut({
  76. 'pinning': {
  77. 'isPinned': true,
  78. 'display': false
  79. },
  80. 'parent': this.slideout,
  81. 'width': "550px",
  82. 'content': {
  83. 'showGobackButton': false,
  84. 'module': this.parseResult.metadata.module,
  85. 'parentView': this,
  86. 'objectInfo': this.objectInfo,
  87. 'parseInfo': this.parseResult,
  88. 'glassContext': this.glassContext
  89. }
  90. });
  91. this.connectionEditorSlideout.onHide = function () {
  92. delete this.connectionEditorSlideout;
  93. }.bind(this);
  94. },
  95. _openSignonPropertiesSlideout: function _openSignonPropertiesSlideout(signon, signonList) {
  96. this.signonListFromReact = mobx.toJS(signonList);
  97. this._resetConnectionInformationSlideout().then(function () {
  98. var selectedTab = "bi/admin/common/GeneralPropertiesTab";
  99. if (signon.isNew) {
  100. selectedTab = "bi/admin/datasource/ui/PropertiesSignonTab";
  101. }
  102. var slideout = this.glassContext.appController.showSlideOut({
  103. 'parent': this.slideout,
  104. 'width': "450px",
  105. 'content': {
  106. 'module': 'bi/admin/common/PropertiesPageView',
  107. 'parentView': this,
  108. 'listPane': this,
  109. 'objectInfo': signon,
  110. 'glassContext': this._glassContext,
  111. 'selectedTabModule': selectedTab,
  112. 'tabChanged': function () {
  113. var signonUICon = slideout.contentView.getPropertyUIControl();
  114. var modProperties = signonUICon.getModifiedProperties();
  115. _.extend(signon, modProperties);
  116. if (modProperties.defaultName) {
  117. this._modifySignon(signon);
  118. }
  119. }.bind(this)
  120. },
  121. 'onHide': function () {
  122. var signonUICon = slideout.contentView.getPropertyUIControl();
  123. var modProperties = signonUICon.getModifiedProperties();
  124. delete modProperties.credentialsEx;
  125. _.extend(signon, modProperties);
  126. this._modifySignon(signon);
  127. }.bind(this)
  128. });
  129. slideout.$el.on("credentialChanged", this.updateSignon.bind(this, slideout));
  130. }.bind(this));
  131. },
  132. _confirmUnsavedChanged: function _confirmUnsavedChanged() {
  133. var oDialog = this._newConfirmationDialog('confirmApplyChanges', StringResource.get('confirmChange'), StringResource.get('datasourceConfirmApply'));
  134. oDialog.confirm(this._saveConnection.bind(this));
  135. },
  136. _newConfirmationDialog: function _newConfirmationDialog(sType, sTitle, sMessage) {
  137. return new ConfirmationDialog(sType, sTitle, sMessage);
  138. },
  139. onClose: function onClose() {
  140. if (this.hasChanged) {
  141. this.hasChanged = false;
  142. this._confirmUnsavedChanged();
  143. }
  144. ReactDOM.unmountComponentAtNode(this.$el.find('#myReactElement')[0]);
  145. return this._oPropertyUIControl.onClose();
  146. },
  147. updateConnectionString: function updateConnectionString() {
  148. if (this.parseResult.metadata.code === 'EXTCATALOG') {
  149. delete this.parseResult.jdbcURL;
  150. } else if (this.parseResult.metadata.categoryId === 'jdbc' && (this.parseResult.jdbcURL === '' || _.isUndefined(this.parseResult.jdbcURL))) {
  151. this.parseResult.jdbcURL = this.parseResult.metadata.urlTemplate;
  152. }
  153. var connString = ConnectionUtils.buildConnection(this.parseResult, this.objectInfo);
  154. this.objectInfo.connectionString = ConnectionUtils.getUpdatedConnectionString(this.parseResult, connString);
  155. },
  156. _modifySignon: function _modifySignon(localSignOn) {
  157. var tempSignonArray = [];
  158. var tempSignonObject = {};
  159. var indexToChange;
  160. this.signonListFromReact.forEach(function (item, index) {
  161. if (item.id === localSignOn.id) {
  162. tempSignonObject = {
  163. label: localSignOn.defaultName,
  164. value: index,
  165. id: localSignOn.id
  166. };
  167. indexToChange = index;
  168. }
  169. tempSignonArray.push(this.signonListFromReact[index]);
  170. }.bind(this));
  171. if (_.isEmpty(tempSignonObject)) {
  172. tempSignonObject = {
  173. label: localSignOn.defaultName,
  174. value: tempSignonArray.length,
  175. id: localSignOn.id
  176. };
  177. }
  178. if (indexToChange > -1) {
  179. tempSignonArray.splice(indexToChange, 1, tempSignonObject);
  180. } else {
  181. tempSignonArray.push(tempSignonObject);
  182. }
  183. this.myDSSignon.updateSignons(tempSignonArray);
  184. this.myDSSignon.updateSelectedSignon(tempSignonObject);
  185. },
  186. updateSignon: function updateSignon(signonSlideout, evt, localSignOn) {
  187. var signonUICon = signonSlideout.contentView.getPropertyUIControl();
  188. var modProperties = signonUICon.getModifiedProperties();
  189. if (modProperties.credentialUserName !== localSignOn.newUser) {
  190. localSignOn.credentialsEx.username = localSignOn.newUser;
  191. } else if (modProperties.credentialUserName) {
  192. localSignOn.credentialsEx.username = modProperties.credentialUserName;
  193. delete modProperties.credentialUserName;
  194. }
  195. if (modProperties.credentialPassword !== localSignOn.newPassword) {
  196. localSignOn.credentialsEx.password = localSignOn.newPassword;
  197. } else if (modProperties.credentialPassword) {
  198. localSignOn.credentialsEx.password = modProperties.credentialPassword;
  199. delete modProperties.credentialPassword;
  200. }
  201. delete localSignOn.newUser;
  202. delete localSignOn.newPassword;
  203. _.extend(localSignOn, modProperties);
  204. this._modifySignon(localSignOn);
  205. localSignOn.credentialsEx.updatedSignon = 'updated';
  206. localSignOn.updated = true;
  207. },
  208. _getTestItems: function _getTestItems(items) {
  209. items.push({
  210. 'type': 'Separator'
  211. });
  212. items.push({
  213. 'name': 'testGroup',
  214. 'type': 'SingleLineLinks',
  215. 'items': [{
  216. 'align': 'left',
  217. 'items': [{
  218. 'type': 'icon',
  219. 'svgIcon': 'common-run',
  220. 'clickCallback': this._executeTest.bind(this),
  221. 'iconTooltip': StringResource.get('test'),
  222. 'role': 'button',
  223. 'class': 'testButton'
  224. }]
  225. }, {
  226. 'align': 'right',
  227. 'items': []
  228. }]
  229. });
  230. items.push({
  231. 'type': 'Separator'
  232. });
  233. },
  234. _getFooter: function _getFooter(items) {
  235. items.push({
  236. 'type': 'Footer',
  237. 'items': [{
  238. 'type': 'Button',
  239. 'label': StringResource.get('dataServerSave'),
  240. 'primary': true,
  241. 'onSelect': this._saveConnection.bind(this)
  242. }]
  243. });
  244. },
  245. _saveConnection_error: function _saveConnection_error(key) {
  246. return this.glassContext.appController.showToast(StringResource.get(key), {
  247. 'type': 'error',
  248. 'onHidden': function (event) {
  249. this.slideout.contentView.getPropertyUIControl().getProperty('defaultName').value = '';
  250. this.setFocus();
  251. }.bind(this)
  252. });
  253. },
  254. _saveConnection: function _saveConnection() {
  255. var modProperties = this.slideout.contentView.getPropertyUIControl().getModifiedProperties();
  256. _.extend(this.objectInfo, modProperties);
  257. this.hasChanged = false;
  258. this.updateConnectionString();
  259. this.slideout.connectionSignons = this.connectionSignons;
  260. this.slideout.removedSignons = this.removedSignons;
  261. delete this.objectInfo.searchPath;
  262. delete this.objectInfo.owner;
  263. delete this.objectInfo._meta;
  264. delete this.objectInfo.ancestors;
  265. delete this.objectInfo.version;
  266. if (this.objectInfo.defaultName === '') {
  267. return this._saveConnection_error('emptyConnectionName');
  268. }
  269. if (this.objectInfo.isNew && _.isUndefined(modProperties.defaultName)) {
  270. return this._saveConnection_error('unmodifiedConnectionName');
  271. }
  272. return this._save().then(function () {
  273. return ConnectionUtils.getSignons(this.glassContext.getCoreSvc('.Ajax'), this.objectInfo.dataSourceId, this.objectInfo.id).then(function (signons) {
  274. this.connectionSignons = signons;
  275. this._updateDatasourceList();
  276. }.bind(this));
  277. }.bind(this));
  278. },
  279. _updateDatasourceList: function _updateDatasourceList() {
  280. $(this.slideout.$el).trigger('com.ibm.cognos.bi.admin.refreshDataServerList');
  281. },
  282. _save: function _save() {
  283. if (this.objectInfo.gatewayDestination && this.objectInfo.gatewayDestination[0]) {
  284. this.objectInfo.gatewayDestination = [{
  285. type: 'gatewayDestination',
  286. searchPath: "storeID('" + this.objectInfo.gatewayDestination[0].id + "')"
  287. }];
  288. }
  289. if (this.objectInfo.isNew) {
  290. return this._saveNewConnection();
  291. } else {
  292. return this._saveExistingConnection();
  293. }
  294. },
  295. _saveNewConnection: function _saveNewConnection() {
  296. var savePromise;
  297. var isNewConnection = false;
  298. if (this.objectInfo.newConnection) {
  299. isNewConnection = true;
  300. delete this.objectInfo.newConnection;
  301. savePromise = ConnectionUtils.createNewConnection(this.glassContext.getCoreSvc('.Ajax'), this.objectInfo, this.connectionSignons);
  302. } else {
  303. savePromise = ConnectionUtils.createNewDataSource(this.glassContext.getCoreSvc('.Ajax'), this.objectInfo, this.connectionSignons);
  304. }
  305. savePromise.then(function () {
  306. var sText = StringResource.get('datasourceConnectionToastUpdateMsg', {
  307. 'name': this.objectInfo.defaultName
  308. });
  309. this.glassContext.appController.showToast(sText, {
  310. type: 'success'
  311. });
  312. this.slideout.contentView.selectedTabModule = "bi/admin/datasource/ui/PropertiesConnectionTab";
  313. if (this.$el.find('#myReactElement')[0]) {
  314. ReactDOM.unmountComponentAtNode(this.$el.find('#myReactElement')[0]);
  315. }
  316. delete this.objectInfo.isNew;
  317. this.slideout.contentView.reload();
  318. if (this.parseResult && this.parseResult.gwStringUpdated) {
  319. delete this.parseResult.gwStringUpdated;
  320. }
  321. }.bind(this)).catch(function (error) {
  322. if (isNewConnection) {
  323. this.objectInfo.newConnection = true;
  324. }
  325. this._errorResponseCheck(error);
  326. }.bind(this));
  327. return savePromise;
  328. },
  329. setFocus: function setFocus() {
  330. var bannerLabel = this.slideout.$el.find(".propertiesBannerLabel.v_defaultName");
  331. if (bannerLabel.length > 0) {
  332. bannerLabel[0].focus();
  333. }
  334. },
  335. _saveExistingConnection: function _saveExistingConnection() {
  336. return ConnectionUtils.saveConnection(this.glassContext.getCoreSvc('.Ajax'), this.objectInfo, this.connectionSignons, this.removedSignons).then(function () {
  337. var sText = StringResource.get('datasourceConnectionToastUpdateMsg', {
  338. 'name': this.objectInfo.defaultName
  339. });
  340. this.glassContext.appController.showToast(sText, {
  341. type: 'success'
  342. });
  343. this.slideout.contentView.selectedTabModule = "bi/admin/datasource/ui/PropertiesConnectionTab";
  344. if (this.$el.find('#myReactElement')[0]) {
  345. ReactDOM.unmountComponentAtNode(this.$el.find('#myReactElement')[0]);
  346. }
  347. this.slideout.contentView.reload();
  348. this.connectionSignons.forEach(function (signon) {
  349. delete signon.isNew;
  350. });
  351. if (this.parseResult && this.parseResult.gwStringUpdated) {
  352. delete this.parseResult.gwStringUpdated;
  353. }
  354. if (this.parseResult && this.parseResult.apiToken) {
  355. delete this.parseResult.apiToken;
  356. }
  357. this.removedSignons = [];
  358. }.bind(this)).catch(this._errorResponseCheck.bind(this));
  359. },
  360. _errorResponseCheck: function _errorResponseCheck(error) {
  361. var errorCode;
  362. if (error.jqXHR && error.jqXHR.responseJSON) {
  363. if (error.jqXHR.responseJSON.errors && error.jqXHR.responseJSON.errors[0].errorCode) {
  364. errorCode = error.jqXHR.responseJSON.errors[0].errorCode;
  365. } else if (error.jqXHR.responseJSON.errorCode) {
  366. errorCode = error.jqXHR.responseJSON.errorCode;
  367. } else {
  368. errorCode = StringResource.get('internalErrorMsg');
  369. }
  370. } else {
  371. errorCode = StringResource.get('internalErrorMsg');
  372. }
  373. var toastMsg;
  374. if (errorCode.includes("cmDuplicateName")) {
  375. toastMsg = StringResource.get('duplicateDSExists');
  376. } else {
  377. toastMsg = StringResource.get('dataServerError', {
  378. errorCode: errorCode
  379. });
  380. }
  381. this.glassContext.appController.showToast(toastMsg, {
  382. 'type': 'error',
  383. 'onHidden': function (event) {
  384. this.setFocus();
  385. }.bind(this)
  386. });
  387. },
  388. _renderProperties: function _renderProperties() {
  389. var items = [];
  390. this._getConnectionParamsItems(items);
  391. this._getTestItems(items);
  392. if (this.objectInfo.permissions && this.objectInfo.permissions.indexOf("write") !== -1) {
  393. this._getFooter(items);
  394. }
  395. return this.renderPropertyUIControl({
  396. 'el': this.$el,
  397. 'glassContext': this.glassContext,
  398. 'items': items
  399. }).then(function () {
  400. $(this.$el.find('.separator')[0]).after($('<div id=myReactElement>'));
  401. ReactDOM.unmountComponentAtNode(this.$el.find('#myReactElement')[0]);
  402. var dsSignon = React.createElement(AdminReact.DataServSignOn, {
  403. 'glassContext': this.glassContext,
  404. 'slideout': this.slideout,
  405. 'StringResource': StringResource,
  406. 'ConnectionUtils': ConnectionUtils,
  407. 'objectInfo': this.objectInfo,
  408. 'authMethod': this.parseResult.authMethod,
  409. 'connectionSignons': this.connectionSignons,
  410. 'removedSignons': this.removedSignons,
  411. 'textDir': BidiUtil.userPreferredTextDir,
  412. 'parent': this
  413. });
  414. this.myDSSignon = ReactDOM.render(dsSignon, this.$el.find('#myReactElement')[0]);
  415. }.bind(this));
  416. },
  417. render: function render() {
  418. this._id = _.uniqueId('prop_');
  419. this.$el.addClass("admin_datasource_slideout");
  420. if (this.objectInfo.isNew) {
  421. if (!this.objectInfo.vendor.module) {
  422. this.objectInfo.vendor.module = ConnectionUtils._DEFAULTCONNECTIONSTRINGMODULE;
  423. }
  424. this.parseResult = {
  425. metadata: this.objectInfo.vendor,
  426. connStringTemplate: ConnectionUtils._connStringTemplateToken,
  427. authMethod: "anon"
  428. };
  429. if (ConnectionUtils.isTMRConnection(this.objectInfo)) {
  430. this.parseResult.tm1Params = {
  431. tm1AdminHost: '',
  432. tm1Port: '',
  433. tm1ServerName: '',
  434. tm1UseSSL: false,
  435. tm1Language: ''
  436. };
  437. } else if (ConnectionUtils.isOLAPConnection(this.objectInfo)) {
  438. this.parseResult.msasVersion = '';
  439. this.parseResult.serverUrl = '';
  440. this.parseResult.namedInstance = '';
  441. }
  442. this.updateConnectionString();
  443. } else {
  444. this.parseResult = ConnectionUtils.parseConnectionString(this.objectInfo);
  445. }
  446. return this._getContent().then(function (signons) {
  447. this.connectionSignons = signons;
  448. ConnectionUtils.resolveAuthMethod(this.parseResult, this.objectInfo, signons); //this code is important because this is a reload situation where the signon was saved
  449. //we need to update the selectedSignon to be passed to test/
  450. //if this doesn't happen - the selected signon does not get updated on a save and we use invalid
  451. //creds for the test connection
  452. if (this.selectedSignonFromReact) {
  453. this.connectionSignons.forEach(function (item) {
  454. if (item.id === signon.id) {
  455. return this.selectedSignonFromReact = item;
  456. }
  457. }.bind(this));
  458. }
  459. return this._renderProperties();
  460. }.bind(this)).then(function () {
  461. this._completeTestButtonRender();
  462. if (this.slideout && this.slideout.contentView) {
  463. $(this.slideout.contentView).on("tabChanged", this._resetConnectionInformationSlideout.bind(this));
  464. }
  465. if (this.objectInfo.isNew) {
  466. this._openConnectionInformation();
  467. }
  468. }.bind(this));
  469. },
  470. _completeTestButtonRender: function _completeTestButtonRender() {
  471. var $resultSec = $(this._getTestResultsSection());
  472. var $testSec = $(this._getTestButtonsSection());
  473. var $testButton = $($testSec.find(".testButton"));
  474. var $testLabel = $('<div role="presentation" class="testText">' + StringResource.get('test') + '</div>');
  475. $testButton.append($testLabel);
  476. $testSec.addClass("testResultSection");
  477. $resultSec.append('<div class="notTestedText">' + StringResource.get('notTested') + '</div>');
  478. },
  479. _openTestResultsSlideout: function _openTestResultsSlideout(results) {
  480. this._resetConnectionInformationSlideout().then(function () {
  481. this.glassContext.appController.showSlideOut({
  482. 'parent': this.slideout,
  483. 'width': "450px",
  484. 'content': {
  485. 'showGobackButton': true,
  486. 'module': 'bi/admin/datasource/slideout/TestResultSlideout',
  487. 'parentView': this,
  488. 'objectInfo': this.objectInfo,
  489. 'results': results,
  490. 'glassContext': this.glassContext
  491. }
  492. });
  493. }.bind(this));
  494. },
  495. _getTestGroup: function _getTestGroup() {
  496. var testSection = this.getPropertyUIControl().getProperty('testGroup');
  497. if (!testSection) {
  498. this.logger.error("could not find test result section");
  499. return;
  500. }
  501. return testSection.getPropertyNode();
  502. },
  503. _getTestButtonsSection: function _getTestButtonsSection() {
  504. var $testSection = $(this._getTestGroup());
  505. return $testSection.find(".left");
  506. },
  507. _getTestResultsSection: function _getTestResultsSection() {
  508. var $testSection = $(this._getTestGroup());
  509. return $testSection.find(".right");
  510. },
  511. _showTestExecuting: function _showTestExecuting($testSec) {
  512. var loadingAnimation = Utils.getLoadingAnimation(1);
  513. var $container = $('<div class="emptyTableContent bi-admin-working"><a class="testCancel">' + StringResource.get('cancel') + '</a></div>');
  514. $container.append(loadingAnimation);
  515. $testSec.append($container);
  516. $container.find(".testCancel").on("primaryaction", this._cancelTesting.bind(this));
  517. },
  518. _cancelTesting: function _cancelTesting() {
  519. if (this.testingPromise) {
  520. this.testingPromise.cancelled = true;
  521. } else {
  522. this.testingPromise = new Promise(function (resolve, reject) {});
  523. this.testingPromise.cancelled = true;
  524. }
  525. this._showTestResult(this.testingPromise);
  526. },
  527. _stopTestExecuting: function _stopTestExecuting($testSec) {
  528. $testSec.empty();
  529. },
  530. _createResultUI: function _createResultUI(message, icon, resultClass, $root, isCancel) {
  531. var htmlStr = dot.template(TestResultTemplate)({
  532. message: message,
  533. icon: icon,
  534. resultClass: resultClass,
  535. isCancel: isCancel ? true : false,
  536. openResultLabel: StringResource.get('openResultPane')
  537. });
  538. $root.append(htmlStr);
  539. },
  540. _showTestResult: function _showTestResult(testingPromise, results) {
  541. var $testResultSec = this._getTestResultsSection();
  542. if (testingPromise && testingPromise.objectInfo && testingPromise.objectInfo.connectionString === 'undefined') {
  543. this._createResultUI(StringResource.get('connection_empty'), 'common-error', 'testFailed', $testResultSec, true);
  544. return;
  545. }
  546. this._stopTestExecuting($testResultSec);
  547. if (testingPromise.cancelled) {
  548. this._createResultUI(StringResource.get('canceled'), '', 'canceled', $testResultSec, true);
  549. return;
  550. } else {
  551. var responsePromise = results.jqXHR;
  552. if (responsePromise.status === 200) {
  553. this._createResultUI(StringResource.get('success'), 'common-success', 'testSuccess', $testResultSec);
  554. } else {
  555. this._createResultUI(StringResource.get('testingFailed'), 'common-error', 'testFailed', $testResultSec);
  556. }
  557. var testResInfoEl = $testResultSec.find(".testResultInfoIcon");
  558. $(testResInfoEl).on("primaryaction", this._openTestResultsSlideout.bind(this, responsePromise));
  559. }
  560. },
  561. _getNewSignOnDialog: function _getNewSignOnDialog(spec) {
  562. return new SignOnDialog(spec);
  563. },
  564. _getSelectedSignonFromPrompt: function _getSelectedSignonFromPrompt() {
  565. return new Promise(function (resolve, reject) {
  566. var signonPrompt = this._getNewSignOnDialog({
  567. 'dataSourceName': "",
  568. 'dataSourceConnectionName': "",
  569. 'glassContext': this.glassContext,
  570. 'displayErrMsg': true,
  571. 'canSaveCredentials': false,
  572. 'onSubmit': function (Object) {
  573. var creds = signonPrompt.view.getCredentialsInfo();
  574. resolve({
  575. credentialsEx: {
  576. username: creds.userID,
  577. password: creds.password,
  578. updatedSignon: 'testDialog'
  579. }
  580. });
  581. }.bind(this),
  582. 'onCancel': function () {
  583. this._cancelTesting();
  584. reject();
  585. }.bind(this)
  586. });
  587. signonPrompt.view.canSaveCredentials = false;
  588. signonPrompt.open();
  589. }.bind(this));
  590. },
  591. _executeTest: function _executeTest() {
  592. var testResultSec = this._getTestResultsSection();
  593. $(testResultSec).empty();
  594. var jdbcString = ConnectionUtils.buildConnection(this.parseResult, this.objectInfo);
  595. this.objectInfo.connectionString = ConnectionUtils.getUpdatedConnectionString(this.parseResult, jdbcString);
  596. if (this.objectInfo.connectionString === 'undefined' || this.objectInfo.connectionString === '') {
  597. return this._showTestResult(this, this.testingPromise);
  598. }
  599. this._showTestExecuting($(testResultSec));
  600. var selectedSignon;
  601. if (this.parseResult.authMethod === 'prompt') {
  602. selectedSignon = this._getSelectedSignonFromPrompt();
  603. } else {
  604. var signOn;
  605. if (this.parseResult.authMethod === 'ucac') {
  606. signOn = {
  607. namespace: this.objectInfo.credentialNamespaces[0].searchPath
  608. };
  609. } else {
  610. if (this.selectedSignonFromReact) {
  611. signOn = this.selectedSignonFromReact;
  612. } else {
  613. signOn = this.connectionSignons[0];
  614. }
  615. }
  616. selectedSignon = Promise.resolve(signOn);
  617. }
  618. return selectedSignon.then(this._completeTesting.bind(this));
  619. },
  620. _completeTesting: function _completeTesting(selectedSignon) {
  621. this.testingPromise = ConnectionUtils.test(this.glassContext.getCoreSvc('.Ajax'), this.objectInfo.connectionString, selectedSignon, this.objectInfo.apiToken);
  622. this.testingPromise.then(this._showTestResult.bind(this, this.testingPromise));
  623. this.testingPromise.fail(this._showTestResult.bind(this, this.testingPromise));
  624. return this.testingPromise;
  625. },
  626. //Calls from React
  627. addSignonFromReact: function addSignonFromReact(signonList) {
  628. //There is a chance that the connection name has been set so lets use that
  629. var connName = this.slideout.$el.find(".v_defaultName");
  630. if (connName.length > 0) {
  631. this.objectInfo.defaultName = connName[0].value;
  632. }
  633. var newSignon = {
  634. id: _.uniqueId('signon_'),
  635. defaultName: this.objectInfo.defaultName,
  636. permissions: ["execute", "read", "setPolicy", "traverse", "write"],
  637. disabled: false,
  638. hidden: false,
  639. isNew: true,
  640. type: 'dataSourceSignon',
  641. credentialsEx: {
  642. password: "###PASSWORD###",
  643. username: StringResource.get('NewSigonUserName')
  644. }
  645. };
  646. this.connectionSignons.push(newSignon);
  647. this.hasChanged = true;
  648. this._openSignonPropertiesSlideout(newSignon, signonList);
  649. },
  650. editSignonFromReact: function editSignonFromReact(signonList, reactSignon) {
  651. var signon;
  652. this.connectionSignons.forEach(function (item) {
  653. if (item.id === reactSignon.id) {
  654. signon = item;
  655. }
  656. }.bind(this));
  657. signon.isEdited = true;
  658. this._openSignonPropertiesSlideout(signon, signonList, reactSignon);
  659. },
  660. setSelectedSignonFromReact: function setSelectedSignonFromReact(signon) {
  661. if (signon) {
  662. this.connectionSignons.forEach(function (item) {
  663. if (item.id === signon.id) {
  664. return this.selectedSignonFromReact = item;
  665. }
  666. }.bind(this));
  667. } else {
  668. if (this.connectionSignons.length > 0) {
  669. this.selectedSignonFromReact = this.connectionSignons[0];
  670. } else {
  671. this.selectedSignonFromReact = null;
  672. }
  673. }
  674. },
  675. updateAuthFromReact: function updateAuthFromReact(signonOption) {
  676. this.hasChanged = this.objectInfo.permissions && this.objectInfo.permissions.indexOf("write") !== -1;
  677. this.parseResult.authMethod = signonOption;
  678. this.objectInfo.signonOption = signonOption;
  679. if (this.objectInfo.signonOption !== 'ucac') {
  680. this.objectInfo.credentialNamespaces = [];
  681. }
  682. },
  683. updateUCACfromReact: function updateUCACfromReact(chosenNamespace) {
  684. this.objectInfo.credentialNamespaces = [];
  685. this.objectInfo.credentialNamespaces.push(chosenNamespace);
  686. },
  687. moveSignonToDeletedFromReact: function moveSignonToDeletedFromReact(selSignon) {
  688. this.hasChanged = true;
  689. if (selSignon.id.substring(0, 7) !== 'signon_') {
  690. this.removedSignons.push(selSignon);
  691. }
  692. this.connectionSignons = _.reject(this.connectionSignons, function (item) {
  693. return item.id === selSignon.id;
  694. });
  695. if (this.connectionSignons && this.connectionSignons.length === 0) {
  696. this.selectedSignonFromReact = null;
  697. }
  698. },
  699. deleteSignonsFromReact: function deleteSignonsFromReact() {
  700. this.connectionSignons.forEach(function (signon) {
  701. if (signon.id.substring(0, 7) !== 'signon_') {
  702. this.removedSignons.push(signon);
  703. }
  704. }.bind(this));
  705. this.connectionSignons = [];
  706. this.selectedSignonFromReact = null;
  707. }
  708. });
  709. return PropertiesConnectionTab;
  710. });