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.
		
		
		
		
			
				
					739 lines
				
				34 KiB
			
		
		
			
		
	
	
					739 lines
				
				34 KiB
			| 
											2 years ago
										 | /* Copyright 2005-2015 Alfresco Software, Ltd. | ||
|  |  * | ||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||
|  |  * you may not use this file except in compliance with the License. | ||
|  |  * You may obtain a copy of the License at | ||
|  |  * | ||
|  |  *      http://www.apache.org/licenses/LICENSE-2.0
 | ||
|  |  * | ||
|  |  * Unless required by applicable law or agreed to in writing, software | ||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, | ||
|  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
|  |  * See the License for the specific language governing permissions and | ||
|  |  * limitations under the License. | ||
|  |  */ | ||
|  | 
 | ||
|  | var extScope; | ||
|  | 
 | ||
|  | angular.module('flowableModeler') | ||
|  |     .controller('DecisionTableDetailsCtrl', ['$rootScope', '$scope', '$translate', '$http', '$location', '$routeParams','$modal', '$timeout', '$popover', 'DecisionTableService', 'hotRegisterer', | ||
|  |         function ($rootScope, $scope, $translate, $http, $location, $routeParams, $modal, $timeout, $popover, DecisionTableService, hotRegisterer) { | ||
|  | 
 | ||
|  |             extScope = $scope; | ||
|  | 
 | ||
|  |             $scope.decisionTableMode = 'read'; | ||
|  | 
 | ||
|  |             // Initialize model
 | ||
|  |             $scope.model = { | ||
|  |                 // Store the main model id, this points to the current version of a model,
 | ||
|  |                 // even when we're showing history
 | ||
|  |                 latestModelId: $routeParams.modelId, | ||
|  |                 columnDefs: [], | ||
|  |                 columnVariableIdMap: {}, | ||
|  |                 readOnly: true, | ||
|  |                 availableVariableTypes: ['string', 'number', 'boolean', 'date', 'collection'] | ||
|  |             }; | ||
|  | 
 | ||
|  |             // Hot Model init
 | ||
|  |             $scope.model.hotSettings = { | ||
|  |                 stretchH: 'all', | ||
|  |                 outsideClickDeselects: false, | ||
|  |                 manualColumnResize: false, | ||
|  |                 readOnly: true, | ||
|  |                 disableVisualSelection: true | ||
|  |             }; | ||
|  | 
 | ||
|  |             var hotReadOnlyDecisionTableEditorInstance; | ||
|  |             var hitPolicies = ['FIRST', 'ANY', 'UNIQUE', 'PRIORITY', 'RULE ORDER', 'OUTPUT ORDER', 'COLLECT']; | ||
|  |             var operators = ['==', '!=', '<', '>', '>=', '<=', 'ANY OF', 'NONE OF', 'ALL OF', 'NOT ALL OF', 'IS IN', 'IS NOT IN']; | ||
|  |             var columnIdCounter = 0; | ||
|  |             var dateFormat = 'YYYY-MM-DD'; | ||
|  | 
 | ||
|  |             var variableUndefined = $translate.instant('DECISION-TABLE-EDITOR.EMPTY-MESSAGES.NO-VARIABLE-SELECTED'); | ||
|  |             // helper for looking up variable id by col id
 | ||
|  |             $scope.getVariableNameByColumnId = function (colId) { | ||
|  | 
 | ||
|  |                 if (!colId) { | ||
|  |                     return; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 if ($scope.model.columnVariableIdMap[colId]) { | ||
|  |                     return $scope.model.columnVariableIdMap[colId]; | ||
|  |                 } else { | ||
|  |                     return variableUndefined; | ||
|  |                 } | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.loadDecisionTable = function() { | ||
|  |                 var url, decisionTableUrl; | ||
|  |                 if ($routeParams.modelHistoryId) { | ||
|  |                     url = FLOWABLE.APP_URL.getModelHistoryUrl($routeParams.modelId, $routeParams.modelHistoryId); | ||
|  |                     decisionTableUrl = FLOWABLE.APP_URL.getDecisionTableModelsHistoryUrl($routeParams.modelHistoryId); | ||
|  |                 } else { | ||
|  |                     url = FLOWABLE.APP_URL.getModelUrl($routeParams.modelId); | ||
|  |                     decisionTableUrl = FLOWABLE.APP_URL.getDecisionTableModelUrl($routeParams.modelId); | ||
|  |                 } | ||
|  | 
 | ||
|  |                 $http({method: 'GET', url: url}). | ||
|  |                     success(function(data, status, headers, config) { | ||
|  |                         $scope.model.decisionTable = data; | ||
|  |                         $scope.model.decisionTableDownloadUrl = decisionTableUrl + '/export?version=' + Date.now(); | ||
|  |                         $scope.loadVersions(); | ||
|  | 
 | ||
|  |                     }).error(function(data, status, headers, config) { | ||
|  |                         $scope.returnToList(); | ||
|  |                     }); | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.useAsNewVersion = function() { | ||
|  |                 _internalCreateModal({ | ||
|  |                     template: 'views/popup/model-use-as-new-version.html', | ||
|  |                     scope: $scope | ||
|  |                 }, $modal, $scope); | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.toggleFavorite = function() { | ||
|  |                 $scope.model.favoritePending = true; | ||
|  | 
 | ||
|  |                 var data = { | ||
|  |                     favorite: !$scope.model.decisionTable.favorite | ||
|  |                 }; | ||
|  | 
 | ||
|  |                 $http({method: 'PUT', url: FLOWABLE.APP_URL.getModelUrl($scope.model.latestModelId), data: data}). | ||
|  |                     success(function(data, status, headers, config) { | ||
|  |                         $scope.model.favoritePending = false; | ||
|  |                         if ($scope.model.decisionTable.favorite) { | ||
|  |                             $scope.addAlertPromise($translate('DECISION-TABLE.ALERT.UN-FAVORITE-CONFIRM'), 'info'); | ||
|  |                         } else { | ||
|  |                             $scope.addAlertPromise($translate('DECISION-TABLE.ALERT.FAVORITE-CONFIRM'), 'info'); | ||
|  |                         } | ||
|  |                         $scope.model.decisionTable.favorite = !$scope.model.decisionTable.favorite; | ||
|  |                     }).error(function(data, status, headers, config) { | ||
|  |                         $scope.model.favoritePending = false; | ||
|  |                     }); | ||
|  |             }; | ||
|  | 
 | ||
|  | 
 | ||
|  |             $scope.loadVersions = function() { | ||
|  | 
 | ||
|  |                 var params = { | ||
|  |                     includeLatestVersion: !$scope.model.decisionTable.latestVersion | ||
|  |                 }; | ||
|  | 
 | ||
|  |                 $http({method: 'GET', url: FLOWABLE.APP_URL.getModelHistoriesUrl($scope.model.latestModelId), params: params}). | ||
|  |                     success(function(data, status, headers, config) { | ||
|  |                         if ($scope.model.decisionTable.latestVersion) { | ||
|  |                             if (!data.data) { | ||
|  |                                 data.data = []; | ||
|  |                             } | ||
|  |                             data.data.unshift($scope.model.decisionTable); | ||
|  |                         } | ||
|  | 
 | ||
|  |                         $scope.model.versions = data; | ||
|  |                     }); | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.showVersion = function(version) { | ||
|  |                 if (version) { | ||
|  |                     if (version.latestVersion) { | ||
|  |                         $location.path("/decision-tables/" +  $scope.model.latestModelId); | ||
|  |                     } else { | ||
|  |                         // Show latest version, no history-suffix needed in URL
 | ||
|  |                         $location.path("/decision-tables/" +  $scope.model.latestModelId + "/history/" + version.id); | ||
|  |                     } | ||
|  |                 } | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.returnToList = function() { | ||
|  |                 $location.path("/decision-tables/"); | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.editDecisionTable = function() { | ||
|  |                 _internalCreateModal({ | ||
|  |                     template: 'views/popup/model-edit.html', | ||
|  |                     scope: $scope | ||
|  |                 }, $modal, $scope); | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.duplicateDecisionTable = function() { | ||
|  | 
 | ||
|  |                 var modalInstance = _internalCreateModal({ | ||
|  |                     template: 'views/popup/decision-table-duplicate.html?version=' + Date.now() | ||
|  |                 }, $modal, $scope); | ||
|  | 
 | ||
|  |                 modalInstance.$scope.originalModel = $scope.model; | ||
|  | 
 | ||
|  |                 modalInstance.$scope.duplicateDecisionTableCallback = function(result) { | ||
|  |                     $rootScope.editorHistory = []; | ||
|  |                     $location.url("/decision-table-editor/" + encodeURIComponent(result.id)); | ||
|  |                 }; | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.deleteDecisionTable = function() { | ||
|  |                 _internalCreateModal({ | ||
|  |                     template: 'views/popup/model-delete.html', | ||
|  |                     scope: $scope | ||
|  |                 }, $modal, $scope); | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.shareDecisionTable = function() { | ||
|  |                 _internalCreateModal({ | ||
|  |                     template: 'views/popup/model-share.html', | ||
|  |                     scope: $scope | ||
|  |                 }, $modal, $scope); | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.openEditor = function() { | ||
|  |                 if ($scope.model.decisionTable) { | ||
|  |                     $location.path("/decision-table-editor/" + $scope.model.decisionTable.id); | ||
|  |                 } | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.toggleHistory = function($event) { | ||
|  |                 if (!$scope.historyState) { | ||
|  |                     var state = {}; | ||
|  |                     $scope.historyState = state; | ||
|  | 
 | ||
|  |                     // Create popover
 | ||
|  |                     state.popover = $popover(angular.element($event.target), { | ||
|  |                         template: 'views/popover/history.html', | ||
|  |                         placement: 'bottom-right', | ||
|  |                         show: true, | ||
|  |                         scope: $scope, | ||
|  |                         container: 'body' | ||
|  |                     }); | ||
|  | 
 | ||
|  |                     var destroy = function() { | ||
|  |                         state.popover.destroy(); | ||
|  |                         delete $scope.historyState; | ||
|  |                     }; | ||
|  | 
 | ||
|  |                     // When popup is hidden or scope is destroyed, hide popup
 | ||
|  |                     state.popover.$scope.$on('tooltip.hide', destroy); | ||
|  |                     $scope.$on('$destroy', destroy); | ||
|  |                 } | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.doAfterGetColHeader = function (col, TH) { | ||
|  |                 if ($scope.model.columnDefs[col] && $scope.model.columnDefs[col].expressionType === 'input-operator') { | ||
|  |                     TH.className += "input-operator-header"; | ||
|  |                 } else if ($scope.model.columnDefs[col] && $scope.model.columnDefs[col].expressionType === 'input-expression') { | ||
|  |                     TH.className += "input-expression-header"; | ||
|  |                     if ($scope.model.startOutputExpression - 1 === col) { | ||
|  |                         TH.className += " last"; | ||
|  |                     } | ||
|  |                 } else if ($scope.model.columnDefs[col] && $scope.model.columnDefs[col].expressionType === 'output') { | ||
|  |                     TH.className += "output-header"; | ||
|  |                     if ($scope.model.startOutputExpression === col) { | ||
|  |                         TH.className += " first"; | ||
|  |                     } | ||
|  |                 } | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.doAfterModifyColWidth = function (width, col) { | ||
|  |                 if ($scope.model.columnDefs[col] && $scope.model.columnDefs[col].width) { | ||
|  |                     var settingsWidth = $scope.model.columnDefs[col].width; | ||
|  |                     if (settingsWidth > width) { | ||
|  |                         return settingsWidth; | ||
|  |                     } | ||
|  |                 } | ||
|  |                 return width; | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.doAfterRender = function () { | ||
|  |                 var element = document.querySelector("thead > tr > th:first-of-type"); | ||
|  |                 if (element) { | ||
|  |                     var firstChild = element.firstChild; | ||
|  |                     var newElement = angular.element('<div class="hit-policy-header"><a onclick="triggerHitPolicyEditor()">' + $scope.currentDecisionTable.hitIndicator.substring(0, 1) + '</a></div>'); | ||
|  |                     element.className = 'hit-policy-container'; | ||
|  |                     element.replaceChild(newElement[0], firstChild); | ||
|  |                 } | ||
|  | 
 | ||
|  |                 $timeout(function () { | ||
|  |                     hotReadOnlyDecisionTableEditorInstance = hotRegisterer.getInstance('read-only-decision-table-editor'); | ||
|  |                     if (hotReadOnlyDecisionTableEditorInstance) { | ||
|  |                         hotReadOnlyDecisionTableEditorInstance.validateCells(); | ||
|  |                     } | ||
|  |                 }); | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.doAfterValidate = function (isValid, value, row, prop, source) { | ||
|  |                 if (isCorrespondingCollectionOperator(row, prop)) { | ||
|  |                     return true; | ||
|  |                 } else if (isCustomExpression(value) || isDashValue(value)) { | ||
|  |                     disableCorrespondingOperatorCell(row, prop); | ||
|  |                     return true; | ||
|  |                 } else { | ||
|  |                     enableCorrespondingOperatorCell(row, prop); | ||
|  |                 } | ||
|  |             }; | ||
|  | 
 | ||
|  |             var isCustomExpression = function (val) { | ||
|  |                 return !!(val != null | ||
|  |                     && (String(val).startsWith('${') || String(val).startsWith('#{'))); | ||
|  |             }; | ||
|  | 
 | ||
|  |             var isDashValue = function (val) { | ||
|  |                 return !!(val != null && "-" === val); | ||
|  |             }; | ||
|  | 
 | ||
|  |             var isCorrespondingCollectionOperator = function (row, prop) { | ||
|  |                 var operatorCol = getCorrespondingOperatorCell(row, prop); | ||
|  |                 var operatorCellMeta = hotReadOnlyDecisionTableEditorInstance.getCellMeta(row, operatorCol); | ||
|  | 
 | ||
|  |                 var isCollectionOperator = false; | ||
|  |                 if (isOperatorCell(operatorCellMeta)) { | ||
|  |                     var operatorValue = hotReadOnlyDecisionTableEditorInstance.getDataAtCell(row, operatorCol); | ||
|  |                     if (operatorValue === "ANY OF" || operatorValue === "NONE OF" || operatorValue === "ALL OF" || operatorValue === "NOT ALL OF" | ||
|  |                         || operatorValue === "IS IN" || operatorValue === "IS NOT IN") { | ||
|  |                         isCollectionOperator = true; | ||
|  |                     } | ||
|  |                 } | ||
|  |                 return isCollectionOperator; | ||
|  |             }; | ||
|  | 
 | ||
|  |             var disableCorrespondingOperatorCell = function (row, prop) { | ||
|  |                 var operatorCol = getCorrespondingOperatorCell(row, prop); | ||
|  |                 var operatorCellMeta = hotReadOnlyDecisionTableEditorInstance.getCellMeta(row, operatorCol); | ||
|  | 
 | ||
|  |                 if (!isOperatorCell(operatorCellMeta)) { | ||
|  |                     return; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 if (operatorCellMeta.className != null && operatorCellMeta.className.indexOf('custom-expression-operator') !== -1) { | ||
|  |                     return; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 var currentEditor = hotReadOnlyDecisionTableEditorInstance.getCellEditor(row, operatorCol); | ||
|  | 
 | ||
|  |                 hotReadOnlyDecisionTableEditorInstance.setCellMeta(row, operatorCol, 'className', operatorCellMeta.className + ' custom-expression-operator'); | ||
|  |                 hotReadOnlyDecisionTableEditorInstance.setCellMeta(row, operatorCol, 'originalEditor', currentEditor); | ||
|  |                 hotReadOnlyDecisionTableEditorInstance.setCellMeta(row, operatorCol, 'editor', false); | ||
|  |                 hotReadOnlyDecisionTableEditorInstance.setDataAtCell(row, operatorCol, null); | ||
|  |             }; | ||
|  | 
 | ||
|  |             var enableCorrespondingOperatorCell = function (row, prop) { | ||
|  |                 var operatorCol = getCorrespondingOperatorCell(row, prop); | ||
|  |                 var operatorCellMeta = hotReadOnlyDecisionTableEditorInstance.getCellMeta(row, operatorCol); | ||
|  | 
 | ||
|  |                 if (!isOperatorCell(operatorCellMeta)) { | ||
|  |                     return; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 if (operatorCellMeta == null || operatorCellMeta.className == null || operatorCellMeta.className.indexOf('custom-expression-operator') == -1) { | ||
|  |                     return; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 operatorCellMeta.className = operatorCellMeta.className.replace('custom-expression-operator', ''); | ||
|  |                 hotReadOnlyDecisionTableEditorInstance.setCellMeta(row, operatorCol, 'className', operatorCellMeta.className); | ||
|  |                 hotReadOnlyDecisionTableEditorInstance.setCellMeta(row, operatorCol, 'editor', operatorCellMeta.originalEditor); | ||
|  |                 hotReadOnlyDecisionTableEditorInstance.setDataAtCell(row, operatorCol, '=='); | ||
|  |             }; | ||
|  | 
 | ||
|  |             var getCorrespondingOperatorCell = function (row, prop) { | ||
|  |                 var currentCol = hotReadOnlyDecisionTableEditorInstance.propToCol(prop); | ||
|  |                 if (currentCol < 1) { | ||
|  |                     return; | ||
|  |                 } | ||
|  |                 var operatorCol = currentCol - 1; | ||
|  |                 return operatorCol; | ||
|  |             }; | ||
|  | 
 | ||
|  |             var isOperatorCell = function (cellMeta) { | ||
|  |                 return !(cellMeta == null || cellMeta.prop == null || typeof cellMeta.prop !== 'string'|| cellMeta.prop.endsWith("_operator") === false); | ||
|  |             }; | ||
|  | 
 | ||
|  |             var createNewInputExpression = function (inputExpression) { | ||
|  |                 var newInputExpression; | ||
|  |                 if (inputExpression) { | ||
|  |                     newInputExpression = { | ||
|  |                         id: _generateColumnId(), | ||
|  |                         label: inputExpression.label, | ||
|  |                         variableId: inputExpression.variableId, | ||
|  |                         type: inputExpression.type, | ||
|  |                         newVariable: inputExpression.newVariable, | ||
|  |                         entries: inputExpression.entries | ||
|  |                     }; | ||
|  |                 } else { | ||
|  |                     newInputExpression = { | ||
|  |                         id: _generateColumnId(), | ||
|  |                         label: null, | ||
|  |                         variableId: null, | ||
|  |                         type: null, | ||
|  |                         newVariable: null, | ||
|  |                         entries: null | ||
|  |                     }; | ||
|  |                 } | ||
|  |                 return newInputExpression; | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.openHitPolicyEditor = function () { | ||
|  |                 var editTemplate = 'views/popup/decision-table-edit-hit-policy.html'; | ||
|  | 
 | ||
|  |                 $scope.model.hitPolicy = $scope.currentDecisionTable.hitIndicator; | ||
|  | 
 | ||
|  |                 _internalCreateModal({ | ||
|  |                     template: editTemplate, | ||
|  |                     scope: $scope | ||
|  |                 }, $modal, $scope); | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.openInputExpressionEditor = function (expressionPos, newExpression) { | ||
|  |                 var editTemplate = 'views/popup/decision-table-edit-input-expression.html'; | ||
|  | 
 | ||
|  |                 $scope.model.newExpression = !!newExpression; | ||
|  | 
 | ||
|  |                 if (!$scope.model.newExpression) { | ||
|  |                     $scope.model.selectedExpression = $scope.currentDecisionTable.inputExpressions[expressionPos]; | ||
|  |                 } else { | ||
|  |                     if (expressionPos >= $scope.model.startOutputExpression) { | ||
|  |                         $scope.model.selectedColumn = $scope.model.startOutputExpression - 1; | ||
|  |                     } else { | ||
|  |                         $scope.model.selectedColumn = Math.floor(expressionPos / 2); | ||
|  |                     } | ||
|  |                 } | ||
|  | 
 | ||
|  |                 _internalCreateModal({ | ||
|  |                     template: editTemplate, | ||
|  |                     scope: $scope | ||
|  |                 }, $modal, $scope); | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.openOutputExpressionEditor = function (expressionPos, newExpression) { | ||
|  |                 var editTemplate = 'views/popup/decision-table-edit-output-expression.html'; | ||
|  | 
 | ||
|  |                 $scope.model.newExpression = !!newExpression; | ||
|  |                 $scope.model.hitPolicy = $scope.currentDecisionTable.hitIndicator; | ||
|  |                 $scope.model.selectedColumn = expressionPos; | ||
|  | 
 | ||
|  | 
 | ||
|  |                 if (!$scope.model.newExpression) { | ||
|  |                     $scope.model.selectedExpression = $scope.currentDecisionTable.outputExpressions[expressionPos]; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 _internalCreateModal({ | ||
|  |                     template: editTemplate, | ||
|  |                     scope: $scope | ||
|  |                 }, $modal, $scope); | ||
|  |             }; | ||
|  | 
 | ||
|  |             var createNewOutputExpression = function (outputExpression) { | ||
|  |                 var newOutputExpression; | ||
|  |                 if (outputExpression) { | ||
|  |                     newOutputExpression = { | ||
|  |                         id: _generateColumnId(), | ||
|  |                         label: outputExpression.label, | ||
|  |                         variableId: outputExpression.variableId, | ||
|  |                         type: outputExpression.variableType, | ||
|  |                         newVariable: outputExpression.newVariable, | ||
|  |                         entries: outputExpression.entries | ||
|  |                     }; | ||
|  |                 } else { | ||
|  |                     newOutputExpression = { | ||
|  |                         id: _generateColumnId(), | ||
|  |                         label: null, | ||
|  |                         variableId: null, | ||
|  |                         type: null, | ||
|  |                         newVariable: null, | ||
|  |                         entries: null | ||
|  |                     }; | ||
|  |                 } | ||
|  |                 return newOutputExpression; | ||
|  |             }; | ||
|  | 
 | ||
|  |             var _loadDecisionTableDefinition = function (modelId, historyId) { | ||
|  |                 DecisionTableService.fetchDecisionTableDetails(modelId, historyId).then(function (decisionTable) { | ||
|  | 
 | ||
|  |                     $rootScope.currentDecisionTable = decisionTable.decisionTableDefinition; | ||
|  |                     $rootScope.currentDecisionTable.id = decisionTable.id; | ||
|  |                     $rootScope.currentDecisionTable.key = decisionTable.decisionTableDefinition.key; | ||
|  |                     $rootScope.currentDecisionTable.name = decisionTable.name; | ||
|  |                     $rootScope.currentDecisionTable.description = decisionTable.description; | ||
|  | 
 | ||
|  |                     // decision table model to used in save dialog
 | ||
|  |                     $rootScope.currentDecisionTableModel = { | ||
|  |                         id: decisionTable.id, | ||
|  |                         name: decisionTable.name, | ||
|  |                         key: decisionTable.decisionTableDefinition.key, | ||
|  |                         description: decisionTable.description | ||
|  |                     }; | ||
|  | 
 | ||
|  |                     if (!$rootScope.currentDecisionTable.hitIndicator) { | ||
|  |                         $rootScope.currentDecisionTable.hitIndicator = hitPolicies[0]; | ||
|  |                     } | ||
|  | 
 | ||
|  |                     evaluateDecisionTableGrid($rootScope.currentDecisionTable); | ||
|  | 
 | ||
|  |                 }); | ||
|  |             }; | ||
|  | 
 | ||
|  |             var evaluateDecisionTableGrid = function (decisionTable) { | ||
|  |                 $scope.evaluateDecisionHeaders(decisionTable); | ||
|  |                 evaluateDecisionGrid(decisionTable); | ||
|  |             }; | ||
|  | 
 | ||
|  |             var setGridValues = function (key, type) { | ||
|  |                 if ($scope.model.rulesData) { | ||
|  |                     $scope.model.rulesData.forEach(function (rowData) { | ||
|  |                         if (type === 'input-operator') { | ||
|  |                             if (!(key in rowData) || rowData[key] === '') { | ||
|  |                                 rowData[key] = '=='; | ||
|  |                             } | ||
|  |                         } | ||
|  |                         // else if (type === 'input-expression') {
 | ||
|  |                         //     if (!(key in rowData) || rowData[key] === '') {
 | ||
|  |                         //         rowData[key] = '-';
 | ||
|  |                         //     }
 | ||
|  |                         // }
 | ||
|  |                     }); | ||
|  |                 } | ||
|  |             }; | ||
|  | 
 | ||
|  |             var evaluateDecisionGrid = function (decisionTable) { | ||
|  |                 var tmpRuleGrid = []; | ||
|  | 
 | ||
|  |                 // rows
 | ||
|  |                 if (decisionTable.rules && decisionTable.rules.length > 0) { | ||
|  |                     decisionTable.rules.forEach(function (rule) { | ||
|  | 
 | ||
|  |                         // rule data
 | ||
|  |                         var tmpRowValues = {}; | ||
|  |                         for (var i = 0; i < Object.keys(rule).length; i++) { | ||
|  |                             var id = Object.keys(rule)[i]; | ||
|  | 
 | ||
|  |                             $scope.model.columnDefs.forEach(function (columnDef) { | ||
|  |                                 // set counter to max value
 | ||
|  |                                 var expressionId = 0; | ||
|  |                                 try { | ||
|  |                                     expressionId = parseInt(columnDef.expression.id); | ||
|  |                                 } catch (e) { | ||
|  |                                 } | ||
|  |                                 if (expressionId > columnIdCounter) { | ||
|  |                                     columnIdCounter = expressionId; | ||
|  |                                 } | ||
|  |                             }); | ||
|  | 
 | ||
|  |                             tmpRowValues[id] = rule[id]; | ||
|  |                         } | ||
|  | 
 | ||
|  |                         tmpRuleGrid.push(tmpRowValues); | ||
|  |                     }); | ||
|  |                 } else { | ||
|  |                     // initialize default values
 | ||
|  |                     tmpRuleGrid.push(createDefaultRow()); | ||
|  |                 } | ||
|  |                 // $rootScope.currentDecisionTableRules = tmpRuleGrid;
 | ||
|  |                 $scope.model.rulesData = tmpRuleGrid; | ||
|  |             }; | ||
|  | 
 | ||
|  |             var createDefaultRow = function () { | ||
|  |                 var defaultRow = {}; | ||
|  |                 $scope.model.columnDefs.forEach(function (columnDefinition) { | ||
|  |                     if (columnDefinition.expressionType === 'input-operator') { | ||
|  |                         defaultRow[columnDefinition.data] = '=='; | ||
|  |                     } | ||
|  |                     // else if (columnDefinition.expressionType === 'input-expression') {
 | ||
|  |                     //     defaultRow[columnDefinition.data] = '-';
 | ||
|  |                     // }
 | ||
|  |                     else if (columnDefinition.expressionType === 'output') { | ||
|  |                         defaultRow[columnDefinition.data] = ''; | ||
|  |                     } | ||
|  |                 }); | ||
|  | 
 | ||
|  |                 return defaultRow; | ||
|  |             }; | ||
|  | 
 | ||
|  |             var composeInputOperatorColumnDefinition = function (inputExpression) { | ||
|  |                 var expressionPosition = $scope.currentDecisionTable.inputExpressions.indexOf(inputExpression); | ||
|  | 
 | ||
|  |                 var columnDefinition = { | ||
|  |                     data: inputExpression.id + '_operator', | ||
|  |                     expressionType: 'input-operator', | ||
|  |                     expression: inputExpression, | ||
|  |                     width: '70', | ||
|  |                     className: 'input-operator-cell', | ||
|  |                     type: 'dropdown', | ||
|  |                     source: operators | ||
|  |                 }; | ||
|  | 
 | ||
|  |                 return columnDefinition; | ||
|  |             }; | ||
|  | 
 | ||
|  |             var composeInputExpressionColumnDefinition = function (inputExpression) { | ||
|  |                 var expressionPosition = $scope.currentDecisionTable.inputExpressions.indexOf(inputExpression); | ||
|  | 
 | ||
|  |                 var type; | ||
|  |                 switch (inputExpression.type) { | ||
|  |                     case 'date': | ||
|  |                         type = 'date'; | ||
|  |                         break; | ||
|  |                     case 'number': | ||
|  |                         type = 'numeric'; | ||
|  |                         break; | ||
|  |                     case 'boolean': | ||
|  |                         type = 'dropdown'; | ||
|  |                         break; | ||
|  |                     default: | ||
|  |                         type = 'text'; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 var columnDefinition = { | ||
|  |                     data: inputExpression.id + '_expression', | ||
|  |                     type: type, | ||
|  |                     title: '<div class="input-header">' + | ||
|  |                     '<a onclick="triggerExpressionEditor(\'input\',' + expressionPosition + ',false)"><span class="header-label">' + (inputExpression.label ? inputExpression.label : "New Input") + '</span></a>' + | ||
|  |                     '<br><span class="header-variable">' + (inputExpression.variableId ? inputExpression.variableId : "none") + '</span>' + | ||
|  |                     '<br/><span class="header-variable-type">' + (inputExpression.type ? inputExpression.type : "") + '</brspan>' + | ||
|  |                     '</div>', | ||
|  |                     expressionType: 'input-expression', | ||
|  |                     expression: inputExpression, | ||
|  |                     className: 'htCenter', | ||
|  |                     width: '200' | ||
|  |                 }; | ||
|  | 
 | ||
|  |                 if (inputExpression.entries && inputExpression.entries.length > 0) { | ||
|  |                     var entriesOptionValues = inputExpression.entries.slice(0, inputExpression.entries.length); | ||
|  |                     entriesOptionValues.push('-', '', ' '); | ||
|  | 
 | ||
|  |                     columnDefinition.type = 'dropdown'; | ||
|  |                     columnDefinition.strict = true; | ||
|  |                     columnDefinition.source = entriesOptionValues; | ||
|  | 
 | ||
|  |                     columnDefinition.title = '<div class="input-header">' + | ||
|  |                         '<a onclick="triggerExpressionEditor(\'input\',' + expressionPosition + ',false)"><span class="header-label">' + (inputExpression.label ? inputExpression.label : "New Input") + '</span></a>' + | ||
|  |                         '<br><span class="header-variable">' + (inputExpression.variableId ? inputExpression.variableId : "none") + '</span>' + | ||
|  |                         '<br/><span class="header-variable-type">' + (inputExpression.type ? inputExpression.type : "") + '</span>' + | ||
|  |                         '<br><span class="header-entries">[' + inputExpression.entries.join() + ']</span>' + | ||
|  |                         '</div>'; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 if (type === 'date') { | ||
|  |                     columnDefinition.dateFormat = dateFormat; | ||
|  |                 } else if (type === 'dropdown') { | ||
|  |                     columnDefinition.source = ['true', 'false', '-']; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 return columnDefinition; | ||
|  |             }; | ||
|  | 
 | ||
|  |             var composeOutputColumnDefinition = function (outputExpression) { | ||
|  |                 var expressionPosition = $scope.currentDecisionTable.outputExpressions.indexOf(outputExpression); | ||
|  | 
 | ||
|  |                 var type; | ||
|  |                 switch (outputExpression.type) { | ||
|  |                     case 'date': | ||
|  |                         type = 'date'; | ||
|  |                         break; | ||
|  |                     case 'number': | ||
|  |                         type = 'numeric'; | ||
|  |                         break; | ||
|  |                     case 'boolean': | ||
|  |                         type = 'dropdown'; | ||
|  |                         break; | ||
|  |                     default: | ||
|  |                         type = 'text'; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 var title = ''; | ||
|  |                 var columnDefinition = { | ||
|  |                     data: outputExpression.id, | ||
|  |                     type: type, | ||
|  |                     expressionType: 'output', | ||
|  |                     expression: outputExpression, | ||
|  |                     className: 'htCenter', | ||
|  |                     width: '270' | ||
|  |                 }; | ||
|  | 
 | ||
|  |                 if (outputExpression.entries && outputExpression.entries.length > 0) { | ||
|  |                     var entriesOptionValues = outputExpression.entries.slice(0, outputExpression.entries.length); | ||
|  |                     columnDefinition.type = 'dropdown'; | ||
|  |                     columnDefinition.source = entriesOptionValues; | ||
|  |                     columnDefinition.strict = true; | ||
|  | 
 | ||
|  |                     title += '<div class="output-header">' + | ||
|  |                         '<a onclick="triggerExpressionEditor(\'output\',' + expressionPosition + ',false)"><span class="header-label">' + (outputExpression.label ? outputExpression.label : "New Output") + '</span></a>' + | ||
|  |                         '<br><span class="header-variable">' + (outputExpression.variableId ? outputExpression.variableId : "none") + '</span>' + | ||
|  |                         '<br/><span class="header-variable-type">' + (outputExpression.type ? outputExpression.type : "") + '</span>' + | ||
|  |                         '<br><span class="header-entries">[' + outputExpression.entries.join() + ']</span>' + | ||
|  |                         '</div>'; | ||
|  |                 } else { | ||
|  |                     title += '<div class="output-header">' + | ||
|  |                         '<a onclick="triggerExpressionEditor(\'output\',' + expressionPosition + ',false)"><span class="header-label">' + (outputExpression.label ? outputExpression.label : "New Output") + '</span></a>' + | ||
|  |                         '<br><span class="header-variable">' + (outputExpression.variableId ? outputExpression.variableId : "none") + '</span>' + | ||
|  |                         '<br/><span class="header-variable-type">' + (outputExpression.type ? outputExpression.type : "") + '</span>' + | ||
|  |                         '</div>' | ||
|  |                 } | ||
|  | 
 | ||
|  |                 if (type === 'date') { | ||
|  |                     columnDefinition.dateFormat = dateFormat; | ||
|  |                 } else if (type === 'dropdown') { | ||
|  |                     columnDefinition.source = ['true', 'false', '-']; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 columnDefinition.title = title; | ||
|  | 
 | ||
|  |                 return columnDefinition; | ||
|  |             }; | ||
|  | 
 | ||
|  |             $scope.evaluateDecisionHeaders = function (decisionTable) { | ||
|  |                 var columnDefinitions = []; | ||
|  |                 var inputExpressionCounter = 0; | ||
|  |                 if (decisionTable.inputExpressions && decisionTable.inputExpressions.length > 0) { | ||
|  |                     decisionTable.inputExpressions.forEach(function (inputExpression) { | ||
|  |                         var inputOperatorColumnDefinition = composeInputOperatorColumnDefinition(inputExpression); | ||
|  |                         columnDefinitions.push(inputOperatorColumnDefinition); | ||
|  |                         setGridValues(inputOperatorColumnDefinition.data, inputOperatorColumnDefinition.expressionType); | ||
|  | 
 | ||
|  |                         var inputExpressionColumnDefinition = composeInputExpressionColumnDefinition(inputExpression); | ||
|  |                         columnDefinitions.push(inputExpressionColumnDefinition); | ||
|  |                         setGridValues(inputExpressionColumnDefinition.data, inputExpressionColumnDefinition.expressionType); | ||
|  | 
 | ||
|  |                         inputExpressionCounter += 2; | ||
|  |                     }); | ||
|  |                 } else { // create default input expression
 | ||
|  |                     decisionTable.inputExpressions = []; | ||
|  |                     var inputExpression = createNewInputExpression(); | ||
|  |                     decisionTable.inputExpressions.push(inputExpression); | ||
|  |                     columnDefinitions.push(composeInputOperatorColumnDefinition(inputExpression)); | ||
|  |                     columnDefinitions.push(composeInputExpressionColumnDefinition(inputExpression)); | ||
|  |                     inputExpressionCounter += 2; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 columnDefinitions[inputExpressionCounter - 1].className += ' last'; | ||
|  |                 $scope.model.startOutputExpression = inputExpressionCounter; | ||
|  | 
 | ||
|  |                 if (decisionTable.outputExpressions && decisionTable.outputExpressions.length > 0) { | ||
|  |                     decisionTable.outputExpressions.forEach(function (outputExpression) { | ||
|  |                         columnDefinitions.push(composeOutputColumnDefinition(outputExpression)); | ||
|  |                     }); | ||
|  |                 } else { // create default output expression
 | ||
|  |                     decisionTable.outputExpressions = []; | ||
|  |                     var outputExpression = createNewOutputExpression(); | ||
|  |                     decisionTable.outputExpressions.push(outputExpression); | ||
|  |                     columnDefinitions.push(composeOutputColumnDefinition(outputExpression)); | ||
|  |                 } | ||
|  | 
 | ||
|  |                 columnDefinitions[inputExpressionCounter].className += ' first'; | ||
|  | 
 | ||
|  |                 // timeout needed for trigger hot update when removing column defs
 | ||
|  |                 $scope.model.columnDefs = columnDefinitions; | ||
|  |                 $timeout(function () { | ||
|  |                     if (hotReadOnlyDecisionTableEditorInstance) { | ||
|  |                         hotReadOnlyDecisionTableEditorInstance.render(); | ||
|  |                     } | ||
|  |                 }); | ||
|  |             }; | ||
|  | 
 | ||
|  |             // fetch table from service and populate model
 | ||
|  |             _loadDecisionTableDefinition($routeParams.modelId, $routeParams.modelHistoryId); | ||
|  | 
 | ||
|  |             var _generateColumnId = function () { | ||
|  |                 columnIdCounter++; | ||
|  |                 return "" + columnIdCounter; | ||
|  |             }; | ||
|  | 
 | ||
|  |             // Load model needed for favorites
 | ||
|  |             $scope.loadDecisionTable(); | ||
|  | 
 | ||
|  |         }]); |