diff --git a/src/main/webapp/wise5/authoringTool/authoringToolController.es6 b/src/main/webapp/wise5/authoringTool/authoringToolController.es6 index 4f027362c9..f2a03c1645 100644 --- a/src/main/webapp/wise5/authoringTool/authoringToolController.es6 +++ b/src/main/webapp/wise5/authoringTool/authoringToolController.es6 @@ -266,6 +266,11 @@ class AuthoringToolController { } else { this.projectTitle = null; } + this.turnOffJSONValidMessage(); + } + + turnOffJSONValidMessage() { + this.$rootScope.$broadcast('setIsJSONValid', { isJSONValid: null }); } /** diff --git a/src/main/webapp/wise5/authoringTool/authoringToolController.js b/src/main/webapp/wise5/authoringTool/authoringToolController.js index 17da20da6b..43229ce03d 100644 --- a/src/main/webapp/wise5/authoringTool/authoringToolController.js +++ b/src/main/webapp/wise5/authoringTool/authoringToolController.js @@ -252,6 +252,12 @@ var AuthoringToolController = function () { } else { this.projectTitle = null; } + this.turnOffJSONValidMessage(); + } + }, { + key: 'turnOffJSONValidMessage', + value: function turnOffJSONValidMessage() { + this.$rootScope.$broadcast('setIsJSONValid', { isJSONValid: null }); } /** diff --git a/src/main/webapp/wise5/authoringTool/authoringToolController.js.map b/src/main/webapp/wise5/authoringTool/authoringToolController.js.map index ee9ef40ad6..9f039190b1 100644 --- a/src/main/webapp/wise5/authoringTool/authoringToolController.js.map +++ b/src/main/webapp/wise5/authoringTool/authoringToolController.js.map @@ -1 +1 @@ -{"version":3,"sources":["authoringToolController.es6"],"names":["AuthoringToolController","$anchorScroll","$filter","$location","$mdDialog","$rootScope","$scope","$state","$timeout","ConfigService","ProjectService","SessionService","TeacherDataService","$translate","numberProject","isMenuOpen","views","id","name","label","icon","type","showToolbar","active","logoPath","getThemePath","processUI","$on","event","toState","toParams","fromState","fromParams","confirm","parent","angular","element","document","body","title","content","ariaLabel","ok","cancel","show","then","renewSession","forceLogOut","ev","alert","textContent","targetEvent","setGlobalMessage","Date","getTime","params","stateParams","isPopup","projectId","nodeId","componentId","target","targetObject","templateUrl","controller","controllerAs","$stateParams","clickOutsideToClose","escapeToClose","saveEvent","current","showStepTools","$current","view","currentViewName","getProjectId","runId","getRunId","projectTitle","getProjectTitle","url","mouseMoved","notifyAuthorProjectEnd","wiseBaseURL","getWISEBaseURL","window","location","message","time","globalMessage","text","$broadcast","eventName","category","context","componentType","data","$inject"],"mappings":"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","file":"authoringToolController.js","sourcesContent":["'use strict';\n\nclass AuthoringToolController {\n\n constructor(\n $anchorScroll,\n $filter,\n $location,\n $mdDialog,\n $rootScope,\n $scope,\n $state,\n $timeout,\n ConfigService,\n ProjectService,\n SessionService,\n TeacherDataService) {\n this.$anchorScroll = $anchorScroll;\n this.$filter = $filter;\n this.$location = $location;\n this.$mdDialog = $mdDialog;\n this.$rootScope = $rootScope;\n this.$scope = $scope;\n this.$state = $state;\n this.$timeout = $timeout;\n this.$translate = this.$filter('translate');\n this.ConfigService = ConfigService;\n this.ProjectService = ProjectService;\n this.SessionService = SessionService;\n this.TeacherDataService = TeacherDataService;\n\n this.numberProject = true; // TODO: make dynamic or remove\n this.isMenuOpen = false;\n\n // ui-views and their corresponding names, labels, and icons\n this.views = {\n 'root.project': {\n id: 'projectHomeButton',\n name: this.$translate('projectHome'),\n label: this.$translate('projectHome'),\n icon: 'home',\n type: 'primary',\n showToolbar: true,\n active: true\n },\n 'root.project.notebook': {\n id: 'notebookButton',\n name: this.$translate('notebookSettings'),\n label: this.$translate('notebookSettings'),\n icon: 'book',\n type: 'primary',\n showToolbar: true,\n active: true\n },\n 'root.project.asset': {\n id: 'assetButton',\n name: this.$translate('fileManager'),\n label: this.$translate('fileManager'),\n icon: 'attach_file',\n type: 'primary',\n showToolbar: true,\n active: true\n },\n 'root.project.info': {\n id: 'infoButton',\n name: this.$translate('PROJECT_INFO'),\n label: this.$translate('PROJECT_INFO'),\n icon: 'info',\n type: 'primary',\n showToolbar: true,\n active: true\n },\n 'root.main': {\n id: 'projectListButton',\n name: this.$translate('projectsList'),\n label: this.$translate('projectsList'),\n icon: 'reorder',\n type: 'primary',\n showToolbar: false,\n active: true\n },\n 'root.project.node': {\n name: '',\n label: '',\n icon: '',\n type: 'secondary',\n showToolbar: true,\n active: false\n },\n 'root.project.nodeConstraints': {\n name: '',\n label: '',\n icon: '',\n type: 'secondary',\n showToolbar: true,\n active: false\n },\n 'root.project.nodeEditPaths': {\n name: '',\n label: '',\n icon: '',\n type: 'secondary',\n showToolbar: true,\n active: false\n },\n };\n\n this.logoPath = this.ProjectService.getThemePath() + '/images/WISE-logo-ffffff.svg';\n this.processUI();\n\n // listen for state change events and close the menu\n this.$scope.$on('$stateChangeSuccess',\n (event, toState, toParams, fromState, fromParams) => {\n this.isMenuOpen = false;\n this.processUI();\n });\n\n $scope.$on('showSessionWarning', () => {\n let confirm = this.$mdDialog.confirm()\n .parent(angular.element(document.body))\n .title(this.$translate('sessionTimeout'))\n .content(this.$translate('autoLogoutMessage'))\n .ariaLabel(this.$translate('sessionTimeout'))\n .ok(this.$translate('yes'))\n .cancel(this.$translate('no'));\n this.$mdDialog.show(confirm).then(() => {\n this.SessionService.renewSession();\n }, () => {\n this.SessionService.forceLogOut();\n });\n });\n\n // alert user when they're inactive for a long time\n this.$scope.$on('showRequestLogout', (ev) => {\n let alert = this.$mdDialog.confirm()\n .parent(angular.element(document.body))\n .title(this.$translate('serverUpdate'))\n .textContent(this.$translate('serverUpdateRequestLogoutMessage'))\n .ariaLabel(this.$translate('serverUpdate'))\n .targetEvent(ev)\n .ok(this.$translate('ok'));\n\n this.$mdDialog.show(alert).then(() => {\n // do nothing\n }, () => {\n // do nothing\n });\n });\n\n /*\n * Listen for the savingProject event which means the authoring tool\n * is in the process of saving the project and display this information\n * globally.\n */\n this.$scope.$on('savingProject', () => {\n this.setGlobalMessage(this.$translate('saving'), null);\n });\n\n /*\n * Listen for the projectSaved event which means the project has just\n * been saved to the server\n */\n this.$scope.$on('projectSaved', () => {\n\n /*\n * Wait half a second before changing the message to 'Saved' so that\n * the 'Saving...' message stays up long enough for the author to\n * see that the project is saving. If we don't perform this wait,\n * it will always say 'Saved' and authors may wonder whether the\n * project ever gets saved.\n */\n this.$timeout(() => {\n this.setGlobalMessage(this.$translate('SAVED'), new Date().getTime());\n }, 500);\n });\n\n /*\n * Open the asset chooser to let the author insert an asset into the\n * specified target\n */\n this.$scope.$on('openAssetChooser', (event, params) => {\n // create the params for opening the asset chooser\n const stateParams = {\n isPopup: params.isPopup,\n projectId: params.projectId,\n nodeId: params.nodeId,\n componentId: params.componentId,\n target: params.target,\n targetObject: params.targetObject\n };\n\n // open the dialog that will display the assets for the user to choose\n this.$mdDialog.show({\n templateUrl: 'wise5/authoringTool/asset/asset.html',\n controller: 'ProjectAssetController',\n controllerAs: 'projectAssetController',\n $stateParams: stateParams,\n clickOutsideToClose: true,\n escapeToClose: true\n });\n });\n\n /*\n * Open the asset chooser to let the author insert an WISE Link into the\n * specified target\n */\n this.$scope.$on('openWISELinkChooser', (event, params) => {\n // create the params for opening the WISE Link authoring popup\n const stateParams = {\n projectId: params.projectId,\n nodeId: params.nodeId,\n componentId: params.componentId,\n target: params.target\n };\n\n // open the WISE Link authoring popup\n this.$mdDialog.show({\n templateUrl: 'wise5/authoringTool/wiseLink/wiseLinkAuthoring.html',\n controller: 'WISELinkAuthoringController',\n controllerAs: 'wiseLinkAuthoringController',\n $stateParams: stateParams,\n clickOutsideToClose: true,\n escapeToClose: true\n });\n });\n\n this.$rootScope.$on('$stateChangeSuccess',\n (event, toState, toParams, fromState, fromParams) => {\n if (toState != null && toState.name == 'root.main') {\n this.saveEvent('projectListViewed', 'Navigation');\n }\n });\n\n if (this.$state.current.name == 'root.main') {\n this.saveEvent('projectListViewed', 'Navigation');\n }\n }\n\n /**\n * Update UI items based on state, show or hide relevant menus and toolbars\n * TODO: remove/rework this and put items in their own ui states?\n */\n processUI() {\n // scroll to the top of the page\n this.$anchorScroll('top');\n\n // set current view and whether to show the toolbars and step tools\n this.showStepTools = this.$state.$current.name === 'root.project' ||\n this.$state.$current.name === 'root.project.node' ||\n this.$state.$current.name === 'root.project.nodeConstraints' ||\n this.$state.$current.name === 'root.project.nodeEditPaths';\n const view = this.views[this.$state.$current.name];\n if (view) {\n this.currentViewName = view.name;\n this.showToolbar = view.showToolbar;\n } else {\n this.currentViewName = '';\n this.showToolbar = false;\n }\n\n this.projectId = this.ConfigService.getProjectId();\n this.runId = this.ConfigService.getRunId();\n\n if (this.projectId) {\n this.projectTitle = this.ProjectService.getProjectTitle();\n } else {\n this.projectTitle = null;\n }\n }\n\n /**\n * Navigate the user to the My Projects page in the Authoring Tool\n */\n goToMyProjects() {\n this.$location.url('/author');\n }\n\n /**\n * Toggle the authoring tool main menu\n */\n toggleMenu() {\n this.isMenuOpen = !this.isMenuOpen;\n }\n\n /**\n * Notify Session to renew when user moves the mouse\n */\n mouseMoved() {\n this.SessionService.mouseMoved();\n }\n\n exit() {\n this.ProjectService.notifyAuthorProjectEnd().then(() => {\n let wiseBaseURL = this.ConfigService.getWISEBaseURL();\n window.location = wiseBaseURL + '/teacher';\n });\n }\n\n /**\n * Set the global message at the top right\n * @param message the message to display\n * @param time the time to display\n */\n setGlobalMessage(message, time) {\n const globalMessage = {\n text: message,\n time: time\n };\n this.$rootScope.$broadcast('setGlobalMessage', { globalMessage: globalMessage });\n };\n\n /**\n * Save an Authoring Tool event\n * @param eventName the name of the event\n * @param category the category of the event\n * example 'Navigation' or 'Authoring'\n */\n saveEvent(eventName, category) {\n let context = 'AuthoringTool';\n let nodeId = null;\n let componentId = null;\n let componentType = null;\n let data = {};\n\n this.TeacherDataService.saveEvent(context, nodeId, componentId,\n componentType, category, eventName, data);\n }\n}\n\nAuthoringToolController.$inject = [\n '$anchorScroll',\n '$filter',\n '$location',\n '$mdDialog',\n '$rootScope',\n '$scope',\n '$state',\n '$timeout',\n 'ConfigService',\n 'ProjectService',\n 'SessionService',\n 'TeacherDataService',\n 'moment'\n];\n\nexport default AuthoringToolController;\n"]} \ No newline at end of file +{"version":3,"sources":["authoringToolController.es6"],"names":["AuthoringToolController","$anchorScroll","$filter","$location","$mdDialog","$rootScope","$scope","$state","$timeout","ConfigService","ProjectService","SessionService","TeacherDataService","$translate","numberProject","isMenuOpen","views","id","name","label","icon","type","showToolbar","active","logoPath","getThemePath","processUI","$on","event","toState","toParams","fromState","fromParams","confirm","parent","angular","element","document","body","title","content","ariaLabel","ok","cancel","show","then","renewSession","forceLogOut","ev","alert","textContent","targetEvent","setGlobalMessage","Date","getTime","params","stateParams","isPopup","projectId","nodeId","componentId","target","targetObject","templateUrl","controller","controllerAs","$stateParams","clickOutsideToClose","escapeToClose","saveEvent","current","showStepTools","$current","view","currentViewName","getProjectId","runId","getRunId","projectTitle","getProjectTitle","turnOffJSONValidMessage","$broadcast","isJSONValid","url","mouseMoved","notifyAuthorProjectEnd","wiseBaseURL","getWISEBaseURL","window","location","message","time","globalMessage","text","eventName","category","context","componentType","data","$inject"],"mappings":"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","file":"authoringToolController.js","sourcesContent":["'use strict';\n\nclass AuthoringToolController {\n\n constructor(\n $anchorScroll,\n $filter,\n $location,\n $mdDialog,\n $rootScope,\n $scope,\n $state,\n $timeout,\n ConfigService,\n ProjectService,\n SessionService,\n TeacherDataService) {\n this.$anchorScroll = $anchorScroll;\n this.$filter = $filter;\n this.$location = $location;\n this.$mdDialog = $mdDialog;\n this.$rootScope = $rootScope;\n this.$scope = $scope;\n this.$state = $state;\n this.$timeout = $timeout;\n this.$translate = this.$filter('translate');\n this.ConfigService = ConfigService;\n this.ProjectService = ProjectService;\n this.SessionService = SessionService;\n this.TeacherDataService = TeacherDataService;\n\n this.numberProject = true; // TODO: make dynamic or remove\n this.isMenuOpen = false;\n\n // ui-views and their corresponding names, labels, and icons\n this.views = {\n 'root.project': {\n id: 'projectHomeButton',\n name: this.$translate('projectHome'),\n label: this.$translate('projectHome'),\n icon: 'home',\n type: 'primary',\n showToolbar: true,\n active: true\n },\n 'root.project.notebook': {\n id: 'notebookButton',\n name: this.$translate('notebookSettings'),\n label: this.$translate('notebookSettings'),\n icon: 'book',\n type: 'primary',\n showToolbar: true,\n active: true\n },\n 'root.project.asset': {\n id: 'assetButton',\n name: this.$translate('fileManager'),\n label: this.$translate('fileManager'),\n icon: 'attach_file',\n type: 'primary',\n showToolbar: true,\n active: true\n },\n 'root.project.info': {\n id: 'infoButton',\n name: this.$translate('PROJECT_INFO'),\n label: this.$translate('PROJECT_INFO'),\n icon: 'info',\n type: 'primary',\n showToolbar: true,\n active: true\n },\n 'root.main': {\n id: 'projectListButton',\n name: this.$translate('projectsList'),\n label: this.$translate('projectsList'),\n icon: 'reorder',\n type: 'primary',\n showToolbar: false,\n active: true\n },\n 'root.project.node': {\n name: '',\n label: '',\n icon: '',\n type: 'secondary',\n showToolbar: true,\n active: false\n },\n 'root.project.nodeConstraints': {\n name: '',\n label: '',\n icon: '',\n type: 'secondary',\n showToolbar: true,\n active: false\n },\n 'root.project.nodeEditPaths': {\n name: '',\n label: '',\n icon: '',\n type: 'secondary',\n showToolbar: true,\n active: false\n },\n };\n\n this.logoPath = this.ProjectService.getThemePath() + '/images/WISE-logo-ffffff.svg';\n this.processUI();\n\n // listen for state change events and close the menu\n this.$scope.$on('$stateChangeSuccess',\n (event, toState, toParams, fromState, fromParams) => {\n this.isMenuOpen = false;\n this.processUI();\n });\n\n $scope.$on('showSessionWarning', () => {\n let confirm = this.$mdDialog.confirm()\n .parent(angular.element(document.body))\n .title(this.$translate('sessionTimeout'))\n .content(this.$translate('autoLogoutMessage'))\n .ariaLabel(this.$translate('sessionTimeout'))\n .ok(this.$translate('yes'))\n .cancel(this.$translate('no'));\n this.$mdDialog.show(confirm).then(() => {\n this.SessionService.renewSession();\n }, () => {\n this.SessionService.forceLogOut();\n });\n });\n\n // alert user when they're inactive for a long time\n this.$scope.$on('showRequestLogout', (ev) => {\n let alert = this.$mdDialog.confirm()\n .parent(angular.element(document.body))\n .title(this.$translate('serverUpdate'))\n .textContent(this.$translate('serverUpdateRequestLogoutMessage'))\n .ariaLabel(this.$translate('serverUpdate'))\n .targetEvent(ev)\n .ok(this.$translate('ok'));\n\n this.$mdDialog.show(alert).then(() => {\n // do nothing\n }, () => {\n // do nothing\n });\n });\n\n /*\n * Listen for the savingProject event which means the authoring tool\n * is in the process of saving the project and display this information\n * globally.\n */\n this.$scope.$on('savingProject', () => {\n this.setGlobalMessage(this.$translate('saving'), null);\n });\n\n /*\n * Listen for the projectSaved event which means the project has just\n * been saved to the server\n */\n this.$scope.$on('projectSaved', () => {\n\n /*\n * Wait half a second before changing the message to 'Saved' so that\n * the 'Saving...' message stays up long enough for the author to\n * see that the project is saving. If we don't perform this wait,\n * it will always say 'Saved' and authors may wonder whether the\n * project ever gets saved.\n */\n this.$timeout(() => {\n this.setGlobalMessage(this.$translate('SAVED'), new Date().getTime());\n }, 500);\n });\n\n /*\n * Open the asset chooser to let the author insert an asset into the\n * specified target\n */\n this.$scope.$on('openAssetChooser', (event, params) => {\n // create the params for opening the asset chooser\n const stateParams = {\n isPopup: params.isPopup,\n projectId: params.projectId,\n nodeId: params.nodeId,\n componentId: params.componentId,\n target: params.target,\n targetObject: params.targetObject\n };\n\n // open the dialog that will display the assets for the user to choose\n this.$mdDialog.show({\n templateUrl: 'wise5/authoringTool/asset/asset.html',\n controller: 'ProjectAssetController',\n controllerAs: 'projectAssetController',\n $stateParams: stateParams,\n clickOutsideToClose: true,\n escapeToClose: true\n });\n });\n\n /*\n * Open the asset chooser to let the author insert an WISE Link into the\n * specified target\n */\n this.$scope.$on('openWISELinkChooser', (event, params) => {\n // create the params for opening the WISE Link authoring popup\n const stateParams = {\n projectId: params.projectId,\n nodeId: params.nodeId,\n componentId: params.componentId,\n target: params.target\n };\n\n // open the WISE Link authoring popup\n this.$mdDialog.show({\n templateUrl: 'wise5/authoringTool/wiseLink/wiseLinkAuthoring.html',\n controller: 'WISELinkAuthoringController',\n controllerAs: 'wiseLinkAuthoringController',\n $stateParams: stateParams,\n clickOutsideToClose: true,\n escapeToClose: true\n });\n });\n\n this.$rootScope.$on('$stateChangeSuccess',\n (event, toState, toParams, fromState, fromParams) => {\n if (toState != null && toState.name == 'root.main') {\n this.saveEvent('projectListViewed', 'Navigation');\n }\n });\n\n if (this.$state.current.name == 'root.main') {\n this.saveEvent('projectListViewed', 'Navigation');\n }\n }\n\n /**\n * Update UI items based on state, show or hide relevant menus and toolbars\n * TODO: remove/rework this and put items in their own ui states?\n */\n processUI() {\n // scroll to the top of the page\n this.$anchorScroll('top');\n\n // set current view and whether to show the toolbars and step tools\n this.showStepTools = this.$state.$current.name === 'root.project' ||\n this.$state.$current.name === 'root.project.node' ||\n this.$state.$current.name === 'root.project.nodeConstraints' ||\n this.$state.$current.name === 'root.project.nodeEditPaths';\n const view = this.views[this.$state.$current.name];\n if (view) {\n this.currentViewName = view.name;\n this.showToolbar = view.showToolbar;\n } else {\n this.currentViewName = '';\n this.showToolbar = false;\n }\n\n this.projectId = this.ConfigService.getProjectId();\n this.runId = this.ConfigService.getRunId();\n\n if (this.projectId) {\n this.projectTitle = this.ProjectService.getProjectTitle();\n } else {\n this.projectTitle = null;\n }\n this.turnOffJSONValidMessage();\n }\n\n turnOffJSONValidMessage() {\n this.$rootScope.$broadcast('setIsJSONValid', { isJSONValid: null });\n }\n\n /**\n * Navigate the user to the My Projects page in the Authoring Tool\n */\n goToMyProjects() {\n this.$location.url('/author');\n }\n\n /**\n * Toggle the authoring tool main menu\n */\n toggleMenu() {\n this.isMenuOpen = !this.isMenuOpen;\n }\n\n /**\n * Notify Session to renew when user moves the mouse\n */\n mouseMoved() {\n this.SessionService.mouseMoved();\n }\n\n exit() {\n this.ProjectService.notifyAuthorProjectEnd().then(() => {\n let wiseBaseURL = this.ConfigService.getWISEBaseURL();\n window.location = wiseBaseURL + '/teacher';\n });\n }\n\n /**\n * Set the global message at the top right\n * @param message the message to display\n * @param time the time to display\n */\n setGlobalMessage(message, time) {\n const globalMessage = {\n text: message,\n time: time\n };\n this.$rootScope.$broadcast('setGlobalMessage', { globalMessage: globalMessage });\n };\n\n /**\n * Save an Authoring Tool event\n * @param eventName the name of the event\n * @param category the category of the event\n * example 'Navigation' or 'Authoring'\n */\n saveEvent(eventName, category) {\n let context = 'AuthoringTool';\n let nodeId = null;\n let componentId = null;\n let componentType = null;\n let data = {};\n\n this.TeacherDataService.saveEvent(context, nodeId, componentId,\n componentType, category, eventName, data);\n }\n}\n\nAuthoringToolController.$inject = [\n '$anchorScroll',\n '$filter',\n '$location',\n '$mdDialog',\n '$rootScope',\n '$scope',\n '$state',\n '$timeout',\n 'ConfigService',\n 'ProjectService',\n 'SessionService',\n 'TeacherDataService',\n 'moment'\n];\n\nexport default AuthoringToolController;\n"]} \ No newline at end of file diff --git a/src/main/webapp/wise5/authoringTool/components/shared/toolbar/toolbar.es6 b/src/main/webapp/wise5/authoringTool/components/shared/toolbar/toolbar.es6 index 245f5b0d6c..4e0abebd32 100644 --- a/src/main/webapp/wise5/authoringTool/components/shared/toolbar/toolbar.es6 +++ b/src/main/webapp/wise5/authoringTool/components/shared/toolbar/toolbar.es6 @@ -11,6 +11,9 @@ class ToolbarController { } this.globalMessage = params.globalMessage; }); + this.$rootScope.$on('setIsJSONValid', (event, params) => { + this.isJSONValid = params.isJSONValid; + }); } toggleMenu() { @@ -39,6 +42,8 @@ const Toolbar = { {{ $ctrl.viewName }}
+ done{{ 'jsonValid' | translate }} + clear{{ 'jsonInvalid' | translate }}
\n
\n \n menu \n \n {{ $ctrl.viewName }}\n \n
\n
\n \n \n
\n \n {{$ctrl.globalMessage.text}}\n \n \n {{ $ctrl.globalMessage.time | amDateFormat:\'ddd, MMM D YYYY, h:mm a\' }}\n \n \n \n \n
\n ' + template: '\n
\n \n menu \n \n {{ $ctrl.viewName }}\n \n
\n done{{ \'jsonValid\' | translate }}\n clear{{ \'jsonInvalid\' | translate }}\n
\n \n \n
\n \n {{$ctrl.globalMessage.text}}\n \n \n {{ $ctrl.globalMessage.time | amDateFormat:\'ddd, MMM D YYYY, h:mm a\' }}\n \n \n \n \n
\n
' }; exports.default = Toolbar; diff --git a/src/main/webapp/wise5/authoringTool/components/shared/toolbar/toolbar.js.map b/src/main/webapp/wise5/authoringTool/components/shared/toolbar/toolbar.js.map index 6d243a773e..918b681e00 100644 --- a/src/main/webapp/wise5/authoringTool/components/shared/toolbar/toolbar.js.map +++ b/src/main/webapp/wise5/authoringTool/components/shared/toolbar/toolbar.js.map @@ -1 +1 @@ -{"version":3,"sources":["toolbar.es6"],"names":["ToolbarController","$rootScope","$on","event","params","globalMessage","time","isProgressIndicatorVisible","onMenuToggle","$inject","Toolbar","bindings","numberProject","showStepTools","viewName","controller","template"],"mappings":"AAAA;;;;;;;;;;IAEMA,iB;AACJ,6BAAYC,UAAZ,EAAwB;AAAA;;AAAA;;AACtB,SAAKA,UAAL,GAAkBA,UAAlB;AACA,SAAKA,UAAL,CAAgBC,GAAhB,CAAoB,kBAApB,EAAwC,UAACC,KAAD,EAAQC,MAAR,EAAmB;AACzD,UAAIA,OAAOC,aAAP,CAAqBC,IAArB,KAA8B,IAAlC,EAAwC;AACtC,cAAKC,0BAAL,GAAkC,IAAlC;AACD,OAFD,MAEO;AACL,cAAKA,0BAAL,GAAkC,KAAlC;AACD;AACD,YAAKF,aAAL,GAAqBD,OAAOC,aAA5B;AACD,KAPD;AAQD;;;;iCAEY;AACX,WAAKG,YAAL;AACD;;;;;;AAGHR,kBAAkBS,OAAlB,GAA4B,CAC1B,YAD0B,CAA5B;;AAIA,IAAMC,UAAU;AACdC,YAAU;AACRC,mBAAe,GADP;AAERC,mBAAe,GAFP;AAGRC,cAAU,GAHF;AAIRN,kBAAc;AAJN,GADI;AAOdO,cAAYf,iBAPE;AAQdgB;AARc,CAAhB;;kBAwCeN,O","file":"toolbar.js","sourcesContent":["\"use strict\";\n\nclass ToolbarController {\n constructor($rootScope) {\n this.$rootScope = $rootScope;\n this.$rootScope.$on('setGlobalMessage', (event, params) => {\n if (params.globalMessage.time === null) {\n this.isProgressIndicatorVisible = true;\n } else {\n this.isProgressIndicatorVisible = false;\n }\n this.globalMessage = params.globalMessage;\n });\n }\n\n toggleMenu() {\n this.onMenuToggle();\n }\n}\n\nToolbarController.$inject = [\n '$rootScope'\n];\n\nconst Toolbar = {\n bindings: {\n numberProject: '<',\n showStepTools: '<',\n viewName: '<',\n onMenuToggle: '&'\n },\n controller: ToolbarController,\n template:\n `\n
\n \n menu \n \n {{ $ctrl.viewName }}\n \n
\n
\n \n \n
\n \n {{$ctrl.globalMessage.text}}\n \n \n {{ $ctrl.globalMessage.time | amDateFormat:'ddd, MMM D YYYY, h:mm a' }}\n \n \n \n \n
\n
`\n};\n\nexport default Toolbar;\n"]} \ No newline at end of file +{"version":3,"sources":["toolbar.es6"],"names":["ToolbarController","$rootScope","$on","event","params","globalMessage","time","isProgressIndicatorVisible","isJSONValid","onMenuToggle","$inject","Toolbar","bindings","numberProject","showStepTools","viewName","controller","template"],"mappings":"AAAA;;;;;;;;;;IAEMA,iB;AACJ,6BAAYC,UAAZ,EAAwB;AAAA;;AAAA;;AACtB,SAAKA,UAAL,GAAkBA,UAAlB;AACA,SAAKA,UAAL,CAAgBC,GAAhB,CAAoB,kBAApB,EAAwC,UAACC,KAAD,EAAQC,MAAR,EAAmB;AACzD,UAAIA,OAAOC,aAAP,CAAqBC,IAArB,KAA8B,IAAlC,EAAwC;AACtC,cAAKC,0BAAL,GAAkC,IAAlC;AACD,OAFD,MAEO;AACL,cAAKA,0BAAL,GAAkC,KAAlC;AACD;AACD,YAAKF,aAAL,GAAqBD,OAAOC,aAA5B;AACD,KAPD;AAQA,SAAKJ,UAAL,CAAgBC,GAAhB,CAAoB,gBAApB,EAAsC,UAACC,KAAD,EAAQC,MAAR,EAAmB;AACvD,YAAKI,WAAL,GAAmBJ,OAAOI,WAA1B;AACD,KAFD;AAGD;;;;iCAEY;AACX,WAAKC,YAAL;AACD;;;;;;AAGHT,kBAAkBU,OAAlB,GAA4B,CAC1B,YAD0B,CAA5B;;AAIA,IAAMC,UAAU;AACdC,YAAU;AACRC,mBAAe,GADP;AAERC,mBAAe,GAFP;AAGRC,cAAU,GAHF;AAIRN,kBAAc;AAJN,GADI;AAOdO,cAAYhB,iBAPE;AAQdiB;AARc,CAAhB;;kBA0CeN,O","file":"toolbar.js","sourcesContent":["\"use strict\";\n\nclass ToolbarController {\n constructor($rootScope) {\n this.$rootScope = $rootScope;\n this.$rootScope.$on('setGlobalMessage', (event, params) => {\n if (params.globalMessage.time === null) {\n this.isProgressIndicatorVisible = true;\n } else {\n this.isProgressIndicatorVisible = false;\n }\n this.globalMessage = params.globalMessage;\n });\n this.$rootScope.$on('setIsJSONValid', (event, params) => {\n this.isJSONValid = params.isJSONValid;\n });\n }\n\n toggleMenu() {\n this.onMenuToggle();\n }\n}\n\nToolbarController.$inject = [\n '$rootScope'\n];\n\nconst Toolbar = {\n bindings: {\n numberProject: '<',\n showStepTools: '<',\n viewName: '<',\n onMenuToggle: '&'\n },\n controller: ToolbarController,\n template:\n `\n
\n \n menu \n \n {{ $ctrl.viewName }}\n \n
\n done{{ 'jsonValid' | translate }}\n clear{{ 'jsonInvalid' | translate }}\n
\n \n \n
\n \n {{$ctrl.globalMessage.text}}\n \n \n {{ $ctrl.globalMessage.time | amDateFormat:'ddd, MMM D YYYY, h:mm a' }}\n \n \n \n \n
\n
`\n};\n\nexport default Toolbar;\n"]} \ No newline at end of file diff --git a/src/main/webapp/wise5/authoringTool/i18n/i18n_en.json b/src/main/webapp/wise5/authoringTool/i18n/i18n_en.json index fe01fd4094..138ec98e16 100644 --- a/src/main/webapp/wise5/authoringTool/i18n/i18n_en.json +++ b/src/main/webapp/wise5/authoringTool/i18n/i18n_en.json @@ -161,6 +161,8 @@ "isVisitable": "Is Visitable", "isVisited": "Is Visited", "json": "JSON", + "jsonInvalid": "JSON Invalid", + "jsonValid": "JSON Valid", "labelLink": "Label (Link)", "labelPlural": "Label (Plural)", "labelSingular": "Label (Singular)", @@ -225,6 +227,7 @@ "projectCreatedOn": "Project created on ", "projectHome": "Project Home", "projectJSON": "Project JSON", + "jsonInvalidErrorMessage": "The JSON is invalid. Invalid JSON will not be saved.\nClick \"OK\" to revert back to the last valid JSON.\nClick \"Cancel\" to keep the invalid JSON open so you can fix it.", "projectsList": "Projects List", "projectStyles": "Project Styles", "projectStructure": "Project Structure", diff --git a/src/main/webapp/wise5/authoringTool/node/node.html b/src/main/webapp/wise5/authoringTool/node/node.html index 57657f36b4..3a80f76150 100644 --- a/src/main/webapp/wise5/authoringTool/node/node.html +++ b/src/main/webapp/wise5/authoringTool/node/node.html @@ -795,7 +795,9 @@
{{ 'ed
{{ 'editStepJSON' | translate }}
+ ng-change='nodeAuthoringController.autoSaveJSON()' + ng-model-options='{ debounce: 1000 }' + style='width: 90%; border: 1px solid black;'>
diff --git a/src/main/webapp/wise5/authoringTool/node/nodeAuthoringController.es6 b/src/main/webapp/wise5/authoringTool/node/nodeAuthoringController.es6 index e65b58ddcc..0b7f275e39 100644 --- a/src/main/webapp/wise5/authoringTool/node/nodeAuthoringController.es6 +++ b/src/main/webapp/wise5/authoringTool/node/nodeAuthoringController.es6 @@ -717,7 +717,7 @@ class NodeAuthoringController { */ showSaveErrorAdvancedAuthoring() { alert(this.$translate('saveErrorAdvancedAuthoring')); - }; + } /** * The author has clicked the cancel button which will revert all @@ -1357,9 +1357,8 @@ class NodeAuthoringController { this.showStepButtons = true; this.showComponents = true; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'generalAdvanced') { - // save and parse the JSON if it has changed - this.saveAndParseJSON(); // toggle the edit transitions view and hide all the other views this.showCreateComponent = false; this.showGeneralAdvanced = !this.showGeneralAdvanced; @@ -1373,9 +1372,8 @@ class NodeAuthoringController { this.showStepButtons = false; this.showComponents = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'editTransitions') { - // save and parse the JSON if it has changed - this.saveAndParseJSON(); // toggle the edit transitions view and hide all the other views this.showCreateComponent = false; this.showGeneralAdvanced = false; @@ -1389,9 +1387,8 @@ class NodeAuthoringController { this.showStepButtons = false; this.showComponents = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'editConstraints') { - // save and parse the JSON if it has changed - this.saveAndParseJSON(); // toggle the edit constraints view and hide all the other views this.showCreateComponent = false; this.showGeneralAdvanced = false; @@ -1405,6 +1402,7 @@ class NodeAuthoringController { this.showStepButtons = false; this.showComponents = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'editButtons') { // toggle the edit buttons view and hide all the other views this.showCreateComponent = false; @@ -1418,6 +1416,7 @@ class NodeAuthoringController { this.showImportView = false; this.showStepButtons = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'editRubric') { // toggle the edit buttons view and hide all the other views this.showCreateComponent = false; @@ -1432,9 +1431,8 @@ class NodeAuthoringController { this.showStepButtons = false; this.showComponents = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'createBranch') { - // save and parse the JSON if it has changed - this.saveAndParseJSON(); // toggle the edit buttons view and hide all the other views this.showCreateComponent = false; this.showGeneralAdvanced = false; @@ -1448,6 +1446,7 @@ class NodeAuthoringController { this.showStepButtons = false; this.showComponents = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'previousNode') { // hide all the other views this.showCreateComponent = false; @@ -1460,6 +1459,7 @@ class NodeAuthoringController { this.showAdvanced = false; this.showImportView = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); let prevNodeId = this.ProjectService.getPreviousNodeId(this.nodeId); if (prevNodeId != null) { // there is a previous node id so we will go to it @@ -1481,6 +1481,7 @@ class NodeAuthoringController { this.showAdvanced = false; this.showImportView = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); let nextNodeId = this.ProjectService.getNextNodeId(this.nodeId); if (nextNodeId != null) { // there is a next node id so we will go to it @@ -1504,6 +1505,7 @@ class NodeAuthoringController { this.showStepButtons = false; this.showComponents = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'copy') { // toggle the copy view and hide all the other views this.showCreateComponent = false; @@ -1518,6 +1520,7 @@ class NodeAuthoringController { this.showStepButtons = true; this.showComponents = true; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'move') { // toggle the move view and hide all the other views this.showCreateComponent = false; @@ -1532,6 +1535,7 @@ class NodeAuthoringController { this.showStepButtons = true; this.showComponents = true; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'import') { // toggle the import view and hide all the other views this.showCreateComponent = false; @@ -1546,9 +1550,8 @@ class NodeAuthoringController { this.showStepButtons = false; this.showComponents = true; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'showJSON') { - // save and parse the JSON if it has changed - this.saveAndParseJSON(); // toggle the import view and hide all the other views this.showCreateComponent = false; this.showGeneralAdvanced = false; @@ -1561,8 +1564,24 @@ class NodeAuthoringController { this.showImportView = false; this.showStepButtons = false; this.showComponents = false; - this.authoringNodeContentJSONString = angular.toJson(this.node, 4); - this.showJSON = !this.showJSON; + if (this.showJSON) { + // we were showing the JSON view and the author now wants to hide it + if (!this.isJSONValid()) { + if (confirm(this.$translate('jsonInvalidErrorMessage'))) { + // the author wants to revert back to the last valid JSON + this.toggleJSONAuthoringView(); + this.UtilService.hideJSONValidMessage(); + } + } else { + this.toggleJSONAuthoringView(); + this.UtilService.hideJSONValidMessage(); + } + } else { + // we were not showing the JSON view and now the author wants to show it + this.toggleJSONAuthoringView(); + this.authoringNodeContentJSONString = angular.toJson(this.node, 4); + this.UtilService.showJSONValidMessage(); + } } else { // hide all the views this.showCreateComponent = false; @@ -1580,6 +1599,19 @@ class NodeAuthoringController { } } + isJSONValid() { + try { + angular.fromJson(this.authoringNodeContentJSONString); + return true; + } catch(e) { + return false; + } + } + + toggleJSONAuthoringView() { + this.showJSON = !this.showJSON; + } + /** * The author has changed the number of branch paths * TODO refactor long function @@ -3254,13 +3286,7 @@ class NodeAuthoringController { */ backButtonClicked() { if (this.showImportView || this.showRubric || this.showAdvanced) { - if (this.showJSON) { - /* - * we are showing the JSON so we will check if it has changed - * and then save and parse the JSON - */ - this.saveAndParseJSON(); - } + this.UtilService.hideJSONValidMessage(); // we are in the import view so we will go back to the node view this.nodeAuthoringViewButtonClicked(); @@ -3350,41 +3376,35 @@ class NodeAuthoringController { } /** - * Check if the JSON has changed and then save and parse the JSON + * Save the project JSON to the server if the JSON is valid. */ - saveAndParseJSON() { - if (this.showJSON) { - /* - * We are showing the JSON so we will now check to see if the - * JSON changed. If the JSON changed we will save the node with - * new JSON. - */ - if (this.authoringNodeContentJSONString != angular.toJson(this.node, 4)) { - // the JSON has been changed so we will update the node - - // create the updated node object - let updatedNode = angular.fromJson(this.authoringNodeContentJSONString); + autoSaveJSON() { + try { + // create the updated node object + let updatedNode = angular.fromJson(this.authoringNodeContentJSONString); - // set the updated node into the project - this.ProjectService.setNode(this.nodeId, updatedNode); + // set the updated node into the project + this.ProjectService.setNode(this.nodeId, updatedNode); - // set the updated node into this controller - this.node = updatedNode; + // set the updated node into this controller + this.node = updatedNode; - // set the components into this controller - this.components = this.ProjectService.getComponentsByNodeId(this.nodeId); + // set the components into this controller + this.components = this.ProjectService.getComponentsByNodeId(this.nodeId); - // set the current node - this.TeacherDataService.setCurrentNodeByNodeId(this.nodeId); + // set the current node + this.TeacherDataService.setCurrentNodeByNodeId(this.nodeId); - // update the branch authoring fields into the controller - this.populateBranchAuthoring(); + // update the branch authoring fields into the controller + this.populateBranchAuthoring(); - // save the project - this.authoringViewNodeChanged().then(() => { - this.$rootScope.$broadcast('parseProject'); - }); - } + // save the project + this.authoringViewNodeChanged().then(() => { + this.$rootScope.$broadcast('parseProject'); + }); + this.UtilService.showJSONValidMessage(); + } catch(e) { + this.UtilService.showJSONInvalidMessage(); } } diff --git a/src/main/webapp/wise5/authoringTool/node/nodeAuthoringController.js b/src/main/webapp/wise5/authoringTool/node/nodeAuthoringController.js index eae3f1616a..3d2852741c 100644 --- a/src/main/webapp/wise5/authoringTool/node/nodeAuthoringController.js +++ b/src/main/webapp/wise5/authoringTool/node/nodeAuthoringController.js @@ -667,14 +667,14 @@ var NodeAuthoringController = function () { value: function showSaveErrorAdvancedAuthoring() { alert(this.$translate('saveErrorAdvancedAuthoring')); } - }, { - key: 'cancel', - /** * The author has clicked the cancel button which will revert all * the recent changes since they opened the node. */ + + }, { + key: 'cancel', value: function cancel() { // check if the user has made any changes if (!angular.equals(this.node, this.originalNodeCopy)) { @@ -1513,9 +1513,8 @@ var NodeAuthoringController = function () { this.showStepButtons = true; this.showComponents = true; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'generalAdvanced') { - // save and parse the JSON if it has changed - this.saveAndParseJSON(); // toggle the edit transitions view and hide all the other views this.showCreateComponent = false; this.showGeneralAdvanced = !this.showGeneralAdvanced; @@ -1529,9 +1528,8 @@ var NodeAuthoringController = function () { this.showStepButtons = false; this.showComponents = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'editTransitions') { - // save and parse the JSON if it has changed - this.saveAndParseJSON(); // toggle the edit transitions view and hide all the other views this.showCreateComponent = false; this.showGeneralAdvanced = false; @@ -1545,9 +1543,8 @@ var NodeAuthoringController = function () { this.showStepButtons = false; this.showComponents = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'editConstraints') { - // save and parse the JSON if it has changed - this.saveAndParseJSON(); // toggle the edit constraints view and hide all the other views this.showCreateComponent = false; this.showGeneralAdvanced = false; @@ -1561,6 +1558,7 @@ var NodeAuthoringController = function () { this.showStepButtons = false; this.showComponents = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'editButtons') { // toggle the edit buttons view and hide all the other views this.showCreateComponent = false; @@ -1574,6 +1572,7 @@ var NodeAuthoringController = function () { this.showImportView = false; this.showStepButtons = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'editRubric') { // toggle the edit buttons view and hide all the other views this.showCreateComponent = false; @@ -1588,9 +1587,8 @@ var NodeAuthoringController = function () { this.showStepButtons = false; this.showComponents = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'createBranch') { - // save and parse the JSON if it has changed - this.saveAndParseJSON(); // toggle the edit buttons view and hide all the other views this.showCreateComponent = false; this.showGeneralAdvanced = false; @@ -1604,6 +1602,7 @@ var NodeAuthoringController = function () { this.showStepButtons = false; this.showComponents = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'previousNode') { // hide all the other views this.showCreateComponent = false; @@ -1616,6 +1615,7 @@ var NodeAuthoringController = function () { this.showAdvanced = false; this.showImportView = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); var prevNodeId = this.ProjectService.getPreviousNodeId(this.nodeId); if (prevNodeId != null) { // there is a previous node id so we will go to it @@ -1637,6 +1637,7 @@ var NodeAuthoringController = function () { this.showAdvanced = false; this.showImportView = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); var nextNodeId = this.ProjectService.getNextNodeId(this.nodeId); if (nextNodeId != null) { // there is a next node id so we will go to it @@ -1660,6 +1661,7 @@ var NodeAuthoringController = function () { this.showStepButtons = false; this.showComponents = false; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'copy') { // toggle the copy view and hide all the other views this.showCreateComponent = false; @@ -1674,6 +1676,7 @@ var NodeAuthoringController = function () { this.showStepButtons = true; this.showComponents = true; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'move') { // toggle the move view and hide all the other views this.showCreateComponent = false; @@ -1688,6 +1691,7 @@ var NodeAuthoringController = function () { this.showStepButtons = true; this.showComponents = true; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'import') { // toggle the import view and hide all the other views this.showCreateComponent = false; @@ -1702,9 +1706,8 @@ var NodeAuthoringController = function () { this.showStepButtons = false; this.showComponents = true; this.showJSON = false; + this.UtilService.hideJSONValidMessage(); } else if (view == 'showJSON') { - // save and parse the JSON if it has changed - this.saveAndParseJSON(); // toggle the import view and hide all the other views this.showCreateComponent = false; this.showGeneralAdvanced = false; @@ -1717,8 +1720,24 @@ var NodeAuthoringController = function () { this.showImportView = false; this.showStepButtons = false; this.showComponents = false; - this.authoringNodeContentJSONString = angular.toJson(this.node, 4); - this.showJSON = !this.showJSON; + if (this.showJSON) { + // we were showing the JSON view and the author now wants to hide it + if (!this.isJSONValid()) { + if (confirm(this.$translate('jsonInvalidErrorMessage'))) { + // the author wants to revert back to the last valid JSON + this.toggleJSONAuthoringView(); + this.UtilService.hideJSONValidMessage(); + } + } else { + this.toggleJSONAuthoringView(); + this.UtilService.hideJSONValidMessage(); + } + } else { + // we were not showing the JSON view and now the author wants to show it + this.toggleJSONAuthoringView(); + this.authoringNodeContentJSONString = angular.toJson(this.node, 4); + this.UtilService.showJSONValidMessage(); + } } else { // hide all the views this.showCreateComponent = false; @@ -1735,6 +1754,21 @@ var NodeAuthoringController = function () { this.showJSON = false; } } + }, { + key: 'isJSONValid', + value: function isJSONValid() { + try { + angular.fromJson(this.authoringNodeContentJSONString); + return true; + } catch (e) { + return false; + } + } + }, { + key: 'toggleJSONAuthoringView', + value: function toggleJSONAuthoringView() { + this.showJSON = !this.showJSON; + } /** * The author has changed the number of branch paths @@ -3773,13 +3807,7 @@ var NodeAuthoringController = function () { key: 'backButtonClicked', value: function backButtonClicked() { if (this.showImportView || this.showRubric || this.showAdvanced) { - if (this.showJSON) { - /* - * we are showing the JSON so we will check if it has changed - * and then save and parse the JSON - */ - this.saveAndParseJSON(); - } + this.UtilService.hideJSONValidMessage(); // we are in the import view so we will go back to the node view this.nodeAuthoringViewButtonClicked(); @@ -3940,46 +3968,40 @@ var NodeAuthoringController = function () { } /** - * Check if the JSON has changed and then save and parse the JSON + * Save the project JSON to the server if the JSON is valid. */ }, { - key: 'saveAndParseJSON', - value: function saveAndParseJSON() { + key: 'autoSaveJSON', + value: function autoSaveJSON() { var _this9 = this; - if (this.showJSON) { - /* - * We are showing the JSON so we will now check to see if the - * JSON changed. If the JSON changed we will save the node with - * new JSON. - */ - if (this.authoringNodeContentJSONString != angular.toJson(this.node, 4)) { - // the JSON has been changed so we will update the node - - // create the updated node object - var updatedNode = angular.fromJson(this.authoringNodeContentJSONString); + try { + // create the updated node object + var updatedNode = angular.fromJson(this.authoringNodeContentJSONString); - // set the updated node into the project - this.ProjectService.setNode(this.nodeId, updatedNode); + // set the updated node into the project + this.ProjectService.setNode(this.nodeId, updatedNode); - // set the updated node into this controller - this.node = updatedNode; + // set the updated node into this controller + this.node = updatedNode; - // set the components into this controller - this.components = this.ProjectService.getComponentsByNodeId(this.nodeId); + // set the components into this controller + this.components = this.ProjectService.getComponentsByNodeId(this.nodeId); - // set the current node - this.TeacherDataService.setCurrentNodeByNodeId(this.nodeId); + // set the current node + this.TeacherDataService.setCurrentNodeByNodeId(this.nodeId); - // update the branch authoring fields into the controller - this.populateBranchAuthoring(); + // update the branch authoring fields into the controller + this.populateBranchAuthoring(); - // save the project - this.authoringViewNodeChanged().then(function () { - _this9.$rootScope.$broadcast('parseProject'); - }); - } + // save the project + this.authoringViewNodeChanged().then(function () { + _this9.$rootScope.$broadcast('parseProject'); + }); + this.UtilService.showJSONValidMessage(); + } catch (e) { + this.UtilService.showJSONInvalidMessage(); } } diff --git a/src/main/webapp/wise5/authoringTool/node/nodeAuthoringController.js.map b/src/main/webapp/wise5/authoringTool/node/nodeAuthoringController.js.map index 90a9ee3b9a..fea4bda627 100644 --- a/src/main/webapp/wise5/authoringTool/node/nodeAuthoringController.js.map +++ b/src/main/webapp/wise5/authoringTool/node/nodeAuthoringController.js.map @@ -1 +1 @@ -{"version":3,"sources":["nodeAuthoringController.es6"],"names":["NodeAuthoringController","$anchorScroll","$filter","$injector","$location","$mdDialog","$rootScope","$scope","$state","$stateParams","$timeout","ConfigService","NodeService","ProjectAssetService","ProjectService","TeacherDataService","UtilService","$translate","projectId","nodeId","showCreateComponent","showEditTransitions","selectedComponent","nodeCopy","undoStack","howToChooseAmongAvailablePathsOptions","whenToChoosePathOptions","canChangePathOptions","createBranchBranches","showComponents","showStepButtons","showComponentAuthoringViews","componentsToChecked","setCurrentNodeByNodeId","constraintActions","value","text","removalConditionals","removalCriteria","params","transitionCriterias","branchCriteria","componentTypes","componentType","componentName","getComponentTypeLabel","node","getNodeById","nodePosition","getNodePositionById","components","getComponentsByNodeId","originalNodeCopy","makeCopyOfJSONObject","currentNodeCopy","populateBranchAuthoring","summernoteRubricId","insertAssetString","insertAssetButton","createInsertAssetButton","summernoteRubricOptions","toolbar","height","disableDragAndDrop","buttons","summernoteRubricHTML","replaceAssetPaths","rubric","$on","event","args","componentId","assetItem","fileName","assetsDirectoryPath","getProjectAssetsDirectoryPath","fullAssetPath","target","summernoteId","isImage","$","summernote","isVideo","videoElement","document","createElement","controls","innerHTML","hide","showSubmitButton","showSaveButton","turnOnSaveButtonInComponents","id","doesAnyComponentShowSubmitButton","turnOffSaveButtonInComponents","authoringViewNodeChanged","current","name","nodeAuthoringViewButtonClicked","scrollToTopOfPage","data","getNodePositionAndTitleByNodeId","isGroupNode","saveEvent","transitionLogic","transitions","createBranchNumberOfBranches","length","t","transition","branch","number","items","idToOrder","checkedItemsInBranchPath","push","criteria","criterion","createBranchNodeId","createBranchComponentId","createBranchCriterion","scores","choiceIds","choiceId","choices","getChoicesByNodeIdAndComponentId","nodeIdsInBranch","getNodeIdsInBranch","to","item","checked","lastNodeIdInBranch","transitionsFromLastNode","getTransitionsByFromNodeId","createBranchMergePointNodeId","howToChooseAmongAvailablePaths","previewProjectURL","getConfigParam","previewStepURL","window","open","$broadcast","nodeToExit","setCurrentNode","go","alert","angular","equals","confirm","replaceNode","saveProject","close","nodeTransitions","lastNodeTransition","newTransition","whenToChoosePath","canChangePath","maxPathsVisitable","calculateNodeNumbers","nodeTransition","newTransitionCriteria","transitionCriteria","stepTitle","answer","index","indexOf","splice","turnOnAddComponentMode","turnOffMoveComponentMode","turnOnInsertComponentMode","hideComponentAuthoring","deleteComponent","checkIfNeedToShowNodeSaveOrNodeSubmitButtons","component","type","service","get","componentUsesSaveButton","parseProject","pop","singleRemovalCriteria","singleTransitionCriteria","choiceType","getComponentByNodeIdAndComponentId","newNodeConstraintId","usedConstraintIds","constraints","nodeConstraints","constraint","constraintId","constraintCounter","potentialNewNodeConstraintId","getNewNodeConstraintId","addConstraint","temporarilyHighlightElement","constraintIndex","removalCriteriaIndex","transitionCriteriaIndex","getRemovalCriteriaParamsByName","paramObject","view","showGeneralAdvanced","showConstraints","showEditButtons","showRubric","showCreateBranch","showAdvanced","showImportView","showJSON","saveAndParseJSON","showRubricButton","prevNodeId","getPreviousNodeId","thereIsNoPreviousStep","nextNodeId","getNextNodeId","thereIsNoNextStep","authoringNodeContentJSONString","toJson","removeBranch","bp","removeBranchPath","createBranchCriterionChanged","b","setTransitionLogicField","createBranchUpdateTransitions","selectedNode","createBranchUpdateChoiceChosenIds","createBranchUpdateChoiceChosenIdsHelper","c","choice","feedback","isCorrect","orderedItems","previousCheckedNodeId","nodeIdAfter","i","orderedItem","previousCheckedNode","$key","previousOrderedItem","branchNumber","firstNodeId","firstCheckedItem","removeBranchPathTakenNodeConstraints","fromNodeId","toNodeId","addBranchPathTakenConstraints","setTransition","itemNodeId","branches","lastNodeIdInBranchPath","lastNodeInBranchPath","branchPath","getNodeIdAfter","checkedItem","branchPathIndex","html","removeAbsoluteAssetPaths","insertWISELinks","insertComponentMode","addComponentMode","moveComponentMode","copyComponentMode","importComponentMode","selectedComponents","componentIds","componentNumberAndType","importProjectIdToOrder","importProjectItems","importMyProjectId","importLibraryProjectId","importProjectId","importProject","turnOnImportComponentMode","myProjectsList","getAuthorableProjects","libraryProjectsList","getLibraryProjects","then","getSelectedComponentIds","turnOffAddComponentMode","turnOnMoveComponentMode","turnOnCopyComponentMode","confirmMessage","selectedComponentNumbersAndTypes","getSelectedComponentNumbersAndTypes","selectedComponentNumberAndType","getComponentObjectsForEventData","clearComponentsToChecked","turnOffInsertComponentMode","showComponentAuthoring","doesAnyComponentHaveWork","hideAllComponentSaveButtons","handleAddComponent","handleMoveComponent","handleCopyComponent","handleImportComponent","newComponents","newComponent","createComponent","highlightNewComponentsAndThenShowComponentAuthoring","selectedComponentIds","moveComponent","componentsCopied","copyComponentAndInsert","componentCopied","fromComponentId","toComponentId","turnOffCopyComponentMode","importComponents","turnOffImportComponentMode","retrieveProjectAssets","componentElement","animate","scrollTop","offset","top","showImportProject","retrieveProjectById","projectJSON","result","getNodeOrderOfProject","nodes","getSelectedComponentsToImport","componentsInNode","insertAfterComponentId","getComponentObjectsForImportEventData","componentsImported","componentImported","newComponentId","eventName","category","context","componentObjects","tempComponent","parseInt","updatedNode","fromJson","setNode","$inject"],"mappings":"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","file":"nodeAuthoringController.js","sourcesContent":["'use strict';\n\nclass NodeAuthoringController {\n\n constructor(\n $anchorScroll,\n $filter,\n $injector,\n $location,\n $mdDialog,\n $rootScope,\n $scope,\n $state,\n $stateParams,\n $timeout,\n ConfigService,\n NodeService,\n ProjectAssetService,\n ProjectService,\n TeacherDataService,\n UtilService) {\n this.$anchorScroll = $anchorScroll;\n this.$filter = $filter;\n this.$injector = $injector;\n this.$location = $location;\n this.$mdDialog = $mdDialog;\n this.$rootScope = $rootScope;\n this.$scope = $scope;\n this.$state = $state;\n this.$stateParams = $stateParams;\n this.$timeout = $timeout;\n this.$translate = this.$filter('translate');\n this.ConfigService = ConfigService;\n this.NodeService = NodeService;\n this.ProjectAssetService = ProjectAssetService;\n this.ProjectService = ProjectService;\n this.TeacherDataService = TeacherDataService;\n this.UtilService = UtilService;\n this.$translate = this.$filter('translate');\n this.projectId = $stateParams.projectId;\n this.nodeId = $stateParams.nodeId;\n this.showCreateComponent = false;\n this.showEditTransitions = false;\n this.selectedComponent = null;\n this.nodeCopy = null;\n this.undoStack = [];\n this.howToChooseAmongAvailablePathsOptions =\n [null, 'random', 'workgroupId', 'firstAvailable', 'lastAvailable'];\n this.whenToChoosePathOptions =\n [null, 'enterNode', 'exitNode', 'scoreChanged', 'studentDataChanged'];\n this.canChangePathOptions = [null, true, false];\n this.createBranchBranches = [];\n this.showComponents = true;\n this.showStepButtons = true;\n this.showComponentAuthoringViews = true;\n\n // mapping from component id to whether the component checkbox is checked\n this.componentsToChecked = {};\n\n this.TeacherDataService.setCurrentNodeByNodeId(this.nodeId);\n\n // the available constraint actions\n this.constraintActions = [\n {\n value: \"\",\n text: this.$translate('pleaseChooseAnAction')\n },\n {\n value: \"makeAllNodesAfterThisNotVisitable\",\n text: this.$translate('makeAllNodesAfterThisNotVisitable')\n },\n {\n value: \"makeAllNodesAfterThisNotVisible\",\n text: this.$translate('makeAllNodesAfterThisNotVisible')\n },\n {\n value: \"makeAllOtherNodesNotVisitable\",\n text: this.$translate('makeAllOtherNodesNotVisitable')\n },\n {\n value: \"makeAllOtherNodesNotVisible\",\n text: this.$translate('makeAllOtherNodesNotVisible')\n },\n {\n value: \"makeThisNodeNotVisitable\",\n text: this.$translate('makeThisNodeNotVisitable')\n },\n {\n value: \"makeThisNodeNotVisible\",\n text: this.$translate('makeThisNodeNotVisible')\n }\n ];\n\n // the available removal conditionals\n this.removalConditionals = [\n {\n value: \"all\",\n text: this.$translate('all')\n },\n {\n value: \"any\",\n text: this.$translate('any')\n }\n ];\n\n // the available removal criteria\n this.removalCriteria = [\n {\n value: \"\",\n text: this.$translate('pleaseChooseARemovalCriteria')\n },\n {\n value: \"isCompleted\",\n text: this.$translate('isCompleted'),\n params: [\n {\n value: \"nodeId\",\n text: this.$translate('step')\n }\n ]\n },\n {\n value: \"score\",\n text: this.$translate('SCORE'),\n params: [\n {\n value: \"nodeId\",\n text: this.$translate('step')\n },\n {\n value: \"component\",\n text: this.$translate('component')\n },\n {\n value: \"scores\",\n text: this.$translate('scoresParens')\n }\n ]\n },\n {\n value: \"branchPathTaken\",\n text: this.$translate('branchPathTaken'),\n params: [\n {\n value: \"fromNodeId\",\n text: this.$translate('fromStep')\n },\n {\n value: \"toNodeId\",\n text: this.$translate('toStep')\n }\n ]\n },\n {\n value: \"choiceChosen\",\n text: this.$translate('choiceChosen'),\n params: [\n {\n value: \"nodeId\",\n text: this.$translate('step')\n },\n {\n value: \"componentId\",\n text: this.$translate('component')\n },\n {\n value: \"choiceIds\",\n text: this.$translate('choices')\n }\n ]\n },\n {\n value: \"isCorrect\",\n text: this.$translate('IS_CORRECT'),\n params: [\n {\n value: \"nodeId\",\n text: this.$translate('step')\n },\n {\n value: \"componentId\",\n text: this.$translate('component')\n }\n ]\n },\n {\n value: \"usedXSubmits\",\n text: this.$translate('usedXSubmits'),\n params: [\n {\n value: \"nodeId\",\n text: this.$translate('step')\n },\n {\n value: \"componentId\",\n text: this.$translate('component')\n },\n {\n value: \"requiredSubmitCount\",\n text: this.$translate('requiredSubmitCount')\n }\n ]\n },\n {\n value: \"isVisible\",\n text: this.$translate('isVisible'),\n params: [\n {\n value: \"nodeId\",\n text: this.$translate('step')\n }\n ]\n },\n {\n value: \"isVisitable\",\n text: this.$translate('isVisitable'),\n params: [\n {\n value: \"nodeId\",\n text: this.$translate('step')\n }\n ]\n },\n {\n value: \"isVisited\",\n text: this.$translate('isVisited'),\n params: [\n {\n value: \"nodeId\",\n text: this.$translate('step')\n }\n ]\n },\n {\n value: \"isPlanningActivityCompleted\",\n text: this.$translate('isPlanningActivityCompleted')\n },\n {\n value: \"wroteXNumberOfWords\",\n text: this.$translate('wroteXNumberOfWords'),\n params: [\n {\n value: \"nodeId\",\n text: this.$translate('step')\n },\n {\n value: \"componentId\",\n text: this.$translate('component')\n },\n {\n value: \"requiredNumberOfWords\",\n text: this.$translate('requiredNumberOfWords')\n }\n ]\n }\n ];\n\n // available transitionCriterias\n this.transitionCriterias = [\n {\n value: \"score\",\n text: this.$translate('getASpecificScoreOnAComponent'),\n params: [\n {\n value: \"nodeId\",\n text: this.$translate('nodeID')\n },\n {\n value: \"componentId\",\n text: this.$translate('componentID')\n },\n {\n value: \"scores\",\n text: this.$translate('scoresParens')\n }\n ]\n },\n {\n value: \"choiceChosen\",\n text: this.$translate('chooseASpecificChoiceOnAComponent'),\n params: [\n {\n value: \"nodeId\",\n text: this.$translate('nodeID')\n },\n {\n value: \"componentId\",\n text: this.$translate('componentID')\n },\n {\n value: \"choiceIds\",\n text: this.$translate('choices')\n }\n ]\n }\n ];\n\n this.branchCriteria = [\n {\n value: \"workgroupId\",\n text: this.$translate('WORKGROUP_ID')\n },\n {\n value: \"score\",\n text: this.$translate('SCORE')\n },\n {\n value: \"choiceChosen\",\n text: this.$translate('choiceChosen')\n },\n {\n value: \"random\",\n text: this.$translate('random')\n }\n ];\n\n // the array of component types that can be created\n // TODO: automate by looping through active component types for this WISE instance\n this.componentTypes = [\n {componentType: 'Animation', componentName: this.UtilService.getComponentTypeLabel('Animation')},\n {componentType: 'AudioOscillator', componentName: this.UtilService.getComponentTypeLabel('AudioOscillator')},\n {componentType: 'ConceptMap', componentName: this.UtilService.getComponentTypeLabel('ConceptMap')},\n {componentType: 'Discussion', componentName: this.UtilService.getComponentTypeLabel('Discussion')},\n {componentType: 'Draw', componentName: this.UtilService.getComponentTypeLabel('Draw')},\n {componentType: 'Embedded', componentName: this.UtilService.getComponentTypeLabel('Embedded')},\n {componentType: 'Graph', componentName: this.UtilService.getComponentTypeLabel('Graph')},\n {componentType: 'HTML', componentName: this.UtilService.getComponentTypeLabel('HTML')},\n {componentType: 'Label', componentName: this.UtilService.getComponentTypeLabel('Label')},\n {componentType: 'Match', componentName: this.UtilService.getComponentTypeLabel('Match')},\n {componentType: 'MultipleChoice', componentName: this.UtilService.getComponentTypeLabel('MultipleChoice')},\n {componentType: 'OpenResponse', componentName: this.UtilService.getComponentTypeLabel('OpenResponse')},\n {componentType: 'OutsideURL', componentName: this.UtilService.getComponentTypeLabel('OutsideURL')},\n {componentType: 'Table', componentName: this.UtilService.getComponentTypeLabel('Table')}\n ];\n\n // select the first component type by default\n this.selectedComponent = this.componentTypes[0].componentType;\n this.node = this.ProjectService.getNodeById(this.nodeId);\n\n // get the step number e.g. 1.3\n this.nodePosition = this.ProjectService.getNodePositionById(this.nodeId);\n\n // get the components in the node\n this.components = this.ProjectService.getComponentsByNodeId(this.nodeId);\n\n /*\n * remember a copy of the node at the beginning of this node authoring\n * session in case we need to roll back if the user decides to\n * cancel/revert all the changes.\n */\n this.originalNodeCopy = this.UtilService.makeCopyOfJSONObject(this.node);\n\n /*\n * remember the current version of the node. this will be updated each\n * time the user makes a change.\n */\n this.currentNodeCopy = this.UtilService.makeCopyOfJSONObject(this.node);\n\n // populate the branch authoring if any\n this.populateBranchAuthoring();\n\n // create the summernote rubric element id\n this.summernoteRubricId = 'summernoteRubric_' + this.nodeId;\n\n // the tooltip text for the insert WISE asset button\n let insertAssetString = this.$translate('INSERT_ASSET');\n\n /*\n * create the custom button for inserting WISE assets into\n * summernote\n */\n let insertAssetButton = this.UtilService.createInsertAssetButton(\n this, null, this.nodeId, null, 'rubric', insertAssetString);\n\n /*\n * the options that specifies the tools to display in the\n * summernote prompt\n */\n this.summernoteRubricOptions = {\n toolbar: [\n ['style', ['style']],\n ['font', ['bold', 'underline', 'clear']],\n ['fontname', ['fontname']],\n ['fontsize', ['fontsize']],\n ['color', ['color']],\n ['para', ['ul', 'ol', 'paragraph']],\n ['table', ['table']],\n ['insert', ['link', 'video']],\n ['view', ['fullscreen', 'codeview', 'help']],\n ['customButton', ['insertAssetButton']]\n ],\n height: 300,\n disableDragAndDrop: true,\n buttons: {\n insertAssetButton: insertAssetButton\n }\n };\n\n /*\n * inject the asset paths into the rubric html and set the summernote\n * rubric html\n */\n this.summernoteRubricHTML =\n this.ProjectService.replaceAssetPaths(this.node.rubric);\n\n /*\n * Listen for the assetSelected event which occurs when the user\n * selects an asset from the choose asset popup\n * TODO refactor too many nesting\n */\n this.$scope.$on('assetSelected', (event, args) => {\n if (args != null) {\n // make sure the event was fired for this component\n if (args.nodeId == this.nodeId && args.componentId == null) {\n // the asset was selected for this component\n if (args.assetItem != null && args.assetItem.fileName != null) {\n let fileName = args.assetItem.fileName;\n /*\n * get the assets directory path\n * e.g.\n * /wise/curriculum/3/\n */\n let assetsDirectoryPath =\n this.ConfigService.getProjectAssetsDirectoryPath();\n let fullAssetPath = assetsDirectoryPath + '/' + fileName;\n\n if (args.target == 'rubric') {\n // the target is the summernote rubric element\n let summernoteId = 'summernoteRubric_' + this.nodeId;\n\n if (this.UtilService.isImage(fileName)) {\n /*\n * move the cursor back to its position when the asset chooser\n * popup was clicked\n */\n $('#' + summernoteId).summernote('editor.restoreRange');\n $('#' + summernoteId).summernote('editor.focus');\n\n // add the image html\n $('#' + summernoteId).summernote('insertImage', fullAssetPath, fileName);\n } else if (this.UtilService.isVideo(fileName)) {\n /*\n * move the cursor back to its position when the asset chooser\n * popup was clicked\n */\n $('#' + summernoteId).summernote('editor.restoreRange');\n $('#' + summernoteId).summernote('editor.focus');\n\n // insert the video element\n let videoElement = document.createElement('video');\n videoElement.controls = 'true';\n videoElement.innerHTML =\n '';\n $('#' + summernoteId).summernote('insertNode', videoElement);\n }\n }\n }\n }\n }\n\n // close the popup\n this.$mdDialog.hide();\n });\n\n this.$scope.$on('componentShowSubmitButtonValueChanged', (event, args) => {\n let showSubmitButton = args.showSubmitButton;\n if (showSubmitButton) {\n /*\n * a component is showing their submit button so we will hide\n * the step save button and submit buttons\n */\n this.node.showSaveButton = false;\n this.node.showSubmitButton = false;\n\n // turn on the save buttons for all components in this step\n this.ProjectService.turnOnSaveButtonInComponents(this.node.id);\n } else {\n /*\n * a component is hiding their submit button so we may need\n * to show the step save button\n */\n if (this.ProjectService.doesAnyComponentShowSubmitButton(this.node.id)) {\n /*\n * there is at least one component in the step that is showing\n * their submit button so we will show the save button on\n * all the components\n */\n\n // turn on the save buttons for all components in this step\n this.ProjectService.turnOnSaveButtonInComponents(this.node.id);\n } else {\n /*\n * no components in this step show their submit button so we\n * will show the step save button\n */\n this.node.showSaveButton = true;\n this.node.showSubmitButton = false;\n\n // turn off the save buttons for all the components\n this.ProjectService.turnOffSaveButtonInComponents(this.node.id);\n }\n }\n\n // save changes\n this.authoringViewNodeChanged();\n });\n\n if (this.$state.current.name == 'root.project.nodeConstraints') {\n this.$timeout(() => {\n this.nodeAuthoringViewButtonClicked('advanced');\n this.$timeout(() => {\n this.nodeAuthoringViewButtonClicked('editConstraints');\n });\n });\n }\n\n if (this.$state.current.name == 'root.project.nodeEditPaths') {\n this.$timeout(() => {\n this.nodeAuthoringViewButtonClicked('advanced');\n this.$timeout(() => {\n this.nodeAuthoringViewButtonClicked('editTransitions');\n });\n });\n }\n\n this.scrollToTopOfPage();\n\n let data = {\n \"title\": this.ProjectService.getNodePositionAndTitleByNodeId(this.nodeId)\n };\n\n if (this.ProjectService.isGroupNode(this.nodeId)) {\n this.saveEvent('activityViewOpened', 'Navigation', data);\n } else {\n this.saveEvent('stepViewOpened', 'Navigation', data);\n }\n }\n\n /**\n * Populate the branch authoring\n * TODO refactor too much nesting\n */\n populateBranchAuthoring() {\n if (this.node.transitionLogic != null) {\n // clear the create branch branches so we can populate them again\n this.createBranchBranches = [];\n\n // get the number of branches\n if (this.node.transitionLogic.transitions != null) {\n this.createBranchNumberOfBranches = this.node.transitionLogic.transitions.length;\n } else {\n this.createBranchNumberOfBranches = 0;\n }\n\n for (let t = 0; t < this.node.transitionLogic.transitions.length; t++) {\n let transition = this.node.transitionLogic.transitions[t];\n\n if (transition != null) {\n\n // create a branch object to hold all the related information for that branch\n let branch = {};\n\n // set the branch number for display purposes\n branch.number = t + 1;\n\n /*\n * set the mapping of all the ids to order for use when choosing which items are\n * in the branch path\n */\n branch.items = this.UtilService.makeCopyOfJSONObject(this.ProjectService.idToOrder);\n\n // an array that will hold all the checked items in the branch path\n branch.checkedItemsInBranchPath = [];\n\n // set the transition into the branch so we can access it easily later\n branch.transition = transition;\n\n // add the branch to the array of branches\n this.createBranchBranches.push(branch);\n\n // get the transition criteria\n let criteria = transition.criteria;\n\n if (criteria != null) {\n for (let criterion of criteria) {\n if (criterion != null) {\n let name = criterion.name;\n let params = criterion.params;\n\n if (params != null) {\n // get the node id and component id params if any\n this.createBranchNodeId = params.nodeId;\n this.createBranchComponentId = params.componentId;\n }\n\n if (name == 'score') {\n // this is a score criteria\n\n // set the branch criterion to score\n this.createBranchCriterion = 'score';\n\n if (params != null && params.scores != null) {\n // set the scores into the branch object\n branch.scores = params.scores;\n }\n } else if (name == 'choiceChosen') {\n // this is a choice chosen criteria\n\n // set the branch criterion to choice chosen\n this.createBranchCriterion = 'choiceChosen';\n\n if (params != null && params.choiceIds != null && params.choiceIds.length > 0) {\n // set the choice id into the branch object\n branch.choiceId = params.choiceIds[0];\n }\n\n // get the choices from the component\n let choices = this.ProjectService.getChoicesByNodeIdAndComponentId(this.createBranchNodeId, this.createBranchComponentId);\n\n if (choices != null) {\n // set the choices into the branch object\n branch.choices = this.UtilService.makeCopyOfJSONObject(choices);\n }\n }\n }\n }\n }\n\n // get the node ids in the branch path\n let nodeIdsInBranch = this.ProjectService\n .getNodeIdsInBranch(this.nodeId, transition.to);\n for (let nodeId of nodeIdsInBranch) {\n let item = branch.items[nodeId];\n if (item != null) {\n // make the item checked\n item.checked = true;\n\n // add the item to the array of checked items in this branch path\n branch.checkedItemsInBranchPath.push(item);\n }\n }\n\n // set the node ids in branch array into the branch object\n branch.nodeIdsInBranch = nodeIdsInBranch;\n\n if (nodeIdsInBranch.length > 0) {\n // get the last node id in the branch path\n let lastNodeIdInBranch = nodeIdsInBranch[nodeIdsInBranch.length - 1];\n\n if (lastNodeIdInBranch != null) {\n let transitionsFromLastNode = this.ProjectService\n .getTransitionsByFromNodeId(lastNodeIdInBranch);\n if (transitionsFromLastNode != null &&\n transitionsFromLastNode.length > 0) {\n let transition = transitionsFromLastNode[0];\n if (transition != null) {\n this.createBranchMergePointNodeId = transition.to;\n }\n }\n }\n }\n }\n }\n\n if (this.createBranchCriterion == null) {\n /*\n * we have not been able to determine the branch criterion yet\n * so we will look at the howToChooseAmongAvailablePaths field\n */\n if (this.node.transitionLogic.howToChooseAmongAvailablePaths == 'workgroupId') {\n // set the branch criterion to workgroup id\n this.createBranchCriterion = 'workgroupId';\n } else if (this.node.transitionLogic.howToChooseAmongAvailablePaths == 'random') {\n // set the branch criterion to random\n this.createBranchCriterion = 'random';\n }\n }\n }\n }\n\n /**\n * Launch VLE with this current step as the initial step\n */\n previewStepInNewWindow() {\n let data = { \"constraints\": true };\n this.saveEvent('stepPreviewed', 'Navigation', data);\n\n let previewProjectURL = this.ConfigService.getConfigParam('previewProjectURL');\n let previewStepURL = previewProjectURL + '#/vle/' + this.nodeId;\n window.open(previewStepURL);\n };\n\n /**\n * Launch VLE with this current step as the initial step without constraints\n */\n previewStepWithoutConstraintsInNewWindow() {\n let data = { \"constraints\": false };\n this.saveEvent('stepPreviewed', 'Navigation', data);\n\n let previewProjectURL = this.ConfigService.getConfigParam('previewProjectURL');\n let previewStepURL = previewProjectURL + '?constraints=false' + '#/vle/' + this.nodeId;\n window.open(previewStepURL);\n };\n\n /**\n * Close the node authoring view\n */\n close() {\n this.$scope.$broadcast('exitNode', {nodeToExit: this.node});\n this.TeacherDataService.setCurrentNode(null);\n this.$state.go('root.project', {projectId: this.projectId});\n this.scrollToTopOfPage();\n };\n\n /**\n * Display an error saving during advanced authoring, most-likely due to malformed JSON\n */\n showSaveErrorAdvancedAuthoring() {\n alert(this.$translate('saveErrorAdvancedAuthoring'));\n };\n\n /**\n * The author has clicked the cancel button which will revert all\n * the recent changes since they opened the node.\n */\n cancel() {\n // check if the user has made any changes\n if (!angular.equals(this.node, this.originalNodeCopy)) {\n // the user has made changes\n if (confirm(this.$translate('confirmUndo'))) {\n // revert the node back to the previous version\n this.ProjectService.replaceNode(this.nodeId, this.originalNodeCopy);\n this.ProjectService.saveProject();\n this.close();\n }\n } else {\n // the user has not made any changes, so close the node authoring view\n this.close();\n }\n }\n\n /**\n * Add a new transition for this node.\n */\n addNewTransition() {\n if (this.node.transitionLogic.transitions == null) {\n this.node.transitionLogic.transitions = [];\n }\n let nodeTransitions = this.node.transitionLogic.transitions;\n if (nodeTransitions.length > 0) {\n // If this node already has transitions, copy the last one.\n let lastNodeTransition = nodeTransitions[nodeTransitions.length - 1];\n let newTransition = {\n \"to\": lastNodeTransition.to\n };\n nodeTransitions.push(newTransition);\n } else {\n // Otherwise set the new transition to the current nodeId\n let newTransition = {\n \"to\": this.nodeId\n };\n nodeTransitions.push(newTransition);\n }\n\n if (nodeTransitions.length > 1) {\n /*\n * there is more than one transition so we will set default values\n * for the transition logic parameters if they haven't already been\n * set\n */\n if (this.node.transitionLogic.howToChooseAmongAvailablePaths == null) {\n this.node.transitionLogic.howToChooseAmongAvailablePaths = 'workgroupId';\n }\n\n if (this.node.transitionLogic.whenToChoosePath == null) {\n this.node.transitionLogic.whenToChoosePath = 'enterNode';\n }\n\n if (this.node.transitionLogic.canChangePath == null) {\n this.node.transitionLogic.canChangePath = false;\n }\n\n if (this.node.transitionLogic.maxPathsVisitable == null) {\n this.node.transitionLogic.maxPathsVisitable = 1;\n }\n }\n // save changes\n this.authoringViewNodeChanged();\n }\n\n /**\n * The transition to node id has changed so need to recalculate the step\n * numbers\n */\n authoringViewTransitionToNodeIdChanged() {\n /*\n * update the node numbers now that a step has been added to a branch path\n * e.g. if this is a branching step that is called\n * 1.5 B View the Potential Energy\n * then the node number is 1.5 B\n */\n this.ProjectService.calculateNodeNumbers();\n\n // save changes\n this.authoringViewNodeChanged();\n }\n\n /**\n * Add a new transition criteria for the specified transition.\n */\n addNewTransitionCriteria(transition) {\n let nodeTransitions = this.node.transitionLogic.transitions;\n for (let nodeTransition of nodeTransitions) {\n if (nodeTransition == transition) {\n if (nodeTransition.criteria == null) {\n nodeTransition.criteria = [];\n }\n let newTransitionCriteria = {\n \"name\":\"\",\n \"params\": {\n \"nodeId\": \"\",\n \"componentId\": \"\"\n }\n };\n nodeTransition.criteria.push(newTransitionCriteria);\n }\n }\n // save changes\n this.authoringViewNodeChanged();\n }\n\n /**\n * The transition criteria node id changed so we will update the params\n * accordingly.\n * @param transitionCriteria the transition criteria object that changed\n */\n transitionCriteriaNodeIdChanged(transitionCriteria) {\n if (transitionCriteria!= null && transitionCriteria.params != null) {\n // remember the node id\n let nodeId = transitionCriteria.params.nodeId;\n\n // clear the params\n transitionCriteria.params = {};\n\n if (nodeId != null) {\n // set the node id back into the params\n transitionCriteria.params.nodeId = nodeId;\n }\n }\n\n // save the node\n this.authoringViewNodeChanged();\n }\n\n /**\n * The transition criteria component id changed so we will update the params\n * accordingly.\n * @param transitionCriteria the transition criteria object that changed\n */\n transitionCriteriaComponentIdChanged(transitionCriteria) {\n if (transitionCriteria!= null && transitionCriteria.params != null) {\n // remember the node id and component id\n let nodeId = transitionCriteria.params.nodeId;\n let componentId = transitionCriteria.params.componentId;\n\n // clear the params\n transitionCriteria.params = {};\n\n if (nodeId != null) {\n // set the node id back into the params\n transitionCriteria.params.nodeId = nodeId;\n }\n\n if (componentId != null) {\n // set the component id back into the params\n transitionCriteria.params.componentId = componentId;\n }\n }\n\n // save the node\n this.authoringViewNodeChanged();\n }\n\n /**\n * Deletes the specified transition from this node\n * @param transition the transition to delete\n */\n deleteTransition(transition) {\n let stepTitle = '';\n if (transition != null) {\n stepTitle = this.ProjectService.getNodePositionAndTitleByNodeId(transition.to);\n }\n let answer = confirm(this.$translate('areYouSureYouWantToDeleteThisPath', { stepTitle: stepTitle }));\n if (answer) {\n let nodeTransitions = this.node.transitionLogic.transitions;\n let index = nodeTransitions.indexOf(transition);\n if (index > -1) {\n nodeTransitions.splice(index, 1);\n }\n if (nodeTransitions.length <= 1) {\n /*\n * there is zero or one transition so we will clear the parameters\n * below since they only apply when there are multiple transitions\n */\n this.node.transitionLogic.howToChooseAmongAvailablePaths = null;\n this.node.transitionLogic.whenToChoosePath = null;\n this.node.transitionLogic.canChangePath = null;\n this.node.transitionLogic.maxPathsVisitable = null;\n }\n // save changes\n this.authoringViewNodeChanged();\n }\n }\n\n /**\n * Save transitions for this node\n */\n saveTransitions() {\n this.ProjectService.saveProject();\n this.showEditTransitions = false;\n }\n\n /**\n * The add component button was clicked\n */\n addComponentButtonClicked() {\n // select the first component type by default\n this.selectedComponent = this.componentTypes[0].componentType;\n\n // show the add component UI elements\n this.nodeAuthoringViewButtonClicked('addComponent');\n\n // turn on add component mode\n this.turnOnAddComponentMode();\n\n // turn on the move component mode\n this.turnOffMoveComponentMode();\n\n // turn on the insert component mode\n this.turnOnInsertComponentMode();\n\n // hide the component authoring\n this.hideComponentAuthoring();\n }\n\n /**\n * Delete the component from this node\n * @param componentId the component id\n */\n deleteComponent(componentId) {\n if (confirm(this.$translate('confirmDeleteComponent'))) {\n // delete the component from the node\n this.ProjectService.deleteComponent(this.nodeId, componentId);\n\n // check if we need to show the node save or node submit buttons\n this.checkIfNeedToShowNodeSaveOrNodeSubmitButtons();\n this.ProjectService.saveProject();\n }\n }\n\n /**\n * Hide the save button in all the components\n * TODO refactor too much nesting\n */\n hideAllComponentSaveButtons() {\n let components = this.components;\n if (components != null) {\n for (let component of components) {\n if (component != null) {\n let componentType = component.type;\n\n // get the service for the component type\n let service = this.$injector.get(componentType + 'Service');\n if (service != null) {\n if (service.componentUsesSaveButton()) {\n /*\n * this component uses a save button so we will hide\n * it\n */\n component.showSaveButton = false;\n }\n }\n }\n }\n }\n }\n\n /**\n * The node has changed in the authoring view\n * @param parseProject whether to parse the whole project to recalculate\n * significant changes such as branch paths\n */\n authoringViewNodeChanged(parseProject) {\n // put the previous version of the node on to the undo stack\n this.undoStack.push(this.currentNodeCopy);\n\n // update the current node copy\n this.currentNodeCopy = this.UtilService.makeCopyOfJSONObject(this.node);\n\n if (parseProject) {\n // refresh the project\n this.ProjectService.parseProject();\n this.items = this.ProjectService.idToOrder;\n }\n\n return this.ProjectService.saveProject();\n }\n\n /**\n * Undo the last change by reverting the node to the previous version\n */\n undo() {\n if (this.undoStack.length === 0) {\n // the undo stack is empty so there are no changes to undo\n alert(this.$translate('noUndoAvailable'));\n } else if (this.undoStack.length > 0) {\n // the undo stack has elements\n\n if (confirm(this.$translate('confirmUndoLastChange'))) {\n // perform any node cleanup if necessary\n this.$scope.$broadcast('exitNode', {nodeToExit: this.node});\n\n // get the previous version of the node\n let nodeCopy = this.undoStack.pop();\n\n // revert the node back to the previous version\n this.ProjectService.replaceNode(this.nodeId, nodeCopy);\n\n this.node = this.ProjectService.getNodeById(this.nodeId);\n this.components = this.ProjectService.getComponentsByNodeId(this.nodeId);\n this.ProjectService.saveProject();\n }\n\n }\n }\n\n /**\n * Get the removal criteria params for a removal criteria name\n * @param name a removal criteria name e.g. 'isCompleted', 'score', 'branchPathTaken'\n * @return the params for the given removal criteria name\n */\n getRemovalCriteriaParamsByName(name) {\n let params = [];\n if (name != null) {\n for (let singleRemovalCriteria of this.removalCriteria) {\n if (singleRemovalCriteria != null) {\n if (singleRemovalCriteria.value == name) {\n /*\n * we have found the removal criteria we are looking for\n * so we will get its params\n */\n params = singleRemovalCriteria.params;\n break;\n }\n }\n }\n }\n return params;\n }\n\n /**\n * Get the transition criteria params for a transition criteria name\n * @param name a transition criteria name e.g. 'score', 'choiceChosen'\n * @return the params for the given transition criteria name\n */\n getTransitionCriteriaParamsByName(name) {\n let params = [];\n if (name != null) {\n for (let singleTransitionCriteria of this.transitionCriterias) {\n if (singleTransitionCriteria != null &&\n singleTransitionCriteria.value == name) {\n /*\n * we have found the removal criteria we are looking for\n * so we will get its params\n */\n params = singleTransitionCriteria.params;\n break;\n }\n }\n }\n return params;\n }\n\n /**\n * Get the choices of a component\n * @param nodeId the node id\n * @param componentId the component id\n * @return the choices from the component\n */\n getChoicesByNodeIdAndComponentId(nodeId, componentId) {\n return this.ProjectService.getChoicesByNodeIdAndComponentId(nodeId, componentId);\n }\n\n /**\n * Get the choice type of a component\n * @param nodeId the node id\n * @param componentId the component id\n * @return the choice type e.g. 'radio' or 'checkbox'\n */\n getChoiceTypeByNodeIdAndComponentId(nodeId, componentId) {\n let choiceType = null;\n let component = this.ProjectService\n .getComponentByNodeIdAndComponentId(nodeId, componentId);\n if (component != null && component.choiceType != null) {\n choiceType = component.choiceType;\n }\n return choiceType;\n }\n\n /**\n * Get the next available constraint id for a node\n * @param nodeId the node id\n * @return a constraint id that hasn't been used yet\n */\n getNewNodeConstraintId(nodeId) {\n let newNodeConstraintId = null;\n let usedConstraintIds = [];\n let node = this.ProjectService.getNodeById(nodeId);\n if (node != null && node.constraints != null) {\n let nodeConstraints = node.constraints;\n for (let constraint of nodeConstraints) {\n if (constraint != null) {\n let constraintId = constraint.id;\n usedConstraintIds.push(constraintId);\n }\n }\n }\n\n // counter used for finding a constraint id that hasn't been used yet\n let constraintCounter = 1;\n\n // loop until we have found an unused constraint id\n while (newNodeConstraintId == null) {\n // create a potential constraint id\n let potentialNewNodeConstraintId = nodeId + 'Constraint' + constraintCounter;\n\n // check if the constraint id has been used already\n if (usedConstraintIds.indexOf(potentialNewNodeConstraintId) == -1) {\n // the constraint id has not been used so we can use it\n newNodeConstraintId = potentialNewNodeConstraintId;\n } else {\n /*\n * the constraint id has been used so we will increment the\n * counter to try another contraint id\n */\n constraintCounter++;\n }\n }\n return newNodeConstraintId;\n }\n\n /**\n * Add a new constraint.\n * @return The id of the DOM element associated with the constraint.\n */\n addConstraint() {\n // get a new constraint id\n let newNodeConstraintId = this.getNewNodeConstraintId(this.nodeId);\n\n // create the constraint object\n let constraint = {\n \"id\": newNodeConstraintId,\n \"action\": '',\n \"targetId\": this.nodeId,\n \"removalConditional\": 'any',\n \"removalCriteria\": []\n };\n\n // create a removal criteria\n let removalCriteria = {\n \"name\": '',\n \"params\": {}\n };\n\n // add the removal criteria to the constraint\n constraint.removalCriteria.push(removalCriteria);\n\n // create the constraints array if it does not exist\n if (this.node.constraints == null) {\n this.node.constraints = [];\n }\n this.node.constraints.push(constraint);\n this.ProjectService.saveProject();\n\n return newNodeConstraintId;\n }\n\n /**\n * Add a new constraint and then scroll to the bottom of the screen because\n * that's where the new constraint will appear.\n */\n addConstraintAndScrollToBottom() {\n let newNodeConstraintId = this.addConstraint();\n this.$timeout(() => {\n this.$rootScope.$broadcast('scrollToBottom');\n this.UtilService.temporarilyHighlightElement(newNodeConstraintId);\n });\n }\n\n /**\n * Delete a constraint\n * @param constraintIndex delete the constraint at the index\n */\n deleteConstraint(constraintIndex) {\n let answer = confirm(this.$translate('areYouSureYouWantToDeleteThisConstraint'));\n if (answer) {\n if (constraintIndex != null) {\n let node = this.ProjectService.getNodeById(this.nodeId);\n if (node != null) {\n let constraints = node.constraints;\n if (constraints != null) {\n // remove the constraint at the given index\n constraints.splice(constraintIndex, 1);\n }\n }\n }\n this.ProjectService.saveProject();\n }\n }\n\n /**\n * Add a removal criteria\n * @param constraint add the removal criteria to this constraint\n */\n addRemovalCriteria(constraint) {\n if (constraint != null) {\n // create the removal criteria\n let removalCriteria = {\n \"name\": '',\n \"params\": {}\n };\n // add the removal criteria to the constraint\n constraint.removalCriteria.push(removalCriteria);\n }\n this.ProjectService.saveProject();\n }\n\n /**\n * Delete a removal criteria from a constraint\n * @param constraint remove the removal criteria from this constraint\n * @param removalCriteriaIndex the index of the removal criteria to remove\n */\n deleteRemovalCriteria(constraint, removalCriteriaIndex) {\n let answer = confirm(this.$translate('areYouSureYouWantToDeleteThisRemovalCriteria'));\n if (answer) {\n if (constraint != null) {\n // get all the removal criteria\n let removalCriteria = constraint.removalCriteria;\n if (removalCriteria != null) {\n // remove the single removal criteria\n removalCriteria.splice(removalCriteriaIndex, 1);\n }\n }\n this.ProjectService.saveProject();\n }\n }\n\n /**\n * Delete a transition criteria from a transition\n * @param constraint remove the removal criteria from this constraint\n * @param removalCriteriaIndex the index of the removal criteria to remove\n */\n deleteTransitionCriteria(transition, transitionCriteriaIndex) {\n let answer = confirm(this.$translate('areYouSureYouWantToDeleteThisRequirement'));\n if (answer) {\n if (transition != null) {\n // get all the transition criteria\n let transitionCriterias = transition.criteria;\n if (transitionCriterias != null) {\n // remove the single transition criteria\n transitionCriterias.splice(transitionCriteriaIndex, 1);\n }\n }\n this.ProjectService.saveProject();\n }\n }\n\n /**\n * A removal criteria name has changed so we will clear the params so\n * that the params from the previous removal criteria name do not persist\n * TODO refactor too many nesting\n */\n removalCriteriaNameChanged(criteria) {\n if (criteria != null) {\n // clear the params\n criteria.params = {};\n\n // get the params for the given criteria name\n let params = this.getRemovalCriteriaParamsByName(criteria.name);\n if (params != null) {\n for (let paramObject of params) {\n if (paramObject != null) {\n let value = paramObject.value;\n\n // initialize the param value\n criteria.params[value] = '';\n\n if (value == 'nodeId') {\n // default the node id param to this node\n criteria.params[value] = this.nodeId;\n }\n }\n }\n }\n }\n this.authoringViewNodeChanged();\n }\n\n /**\n * A removal criteria name has changed so we will clear the params so\n * that the params from the previous removal criteria name do not persist.\n * @param transitionCriteria the transition criteria object\n */\n transitionCriteriaNameChanged(transitionCriteria) {\n if (transitionCriteria != null) {\n let nodeId = null;\n let componentId = null;\n\n if (transitionCriteria.params != null) {\n // remember the node id and component id\n nodeId = transitionCriteria.params.nodeId;\n componentId = transitionCriteria.params.componentId;\n }\n\n // clear the params\n transitionCriteria.params = {};\n\n if (nodeId != null) {\n // set the node id back into the params\n transitionCriteria.params.nodeId = nodeId;\n }\n\n if (componentId != null) {\n // set the component id back into the params\n transitionCriteria.params.componentId = componentId;\n }\n }\n this.authoringViewNodeChanged();\n }\n\n /**\n * A button to author a specific view of the node was clicked\n * @param view the view name\n */\n nodeAuthoringViewButtonClicked(view) {\n if (view == 'addComponent') {\n // toggle the add component view and hide all the other views\n this.showCreateComponent = !this.showCreateComponent;\n this.showGeneralAdvanced = false;\n this.showEditTransitions = false;\n this.showConstraints = false;\n this.showEditButtons = false;\n this.showRubric = false;\n this.showCreateBranch = false;\n this.showAdvanced = false;\n this.showImportView = false;\n this.showStepButtons = true;\n this.showComponents = true;\n this.showJSON = false;\n } else if (view == 'generalAdvanced') {\n // save and parse the JSON if it has changed\n this.saveAndParseJSON();\n // toggle the edit transitions view and hide all the other views\n this.showCreateComponent = false;\n this.showGeneralAdvanced = !this.showGeneralAdvanced;\n this.showEditTransitions = false;\n this.showConstraints = false;\n this.showEditButtons = false;\n this.showRubricButton = false;\n this.showCreateBranch = false;\n //this.showAdvanced = false;\n this.showImportView = false;\n this.showStepButtons = false;\n this.showComponents = false;\n this.showJSON = false;\n } else if (view == 'editTransitions') {\n // save and parse the JSON if it has changed\n this.saveAndParseJSON();\n // toggle the edit transitions view and hide all the other views\n this.showCreateComponent = false;\n this.showGeneralAdvanced = false;\n this.showEditTransitions = !this.showEditTransitions;\n this.showConstraints = false;\n this.showEditButtons = false;\n this.showRubricButton = false;\n this.showCreateBranch = false;\n //this.showAdvanced = false;\n this.showImportView = false;\n this.showStepButtons = false;\n this.showComponents = false;\n this.showJSON = false;\n } else if (view == 'editConstraints') {\n // save and parse the JSON if it has changed\n this.saveAndParseJSON();\n // toggle the edit constraints view and hide all the other views\n this.showCreateComponent = false;\n this.showGeneralAdvanced = false;\n this.showEditTransitions = false;\n this.showConstraints = !this.showConstraints;\n this.showEditButtons = false;\n this.showRubric = false;\n this.showCreateBranch = false;\n //this.showAdvanced = false;\n this.showImportView = false;\n this.showStepButtons = false;\n this.showComponents = false;\n this.showJSON = false;\n } else if (view == 'editButtons') {\n // toggle the edit buttons view and hide all the other views\n this.showCreateComponent = false;\n this.showGeneralAdvanced = false;\n this.showEditTransitions = false;\n this.showConstraints = false;\n this.showEditButtons = !this.showEditButtons;\n this.showRubric = false;\n this.showCreateBranch = false;\n this.showAdvanced = false;\n this.showImportView = false;\n this.showStepButtons = false;\n this.showJSON = false;\n } else if (view == 'editRubric') {\n // toggle the edit buttons view and hide all the other views\n this.showCreateComponent = false;\n this.showGeneralAdvanced = false;\n this.showEditTransitions = false;\n this.showConstraints = false;\n this.showEditButtons = false;\n this.showRubric = !this.showRubric;\n this.showCreateBranch = false;\n this.showAdvanced = false;\n this.showImportView = false;\n this.showStepButtons = false;\n this.showComponents = false;\n this.showJSON = false;\n } else if (view == 'createBranch') {\n // save and parse the JSON if it has changed\n this.saveAndParseJSON();\n // toggle the edit buttons view and hide all the other views\n this.showCreateComponent = false;\n this.showGeneralAdvanced = false;\n this.showEditTransitions = false;\n this.showConstraints = false;\n this.showEditButtons = false;\n this.showRubric = false;\n this.showCreateBranch = !this.showCreateBranch;\n //this.showAdvanced = false;\n this.showImportView = false;\n this.showStepButtons = false;\n this.showComponents = false;\n this.showJSON = false;\n } else if (view == 'previousNode') {\n // hide all the other views\n this.showCreateComponent = false;\n this.showGeneralAdvanced = false;\n this.showEditTransitions = false;\n this.showConstraints = false;\n this.showEditButtons = false;\n this.showRubric = false;\n this.showCreateBranch = false;\n this.showAdvanced = false;\n this.showImportView = false;\n this.showJSON = false;\n let prevNodeId = this.ProjectService.getPreviousNodeId(this.nodeId);\n if (prevNodeId != null) {\n // there is a previous node id so we will go to it\n this.$state.go('root.project.node', {projectId: this.projectId, nodeId:prevNodeId});\n } else {\n // there is no previous node id so we will display a message\n let thereIsNoPreviousStep = this.$translate('thereIsNoPreviousStep');\n alert(thereIsNoPreviousStep);\n }\n } else if (view == 'nextNode') {\n // hide all the other views\n this.showCreateComponent = false;\n this.showGeneralAdvanced = false;\n this.showEditTransitions = false;\n this.showConstraints = false;\n this.showEditButtons = false;\n this.showRubric = false;\n this.showCreateBranch = false;\n this.showAdvanced = false;\n this.showImportView = false;\n this.showJSON = false;\n let nextNodeId = this.ProjectService.getNextNodeId(this.nodeId);\n if (nextNodeId != null) {\n // there is a next node id so we will go to it\n this.$state.go('root.project.node', {projectId: this.projectId, nodeId:nextNodeId});\n } else {\n // there is no next node id so we will display a message\n let thereIsNoNextStep = this.$translate('thereIsNoNextStep');\n alert(thereIsNoNextStep);\n }\n } else if (view == 'advanced') {\n // toggle the advanced view and hide all the other views\n this.showCreateComponent = false;\n this.showGeneralAdvanced = false;\n this.showEditTransitions = false;\n this.showConstraints = false;\n this.showEditButtons = false;\n this.showRubric = false;\n this.showCreateBranch = false;\n this.showAdvanced = !this.showAdvanced;\n this.showImportView = false;\n this.showStepButtons = false;\n this.showComponents = false;\n this.showJSON = false;\n } else if (view == 'copy') {\n // toggle the copy view and hide all the other views\n this.showCreateComponent = false;\n this.showGeneralAdvanced = false;\n this.showEditTransitions = false;\n this.showConstraints = false;\n this.showEditButtons = false;\n this.showRubric = false;\n this.showCreateBranch = false;\n this.showAdvanced = false;\n this.showImportView = false;\n this.showStepButtons = true;\n this.showComponents = true;\n this.showJSON = false;\n } else if (view == 'move') {\n // toggle the move view and hide all the other views\n this.showCreateComponent = false;\n this.showGeneralAdvanced = false;\n this.showEditTransitions = false;\n this.showConstraints = false;\n this.showEditButtons = false;\n this.showRubric = false;\n this.showCreateBranch = false;\n this.showAdvanced = false;\n this.showImportView = false;\n this.showStepButtons = true;\n this.showComponents = true;\n this.showJSON = false;\n } else if (view == 'import') {\n // toggle the import view and hide all the other views\n this.showCreateComponent = false;\n this.showGeneralAdvanced = false;\n this.showEditTransitions = false;\n this.showConstraints = false;\n this.showEditButtons = false;\n this.showRubric = false;\n this.showCreateBranch = false;\n this.showAdvanced = false;\n this.showImportView = !this.showImportView;\n this.showStepButtons = false;\n this.showComponents = true;\n this.showJSON = false;\n } else if (view == 'showJSON') {\n // save and parse the JSON if it has changed\n this.saveAndParseJSON();\n // toggle the import view and hide all the other views\n this.showCreateComponent = false;\n this.showGeneralAdvanced = false;\n this.showEditTransitions = false;\n this.showConstraints = false;\n this.showEditButtons = false;\n this.showRubric = false;\n this.showCreateBranch = false;\n //this.showAdvanced = false;\n this.showImportView = false;\n this.showStepButtons = false;\n this.showComponents = false;\n this.authoringNodeContentJSONString = angular.toJson(this.node, 4);\n this.showJSON = !this.showJSON;\n } else {\n // hide all the views\n this.showCreateComponent = false;\n this.showGeneralAdvanced = false;\n this.showEditTransitions = false;\n this.showConstraints = false;\n this.showEditButtons = false;\n this.showRubric = false;\n this.showCreateBranch = false;\n this.showAdvanced = false;\n this.showImportView = false;\n this.showStepButtons = true;\n this.showComponents = true;\n this.showJSON = false;\n }\n }\n\n /**\n * The author has changed the number of branch paths\n * TODO refactor long function\n */\n createBranchNumberOfBranchesChanged() {\n if (this.createBranchNumberOfBranches == 0) {\n // the author has set the number of branch paths to 0 which is not allowed\n alert(this.$translate('errorYouCantHave0BranchPaths'));\n\n // revert the number of branch paths value\n this.createBranchNumberOfBranches = this.createBranchBranches.length;\n } else if (this.createBranchNumberOfBranches < this.createBranchBranches.length) {\n /*\n * the author is reducing the number of branches so we want to\n * confirm they want to do so\n */\n let answer = confirm(this.$translate('areYouSureYouWantToReduceTheNumberOfBranchesToX', {createBranchNumberOfBranches:this.createBranchNumberOfBranches}));\n\n if (answer) {\n if (this.createBranchNumberOfBranches == 1) {\n /*\n * the author has removed all the branch paths so we will\n * remove the branch\n */\n this.removeBranch();\n } else {\n /*\n * the author is reducing the number of branch paths but\n * not removing all of them\n */\n for (let bp = 0; bp < this.createBranchBranches.length; bp++) {\n if (bp >= this.createBranchNumberOfBranches) {\n // this is a branch we want to remove\n let branch = this.createBranchBranches[bp];\n this.removeBranchPath(branch);\n\n /*\n * decrement the counter back one because we have\n * just removed a branch path\n */\n bp--;\n }\n }\n }\n } else {\n // they answered no so we will revert the number of branches value\n this.createBranchNumberOfBranches = this.createBranchBranches.length;\n }\n } else if (this.createBranchNumberOfBranches > this.createBranchBranches.length) {\n // the author is increasing the number of branches\n if (this.createBranchCriterion == null) {\n /*\n * we will default the branching to be based on workgroup id\n * since that is what our researchers use most often\n */\n this.createBranchCriterion = 'workgroupId';\n this.createBranchCriterionChanged();\n }\n\n // loop for the number of branches and create new branches objects\n for (let b = 0; b < this.createBranchNumberOfBranches; b++) {\n if (b >= this.createBranchBranches.length) {\n /*\n * we do not have a branch object for this branch number so\n * we will create it\n */\n\n // create the branch object\n let branch = {};\n\n // set the branch number\n branch.number = b + 1;\n\n /*\n * set the mapping of all the ids to order for use when choosing which items are\n * in the branch path\n */\n branch.items = this.UtilService.makeCopyOfJSONObject(this.ProjectService.idToOrder);\n\n // add the branch to the array of branches\n this.createBranchBranches.push(branch);\n\n // create a transition to represent the branch\n let transition = {};\n\n if (this.createBranchCriterion == 'score') {\n // the branch is based on score\n\n // create a score criterion\n let criterion = {\n \"name\": this.createBranchCriterion,\n \"params\": {\n \"scores\": []\n }\n };\n\n if (this.createBranchNodeId != null) {\n // set the node for which to look for the score\n criterion.params.nodeId = this.createBranchNodeId;\n }\n\n if (this.createBranchComponentId != null) {\n // set the component for which to look for the score\n criterion.params.componentId = this.createBranchComponentId;\n }\n\n transition.criteria = [criterion];\n } else if (this.createBranchCriterion == 'choiceChosen') {\n // the branch is based on choice chosen\n let criterion = {};\n criterion.name = this.createBranchCriterion;\n criterion.params = {};\n criterion.params.choiceIds = [];\n\n if (this.createBranchNodeId != null) {\n // set the node for which to look for the score\n criterion.params.nodeId = this.createBranchNodeId;\n }\n\n if (this.createBranchComponentId != null) {\n // set the component for which to look for the score\n criterion.params.componentId = this.createBranchComponentId;\n }\n\n transition.criteria = [criterion];\n } else if (this.createBranchCriterion == 'workgroupId') {\n // workgroup id branching does not require a transition criterion\n } else if (this.createBranchCriterion == 'random') {\n // random branching does not require a transition criterion\n }\n\n // add the transition\n this.node.transitionLogic.transitions.push(transition);\n\n // save a reference to the transition in the branch\n branch.transition = transition;\n }\n }\n }\n this.authoringViewNodeChanged();\n }\n\n /**\n * The branch criterion has changed\n */\n createBranchCriterionChanged() {\n if (this.createBranchCriterion != null) {\n let nodeId = this.node.id;\n if (this.createBranchCriterion == 'workgroupId') {\n // the branch is based on workgroup id\n this.ProjectService.setTransitionLogicField(nodeId, 'howToChooseAmongAvailablePaths', 'workgroupId');\n this.ProjectService.setTransitionLogicField(nodeId, 'whenToChoosePath', 'enterNode');\n this.ProjectService.setTransitionLogicField(nodeId, 'canChangePath', false);\n this.ProjectService.setTransitionLogicField(nodeId, 'maxPathsVisitable', 1);\n } else if (this.createBranchCriterion == 'score') {\n // the branch is based on score\n this.ProjectService.setTransitionLogicField(nodeId, 'howToChooseAmongAvailablePaths', 'random');\n this.ProjectService.setTransitionLogicField(nodeId, 'whenToChoosePath', 'studentDataChanged');\n this.ProjectService.setTransitionLogicField(nodeId, 'canChangePath', false);\n this.ProjectService.setTransitionLogicField(nodeId, 'maxPathsVisitable', 1);\n } else if (this.createBranchCriterion == 'choiceChosen') {\n // the branch is based on choice chosen\n this.ProjectService.setTransitionLogicField(nodeId, 'howToChooseAmongAvailablePaths', 'random');\n this.ProjectService.setTransitionLogicField(nodeId, 'whenToChoosePath', 'studentDataChanged');\n this.ProjectService.setTransitionLogicField(nodeId, 'canChangePath', false);\n this.ProjectService.setTransitionLogicField(nodeId, 'maxPathsVisitable', 1);\n } else if (this.createBranchCriterion == 'random') {\n // the branch is based on random assignment\n this.ProjectService.setTransitionLogicField(nodeId, 'howToChooseAmongAvailablePaths', 'random');\n this.ProjectService.setTransitionLogicField(nodeId, 'whenToChoosePath', 'enterNode');\n this.ProjectService.setTransitionLogicField(nodeId, 'canChangePath', false);\n this.ProjectService.setTransitionLogicField(nodeId, 'maxPathsVisitable', 1);\n }\n }\n\n /*\n * update the transitions so that they have the necessary parameter\n * fields for the given branch criterion\n */\n this.createBranchUpdateTransitions();\n this.authoringViewNodeChanged();\n }\n\n /**\n * The create branch node id has changed\n */\n createBranchNodeIdChanged() {\n this.createBranchComponentId = null;\n let selectedNode = this.ProjectService.getNodeById(this.createBranchNodeId);\n if (selectedNode != null) {\n let components = selectedNode.components;\n if (components != null) {\n if (components.length == 1) {\n /*\n * there is only one component in the node so we will\n * automatically select it in the drop down\n */\n let component = components[0];\n this.createBranchComponentId = component.id;\n }\n }\n }\n\n /*\n * update the transitions so that they have the necessary parameter\n * fields for the given branch criterion\n */\n this.createBranchUpdateTransitions();\n\n // save the project\n this.authoringViewNodeChanged();\n }\n\n /**\n * The create branch component id has changed\n */\n createBranchComponentIdChanged() {\n\n /*\n * update the transitions so that they have the necessary parameter\n * fields for the given branch criterion\n */\n this.createBranchUpdateTransitions();\n\n // save the project\n this.authoringViewNodeChanged();\n }\n\n /**\n * Update the transitions so that they have the necessary parameter\n * fields for the given branch criterion\n */\n createBranchUpdateTransitions() {\n for (let b = 0; b < this.createBranchBranches.length; b++) {\n let branch = this.createBranchBranches[b];\n if (branch != null) {\n // get the transition corresponding to the branch\n let transition = branch.transition;\n if (transition != null) {\n if (this.createBranchCriterion == 'choiceChosen') {\n // we are branching based on choice chosen\n\n // clear the criteria array\n transition.criteria = [];\n\n // create a new choice chosen criterion\n let criterion = {\n \"name\": 'choiceChosen',\n \"params\": {\n \"nodeId\": this.createBranchNodeId,\n \"componentId\": this.createBranchComponentId,\n \"choiceIds\": []\n }\n };\n\n // add the criterion to the array of criteria\n transition.criteria.push(criterion);\n\n /*\n * clear the choice id. we will set the choice id in\n * the branch object when we call createBranchUpdateChoiceChosenIds()\n */\n branch.choiceId = null;\n\n /*\n * clear the scores since we don't need it in choice\n * chosen branching\n */\n branch.scores = null;\n } else if (this.createBranchCriterion == 'score') {\n // we are branching based on score\n\n // clear the criteria array\n transition.criteria = [];\n\n // create a new score criterion\n let criterion = {\n \"name\": 'score',\n \"params\": {\n \"nodeId\": this.createBranchNodeId,\n \"componentId\": this.createBranchComponentId,\n \"scores\": []\n },\n };\n\n // re-use scores if available\n\n // add the criterion to the array of criteria\n transition.criteria.push(criterion);\n\n /*\n * clear the choice id since we don't need it in score\n * branching\n */\n branch.choiceId = null;\n\n // set the scores into the branch object\n branch.scores = criterion.params.scores;\n } else if (this.createBranchCriterion == 'workgroupId') {\n // we are branching based on workgroup id\n\n /*\n * remove the criteria array since it is not used for\n * branching based on workgroup id\n */\n delete transition['criteria'];\n\n // clear the node id and component id\n this.createBranchNodeId = null;\n this.createBranchComponentId = null;\n\n /*\n * clear the choice id and scores fields since we don't\n * need them in workgroup id branching\n */\n branch.choiceId = null;\n branch.scores = null;\n } else if (this.createBranchCriterion == 'random') {\n // we are branching based on random assignment\n\n /*\n * remove the criteria array since it is not used for\n * branching based on random assignment\n */\n delete transition['criteria'];\n\n // clear the node id and component id\n this.createBranchNodeId = null;\n this.createBranchComponentId = null;\n\n /*\n * clear the choice id and scores fields since we don't\n * need them in random branching\n */\n branch.choiceId = null;\n branch.scores = null;\n }\n }\n }\n }\n\n if (this.createBranchCriterion == 'choiceChosen') {\n /*\n * the branching is based on choice chosen so we will populate the\n * choice ids\n */\n this.createBranchUpdateChoiceChosenIds();\n }\n }\n\n /**\n * Automatically populate the selected choices if the branch is based on\n * choice chosen and the selected component is a multiple choice component\n * TODO refactor too many nesting\n */\n createBranchUpdateChoiceChosenIds() {\n let nodeId = this.createBranchNodeId;\n let componentId = this.createBranchComponentId;\n let component = this.ProjectService\n .getComponentByNodeIdAndComponentId(nodeId, componentId);\n if (component != null) {\n if (component.type == 'MultipleChoice') {\n // populate the drop down with the choices\n this.createBranchUpdateChoiceChosenIdsHelper(component);\n }\n }\n }\n\n /**\n * We are creating a branch that is based on which choice the student chooses\n * in a multiple choice component. We will populate the drop down with the\n * choices.\n * @param component we are branching based on the choice chosen in this\n * component\n */\n createBranchUpdateChoiceChosenIdsHelper(component) {\n let nodeId = this.createBranchNodeId;\n let componentId = this.createBranchComponentId;\n\n // get the choices from the component\n let choices = component.choices;\n\n if (choices != null) {\n\n // loop through all the choices\n for (let c = 0; c < choices.length; c++) {\n let choice = choices[c];\n if (choice != null) {\n\n // get the fields of the choice\n let id = choice.id;\n let text = choice.text;\n let feedback = choice.feedback;\n let isCorrect = choice.isCorrect;\n\n // get the branch that corresponds to the choice\n let branch = this.createBranchBranches[c];\n\n if (branch != null) {\n // get the choice for this branch\n branch.choiceId = id;\n\n // make a copy of the choices from the component\n branch.choices = this.UtilService.makeCopyOfJSONObject(choices);\n\n // get the transition corresponding to the branch\n let transition = branch.transition;\n\n if (transition != null) {\n\n /*\n * get the first transition criterion. we will assume\n * there is only one transition criterion\n */\n let criterion = transition.criteria[0];\n\n if (criterion != null) {\n\n // get the params\n let params = criterion.params;\n\n if (params != null) {\n\n // set the node id and component id\n params.nodeId = nodeId;\n params.componentId = componentId;\n\n if (this.createBranchCriterion == 'choiceChosen') {\n // set the choice id\n params.choiceIds = [];\n params.choiceIds.push(id);\n }\n }\n }\n }\n }\n }\n }\n }\n }\n\n /**\n * A step was clicked in the create branch authoring view\n * @param branch the branch path\n * @param item the step that was clicked\n * TODO refactor function too long\n */\n createBranchStepClicked(branch, item) {\n // get all the steps in order\n let orderedItems = this.$filter('orderBy')(this.$filter('toArray')(branch.items), 'order');\n\n // an array that will hold the items that were checked\n branch.checkedItemsInBranchPath = [];\n let checkedItemsInBranchPath = branch.checkedItemsInBranchPath;\n\n // an array that will hold the node ids that were checked\n branch.nodeIdsInBranch = [];\n\n // used to hold the previously checked node id\n let previousCheckedNodeId = null;\n\n // the node id after the node that was clicked\n let nodeIdAfter = null;\n\n /*\n * loop through all the items in order and set the transitions so that\n * the steps in a branch path transition to one after the other\n */\n for (var i = 0; i < orderedItems.length; i++) {\n var orderedItem = orderedItems[i];\n if (orderedItem != null && orderedItem.checked) {\n if (previousCheckedNodeId != null) {\n // make the previous node id point to the current item\n let previousCheckedNode = this.ProjectService.getNodeById(previousCheckedNodeId);\n if (previousCheckedNode != null) {\n // get the transition logic\n let transitionLogic = previousCheckedNode.transitionLogic;\n if (transitionLogic != null) {\n if (transitionLogic.transitions != null) {\n // clear the transitions\n transitionLogic.transitions = [];\n\n // create a new transition object to the current item\n let transition = {\n \"to\": orderedItem.$key\n };\n // add the transition\n transitionLogic.transitions.push(transition);\n }\n }\n }\n }\n\n // add the item to the checked items array\n checkedItemsInBranchPath.push(orderedItem);\n\n // add the node id to the array of node ids in the branch path\n branch.nodeIdsInBranch.push(orderedItem.$key);\n\n // remember the previously checked node id\n previousCheckedNodeId = orderedItem.$key;\n }\n\n // get the previous ordered item (checked or unchecked)\n let previousOrderedItem = orderedItems[i - 1];\n if (previousOrderedItem != null) {\n if (previousOrderedItem.$key == item.$key) {\n /*\n * the previous item was the node that was checked/unchecked\n * so we will remember this item because it is the node\n * that comes after the node that was checked/unchecked\n */\n nodeIdAfter = orderedItem.$key;\n }\n }\n }\n\n if (this.createBranchMergePointNodeId != null) {\n /*\n * the merge point is specified so we will make the last checked\n * node in this branch path point to the merge point\n */\n\n /*\n * this is the last node in the branch path so we will make it\n * transition to the merge point\n */\n let node = this.ProjectService.getNodeById(previousCheckedNodeId);\n if (node != null) {\n let transitionLogic = node.transitionLogic;\n if (transitionLogic != null) {\n if (transitionLogic.transitions != null) {\n // clear the transitions\n transitionLogic.transitions = [];\n\n // make a transition to the merge point\n let transition = {};\n transition.to = this.createBranchMergePointNodeId;\n\n // add the transition\n transitionLogic.transitions.push(transition);\n }\n }\n }\n }\n\n // get the branch number\n let branchNumber = branch.number;\n\n // get the node id that was clicked\n let nodeId = item.$key;\n\n // get the transition that corresponds to the branch\n let transition = this.node.transitionLogic.transitions[branchNumber - 1];\n\n let firstNodeId = null;\n\n /*\n * update the branch point transition in case the first step in the\n * branch path has changed\n */\n if (transition != null) {\n\n if (checkedItemsInBranchPath.length == 0) {\n // there are no steps in the path\n transition.to = null;\n } else {\n // get the first step in the path\n let firstCheckedItem = checkedItemsInBranchPath[0];\n\n if (firstCheckedItem != null) {\n // set the branch point transition to the first step in the path\n firstNodeId = firstCheckedItem.$key;\n transition.to = firstNodeId;\n }\n }\n }\n\n // get the node that was clicked\n let node = this.ProjectService.getNodeById(nodeId);\n\n if (node != null) {\n\n // remove all branch path taken constraints from the node\n this.ProjectService.removeBranchPathTakenNodeConstraints(nodeId);\n\n if (item.checked) {\n // the item was checked so we will add the branch path taken constraints to it\n\n /*\n * the branch path taken constraints will be from this node to\n * the first node in the branch path\n */\n let fromNodeId = this.nodeId;\n let toNodeId = firstNodeId;\n\n // add the branch path taken constraints\n this.ProjectService.addBranchPathTakenConstraints(nodeId, fromNodeId, toNodeId);\n } else {\n /*\n * the item was unchecked so we will change its transition to\n * point to the node that comes right after it\n */\n this.ProjectService.setTransition(nodeId, nodeIdAfter);\n }\n }\n\n /*\n * update the constraints of other steps in the branch path if necessary.\n * loop through all theh checked items in the path\n */\n for (let item of checkedItemsInBranchPath) {\n let itemNodeId = item.$key;\n\n // remove all branch path taken constraints from the node\n this.ProjectService.removeBranchPathTakenNodeConstraints(itemNodeId);\n\n /*\n * the branch path taken constraints will be from this node to\n * the first node in the branch path\n */\n let fromNodeId = this.nodeId;\n let toNodeId = firstNodeId;\n\n // add the branch path taken constraints\n this.ProjectService.addBranchPathTakenConstraints(itemNodeId, fromNodeId, toNodeId);\n }\n\n /*\n * update the node numbers now that a step has been added to a branch path\n * e.g. if this is a branching step that is called\n * 1.5 B View the Potential Energy\n * then the node number is 1.5 B\n */\n this.ProjectService.calculateNodeNumbers();\n this.authoringViewNodeChanged();\n }\n\n /**\n * The score for a path has changed in the branch authoring\n * @param branch the branch for which the score has changed\n * TODO refactor too many nesting\n */\n createBranchScoreChanged(branch) {\n if (branch != null) {\n let transition = branch.transition;\n if (transition != null) {\n let scores = branch.scores;\n if (scores != null) {\n let criteria = transition.criteria;\n if (criteria != null) {\n // get the first criteria. we will assume there is only one criteria\n let criterion = criteria[0];\n if (criterion != null) {\n // get the params of the criterion\n let params = criterion.params;\n if (params != null) {\n // update the scores into the params\n params.scores = scores;\n }\n }\n }\n }\n }\n }\n\n // save the project\n this.authoringViewNodeChanged();\n }\n\n /**\n * The merge point has changed in the branch authoring\n * TODO refactor too many nesting\n */\n createBranchMergePointNodeIdChanged() {\n // get the merge point node id\n let createBranchMergePointNodeId = this.createBranchMergePointNodeId;\n let branches = this.createBranchBranches;\n for (let branch of branches) {\n if (branch != null) {\n // get the node ids in the branch path\n let nodeIdsInBranch = branch.nodeIdsInBranch;\n if (nodeIdsInBranch != null && nodeIdsInBranch.length > 0) {\n // get the last node id in the branch path\n let lastNodeIdInBranchPath = nodeIdsInBranch[nodeIdsInBranch.length - 1];\n if (lastNodeIdInBranchPath != null) {\n // get the last node in the branch path\n let lastNodeInBranchPath =\n this.ProjectService.getNodeById(lastNodeIdInBranchPath);\n if (lastNodeInBranchPath != null) {\n // get the transition logic of the last node\n let transitionLogic = lastNodeInBranchPath.transitionLogic;\n if (transitionLogic != null) {\n if (transitionLogic.transitions != null) {\n // clear the transitions\n transitionLogic.transitions = [];\n\n // make a new transition to the merge point\n let transition = {\n \"to\": createBranchMergePointNodeId\n };\n // add the transition\n transitionLogic.transitions.push(transition);\n }\n }\n }\n }\n }\n }\n }\n\n /*\n * calculate the node numbers\n * e.g. if the step is called\n * 1.5 View the Potential Energy\n * then the node number is 1.5\n */\n this.ProjectService.calculateNodeNumbers();\n\n // save the project\n let parseProject = true;\n this.authoringViewNodeChanged(parseProject);\n }\n\n /**\n * Remove the branch after confirming with the user\n */\n removeBranchButtonClicked() {\n if (confirm(this.$translate('areYouSureYouWantToRemoveTheBranch'))) {\n this.removeBranch();\n }\n }\n\n /**\n * Remove the branch from the step by removing all the branch paths\n */\n removeBranch() {\n for (let bp = 0; bp < this.createBranchBranches.length; bp++) {\n // remove a branch path\n let branchPath = this.createBranchBranches[bp];\n this.removeBranchPath(branchPath);\n\n /*\n * shift the counter back one because we have just removed a branch\n * path\n */\n bp--;\n }\n\n // get the node id of this node (which is the branch point)\n let nodeId = this.node.id;\n\n // get the node id that comes after this node\n let nodeIdAfter = this.ProjectService.getNodeIdAfter(nodeId);\n\n /*\n * update the transition of this step to point to the next step\n * in the project. this may be different than the next step\n * if it was still the branch point.\n */\n this.ProjectService.setTransition(nodeId, nodeIdAfter);\n\n // clear the transition logic fields\n this.ProjectService.setTransitionLogicField(nodeId, 'howToChooseAmongAvailablePaths', null);\n this.ProjectService.setTransitionLogicField(nodeId, 'whenToChoosePath', null);\n this.ProjectService.setTransitionLogicField(nodeId, 'canChangePath', null);\n this.ProjectService.setTransitionLogicField(nodeId, 'maxPathsVisitable', null);\n\n // clear the branch authoring fields\n this.createBranchNumberOfBranches = 1;\n this.createBranchCriterion = null;\n this.createBranchNodeId = null;\n this.createBranchComponentId = null;\n this.createBranchMergePointNodeId = null;\n\n /*\n * branch paths are determined by the transitions. since there is now\n * just one transition, we will create a single branch object to\n * represent it.\n */\n\n // create a branch object to hold all the related information for that branch\n let branch = {};\n\n // set the branch number for display purposes\n branch.number = 1;\n\n /*\n * set the mapping of all the ids to order for use when choosing which items are\n * in the branch path\n */\n branch.items = this.UtilService.makeCopyOfJSONObject(this.ProjectService.idToOrder);\n\n // an array that will hold all the checked items in the branch path\n branch.checkedItemsInBranchPath = [];\n\n let transition = null;\n\n // get the transition from the node\n let transitions = this.ProjectService.getTransitionsByFromNodeId(nodeId);\n\n if (transitions != null && transitions.length > 0) {\n transition = transitions[0];\n }\n\n // set the transition into the branch so we can access it easily later\n branch.transition = transition;\n\n // add the branch to the array of branches\n this.createBranchBranches.push(branch);\n\n /*\n * calculate the node numbers\n * e.g. if the step is called\n * 1.5 View the Potential Energy\n * then the node number is 1.5\n */\n this.ProjectService.calculateNodeNumbers();\n\n // save the project\n let parseProject = true;\n this.authoringViewNodeChanged(parseProject);\n }\n\n /**\n * Remove a branch path by removing all the branch path taken constraints\n * from the steps in the branch path, resetting the transitions in the\n * steps in the branch path, and removing the transition corresponding to\n * the branch path in this branch point node.\n * @param branch the branch object\n */\n removeBranchPath(branch) {\n if (branch != null) {\n // get the checked items in the branch path\n let checkedItemsInBranchPath = branch.checkedItemsInBranchPath;\n if (checkedItemsInBranchPath != null) {\n for (let checkedItem of checkedItemsInBranchPath) {\n if (checkedItem != null) {\n // get the node id of the checked item\n let nodeId = checkedItem.$key;\n\n // remove the branchPathTaken constraints from the step\n this.ProjectService.removeBranchPathTakenNodeConstraints(nodeId);\n\n /*\n * update the transition of the step to point to the next step\n * in the project. this may be different than the next step\n * if it was still in the branch path.\n */\n let nodeIdAfter = this.ProjectService.getNodeIdAfter(nodeId);\n this.ProjectService.setTransition(nodeId, nodeIdAfter);\n }\n }\n }\n // get the index of the branch path\n let branchPathIndex = this.createBranchBranches.indexOf(branch);\n\n // remove the branch path\n this.createBranchBranches.splice(branchPathIndex, 1);\n\n // remove the transition that corresponds to the branch path\n this.node.transitionLogic.transitions.splice(branchPathIndex, 1);\n }\n }\n\n /**\n * The author has changed the step rubric\n */\n summernoteRubricHTMLChanged() {\n // get the summernote rubric html\n let html = this.summernoteRubricHTML;\n\n /*\n * remove the absolute asset paths\n * e.g.\n * \n * will be changed to\n * \n */\n html = this.ConfigService.removeAbsoluteAssetPaths(html);\n\n /*\n * replace and \";\n } else {\n // default to creating a link that represents the wiselink\n newElement = \"\" + linkText + \"\";\n }\n\n if (newElement != null) {\n // replace the wiselink with the new element\n html = html.replace(wiseLinkHTML, newElement);\n }\n\n // find the next match\n wiseLinkRegExMatchResult = wiseLinkRegEx.exec(html);\n }\n return html;\n }\n\n /**\n * Create a custom summernote button that inserts a WISE asset into\n * summernote\n * @param controller the controller that is creating the button\n * e.g. openResponseController\n * @param nodeId the node id of the component that is creating the button\n * @param componentId the component id of the component that is creating the button\n * @param target the target element in the component to insert the asset into\n * e.g. 'prompt' or 'rubricSummernoteId'\n * @param tooltip the tooltip text for the custom button\n * @return custom summernote button\n */\n createInsertAssetButton(controller, projectId, nodeId, componentId, target, tooltip) {\n const thisRootScope = this.$rootScope;\n\n const InsertAssetButton = function(context) {\n const ui = $.summernote.ui;\n\n const button = ui.button({\n contents: '',\n tooltip: tooltip,\n click: function () {\n // remember the position of the cursor\n context.invoke('editor.saveRange');\n\n // create the params for opening the asset chooser\n const params = {};\n params.isPopup = true;\n\n if (projectId != null) {\n params.projectId = projectId;\n }\n\n if (nodeId != null) {\n params.nodeId = nodeId;\n }\n\n if (componentId != null) {\n params.componentId = componentId;\n }\n\n params.target = target;\n\n // display the asset chooser\n thisRootScope.$broadcast('openAssetChooser', params);\n }\n });\n return button.render(); // return button as jquery object\n };\n return InsertAssetButton;\n }\n\n /**\n * Create a custom summernote button that inserts a WISE link into\n * summernote\n * @param controller the controller that is creating the WISE link\n * e.g. openResponseController\n * @param nodeId the node id of the component that is creating the WISE link\n * @param componentId the component id of the component that is creating the WISE link\n * @param target the target element in the component to insert the WISE link into\n * e.g. 'prompt' or 'rubricSummernoteId'\n * @param tooltip the tooltip text for the custom button\n * @return custom summernote button\n */\n createInsertWISELinkButton(controller, projectId, nodeId, componentId, target, tooltip) {\n const thisRootScope = this.$rootScope;\n\n const InsertWISELinkButton = function(context) {\n const ui = $.summernote.ui;\n\n const button = ui.button({\n contents: '',\n tooltip: tooltip,\n click: function () {\n // remember the position of the cursor\n context.invoke('editor.saveRange');\n\n // create the params for opening the WISE Link chooser\n const params = {};\n\n if (projectId != null) {\n params.projectId = projectId;\n }\n\n if (nodeId != null) {\n params.nodeId = nodeId;\n }\n\n if (componentId != null) {\n params.componentId = componentId;\n }\n\n params.target = target;\n\n // display the WISE Link authoring popup\n thisRootScope.$broadcast('openWISELinkChooser', params);\n }\n });\n return button.render(); // return button as jquery object\n };\n return InsertWISELinkButton;\n }\n\n /**\n * Remove html tags from the string. Also remove new lines.\n * @param html an html string\n * @return text without html tags\n */\n removeHTMLTags(html) {\n let text = '';\n if (html != null) {\n // remove tags\n text = html.replace(/<\\/?[^>]+(>|$)/g, \" \");\n text = text.replace(/\\n/g, \" \");\n text = text.replace(/\\r/g, \" \");\n }\n return text;\n }\n\n /**\n * Check if a string ends with a specific string\n * @param subjectString the main string\n * @param searchString the potential end of the string\n * @param position (optional) the position to start searching\n * @return whether the subjectString ends with the searchString\n */\n endsWith(subjectString, searchString, position) {\n if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {\n position = subjectString.length;\n }\n position -= searchString.length;\n const lastIndex = subjectString.lastIndexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n }\n\n /**\n * Sort the objects by server save time\n * @param object1 an object\n * @param object2 an object\n * @return -1 if object1 server save time comes before object2 server save time\n * 1 if object1 server save time comes after object2 server save time\n * 0 if object1 server save time is equal to object2 server save time\n */\n sortByServerSaveTime(object1, object2) {\n if (object1.serverSaveTime < object2.serverSaveTime) {\n return -1;\n } else if (object1.serverSaveTime > object2.serverSaveTime) {\n return 1;\n } else {\n return 0;\n }\n }\n\n /**\n * Convert milliseconds since the epoch to a pretty printed date time\n * @param milliseconds the milliseconds since the epoch\n * @return a string containing the pretty printed date time\n * example\n * Wed Apr 06 2016 9:05:38 AM\n */\n convertMillisecondsToFormattedDateTime(milliseconds) {\n const date = new Date(milliseconds);\n if (date != null) {\n return date.toDateString() + \" \" + date.toLocaleTimeString();\n }\n return \"\";\n }\n\n /**\n * Get the label for the given component type\n * @param componentType string\n * @return string label for the component type\n */\n getComponentTypeLabel(componentType) {\n /*\n * check if we have already obtained the label for this component type\n * before\n */\n let label = this.componentTypeToLabel[componentType];\n\n if (label == null) {\n let componentService = this.$injector.get(componentType + 'Service');\n if (componentService != null && componentService.getComponentTypeLabel != null) {\n label = componentService.getComponentTypeLabel();\n this.componentTypeToLabel[componentType] = label;\n }\n }\n\n if (label == null) {\n /*\n * we were unable to find the label so we will just use the\n * component type as the label\n */\n label = componentType;\n }\n return label;\n }\n\n /**\n * Check if two arrays contain the same values. This is commonly used to\n * check if two arrays of ids contain the same values. The order of the\n * elements is not compared, only the actual values. This means the elements\n * can be in different orders but still contain the same values.\n * Example:\n * array1=['1234567890', 'abcdefghij']\n * array2=['abcdefghij', '1234567890']\n * If these two arrays are passed in as the two arguments, this function\n * will return true.\n * Note: This may only work if the elements are strings, numbers or\n * booleans. If the elements are objects, this function may or may not work.\n * @param array1 an array of strings, numbers, or booleans\n * @param array2 an array of strings, numbers, or booleans\n * @return whether the arrays contain the same values\n */\n arraysContainSameValues(array1, array2) {\n if (array1 != null && array2 != null) {\n const array1Copy = this.makeCopyOfJSONObject(array1);\n array1Copy.sort();\n\n const array2Copy = this.makeCopyOfJSONObject(array2);\n array2Copy.sort();\n\n if (angular.toJson(array1Copy) == angular.toJson(array2Copy)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Whether there are any connected components\n * @param componentContent the component content\n * @return whether there are any connected components\n */\n hasConnectedComponent(componentContent) {\n if (componentContent != null) {\n const connectedComponents = componentContent.connectedComponents;\n if (connectedComponents != null && connectedComponents.length > 0) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @param componentContent The component content.\n * @return Whether there are any connected components with a field we always\n * want to read or write.\n */\n hasConnectedComponentAlwaysField(componentContent) {\n if (componentContent != null) {\n const connectedComponents = componentContent.connectedComponents;\n if (connectedComponents != null && connectedComponents.length > 0) {\n for (let connectedComponent of connectedComponents) {\n if (connectedComponent.fields != null) {\n for (let field of connectedComponent.fields) {\n if (field.when == \"always\") {\n return true;\n }\n }\n }\n }\n }\n }\n return false;\n }\n\n /**\n * Whether this component shows work from a connected component\n * @param componentContent the component content\n * @return whether this component shows work from a connected component\n */\n hasShowWorkConnectedComponent(componentContent) {\n if (componentContent != null) {\n const connectedComponents = componentContent.connectedComponents;\n if (connectedComponents != null) {\n for (let connectedComponent of connectedComponents) {\n if (connectedComponent != null) {\n if (connectedComponent.type == 'showWork') {\n return true;\n }\n }\n }\n }\n }\n return false;\n }\n\n /**\n * Whether this component imports work from a connected component\n * @param componentContent the component content\n * @return whether this component imports work from a connected component\n */\n hasImportWorkConnectedComponent(componentContent) {\n if (componentContent != null) {\n const connectedComponents = componentContent.connectedComponents;\n if (connectedComponents != null) {\n for (let connectedComponent of connectedComponents) {\n if (connectedComponent != null) {\n if (connectedComponent.type == 'importWork') {\n return true;\n }\n }\n }\n }\n }\n return false;\n }\n\n /**\n * Check if an array has any non null elements.\n * @param arrayToCheck An array which may have null and non null elements.\n * @return True if the array has at least one non null element.\n * False if the array has all null elements.\n */\n arrayHasNonNullElement(arrayToCheck) {\n for (let element of arrayToCheck) {\n if (element != null) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Takes a string and breaks it up into multiple lines so that the length of\n * each line does not exceed a certain number of characters. This code was\n * found on stackoverflow.\n * https://stackoverflow.com/questions/14484787/wrap-text-in-javascript\n * @param str The string to break up.\n * @param maxWidth The max width of a line.\n * @return A string that has been broken up into multiple lines using \\n.\n */\n wordWrap(str, maxWidth) {\n if (str.length <= maxWidth) {\n return str;\n }\n let newLineStr = \"\\n\";\n let done = false;\n let res = '';\n do {\n let found = false;\n // Inserts new line at first whitespace of the line\n for (let i = maxWidth - 1; i >= 0; i--) {\n if (this.testWhite(str.charAt(i))) {\n res = res + [str.slice(0, i), newLineStr].join('');\n str = str.slice(i + 1);\n found = true;\n break;\n }\n }\n // Inserts new line at maxWidth position, the word is too long to wrap\n if (!found) {\n res += [str.slice(0, maxWidth), newLineStr].join('');\n str = str.slice(maxWidth);\n }\n\n if (str.length < maxWidth)\n done = true;\n } while (!done);\n\n return res + str;\n }\n\n /**\n * Helper function for wordWrap().\n * @param x A single character string.\n * @return Whether the single character is a whitespace character.\n */\n testWhite(x) {\n let white = new RegExp(/^\\s$/);\n return white.test(x.charAt(0));\n };\n\n /**\n * Get the number of words in the string.\n * @param str The string.\n * @return The number of words in the string.\n */\n wordCount(str) {\n return str.trim().split(/\\s+/).length;\n }\n\n /**\n * Check if there is a 'nodeEntered' event in the array of events.\n * @param events An array of events.\n * @return Whether there is a 'nodeEntered' event in the array of events.\n */\n hasNodeEnteredEvent(events) {\n for (let event of events) {\n if (event.event == 'nodeEntered') {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Determine whether the component has been authored to import work.\n * @param componentContent The component content.\n * @return Whether to import work in this component.\n */\n hasImportWorkConnectedComponent(componentContent) {\n return this.hasXConnectedComponent(componentContent, 'importWork');\n }\n\n /**\n * Determine whether the component has been authored to show work.\n * @param componentContent The component content.\n * @return Whether to show work in this component.\n */\n hasShowWorkConnectedComponent(componentContent) {\n return this.hasXConnectedComponent(componentContent, 'showWork');\n }\n\n /**\n * Determine whether the component has been authored to show classmate work.\n * @param componentContent The component content.\n * @return Whether to show classmate work in this component.\n */\n hasShowClassmateWorkConnectedComponent(componentContent) {\n return this.hasXConnectedComponent(componentContent, 'showClassmateWork');\n }\n\n /**\n * Determine whether the component has a connected component of the given type.\n * @param componentContent The component content.\n * @param connectedComponentType The connected component type.\n * @return Whether the component has a connected component of the given type.\n */\n hasXConnectedComponent(componentContent, connectedComponentType) {\n if (componentContent.connectedComponents != null) {\n let connectedComponents = componentContent.connectedComponents;\n // loop through all the connected components\n for (let connectedComponent of connectedComponents) {\n if (connectedComponent.type == connectedComponentType) {\n // the connected component is the type we're looking for\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * Temporarily highlight an element in the DOM.\n * @param id The id of the element.\n * @param duration The number of milliseconds to keep the element highlighted.\n */\n temporarilyHighlightElement(id, duration = 1000) {\n let element = $('#' + id);\n let originalBackgroundColor = element.css('backgroundColor');\n element.css('background-color', '#FFFF9C');\n\n /*\n * Use a timeout before starting to transition back to\n * the original background color. For some reason the\n * element won't get highlighted in the first place\n * unless this timeout is used.\n */\n this.$timeout(() => {\n // slowly fade back to the original background color\n element.css({\n 'transition': 'background-color 2s ease-in-out',\n 'background-color': originalBackgroundColor\n });\n\n /*\n * remove these styling fields after we perform\n * the fade otherwise the regular mouseover\n * background color change will not work\n */\n this.$timeout(() => {\n element.css({\n 'transition': '',\n 'background-color': ''\n });\n }, 2000);\n }, duration);\n }\n\n /**\n * Render the component state and then generate an image from it.\n * @param componentState The component state to render.\n * @return A promise that will return an image.\n */\n generateImageFromComponentState(componentState) {\n let deferred = this.$q.defer();\n this.$mdDialog.show({\n template: `\n
\n
\n {{ \"importingWork\" | translate }}...\n
\n
\n \n
\n \n `,\n locals: {\n nodeId: componentState.nodeId,\n componentId: componentState.componentId,\n componentState: componentState\n },\n controller: DialogController\n });\n function DialogController($scope, $mdDialog, nodeId, componentId, componentState) {\n $scope.nodeId = nodeId;\n $scope.componentId = componentId;\n $scope.componentState = componentState;\n $scope.closeDialog = function() {\n $mdDialog.hide();\n }\n }\n DialogController.$inject = ['$scope', '$mdDialog', 'nodeId', 'componentId', 'componentState'];\n // wait for the component in the dialog to finish rendering\n let doneRenderingComponentListener = this.$rootScope.$on('doneRenderingComponent', (event, args) => {\n if (componentState.nodeId == args.nodeId && componentState.componentId == args.componentId) {\n this.$timeout(() => {\n this.generateImageFromComponentStateHelper(componentState).then((image) => {\n /*\n * Destroy the listener otherwise this block of code will be called every time\n * doneRenderingComponent is fired in the future.\n */\n doneRenderingComponentListener();\n this.$timeout.cancel(destroyDoneRenderingComponentListenerTimeout);\n deferred.resolve(image);\n });\n }, 1000);\n }\n });\n /*\n * Set a timeout to destroy the listener in case there is an error creating the image and\n * we don't get to destroying it above.\n */\n let destroyDoneRenderingComponentListenerTimeout = this.$timeout(() => {\n // destroy the listener\n doneRenderingComponentListener();\n }, 10000);\n return deferred.promise;\n }\n\n /**\n * The component state has been rendered in the DOM and now we want to create an image\n * from it.\n * @param componentState The component state that has been rendered.\n * @return A promise that will return an image.\n */\n generateImageFromComponentStateHelper(componentState) {\n let deferred = this.$q.defer();\n let componentService = this.$injector.get(componentState.componentType + 'Service');\n componentService.generateImageFromRenderedComponentState(componentState).then((image) => {\n deferred.resolve(image);\n this.$mdDialog.hide();\n });\n return deferred.promise;\n }\n\n /**\n * Get the connected component associated with the component state.\n * @param componentContent The component content.\n * @param componentState The component state.\n * @return A connected component object or null.\n */\n getConnectedComponentByComponentState(componentContent, componentState) {\n let nodeId = componentState.nodeId;\n let componentId = componentState.componentId;\n let connectedComponents = componentContent.connectedComponents;\n for (let connectedComponent of connectedComponents) {\n if (connectedComponent.nodeId == nodeId && connectedComponent.componentId == componentId) {\n return connectedComponent;\n }\n }\n return null;\n }\n}\n\n// Get the last element of the array\nif (!Array.prototype.last) {\n Array.prototype.last = function() {\n return this[this.length - 1];\n };\n}\n\nUtilService.$inject = [\n '$filter',\n '$injector',\n '$mdDialog',\n '$q',\n '$rootScope',\n '$timeout'\n];\n\nexport default UtilService;\n"]} \ No newline at end of file +{"version":3,"sources":["utilService.es6"],"names":["UtilService","$filter","$injector","$mdDialog","$q","$rootScope","$timeout","componentTypeToLabel","$translate","length","CHARS","key","a","Math","floor","random","str","isNaN","Number","jsonObject","jsonObjectString","angular","toJson","fromJson","img_b64","blob","dataURItoBlob","now","Date","getTime","filename","encodeURIComponent","pngFile","File","lastModified","type","dataURI","byteString","split","indexOf","atob","unescape","mimeString","ia","Uint8Array","i","charCodeAt","Blob","imageElement","imageObject","canvas","document","createElement","width","naturalWidth","height","naturalHeight","ctx","getContext","drawImage","dataURL","toDataURL","getImageObjectFromBase64String","fileName","imageExtensionsRegEx","RegExp","lowerCaseFileName","toLowerCase","matchResult","match","videoExtensionsRegEx","html","insertWISELinkAnchors","insertWISELinkButtons","wiseLinkRegEx","wiseLinkRegExMatchResult","exec","anchorHTML","anchorText","nodeId","getWISELinkNodeId","componentIdAttr","componentId","getWISELinkComponentId","wiselinkHtml","replace","buttonHTML","buttonText","nodeIdRegEx","nodeIdRegExResult","componentIdRegEx","componentIdRegExResult","typeRegEx","typeRegExResult","linkTextRegEx","linkTextRegExResult","replaceWISELinksHelper","regex","wiseLinkHTML","componentHTML","getWISELinkType","linkText","getWISELinkLinkText","newElement","controller","projectId","target","tooltip","thisRootScope","InsertAssetButton","context","ui","$","summernote","button","contents","click","invoke","params","isPopup","$broadcast","render","InsertWISELinkButton","text","subjectString","searchString","position","isFinite","lastIndex","lastIndexOf","object1","object2","serverSaveTime","milliseconds","date","toDateString","toLocaleTimeString","componentType","label","componentService","get","getComponentTypeLabel","array1","array2","array1Copy","makeCopyOfJSONObject","sort","array2Copy","componentContent","connectedComponents","connectedComponent","fields","field","when","arrayToCheck","element","maxWidth","newLineStr","done","res","found","testWhite","charAt","slice","join","x","white","test","trim","events","event","hasXConnectedComponent","connectedComponentType","id","duration","originalBackgroundColor","css","componentState","deferred","defer","show","template","locals","DialogController","$scope","closeDialog","hide","$inject","doneRenderingComponentListener","$on","args","generateImageFromComponentStateHelper","then","image","cancel","destroyDoneRenderingComponentListenerTimeout","resolve","promise","generateImageFromRenderedComponentState","setIsJSONValidMessage","isJSONValid","Array","prototype","last"],"mappings":"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","file":"utilService.js","sourcesContent":["'use strict';\n\nclass UtilService {\n constructor(\n $filter,\n $injector,\n $mdDialog,\n $q,\n $rootScope,\n $timeout) {\n this.$filter = $filter;\n this.$injector = $injector;\n this.$mdDialog = $mdDialog;\n this.$q = $q;\n this.$rootScope = $rootScope;\n this.$timeout = $timeout;\n this.componentTypeToLabel = {};\n this.$translate = this.$filter('translate');\n }\n\n /**\n * Generates and returns a random key of the given length if\n * specified. If length is not specified, returns a key 10\n * characters in length.\n */\n generateKey(length) {\n this.CHARS = [\"a\",\"b\",\"c\",\"d\",\"e\",\"f\",\"g\",\"h\",\"i\",\"j\",\"k\",\"l\",\"m\",\n \"n\",\"o\",\"p\",\"q\",\"r\", \"s\",\"t\",\"u\",\"v\",\"w\",\"x\",\"y\",\"z\",\n \"0\",\"1\",\"2\",\"3\",\"4\",\"5\",\"6\",\"7\",\"8\",\"9\"];\n\n if (!length) {\n length = 10;\n }\n\n let key = '';\n for (let a = 0; a < length; a++) {\n key += this.CHARS[Math.floor(Math.random() * (this.CHARS.length - 1))];\n }\n\n return key;\n };\n\n /**\n * Try to convert a string to a number\n * @param str the string to convert\n * @returns a number if we were able to convert the string to a number.\n * if we couldn't convert the string to a number we will just return the string.\n */\n convertStringToNumber(str) {\n if (str != null && str != '' && !isNaN(Number(str))) {\n return Number(str);\n }\n return str;\n };\n\n /**\n * Create a copy of a JSON object\n * @param jsonObject the JSON object to get a copy of\n * @return a copy of the JSON object that was passed in\n */\n makeCopyOfJSONObject(jsonObject) {\n if (jsonObject != null) {\n const jsonObjectString = angular.toJson(jsonObject);\n return angular.fromJson(jsonObjectString);\n }\n return null;\n };\n\n /**\n * Get the image object\n * @params img_b64 the base64 image string\n * @returns an image object\n */\n getImageObjectFromBase64String(img_b64) {\n // create a blob from the base64 image string\n const blob = this.dataURItoBlob(img_b64);\n\n const now = new Date().getTime();\n const filename = encodeURIComponent('picture_' + now + '.png');\n const pngFile = new File([blob], filename, {\n lastModified: now, // optional - default = now\n type: 'image/png' // optional - default = ''\n });\n return pngFile;\n }\n\n /**\n * Convert base64/URLEncoded data component to raw binary data held in a string\n * @param dataURI base64/URLEncoded data\n * @returns a Blob object\n */\n dataURItoBlob(dataURI) {\n let byteString;\n if (dataURI.split(',')[0].indexOf('base64') >= 0)\n byteString = atob(dataURI.split(',')[1]);\n else\n byteString = unescape(dataURI.split(',')[1]);\n\n // separate out the mime component\n const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];\n\n // write the bytes of the string to a typed array\n const ia = new Uint8Array(byteString.length);\n for (let i = 0; i < byteString.length; i++) {\n ia[i] = byteString.charCodeAt(i);\n }\n return new Blob([ia], {type:mimeString});\n };\n\n /**\n * Get an image object from an image element\n * @param imageElement an image element ()\n * @returns an image object\n */\n getImageObjectFromImageElement(imageElement) {\n let imageObject = null;\n if (imageElement != null) {\n // create a canvas element that we will use to generate a base64 string\n const canvas = document.createElement(\"canvas\");\n\n // set the width and height of the canvas to match the image dimensions\n canvas.width = imageElement.naturalWidth;\n canvas.height = imageElement.naturalHeight;\n\n // draw the image onto the canvas\n const ctx = canvas.getContext(\"2d\");\n ctx.drawImage(imageElement, 0, 0);\n\n const dataURL = canvas.toDataURL(\"image/png\");\n imageObject = this.getImageObjectFromBase64String(dataURL);\n }\n return imageObject;\n }\n\n /**\n * Check if the asset is an image\n * @param fileName the file name of the asset\n * @return whether the asset is an image or not\n */\n isImage(fileName) {\n if (fileName != null) {\n const imageExtensionsRegEx =\n new RegExp('.*\\.(png|jpg|jpeg|bmp|gif|tiff|svg)');\n const lowerCaseFileName = fileName.toLowerCase();\n const matchResult = lowerCaseFileName.match(imageExtensionsRegEx);\n\n if (matchResult != null) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Check if the asset is a video\n * @param fileName the file name of the asset\n * @return whether the asset is a video or not\n */\n isVideo(fileName) {\n if (fileName != null) {\n const videoExtensionsRegEx =\n new RegExp('.*\\.(mp4|mpg|mpeg|m4v|m2v|avi|gifv|mov|qt)');\n const lowerCaseFileName = fileName.toLowerCase();\n const matchResult = lowerCaseFileName.match(videoExtensionsRegEx);\n\n if (matchResult != null) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Replace and \";\n } else {\n // default to creating a link that represents the wiselink\n newElement = \"\" + linkText + \"\";\n }\n\n if (newElement != null) {\n // replace the wiselink with the new element\n html = html.replace(wiseLinkHTML, newElement);\n }\n\n // find the next match\n wiseLinkRegExMatchResult = wiseLinkRegEx.exec(html);\n }\n return html;\n }\n\n /**\n * Create a custom summernote button that inserts a WISE asset into\n * summernote\n * @param controller the controller that is creating the button\n * e.g. openResponseController\n * @param nodeId the node id of the component that is creating the button\n * @param componentId the component id of the component that is creating the button\n * @param target the target element in the component to insert the asset into\n * e.g. 'prompt' or 'rubricSummernoteId'\n * @param tooltip the tooltip text for the custom button\n * @return custom summernote button\n */\n createInsertAssetButton(controller, projectId, nodeId, componentId, target, tooltip) {\n const thisRootScope = this.$rootScope;\n\n const InsertAssetButton = function(context) {\n const ui = $.summernote.ui;\n\n const button = ui.button({\n contents: '',\n tooltip: tooltip,\n click: function () {\n // remember the position of the cursor\n context.invoke('editor.saveRange');\n\n // create the params for opening the asset chooser\n const params = {};\n params.isPopup = true;\n\n if (projectId != null) {\n params.projectId = projectId;\n }\n\n if (nodeId != null) {\n params.nodeId = nodeId;\n }\n\n if (componentId != null) {\n params.componentId = componentId;\n }\n\n params.target = target;\n\n // display the asset chooser\n thisRootScope.$broadcast('openAssetChooser', params);\n }\n });\n return button.render(); // return button as jquery object\n };\n return InsertAssetButton;\n }\n\n /**\n * Create a custom summernote button that inserts a WISE link into\n * summernote\n * @param controller the controller that is creating the WISE link\n * e.g. openResponseController\n * @param nodeId the node id of the component that is creating the WISE link\n * @param componentId the component id of the component that is creating the WISE link\n * @param target the target element in the component to insert the WISE link into\n * e.g. 'prompt' or 'rubricSummernoteId'\n * @param tooltip the tooltip text for the custom button\n * @return custom summernote button\n */\n createInsertWISELinkButton(controller, projectId, nodeId, componentId, target, tooltip) {\n const thisRootScope = this.$rootScope;\n\n const InsertWISELinkButton = function(context) {\n const ui = $.summernote.ui;\n\n const button = ui.button({\n contents: '',\n tooltip: tooltip,\n click: function () {\n // remember the position of the cursor\n context.invoke('editor.saveRange');\n\n // create the params for opening the WISE Link chooser\n const params = {};\n\n if (projectId != null) {\n params.projectId = projectId;\n }\n\n if (nodeId != null) {\n params.nodeId = nodeId;\n }\n\n if (componentId != null) {\n params.componentId = componentId;\n }\n\n params.target = target;\n\n // display the WISE Link authoring popup\n thisRootScope.$broadcast('openWISELinkChooser', params);\n }\n });\n return button.render(); // return button as jquery object\n };\n return InsertWISELinkButton;\n }\n\n /**\n * Remove html tags from the string. Also remove new lines.\n * @param html an html string\n * @return text without html tags\n */\n removeHTMLTags(html) {\n let text = '';\n if (html != null) {\n // remove tags\n text = html.replace(/<\\/?[^>]+(>|$)/g, \" \");\n text = text.replace(/\\n/g, \" \");\n text = text.replace(/\\r/g, \" \");\n }\n return text;\n }\n\n /**\n * Check if a string ends with a specific string\n * @param subjectString the main string\n * @param searchString the potential end of the string\n * @param position (optional) the position to start searching\n * @return whether the subjectString ends with the searchString\n */\n endsWith(subjectString, searchString, position) {\n if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {\n position = subjectString.length;\n }\n position -= searchString.length;\n const lastIndex = subjectString.lastIndexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n }\n\n /**\n * Sort the objects by server save time\n * @param object1 an object\n * @param object2 an object\n * @return -1 if object1 server save time comes before object2 server save time\n * 1 if object1 server save time comes after object2 server save time\n * 0 if object1 server save time is equal to object2 server save time\n */\n sortByServerSaveTime(object1, object2) {\n if (object1.serverSaveTime < object2.serverSaveTime) {\n return -1;\n } else if (object1.serverSaveTime > object2.serverSaveTime) {\n return 1;\n } else {\n return 0;\n }\n }\n\n /**\n * Convert milliseconds since the epoch to a pretty printed date time\n * @param milliseconds the milliseconds since the epoch\n * @return a string containing the pretty printed date time\n * example\n * Wed Apr 06 2016 9:05:38 AM\n */\n convertMillisecondsToFormattedDateTime(milliseconds) {\n const date = new Date(milliseconds);\n if (date != null) {\n return date.toDateString() + \" \" + date.toLocaleTimeString();\n }\n return \"\";\n }\n\n /**\n * Get the label for the given component type\n * @param componentType string\n * @return string label for the component type\n */\n getComponentTypeLabel(componentType) {\n /*\n * check if we have already obtained the label for this component type\n * before\n */\n let label = this.componentTypeToLabel[componentType];\n\n if (label == null) {\n let componentService = this.$injector.get(componentType + 'Service');\n if (componentService != null && componentService.getComponentTypeLabel != null) {\n label = componentService.getComponentTypeLabel();\n this.componentTypeToLabel[componentType] = label;\n }\n }\n\n if (label == null) {\n /*\n * we were unable to find the label so we will just use the\n * component type as the label\n */\n label = componentType;\n }\n return label;\n }\n\n /**\n * Check if two arrays contain the same values. This is commonly used to\n * check if two arrays of ids contain the same values. The order of the\n * elements is not compared, only the actual values. This means the elements\n * can be in different orders but still contain the same values.\n * Example:\n * array1=['1234567890', 'abcdefghij']\n * array2=['abcdefghij', '1234567890']\n * If these two arrays are passed in as the two arguments, this function\n * will return true.\n * Note: This may only work if the elements are strings, numbers or\n * booleans. If the elements are objects, this function may or may not work.\n * @param array1 an array of strings, numbers, or booleans\n * @param array2 an array of strings, numbers, or booleans\n * @return whether the arrays contain the same values\n */\n arraysContainSameValues(array1, array2) {\n if (array1 != null && array2 != null) {\n const array1Copy = this.makeCopyOfJSONObject(array1);\n array1Copy.sort();\n\n const array2Copy = this.makeCopyOfJSONObject(array2);\n array2Copy.sort();\n\n if (angular.toJson(array1Copy) == angular.toJson(array2Copy)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Whether there are any connected components\n * @param componentContent the component content\n * @return whether there are any connected components\n */\n hasConnectedComponent(componentContent) {\n if (componentContent != null) {\n const connectedComponents = componentContent.connectedComponents;\n if (connectedComponents != null && connectedComponents.length > 0) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @param componentContent The component content.\n * @return Whether there are any connected components with a field we always\n * want to read or write.\n */\n hasConnectedComponentAlwaysField(componentContent) {\n if (componentContent != null) {\n const connectedComponents = componentContent.connectedComponents;\n if (connectedComponents != null && connectedComponents.length > 0) {\n for (let connectedComponent of connectedComponents) {\n if (connectedComponent.fields != null) {\n for (let field of connectedComponent.fields) {\n if (field.when == \"always\") {\n return true;\n }\n }\n }\n }\n }\n }\n return false;\n }\n\n /**\n * Whether this component shows work from a connected component\n * @param componentContent the component content\n * @return whether this component shows work from a connected component\n */\n hasShowWorkConnectedComponent(componentContent) {\n if (componentContent != null) {\n const connectedComponents = componentContent.connectedComponents;\n if (connectedComponents != null) {\n for (let connectedComponent of connectedComponents) {\n if (connectedComponent != null) {\n if (connectedComponent.type == 'showWork') {\n return true;\n }\n }\n }\n }\n }\n return false;\n }\n\n /**\n * Whether this component imports work from a connected component\n * @param componentContent the component content\n * @return whether this component imports work from a connected component\n */\n hasImportWorkConnectedComponent(componentContent) {\n if (componentContent != null) {\n const connectedComponents = componentContent.connectedComponents;\n if (connectedComponents != null) {\n for (let connectedComponent of connectedComponents) {\n if (connectedComponent != null) {\n if (connectedComponent.type == 'importWork') {\n return true;\n }\n }\n }\n }\n }\n return false;\n }\n\n /**\n * Check if an array has any non null elements.\n * @param arrayToCheck An array which may have null and non null elements.\n * @return True if the array has at least one non null element.\n * False if the array has all null elements.\n */\n arrayHasNonNullElement(arrayToCheck) {\n for (let element of arrayToCheck) {\n if (element != null) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Takes a string and breaks it up into multiple lines so that the length of\n * each line does not exceed a certain number of characters. This code was\n * found on stackoverflow.\n * https://stackoverflow.com/questions/14484787/wrap-text-in-javascript\n * @param str The string to break up.\n * @param maxWidth The max width of a line.\n * @return A string that has been broken up into multiple lines using \\n.\n */\n wordWrap(str, maxWidth) {\n if (str.length <= maxWidth) {\n return str;\n }\n let newLineStr = \"\\n\";\n let done = false;\n let res = '';\n do {\n let found = false;\n // Inserts new line at first whitespace of the line\n for (let i = maxWidth - 1; i >= 0; i--) {\n if (this.testWhite(str.charAt(i))) {\n res = res + [str.slice(0, i), newLineStr].join('');\n str = str.slice(i + 1);\n found = true;\n break;\n }\n }\n // Inserts new line at maxWidth position, the word is too long to wrap\n if (!found) {\n res += [str.slice(0, maxWidth), newLineStr].join('');\n str = str.slice(maxWidth);\n }\n\n if (str.length < maxWidth)\n done = true;\n } while (!done);\n\n return res + str;\n }\n\n /**\n * Helper function for wordWrap().\n * @param x A single character string.\n * @return Whether the single character is a whitespace character.\n */\n testWhite(x) {\n let white = new RegExp(/^\\s$/);\n return white.test(x.charAt(0));\n };\n\n /**\n * Get the number of words in the string.\n * @param str The string.\n * @return The number of words in the string.\n */\n wordCount(str) {\n return str.trim().split(/\\s+/).length;\n }\n\n /**\n * Check if there is a 'nodeEntered' event in the array of events.\n * @param events An array of events.\n * @return Whether there is a 'nodeEntered' event in the array of events.\n */\n hasNodeEnteredEvent(events) {\n for (let event of events) {\n if (event.event == 'nodeEntered') {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Determine whether the component has been authored to import work.\n * @param componentContent The component content.\n * @return Whether to import work in this component.\n */\n hasImportWorkConnectedComponent(componentContent) {\n return this.hasXConnectedComponent(componentContent, 'importWork');\n }\n\n /**\n * Determine whether the component has been authored to show work.\n * @param componentContent The component content.\n * @return Whether to show work in this component.\n */\n hasShowWorkConnectedComponent(componentContent) {\n return this.hasXConnectedComponent(componentContent, 'showWork');\n }\n\n /**\n * Determine whether the component has been authored to show classmate work.\n * @param componentContent The component content.\n * @return Whether to show classmate work in this component.\n */\n hasShowClassmateWorkConnectedComponent(componentContent) {\n return this.hasXConnectedComponent(componentContent, 'showClassmateWork');\n }\n\n /**\n * Determine whether the component has a connected component of the given type.\n * @param componentContent The component content.\n * @param connectedComponentType The connected component type.\n * @return Whether the component has a connected component of the given type.\n */\n hasXConnectedComponent(componentContent, connectedComponentType) {\n if (componentContent.connectedComponents != null) {\n let connectedComponents = componentContent.connectedComponents;\n // loop through all the connected components\n for (let connectedComponent of connectedComponents) {\n if (connectedComponent.type == connectedComponentType) {\n // the connected component is the type we're looking for\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * Temporarily highlight an element in the DOM.\n * @param id The id of the element.\n * @param duration The number of milliseconds to keep the element highlighted.\n */\n temporarilyHighlightElement(id, duration = 1000) {\n let element = $('#' + id);\n let originalBackgroundColor = element.css('backgroundColor');\n element.css('background-color', '#FFFF9C');\n\n /*\n * Use a timeout before starting to transition back to\n * the original background color. For some reason the\n * element won't get highlighted in the first place\n * unless this timeout is used.\n */\n this.$timeout(() => {\n // slowly fade back to the original background color\n element.css({\n 'transition': 'background-color 2s ease-in-out',\n 'background-color': originalBackgroundColor\n });\n\n /*\n * remove these styling fields after we perform\n * the fade otherwise the regular mouseover\n * background color change will not work\n */\n this.$timeout(() => {\n element.css({\n 'transition': '',\n 'background-color': ''\n });\n }, 2000);\n }, duration);\n }\n\n /**\n * Render the component state and then generate an image from it.\n * @param componentState The component state to render.\n * @return A promise that will return an image.\n */\n generateImageFromComponentState(componentState) {\n let deferred = this.$q.defer();\n this.$mdDialog.show({\n template: `\n
\n
\n {{ \"importingWork\" | translate }}...\n
\n
\n \n
\n \n `,\n locals: {\n nodeId: componentState.nodeId,\n componentId: componentState.componentId,\n componentState: componentState\n },\n controller: DialogController\n });\n function DialogController($scope, $mdDialog, nodeId, componentId, componentState) {\n $scope.nodeId = nodeId;\n $scope.componentId = componentId;\n $scope.componentState = componentState;\n $scope.closeDialog = function() {\n $mdDialog.hide();\n }\n }\n DialogController.$inject = ['$scope', '$mdDialog', 'nodeId', 'componentId', 'componentState'];\n // wait for the component in the dialog to finish rendering\n let doneRenderingComponentListener = this.$rootScope.$on('doneRenderingComponent', (event, args) => {\n if (componentState.nodeId == args.nodeId && componentState.componentId == args.componentId) {\n this.$timeout(() => {\n this.generateImageFromComponentStateHelper(componentState).then((image) => {\n /*\n * Destroy the listener otherwise this block of code will be called every time\n * doneRenderingComponent is fired in the future.\n */\n doneRenderingComponentListener();\n this.$timeout.cancel(destroyDoneRenderingComponentListenerTimeout);\n deferred.resolve(image);\n });\n }, 1000);\n }\n });\n /*\n * Set a timeout to destroy the listener in case there is an error creating the image and\n * we don't get to destroying it above.\n */\n let destroyDoneRenderingComponentListenerTimeout = this.$timeout(() => {\n // destroy the listener\n doneRenderingComponentListener();\n }, 10000);\n return deferred.promise;\n }\n\n /**\n * The component state has been rendered in the DOM and now we want to create an image\n * from it.\n * @param componentState The component state that has been rendered.\n * @return A promise that will return an image.\n */\n generateImageFromComponentStateHelper(componentState) {\n let deferred = this.$q.defer();\n let componentService = this.$injector.get(componentState.componentType + 'Service');\n componentService.generateImageFromRenderedComponentState(componentState).then((image) => {\n deferred.resolve(image);\n this.$mdDialog.hide();\n });\n return deferred.promise;\n }\n\n /**\n * Get the connected component associated with the component state.\n * @param componentContent The component content.\n * @param componentState The component state.\n * @return A connected component object or null.\n */\n getConnectedComponentByComponentState(componentContent, componentState) {\n let nodeId = componentState.nodeId;\n let componentId = componentState.componentId;\n let connectedComponents = componentContent.connectedComponents;\n for (let connectedComponent of connectedComponents) {\n if (connectedComponent.nodeId == nodeId && connectedComponent.componentId == componentId) {\n return connectedComponent;\n }\n }\n return null;\n }\n\n showJSONValidMessage() {\n this.setIsJSONValidMessage(true);\n }\n\n showJSONInvalidMessage() {\n this.setIsJSONValidMessage(false);\n }\n\n hideJSONValidMessage() {\n this.setIsJSONValidMessage(null);\n }\n\n /**\n * Show the message in the toolbar that says \"JSON Valid\" or \"JSON Invalid\".\n * @param isJSONValid\n * true if we want to show \"JSON Valid\"\n * false if we want to show \"JSON Invalid\"\n * null if we don't want to show anything\n */\n setIsJSONValidMessage(isJSONValid) {\n this.$rootScope.$broadcast('setIsJSONValid', { isJSONValid: isJSONValid });\n }\n}\n\n// Get the last element of the array\nif (!Array.prototype.last) {\n Array.prototype.last = function() {\n return this[this.length - 1];\n };\n}\n\nUtilService.$inject = [\n '$filter',\n '$injector',\n '$mdDialog',\n '$q',\n '$rootScope',\n '$timeout'\n];\n\nexport default UtilService;\n"]} \ No newline at end of file