电子档案
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

738 lines
34 KiB

  1. /* Copyright 2005-2015 Alfresco Software, Ltd.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. var extScope;
  16. angular.module('flowableModeler')
  17. .controller('DecisionTableDetailsCtrl', ['$rootScope', '$scope', '$translate', '$http', '$location', '$routeParams','$modal', '$timeout', '$popover', 'DecisionTableService', 'hotRegisterer',
  18. function ($rootScope, $scope, $translate, $http, $location, $routeParams, $modal, $timeout, $popover, DecisionTableService, hotRegisterer) {
  19. extScope = $scope;
  20. $scope.decisionTableMode = 'read';
  21. // Initialize model
  22. $scope.model = {
  23. // Store the main model id, this points to the current version of a model,
  24. // even when we're showing history
  25. latestModelId: $routeParams.modelId,
  26. columnDefs: [],
  27. columnVariableIdMap: {},
  28. readOnly: true,
  29. availableVariableTypes: ['string', 'number', 'boolean', 'date', 'collection']
  30. };
  31. // Hot Model init
  32. $scope.model.hotSettings = {
  33. stretchH: 'all',
  34. outsideClickDeselects: false,
  35. manualColumnResize: false,
  36. readOnly: true,
  37. disableVisualSelection: true
  38. };
  39. var hotReadOnlyDecisionTableEditorInstance;
  40. var hitPolicies = ['FIRST', 'ANY', 'UNIQUE', 'PRIORITY', 'RULE ORDER', 'OUTPUT ORDER', 'COLLECT'];
  41. var operators = ['==', '!=', '<', '>', '>=', '<=', 'ANY OF', 'NONE OF', 'ALL OF', 'NOT ALL OF', 'IS IN', 'IS NOT IN'];
  42. var columnIdCounter = 0;
  43. var dateFormat = 'YYYY-MM-DD';
  44. var variableUndefined = $translate.instant('DECISION-TABLE-EDITOR.EMPTY-MESSAGES.NO-VARIABLE-SELECTED');
  45. // helper for looking up variable id by col id
  46. $scope.getVariableNameByColumnId = function (colId) {
  47. if (!colId) {
  48. return;
  49. }
  50. if ($scope.model.columnVariableIdMap[colId]) {
  51. return $scope.model.columnVariableIdMap[colId];
  52. } else {
  53. return variableUndefined;
  54. }
  55. };
  56. $scope.loadDecisionTable = function() {
  57. var url, decisionTableUrl;
  58. if ($routeParams.modelHistoryId) {
  59. url = FLOWABLE.APP_URL.getModelHistoryUrl($routeParams.modelId, $routeParams.modelHistoryId);
  60. decisionTableUrl = FLOWABLE.APP_URL.getDecisionTableModelsHistoryUrl($routeParams.modelHistoryId);
  61. } else {
  62. url = FLOWABLE.APP_URL.getModelUrl($routeParams.modelId);
  63. decisionTableUrl = FLOWABLE.APP_URL.getDecisionTableModelUrl($routeParams.modelId);
  64. }
  65. $http({method: 'GET', url: url}).
  66. success(function(data, status, headers, config) {
  67. $scope.model.decisionTable = data;
  68. $scope.model.decisionTableDownloadUrl = decisionTableUrl + '/export?version=' + Date.now();
  69. $scope.loadVersions();
  70. }).error(function(data, status, headers, config) {
  71. $scope.returnToList();
  72. });
  73. };
  74. $scope.useAsNewVersion = function() {
  75. _internalCreateModal({
  76. template: 'views/popup/model-use-as-new-version.html',
  77. scope: $scope
  78. }, $modal, $scope);
  79. };
  80. $scope.toggleFavorite = function() {
  81. $scope.model.favoritePending = true;
  82. var data = {
  83. favorite: !$scope.model.decisionTable.favorite
  84. };
  85. $http({method: 'PUT', url: FLOWABLE.APP_URL.getModelUrl($scope.model.latestModelId), data: data}).
  86. success(function(data, status, headers, config) {
  87. $scope.model.favoritePending = false;
  88. if ($scope.model.decisionTable.favorite) {
  89. $scope.addAlertPromise($translate('DECISION-TABLE.ALERT.UN-FAVORITE-CONFIRM'), 'info');
  90. } else {
  91. $scope.addAlertPromise($translate('DECISION-TABLE.ALERT.FAVORITE-CONFIRM'), 'info');
  92. }
  93. $scope.model.decisionTable.favorite = !$scope.model.decisionTable.favorite;
  94. }).error(function(data, status, headers, config) {
  95. $scope.model.favoritePending = false;
  96. });
  97. };
  98. $scope.loadVersions = function() {
  99. var params = {
  100. includeLatestVersion: !$scope.model.decisionTable.latestVersion
  101. };
  102. $http({method: 'GET', url: FLOWABLE.APP_URL.getModelHistoriesUrl($scope.model.latestModelId), params: params}).
  103. success(function(data, status, headers, config) {
  104. if ($scope.model.decisionTable.latestVersion) {
  105. if (!data.data) {
  106. data.data = [];
  107. }
  108. data.data.unshift($scope.model.decisionTable);
  109. }
  110. $scope.model.versions = data;
  111. });
  112. };
  113. $scope.showVersion = function(version) {
  114. if (version) {
  115. if (version.latestVersion) {
  116. $location.path("/decision-tables/" + $scope.model.latestModelId);
  117. } else {
  118. // Show latest version, no history-suffix needed in URL
  119. $location.path("/decision-tables/" + $scope.model.latestModelId + "/history/" + version.id);
  120. }
  121. }
  122. };
  123. $scope.returnToList = function() {
  124. $location.path("/decision-tables/");
  125. };
  126. $scope.editDecisionTable = function() {
  127. _internalCreateModal({
  128. template: 'views/popup/model-edit.html',
  129. scope: $scope
  130. }, $modal, $scope);
  131. };
  132. $scope.duplicateDecisionTable = function() {
  133. var modalInstance = _internalCreateModal({
  134. template: 'views/popup/decision-table-duplicate.html?version=' + Date.now()
  135. }, $modal, $scope);
  136. modalInstance.$scope.originalModel = $scope.model;
  137. modalInstance.$scope.duplicateDecisionTableCallback = function(result) {
  138. $rootScope.editorHistory = [];
  139. $location.url("/decision-table-editor/" + encodeURIComponent(result.id));
  140. };
  141. };
  142. $scope.deleteDecisionTable = function() {
  143. _internalCreateModal({
  144. template: 'views/popup/model-delete.html',
  145. scope: $scope
  146. }, $modal, $scope);
  147. };
  148. $scope.shareDecisionTable = function() {
  149. _internalCreateModal({
  150. template: 'views/popup/model-share.html',
  151. scope: $scope
  152. }, $modal, $scope);
  153. };
  154. $scope.openEditor = function() {
  155. if ($scope.model.decisionTable) {
  156. $location.path("/decision-table-editor/" + $scope.model.decisionTable.id);
  157. }
  158. };
  159. $scope.toggleHistory = function($event) {
  160. if (!$scope.historyState) {
  161. var state = {};
  162. $scope.historyState = state;
  163. // Create popover
  164. state.popover = $popover(angular.element($event.target), {
  165. template: 'views/popover/history.html',
  166. placement: 'bottom-right',
  167. show: true,
  168. scope: $scope,
  169. container: 'body'
  170. });
  171. var destroy = function() {
  172. state.popover.destroy();
  173. delete $scope.historyState;
  174. };
  175. // When popup is hidden or scope is destroyed, hide popup
  176. state.popover.$scope.$on('tooltip.hide', destroy);
  177. $scope.$on('$destroy', destroy);
  178. }
  179. };
  180. $scope.doAfterGetColHeader = function (col, TH) {
  181. if ($scope.model.columnDefs[col] && $scope.model.columnDefs[col].expressionType === 'input-operator') {
  182. TH.className += "input-operator-header";
  183. } else if ($scope.model.columnDefs[col] && $scope.model.columnDefs[col].expressionType === 'input-expression') {
  184. TH.className += "input-expression-header";
  185. if ($scope.model.startOutputExpression - 1 === col) {
  186. TH.className += " last";
  187. }
  188. } else if ($scope.model.columnDefs[col] && $scope.model.columnDefs[col].expressionType === 'output') {
  189. TH.className += "output-header";
  190. if ($scope.model.startOutputExpression === col) {
  191. TH.className += " first";
  192. }
  193. }
  194. };
  195. $scope.doAfterModifyColWidth = function (width, col) {
  196. if ($scope.model.columnDefs[col] && $scope.model.columnDefs[col].width) {
  197. var settingsWidth = $scope.model.columnDefs[col].width;
  198. if (settingsWidth > width) {
  199. return settingsWidth;
  200. }
  201. }
  202. return width;
  203. };
  204. $scope.doAfterRender = function () {
  205. var element = document.querySelector("thead > tr > th:first-of-type");
  206. if (element) {
  207. var firstChild = element.firstChild;
  208. var newElement = angular.element('<div class="hit-policy-header"><a onclick="triggerHitPolicyEditor()">' + $scope.currentDecisionTable.hitIndicator.substring(0, 1) + '</a></div>');
  209. element.className = 'hit-policy-container';
  210. element.replaceChild(newElement[0], firstChild);
  211. }
  212. $timeout(function () {
  213. hotReadOnlyDecisionTableEditorInstance = hotRegisterer.getInstance('read-only-decision-table-editor');
  214. if (hotReadOnlyDecisionTableEditorInstance) {
  215. hotReadOnlyDecisionTableEditorInstance.validateCells();
  216. }
  217. });
  218. };
  219. $scope.doAfterValidate = function (isValid, value, row, prop, source) {
  220. if (isCorrespondingCollectionOperator(row, prop)) {
  221. return true;
  222. } else if (isCustomExpression(value) || isDashValue(value)) {
  223. disableCorrespondingOperatorCell(row, prop);
  224. return true;
  225. } else {
  226. enableCorrespondingOperatorCell(row, prop);
  227. }
  228. };
  229. var isCustomExpression = function (val) {
  230. return !!(val != null
  231. && (String(val).startsWith('${') || String(val).startsWith('#{')));
  232. };
  233. var isDashValue = function (val) {
  234. return !!(val != null && "-" === val);
  235. };
  236. var isCorrespondingCollectionOperator = function (row, prop) {
  237. var operatorCol = getCorrespondingOperatorCell(row, prop);
  238. var operatorCellMeta = hotReadOnlyDecisionTableEditorInstance.getCellMeta(row, operatorCol);
  239. var isCollectionOperator = false;
  240. if (isOperatorCell(operatorCellMeta)) {
  241. var operatorValue = hotReadOnlyDecisionTableEditorInstance.getDataAtCell(row, operatorCol);
  242. if (operatorValue === "ANY OF" || operatorValue === "NONE OF" || operatorValue === "ALL OF" || operatorValue === "NOT ALL OF"
  243. || operatorValue === "IS IN" || operatorValue === "IS NOT IN") {
  244. isCollectionOperator = true;
  245. }
  246. }
  247. return isCollectionOperator;
  248. };
  249. var disableCorrespondingOperatorCell = function (row, prop) {
  250. var operatorCol = getCorrespondingOperatorCell(row, prop);
  251. var operatorCellMeta = hotReadOnlyDecisionTableEditorInstance.getCellMeta(row, operatorCol);
  252. if (!isOperatorCell(operatorCellMeta)) {
  253. return;
  254. }
  255. if (operatorCellMeta.className != null && operatorCellMeta.className.indexOf('custom-expression-operator') !== -1) {
  256. return;
  257. }
  258. var currentEditor = hotReadOnlyDecisionTableEditorInstance.getCellEditor(row, operatorCol);
  259. hotReadOnlyDecisionTableEditorInstance.setCellMeta(row, operatorCol, 'className', operatorCellMeta.className + ' custom-expression-operator');
  260. hotReadOnlyDecisionTableEditorInstance.setCellMeta(row, operatorCol, 'originalEditor', currentEditor);
  261. hotReadOnlyDecisionTableEditorInstance.setCellMeta(row, operatorCol, 'editor', false);
  262. hotReadOnlyDecisionTableEditorInstance.setDataAtCell(row, operatorCol, null);
  263. };
  264. var enableCorrespondingOperatorCell = function (row, prop) {
  265. var operatorCol = getCorrespondingOperatorCell(row, prop);
  266. var operatorCellMeta = hotReadOnlyDecisionTableEditorInstance.getCellMeta(row, operatorCol);
  267. if (!isOperatorCell(operatorCellMeta)) {
  268. return;
  269. }
  270. if (operatorCellMeta == null || operatorCellMeta.className == null || operatorCellMeta.className.indexOf('custom-expression-operator') == -1) {
  271. return;
  272. }
  273. operatorCellMeta.className = operatorCellMeta.className.replace('custom-expression-operator', '');
  274. hotReadOnlyDecisionTableEditorInstance.setCellMeta(row, operatorCol, 'className', operatorCellMeta.className);
  275. hotReadOnlyDecisionTableEditorInstance.setCellMeta(row, operatorCol, 'editor', operatorCellMeta.originalEditor);
  276. hotReadOnlyDecisionTableEditorInstance.setDataAtCell(row, operatorCol, '==');
  277. };
  278. var getCorrespondingOperatorCell = function (row, prop) {
  279. var currentCol = hotReadOnlyDecisionTableEditorInstance.propToCol(prop);
  280. if (currentCol < 1) {
  281. return;
  282. }
  283. var operatorCol = currentCol - 1;
  284. return operatorCol;
  285. };
  286. var isOperatorCell = function (cellMeta) {
  287. return !(cellMeta == null || cellMeta.prop == null || typeof cellMeta.prop !== 'string'|| cellMeta.prop.endsWith("_operator") === false);
  288. };
  289. var createNewInputExpression = function (inputExpression) {
  290. var newInputExpression;
  291. if (inputExpression) {
  292. newInputExpression = {
  293. id: _generateColumnId(),
  294. label: inputExpression.label,
  295. variableId: inputExpression.variableId,
  296. type: inputExpression.type,
  297. newVariable: inputExpression.newVariable,
  298. entries: inputExpression.entries
  299. };
  300. } else {
  301. newInputExpression = {
  302. id: _generateColumnId(),
  303. label: null,
  304. variableId: null,
  305. type: null,
  306. newVariable: null,
  307. entries: null
  308. };
  309. }
  310. return newInputExpression;
  311. };
  312. $scope.openHitPolicyEditor = function () {
  313. var editTemplate = 'views/popup/decision-table-edit-hit-policy.html';
  314. $scope.model.hitPolicy = $scope.currentDecisionTable.hitIndicator;
  315. _internalCreateModal({
  316. template: editTemplate,
  317. scope: $scope
  318. }, $modal, $scope);
  319. };
  320. $scope.openInputExpressionEditor = function (expressionPos, newExpression) {
  321. var editTemplate = 'views/popup/decision-table-edit-input-expression.html';
  322. $scope.model.newExpression = !!newExpression;
  323. if (!$scope.model.newExpression) {
  324. $scope.model.selectedExpression = $scope.currentDecisionTable.inputExpressions[expressionPos];
  325. } else {
  326. if (expressionPos >= $scope.model.startOutputExpression) {
  327. $scope.model.selectedColumn = $scope.model.startOutputExpression - 1;
  328. } else {
  329. $scope.model.selectedColumn = Math.floor(expressionPos / 2);
  330. }
  331. }
  332. _internalCreateModal({
  333. template: editTemplate,
  334. scope: $scope
  335. }, $modal, $scope);
  336. };
  337. $scope.openOutputExpressionEditor = function (expressionPos, newExpression) {
  338. var editTemplate = 'views/popup/decision-table-edit-output-expression.html';
  339. $scope.model.newExpression = !!newExpression;
  340. $scope.model.hitPolicy = $scope.currentDecisionTable.hitIndicator;
  341. $scope.model.selectedColumn = expressionPos;
  342. if (!$scope.model.newExpression) {
  343. $scope.model.selectedExpression = $scope.currentDecisionTable.outputExpressions[expressionPos];
  344. }
  345. _internalCreateModal({
  346. template: editTemplate,
  347. scope: $scope
  348. }, $modal, $scope);
  349. };
  350. var createNewOutputExpression = function (outputExpression) {
  351. var newOutputExpression;
  352. if (outputExpression) {
  353. newOutputExpression = {
  354. id: _generateColumnId(),
  355. label: outputExpression.label,
  356. variableId: outputExpression.variableId,
  357. type: outputExpression.variableType,
  358. newVariable: outputExpression.newVariable,
  359. entries: outputExpression.entries
  360. };
  361. } else {
  362. newOutputExpression = {
  363. id: _generateColumnId(),
  364. label: null,
  365. variableId: null,
  366. type: null,
  367. newVariable: null,
  368. entries: null
  369. };
  370. }
  371. return newOutputExpression;
  372. };
  373. var _loadDecisionTableDefinition = function (modelId, historyId) {
  374. DecisionTableService.fetchDecisionTableDetails(modelId, historyId).then(function (decisionTable) {
  375. $rootScope.currentDecisionTable = decisionTable.decisionTableDefinition;
  376. $rootScope.currentDecisionTable.id = decisionTable.id;
  377. $rootScope.currentDecisionTable.key = decisionTable.decisionTableDefinition.key;
  378. $rootScope.currentDecisionTable.name = decisionTable.name;
  379. $rootScope.currentDecisionTable.description = decisionTable.description;
  380. // decision table model to used in save dialog
  381. $rootScope.currentDecisionTableModel = {
  382. id: decisionTable.id,
  383. name: decisionTable.name,
  384. key: decisionTable.decisionTableDefinition.key,
  385. description: decisionTable.description
  386. };
  387. if (!$rootScope.currentDecisionTable.hitIndicator) {
  388. $rootScope.currentDecisionTable.hitIndicator = hitPolicies[0];
  389. }
  390. evaluateDecisionTableGrid($rootScope.currentDecisionTable);
  391. });
  392. };
  393. var evaluateDecisionTableGrid = function (decisionTable) {
  394. $scope.evaluateDecisionHeaders(decisionTable);
  395. evaluateDecisionGrid(decisionTable);
  396. };
  397. var setGridValues = function (key, type) {
  398. if ($scope.model.rulesData) {
  399. $scope.model.rulesData.forEach(function (rowData) {
  400. if (type === 'input-operator') {
  401. if (!(key in rowData) || rowData[key] === '') {
  402. rowData[key] = '==';
  403. }
  404. }
  405. // else if (type === 'input-expression') {
  406. // if (!(key in rowData) || rowData[key] === '') {
  407. // rowData[key] = '-';
  408. // }
  409. // }
  410. });
  411. }
  412. };
  413. var evaluateDecisionGrid = function (decisionTable) {
  414. var tmpRuleGrid = [];
  415. // rows
  416. if (decisionTable.rules && decisionTable.rules.length > 0) {
  417. decisionTable.rules.forEach(function (rule) {
  418. // rule data
  419. var tmpRowValues = {};
  420. for (var i = 0; i < Object.keys(rule).length; i++) {
  421. var id = Object.keys(rule)[i];
  422. $scope.model.columnDefs.forEach(function (columnDef) {
  423. // set counter to max value
  424. var expressionId = 0;
  425. try {
  426. expressionId = parseInt(columnDef.expression.id);
  427. } catch (e) {
  428. }
  429. if (expressionId > columnIdCounter) {
  430. columnIdCounter = expressionId;
  431. }
  432. });
  433. tmpRowValues[id] = rule[id];
  434. }
  435. tmpRuleGrid.push(tmpRowValues);
  436. });
  437. } else {
  438. // initialize default values
  439. tmpRuleGrid.push(createDefaultRow());
  440. }
  441. // $rootScope.currentDecisionTableRules = tmpRuleGrid;
  442. $scope.model.rulesData = tmpRuleGrid;
  443. };
  444. var createDefaultRow = function () {
  445. var defaultRow = {};
  446. $scope.model.columnDefs.forEach(function (columnDefinition) {
  447. if (columnDefinition.expressionType === 'input-operator') {
  448. defaultRow[columnDefinition.data] = '==';
  449. }
  450. // else if (columnDefinition.expressionType === 'input-expression') {
  451. // defaultRow[columnDefinition.data] = '-';
  452. // }
  453. else if (columnDefinition.expressionType === 'output') {
  454. defaultRow[columnDefinition.data] = '';
  455. }
  456. });
  457. return defaultRow;
  458. };
  459. var composeInputOperatorColumnDefinition = function (inputExpression) {
  460. var expressionPosition = $scope.currentDecisionTable.inputExpressions.indexOf(inputExpression);
  461. var columnDefinition = {
  462. data: inputExpression.id + '_operator',
  463. expressionType: 'input-operator',
  464. expression: inputExpression,
  465. width: '70',
  466. className: 'input-operator-cell',
  467. type: 'dropdown',
  468. source: operators
  469. };
  470. return columnDefinition;
  471. };
  472. var composeInputExpressionColumnDefinition = function (inputExpression) {
  473. var expressionPosition = $scope.currentDecisionTable.inputExpressions.indexOf(inputExpression);
  474. var type;
  475. switch (inputExpression.type) {
  476. case 'date':
  477. type = 'date';
  478. break;
  479. case 'number':
  480. type = 'numeric';
  481. break;
  482. case 'boolean':
  483. type = 'dropdown';
  484. break;
  485. default:
  486. type = 'text';
  487. }
  488. var columnDefinition = {
  489. data: inputExpression.id + '_expression',
  490. type: type,
  491. title: '<div class="input-header">' +
  492. '<a onclick="triggerExpressionEditor(\'input\',' + expressionPosition + ',false)"><span class="header-label">' + (inputExpression.label ? inputExpression.label : "New Input") + '</span></a>' +
  493. '<br><span class="header-variable">' + (inputExpression.variableId ? inputExpression.variableId : "none") + '</span>' +
  494. '<br/><span class="header-variable-type">' + (inputExpression.type ? inputExpression.type : "") + '</brspan>' +
  495. '</div>',
  496. expressionType: 'input-expression',
  497. expression: inputExpression,
  498. className: 'htCenter',
  499. width: '200'
  500. };
  501. if (inputExpression.entries && inputExpression.entries.length > 0) {
  502. var entriesOptionValues = inputExpression.entries.slice(0, inputExpression.entries.length);
  503. entriesOptionValues.push('-', '', ' ');
  504. columnDefinition.type = 'dropdown';
  505. columnDefinition.strict = true;
  506. columnDefinition.source = entriesOptionValues;
  507. columnDefinition.title = '<div class="input-header">' +
  508. '<a onclick="triggerExpressionEditor(\'input\',' + expressionPosition + ',false)"><span class="header-label">' + (inputExpression.label ? inputExpression.label : "New Input") + '</span></a>' +
  509. '<br><span class="header-variable">' + (inputExpression.variableId ? inputExpression.variableId : "none") + '</span>' +
  510. '<br/><span class="header-variable-type">' + (inputExpression.type ? inputExpression.type : "") + '</span>' +
  511. '<br><span class="header-entries">[' + inputExpression.entries.join() + ']</span>' +
  512. '</div>';
  513. }
  514. if (type === 'date') {
  515. columnDefinition.dateFormat = dateFormat;
  516. } else if (type === 'dropdown') {
  517. columnDefinition.source = ['true', 'false', '-'];
  518. }
  519. return columnDefinition;
  520. };
  521. var composeOutputColumnDefinition = function (outputExpression) {
  522. var expressionPosition = $scope.currentDecisionTable.outputExpressions.indexOf(outputExpression);
  523. var type;
  524. switch (outputExpression.type) {
  525. case 'date':
  526. type = 'date';
  527. break;
  528. case 'number':
  529. type = 'numeric';
  530. break;
  531. case 'boolean':
  532. type = 'dropdown';
  533. break;
  534. default:
  535. type = 'text';
  536. }
  537. var title = '';
  538. var columnDefinition = {
  539. data: outputExpression.id,
  540. type: type,
  541. expressionType: 'output',
  542. expression: outputExpression,
  543. className: 'htCenter',
  544. width: '270'
  545. };
  546. if (outputExpression.entries && outputExpression.entries.length > 0) {
  547. var entriesOptionValues = outputExpression.entries.slice(0, outputExpression.entries.length);
  548. columnDefinition.type = 'dropdown';
  549. columnDefinition.source = entriesOptionValues;
  550. columnDefinition.strict = true;
  551. title += '<div class="output-header">' +
  552. '<a onclick="triggerExpressionEditor(\'output\',' + expressionPosition + ',false)"><span class="header-label">' + (outputExpression.label ? outputExpression.label : "New Output") + '</span></a>' +
  553. '<br><span class="header-variable">' + (outputExpression.variableId ? outputExpression.variableId : "none") + '</span>' +
  554. '<br/><span class="header-variable-type">' + (outputExpression.type ? outputExpression.type : "") + '</span>' +
  555. '<br><span class="header-entries">[' + outputExpression.entries.join() + ']</span>' +
  556. '</div>';
  557. } else {
  558. title += '<div class="output-header">' +
  559. '<a onclick="triggerExpressionEditor(\'output\',' + expressionPosition + ',false)"><span class="header-label">' + (outputExpression.label ? outputExpression.label : "New Output") + '</span></a>' +
  560. '<br><span class="header-variable">' + (outputExpression.variableId ? outputExpression.variableId : "none") + '</span>' +
  561. '<br/><span class="header-variable-type">' + (outputExpression.type ? outputExpression.type : "") + '</span>' +
  562. '</div>'
  563. }
  564. if (type === 'date') {
  565. columnDefinition.dateFormat = dateFormat;
  566. } else if (type === 'dropdown') {
  567. columnDefinition.source = ['true', 'false', '-'];
  568. }
  569. columnDefinition.title = title;
  570. return columnDefinition;
  571. };
  572. $scope.evaluateDecisionHeaders = function (decisionTable) {
  573. var columnDefinitions = [];
  574. var inputExpressionCounter = 0;
  575. if (decisionTable.inputExpressions && decisionTable.inputExpressions.length > 0) {
  576. decisionTable.inputExpressions.forEach(function (inputExpression) {
  577. var inputOperatorColumnDefinition = composeInputOperatorColumnDefinition(inputExpression);
  578. columnDefinitions.push(inputOperatorColumnDefinition);
  579. setGridValues(inputOperatorColumnDefinition.data, inputOperatorColumnDefinition.expressionType);
  580. var inputExpressionColumnDefinition = composeInputExpressionColumnDefinition(inputExpression);
  581. columnDefinitions.push(inputExpressionColumnDefinition);
  582. setGridValues(inputExpressionColumnDefinition.data, inputExpressionColumnDefinition.expressionType);
  583. inputExpressionCounter += 2;
  584. });
  585. } else { // create default input expression
  586. decisionTable.inputExpressions = [];
  587. var inputExpression = createNewInputExpression();
  588. decisionTable.inputExpressions.push(inputExpression);
  589. columnDefinitions.push(composeInputOperatorColumnDefinition(inputExpression));
  590. columnDefinitions.push(composeInputExpressionColumnDefinition(inputExpression));
  591. inputExpressionCounter += 2;
  592. }
  593. columnDefinitions[inputExpressionCounter - 1].className += ' last';
  594. $scope.model.startOutputExpression = inputExpressionCounter;
  595. if (decisionTable.outputExpressions && decisionTable.outputExpressions.length > 0) {
  596. decisionTable.outputExpressions.forEach(function (outputExpression) {
  597. columnDefinitions.push(composeOutputColumnDefinition(outputExpression));
  598. });
  599. } else { // create default output expression
  600. decisionTable.outputExpressions = [];
  601. var outputExpression = createNewOutputExpression();
  602. decisionTable.outputExpressions.push(outputExpression);
  603. columnDefinitions.push(composeOutputColumnDefinition(outputExpression));
  604. }
  605. columnDefinitions[inputExpressionCounter].className += ' first';
  606. // timeout needed for trigger hot update when removing column defs
  607. $scope.model.columnDefs = columnDefinitions;
  608. $timeout(function () {
  609. if (hotReadOnlyDecisionTableEditorInstance) {
  610. hotReadOnlyDecisionTableEditorInstance.render();
  611. }
  612. });
  613. };
  614. // fetch table from service and populate model
  615. _loadDecisionTableDefinition($routeParams.modelId, $routeParams.modelHistoryId);
  616. var _generateColumnId = function () {
  617. columnIdCounter++;
  618. return "" + columnIdCounter;
  619. };
  620. // Load model needed for favorites
  621. $scope.loadDecisionTable();
  622. }]);