diff --git a/.idea/compiler.xml b/.idea/compiler.xml index da78bd3101..6075adace3 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -5,7 +5,6 @@ - diff --git a/package.json b/package.json index 48f97a8336..1aa32a66bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wise", - "version": "5.7.5", + "version": "5.7.6", "description": "Web-based Inquiry Science Environment", "main": "app.js", "dependencies": { diff --git a/pom.xml b/pom.xml index 65c3267bbc..50ba12b720 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,7 @@ wise war Web-based Inquiry Science Environment - 5.7.5 + 5.7.6 http://wise5.org @@ -124,7 +124,6 @@ **/org/wise/portal/service/**/*.java **/org/wise/portal/domain/**/*.java - **/org/wise/portal/presentation/web/controllers/admin/*.java **/org/wise/portal/presentation/web/controllers/general/contactwise/*.java **/org/wise/portal/presentation/web/controllers/teacher/**/*.java **/org/wise/portal/presentation/web/controllers/*.java @@ -148,7 +147,6 @@ **/org/wise/portal/service/**/*.java **/org/wise/portal/domain/**/*.java - **/org/wise/portal/presentation/web/controllers/admin/*.java **/org/wise/portal/presentation/web/controllers/general/contactwise/*.java **/org/wise/portal/presentation/web/controllers/teacher/**/*.java **/org/wise/portal/presentation/web/controllers/*.java diff --git a/src/main/java/org/wise/portal/domain/admin/DailyAdminJob.java b/src/main/java/org/wise/portal/domain/admin/DailyAdminJob.java index 0b27c0c617..a04278f16a 100644 --- a/src/main/java/org/wise/portal/domain/admin/DailyAdminJob.java +++ b/src/main/java/org/wise/portal/domain/admin/DailyAdminJob.java @@ -147,7 +147,6 @@ public void doJob() { try { JSONObject wiseStatisticsJSONObject = new JSONObject(); wiseStatisticsJSONObject.put("wiseName", wiseProperties.getProperty("wise.name")); - wiseStatisticsJSONObject.put("wiseBaseURL", wiseProperties.getProperty("wiseBaseURL")); PortalStatistics latestPortalStatistics = portalStatisticsService.getLatestPortalStatistics(); wiseStatisticsJSONObject.put("portal", latestPortalStatistics.getJSONObject()); @@ -680,7 +679,6 @@ public void postStatistics(String wiseStatisticsString) { List urlParameters = new ArrayList(); urlParameters.add(new BasicNameValuePair("name", wiseProperties.getProperty("wise.name"))); - urlParameters.add(new BasicNameValuePair("wiseBaseURL", wiseProperties.getProperty("wiseBaseURL"))); urlParameters.add(new BasicNameValuePair("stats", wiseStatisticsString)); try { diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/InformationController.java b/src/main/java/org/wise/portal/presentation/web/controllers/InformationController.java index 8c31e4ffe5..420636b351 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/InformationController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/InformationController.java @@ -136,14 +136,13 @@ public void handleGetConfigWISE4(HttpServletRequest request, HttpServletResponse throws ObjectNotFoundException, IOException { User signedInUser = ControllerUtil.getSignedInUser(); String mode = request.getParameter("mode"); - - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); + String contextPath = request.getContextPath(); JSONObject config = new JSONObject(); String projectIdString = request.getParameter("projectId"); // if projectId provided, this is a request for preview if (projectIdString != null) { Project project = projectService.getById(Long.parseLong(projectIdString)); - addPreviewConfigParametersWISE4(request, signedInUser, mode, wiseBaseURL, config, project); + addPreviewConfigParametersWISE4(request, signedInUser, mode, contextPath, config, project); printConfigToResponse(response, config); return; } @@ -155,7 +154,7 @@ public void handleGetConfigWISE4(HttpServletRequest request, HttpServletResponse if (workgroup == null && signedInUser == null && !signedInUser.isAdmin()) { return; } - addRunConfigParametersWISE4(request, signedInUser, mode, wiseBaseURL, config, runId, run, workgroup); + addRunConfigParametersWISE4(request, signedInUser, mode, contextPath, config, runId, run, workgroup); printConfigToResponse(response, config); return; } @@ -219,18 +218,19 @@ public void handleGetConfigWISE5ClassroomMonitor(HttpServletRequest request, getRunConfigParameters(request, config, run); User signedInUser = ControllerUtil.getSignedInUser(); - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); + String contextPath = request.getContextPath(); + if (hasRunReadAccess(signedInUser, run)) { config.put("runCode", run.getRuncode()); - config.put("teacherDataURL", wiseBaseURL + "/teacher/data"); - config.put("runDataExportURL", wiseBaseURL + "/teacher/export"); - config.put("studentNotebookURL", wiseBaseURL + "/teacher/notebook/" + runId); + config.put("teacherDataURL", contextPath + "/teacher/data"); + config.put("runDataExportURL", contextPath + "/teacher/export"); + config.put("studentNotebookURL", contextPath + "/teacher/notebook/" + runId); } Project project = run.getProject(); if (hasRunWriteAccess(signedInUser, run)) { String projectId = project.getId().toString(); - String saveProjectURL = wiseBaseURL + "/project/save/" + projectId; + String saveProjectURL = contextPath + "/project/save/" + projectId; config.put("saveProjectURL", saveProjectURL); } @@ -444,7 +444,7 @@ private JSONArray getPeriodsJSONArray(Run run) { private void addPreviewConfigParametersWISE4( HttpServletRequest request, User signedInUser, String mode, - String wiseBaseURL, JSONObject config, Project project) { + String contextPath, JSONObject config, Project project) { try { config.put("runId", ""); config.put("runName", ""); @@ -462,11 +462,11 @@ private void addPreviewConfigParametersWISE4( } catch (JSONException e) { e.printStackTrace(); } - addCommonConfigParametersWISE4(request, signedInUser, mode, wiseBaseURL, config, project); + addCommonConfigParametersWISE4(request, signedInUser, mode, contextPath, config, project); } private void addRunConfigParametersWISE4(HttpServletRequest request, User signedInUser, - String mode, String wiseBaseURL, JSONObject config, String runId, Run run, Workgroup workgroup) { + String mode, String contextPath, JSONObject config, String runId, Run run, Workgroup workgroup) { Long workgroupId = null; Long periodId = null; if (workgroup != null && workgroup.isStudentWorkgroup()) { @@ -482,47 +482,46 @@ private void addRunConfigParametersWISE4(HttpServletRequest request, User signed config.put("runId", Long.parseLong(runId)); config.put("runName", run.getName()); config.put("isRunActive", !run.isEnded()); - config.put("flagsURL", wiseBaseURL + "/annotation?type=flag&runId=" + runId); - config.put("inappropriateFlagsURL", wiseBaseURL + "/annotation?type=inappropriateFlag&runId=" + runId); - config.put("annotationsURL", wiseBaseURL + "/annotation?type=annotation&runId=" + runId); - config.put("studentDataURL", wiseBaseURL + "/studentData.html"); + config.put("flagsURL", contextPath + "/annotation?type=flag&runId=" + runId); + config.put("inappropriateFlagsURL", contextPath + "/annotation?type=inappropriateFlag&runId=" + runId); + config.put("annotationsURL", contextPath + "/annotation?type=annotation&runId=" + runId); + config.put("studentDataURL", contextPath + "/studentData.html"); config.put("gradingType", request.getParameter("gradingType")); config.put("getRevisions", request.getParameter("getRevisions")); - config.put("peerReviewURL", wiseBaseURL + "/peerReview.html?type=peerreview"); - config.put("ideaBasketURL", getIdeaBasketURL(runId, wiseBaseURL, run, periodId, workgroupId)); - config.put("portfolioURL", getPortfolioURL(runId, wiseBaseURL, periodId, workgroupId)); - config.put("studentAssetManagerURL", wiseBaseURL + "/assetManager?type=studentAssetManager&runId=" + runId); + config.put("peerReviewURL", contextPath + "/peerReview.html?type=peerreview"); + config.put("ideaBasketURL", getIdeaBasketURL(runId, contextPath, run, periodId, workgroupId)); + config.put("portfolioURL", getPortfolioURL(runId, contextPath, periodId, workgroupId)); + config.put("studentAssetManagerURL", contextPath + "/assetManager?type=studentAssetManager&runId=" + runId); config.put("runInfo", run.getInfo()); config.put("isRealTimeEnabled", true); // TODO: make this run-specific setting - config.put("webSocketURL", getWebSocketURL(request, wiseBaseURL)); - config.put("studentStatusURL", wiseBaseURL + "/studentStatus"); - config.put("runStatusURL", wiseBaseURL + "/runStatus"); + config.put("webSocketURL", getWebSocketURL(request, contextPath)); + config.put("studentStatusURL", contextPath + "/studentStatus"); + config.put("runStatusURL", contextPath + "/runStatus"); config.put("postLevel", run.getPostLevel()); - config.put("userInfoURL", wiseBaseURL + "/userInfo?runId=" + runId); + config.put("userInfoURL", contextPath + "/userInfo?runId=" + runId); if ("grading".equals(mode)) { - config.put("premadeCommentsURL", wiseBaseURL + "/teacher/grading/premadeComments.html"); - config.put("getXLSExportURL", wiseBaseURL + "/export?type=xlsexport&runId=" + runId); - config.put("getSpecialExportURL", wiseBaseURL + "/specialExport?type=specialExport&runId=" + runId); - config.put("getStudentListURL", wiseBaseURL + "/teacher/management/studentListExport?runId=" + runId); + config.put("premadeCommentsURL", contextPath + "/teacher/grading/premadeComments.html"); + config.put("getXLSExportURL", contextPath + "/export?type=xlsexport&runId=" + runId); + config.put("getSpecialExportURL", contextPath + "/specialExport?type=specialExport&runId=" + runId); + config.put("getStudentListURL", contextPath + "/teacher/management/studentListExport?runId=" + runId); } } catch (JSONException e) { e.printStackTrace(); } Project project = run.getProject(); - addCommonConfigParametersWISE4(request, signedInUser, mode, wiseBaseURL, config, project); + addCommonConfigParametersWISE4(request, signedInUser, mode, contextPath, config, project); } private void addCommonConfigParametersWISE4( HttpServletRequest request, User signedInUser, String mode, - String wiseBaseURL, JSONObject config, Project project) { + String contextPath, JSONObject config, Project project) { assert project != null; try { - config.put("wiseBaseURL", wiseBaseURL); - String contextPath = request.getContextPath(); + config.put("wiseBaseURL", contextPath); config.put("contextPath", contextPath); config.put("mode", mode); - config.put("projectMetadataURL", wiseBaseURL + "/metadata.html"); + config.put("projectMetadataURL", contextPath + "/metadata.html"); String curriculumBaseWWW = wiseProperties.getProperty("curriculum_base_www"); String rawProjectUrl = project.getModulePath(); String projectURL = curriculumBaseWWW + rawProjectUrl; @@ -532,9 +531,9 @@ private void addCommonConfigParametersWISE4( addProjectBaseURL(config, projectURL); config.put("studentUploadsBaseURL", wiseProperties.getProperty("studentuploads_base_www")); config.put("theme", "WISE"); - config.put("cRaterRequestURL", wiseBaseURL + "/cRater"); + config.put("cRaterRequestURL", contextPath + "/cRater"); config.put("mainHomePageURL", contextPath); - config.put("renewSessionURL", wiseBaseURL + "/session/renew"); + config.put("renewSessionURL", contextPath + "/session/renew"); config.put("sessionLogOutURL", contextPath + "/logout"); addStep(request, config); setUserLocale(request, signedInUser, config); @@ -555,8 +554,8 @@ private void addStep(HttpServletRequest request, JSONObject config) throws JSONE } } - private String getPortfolioURL(String runId, String wiseBaseURL, Long periodId, Long workgroupId) { - String portfolioURL = wiseBaseURL + "/portfolio?runId=" + runId; + private String getPortfolioURL(String runId, String contextPath, Long periodId, Long workgroupId) { + String portfolioURL = contextPath + "/portfolio?runId=" + runId; if (periodId != null) { portfolioURL += "&periodId=" + periodId; } @@ -566,8 +565,8 @@ private String getPortfolioURL(String runId, String wiseBaseURL, Long periodId, return portfolioURL; } - private String getIdeaBasketURL(String runId, String wiseBaseURL, Run run, Long periodId, Long workgroupId) { - String ideaBasketURL = wiseBaseURL + "/ideaBasket?runId=" + runId + "&projectId=" + run.getProject().getId().toString(); + private String getIdeaBasketURL(String runId, String contextPath, Run run, Long periodId, Long workgroupId) { + String ideaBasketURL = contextPath + "/ideaBasket?runId=" + runId + "&projectId=" + run.getProject().getId().toString(); if (periodId != null) { ideaBasketURL += "&periodId=" + periodId; } @@ -585,11 +584,11 @@ private String getIdeaBasketURL(String runId, String wiseBaseURL, Run run, Long * e.g. * ws://localhost:8080/wise */ - private String getWebSocketURL(HttpServletRequest request, String wiseBaseURL) { + private String getWebSocketURL(HttpServletRequest request, String contextPath) { String webSocketBaseURL = wiseProperties.getProperty("webSocketBaseUrl"); if (webSocketBaseURL == null) { - if (wiseBaseURL.contains("http")) { - webSocketBaseURL = wiseBaseURL.replace("http", "ws"); + if (contextPath.contains("http")) { + webSocketBaseURL = contextPath.replace("http", "ws"); } else { String portalContextPath = ControllerUtil.getPortalUrlString(request); webSocketBaseURL = portalContextPath.replace("http", "ws"); @@ -664,26 +663,26 @@ private void setUserLocale(HttpServletRequest request, User signedInUser, JSONOb private void getRunConfigParameters(HttpServletRequest request, JSONObject config, Run run) throws JSONException, ObjectNotFoundException { - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); + String contextPath = request.getContextPath(); Long runId = run.getId(); - String annotationsURL = wiseBaseURL + "/annotation?type=annotation&runId=" + runId; - String studentStatusURL = wiseBaseURL + "/studentStatus"; - String runStatusURL = wiseBaseURL + "/runStatus"; + String annotationsURL = contextPath + "/annotation?type=annotation&runId=" + runId; + String studentStatusURL = contextPath + "/studentStatus"; + String runStatusURL = contextPath + "/runStatus"; config.put("runName", run.getName()); config.put("runId", runId); config.put("annotationsURL", annotationsURL); config.put("runInfo", run.getInfo()); config.put("isRealTimeEnabled", run.isRealTimeEnabled()); - config.put("webSocketURL", getWebSocketURL(request, wiseBaseURL)); + config.put("webSocketURL", getWebSocketURL(request, contextPath)); config.put("studentStatusURL", studentStatusURL); config.put("runStatusURL", runStatusURL); config.put("userInfo", getUserInfo(run)); - config.put("studentDataURL", wiseBaseURL + "/student/data"); // the url to get/post student data - config.put("studentAssetsURL", wiseBaseURL + "/student/asset/" + runId); - config.put("studentNotebookURL", wiseBaseURL + "/student/notebook/" + runId); - config.put("achievementURL", wiseBaseURL + "/achievement/" + runId); - config.put("notificationURL", wiseBaseURL + "/notification/" + runId); + config.put("studentDataURL", contextPath + "/student/data"); // the url to get/post student data + config.put("studentAssetsURL", contextPath + "/student/asset/" + runId); + config.put("studentNotebookURL", contextPath + "/student/notebook/" + runId); + config.put("achievementURL", contextPath + "/achievement/" + runId); + config.put("notificationURL", contextPath + "/notification/" + runId); String openCPUURL = wiseProperties.getProperty("openCPUURL"); if (openCPUURL != null) { config.put("openCPUURL", openCPUURL); @@ -729,21 +728,19 @@ private void addCommonConfigParameters( String curriculumBaseWWW = wiseProperties.getProperty("curriculum_base_www"); String projectURL = curriculumBaseWWW + rawProjectUrl; - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); - config.put("wiseBaseURL", wiseBaseURL); + String contextPath = request.getContextPath(); + config.put("wiseBaseURL", contextPath); config.put("projectId", project.getId()); config.put("parentProjectId", project.getParentProjectId()); - config.put("previewProjectURL", wiseBaseURL + "/project/" + project.getId()); + config.put("previewProjectURL", contextPath + "/project/" + project.getId()); config.put("theme", "WISE"); config.put("projectURL", projectURL); addProjectBaseURL(config, projectURL); config.put("studentUploadsBaseURL", wiseProperties.getProperty("studentuploads_base_www")); - config.put("cRaterRequestURL", wiseBaseURL + "/cRater"); - - String contextPath = request.getContextPath(); //get the context path e.g. /wise + config.put("cRaterRequestURL", contextPath + "/cRater"); config.put("contextPath", contextPath); config.put("mainHomePageURL", contextPath); - config.put("renewSessionURL", wiseBaseURL + "/session/renew"); + config.put("renewSessionURL", contextPath + "/session/renew"); config.put("sessionLogOutURL", contextPath + "/logout"); User signedInUser = ControllerUtil.getSignedInUser(); diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/StatisticsController.java b/src/main/java/org/wise/portal/presentation/web/controllers/StatisticsController.java index 8562b2ef5b..5725db22ac 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/StatisticsController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/StatisticsController.java @@ -118,10 +118,6 @@ protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpSer return null; } else { ModelAndView modelAndView = new ModelAndView(); - - //add the wise base url to the model so the jsp can access it - modelAndView.addObject("wiseBaseURL", wiseProperties.getProperty("wiseBaseURL")); - return modelAndView; } } diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/VLEController.java b/src/main/java/org/wise/portal/presentation/web/controllers/VLEController.java index 5add832f93..b9763b4cc5 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/VLEController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/VLEController.java @@ -23,11 +23,6 @@ */ package org.wise.portal.presentation.web.controllers; -import java.util.Properties; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; @@ -37,8 +32,12 @@ import org.springframework.web.servlet.ModelAndView; import org.wise.portal.dao.ObjectNotFoundException; import org.wise.portal.domain.run.Run; -import org.wise.portal.service.run.RunService; import org.wise.portal.service.project.ProjectService; +import org.wise.portal.service.run.RunService; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Properties; /** * Controller for handling student VLE-portal interactions. @@ -63,13 +62,13 @@ protected ModelAndView launchVLEWISE4Run(HttpServletRequest request, HttpServlet throws Exception { String runIdString = request.getParameter("runId"); Run run = runService.retrieveById(Long.parseLong(runIdString)); - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); + String contextPath = request.getContextPath(); ModelAndView modelAndView = new ModelAndView("vle"); modelAndView.addObject("run", run); - modelAndView.addObject("vleurl", wiseBaseURL + "/vle/vle.html"); + modelAndView.addObject("vleurl", contextPath + "/vle/vle.html"); modelAndView.addObject("vleConfigUrl", - wiseBaseURL + "/vleconfig?runId=" + run.getId() + "&mode=run"); + contextPath + "/vleconfig?runId=" + run.getId() + "&mode=run"); String curriculumBaseWWW = wiseProperties.getProperty("curriculum_base_www"); String rawProjectUrl = run.getProject().getModulePath(); String contentUrl = curriculumBaseWWW + rawProjectUrl; @@ -78,20 +77,20 @@ protected ModelAndView launchVLEWISE4Run(HttpServletRequest request, HttpServlet } @RequestMapping(value = "/student/run/{runId}") - protected String launchVLEWISE5Run(@PathVariable Long runId, ModelMap modelMap) { - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); - modelMap.put("configURL", wiseBaseURL + "/config/studentRun/" + runId); + protected String launchVLEWISE5Run(HttpServletRequest request, @PathVariable Long runId, ModelMap modelMap) { + String contextPath = request.getContextPath(); + modelMap.put("configURL", contextPath + "/config/studentRun/" + runId); return "student"; } @RequestMapping(value = "/project/{projectId}", method = RequestMethod.GET) - protected String launchVLEWISE5Preview(@PathVariable String projectId, ModelMap modelMap) { + protected String launchVLEWISE5Preview(HttpServletRequest request, @PathVariable String projectId, ModelMap modelMap) { try { if (!"demo".equals(projectId)) { projectService.getById(Long.parseLong(projectId)); } - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); - modelMap.put("configURL", wiseBaseURL + "/config/preview/" + projectId); + String contextPath = request.getContextPath(); + modelMap.put("configURL", contextPath + "/config/preview/" + projectId); return "student"; } catch (ObjectNotFoundException onfe) { onfe.printStackTrace(); diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/admin/FindProjectRunsController.java b/src/main/java/org/wise/portal/presentation/web/controllers/admin/FindProjectRunsController.java index 5e99b6bfd0..b5d15079d4 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/admin/FindProjectRunsController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/admin/FindProjectRunsController.java @@ -31,8 +31,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import org.wise.portal.dao.ObjectNotFoundException; import org.wise.portal.domain.project.Project; @@ -43,15 +45,13 @@ import org.wise.portal.service.user.UserService; /** - * Controller to find project runs for admin users + * Controller for admins to find project runs * @author Patrick Lawler */ @Controller @RequestMapping("/admin/run/manageprojectruns.html") public class FindProjectRunsController { - private final static String VIEW = "admin/run/manageprojectruns"; - @Autowired private RunService runService; @@ -64,41 +64,29 @@ public class FindProjectRunsController { @Autowired private Properties wiseProperties; - @RequestMapping(method=RequestMethod.GET) - protected ModelAndView handleGET( - HttpServletRequest request) { - - ModelAndView modelAndView = new ModelAndView(); + @RequestMapping(method = RequestMethod.GET) + protected String findRun( + @RequestParam(value = "runLookupType", required = true) String runLookupType, + @RequestParam(value = "runLookupValue", required = true) String runLookupValue, + ModelMap modelMap) { List runList = new ArrayList(); - - // check if runLookupType was passed in, can be ["runId","projectId","teacherUsername"] - String runLookupType = request.getParameter("runLookupType"); - String runLookupValue = request.getParameter("runLookupValue"); - - if (runLookupType != null && runLookupValue != null) { - if ("runId".equals(runLookupType)) { - runList = this.getRunListByRunId(Long.parseLong(runLookupValue)); - } else if ("projectId".equals(runLookupType)) { - runList = this.getRunListByProjectId(Long.parseLong(runLookupValue)); - } else if ("teacherUsername".equals(runLookupType)) { - runList = this.getRunListByUsername(runLookupValue); - } else if ("runTitle".equals(runLookupType)) { - runList = this.getRunListByRunTitle(runLookupValue); - } + if ("runId".equals(runLookupType)) { + runList = this.getRunListByRunId(Long.parseLong(runLookupValue)); + } else if ("projectId".equals(runLookupType)) { + runList = this.getRunListByProjectId(Long.parseLong(runLookupValue)); + } else if ("teacherUsername".equals(runLookupType)) { + runList = this.getRunListByUsername(runLookupValue); + } else if ("runTitle".equals(runLookupType)) { + runList = this.getRunListByRunTitle(runLookupValue); } - - modelAndView = new ModelAndView(VIEW); - modelAndView.addObject("runList", runList); - - String isRealTimeEnabledStr = wiseProperties.getProperty("isRealTimeEnabled", "false"); - modelAndView.addObject("isRealTimeEnabled", Boolean.valueOf(isRealTimeEnabledStr)); - - return modelAndView; + modelMap.put("runList", runList); + return "admin/run/manageprojectruns"; } /** * Returns a List list of any runs that are - * associated with the given Long project id. + * associated with the given Long project id, including runs that were made + * using copies of the project * * @param projectId * @return List - list of runs associated with the projectId @@ -147,17 +135,14 @@ private List getRunListByUsername(String username) { */ private List getRunListByRunId(Long runId) { List runList = new ArrayList(); - try { Run run = this.runService.retrieveById(runId); - if (run != null) { runList.add(run); } } catch(ObjectNotFoundException e) { e.printStackTrace(); } - return runList; } diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/admin/UserInfoController.java b/src/main/java/org/wise/portal/presentation/web/controllers/admin/UserInfoController.java index 322f62328a..b6859b326e 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/admin/UserInfoController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/admin/UserInfoController.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2007-2017 Regents of the University of California (Regents). + * Copyright (c) 2007-2018 Regents of the University of California (Regents). * Created by WISE, Graduate School of Education, University of California, Berkeley. * * This software is distributed under the GNU General Public License, v3, @@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; @@ -43,7 +44,8 @@ import org.wise.portal.service.user.UserService; /** - * Controller for displaying user information + * Controller for displaying user information to admin users + * and student information to their teachers * @author Sally Ahn */ @Controller @@ -61,34 +63,29 @@ public class UserInfoController { protected final static String USER_INFO_MAP = "userInfoMap"; @RequestMapping(value = {"/student/account/info", "/teacher/account/info"}) - protected ModelAndView handleGetUserAccountInfo( - @RequestParam("userName") String userName) throws Exception { + protected String getUserAccountInfo( + @RequestParam("userName") String userName, + ModelMap modelMap) throws Exception { User signedInUser = ControllerUtil.getSignedInUser(); - User infoUser = this.userService.retrieveUserByUsername(userName); + User user = this.userService.retrieveUserByUsername(userName); if (signedInUser.isAdmin() || - this.studentService.isStudentAssociatedWithTeacher(infoUser, signedInUser)) { - MutableUserDetails userDetails = (MutableUserDetails) infoUser.getUserDetails(); - ModelAndView modelAndView = new ModelAndView(); - + this.studentService.isStudentAssociatedWithTeacher(user, signedInUser)) { + MutableUserDetails userDetails = (MutableUserDetails) user.getUserDetails(); HashMap userInfoMap = userDetails.getInfo(); - userInfoMap.put("ID", infoUser.getId()); - modelAndView.addObject(USER_INFO_MAP, userInfoMap); - - if (infoUser.getUserDetails().hasGrantedAuthority(UserDetailsService.STUDENT_ROLE)) { - modelAndView.addObject("isStudent", true); - List runList = runService.getRunList(infoUser); - modelAndView.addObject("runList", runList); - modelAndView.setViewName("student/account/info"); + userInfoMap.put("ID", user.getId()); + modelMap.put(USER_INFO_MAP, userInfoMap); + if (user.getUserDetails().hasGrantedAuthority(UserDetailsService.STUDENT_ROLE)) { + modelMap.put("isStudent", true); + modelMap.put("runList", runService.getRunList(user)); + return "student/account/info"; } else { - modelAndView.addObject("isStudent", false); - List runListByOwner = runService.getRunListByOwner(infoUser); - modelAndView.addObject("runList", runListByOwner); - modelAndView.setViewName("teacher/account/info"); + modelMap.put("isStudent", false); + modelMap.put("runList", runService.getRunListByOwner(user)); + return "teacher/account/info"; } - return modelAndView; } else { - return new ModelAndView("errors/accessdenied"); + return "errors/accessdenied"; } } } diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/admin/ViewAllUsersController.java b/src/main/java/org/wise/portal/presentation/web/controllers/admin/ViewAllUsersController.java index 947dd6fd81..05682e33ec 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/admin/ViewAllUsersController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/admin/ViewAllUsersController.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2007-2015 Regents of the University of California (Regents). + * Copyright (c) 2007-2018 Regents of the University of California (Regents). * Created by WISE, Graduate School of Education, University of California, Berkeley. * * This software is distributed under the GNU General Public License, v3, @@ -30,7 +30,6 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @@ -61,8 +60,6 @@ public class ViewAllUsersController{ @Autowired private DailyAdminJob adminJob; - protected static final String VIEW_NAME = "admin/account/manageusers"; - protected static final String TEACHERS = "teachers"; protected static final String STUDENTS = "students"; @@ -81,26 +78,19 @@ public class ViewAllUsersController{ private static final String LOGGED_IN_TEACHER_USERNAMES = "loggedInTeacherUsernames"; - /** - * @see org.springframework.web.servlet.mvc.AbstractController#handleRequestInternal(javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ @RequestMapping(method = RequestMethod.GET) @SuppressWarnings("unchecked") - protected String handleRequestInternal( - HttpServletRequest servletRequest, - ModelMap modelMap) throws Exception { - - String onlyShowLoggedInUser = servletRequest.getParameter("onlyShowLoggedInUser"); - String onlyShowUsersWhoLoggedIn = servletRequest.getParameter("onlyShowUsersWhoLoggedIn"); + protected String showUsers(HttpServletRequest request, ModelMap modelMap) throws Exception { + String onlyShowLoggedInUser = request.getParameter("onlyShowLoggedInUser"); + String onlyShowUsersWhoLoggedIn = request.getParameter("onlyShowUsersWhoLoggedIn"); if (onlyShowLoggedInUser != null && onlyShowLoggedInUser.equals("true")) { // get logged in users from servlet context HashMap allLoggedInUsers = - (HashMap) servletRequest.getSession() + (HashMap) request.getSession() .getServletContext().getAttribute(WISESessionListener.ALL_LOGGED_IN_USERS); HashMap studentsToRunIds = - (HashMap) servletRequest.getSession() + (HashMap) request.getSession() .getServletContext().getAttribute("studentsToRunIds"); ArrayList loggedInStudent = new ArrayList(); @@ -166,20 +156,18 @@ protected String handleRequestInternal( modelMap.put("teachersWhoLoggedInSince", teachersWhoLoggedInSince); } else { // result depends on passed-in userType parameter - String userType = servletRequest.getParameter(USER_TYPE); + String userType = request.getParameter(USER_TYPE); if (userType == null) { List allUsernames = this.userService.retrieveAllUsernames(); modelMap.put(USERNAMES, allUsernames); } else if (userType.equals(STUDENT)) { - List usernames = this.userDetailsService.retrieveAllUsernames(StudentUserDetails.class.getName()); modelMap.put(STUDENTS, usernames); } else if (userType.equals(TEACHER)) { List usernames = this.userDetailsService.retrieveAllUsernames(TeacherUserDetails.class.getName()); - modelMap.put(TEACHERS, usernames); } } - return VIEW_NAME; + return "admin/account/manageusers"; } } diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/author/project/AuthorProjectController.java b/src/main/java/org/wise/portal/presentation/web/controllers/author/project/AuthorProjectController.java index fbe1dc5f11..e1562093ae 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/author/project/AuthorProjectController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/author/project/AuthorProjectController.java @@ -23,22 +23,6 @@ */ package org.wise.portal.presentation.web.controllers.author.project; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -77,6 +61,15 @@ import org.wise.vle.web.AssetManager; import org.wise.vle.web.SecurityUtils; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.File; +import java.io.IOException; +import java.util.*; + /** * Controller for users with author privileges to author WISE4 projects * @@ -812,10 +805,10 @@ protected ModelAndView handleConvertRequestInternal( */ private ModelAndView handleLaunchAuthoring(HttpServletRequest request) { User author = ControllerUtil.getSignedInUser(); - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); + String contextPath = request.getContextPath(); - String vleUrl = wiseBaseURL + "/vle/author.html"; - String portalAuthorUrl = wiseBaseURL + "/author/authorproject.html"; + String vleUrl = contextPath + "/vle/author.html"; + String portalAuthorUrl = contextPath + "/author/authorproject.html"; String command = request.getParameter("param1"); String projectIdStr = request.getParameter(PROJECT_ID_PARAM_NAME); @@ -1469,32 +1462,29 @@ private ModelAndView handleGetConfig(HttpServletRequest request, HttpServletResp //get the username String username = user.getUserDetails().getUsername(); - //get the wise base url - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); - //get the context path e.g. /wise String contextPath = request.getContextPath(); //get the url to get and post metadata - String projectMetadataURL = wiseBaseURL + "/metadata.html"; + String projectMetadataURL = contextPath + "/metadata.html"; //get the url to make CRater requests - String cRaterRequestURL = wiseBaseURL + "/cRater"; + String cRaterRequestURL = contextPath + "/cRater"; //get the curriculum_base_www variable from the wise.properties file String curriculumBaseUrl = wiseProperties.getProperty("curriculum_base_www"); //get the url to preview project - String previewProjectUrl = wiseBaseURL + "/previewproject.html"; + String previewProjectUrl = contextPath + "/previewproject.html"; //get the url to make CRater requests - String deleteProjectUrl = wiseBaseURL + "/teacher/projects/deleteproject.html"; + String deleteProjectUrl = contextPath + "/teacher/projects/deleteproject.html"; //get the url to make analyze project requests - String analyzeProjectUrl = wiseBaseURL + "/teacher/projects/analyzeproject.html"; + String analyzeProjectUrl = contextPath + "/teacher/projects/analyzeproject.html"; //the get/post url for premade comments - String premadeCommentsURL = wiseBaseURL + "/teacher/grading/premadeComments.html"; + String premadeCommentsURL = contextPath + "/teacher/grading/premadeComments.html"; //create a JSONObject to contain the config params JSONObject config = new JSONObject(); @@ -1504,7 +1494,7 @@ private ModelAndView handleGetConfig(HttpServletRequest request, HttpServletResp config.put("username", username); config.put("projectMetadataURL", projectMetadataURL); config.put("curriculumBaseUrl", curriculumBaseUrl); - config.put("indexURL", wiseBaseURL + WISEAuthenticationProcessingFilter.TEACHER_DEFAULT_TARGET_PATH); + config.put("indexURL", contextPath + WISEAuthenticationProcessingFilter.TEACHER_DEFAULT_TARGET_PATH); int maxInactiveInterval = request.getSession().getMaxInactiveInterval() * 1000; config.put("sessionTimeoutInterval", maxInactiveInterval); // add sessiontimeout interval, in milleseconds int sessionTimeoutCheckInterval = maxInactiveInterval / 20; // check 20 times during the session. @@ -1519,7 +1509,7 @@ private ModelAndView handleGetConfig(HttpServletRequest request, HttpServletResp config.put("deleteProjectUrl", deleteProjectUrl); config.put("analyzeProjectUrl", analyzeProjectUrl); config.put("premadeCommentsURL", premadeCommentsURL); - config.put("wiseBaseURL", wiseBaseURL); + config.put("wiseBaseURL", contextPath); config.put("contextPath", contextPath); // if projectId provided, this is a request for preview diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/author/project/WISE5AuthorProjectController.java b/src/main/java/org/wise/portal/presentation/web/controllers/author/project/WISE5AuthorProjectController.java index ea91bbaac1..44922ea77c 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/author/project/WISE5AuthorProjectController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/author/project/WISE5AuthorProjectController.java @@ -116,8 +116,8 @@ protected String authorProject(HttpServletRequest request, HttpServletResponse r // do nothing } - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); - modelMap.put("configURL", wiseBaseURL + "/authorConfig"); + String contextPath = request.getContextPath(); + modelMap.put("configURL", contextPath + "/authorConfig"); return "author"; } @@ -343,7 +343,7 @@ protected void getAuthorProjectConfig(HttpServletRequest request, HttpServletRes JSONObject config = getDefaultAuthoringConfigJsonObject(request); try { - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); + String contextPath = request.getContextPath(); String curriculumBaseWWW = wiseProperties.getProperty("curriculum_base_www"); String rawProjectUrl = project.getModulePath(); String projectURL = curriculumBaseWWW + rawProjectUrl; @@ -358,16 +358,16 @@ protected void getAuthorProjectConfig(HttpServletRequest request, HttpServletRes config.put("projectId", projectId); config.put("projectURL", projectURL); config.put("projectAssetTotalSizeMax", projectAssetTotalSizeMax); - config.put("projectAssetURL", wiseBaseURL + "/project/asset/" + projectId); + config.put("projectAssetURL", contextPath + "/project/asset/" + projectId); config.put("projectBaseURL", projectBaseURL); - config.put("previewProjectURL", wiseBaseURL + "/project/" + projectId); - config.put("cRaterRequestURL", wiseBaseURL + "/cRater"); - config.put("importStepsURL", wiseBaseURL + "/project/importSteps/" + projectId); + config.put("previewProjectURL", contextPath + "/project/" + projectId); + config.put("cRaterRequestURL", contextPath + "/cRater"); + config.put("importStepsURL", contextPath + "/project/importSteps/" + projectId); config.put("mode", "author"); if (projectService.canAuthorProject(project, ControllerUtil.getSignedInUser())) { - config.put("saveProjectURL", wiseBaseURL + "/project/save/" + projectId); - config.put("commitProjectURL", wiseBaseURL + "/project/commit/" + projectId); + config.put("saveProjectURL", contextPath + "/project/save/" + projectId); + config.put("commitProjectURL", contextPath + "/project/commit/" + projectId); } Long runId = this.getRunId(projectId); @@ -390,18 +390,17 @@ private JSONObject getDefaultAuthoringConfigJsonObject(HttpServletRequest reques User user = ControllerUtil.getSignedInUser(); try { String contextPath = request.getContextPath(); - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); config.put("contextPath", contextPath); - config.put("copyProjectURL", wiseBaseURL + "/project/copy"); - config.put("mainHomePageURL", wiseBaseURL); - config.put("renewSessionURL", wiseBaseURL + "/session/renew"); - config.put("sessionLogOutURL", wiseBaseURL + "/logout"); - config.put("registerNewProjectURL", wiseBaseURL + "/project/new"); - config.put("wiseBaseURL", wiseBaseURL); - config.put("notifyProjectBeginURL", wiseBaseURL + "/project/notifyAuthorBegin/"); - config.put("notifyProjectEndURL", wiseBaseURL + "/project/notifyAuthorEnd/"); - config.put("getLibraryProjectsURL", wiseBaseURL + "/author/authorproject.html?command=projectList&projectPaths=&projectTag=library&wiseVersion=5"); - config.put("teacherDataURL", wiseBaseURL + "/teacher/data"); + config.put("copyProjectURL", contextPath + "/project/copy"); + config.put("mainHomePageURL", contextPath); + config.put("renewSessionURL", contextPath + "/session/renew"); + config.put("sessionLogOutURL", contextPath + "/logout"); + config.put("registerNewProjectURL", contextPath + "/project/new"); + config.put("wiseBaseURL", contextPath); + config.put("notifyProjectBeginURL", contextPath + "/project/notifyAuthorBegin/"); + config.put("notifyProjectEndURL", contextPath + "/project/notifyAuthorEnd/"); + config.put("getLibraryProjectsURL", contextPath + "/author/authorproject.html?command=projectList&projectPaths=&projectTag=library&wiseVersion=5"); + config.put("teacherDataURL", contextPath + "/teacher/data"); String projectMetadataSettings = null; try { @@ -503,8 +502,8 @@ private JSONObject getDefaultAuthoringConfigJsonObject(HttpServletRequest reques * e.g. * ws://localhost:8080/wise */ - if (wiseBaseURL.contains("http")) { - webSocketBaseURL = wiseBaseURL.replace("http", "ws"); + if (contextPath.contains("http")) { + webSocketBaseURL = contextPath.replace("http", "ws"); } else { String portalContextPath = ControllerUtil.getPortalUrlString(request); webSocketBaseURL = portalContextPath.replace("http", "ws"); diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/forgotaccount/teacher/ForgotAccountTeacherIndexController.java b/src/main/java/org/wise/portal/presentation/web/controllers/forgotaccount/teacher/ForgotAccountTeacherIndexController.java index f2aa62d359..fb13ecf0e8 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/forgotaccount/teacher/ForgotAccountTeacherIndexController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/forgotaccount/teacher/ForgotAccountTeacherIndexController.java @@ -23,14 +23,6 @@ */ package org.wise.portal.presentation.web.controllers.forgotaccount.teacher; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import java.util.Properties; -import java.util.regex.Pattern; - -import javax.servlet.http.HttpServletRequest; - import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -38,7 +30,6 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; -import org.springframework.validation.Errors; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -49,6 +40,13 @@ import org.wise.portal.service.mail.MailService; import org.wise.portal.service.user.UserService; +import javax.servlet.http.HttpServletRequest; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.Properties; +import java.util.regex.Pattern; + /** * Controller for lost password teacher username and email lookup * @@ -171,13 +169,13 @@ protected String onSubmit(@ModelAttribute("userDetails") TeacherUserDetails user * e.g. * http://wise4.berkeley.edu/wise/forgotaccount/resetpassword.html?k=1234567890abc */ - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); + String contextPath = request.getContextPath(); String portalContextURL = ""; - if (wiseBaseURL.startsWith("http")) { - // in case wiseBaseURL is absolute, in the form "http://xyz:8080/wise" - portalContextURL = wiseBaseURL; + if (contextPath.startsWith("http")) { + // in case contextPath is absolute, in the form "http://xyz:8080/wise" + portalContextURL = contextPath; } else { - // in case wiseBaseURL is relative, in the form "/wise" + // in case contextPath is relative, in the form "/wise" portalContextURL = ControllerUtil.getPortalUrlString(request); } String passwordResetLink = portalContextURL + "/forgotaccount/resetpassword.html?k=" + randomAlphanumeric; diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/student/StartProjectController.java b/src/main/java/org/wise/portal/presentation/web/controllers/student/StartProjectController.java index 7450a91ebe..87938c6124 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/student/StartProjectController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/student/StartProjectController.java @@ -23,17 +23,6 @@ */ package org.wise.portal.presentation.web.controllers.student; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Properties; -import java.util.Set; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - import org.hibernate.StaleObjectStateException; import org.json.JSONArray; import org.springframework.beans.factory.annotation.Autowired; @@ -47,10 +36,15 @@ import org.wise.portal.domain.workgroup.Workgroup; import org.wise.portal.presentation.web.controllers.ControllerUtil; import org.wise.portal.service.attendance.StudentAttendanceService; -import org.wise.portal.service.run.RunService; import org.wise.portal.service.project.ProjectService; +import org.wise.portal.service.run.RunService; import org.wise.portal.service.workgroup.WorkgroupService; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.util.*; + /** * Controller to allow students to launch the VLE using the project. * This link is *always* used to start the project for students, whether: @@ -170,7 +164,7 @@ protected synchronized ModelAndView handleRequestInternal( // create a student attendance entry addStudentAttendanceEntry(workgroupId, runId, presentUserIds, absentUserIds); - return projectService.launchProject(workgroup); + return projectService.launchProject(workgroup, request.getContextPath()); } else { // need to create a workgroup for this user, take them to create workgroup wizard ModelAndView modelAndView = new ModelAndView(SELECT_TEAM_URL); @@ -219,7 +213,7 @@ protected synchronized ModelAndView handleRequestInternal( // update servlet session notifyServletSession(request, run); - return projectService.launchProject(workgroup); + return projectService.launchProject(workgroup, request.getContextPath()); } else { ModelAndView modelAndView = new ModelAndView(TEAM_SIGN_IN_URL); modelAndView.addObject("runId", runId); @@ -264,7 +258,7 @@ protected synchronized ModelAndView handleRequestInternal( // update servlet session notifyServletSession(request, run); - return projectService.launchProject(workgroup); + return projectService.launchProject(workgroup, request.getContextPath()); } else { ModelAndView modelAndView = new ModelAndView(TEAM_SIGN_IN_URL); modelAndView.addObject("runId", runId); diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/student/TeamSignInController.java b/src/main/java/org/wise/portal/presentation/web/controllers/student/TeamSignInController.java index 88ab7406de..dbe746cb07 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/student/TeamSignInController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/student/TeamSignInController.java @@ -23,17 +23,6 @@ */ package org.wise.portal.presentation.web.controllers.student; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; -import java.util.Set; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.hibernate.StaleObjectStateException; import org.json.JSONArray; import org.springframework.beans.factory.annotation.Autowired; @@ -57,12 +46,16 @@ import org.wise.portal.presentation.web.controllers.ControllerUtil; import org.wise.portal.service.attendance.StudentAttendanceService; import org.wise.portal.service.group.GroupService; -import org.wise.portal.service.run.RunService; import org.wise.portal.service.project.ProjectService; +import org.wise.portal.service.run.RunService; import org.wise.portal.service.student.StudentService; import org.wise.portal.service.user.UserService; import org.wise.portal.service.workgroup.WorkgroupService; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.*; + /** * Controller for handling team sign-ins before students start the project. The first user * entered in the form must be already signed-in and associated with a specific @@ -333,7 +326,7 @@ protected synchronized String onSubmit(@ModelAttribute("teamSignInForm") TeamSig } StartProjectController.notifyServletSession(request, run); - ModelAndView modelAndView = projectService.launchProject(workgroup); + ModelAndView modelAndView = projectService.launchProject(workgroup, request.getContextPath()); // clear the command object from the session status.setComplete(); diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/teacher/TeacherAccountController.java b/src/main/java/org/wise/portal/presentation/web/controllers/teacher/TeacherAccountController.java index e8fafe6c22..5b229aab86 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/teacher/TeacherAccountController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/teacher/TeacherAccountController.java @@ -23,13 +23,6 @@ */ package org.wise.portal.presentation.web.controllers.teacher; -import java.util.Calendar; -import java.util.Locale; -import java.util.Properties; - -import javax.mail.MessagingException; -import javax.servlet.http.HttpServletRequest; - import org.apache.commons.lang3.ArrayUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; @@ -55,6 +48,12 @@ import org.wise.portal.service.mail.IMailFacade; import org.wise.portal.service.user.UserService; +import javax.mail.MessagingException; +import javax.servlet.http.HttpServletRequest; +import java.util.Calendar; +import java.util.Locale; +import java.util.Properties; + /** * Controller for creating and updating WISE teacher accounts * @@ -171,7 +170,7 @@ protected String createNewTeacher( userDetails.setDisplayname(userDetails.getFirstname() + " " + userDetails.getLastname()); userDetails.setEmailValid(true); User createdUser = this.userService.createUser(userDetails); - NewAccountEmailService newAccountEmailService = new NewAccountEmailService(createdUser, request.getLocale()); + NewAccountEmailService newAccountEmailService = new NewAccountEmailService(createdUser, request.getLocale(), request); Thread thread = new Thread(newAccountEmailService); thread.start(); modelMap.addAttribute("username", userDetails.getUsername()); @@ -310,10 +309,12 @@ public boolean isOnRegisterNewTeacherPage(HttpServletRequest request) { class NewAccountEmailService implements Runnable { private User newUser; private Locale locale; + private HttpServletRequest request; - public NewAccountEmailService(User newUser, Locale locale) { + public NewAccountEmailService(User newUser, Locale locale, HttpServletRequest request) { this.newUser = newUser; this.locale = locale; + this.request = request; } public void run() { @@ -322,14 +323,14 @@ public void run() { if (!sendEmailEnabled) { return; } else { - this.sendEmail(); + this.sendEmail(this.request); } } /** * Sends a welcome email to the new user with WISE resources. */ - private void sendEmail() { + private void sendEmail(HttpServletRequest request) { TeacherUserDetails newUserDetails = (TeacherUserDetails) newUser.getUserDetails(); String userUsername = newUserDetails.getUsername(); String userEmailAddress[] = {newUserDetails.getEmailAddress()}; @@ -337,8 +338,8 @@ private void sendEmail() { wiseProperties.getProperty("uber_admin").split(",")); String defaultSubject = messageSource.getMessage("presentation.web.controllers.teacher.registerTeacherController.welcomeTeacherEmailSubject", null, Locale.US); String subject = messageSource.getMessage("presentation.web.controllers.teacher.registerTeacherController.welcomeTeacherEmailSubject", null, defaultSubject, this.locale); - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); - String gettingStartedUrl = wiseBaseURL + "/pages/gettingstarted.html"; + String portalString = ControllerUtil.getPortalUrlString(request); + String gettingStartedUrl = portalString + "/pages/gettingstarted.html"; String defaultBody = messageSource.getMessage("presentation.web.controllers.teacher.registerTeacherController.welcomeTeacherEmailBody", new Object[] {userUsername,gettingStartedUrl}, Locale.US); String message = messageSource.getMessage("presentation.web.controllers.teacher.registerTeacherController.welcomeTeacherEmailBody", new Object[] {userUsername,gettingStartedUrl}, defaultBody, this.locale); diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/teacher/grading/GradeWorkController.java b/src/main/java/org/wise/portal/presentation/web/controllers/teacher/grading/GradeWorkController.java index c1bffc4152..34aab1d47d 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/teacher/grading/GradeWorkController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/teacher/grading/GradeWorkController.java @@ -23,12 +23,6 @@ */ package org.wise.portal.presentation.web.controllers.teacher.grading; -import java.io.IOException; -import java.util.Properties; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -39,7 +33,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.view.RedirectView; import org.wise.portal.dao.ObjectNotFoundException; import org.wise.portal.domain.project.impl.ProjectType; import org.wise.portal.domain.run.Run; @@ -47,6 +40,11 @@ import org.wise.portal.presentation.web.controllers.ControllerUtil; import org.wise.portal.service.run.RunService; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Properties; + /** * A Controller for Grading Student Work * @@ -70,7 +68,7 @@ public class GradeWorkController { * @throws Exception */ @RequestMapping(value = "/classroomMonitor/{runId}") - protected ModelAndView launchClassroomMonitorWISE5(@PathVariable Integer runId) throws Exception { + protected ModelAndView launchClassroomMonitorWISE5(HttpServletRequest request, @PathVariable Integer runId) throws Exception { Run run = null; try { run = runService.retrieveById(new Long(runId)); @@ -87,8 +85,8 @@ protected ModelAndView launchClassroomMonitorWISE5(@PathVariable Integer runId) this.runService.hasRunPermission(run, user, BasePermission.WRITE) || this.runService.hasRunPermission(run, user, BasePermission.READ)) { - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); - String getClassroomMonitorConfigUrl = wiseBaseURL + "/config/classroomMonitor/" + runId; + String contextPath = request.getContextPath(); + String getClassroomMonitorConfigUrl = contextPath + "/config/classroomMonitor/" + runId; ModelAndView modelAndView = new ModelAndView("classroomMonitor"); modelAndView.addObject("configURL", getClassroomMonitorConfigUrl); @@ -137,14 +135,14 @@ protected ModelAndView handleRequestInternal( this.runService.hasRunPermission(run, user, BasePermission.WRITE) || this.runService.hasRunPermission(run, user, BasePermission.READ)) { - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); + String contextPath = request.getContextPath(); - String getGradeWorkUrl = wiseBaseURL + "/vle/gradework.html"; - String getGradingConfigUrl = wiseBaseURL + "/vleconfig?runId=" + run.getId().toString() + "&gradingType=" + gradingType + "&mode=grading&getRevisions=" + getRevisions; + String getGradeWorkUrl = contextPath + "/vle/gradework.html"; + String getGradingConfigUrl = contextPath + "/vleconfig?runId=" + run.getId().toString() + "&gradingType=" + gradingType + "&mode=grading&getRevisions=" + getRevisions; // get the classroom monitor urls - String getClassroomMonitorUrl = wiseBaseURL + "/vle/classroomMonitor.html"; - String getClassroomMonitorConfigUrl = wiseBaseURL + "/vleconfig?runId=" + run.getId().toString() + "&gradingType=" + gradingType + "&mode=grading&getRevisions=" + getRevisions; + String getClassroomMonitorUrl = contextPath + "/vle/classroomMonitor.html"; + String getClassroomMonitorConfigUrl = contextPath + "/vleconfig?runId=" + run.getId().toString() + "&gradingType=" + gradingType + "&mode=grading&getRevisions=" + getRevisions; // set the permission variable so that we can access it in the .jsp if (this.runService.hasRunPermission(run, user, BasePermission.WRITE)) { diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/teacher/run/UpdateRunController.java b/src/main/java/org/wise/portal/presentation/web/controllers/teacher/run/UpdateRunController.java index b93724e4f5..1955792ecb 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/teacher/run/UpdateRunController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/teacher/run/UpdateRunController.java @@ -23,19 +23,11 @@ */ package org.wise.portal.presentation.web.controllers.teacher.run; -import java.util.Date; -import java.util.Properties; - -import javax.mail.MessagingException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.view.RedirectView; import org.wise.portal.domain.project.Project; import org.wise.portal.domain.run.Run; import org.wise.portal.domain.user.User; @@ -43,8 +35,14 @@ import org.wise.portal.presentation.web.exception.NotAuthorizedException; import org.wise.portal.service.authentication.UserDetailsService; import org.wise.portal.service.mail.IMailFacade; -import org.wise.portal.service.run.RunService; import org.wise.portal.service.project.ProjectService; +import org.wise.portal.service.run.RunService; + +import javax.mail.MessagingException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Date; +import java.util.Properties; /** * Controller for updating run settings, like add period, @@ -139,7 +137,7 @@ protected ModelAndView handlePOST(HttpServletRequest request, HttpServletRespons this.runService.updateSurvey(Long.parseLong(runId), survey); // send email to WISE staff with Survey - String linkToSurvey = wiseProperties.getProperty("wiseBaseURL")+"/teacher/run/survey.html?runId="+runId; + String linkToSurvey = ControllerUtil.getPortalUrlString(request)+"/teacher/run/survey.html?runId="+runId; String emailBody = user.getUserDetails().getUsername()+ " completed a survey for "+run.getName()+" (Run ID="+runId+").\n\nLink to view survey on WISE: "+linkToSurvey+"\n\n"+survey; EmailService emailService = new EmailService("Survey completed [Run ID="+runId+"]: "+run.getName(), emailBody); diff --git a/src/main/java/org/wise/portal/service/project/ProjectService.java b/src/main/java/org/wise/portal/service/project/ProjectService.java index 50369299d0..68922cad02 100644 --- a/src/main/java/org/wise/portal/service/project/ProjectService.java +++ b/src/main/java/org/wise/portal/service/project/ProjectService.java @@ -23,11 +23,6 @@ */ package org.wise.portal.service.project; -import java.io.IOException; -import java.io.Serializable; -import java.util.List; -import java.util.Set; - import org.springframework.security.access.annotation.Secured; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.servlet.ModelAndView; @@ -40,6 +35,11 @@ import org.wise.portal.domain.workgroup.Workgroup; import org.wise.portal.presentation.web.exception.NotAuthorizedException; +import java.io.IOException; +import java.io.Serializable; +import java.util.List; +import java.util.Set; + /** * A Service for Projects * @@ -152,7 +152,7 @@ void removeSharedTeacherFromProject(String username, Project project) * @return * @throws Exception */ - ModelAndView launchProject(Workgroup workgroup) throws Exception; + ModelAndView launchProject(Workgroup workgroup, String contextPath) throws Exception; /** * Launches a Preview of the Project. diff --git a/src/main/java/org/wise/portal/service/project/impl/ProjectServiceImpl.java b/src/main/java/org/wise/portal/service/project/impl/ProjectServiceImpl.java index 66c03c2b40..2be33dde87 100644 --- a/src/main/java/org/wise/portal/service/project/impl/ProjectServiceImpl.java +++ b/src/main/java/org/wise/portal/service/project/impl/ProjectServiceImpl.java @@ -301,8 +301,8 @@ public List getAdminProjectList() { /** * @see ProjectService#launchProject(Workgroup) */ - public ModelAndView launchProject(Workgroup workgroup) throws Exception { - return new ModelAndView(new RedirectView(generateStudentStartProjectUrlString(workgroup))); + public ModelAndView launchProject(Workgroup workgroup, String contextPath) throws Exception { + return new ModelAndView(new RedirectView(generateStudentStartProjectUrlString(workgroup, contextPath))); } /** @@ -313,20 +313,20 @@ public ModelAndView previewProject(PreviewProjectParameters params) throws Excep if (project.getWiseVersion().equals(4)) { return previewProjectWISE4(params, project); } else { - return previewProjectWISE5(project); + return previewProjectWISE5(params, project); } } - private ModelAndView previewProjectWISE5(Project project) { - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); - String wise5URL = wiseBaseURL + "/project/" + project.getId(); + private ModelAndView previewProjectWISE5(PreviewProjectParameters params, Project project) { + String contextPath = params.getHttpServletRequest().getContextPath(); + String wise5URL = contextPath + "/project/" + project.getId(); return new ModelAndView(new RedirectView(wise5URL)); } private ModelAndView previewProjectWISE4(PreviewProjectParameters params, Project project) { - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); + String contextPath = params.getHttpServletRequest().getContextPath(); String vleConfigUrl = - wiseBaseURL + "/vleconfig" + "?projectId=" + project.getId() + "&mode=preview"; + contextPath + "/vleconfig" + "?projectId=" + project.getId() + "&mode=preview"; String step = params.getStep(); if (step != null) { @@ -348,7 +348,7 @@ private ModelAndView previewProjectWISE4(PreviewProjectParameters params, Projec } ModelAndView modelAndView = new ModelAndView("vle"); - String vleurl = wiseBaseURL + "/vle/vle.html"; + String vleurl = contextPath + "/vle/vle.html"; modelAndView.addObject("vleurl", vleurl); modelAndView.addObject("vleConfigUrl", vleConfigUrl); String curriculumBaseWWW = wiseProperties.getProperty("curriculum_base_www"); @@ -393,15 +393,14 @@ public void updateProject(Project project, User user) throws NotAuthorizedExcept * @param workgroup Workgroup requesting to launch the project * @return url string that, when accessed, will launch the project */ - public String generateStudentStartProjectUrlString(Workgroup workgroup) { + public String generateStudentStartProjectUrlString(Workgroup workgroup, String contextPath) { Run run = workgroup.getRun(); Project project = run.getProject(); Integer wiseVersion = project.getWiseVersion(); - String wiseBaseURL = wiseProperties.getProperty("wiseBaseURL"); if (wiseVersion.equals(4)) { - return wiseBaseURL + "/student/vle/vle.html?runId=" + run.getId() + "&workgroupId=" + workgroup.getId(); + return contextPath + "/student/vle/vle.html?runId=" + run.getId() + "&workgroupId=" + workgroup.getId(); } else if (wiseVersion.equals(5)) { - return wiseBaseURL + "/student/run/" + run.getId(); + return contextPath + "/student/run/" + run.getId(); } return null; } diff --git a/src/main/resources/version.txt b/src/main/resources/version.txt index 6ab7204dab..bdbab22610 100644 --- a/src/main/resources/version.txt +++ b/src/main/resources/version.txt @@ -1 +1 @@ -5.7.5 +5.7.6 diff --git a/src/main/resources/wise_sample.properties b/src/main/resources/wise_sample.properties index 92c390f0df..94260be5a0 100644 --- a/src/main/resources/wise_sample.properties +++ b/src/main/resources/wise_sample.properties @@ -3,7 +3,7 @@ # This section is for portal definitions # NOTE FOR WINDOWS USERS: you can use paths like this: C:/apache-tomcat-7.0.32/webapps/curriculum instead of C:\.... # wise.name - name this WISE instance. Used when sending email to users. (e.g. "Hello from My Local WISE Instance", "Password changed on My Local WISE Instance") -# defaultLocale - the default locale for this WISE instance. [en, es, he, zh_CN,...] First-time users will see WISE in this locale when they visit the homepage. +# defaultLocale - the default locale for this WISE instance. [en, es, he, zh_CN,...] First-time users will see WISE in this locale when they visit the homepage. # wiseBaseURL - hosted wise location, viewable by browser. ex: if running locally, http://localhost:8080/wise. if running publicly, http://wise4.xyz.com:8080/wise, etc. # wiseBaseDir - absolute server path to the wise folder in CATALINA_HOME/webapps/wise. ex: /home/userx/apache-tomcat-6.0.29/webapps/wise # curriculum_base_www - hosted curriculum location, viewable by browser. ex: if running locally, http://localhost:8080/curriculum. if running publicly, http://wise4.xyz.com:8080/curriculum, etc. @@ -28,7 +28,6 @@ wise.name=My WISE Production Instance defaultLocale=en supportedLocales=en,ar,zh_TW,zh_CN,nl,fr,de,el,he,it,ja,ko,pt,es,th,tr -wiseBaseURL=http://localhost:8080/wise wiseBaseDir=/Users/wise/tomcat/webapps/wise curriculum_base_www=http://localhost:8080/curriculum curriculum_base_dir=/Users/wise/tomcat/webapps/curriculum @@ -70,7 +69,7 @@ hibernate.bytecode.use_reflection_optimizer=true hibernate.hbm2ddl.auto=none # Sample HSQLDB setting (for development server) -# You can also use HSQLDB embedded database, but it's not recommended for +# You can also use HSQLDB embedded database, but it's not recommended for # production/qa purposes. # Comment out the above MySQL section and uncomment the below. @@ -112,9 +111,9 @@ c3p0.idleConnectionTestPeriod=100 # - when a run is set up or shared # - when a project is shared # - daily reports for admins -# +# # One easy thing to do is create a gmail account and use it as an smtp server to send emails on behalf of the portal. -# With this approach, +# With this approach, # mail.user is the gmail username # mail.password is the gmail password # mail.from is the gmail address (ex xyz@gmail.com) @@ -167,12 +166,12 @@ cronJobExpression=0 0 0 * * ? ########## run codes prefixes ########## -# List available run codes for each locale here. -# Each line should follow this format runcode_prefixes_[locale]=comma separated values for runcode prefixes. +# List available run codes for each locale here. +# Each line should follow this format runcode_prefixes_[locale]=comma separated values for runcode prefixes. # For example, runcode_prefixes_en=urchin,lion for english, runcode_prefixes_es=queso,azul for spanish runcode_prefixes_en=Tiger,Lion,Fox,Owl,Panda,Hawk,Mole,Falcon,Orca,Eagle,Manta,Otter,Cat,Zebra,Flea,Wolf,Dragon,Seal,Cobra,Bug,Gecko,Fish,Koala,Mouse,Wombat,Shark,Whale,Sloth,Slug,Ant,Mantis,Bat,Rhino,Gator,Monkey,Swan,Ray,Crow,Goat,Marmot,Dog,Finch,Puffin,Fly,Camel,Kiwi,Spider,Lizard,Robin,Bear,Boa,Cow,Crab,Mule,Moth,Lynx,Moose,Skunk,Mako,Liger,Llama,Shrimp,Parrot,Pig,Clam,Urchin,Toucan,Frog,Toad,Turtle,Viper,Trout,Hare,Bee,Krill,Dodo,Tuna,Loon,Leech,Python,Wasp,Yak,Snake,Duck,Worm,Yeti runcode_prefixes_es=Cabra,Liebre,Oruga,Casa,Panda,Ciervo,Alce,Toro,Tigre,Rana,Sapo,Cebra,Rata,Selva,Sombra,Teja,Auto,Ronda,Libra,Tauro,Libro,Libre,Huerta,Pan,Ostra,Pez - + ########## VLE Properties ########## @@ -181,7 +180,7 @@ runcode_prefixes_es=Cabra,Liebre,Oruga,Casa,Panda,Ciervo,Alce,Toro,Tigre,Rana,Sa # remember to set maxFileUploadSize >= project_max_total_assets_size # student_max_asset_size: max size for any asset uploaded by student, in bytes. Default: 5MB=5242880 bytes # student_max_total_assets_size: max size for all assets combined uploaded by student, in bytes. Default: 10MB=10485760 bytes -# student_max_work_size: max size of student work (data in one node visit) for nodes in bytes. Default: 500K=512000 bytes +# student_max_work_size: max size of student work (data in one node visit) for nodes in bytes. Default: 500K=512000 bytes # # Note: if you set any of these values above 1MB, you'll also need to set mysql's max_allowed_packet value to allow saving the big data. # See this post: https://groups.google.com/d/topic/wise4-dev/CPS4AZEiquo/discussion diff --git a/src/main/resources/wise_sample_embedded_tomcat.properties b/src/main/resources/wise_sample_embedded_tomcat.properties index 10304366d1..fc6f5e6198 100644 --- a/src/main/resources/wise_sample_embedded_tomcat.properties +++ b/src/main/resources/wise_sample_embedded_tomcat.properties @@ -27,7 +27,6 @@ wise.name=My Local WISE Development Instance defaultLocale=en supportedLocales=en,ar,zh_TW,zh_CN,nl,fr,de,el,he,it,ja,ko,pt,es,th,tr -wiseBaseURL=/wise wiseBaseDir=/path_to_WISE_checkout/src/main/webapp/ curriculum_base_www=/wise/curriculum curriculum_base_dir=/path_to_WISE_checkout/src/main/webapp/curriculum @@ -175,7 +174,7 @@ runcode_prefixes_es=Cabra,Liebre,Oruga,Casa,Panda,Ciervo,Alce,Toro,Tigre,Rana,Sa # remember to set maxFileUploadSize >= project_max_total_assets_size # student_max_asset_size: max size for any asset uploaded by student, in bytes. Default: 5MB=5242880 bytes # student_max_total_assets_size: max size for all assets combined uploaded by student, in bytes. Default: 2MB=2097152 bytes -# student_max_work_size: max size of student work (data in one node visit) for nodes in bytes. Default: 500K=512000 bytes +# student_max_work_size: max size of student work (data in one node visit) for nodes in bytes. Default: 500K=512000 bytes # # Note: if you set any of these values above 1MB, you'll also need to set mysql's max_allowed_packet value to allow saving the big data. # See this post: https://groups.google.com/d/topic/wise4-dev/CPS4AZEiquo/discussion diff --git a/src/main/webapp/portal/admin/run/manageprojectruns.jsp b/src/main/webapp/portal/admin/run/manageprojectruns.jsp index 739d13a3ea..c1abf78261 100644 --- a/src/main/webapp/portal/admin/run/manageprojectruns.jsp +++ b/src/main/webapp/portal/admin/run/manageprojectruns.jsp @@ -3,479 +3,479 @@ - - -" /> -<spring:message code="wiseAdmin" /> + + + " /> + <spring:message code="wiseAdmin" /> -" media="screen" rel="stylesheet" type="text/css" /> -" media="screen" rel="stylesheet" type="text/css" /> -" media="screen" rel="stylesheet" type="text/css" /> -" media="screen" rel="stylesheet" type="text/css" /> -" media="screen" rel="stylesheet" type="text/css" /> -" media="screen" rel="stylesheet" type="text/css" /> -" media="screen" rel="stylesheet" type="text/css" /> + " media="screen" rel="stylesheet" type="text/css" /> + " media="screen" rel="stylesheet" type="text/css" /> + " media="screen" rel="stylesheet" type="text/css" /> + " media="screen" rel="stylesheet" type="text/css" /> + " media="screen" rel="stylesheet" type="text/css" /> + " media="screen" rel="stylesheet" type="text/css" /> + " media="screen" rel="stylesheet" type="text/css" /> - - - - - + + + + + - - + //setup archive and restore run dialogs + $('.archiveRun, .activateRun').on('click',function(){ + var title = $(this).attr('title'); + if($(this).hasClass('archiveRun')){ + var params = $(this).attr('id').replace('archiveRun_',''); + var path = "${contextPath}/teacher/run/manage/archiveRun.html?" + params; + } else if($(this).hasClass('activateRun')){ + var params = $(this).attr('id').replace('activateRun_',''); + var path = "${contextPath}/teacher/run/manage/startRun.html?" + params; + } + var div = $('#archiveRunDialog').html(''); + div.dialog({ + modal: true, + width: '600', + height: '450', + title: title, + position: 'center', + close: function(){ + if(document.getElementById('archiveIfrm').contentWindow['refreshRequired']){ + window.location.reload(); + } + $(this).html(''); + }, + buttons: { + Close: function(){ + $(this).dialog('close'); + } + } + }); + $("#archiveRunDialog > #archiveIfrm").attr('src',path); + }); + + // setup manage students dialog + $('.manageStudents').on('click',function(){ + var title = $(this).attr('title'); + var params = $(this).attr('id').replace('manageStudents_',''); + var path = "${contextPath}/teacher/management/viewmystudents?" + params; + var div = $('#manageStudentsDialog').html(''); + $('body').css('overflow','hidden'); + div.dialog({ + modal: true, + width: $(window).width() - 32, + height: $(window).height() - 32, + title: title, + position: 'center', + beforeClose: function() { + // check for unsaved changes and alert user if necessary + if(document.getElementById('manageStudentsIfrm').contentWindow['unsavedChanges']){ + var answer = confirm("Warning: You currently have unsaved changes to student teams. If you exit now, they will be discarded. To save your changes, choose 'Cancel' and click the 'SAVE CHANGES' button in the upper right corner.\n\nAre you sure you want to exit without saving?") + if(answer){ + return true; + } else { + return false; + }; + } else { + return true; + } + }, + close: function(){ + // refresh page if required (run title or student periods have been modified) + if(document.getElementById('manageStudentsIfrm').contentWindow['refreshRequired']){ + window.location.reload(); + } + $(this).html(''); + $('body').css('overflow','auto'); + }, + buttons: { + Exit: function(){ + $(this).dialog('close'); + } + } + }); + $("#manageStudentsDialog > #manageStudentsIfrm").attr('src',path); + }); + + //Set up view project details click action for each project id link + $('a.projectDetail').on('click',function(){ + var title = $(this).attr('title'); + if($(this).hasClass('projectDetail')){ + var projectId = $(this).attr('id').replace('projectDetail_',''); + } else if($(this).hasClass('projectInfo')){ + var projectId = $(this).attr('id').replace('projectInfo_',''); + } + var path = "${contextPath}/projectInfo?projectId=" + projectId; + var div = $('#projectDetailDialog').html(''); + div.dialog({ + modal: true, + width: '800', + height: '400', + title: title, + position: 'center', + close: function(){ $(this).html(''); }, + buttons: { + Close: function(){ + $(this).dialog('close'); + } + } + }); + $("#projectDetailDialog > #projectIfrm").attr('src',path); + }); + + + + var oTable = $('.runTable').dataTable({ + "sPaginationType": "full_numbers", + "iDisplayLength": 10, + "aLengthMenu": [[10, 25, 100, -1], [10, 25, 100, "All"]], + "bSort": false, + "oLanguage": { + "sInfo": " _START_-_END_ _TOTAL_", + "sInfoEmpty": "", + "sInfoFiltered": "", // (from _MAX_ total) + "sLengthMenu": " _MENU_ ", + "sProcessing": "", + "sZeroRecords": "", + "sInfoPostFix": "", + "sSearch": "", + "sUrl": "", + "oPaginate": { + "sFirst": "", + "sPrevious": "", + "sNext": "", + "sLast": "" + } + }, + "fnDrawCallback": function( oSettings ){ + // automatically scroll to top on page change + var tableID = $(this).attr('id'); + var targetOffset = $('#' + tableID).offset().top - 14; + if ($(window).scrollTop() > targetOffset){ + $('html,body').scrollTop(targetOffset); + } + }, + "sDom":'<"top"lip>rt<"bottom"ip><"clear">' + }); + + // define sort options + var sortParams = { + "items": [ + {"label": "", "column": 3, "direction": "desc" }, + {"label": "", "column": 3, "direction": "asc" }, + {"label": "", "column": 0, "direction": "asc" }, + {"label": "", "column": 0, "direction": "desc" } + ] + }; + + // setup sorting + function setSort(index,sortParams,wrapper) { + if(sortParams.items.length){ + // insert sort options into DOM + var sortHtml = '
'; + $(wrapper).children('.top').prepend(sortHtml); + + $('#sort_' + index).change(function(){ + $.fn.dataTableExt.iApiIndex = index; + var i = $('option:selected', '#sort_' + index).index(); + oTable.fnSort( [ [sortParams.items[i].column,sortParams.items[i].direction] ] ); + }); + } + }; + + var i; + for(i=0; i", + "sClearSearchLabel": "", + "sFilterLabel": "", + "sSearchLabel": "", + "aSearchOpts": [ + { + "identifier": "keyword", "label": " ", "column": 0, "maxlength": 50 + }, + { + "identifier": "period", "label": " ", "column": 7, "maxlength": 30, + "regexreplace": {"match": "/,\s*/gi", "replacement": " "}, + "instructions": "" + } + ] + }); + + // add sort logic + setSort(i,sortParams,wrapper); + + // reset cloumn widths on run tables (datatables seems to change these) + $('.runHeader').width(215); + $('.studentHeader').width(145); + $('.teacherHeader').width(115); + $('.toolsHeader').width(170); + + oTable.fnSort( [ [7,'desc'] ] ); + } + + // Make top header scroll with page + var $stickyEl = $('.dataTables_wrapper .top'); + if($stickyEl.length>0){ + var elTop = $stickyEl.offset().top, + width = $stickyEl.width(); + $(window).scroll(function() { + var windowTop = $(window).scrollTop(); + if (windowTop > elTop) { + $stickyEl.addClass('sticky'); + $stickyEl.css('width',width); + } else { + $stickyEl.removeClass('sticky'); + $stickyEl.css('width','auto'); + } + }); + } + }); +
-
- -
+
+ +
+ +
+ +
+
+ +
-
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
${run.name}
+ + + + + +
+ " alt="shared project" /> + ${run.owner.userDetails.firstname} ${run.owner.userDetails.lastname} +
+ + ${run.name}');"> +
+
-
-
- -
- -
- - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - -
-
${run.name}
- - - - - -
- " alt="shared project" /> - ${run.owner.userDetails.firstname} ${run.owner.userDetails.lastname} -
- - ${run.name}');"> -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ${run.owner.userDetails.firstname} ${run.owner.userDetails.lastname} -
${run.runcode}
${run.id}
">${run.project.id}
">${run.project.parentProjectId}
- : ${run.name} ( ${run.id})">settings" /> -
-
- - - - - - - - - - - - -
${period.name} - : ${run.name} ( ${run.id})" id="runId=${run.id}&periodName=${period.name}">${fn:length(period.members)}  -
: ${run.name} ( ${run.id})" id="runId=${run.id}">groups" />
-
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ${run.owner.userDetails.firstname} ${run.owner.userDetails.lastname} +
${run.runcode}
${run.id}
">${run.project.id}
">${run.project.parentProjectId}
+ : ${run.name} ( ${run.id})">settings" /> +
+
+ + + + + + + + + + + + +
${period.name} + : ${run.name} ( ${run.id})" id="runId=${run.id}&periodName=${period.name}">${fn:length(period.members)}  +
: ${run.name} ( ${run.id})" id="runId=${run.id}">groups" />
+
- - - - ${run.starttime}${source}${ownership} - ${period.name}, -
-
-
- - - <%@ include file="../../footer.jsp"%> + + + +
${run.starttime}${source}${ownership} + ${period.name}, +
+
+
+
+
+ <%@ include file="../../footer.jsp"%>
@@ -485,4 +485,4 @@
- \ No newline at end of file + diff --git a/src/main/webapp/portal/author.jsp b/src/main/webapp/portal/author.jsp index 9e8412027d..a8043e5c01 100644 --- a/src/main/webapp/portal/author.jsp +++ b/src/main/webapp/portal/author.jsp @@ -12,7 +12,7 @@ <%@ include file="favicon.jsp"%> - + diff --git a/src/main/webapp/portal/classroomMonitor.jsp b/src/main/webapp/portal/classroomMonitor.jsp index c1904e25e6..42b5964854 100644 --- a/src/main/webapp/portal/classroomMonitor.jsp +++ b/src/main/webapp/portal/classroomMonitor.jsp @@ -12,7 +12,7 @@ <%@ include file="favicon.jsp"%> - + diff --git a/src/main/webapp/portal/student.jsp b/src/main/webapp/portal/student.jsp index 84a554e197..9aadbd9e65 100644 --- a/src/main/webapp/portal/student.jsp +++ b/src/main/webapp/portal/student.jsp @@ -13,7 +13,7 @@ <%@ include file="favicon.jsp"%> - + 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/main.es6 b/src/main/webapp/wise5/authoringTool/main.es6 index ab6bdef9e6..2cb103bbf1 100644 --- a/src/main/webapp/wise5/authoringTool/main.es6 +++ b/src/main/webapp/wise5/authoringTool/main.es6 @@ -28,6 +28,7 @@ import '../components/conceptMap/conceptMapComponentModule'; import ConfigService from '../services/configService'; import CRaterService from '../services/cRaterService'; import '../directives/components'; +import ComponentService from '../components/componentService'; import '../components/discussion/discussionComponentModule'; import '../components/draw/drawComponentModule'; import '../components/embedded/embeddedComponentModule'; @@ -50,6 +51,7 @@ import ProjectAssetService from '../services/projectAssetService'; import ProjectController from './project/projectController'; import ProjectHistoryController from './history/projectHistoryController'; import ProjectInfoController from './info/projectInfoController'; +import PlanningService from '../services/planningService'; import ProjectService from '../services/projectService'; import SessionService from '../services/sessionService'; import SpaceService from '../services/spaceService'; @@ -101,11 +103,13 @@ let authoringModule = angular.module('authoring', [ ]) .service(AnnotationService.name, AnnotationService) .service(AuthorWebSocketService.name, AuthorWebSocketService) + .service(ComponentService.name, ComponentService) .service(ConfigService.name, ConfigService) .service(CRaterService.name, CRaterService) .service(NodeService.name, NodeService) .service(NotebookService.name, NotebookService) .service(NotificationService.name, NotificationService) + .service(PlanningService.name, PlanningService) .service(ProjectService.name, AuthoringToolProjectService) .service(ProjectAssetService.name, ProjectAssetService) .service(SessionService.name, SessionService) diff --git a/src/main/webapp/wise5/authoringTool/main.js b/src/main/webapp/wise5/authoringTool/main.js index af5a3a87f5..4dda2e36df 100644 --- a/src/main/webapp/wise5/authoringTool/main.js +++ b/src/main/webapp/wise5/authoringTool/main.js @@ -82,6 +82,10 @@ var _cRaterService2 = _interopRequireDefault(_cRaterService); require('../directives/components'); +var _componentService = require('../components/componentService'); + +var _componentService2 = _interopRequireDefault(_componentService); + require('../components/discussion/discussionComponentModule'); require('../components/draw/drawComponentModule'); @@ -144,6 +148,10 @@ var _projectInfoController = require('./info/projectInfoController'); var _projectInfoController2 = _interopRequireDefault(_projectInfoController); +var _planningService = require('../services/planningService'); + +var _planningService2 = _interopRequireDefault(_planningService); + var _projectService = require('../services/projectService'); var _projectService2 = _interopRequireDefault(_projectService); @@ -198,7 +206,7 @@ var _moment2 = _interopRequireDefault(_moment); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var authoringModule = _angular2.default.module('authoring', [(0, _angularDragula2.default)(_angular2.default), 'angularMoment', 'angular-toArrayFilter', 'animationComponentModule', 'audioOscillatorComponentModule', 'authoringTool.components', 'components', 'conceptMapComponentModule', 'discussionComponentModule', 'drawComponentModule', 'embeddedComponentModule', 'filters', 'graphComponentModule', 'highcharts-ng', 'htmlComponentModule', 'labelComponentModule', 'matchComponentModule', 'multipleChoiceComponentModule', 'ngAnimate', 'ngAria', 'ngFileUpload', 'ngMaterial', 'ngSanitize', 'ngWebSocket', 'notebook', 'openResponseComponentModule', 'outsideURLComponentModule', 'pascalprecht.translate', 'summernote', 'tableComponentModule', 'ui.router']).service(_annotationService2.default.name, _annotationService2.default).service(_authorWebSocketService2.default.name, _authorWebSocketService2.default).service(_configService2.default.name, _configService2.default).service(_cRaterService2.default.name, _cRaterService2.default).service(_nodeService2.default.name, _nodeService2.default).service(_notebookService2.default.name, _notebookService2.default).service(_notificationService2.default.name, _notificationService2.default).service(_projectService2.default.name, _authoringToolProjectService2.default).service(_projectAssetService2.default.name, _projectAssetService2.default).service(_sessionService2.default.name, _sessionService2.default).service(_spaceService2.default.name, _spaceService2.default).service(_studentAssetService2.default.name, _studentAssetService2.default).service(_studentDataService2.default.name, _studentDataService2.default).service(_studentStatusService2.default.name, _studentStatusService2.default).service(_studentWebSocketService2.default.name, _studentWebSocketService2.default).service(_teacherDataService2.default.name, _teacherDataService2.default).service(_teacherWebSocketService2.default.name, _teacherWebSocketService2.default).service(_utilService2.default.name, _utilService2.default).controller(_authoringToolController2.default.name, _authoringToolController2.default).controller(_authoringToolMainController2.default.name, _authoringToolMainController2.default).controller(_authoringToolNewProjectController2.default.name, _authoringToolNewProjectController2.default).controller(_authorNotebookController2.default.name, _authorNotebookController2.default).controller(_nodeAuthoringController2.default.name, _nodeAuthoringController2.default).controller(_projectAssetController2.default.name, _projectAssetController2.default).controller(_projectController2.default.name, _projectController2.default).controller(_projectHistoryController2.default.name, _projectHistoryController2.default).controller(_projectInfoController2.default.name, _projectInfoController2.default).controller(_wiseLinkAuthoringController2.default.name, _wiseLinkAuthoringController2.default).config(['$urlRouterProvider', '$stateProvider', '$translateProvider', '$translatePartialLoaderProvider', '$controllerProvider', '$mdThemingProvider', function ($urlRouterProvider, $stateProvider, $translateProvider, $translatePartialLoaderProvider, $controllerProvider, $mdThemingProvider) { +var authoringModule = _angular2.default.module('authoring', [(0, _angularDragula2.default)(_angular2.default), 'angularMoment', 'angular-toArrayFilter', 'animationComponentModule', 'audioOscillatorComponentModule', 'authoringTool.components', 'components', 'conceptMapComponentModule', 'discussionComponentModule', 'drawComponentModule', 'embeddedComponentModule', 'filters', 'graphComponentModule', 'highcharts-ng', 'htmlComponentModule', 'labelComponentModule', 'matchComponentModule', 'multipleChoiceComponentModule', 'ngAnimate', 'ngAria', 'ngFileUpload', 'ngMaterial', 'ngSanitize', 'ngWebSocket', 'notebook', 'openResponseComponentModule', 'outsideURLComponentModule', 'pascalprecht.translate', 'summernote', 'tableComponentModule', 'ui.router']).service(_annotationService2.default.name, _annotationService2.default).service(_authorWebSocketService2.default.name, _authorWebSocketService2.default).service(_componentService2.default.name, _componentService2.default).service(_configService2.default.name, _configService2.default).service(_cRaterService2.default.name, _cRaterService2.default).service(_nodeService2.default.name, _nodeService2.default).service(_notebookService2.default.name, _notebookService2.default).service(_notificationService2.default.name, _notificationService2.default).service(_planningService2.default.name, _planningService2.default).service(_projectService2.default.name, _authoringToolProjectService2.default).service(_projectAssetService2.default.name, _projectAssetService2.default).service(_sessionService2.default.name, _sessionService2.default).service(_spaceService2.default.name, _spaceService2.default).service(_studentAssetService2.default.name, _studentAssetService2.default).service(_studentDataService2.default.name, _studentDataService2.default).service(_studentStatusService2.default.name, _studentStatusService2.default).service(_studentWebSocketService2.default.name, _studentWebSocketService2.default).service(_teacherDataService2.default.name, _teacherDataService2.default).service(_teacherWebSocketService2.default.name, _teacherWebSocketService2.default).service(_utilService2.default.name, _utilService2.default).controller(_authoringToolController2.default.name, _authoringToolController2.default).controller(_authoringToolMainController2.default.name, _authoringToolMainController2.default).controller(_authoringToolNewProjectController2.default.name, _authoringToolNewProjectController2.default).controller(_authorNotebookController2.default.name, _authorNotebookController2.default).controller(_nodeAuthoringController2.default.name, _nodeAuthoringController2.default).controller(_projectAssetController2.default.name, _projectAssetController2.default).controller(_projectController2.default.name, _projectController2.default).controller(_projectHistoryController2.default.name, _projectHistoryController2.default).controller(_projectInfoController2.default.name, _projectInfoController2.default).controller(_wiseLinkAuthoringController2.default.name, _wiseLinkAuthoringController2.default).config(['$urlRouterProvider', '$stateProvider', '$translateProvider', '$translatePartialLoaderProvider', '$controllerProvider', '$mdThemingProvider', function ($urlRouterProvider, $stateProvider, $translateProvider, $translatePartialLoaderProvider, $controllerProvider, $mdThemingProvider) { $urlRouterProvider.otherwise('/'); diff --git a/src/main/webapp/wise5/authoringTool/main.js.map b/src/main/webapp/wise5/authoringTool/main.js.map index 7da41e75bd..1be1d23e9b 100644 --- a/src/main/webapp/wise5/authoringTool/main.js.map +++ b/src/main/webapp/wise5/authoringTool/main.js.map @@ -1 +1 @@ -{"version":3,"sources":["main.es6"],"names":["authoringModule","module","service","name","controller","config","$urlRouterProvider","$stateProvider","$translateProvider","$translatePartialLoaderProvider","$controllerProvider","$mdThemingProvider","otherwise","state","url","abstract","templateUrl","controllerAs","resolve","ConfigService","retrieveConfig","window","configURL","language","$translate","use","getLocale","sessionTimers","SessionService","initializeSession","projectConfig","$stateParams","projectId","project","ProjectService","retrieveProject","projectAssets","ProjectAssetService","retrieveProjectAssets","webSocket","AuthorWebSocketService","initialize","addPart","useLoader","urlTemplate","registerAvailableLanguageKeys","determinePreferredLanguage","fallbackLanguage","useSanitizeValueStrategy","definePalette","undefined","theme","primaryPalette","accentPalette","warnPalette","lightMap","extendPalette","setDefaultTheme","enableBrowserColor","updateLocale","calendar","lastDay","sameDay","nextDay","lastWeek","nextWeek","sameElse"],"mappings":"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","file":"main.js","sourcesContent":["'use strict';\n\nimport '../themes/default/js/webfonts';\nimport 'jquery';\nimport angular from 'angular';\nimport angularDragula from 'angular-dragula';\nimport 'ng-file-upload';\nimport 'highcharts-ng';\nimport 'angular-ui-router';\nimport 'angular-material';\nimport 'angular-moment';\nimport 'angular-sanitize';\nimport 'lib/angular-toArrayFilter/toArrayFilter';\nimport 'angular-translate';\nimport 'angular-translate-loader-partial';\nimport 'angular-websocket';\nimport '../components/animation/animationComponentModule';\nimport AnnotationService from '../services/annotationService';\nimport '../components/audioOscillator/audioOscillatorComponentModule';\nimport './components/authoringToolComponents';\nimport AuthoringToolController from './authoringToolController';\nimport AuthoringToolMainController from './main/authoringToolMainController';\nimport AuthoringToolNewProjectController from './main/authoringToolNewProjectController';\nimport AuthoringToolProjectService from './authoringToolProjectService';\nimport AuthorNotebookController from './notebook/authorNotebookController';\nimport AuthorWebSocketService from '../services/authorWebSocketService';\nimport '../components/conceptMap/conceptMapComponentModule';\nimport ConfigService from '../services/configService';\nimport CRaterService from '../services/cRaterService';\nimport '../directives/components';\nimport '../components/discussion/discussionComponentModule';\nimport '../components/draw/drawComponentModule';\nimport '../components/embedded/embeddedComponentModule';\nimport '../filters/filters';\nimport '../lib/highcharts@4.2.1';\nimport '../components/graph/graphComponentModule';\nimport '../components/html/htmlComponentModule';\nimport '../components/label/labelComponentModule';\nimport '../components/match/matchComponentModule';\nimport '../components/multipleChoice/multipleChoiceComponentModule';\nimport NodeAuthoringController from './node/nodeAuthoringController';\nimport NodeService from '../services/nodeService';\nimport '../directives/notebook/notebook';\nimport NotebookService from '../services/notebookService';\nimport NotificationService from '../services/notificationService';\nimport '../components/openResponse/openResponseComponentModule';\nimport '../components/outsideURL/outsideURLComponentModule';\nimport ProjectAssetController from './asset/projectAssetController';\nimport ProjectAssetService from '../services/projectAssetService';\nimport ProjectController from './project/projectController';\nimport ProjectHistoryController from './history/projectHistoryController';\nimport ProjectInfoController from './info/projectInfoController';\nimport ProjectService from '../services/projectService';\nimport SessionService from '../services/sessionService';\nimport SpaceService from '../services/spaceService';\nimport StudentAssetService from '../services/studentAssetService';\nimport StudentDataService from '../services/studentDataService';\nimport StudentStatusService from '../services/studentStatusService';\nimport StudentWebSocketService from '../services/studentWebSocketService';\nimport '../components/table/tableComponentModule';\nimport TeacherDataService from '../services/teacherDataService';\nimport TeacherWebSocketService from '../services/teacherWebSocketService';\nimport UtilService from '../services/utilService';\nimport WISELinkAuthoringController from './wiseLink/wiseLinkAuthoringController';\n\nimport 'lib/angular-summernote/dist/angular-summernote.min';\nimport moment from 'moment';\n\nlet authoringModule = angular.module('authoring', [\n angularDragula(angular),\n 'angularMoment',\n 'angular-toArrayFilter',\n 'animationComponentModule',\n 'audioOscillatorComponentModule',\n 'authoringTool.components',\n 'components',\n 'conceptMapComponentModule',\n 'discussionComponentModule',\n 'drawComponentModule',\n 'embeddedComponentModule',\n 'filters',\n 'graphComponentModule',\n 'highcharts-ng',\n 'htmlComponentModule',\n 'labelComponentModule',\n 'matchComponentModule',\n 'multipleChoiceComponentModule',\n 'ngAnimate',\n 'ngAria',\n 'ngFileUpload',\n 'ngMaterial',\n 'ngSanitize',\n 'ngWebSocket',\n 'notebook',\n 'openResponseComponentModule',\n 'outsideURLComponentModule',\n 'pascalprecht.translate',\n 'summernote',\n 'tableComponentModule',\n 'ui.router'\n ])\n .service(AnnotationService.name, AnnotationService)\n .service(AuthorWebSocketService.name, AuthorWebSocketService)\n .service(ConfigService.name, ConfigService)\n .service(CRaterService.name, CRaterService)\n .service(NodeService.name, NodeService)\n .service(NotebookService.name, NotebookService)\n .service(NotificationService.name, NotificationService)\n .service(ProjectService.name, AuthoringToolProjectService)\n .service(ProjectAssetService.name, ProjectAssetService)\n .service(SessionService.name, SessionService)\n .service(SpaceService.name, SpaceService)\n .service(StudentAssetService.name, StudentAssetService)\n .service(StudentDataService.name, StudentDataService)\n .service(StudentStatusService.name, StudentStatusService)\n .service(StudentWebSocketService.name, StudentWebSocketService)\n .service(TeacherDataService.name, TeacherDataService)\n .service(TeacherWebSocketService.name, TeacherWebSocketService)\n .service(UtilService.name, UtilService)\n .controller(AuthoringToolController.name, AuthoringToolController)\n .controller(AuthoringToolMainController.name, AuthoringToolMainController)\n .controller(AuthoringToolNewProjectController.name, AuthoringToolNewProjectController)\n .controller(AuthorNotebookController.name, AuthorNotebookController)\n .controller(NodeAuthoringController.name, NodeAuthoringController)\n .controller(ProjectAssetController.name, ProjectAssetController)\n .controller(ProjectController.name, ProjectController)\n .controller(ProjectHistoryController.name, ProjectHistoryController)\n .controller(ProjectInfoController.name, ProjectInfoController)\n .controller(WISELinkAuthoringController.name, WISELinkAuthoringController)\n .config([\n '$urlRouterProvider',\n '$stateProvider',\n '$translateProvider',\n '$translatePartialLoaderProvider',\n '$controllerProvider',\n '$mdThemingProvider',\n ($urlRouterProvider,\n $stateProvider,\n $translateProvider,\n $translatePartialLoaderProvider,\n $controllerProvider,\n $mdThemingProvider) => {\n\n $urlRouterProvider.otherwise('/');\n\n $stateProvider\n .state('root', {\n url: '',\n abstract: true,\n templateUrl: 'wise5/authoringTool/authoringTool.html',\n controller: 'AuthoringToolController',\n controllerAs: 'authoringToolController',\n resolve: {}\n })\n .state('root.main', {\n url: '/',\n templateUrl: 'wise5/authoringTool/main/main.html',\n controller: 'AuthoringToolMainController',\n controllerAs: 'authoringToolMainController',\n resolve: {\n config: (ConfigService) => {\n return ConfigService.retrieveConfig(window.configURL);\n },\n language: ($translate, ConfigService, config) => {\n $translate.use(ConfigService.getLocale());\n },\n sessionTimers: (SessionService, config) => {\n return SessionService.initializeSession();\n }\n }\n })\n .state('root.new', {\n url: '/new',\n templateUrl: 'wise5/authoringTool/main/new.html',\n controller: 'AuthoringToolNewProjectController',\n controllerAs: 'authoringToolNewProjectController',\n resolve: {\n config: (ConfigService) => {\n return ConfigService.retrieveConfig(window.configURL);\n },\n language: ($translate, ConfigService, config) => {\n $translate.use(ConfigService.getLocale());\n },\n sessionTimers: (SessionService, config) => {\n return SessionService.initializeSession();\n }\n }\n })\n .state('root.project', {\n url: '/project/:projectId',\n templateUrl: 'wise5/authoringTool/project/project.html',\n controller: 'ProjectController',\n controllerAs: 'projectController',\n resolve: {\n projectConfig: (ConfigService, $stateParams) => {\n const configURL = window.configURL + '/' + $stateParams.projectId;\n return ConfigService.retrieveConfig(configURL);\n },\n project: (ProjectService, projectConfig) => {\n return ProjectService.retrieveProject();\n },\n projectAssets: (ProjectAssetService, projectConfig, project) => {\n return ProjectAssetService.retrieveProjectAssets();\n },\n language: ($translate, ConfigService, projectConfig) => {\n $translate.use(ConfigService.getLocale());\n },\n sessionTimers: (SessionService, projectConfig) => {\n return SessionService.initializeSession();\n },\n webSocket: (AuthorWebSocketService, projectConfig) => {\n return AuthorWebSocketService.initialize();\n }\n }\n })\n .state('root.project.node', {\n url: '/node/:nodeId',\n templateUrl: 'wise5/authoringTool/node/node.html',\n controller: 'NodeAuthoringController',\n controllerAs: 'nodeAuthoringController',\n resolve: {}\n })\n .state('root.project.nodeConstraints', {\n url: '/node/constraints/:nodeId',\n templateUrl: 'wise5/authoringTool/node/node.html',\n controller: 'NodeAuthoringController',\n controllerAs: 'nodeAuthoringController',\n resolve: {}\n })\n .state('root.project.nodeEditPaths', {\n url: '/node/editpaths/:nodeId',\n templateUrl: 'wise5/authoringTool/node/node.html',\n controller: 'NodeAuthoringController',\n controllerAs: 'nodeAuthoringController',\n resolve: {}\n })\n .state('root.project.asset', {\n url: '/asset',\n templateUrl: 'wise5/authoringTool/asset/asset.html',\n controller: 'ProjectAssetController',\n controllerAs: 'projectAssetController',\n resolve: {}\n })\n .state('root.project.info', {\n url: '/info',\n templateUrl: 'wise5/authoringTool/info/info.html',\n controller: 'ProjectInfoController',\n controllerAs: 'projectInfoController',\n resolve: {}\n })\n .state('root.project.history', {\n url: '/history',\n templateUrl: 'wise5/authoringTool/history/history.html',\n controller: 'ProjectHistoryController',\n controllerAs: 'projectHistoryController',\n resolve: {}\n })\n .state('root.project.notebook', {\n url: '/notebook',\n templateUrl: 'wise5/authoringTool/notebook/notebook.html',\n controller: 'AuthorNotebookController',\n controllerAs: 'authorNotebookController',\n resolve: {}\n });\n\n $translatePartialLoaderProvider.addPart('i18n');\n $translatePartialLoaderProvider.addPart('authoringTool/i18n');\n $translateProvider\n .useLoader('$translatePartialLoader', {\n urlTemplate: 'wise5/{part}/i18n_{lang}.json'\n })\n .registerAvailableLanguageKeys(\n ['el','en','es','ja','ko','pt','tr','zh_CN','zh_TW'], {\n 'en_US': 'en',\n 'en_UK': 'en'\n })\n .determinePreferredLanguage()\n .fallbackLanguage(['en'])\n .useSanitizeValueStrategy('sanitizeParameters', 'escape');\n\n $mdThemingProvider.definePalette('accent', {\n '50': 'fde9e6',\n '100': 'fbcbc4',\n '200': 'f8aca1',\n '300': 'f4897b',\n '400': 'f2705f',\n '500': 'f05843',\n '600': 'da503c',\n '700': 'c34736',\n '800': 'aa3e2f',\n '900': '7d2e23',\n 'A100': 'ff897d',\n 'A200': 'ff7061',\n 'A400': 'ff3829',\n 'A700': 'cc1705',\n 'contrastDefaultColor': 'light',\n 'contrastDarkColors': ['50', '100', '200', '300', 'A100'],\n 'contrastLightColors': undefined\n });\n $mdThemingProvider.theme('default')\n .primaryPalette('deep-purple', { 'default': '400' })\n .accentPalette('accent', { 'default': '500' })\n .warnPalette('red', { 'default': '800' });\n const lightMap = $mdThemingProvider.extendPalette('grey', {\n 'A100': 'ffffff'\n });\n $mdThemingProvider.definePalette('light', lightMap);\n $mdThemingProvider.theme('light')\n .primaryPalette('light', { 'default': 'A100' })\n .accentPalette('pink', { 'default': '900' });\n $mdThemingProvider.setDefaultTheme('default');\n $mdThemingProvider.enableBrowserColor();\n\n // moment.js default overrides\n // TODO: add i18n support\n moment.updateLocale('en', {\n calendar: {\n lastDay : '[Yesterday at] LT',\n sameDay : '[Today at] LT',\n nextDay : '[Tomorrow at] LT',\n lastWeek : '[last] dddd [at] LT',\n nextWeek : 'dddd [at] LT',\n sameElse : 'll'\n }\n });\n }\n]);\n\nexport default authoringModule;\n"]} \ No newline at end of file +{"version":3,"sources":["main.es6"],"names":["authoringModule","module","service","name","controller","config","$urlRouterProvider","$stateProvider","$translateProvider","$translatePartialLoaderProvider","$controllerProvider","$mdThemingProvider","otherwise","state","url","abstract","templateUrl","controllerAs","resolve","ConfigService","retrieveConfig","window","configURL","language","$translate","use","getLocale","sessionTimers","SessionService","initializeSession","projectConfig","$stateParams","projectId","project","ProjectService","retrieveProject","projectAssets","ProjectAssetService","retrieveProjectAssets","webSocket","AuthorWebSocketService","initialize","addPart","useLoader","urlTemplate","registerAvailableLanguageKeys","determinePreferredLanguage","fallbackLanguage","useSanitizeValueStrategy","definePalette","undefined","theme","primaryPalette","accentPalette","warnPalette","lightMap","extendPalette","setDefaultTheme","enableBrowserColor","updateLocale","calendar","lastDay","sameDay","nextDay","lastWeek","nextWeek","sameElse"],"mappings":"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","file":"main.js","sourcesContent":["'use strict';\n\nimport '../themes/default/js/webfonts';\nimport 'jquery';\nimport angular from 'angular';\nimport angularDragula from 'angular-dragula';\nimport 'ng-file-upload';\nimport 'highcharts-ng';\nimport 'angular-ui-router';\nimport 'angular-material';\nimport 'angular-moment';\nimport 'angular-sanitize';\nimport 'lib/angular-toArrayFilter/toArrayFilter';\nimport 'angular-translate';\nimport 'angular-translate-loader-partial';\nimport 'angular-websocket';\nimport '../components/animation/animationComponentModule';\nimport AnnotationService from '../services/annotationService';\nimport '../components/audioOscillator/audioOscillatorComponentModule';\nimport './components/authoringToolComponents';\nimport AuthoringToolController from './authoringToolController';\nimport AuthoringToolMainController from './main/authoringToolMainController';\nimport AuthoringToolNewProjectController from './main/authoringToolNewProjectController';\nimport AuthoringToolProjectService from './authoringToolProjectService';\nimport AuthorNotebookController from './notebook/authorNotebookController';\nimport AuthorWebSocketService from '../services/authorWebSocketService';\nimport '../components/conceptMap/conceptMapComponentModule';\nimport ConfigService from '../services/configService';\nimport CRaterService from '../services/cRaterService';\nimport '../directives/components';\nimport ComponentService from '../components/componentService';\nimport '../components/discussion/discussionComponentModule';\nimport '../components/draw/drawComponentModule';\nimport '../components/embedded/embeddedComponentModule';\nimport '../filters/filters';\nimport '../lib/highcharts@4.2.1';\nimport '../components/graph/graphComponentModule';\nimport '../components/html/htmlComponentModule';\nimport '../components/label/labelComponentModule';\nimport '../components/match/matchComponentModule';\nimport '../components/multipleChoice/multipleChoiceComponentModule';\nimport NodeAuthoringController from './node/nodeAuthoringController';\nimport NodeService from '../services/nodeService';\nimport '../directives/notebook/notebook';\nimport NotebookService from '../services/notebookService';\nimport NotificationService from '../services/notificationService';\nimport '../components/openResponse/openResponseComponentModule';\nimport '../components/outsideURL/outsideURLComponentModule';\nimport ProjectAssetController from './asset/projectAssetController';\nimport ProjectAssetService from '../services/projectAssetService';\nimport ProjectController from './project/projectController';\nimport ProjectHistoryController from './history/projectHistoryController';\nimport ProjectInfoController from './info/projectInfoController';\nimport PlanningService from '../services/planningService';\nimport ProjectService from '../services/projectService';\nimport SessionService from '../services/sessionService';\nimport SpaceService from '../services/spaceService';\nimport StudentAssetService from '../services/studentAssetService';\nimport StudentDataService from '../services/studentDataService';\nimport StudentStatusService from '../services/studentStatusService';\nimport StudentWebSocketService from '../services/studentWebSocketService';\nimport '../components/table/tableComponentModule';\nimport TeacherDataService from '../services/teacherDataService';\nimport TeacherWebSocketService from '../services/teacherWebSocketService';\nimport UtilService from '../services/utilService';\nimport WISELinkAuthoringController from './wiseLink/wiseLinkAuthoringController';\n\nimport 'lib/angular-summernote/dist/angular-summernote.min';\nimport moment from 'moment';\n\nlet authoringModule = angular.module('authoring', [\n angularDragula(angular),\n 'angularMoment',\n 'angular-toArrayFilter',\n 'animationComponentModule',\n 'audioOscillatorComponentModule',\n 'authoringTool.components',\n 'components',\n 'conceptMapComponentModule',\n 'discussionComponentModule',\n 'drawComponentModule',\n 'embeddedComponentModule',\n 'filters',\n 'graphComponentModule',\n 'highcharts-ng',\n 'htmlComponentModule',\n 'labelComponentModule',\n 'matchComponentModule',\n 'multipleChoiceComponentModule',\n 'ngAnimate',\n 'ngAria',\n 'ngFileUpload',\n 'ngMaterial',\n 'ngSanitize',\n 'ngWebSocket',\n 'notebook',\n 'openResponseComponentModule',\n 'outsideURLComponentModule',\n 'pascalprecht.translate',\n 'summernote',\n 'tableComponentModule',\n 'ui.router'\n ])\n .service(AnnotationService.name, AnnotationService)\n .service(AuthorWebSocketService.name, AuthorWebSocketService)\n .service(ComponentService.name, ComponentService)\n .service(ConfigService.name, ConfigService)\n .service(CRaterService.name, CRaterService)\n .service(NodeService.name, NodeService)\n .service(NotebookService.name, NotebookService)\n .service(NotificationService.name, NotificationService)\n .service(PlanningService.name, PlanningService)\n .service(ProjectService.name, AuthoringToolProjectService)\n .service(ProjectAssetService.name, ProjectAssetService)\n .service(SessionService.name, SessionService)\n .service(SpaceService.name, SpaceService)\n .service(StudentAssetService.name, StudentAssetService)\n .service(StudentDataService.name, StudentDataService)\n .service(StudentStatusService.name, StudentStatusService)\n .service(StudentWebSocketService.name, StudentWebSocketService)\n .service(TeacherDataService.name, TeacherDataService)\n .service(TeacherWebSocketService.name, TeacherWebSocketService)\n .service(UtilService.name, UtilService)\n .controller(AuthoringToolController.name, AuthoringToolController)\n .controller(AuthoringToolMainController.name, AuthoringToolMainController)\n .controller(AuthoringToolNewProjectController.name, AuthoringToolNewProjectController)\n .controller(AuthorNotebookController.name, AuthorNotebookController)\n .controller(NodeAuthoringController.name, NodeAuthoringController)\n .controller(ProjectAssetController.name, ProjectAssetController)\n .controller(ProjectController.name, ProjectController)\n .controller(ProjectHistoryController.name, ProjectHistoryController)\n .controller(ProjectInfoController.name, ProjectInfoController)\n .controller(WISELinkAuthoringController.name, WISELinkAuthoringController)\n .config([\n '$urlRouterProvider',\n '$stateProvider',\n '$translateProvider',\n '$translatePartialLoaderProvider',\n '$controllerProvider',\n '$mdThemingProvider',\n ($urlRouterProvider,\n $stateProvider,\n $translateProvider,\n $translatePartialLoaderProvider,\n $controllerProvider,\n $mdThemingProvider) => {\n\n $urlRouterProvider.otherwise('/');\n\n $stateProvider\n .state('root', {\n url: '',\n abstract: true,\n templateUrl: 'wise5/authoringTool/authoringTool.html',\n controller: 'AuthoringToolController',\n controllerAs: 'authoringToolController',\n resolve: {}\n })\n .state('root.main', {\n url: '/',\n templateUrl: 'wise5/authoringTool/main/main.html',\n controller: 'AuthoringToolMainController',\n controllerAs: 'authoringToolMainController',\n resolve: {\n config: (ConfigService) => {\n return ConfigService.retrieveConfig(window.configURL);\n },\n language: ($translate, ConfigService, config) => {\n $translate.use(ConfigService.getLocale());\n },\n sessionTimers: (SessionService, config) => {\n return SessionService.initializeSession();\n }\n }\n })\n .state('root.new', {\n url: '/new',\n templateUrl: 'wise5/authoringTool/main/new.html',\n controller: 'AuthoringToolNewProjectController',\n controllerAs: 'authoringToolNewProjectController',\n resolve: {\n config: (ConfigService) => {\n return ConfigService.retrieveConfig(window.configURL);\n },\n language: ($translate, ConfigService, config) => {\n $translate.use(ConfigService.getLocale());\n },\n sessionTimers: (SessionService, config) => {\n return SessionService.initializeSession();\n }\n }\n })\n .state('root.project', {\n url: '/project/:projectId',\n templateUrl: 'wise5/authoringTool/project/project.html',\n controller: 'ProjectController',\n controllerAs: 'projectController',\n resolve: {\n projectConfig: (ConfigService, $stateParams) => {\n const configURL = window.configURL + '/' + $stateParams.projectId;\n return ConfigService.retrieveConfig(configURL);\n },\n project: (ProjectService, projectConfig) => {\n return ProjectService.retrieveProject();\n },\n projectAssets: (ProjectAssetService, projectConfig, project) => {\n return ProjectAssetService.retrieveProjectAssets();\n },\n language: ($translate, ConfigService, projectConfig) => {\n $translate.use(ConfigService.getLocale());\n },\n sessionTimers: (SessionService, projectConfig) => {\n return SessionService.initializeSession();\n },\n webSocket: (AuthorWebSocketService, projectConfig) => {\n return AuthorWebSocketService.initialize();\n }\n }\n })\n .state('root.project.node', {\n url: '/node/:nodeId',\n templateUrl: 'wise5/authoringTool/node/node.html',\n controller: 'NodeAuthoringController',\n controllerAs: 'nodeAuthoringController',\n resolve: {}\n })\n .state('root.project.nodeConstraints', {\n url: '/node/constraints/:nodeId',\n templateUrl: 'wise5/authoringTool/node/node.html',\n controller: 'NodeAuthoringController',\n controllerAs: 'nodeAuthoringController',\n resolve: {}\n })\n .state('root.project.nodeEditPaths', {\n url: '/node/editpaths/:nodeId',\n templateUrl: 'wise5/authoringTool/node/node.html',\n controller: 'NodeAuthoringController',\n controllerAs: 'nodeAuthoringController',\n resolve: {}\n })\n .state('root.project.asset', {\n url: '/asset',\n templateUrl: 'wise5/authoringTool/asset/asset.html',\n controller: 'ProjectAssetController',\n controllerAs: 'projectAssetController',\n resolve: {}\n })\n .state('root.project.info', {\n url: '/info',\n templateUrl: 'wise5/authoringTool/info/info.html',\n controller: 'ProjectInfoController',\n controllerAs: 'projectInfoController',\n resolve: {}\n })\n .state('root.project.history', {\n url: '/history',\n templateUrl: 'wise5/authoringTool/history/history.html',\n controller: 'ProjectHistoryController',\n controllerAs: 'projectHistoryController',\n resolve: {}\n })\n .state('root.project.notebook', {\n url: '/notebook',\n templateUrl: 'wise5/authoringTool/notebook/notebook.html',\n controller: 'AuthorNotebookController',\n controllerAs: 'authorNotebookController',\n resolve: {}\n });\n\n $translatePartialLoaderProvider.addPart('i18n');\n $translatePartialLoaderProvider.addPart('authoringTool/i18n');\n $translateProvider\n .useLoader('$translatePartialLoader', {\n urlTemplate: 'wise5/{part}/i18n_{lang}.json'\n })\n .registerAvailableLanguageKeys(\n ['el','en','es','ja','ko','pt','tr','zh_CN','zh_TW'], {\n 'en_US': 'en',\n 'en_UK': 'en'\n })\n .determinePreferredLanguage()\n .fallbackLanguage(['en'])\n .useSanitizeValueStrategy('sanitizeParameters', 'escape');\n\n $mdThemingProvider.definePalette('accent', {\n '50': 'fde9e6',\n '100': 'fbcbc4',\n '200': 'f8aca1',\n '300': 'f4897b',\n '400': 'f2705f',\n '500': 'f05843',\n '600': 'da503c',\n '700': 'c34736',\n '800': 'aa3e2f',\n '900': '7d2e23',\n 'A100': 'ff897d',\n 'A200': 'ff7061',\n 'A400': 'ff3829',\n 'A700': 'cc1705',\n 'contrastDefaultColor': 'light',\n 'contrastDarkColors': ['50', '100', '200', '300', 'A100'],\n 'contrastLightColors': undefined\n });\n $mdThemingProvider.theme('default')\n .primaryPalette('deep-purple', { 'default': '400' })\n .accentPalette('accent', { 'default': '500' })\n .warnPalette('red', { 'default': '800' });\n const lightMap = $mdThemingProvider.extendPalette('grey', {\n 'A100': 'ffffff'\n });\n $mdThemingProvider.definePalette('light', lightMap);\n $mdThemingProvider.theme('light')\n .primaryPalette('light', { 'default': 'A100' })\n .accentPalette('pink', { 'default': '900' });\n $mdThemingProvider.setDefaultTheme('default');\n $mdThemingProvider.enableBrowserColor();\n\n // moment.js default overrides\n // TODO: add i18n support\n moment.updateLocale('en', {\n calendar: {\n lastDay : '[Yesterday at] LT',\n sameDay : '[Today at] LT',\n nextDay : '[Tomorrow at] LT',\n lastWeek : '[last] dddd [at] LT',\n nextWeek : 'dddd [at] LT',\n sameElse : 'll'\n }\n });\n }\n]);\n\nexport default authoringModule;\n"]} \ No newline at end of file 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
diff --git a/src/main/webapp/wise5/authoringTool/project/projectController.es6 b/src/main/webapp/wise5/authoringTool/project/projectController.es6 index 4c90aa2461..97672e914b 100644 --- a/src/main/webapp/wise5/authoringTool/project/projectController.es6 +++ b/src/main/webapp/wise5/authoringTool/project/projectController.es6 @@ -1135,17 +1135,58 @@ class ProjectController { * The show JSON button was clicked */ showJSONClicked() { - this.showJSONAuthoring = !this.showJSONAuthoring; if (this.showJSONAuthoring) { + // we were showing the JSON view and the author now wants to hide it + if (this.isJSONValid()) { + this.toggleJSONAuthoringView(); + this.UtilService.hideJSONValidMessage(); + } else { + let answer = confirm(this.$translate('jsonInvalidErrorMessage')); + if (answer) { + // the author wants to revert back to the last valid JSON + this.toggleJSONAuthoringView(); + this.UtilService.hideJSONValidMessage(); + } + } + } else { + // we were not showing the JSON view and now the author wants to show it + this.toggleJSONAuthoringView(); this.projectJSONString = angular.toJson(this.ProjectService.project, 4); + this.UtilService.showJSONValidMessage(); + } + } + + isJSONValid() { + try { + angular.fromJson(this.projectJSONString); + return true; + } catch(e) { + return false; + } + } + + toggleJSONAuthoringView() { + this.showJSONAuthoring = !this.showJSONAuthoring; + } + + /** + * Save the project JSON to the server if the JSON is valid. + */ + autoSaveProjectJSONString() { + try { + this.saveProjectJSON(this.projectJSONString); + this.UtilService.showJSONValidMessage(); + } catch(e) { + this.UtilService.showJSONInvalidMessage(); } } /** * Save the project JSON string to the server + * @param projectJSONString */ - saveProjectJSONString() { - let project = angular.fromJson(this.projectJSONString); + saveProjectJSON(projectJSONString) { + let project = angular.fromJson(projectJSONString); this.ProjectService.setProject(project); let scriptFilename = this.ProjectService.getProjectScriptFilename(); if (scriptFilename != null) { @@ -1300,6 +1341,9 @@ class ProjectController { // if the advanced view is shown, do not show the project view this.projectMode = !this.advancedMode; } + if (!this.showJSONAuthoring) { + this.UtilService.hideJSONValidMessage(); + } } /** diff --git a/src/main/webapp/wise5/authoringTool/project/projectController.js b/src/main/webapp/wise5/authoringTool/project/projectController.js index 1646dc01cd..a80bb1e7ec 100644 --- a/src/main/webapp/wise5/authoringTool/project/projectController.js +++ b/src/main/webapp/wise5/authoringTool/project/projectController.js @@ -1394,20 +1394,66 @@ var ProjectController = function () { }, { key: 'showJSONClicked', value: function showJSONClicked() { - this.showJSONAuthoring = !this.showJSONAuthoring; if (this.showJSONAuthoring) { + // we were showing the JSON view and the author now wants to hide it + if (this.isJSONValid()) { + this.toggleJSONAuthoringView(); + this.UtilService.hideJSONValidMessage(); + } else { + var answer = confirm(this.$translate('jsonInvalidErrorMessage')); + if (answer) { + // the author wants to revert back to the last valid JSON + this.toggleJSONAuthoringView(); + this.UtilService.hideJSONValidMessage(); + } + } + } else { + // we were not showing the JSON view and now the author wants to show it + this.toggleJSONAuthoringView(); this.projectJSONString = angular.toJson(this.ProjectService.project, 4); + this.UtilService.showJSONValidMessage(); + } + } + }, { + key: 'isJSONValid', + value: function isJSONValid() { + try { + angular.fromJson(this.projectJSONString); + return true; + } catch (e) { + return false; + } + } + }, { + key: 'toggleJSONAuthoringView', + value: function toggleJSONAuthoringView() { + this.showJSONAuthoring = !this.showJSONAuthoring; + } + + /** + * Save the project JSON to the server if the JSON is valid. + */ + + }, { + key: 'autoSaveProjectJSONString', + value: function autoSaveProjectJSONString() { + try { + this.saveProjectJSON(this.projectJSONString); + this.UtilService.showJSONValidMessage(); + } catch (e) { + this.UtilService.showJSONInvalidMessage(); } } /** * Save the project JSON string to the server + * @param projectJSONString */ }, { - key: 'saveProjectJSONString', - value: function saveProjectJSONString() { - var project = angular.fromJson(this.projectJSONString); + key: 'saveProjectJSON', + value: function saveProjectJSON(projectJSONString) { + var project = angular.fromJson(projectJSONString); this.ProjectService.setProject(project); var scriptFilename = this.ProjectService.getProjectScriptFilename(); if (scriptFilename != null) { @@ -1577,6 +1623,9 @@ var ProjectController = function () { // if the advanced view is shown, do not show the project view this.projectMode = !this.advancedMode; } + if (!this.showJSONAuthoring) { + this.UtilService.hideJSONValidMessage(); + } } /** diff --git a/src/main/webapp/wise5/authoringTool/project/projectController.js.map b/src/main/webapp/wise5/authoringTool/project/projectController.js.map index 34d720c397..74ed73303e 100644 --- a/src/main/webapp/wise5/authoringTool/project/projectController.js.map +++ b/src/main/webapp/wise5/authoringTool/project/projectController.js.map @@ -1 +1 @@ -{"version":3,"sources":["projectController.es6"],"names":["ProjectController","$anchorScroll","$filter","$interval","$mdDialog","$q","$rootScope","$scope","$state","$stateParams","$timeout","AuthorWebSocketService","ConfigService","ProjectAssetService","ProjectService","TeacherDataService","UtilService","$translate","projectId","runId","getRunId","items","idToOrder","nodeIds","getFlattenedProjectAsNodeIds","showCreateGroup","showCreateNode","projectTitle","getProjectTitle","inactiveGroupNodes","getInactiveGroupNodes","inactiveStepNodes","getInactiveStepNodes","inactiveNodes","getInactiveNodes","idToNode","getIdToNode","projectScriptFilename","getProjectScriptFilename","currentAuthorsMessage","projectMode","showImportView","importMode","editProjectRubricMode","advancedMode","showJSONAuthoring","stepNodeSelected","activityNodeSelected","stepBackgroundColors","setCurrentNode","metadata","getProjectMetadata","notifyAuthorProjectBegin","summernoteRubricId","summernoteRubricHTML","replaceAssetPaths","getProjectRubric","insertAssetToolTipText","insertAssetButton","createInsertAssetButton","summernoteRubricOptions","toolbar","height","disableDragAndDrop","buttons","projectURL","window","location","origin","getConfigParam","$on","event","args","currentAuthorsUsernames","myUserName","getMyUserName","splice","indexOf","length","currentAuthors","join","notifyAuthorProjectEnd","assetItem","fileName","assetFileName","target","summernoteElement","$","fullAssetPath","getProjectAssetsDirectoryPath","isImage","summernote","isVideo","videoElement","document","createElement","controls","innerHTML","projectScriptFilenameChanged","hide","toState","toParams","fromState","fromParams","stateName","name","saveEvent","refreshProject","scrollToBottomOfPage","previewProjectEventData","constraints","open","go","commitMessage","saveProject","then","commitHistoryArray","commitHistory","val","error","alert","href","getWISEBaseURL","nodeId","getNodePositionById","getComponentsByNodeId","componentId","getPossibleTransitionCriteria","getNodeTitleByNodeId","isGroupNode","unselectAllItems","endCurrentNodeAndSetCurrentNodeByNodeId","nodeToAdd","createGroup","createGroupTitle","insertGroupMode","createMode","createNode","createNodeTitle","insertNodeMode","handleCreateModeInsert","moveMode","handleMoveModeInsert","copyMode","handleCopyModeInsert","importSelectedNodes","moveTo","createNodeInside","createNodeAfter","newNodes","newNode","temporarilyHighlightNewNodes","checkPotentialStartNodeIdChangeThenSaveProject","nodeCreatedEventData","id","getNodePositionAndTitleByNodeId","selectedNodeIds","getSelectedNodeIds","movedNodes","selectedNodeId","node","push","moveNodesInside","moveNodesAfter","firstNewNode","n","toTitle","nodeMovedEventData","activitiesMoved","stepsMoved","copiedNodes","copyNodesInside","copyNodesAfter","toNodeId","nodeCopiedEventData","activitiesCopied","stepsCopied","nodeIdToInsertInsideOrAfter","selectedNodes","getSelectedNodesToImport","selectedNodeTitles","getSelectedNodeTitlesToImport","toProjectId","fromProjectId","importProjectId","performImport","doScrollToNewNodes","stepsImported","selectedNode","selectedNodeTitle","stepImported","parseInt","fromNodeId","fromTitle","stepsImportedEventData","copyNodes","toggleView","importProjectIdToOrder","importProjectItems","importMyProjectId","importLibraryProjectId","importProject","showProjectHome","retrieveProjectAssets","selectedItemTypes","getSelectedItemTypes","confirmMessage","numItems","confirm","deletedStartNodeId","activityDeleted","stepDeleted","stepsDeleted","activitiesDeleted","getNodeById","tempNode","title","isStartNodeId","stepsInActivityDeleted","ids","stepNodeId","stepTitle","stepObject","deleteNode","updateStartNodeId","activitiesDeletedEventData","stepDeletedEventData","angular","forEach","value","key","checked","inactiveNode","nodeType","type","inactiveNodeType","focus","newStartNodeId","startGroupId","getStartGroupId","done","startId","isApplicationNode","setStartNodeId","resolve","reject","firstLeafNodeId","getFirstLeafNodeId","currentStartNodeId","getStartNodeId","checkPotentialStartNodeIdChange","parseProject","setProjectTitle","myProjectsList","getAuthorableProjects","libraryProjectsList","getLibraryProjects","showImportProject","retrieveProjectById","projectJSON","nodeOrderOfProject","getNodeOrderOfProject","nodes","previewProjectURL","previewStepURL","item","projectJSONString","toJson","project","fromJson","setProject","scriptFilename","html","removeAbsoluteAssetPaths","insertWISELinks","setProjectRubric","isNodeInAnyBranchPath","setProjectScriptFilename","openAssetChooserParams","popup","$broadcast","view","scrollToTopOfPage","animate","scrollTop","prop","temporarilyHighlightElement","firstNodeElementAdded","eventName","category","data","context","componentType","stepNumber","color","branchPathLetter","getBranchPathLetter","letterASCIICode","charCodeAt","branchPathNumber","textArea","body","appendChild","select","execCommand","removeChild","count","getParentGroup","isBranchPoint","getNumberOfBranchPaths","getBranchCriteriaDescription","nodeHasConstraint","getConstraintsOnNode","constraintDescriptions","c","constraint","description","getConstraintDescription","nodeHasRubric","$inject"],"mappings":"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","file":"projectController.js","sourcesContent":["'use strict';\n\nclass ProjectController {\n\n constructor(\n $anchorScroll,\n $filter,\n $interval,\n $mdDialog,\n $q,\n $rootScope,\n $scope,\n $state,\n $stateParams,\n $timeout,\n AuthorWebSocketService,\n ConfigService,\n ProjectAssetService,\n ProjectService,\n TeacherDataService,\n UtilService) {\n this.$anchorScroll = $anchorScroll;\n this.$filter = $filter;\n this.$interval = $interval;\n this.$mdDialog = $mdDialog;\n this.$q = $q;\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.AuthorWebSocketService = AuthorWebSocketService;\n this.ConfigService = ConfigService;\n this.ProjectAssetService = ProjectAssetService;\n this.ProjectService = ProjectService;\n this.TeacherDataService = TeacherDataService;\n this.UtilService = UtilService;\n\n this.projectId = this.$stateParams.projectId;\n this.runId = this.ConfigService.getRunId();\n this.items = this.ProjectService.idToOrder;\n this.nodeIds = this.ProjectService.getFlattenedProjectAsNodeIds();\n this.showCreateGroup = false;\n this.showCreateNode = false;\n this.projectTitle = this.ProjectService.getProjectTitle();\n this.inactiveGroupNodes = this.ProjectService.getInactiveGroupNodes();\n this.inactiveStepNodes = this.ProjectService.getInactiveStepNodes();\n this.inactiveNodes = this.ProjectService.getInactiveNodes();\n this.idToNode = this.ProjectService.getIdToNode();\n this.projectScriptFilename = this.ProjectService.getProjectScriptFilename();\n this.currentAuthorsMessage = '';\n this.projectMode = true;\n this.showCreateGroup = false;\n this.showCreateNode = false;\n this.showImportView = false;\n this.importMode = false;\n this.editProjectRubricMode = false;\n this.advancedMode = false;\n this.showJSONAuthoring = false;\n\n // whether there are any step nodes checked\n this.stepNodeSelected = false;\n\n // whether there are any activity nodes checked\n this.activityNodeSelected = false;\n\n /*\n * The colors for the branch path steps. The colors are from\n * http://colorbrewer2.org/\n * http://colorbrewer2.org/export/colorbrewer.js\n * The colors chosen are from the 'qualitative', 'Set2'.\n */\n this.stepBackgroundColors = ['#66c2a5','#fc8d62','#8da0cb','#e78ac3',\n '#a6d854','#ffd92f','#e5c494','#b3b3b3'];\n\n // start by opening the project, with no node being authored\n this.TeacherDataService.setCurrentNode(null);\n\n this.metadata = this.ProjectService.getProjectMetadata();\n this.ProjectService.notifyAuthorProjectBegin(this.projectId);\n this.summernoteRubricId = 'summernoteRubric_' + this.projectId;\n this.summernoteRubricHTML = this.ProjectService\n .replaceAssetPaths(this.ProjectService.getProjectRubric());\n\n let insertAssetToolTipText = this.$translate('INSERT_ASSET');\n let insertAssetButton = this.UtilService.createInsertAssetButton(this,\n this.projectId, null, null, 'rubric', insertAssetToolTipText);\n\n // options to display in the summernote tool\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 this.projectURL = window.location.origin + this.ConfigService.getConfigParam('projectURL');\n\n this.$scope.$on('currentAuthorsReceived', (event, args) => {\n let currentAuthorsUsernames = args.currentAuthorsUsernames;\n let myUserName = this.ConfigService.getMyUserName();\n currentAuthorsUsernames\n .splice(currentAuthorsUsernames.indexOf(myUserName), 1);\n if (currentAuthorsUsernames.length > 0) {\n this.currentAuthorsMessage = this.$translate('concurrentAuthorsWarning',\n { currentAuthors: currentAuthorsUsernames.join(', ') });\n } else {\n this.currentAuthorsMessage = '';\n }\n });\n\n this.$scope.$on('$destroy', () => {\n this.ProjectService.notifyAuthorProjectEnd(this.projectId);\n });\n\n /*\n * Listen for the assetSelected event which occurs when the author\n * selects an asset from the choose asset popup to add to project rubric\n * or choosing the script file.\n */\n this.$scope.$on('assetSelected', (event, args) => {\n if (args != null && args.projectId == this.projectId &&\n args.assetItem != null && args.assetItem.fileName != null) {\n let assetFileName = args.assetItem.fileName;\n if (args.target === 'rubric') {\n let summernoteElement = $('#summernoteRubric_' + this.projectId);\n let fullAssetPath =\n this.ConfigService.getProjectAssetsDirectoryPath() +\n '/' + assetFileName;\n if (this.UtilService.isImage(assetFileName)) {\n /*\n * move the cursor back to its position when the asset chooser\n * popup was clicked\n */\n summernoteElement.summernote('editor.restoreRange');\n summernoteElement.summernote('editor.focus');\n summernoteElement.summernote(\n 'insertImage', fullAssetPath, assetFileName);\n } else if (this.UtilService.isVideo(assetFileName)) {\n /*\n * move the cursor back to its position when the asset chooser\n * popup was clicked\n */\n summernoteElement.summernote('editor.restoreRange');\n summernoteElement.summernote('editor.focus');\n let videoElement = document.createElement('video');\n videoElement.controls = 'true';\n videoElement.innerHTML =\n '';\n summernoteElement.summernote('insertNode', videoElement);\n }\n } else if (args.target === 'scriptFilename') {\n this.projectScriptFilename = assetFileName;\n this.projectScriptFilenameChanged();\n }\n }\n this.$mdDialog.hide();\n });\n\n this.$rootScope.$on('$stateChangeSuccess',\n (event, toState, toParams, fromState, fromParams) => {\n if (toState != null) {\n let stateName = toState.name;\n if (stateName == 'root.project') {\n this.saveEvent('projectHomeViewOpened', 'Navigation');\n } else if (stateName == 'root.project.node') {\n } else if (stateName == 'root.project.asset') {\n this.saveEvent('assetsViewOpened', 'Navigation');\n } else if (stateName == 'root.project.info') {\n this.saveEvent('projectInfoViewOpened', 'Navigation');\n } else if (stateName == 'root.project.notebook') {\n this.saveEvent('notebookViewOpened', 'Navigation');\n }\n }\n });\n\n this.$rootScope.$on('projectSaved', () => {\n //this.saveEvent('projectSaved', 'Authoring');\n });\n\n /*\n * Listen for the event to parse the project. This is so other\n * controllers can trigger parsing the project in this controller.\n */\n this.$rootScope.$on('parseProject', () => {\n this.refreshProject();\n });\n\n this.$rootScope.$on('scrollToBottom', () => {\n this.scrollToBottomOfPage();\n });\n\n this.saveEvent('projectOpened', 'Navigation');\n };\n\n /**\n * Launch the project in preview mode in a new tab\n */\n previewProject() {\n let previewProjectEventData = { constraints: true };\n this.saveEvent('projectPreviewed', 'Navigation', previewProjectEventData);\n window.open(this.ConfigService.getConfigParam('previewProjectURL'));\n };\n\n /**\n * Launch the project in preview mode without constraints in a new tab\n */\n previewProjectWithoutConstraints() {\n let previewProjectEventData = { constraints: false };\n this.saveEvent('projectPreviewed', 'Navigation', previewProjectEventData);\n window.open(this.ConfigService.getConfigParam('previewProjectURL') +\n '?constraints=false');\n };\n\n viewProjectAssets() {\n this.$state.go('root.project.asset', {projectId: this.projectId});\n };\n\n viewProjectHistory() {\n this.$state.go('root.project.history', {projectId: this.projectId});\n };\n\n viewNotebookSettings() {\n this.$state.go('root.project.notebook', {projectId: this.projectId});\n }\n\n saveProject() {\n let commitMessage = 'Made changes to the project.';\n try {\n // if projectJSONString is bad json,\n // an exception will be thrown and it will not save.\n this.ProjectService.saveProject(commitMessage)\n .then((commitHistoryArray) => {\n this.commitHistory = commitHistoryArray;\n $('#commitMessageInput').val('');\n });\n } catch (error) {\n // TODO: i18n\n alert('Invalid JSON. Please check syntax. Aborting save.');\n return;\n }\n };\n\n /**\n * Make a request to download this project as a zip file\n */\n downloadProject() {\n window.location.href = this.ConfigService.getWISEBaseURL()\n + '/project/export/' + this.projectId;\n }\n\n /**\n * Close authoring for the current project and bring user back to main AT page\n */\n closeProject() {\n this.$state.go('root.main');\n };\n\n /**\n * Get the node position\n * @param nodeId the node id\n * @returns the node position\n */\n getNodePositionById(nodeId) {\n return this.ProjectService.getNodePositionById(nodeId);\n };\n\n /**\n * Get the components that are in the specified node id.\n * @param nodeId the node id\n * @returns components in the node\n */\n getComponentsByNodeId(nodeId) {\n return this.ProjectService.getComponentsByNodeId(nodeId);\n }\n\n /**\n * Returns a list of possible criteria for the specified node and component\n * @param nodeId the node id\n * @param componentId the component id in the node\n */\n getPossibleTransitionCriteria(nodeId, componentId) {\n return this.ProjectService\n .getPossibleTransitionCriteria(nodeId, componentId);\n }\n\n /**\n * Get the node title for a node\n * @param nodeId the node id\n * @returns the node title\n */\n getNodeTitleByNodeId(nodeId) {\n return this.ProjectService.getNodeTitleByNodeId(nodeId);\n };\n\n /**\n * Check if a node id is for a group\n * @param nodeId\n * @returns whether the node is a group node\n */\n isGroupNode(nodeId) {\n return this.ProjectService.isGroupNode(nodeId);\n };\n\n /**\n * A node was clicked so we will go to the node authoring view\n * @param nodeId\n */\n nodeClicked(nodeId) {\n this.unselectAllItems();\n this.TeacherDataService\n .endCurrentNodeAndSetCurrentNodeByNodeId(this.nodeId);\n this.$state\n .go('root.project.node', {projectId: this.projectId, nodeId: nodeId});\n };\n\n /**\n * The constraint icon on a step in the project view was clicked.\n * We will open the constraint view for the step.\n * @param nodeId The node id of the step.\n */\n constraintIconClicked(nodeId) {\n this.TeacherDataService\n .endCurrentNodeAndSetCurrentNodeByNodeId(nodeId);\n this.$state\n .go('root.project.nodeConstraints', {projectId: this.projectId, nodeId: nodeId});\n }\n\n /**\n * The branch icon on a step in the project view was clicked.\n * We will open the transitions view for the step.\n * @param nodeId The node id of the step.\n */\n branchIconClicked(nodeId) {\n this.TeacherDataService\n .endCurrentNodeAndSetCurrentNodeByNodeId(nodeId);\n this.$state\n .go('root.project.nodeEditPaths', {projectId: this.projectId, nodeId: nodeId});\n }\n\n /**\n * Create a new group (activity)\n */\n createGroup() {\n /*\n * set the group into this variable to hold it temporarily while the\n * author decides where to place it\n */\n this.nodeToAdd = this.ProjectService.createGroup(this.createGroupTitle);\n\n this.showCreateGroup = false;\n this.createGroupTitle = '';\n this.insertGroupMode = true;\n this.createMode = true;\n }\n\n /**\n * Create a new node (step)\n */\n createNode() {\n /*\n * set the node into this variable to hold it temporarily while the\n * author decides where to place it\n */\n this.nodeToAdd = this.ProjectService.createNode(this.createNodeTitle);\n\n this.showCreateNode = false;\n this.createNodeTitle = '';\n this.insertNodeMode = true;\n this.createMode = true;\n }\n\n /**\n * Insert the node(s) inside\n * @param nodeId the node id of the group that we will insert into\n */\n insertInside(nodeId) {\n // TODO check that we are inserting into a group\n if (this.createMode) {\n this.handleCreateModeInsert(nodeId, 'inside');\n } else if (this.moveMode) {\n this.handleMoveModeInsert(nodeId, 'inside');\n } else if (this.copyMode) {\n this.handleCopyModeInsert(nodeId, 'inside');\n } else if (this.importMode) {\n this.importSelectedNodes(nodeId);\n }\n }\n\n /**\n * Insert the node(s) after\n * @param nodeId the node id of the node we will insert after\n */\n insertAfter(nodeId) {\n if (this.createMode) {\n this.handleCreateModeInsert(nodeId, 'after');\n } else if (this.moveMode) {\n this.handleMoveModeInsert(nodeId, 'after');\n } else if (this.copyMode) {\n this.handleCopyModeInsert(nodeId, 'after');\n } else if (this.importMode) {\n this.importSelectedNodes(nodeId);\n }\n }\n\n /**\n * Create a node and then insert it in the specified location\n * @param nodeId insert the new node inside or after this node id\n * @param moveTo whether to insert 'inside' or 'after' the nodeId parameter\n */\n handleCreateModeInsert(nodeId, moveTo) {\n if (moveTo === 'inside') {\n this.ProjectService.createNodeInside(this.nodeToAdd, nodeId);\n } else if (moveTo === 'after') {\n this.ProjectService.createNodeAfter(this.nodeToAdd, nodeId);\n } else {\n // an unspecified moveTo was provided\n return;\n }\n\n let newNodes = [this.nodeToAdd];\n let newNode = this.nodeToAdd;\n\n /*\n * clear this variable that we used to hold the node we inserted.\n * since we have inserted the node we don't need a handle to it\n * anymore\n */\n this.nodeToAdd = null;\n\n this.createMode = false;\n this.insertGroupMode = false;\n this.insertNodeMode = false;\n this.temporarilyHighlightNewNodes(newNodes);\n\n this.checkPotentialStartNodeIdChangeThenSaveProject().then(() => {\n if (newNode != null) {\n let nodeCreatedEventData = {\n 'nodeId': newNode.id,\n 'title': this.ProjectService\n .getNodePositionAndTitleByNodeId(newNode.id)\n };\n\n if (this.ProjectService.isGroupNode(newNode.id)) {\n this.saveEvent('activityCreated', 'Authoring', nodeCreatedEventData);\n } else {\n this.saveEvent('stepCreated', 'Authoring', nodeCreatedEventData);\n }\n }\n });\n }\n\n /**\n * Move a node and insert it in the specified location\n * @param nodeId insert the new node inside or after this node id\n * @param moveTo whether to insert 'inside' or 'after' the nodeId parameter\n */\n handleMoveModeInsert(nodeId, moveTo) {\n let selectedNodeIds = this.getSelectedNodeIds();\n if (selectedNodeIds != null && selectedNodeIds.indexOf(nodeId) != -1) {\n /*\n * the user is trying to insert the selected node ids after\n * itself so we will not allow that\n */\n if (selectedNodeIds.length == 1) {\n alert(this\n .$translate('youAreNotAllowedToInsertTheSelectedItemAfterItself'));\n } else if (selectedNodeIds.length > 1) {\n alert(this\n .$translate('youAreNotAllowedToInsertTheSelectedItemsAfterItself'));\n }\n } else {\n let movedNodes = [];\n for (let selectedNodeId of selectedNodeIds) {\n let node = {\n 'nodeId': selectedNodeId,\n 'fromTitle': this.ProjectService\n .getNodePositionAndTitleByNodeId(selectedNodeId)\n };\n movedNodes.push(node);\n }\n\n let newNodes = [];\n if (moveTo === 'inside') {\n newNodes = this.ProjectService.moveNodesInside(selectedNodeIds, nodeId);\n } else if (moveTo === 'after') {\n newNodes = this.ProjectService.moveNodesAfter(selectedNodeIds, nodeId);\n } else {\n // an unspecified moveTo was provided\n return;\n }\n\n this.moveMode = false;\n this.insertGroupMode = false;\n this.insertNodeMode = false;\n this.temporarilyHighlightNewNodes(newNodes);\n this.checkPotentialStartNodeIdChangeThenSaveProject().then(() => {\n if (newNodes != null && newNodes.length > 0) {\n let firstNewNode = newNodes[0];\n if (firstNewNode != null && firstNewNode.id != null) {\n for (let n = 0; n < movedNodes.length; n++) {\n let node = movedNodes[n];\n let newNode = newNodes[n];\n if (node != null && newNode != null) {\n node.toTitle = this.ProjectService\n .getNodePositionAndTitleByNodeId(newNode.id);\n }\n }\n\n if (this.ProjectService.isGroupNode(firstNewNode.id)) {\n let nodeMovedEventData = { activitiesMoved: movedNodes };\n this.saveEvent('activityMoved', 'Authoring', nodeMovedEventData);\n } else {\n let nodeMovedEventData = { stepsMoved: movedNodes };\n this.saveEvent('stepMoved', 'Authoring', nodeMovedEventData);\n }\n }\n }\n });\n }\n }\n\n /**\n * Copy a node and insert it in the specified location\n * @param nodeId insert the new node inside or after this node id\n * @param moveTo whether to insert 'inside' or 'after' the nodeId parameter\n */\n handleCopyModeInsert(nodeId, moveTo) {\n let copiedNodes = [];\n let selectedNodeIds = this.getSelectedNodeIds();\n for (let selectedNodeId of selectedNodeIds) {\n let node = {\n 'fromNodeId': selectedNodeId,\n 'fromTitle': this.ProjectService\n .getNodePositionAndTitleByNodeId(selectedNodeId)\n };\n copiedNodes.push(node);\n }\n\n let newNodes = [];\n if (moveTo === 'inside') {\n newNodes = this.ProjectService.copyNodesInside(selectedNodeIds, nodeId);\n } else if (moveTo === 'after') {\n newNodes = this.ProjectService.copyNodesAfter(selectedNodeIds, nodeId);\n } else {\n // an unspecified moveTo was provided\n return;\n }\n\n this.copyMode = false;\n this.insertGroupMode = false;\n this.insertNodeMode = false;\n this.temporarilyHighlightNewNodes(newNodes);\n this.checkPotentialStartNodeIdChangeThenSaveProject().then(() => {\n if (newNodes != null && newNodes.length > 0) {\n let firstNewNode = newNodes[0];\n if (firstNewNode != null && firstNewNode.id != null) {\n for (let n = 0; n < copiedNodes.length; n++) {\n let node = copiedNodes[n];\n let newNode = newNodes[n];\n if (node != null && newNode != null) {\n node.toNodeId = newNode.id;\n node.toTitle = this.ProjectService\n .getNodePositionAndTitleByNodeId(newNode.id);\n }\n }\n\n if (this.ProjectService.isGroupNode(firstNewNode.id)) {\n let nodeCopiedEventData = { activitiesCopied: copiedNodes };\n this.saveEvent('activityCopied', 'Authoring', nodeCopiedEventData);\n } else {\n let nodeCopiedEventData = { stepsCopied: copiedNodes };\n this.saveEvent('stepCopied', 'Authoring', nodeCopiedEventData);\n }\n }\n }\n });\n }\n\n /**\n * Import the selected steps and draw attention to them by highlighting them\n * and scrolling to them.\n * @param nodeIdToInsertInsideOrAfter If this is a group, we will make the\n * new step the first step in the group. If this is a step, we will place\n * the new step after it.\n */\n importSelectedNodes(nodeIdToInsertInsideOrAfter) {\n let selectedNodes = this.getSelectedNodesToImport();\n let selectedNodeTitles = this.getSelectedNodeTitlesToImport();\n let toProjectId = this.ConfigService.getConfigParam('projectId');\n let fromProjectId = this.importProjectId;\n\n this.performImport(nodeIdToInsertInsideOrAfter).then((newNodes) => {\n this.checkPotentialStartNodeIdChangeThenSaveProject().then(() => {\n let doScrollToNewNodes = true;\n this.temporarilyHighlightNewNodes(newNodes, doScrollToNewNodes);\n\n let stepsImported = [];\n for (let n = 0; n < selectedNodes.length; n++) {\n let selectedNode = selectedNodes[n];\n let selectedNodeTitle = selectedNodeTitles[n];\n let newNode = newNodes[n];\n\n let stepImported = {\n fromProjectId: parseInt(fromProjectId),\n fromNodeId: selectedNode.id,\n fromTitle: selectedNodeTitle,\n toNodeId: newNode.id,\n toTitle: this.ProjectService\n .getNodePositionAndTitleByNodeId(newNode.id)\n };\n stepsImported.push(stepImported);\n }\n\n let stepsImportedEventData = { 'stepsImported': stepsImported };\n this.saveEvent('stepImported', 'Authoring', stepsImportedEventData);\n });\n });\n }\n\n /**\n * Import the step and place it in the chosen location\n * @param nodeIdToInsertInsideOrAfter If this is a group, we will make the\n * new step the first step in the group. If this is a step, we will place\n * the new step after it.\n */\n performImport(nodeIdToInsertInsideOrAfter) {\n let selectedNodes = this.getSelectedNodesToImport();\n let toProjectId = this.ConfigService.getConfigParam('projectId');\n let fromProjectId = this.importProjectId;\n\n return this.ProjectService.copyNodes(selectedNodes, fromProjectId,\n toProjectId, nodeIdToInsertInsideOrAfter).then((newNodes) => {\n this.refreshProject();\n this.insertNodeMode = false;\n this.toggleView('project');\n\n this.importProjectIdToOrder = {};\n this.importProjectItems = [];\n this.importMyProjectId = null;\n this.importLibraryProjectId = null;\n this.importProjectId = null;\n this.importProject = null;\n\n /*\n * go back to the project view and\n * refresh the project assets in case any of the imported\n * steps also imported assets\n */\n this.showProjectHome();\n this.ProjectAssetService.retrieveProjectAssets();\n return newNodes;\n });\n }\n\n /**\n * Turn on copy mode\n */\n copy() {\n // make sure there is at least one item selected\n let selectedNodeIds = this.getSelectedNodeIds();\n if (selectedNodeIds == null || selectedNodeIds.length == 0) {\n alert(this.$translate('pleaseSelectAnItemToCopyAndThenClickTheCopyButtonAgain'));\n } else {\n let selectedItemTypes = this.getSelectedItemTypes();\n if (selectedItemTypes.length === 1 && selectedItemTypes[0] === 'node') {\n this.insertNodeMode = true;\n this.copyMode = true;\n } else if (selectedItemTypes.length === 1 && selectedItemTypes[0] === 'group') {\n alert(this.$translate('youCannotCopyActivitiesAtThisTime'));\n }\n }\n }\n\n /**\n * Turn on move mode\n * TODO refactor. too many nesting. Rename function to \"turnOnMoveMode\"?\n */\n move() {\n // make sure there is at least one item selected\n let selectedNodeIds = this.getSelectedNodeIds();\n if (selectedNodeIds == null || selectedNodeIds.length == 0) {\n alert(this.$translate('pleaseSelectAnItemToMoveAndThenClickTheMoveButtonAgain'));\n } else {\n let selectedItemTypes = this.getSelectedItemTypes();\n if (selectedItemTypes.length === 1 && selectedItemTypes[0] === 'node') {\n this.insertNodeMode = true;\n this.moveMode = true;\n } else if (selectedItemTypes.length === 1 && selectedItemTypes[0] === 'group') {\n this.insertGroupMode = true;\n this.moveMode = true;\n }\n }\n }\n\n /**\n * Delete the selected nodes after asking user for confirmation\n * TODO refactor too many nesting\n */\n delete() {\n let selectedNodeIds = this.getSelectedNodeIds();\n if (selectedNodeIds == null || selectedNodeIds.length == 0) {\n alert(this.$translate('pleaseSelectAnItemToDeleteAndThenClickTheDeleteButtonAgain'));\n } else {\n let confirmMessage = '';\n if (selectedNodeIds.length == 1) {\n confirmMessage = this.$translate('areYouSureYouWantToDeleteTheSelectedItem');\n } else if (selectedNodeIds.length > 1) {\n confirmMessage = this.$translate('areYouSureYouWantToDeleteTheXSelectedItems',\n { numItems: selectedNodeIds.length });\n }\n if (confirm(confirmMessage)) {\n let deletedStartNodeId = false;\n let activityDeleted = false;\n let stepDeleted = false;\n let stepsDeleted = [];\n let activitiesDeleted = [];\n for (let nodeId of selectedNodeIds) {\n let node = this.ProjectService.getNodeById(nodeId);\n let tempNode = {};\n\n if (node != null) {\n tempNode.nodeId = node.id;\n tempNode.title =\n this.ProjectService.getNodePositionAndTitleByNodeId(node.id);\n }\n\n if (this.ProjectService.isStartNodeId(nodeId)) {\n deletedStartNodeId = true;\n }\n\n if (this.ProjectService.isGroupNode(nodeId)) {\n activityDeleted = true;\n let stepsInActivityDeleted = [];\n for (let stepNodeId of node.ids) {\n let stepTitle = this.ProjectService\n .getNodePositionAndTitleByNodeId(stepNodeId);\n\n // create an object with the step id and title\n let stepObject = {\n 'nodeId': stepNodeId,\n 'title': stepTitle\n };\n stepsInActivityDeleted.push(stepObject);\n }\n tempNode.stepsInActivityDeleted = stepsInActivityDeleted;\n activitiesDeleted.push(tempNode);\n } else {\n stepDeleted = true;\n stepsDeleted.push(tempNode);\n }\n this.ProjectService.deleteNode(nodeId);\n }\n\n if (deletedStartNodeId) {\n this.updateStartNodeId();\n }\n\n if (activityDeleted) {\n let activitiesDeletedEventData = {\n 'activitiesDeleted': activitiesDeleted\n };\n this.saveEvent('activityDeleted', 'Authoring',\n activitiesDeletedEventData);\n }\n\n if (stepDeleted) {\n let stepDeletedEventData = {\n 'stepsDeleted': stepsDeleted\n };\n this.saveEvent('stepDeleted', 'Authoring', stepDeletedEventData);\n }\n\n this.ProjectService.saveProject();\n this.refreshProject();\n }\n }\n }\n\n /**\n * Get the ids of the selected nodes, both active and inactive.\n * @returns an array of node ids that are selected\n */\n getSelectedNodeIds() {\n let selectedNodeIds = [];\n angular.forEach(this.items, function(value, key) {\n if (value.checked) {\n selectedNodeIds.push(key);\n }\n }, selectedNodeIds);\n\n if (this.inactiveNodes != null) {\n for (let inactiveNode of this.inactiveNodes) {\n if (inactiveNode != null && inactiveNode.checked) {\n selectedNodeIds.push(inactiveNode.id);\n }\n }\n }\n return selectedNodeIds;\n }\n\n /**\n * Get the distinct types of the selected items, both active and inactive.\n * @returns an array of item types. possible items are group or node.\n */\n getSelectedItemTypes() {\n let selectedItemTypes = [];\n\n angular.forEach(this.items, function(value, key) {\n if (value.checked) {\n let node = this.ProjectService.getNodeById(key);\n if (node != null) {\n let nodeType = node.type;\n if (selectedItemTypes.indexOf(nodeType) == -1) {\n selectedItemTypes.push(nodeType);\n }\n }\n }\n }, this);\n\n if (this.inactiveNodes != null) {\n for (let inactiveNode of this.inactiveNodes) {\n if (inactiveNode != null && inactiveNode.checked) {\n let inactiveNodeType = inactiveNode.type;\n if (selectedItemTypes.indexOf(inactiveNodeType) == -1) {\n selectedItemTypes.push(inactiveNodeType);\n }\n }\n }\n }\n\n return selectedItemTypes;\n }\n\n unselectAllItems() {\n angular.forEach(this.items, function(value, key) {\n value.checked = false;\n });\n angular.forEach(this.inactiveGroupNodes, function(value, key) {\n value.checked = false;\n });\n angular.forEach(this.inactiveStepNodes, function(value, key) {\n value.checked = false;\n });\n this.stepNodeSelected = false;\n this.activityNodeSelected = false;\n }\n\n /**\n * Toggle the create group input\n */\n creatNewActivityClicked() {\n this.createGroupTitle = '';\n this.toggleView('createGroup');\n if (this.showCreateGroup) {\n this.$timeout(() => {\n $('#createGroupTitle').focus();\n });\n }\n }\n\n /**\n * Toggle the create node input\n */\n createNewStepClicked() {\n this.createNodeTitle = '';\n this.toggleView('createNode');\n if (this.showCreateNode) {\n this.$timeout(() => {\n $('#createNodeTitle').focus();\n });\n }\n }\n\n /**\n * Cancel the move mode\n */\n cancelMove() {\n this.insertGroupMode = false;\n this.insertNodeMode = false;\n this.nodeToAdd = null;\n this.createMode = false;\n this.moveMode = false;\n this.copyMode = false;\n this.importMode = false;\n this.unselectAllItems();\n }\n\n /**\n * Update the start node id by traversing start ids until a\n * node id is found.\n */\n updateStartNodeId() {\n let newStartNodeId = null;\n let startGroupId = this.ProjectService.getStartGroupId();\n let node = this.ProjectService.getNodeById(startGroupId);\n let done = false;\n\n // recursively traverse the start ids\n while (!done) {\n if (node == null) {\n // base case in case something went wrong\n done = true;\n } else if (this.ProjectService.isGroupNode(node.id)) {\n // the node is a group node so we will get its start node\n node = this.ProjectService.getNodeById(node.startId);\n } else if (this.ProjectService.isApplicationNode(node.id)) {\n // the node is a step node so we have found the new start node id\n newStartNodeId = node.id;\n done = true;\n } else {\n // base case in case something went wrong\n done = true;\n }\n }\n\n if (newStartNodeId) {\n this.ProjectService.setStartNodeId(newStartNodeId);\n }\n }\n\n /**\n * Check if the start node id for the project could potentially\n * change.\n */\n checkPotentialStartNodeIdChange() {\n return this.$q((resolve, reject) => {\n let firstLeafNodeId = this.ProjectService.getFirstLeafNodeId();\n if (firstLeafNodeId == null) {\n // there are no steps in the project\n // set the start node id to empty string\n this.ProjectService.setStartNodeId('');\n resolve();\n } else {\n // we have found a leaf node\n let currentStartNodeId = this.ProjectService.getStartNodeId();\n if (currentStartNodeId != firstLeafNodeId) {\n // update the start node id\n this.ProjectService.setStartNodeId(firstLeafNodeId);\n resolve();\n } else {\n resolve();\n }\n }\n });\n }\n\n /**\n * Check if the start node id has changed and then save the project\n */\n checkPotentialStartNodeIdChangeThenSaveProject() {\n return this.checkPotentialStartNodeIdChange().then(() => {\n this.ProjectService.saveProject();\n this.refreshProject();\n });\n }\n\n /**\n * Recalculates step numbering\n */\n refreshProject() {\n /*\n * Use a timeout before we refresh the project in order to allow the\n * spinning progress indicator to show up before the browser starts\n * blocking/freezing.\n */\n this.$timeout(() => {\n this.ProjectService.parseProject();\n this.items = this.ProjectService.idToOrder;\n this.inactiveGroupNodes = this.ProjectService.getInactiveGroupNodes();\n this.inactiveStepNodes = this.ProjectService.getInactiveStepNodes();\n this.inactiveNodes = this.ProjectService.getInactiveNodes();\n this.idToNode = this.ProjectService.getIdToNode();\n this.unselectAllItems();\n });\n }\n\n /**\n * The project title changed so we will update the project title in the\n * project service and save the project\n */\n projectTitleChanged() {\n this.ProjectService.setProjectTitle(this.projectTitle);\n this.ProjectService.saveProject();\n }\n\n /**\n * Toggle the import view and populate the project drop downs if necessary\n */\n importStepClicked() {\n this.toggleView('importStep');\n\n if (this.importMode) {\n if (this.myProjectsList == null) {\n this.myProjectsList = this.ConfigService.getAuthorableProjects();\n }\n\n if (this.libraryProjectsList == null) {\n this.ConfigService.getLibraryProjects().then((libraryProjectsList) => {\n this.libraryProjectsList = libraryProjectsList;\n });\n }\n }\n }\n\n /**\n * The author has chosen an authorable project to import from\n * @param importProjectId the project id to import from\n */\n showMyImportProject(importProjectId) {\n this.importLibraryProjectId = null;\n this.showImportProject(importProjectId);\n }\n\n /**\n * The author has chosen a library project to import from\n * @param importProjectId the project id to import from\n */\n showLibraryImportProject(importProjectId) {\n this.importMyProjectId = null;\n this.showImportProject(importProjectId);\n }\n\n /**\n * Show the project we want to import steps from\n * @param importProjectId the import project id\n */\n showImportProject(importProjectId) {\n this.importProjectId = importProjectId;\n if (this.importProjectId == null) {\n // clear all the import project values\n this.importProjectIdToOrder = {};\n this.importProjectItems = [];\n this.importMyProjectId = null;\n this.importLibraryProjectId = null;\n this.importProjectId = null;\n this.importProject = null;\n } else {\n this.ProjectService.retrieveProjectById(this.importProjectId)\n .then((projectJSON) => {\n this.importProject = projectJSON;\n const nodeOrderOfProject = this.ProjectService\n .getNodeOrderOfProject(this.importProject);\n this.importProjectIdToOrder = nodeOrderOfProject.idToOrder;\n this.importProjectItems = nodeOrderOfProject.nodes;\n });\n }\n }\n\n /**\n * Preview the import project in a new tab\n */\n previewImportProject() {\n if (this.importProject != null) {\n window.open(this.importProject.previewProjectURL);\n }\n }\n\n /**\n * Preview the import step in a new tab\n * @param node\n */\n previewImportNode(node) {\n if (node != null) {\n const nodeId = node.id;\n const previewProjectURL = this.importProject.previewProjectURL;\n const previewStepURL = previewProjectURL + '#/vle/' + nodeId;\n window.open(previewStepURL);\n }\n }\n\n /**\n * Import the selected steps\n */\n importSteps() {\n let selectedNodes = this.getSelectedNodesToImport();\n if (selectedNodes == null || selectedNodes.length == 0) {\n // TODO i18n\n alert('Please select a step to import.');\n } else {\n /*\n * hide the import view because we want to go back to the\n * project view so that the author can choose where to place\n * the new steps\n */\n this.showImportView = false;\n this.insertNodeMode = true;\n this.projectMode = true;\n }\n }\n\n /**\n * Get the selected nodes to import\n * @return an array of selected nodes\n */\n getSelectedNodesToImport() {\n let selectedNodes = [];\n for (let item of this.importProjectItems) {\n if (item.checked) {\n selectedNodes.push(item.node);\n }\n }\n return selectedNodes;\n }\n\n /**\n * Show the view to edit the project rubric\n */\n editProjectRubricClicked() {\n this.toggleView('rubric');\n }\n\n /**\n * Show the advanced authoring view\n */\n advancedClicked() {\n this.toggleView('advanced');\n }\n\n /**\n * The show JSON button was clicked\n */\n showJSONClicked() {\n this.showJSONAuthoring = !this.showJSONAuthoring;\n if (this.showJSONAuthoring) {\n this.projectJSONString = angular.toJson(this.ProjectService.project, 4);\n }\n }\n\n /**\n * Save the project JSON string to the server\n */\n saveProjectJSONString() {\n let project = angular.fromJson(this.projectJSONString);\n this.ProjectService.setProject(project);\n let scriptFilename = this.ProjectService.getProjectScriptFilename();\n if (scriptFilename != null) {\n this.projectScriptFilename = scriptFilename;\n }\n this.checkPotentialStartNodeIdChangeThenSaveProject();\n }\n\n /**\n * The author has changed the rubric, so save the changes\n */\n summernoteRubricHTMLChanged() {\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 diff --git a/src/main/webapp/wise5/themes/default/themeComponents/navItem/navItemController.es6 b/src/main/webapp/wise5/themes/default/themeComponents/navItem/navItemController.es6 index e2ec2d2e5b..8ba9184c97 100644 --- a/src/main/webapp/wise5/themes/default/themeComponents/navItem/navItemController.es6 +++ b/src/main/webapp/wise5/themes/default/themeComponents/navItem/navItemController.es6 @@ -7,6 +7,7 @@ class NavItemController { $element, dragulaService, NodeService, + PlanningService, ProjectService, StudentDataService, $mdDialog) { @@ -17,6 +18,7 @@ class NavItemController { this.$element = $element; this.dragulaService = dragulaService; this.NodeService = NodeService; + this.PlanningService = PlanningService; this.ProjectService = ProjectService; this.StudentDataService = StudentDataService; this.$mdDialog = $mdDialog; @@ -36,14 +38,14 @@ class NavItemController { this.isCurrentNode = (this.currentNode.id === this.nodeId); // whether this node is a planning node - this.isPlanning = this.ProjectService.isPlanning(this.nodeId); + this.isPlanning = this.PlanningService.isPlanning(this.nodeId); // the array of nodes used for drag/drop planning sorting this.availablePlanningNodes = []; // whether the node is a planning node instance this.node = this.ProjectService.getNodeById(this.nodeId); - this.isPlanningInstance = this.ProjectService.isPlanningInstance(this.nodeId); + this.isPlanningInstance = this.PlanningService.isPlanningInstance(this.nodeId); this.parentGroupId = null; @@ -58,7 +60,7 @@ class NavItemController { if (parentGroup != null) { this.parentGroupId = parentGroup.id; - this.isParentGroupPlanning = this.ProjectService.isPlanning(this.parentGroupId); + this.isParentGroupPlanning = this.PlanningService.isPlanning(this.parentGroupId); } if (this.isPlanning) { @@ -66,7 +68,7 @@ class NavItemController { * planning is enabled so we will get the available planning * nodes that can be used in this group */ - this.availablePlanningNodes = this.ProjectService.getAvailablePlanningNodes(this.nodeId); + this.availablePlanningNodes = this.PlanningService.getAvailablePlanningNodes(this.nodeId); } if (this.isParentGroupPlanning) { @@ -80,7 +82,7 @@ class NavItemController { * planning is enabled so we will get the available planning * nodes that can be used in this group */ - this.availablePlanningNodes = this.ProjectService.getAvailablePlanningNodes(this.parentGroupId); + this.availablePlanningNodes = this.PlanningService.getAvailablePlanningNodes(this.parentGroupId); this.$scope.$watch( () => { @@ -189,7 +191,7 @@ class NavItemController { } let nodeId = el.getAttribute('data-nodeid'); - return this.ProjectService.isPlanningInstance(nodeId); + return this.PlanningService.isPlanningInstance(nodeId); } }); @@ -350,10 +352,10 @@ class NavItemController { addPlanningNodeInstanceInside(nodeIdToInsertInside, templateNodeId) { // create the planning node instance let nextAvailablePlanningNodeId = this.StudentDataService.getNextAvailablePlanningNodeId(); - let planningNodeInstance = this.ProjectService.createPlanningNodeInstance(nodeIdToInsertInside, templateNodeId, nextAvailablePlanningNodeId); + let planningNodeInstance = this.PlanningService.createPlanningNodeInstance(templateNodeId, nextAvailablePlanningNodeId); // add the planning node instance inside - this.ProjectService.addPlanningNodeInstanceInside(nodeIdToInsertInside, planningNodeInstance); + this.PlanningService.addPlanningNodeInstanceInside(nodeIdToInsertInside, planningNodeInstance); /* * update the node statuses so that a node status is created for @@ -432,10 +434,10 @@ class NavItemController { // create the planning node instance let nextAvailablePlanningNodeId = this.StudentDataService.getNextAvailablePlanningNodeId(); - let planningNodeInstance = this.ProjectService.createPlanningNodeInstance(parentGroupId, templateNodeId, nextAvailablePlanningNodeId); + let planningNodeInstance = this.PlanningService.createPlanningNodeInstance(templateNodeId, nextAvailablePlanningNodeId); // insert planning node instance after - this.ProjectService.addPlanningNodeInstanceAfter(nodeIdToInsertAfter, planningNodeInstance); + this.PlanningService.addPlanningNodeInstanceAfter(nodeIdToInsertAfter, planningNodeInstance); /* * update the node statuses so that a node status is created for @@ -520,44 +522,6 @@ class NavItemController { return description; } - /** - * Move the planning node. If the other node is a group node, we will - * insert this node as the first node in the group. If the other node is - * a step node, we will insert this node after the other node. - * @param otherNodeId the other node we will move this node inside or after - */ - movePlanningNode0(otherNodeId) { - - /* - * check that this node is not the same as the other node. - * if they are the same we don't need to do anything. - */ - if (this.nodeId != otherNodeId) { - if (this.ProjectService.isGroupNode(otherNodeId)) { - // insert this node inside the group node - this.ProjectService.movePlanningNodeInstanceInside(this.nodeId, otherNodeId); - } else { - // insert this node after the other node - this.ProjectService.movePlanningNodeInstanceAfter(this.nodeId, otherNodeId); - } - - // Save move planning node event - let componentId = null; - let componentType = null; - let category = "Planning"; - let eventName = "planningNodeMoved"; - let eventData = { - nodeIdMoved: this.nodeId, - nodeIdMovedInsideOrAfter: otherNodeId - }; - let eventNodeId = this.nodeId; - this.StudentDataService.saveVLEEvent(eventNodeId, componentId, componentType, category, eventName, eventData); - } - - // perform any necessary updating - this.planningNodeChanged(); - } - /** * Move the planning node. If the other node is a group node, we will * insert this node as the first node in the group. If the other node is @@ -572,11 +536,9 @@ class NavItemController { */ if (nodeIdToMove != nodeIdToMoveAfter) { if (this.ProjectService.isGroupNode(nodeIdToMoveAfter)) { - // insert this node inside the group node - this.ProjectService.movePlanningNodeInstanceInside(nodeIdToMove, nodeIdToMoveAfter); + this.PlanningService.movePlanningNodeInstanceInside(nodeIdToMove, nodeIdToMoveAfter); } else { - // insert this node after the other node - this.ProjectService.movePlanningNodeInstanceAfter(nodeIdToMove, nodeIdToMoveAfter); + this.PlanningService.movePlanningNodeInstanceAfter(nodeIdToMove, nodeIdToMoveAfter); } } @@ -688,6 +650,7 @@ NavItemController.$inject = [ '$element', 'dragulaService', 'NodeService', + 'PlanningService', 'ProjectService', 'StudentDataService', '$mdDialog' diff --git a/src/main/webapp/wise5/themes/default/themeComponents/navItem/navItemController.js b/src/main/webapp/wise5/themes/default/themeComponents/navItem/navItemController.js index be3533efc0..54bff7f0b2 100644 --- a/src/main/webapp/wise5/themes/default/themeComponents/navItem/navItemController.js +++ b/src/main/webapp/wise5/themes/default/themeComponents/navItem/navItemController.js @@ -9,7 +9,7 @@ var _createClass = function () { function defineProperties(target, props) { for function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var NavItemController = function () { - function NavItemController($filter, $rootScope, $scope, $element, dragulaService, NodeService, ProjectService, StudentDataService, $mdDialog) { + function NavItemController($filter, $rootScope, $scope, $element, dragulaService, NodeService, PlanningService, ProjectService, StudentDataService, $mdDialog) { var _this = this; _classCallCheck(this, NavItemController); @@ -20,6 +20,7 @@ var NavItemController = function () { this.$element = $element; this.dragulaService = dragulaService; this.NodeService = NodeService; + this.PlanningService = PlanningService; this.ProjectService = ProjectService; this.StudentDataService = StudentDataService; this.$mdDialog = $mdDialog; @@ -39,14 +40,14 @@ var NavItemController = function () { this.isCurrentNode = this.currentNode.id === this.nodeId; // whether this node is a planning node - this.isPlanning = this.ProjectService.isPlanning(this.nodeId); + this.isPlanning = this.PlanningService.isPlanning(this.nodeId); // the array of nodes used for drag/drop planning sorting this.availablePlanningNodes = []; // whether the node is a planning node instance this.node = this.ProjectService.getNodeById(this.nodeId); - this.isPlanningInstance = this.ProjectService.isPlanningInstance(this.nodeId); + this.isPlanningInstance = this.PlanningService.isPlanningInstance(this.nodeId); this.parentGroupId = null; @@ -61,7 +62,7 @@ var NavItemController = function () { if (parentGroup != null) { this.parentGroupId = parentGroup.id; - this.isParentGroupPlanning = this.ProjectService.isPlanning(this.parentGroupId); + this.isParentGroupPlanning = this.PlanningService.isPlanning(this.parentGroupId); } if (this.isPlanning) { @@ -69,7 +70,7 @@ var NavItemController = function () { * planning is enabled so we will get the available planning * nodes that can be used in this group */ - this.availablePlanningNodes = this.ProjectService.getAvailablePlanningNodes(this.nodeId); + this.availablePlanningNodes = this.PlanningService.getAvailablePlanningNodes(this.nodeId); } if (this.isParentGroupPlanning) { @@ -83,7 +84,7 @@ var NavItemController = function () { * planning is enabled so we will get the available planning * nodes that can be used in this group */ - this.availablePlanningNodes = this.ProjectService.getAvailablePlanningNodes(this.parentGroupId); + this.availablePlanningNodes = this.PlanningService.getAvailablePlanningNodes(this.parentGroupId); this.$scope.$watch(function () { // watch the position of this node @@ -186,7 +187,7 @@ var NavItemController = function () { } var nodeId = el.getAttribute('data-nodeid'); - return _this.ProjectService.isPlanningInstance(nodeId); + return _this.PlanningService.isPlanningInstance(nodeId); } }); @@ -360,10 +361,10 @@ var NavItemController = function () { value: function addPlanningNodeInstanceInside(nodeIdToInsertInside, templateNodeId) { // create the planning node instance var nextAvailablePlanningNodeId = this.StudentDataService.getNextAvailablePlanningNodeId(); - var planningNodeInstance = this.ProjectService.createPlanningNodeInstance(nodeIdToInsertInside, templateNodeId, nextAvailablePlanningNodeId); + var planningNodeInstance = this.PlanningService.createPlanningNodeInstance(templateNodeId, nextAvailablePlanningNodeId); // add the planning node instance inside - this.ProjectService.addPlanningNodeInstanceInside(nodeIdToInsertInside, planningNodeInstance); + this.PlanningService.addPlanningNodeInstanceInside(nodeIdToInsertInside, planningNodeInstance); /* * update the node statuses so that a node status is created for @@ -448,10 +449,10 @@ var NavItemController = function () { // create the planning node instance var nextAvailablePlanningNodeId = this.StudentDataService.getNextAvailablePlanningNodeId(); - var planningNodeInstance = this.ProjectService.createPlanningNodeInstance(parentGroupId, templateNodeId, nextAvailablePlanningNodeId); + var planningNodeInstance = this.PlanningService.createPlanningNodeInstance(templateNodeId, nextAvailablePlanningNodeId); // insert planning node instance after - this.ProjectService.addPlanningNodeInstanceAfter(nodeIdToInsertAfter, planningNodeInstance); + this.PlanningService.addPlanningNodeInstanceAfter(nodeIdToInsertAfter, planningNodeInstance); /* * update the node statuses so that a node status is created for @@ -547,47 +548,6 @@ var NavItemController = function () { * @param otherNodeId the other node we will move this node inside or after */ - }, { - key: 'movePlanningNode0', - value: function movePlanningNode0(otherNodeId) { - - /* - * check that this node is not the same as the other node. - * if they are the same we don't need to do anything. - */ - if (this.nodeId != otherNodeId) { - if (this.ProjectService.isGroupNode(otherNodeId)) { - // insert this node inside the group node - this.ProjectService.movePlanningNodeInstanceInside(this.nodeId, otherNodeId); - } else { - // insert this node after the other node - this.ProjectService.movePlanningNodeInstanceAfter(this.nodeId, otherNodeId); - } - - // Save move planning node event - var componentId = null; - var componentType = null; - var category = "Planning"; - var eventName = "planningNodeMoved"; - var eventData = { - nodeIdMoved: this.nodeId, - nodeIdMovedInsideOrAfter: otherNodeId - }; - var eventNodeId = this.nodeId; - this.StudentDataService.saveVLEEvent(eventNodeId, componentId, componentType, category, eventName, eventData); - } - - // perform any necessary updating - this.planningNodeChanged(); - } - - /** - * Move the planning node. If the other node is a group node, we will - * insert this node as the first node in the group. If the other node is - * a step node, we will insert this node after the other node. - * @param otherNodeId the other node we will move this node inside or after - */ - }, { key: 'movePlanningNode', value: function movePlanningNode(nodeIdToMove, nodeIdToMoveAfter) { @@ -598,11 +558,9 @@ var NavItemController = function () { */ if (nodeIdToMove != nodeIdToMoveAfter) { if (this.ProjectService.isGroupNode(nodeIdToMoveAfter)) { - // insert this node inside the group node - this.ProjectService.movePlanningNodeInstanceInside(nodeIdToMove, nodeIdToMoveAfter); + this.PlanningService.movePlanningNodeInstanceInside(nodeIdToMove, nodeIdToMoveAfter); } else { - // insert this node after the other node - this.ProjectService.movePlanningNodeInstanceAfter(nodeIdToMove, nodeIdToMoveAfter); + this.PlanningService.movePlanningNodeInstanceAfter(nodeIdToMove, nodeIdToMoveAfter); } } @@ -721,7 +679,7 @@ var NavItemController = function () { return NavItemController; }(); -NavItemController.$inject = ['$filter', '$rootScope', '$scope', '$element', 'dragulaService', 'NodeService', 'ProjectService', 'StudentDataService', '$mdDialog']; +NavItemController.$inject = ['$filter', '$rootScope', '$scope', '$element', 'dragulaService', 'NodeService', 'PlanningService', 'ProjectService', 'StudentDataService', '$mdDialog']; exports.default = NavItemController; -//# sourceMappingURL=navItemController.js.map \ No newline at end of file +//# sourceMappingURL=navItemController.js.map diff --git a/src/main/webapp/wise5/themes/default/themeComponents/navItem/navItemController.js.map b/src/main/webapp/wise5/themes/default/themeComponents/navItem/navItemController.js.map index 0f3a443241..1abcd891f9 100644 --- a/src/main/webapp/wise5/themes/default/themeComponents/navItem/navItemController.js.map +++ b/src/main/webapp/wise5/themes/default/themeComponents/navItem/navItemController.js.map @@ -1 +1 @@ -{"version":3,"sources":["navItemController.es6"],"names":["NavItemController","$filter","$rootScope","$scope","$element","dragulaService","NodeService","ProjectService","StudentDataService","$mdDialog","$translate","autoScroll","require","expanded","item","idToNode","nodeId","isGroup","isGroupNode","nodeStatuses","nodeStatus","nodeTitle","showPosition","nodeIdToNumber","title","currentNode","previousNode","isCurrentNode","id","isPlanning","availablePlanningNodes","node","getNodeById","isPlanningInstance","parentGroupId","planningMode","parentGroup","getParentGroup","isParentGroupPlanning","getAvailablePlanningNodes","$watch","value","newNode","oldNode","isPrev","isApplicationNode","previousStep","$parent","isPrevStep","prevNodeisGroup","prevNodeIsDescendant","isNodeDescendentOfGroup","zoomToElement","itemExpanded","$on","event","args","planningModeClickedNodeId","dragId","dropEvent","el","target","source","nodeChangedId","data","nodeid","planningNodeItemsChanged","options","moves","handle","sibling","getAttribute","drake","find","scroll","document","querySelector","margin","pixels","scrollWhenOutside","down","dragging","getThemePath","setTimeout","top","offsetTop","location","delay","$","animate","scrollTop","endCurrentNodeAndSetCurrentNodeByNodeId","show","alert","textContent","ariaLabel","ok","targetEvent","planningNodeAdded","componentId","componentType","category","eventName","eventData","nodeIdAdded","planningNodeTemplateId","eventNodeId","saveVLEEvent","planningNodeId","maxAddAllowed","planningGroupNode","a","length","availablePlanningNode","max","numPlanningNodesAdded","ids","c","childPlanningNodeId","childPlanningNode","getPlannindNodeMaxAllowed","getNumPlannindNodeInstances","nodeIdToInsertInside","templateNodeId","nextAvailablePlanningNodeId","getNextAvailablePlanningNodeId","planningNodeInstance","createPlanningNodeInstance","addPlanningNodeInstanceInside","updateNodeStatuses","planningNodeChanged","savePlanningNodeAddedEvent","targetNodeId","insertInside","choosePlanningItemTemplateUrl","navitemCtrl","parent","angular","element","body","locals","templateUrl","controller","ChoosePlanningItemController","addSelectedPlanningInstance","addPlanningNodeInstanceAfter","hide","close","$inject","nodeIdToInsertAfter","planningNodeInstanceNodeId","confirm","cancel","then","deleteNode","nodeIdRemoved","description","otherNodeId","movePlanningNodeInstanceInside","movePlanningNodeInstanceAfter","nodeIdMoved","nodeIdMovedInsideOrAfter","nodeIdToMove","nodeIdToMoveAfter","savePlanningNodeChanges","$broadcast","nodeState","createNewNodeState","isAutoSave","isSubmit","studentData","nodes","planningNode","push","nodeStates","saveNodeStates","index","indexOf","nodeIdAddedAfter","movePlanningNode"],"mappings":"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","file":"navItemController.js","sourcesContent":["\"use strict\";\n\nclass NavItemController {\n constructor($filter,\n $rootScope,\n $scope,\n $element,\n dragulaService,\n NodeService,\n ProjectService,\n StudentDataService,\n $mdDialog) {\n\n this.$filter = $filter;\n this.$rootScope = $rootScope;\n this.$scope = $scope;\n this.$element = $element;\n this.dragulaService = dragulaService;\n this.NodeService = NodeService;\n this.ProjectService = ProjectService;\n this.StudentDataService = StudentDataService;\n this.$mdDialog = $mdDialog;\n this.$translate = this.$filter('translate');\n this.autoScroll = require('dom-autoscroller');\n\n this.expanded = false;\n\n this.item = this.ProjectService.idToNode[this.nodeId];\n this.isGroup = this.ProjectService.isGroupNode(this.nodeId);\n this.nodeStatuses = this.StudentDataService.nodeStatuses;\n this.nodeStatus = this.nodeStatuses[this.nodeId];\n\n this.nodeTitle = this.showPosition ? (this.ProjectService.nodeIdToNumber[this.nodeId] + ': ' + this.item.title) : this.item.title;\n this.currentNode = this.StudentDataService.currentNode;\n this.previousNode = null;\n this.isCurrentNode = (this.currentNode.id === this.nodeId);\n\n // whether this node is a planning node\n this.isPlanning = this.ProjectService.isPlanning(this.nodeId);\n\n // the array of nodes used for drag/drop planning sorting\n this.availablePlanningNodes = [];\n\n // whether the node is a planning node instance\n this.node = this.ProjectService.getNodeById(this.nodeId);\n this.isPlanningInstance = this.ProjectService.isPlanningInstance(this.nodeId);\n\n this.parentGroupId = null;\n\n /*\n * whether planning mode is on or off which determines if students\n * can edit planning related aspects of the project such as adding,\n * moving, or deleting planning steps.\n */\n this.planningMode = false;\n\n var parentGroup = this.ProjectService.getParentGroup(this.nodeId);\n\n if (parentGroup != null) {\n this.parentGroupId = parentGroup.id;\n this.isParentGroupPlanning = this.ProjectService.isPlanning(this.parentGroupId);\n }\n\n if (this.isPlanning) {\n /*\n * planning is enabled so we will get the available planning\n * nodes that can be used in this group\n */\n this.availablePlanningNodes = this.ProjectService.getAvailablePlanningNodes(this.nodeId);\n }\n\n if (this.isParentGroupPlanning) {\n\n if (parentGroup.planningMode) {\n // the parent is currently in planning mode\n this.planningMode = true;\n }\n\n /*\n * planning is enabled so we will get the available planning\n * nodes that can be used in this group\n */\n this.availablePlanningNodes = this.ProjectService.getAvailablePlanningNodes(this.parentGroupId);\n\n this.$scope.$watch(\n () => {\n // watch the position of this node\n return this.ProjectService.nodeIdToNumber[this.nodeId];\n },\n (value) => {\n // the position has changed for this node so we will update it in the UI\n this.nodeTitle = this.showPosition ? (this.ProjectService.nodeIdToNumber[this.nodeId] + ': ' + this.item.title) : this.item.title;\n }\n );\n }\n\n this.$scope.$watch(\n () => { return this.StudentDataService.currentNode; },\n (newNode, oldNode) => {\n this.currentNode = newNode;\n this.previousNode = oldNode;\n this.isCurrentNode = (this.nodeId === newNode.id);\n let isPrev = false;\n\n if (this.ProjectService.isApplicationNode(newNode.id)) {\n return;\n }\n\n if (oldNode) {\n isPrev = (this.nodeId === oldNode.id);\n\n if (this.StudentDataService.previousStep) {\n this.$scope.$parent.isPrevStep = (this.nodeId === this.StudentDataService.previousStep.id);\n }\n }\n\n if (this.isGroup) {\n let prevNodeisGroup = (!oldNode || this.ProjectService.isGroupNode(oldNode.id));\n let prevNodeIsDescendant = this.ProjectService.isNodeDescendentOfGroup(oldNode, this.item);\n if (this.isCurrentNode) {\n this.expanded = true;\n if (prevNodeisGroup || !prevNodeIsDescendant) {\n this.zoomToElement();\n }\n } else {\n if (!prevNodeisGroup) {\n if (prevNodeIsDescendant) {\n this.expanded = true;\n } else {\n this.expanded = false;\n }\n }\n }\n } else {\n if (isPrev && this.ProjectService.isNodeDescendentOfGroup(this.item, newNode)) {\n this.zoomToElement();\n }\n }\n }\n );\n\n this.$scope.$watch(\n () => { return this.expanded; },\n (value) => {\n this.$scope.$parent.itemExpanded = value;\n }\n );\n\n this.$scope.$watch(\n () => { return this.planningMode; },\n (value) => {\n this.$scope.$parent.planningMode = value;\n }\n );\n\n // a group node has turned on or off planning mode\n this.$rootScope.$on('togglePlanningMode', (event, args) => {\n\n // get the group node that has had its planning node changed\n let planningModeClickedNodeId = args.nodeId;\n let planningMode = args.planningMode;\n\n // get this node's parent group\n let parentGroup = this.ProjectService.getParentGroup(this.nodeId);\n let parentGroupId = null;\n\n if (parentGroup != null) {\n parentGroupId = parentGroup.id;\n }\n\n if (parentGroupId == planningModeClickedNodeId) {\n // the parent of this node has changed their planning mode\n this.planningMode = planningMode;\n }\n });\n\n let dragId = 'planning_' + this.nodeId ;\n // handle item drop events\n let dropEvent = dragId + '.drop-model';\n this.$scope.$on(dropEvent, (el, target, source) => {\n let nodeChangedId = target.data().nodeid;\n this.planningNodeItemsChanged(nodeChangedId);\n });\n\n this.dragulaService.options(this.$scope, dragId, {\n moves: (el, source, handle, sibling) => {\n if (!this.planningMode) {\n return false;\n }\n\n let nodeId = el.getAttribute('data-nodeid');\n return this.ProjectService.isPlanningInstance(nodeId);\n }\n });\n\n let drake = dragulaService.find(this.$scope, dragId).drake;\n\n // support scroll while dragging\n let scroll = this.autoScroll(\n [document.querySelector('#content')], {\n margin: 30,\n pixels: 50,\n scrollWhenOutside: true,\n autoScroll: function() {\n // Only scroll when the pointer is down, and there is a child being dragged\n return this.down && drake.dragging;\n }\n });\n }\n\n getTemplateUrl(){\n return this.ProjectService.getThemePath() + '/themeComponents/navItem/navItem.html';\n };\n\n zoomToElement() {\n setTimeout(()=> {\n // smooth scroll to expanded group's page location\n let top = this.$element[0].offsetTop;\n let location = this.isGroup ? top - 32 : top - 80;\n let delay = 350;\n $('#content').animate({\n scrollTop: location\n }, delay, 'linear');\n }, 500);\n };\n\n itemClicked(event) {\n if (this.isGroup) {\n this.expanded = !this.expanded;\n if (this.expanded) {\n if (this.isCurrentNode) {\n this.zoomToElement();\n } else {\n this.StudentDataService.endCurrentNodeAndSetCurrentNodeByNodeId(this.nodeId);\n }\n }\n } else {\n if (this.StudentDataService.planningMode) {\n // Don't allow students to enter planning steps while in planning mode\n this.$mdDialog.show(\n this.$mdDialog.alert()\n .title(this.$translate('itemLocked'))\n .textContent(this.$translate('planningModeStepsUnVisitable'))\n .ariaLabel(this.$translate('itemLocked'))\n .ok(this.$translate('ok'))\n .targetEvent(event)\n );\n } else {\n this.StudentDataService.endCurrentNodeAndSetCurrentNodeByNodeId(this.nodeId);\n }\n }\n };\n\n /**\n * Save an event when planning node is added\n * @param planningNodeAdded\n */\n savePlanningNodeAddedEvent(planningNodeAdded) {\n let componentId = null;\n let componentType = null;\n let category = \"Planning\";\n let eventName = \"planningNodeAdded\";\n let eventData = {\n nodeIdAdded: planningNodeAdded.id,\n planningNodeTemplateId: planningNodeAdded.planningNodeTemplateId\n };\n let eventNodeId = this.nodeId;\n this.StudentDataService.saveVLEEvent(eventNodeId, componentId, componentType, category, eventName, eventData);\n };\n\n /**\n * Returns the max times a planning node can be added to the project (-1 is\n * is returned if there is no limit)\n * @param planningNodeId\n */\n getPlannindNodeMaxAllowed(planningNodeId) {\n let maxAddAllowed = -1; // by default, students can add as many instances as they want\n let planningGroupNode = null;\n if (this.isParentGroupPlanning) {\n planningGroupNode = this.ProjectService.getNodeById(this.parentGroupId);\n } else {\n planningGroupNode = this.ProjectService.getNodeById(this.nodeId);\n }\n // get the maxAddAllowed value by looking up the planningNode in the project.\n if (planningGroupNode && planningGroupNode.availablePlanningNodes) {\n for (let a = 0; a < planningGroupNode.availablePlanningNodes.length; a++) {\n let availablePlanningNode = planningGroupNode.availablePlanningNodes[a];\n if (availablePlanningNode.nodeId === planningNodeId && availablePlanningNode.max != null) {\n maxAddAllowed = availablePlanningNode.max;\n }\n }\n }\n\n return maxAddAllowed;\n };\n\n /**\n * Returns the number of times a planning node has been added to the project\n * @param planningNodeId\n */\n getNumPlannindNodeInstances(planningNodeId) {\n let numPlanningNodesAdded = 0; // keep track of number of instances\n // otherwise, see how many times the planning node template has been used.\n\n let planningGroupNode = null;\n if (this.isParentGroupPlanning) {\n planningGroupNode = this.ProjectService.getNodeById(this.parentGroupId);\n } else {\n planningGroupNode = this.ProjectService.getNodeById(this.nodeId);\n }\n\n // loop through the child ids in the planning group and see how many times they've been used\n if (planningGroupNode && planningGroupNode.ids) {\n for (let c = 0; c < planningGroupNode.ids.length; c++) {\n let childPlanningNodeId = planningGroupNode.ids[c];\n let childPlanningNode = this.ProjectService.getNodeById(childPlanningNodeId);\n if (childPlanningNode != null && childPlanningNode.planningNodeTemplateId === planningNodeId) {\n numPlanningNodesAdded++;\n }\n }\n }\n\n return numPlanningNodesAdded;\n };\n\n /**\n * Returns true iff this student can add the specified planning node.\n * Limits include reaching the max allowed count\n * @param planningNodeId\n */\n canAddPlanningNode(planningNodeId) {\n let maxAddAllowed = this.getPlannindNodeMaxAllowed(planningNodeId);\n\n // if maxAddAllowed was not found or is set to 0, it means students can add as many as they want\n if (maxAddAllowed < 1) {\n return true;\n }\n\n let numPlanningNodesAdded = this.getNumPlannindNodeInstances(planningNodeId);\n\n return numPlanningNodesAdded < maxAddAllowed;\n };\n\n /**\n * Create a planning node instance and add it to the project\n * @param groupId the group the new planning node instance will be added to\n * @param templateNodeId the node id of the planning node template\n * @returns the planning node instance\n */\n addPlanningNodeInstanceInside(nodeIdToInsertInside, templateNodeId) {\n // create the planning node instance\n let nextAvailablePlanningNodeId = this.StudentDataService.getNextAvailablePlanningNodeId();\n let planningNodeInstance = this.ProjectService.createPlanningNodeInstance(nodeIdToInsertInside, templateNodeId, nextAvailablePlanningNodeId);\n\n // add the planning node instance inside\n this.ProjectService.addPlanningNodeInstanceInside(nodeIdToInsertInside, planningNodeInstance);\n\n /*\n * update the node statuses so that a node status is created for\n * the new planning node instance\n */\n this.StudentDataService.updateNodeStatuses();\n\n // perform any necessary updating\n this.planningNodeChanged();\n\n // Save add planning node event\n this.savePlanningNodeAddedEvent(planningNodeInstance);\n\n return planningNodeInstance;\n }\n\n /**\n * Open the planning mode select dialog to choose a planning node template\n * to create a new planning instance\n * @param event the trigger event\n * @param targetNodeId the node to insert the new planning instance after or inside\n * @param insertInside boolean whether to insert the new planning instance\n * inside the target node (optional; default is after)\n */\n addPlanningInstance(event, targetNodeId, insertInside) {\n // show dialog with list of planning nodes user can add to current group\n\n let choosePlanningItemTemplateUrl = this.ProjectService.getThemePath() + '/themeComponents/navItem/choosePlanningItem.html';\n let navitemCtrl = this;\n\n this.$mdDialog.show({\n parent: angular.element(document.body),\n locals: {\n targetNodeId: targetNodeId,\n insertInside: insertInside,\n navitemCtrl: navitemCtrl,\n },\n templateUrl: choosePlanningItemTemplateUrl,\n targetEvent: event,\n controller: ChoosePlanningItemController\n });\n\n function ChoosePlanningItemController($scope, $mdDialog, targetNodeId, insertInside, navitemCtrl) {\n $scope.navitemCtrl = navitemCtrl;\n $scope.targetNodeId = targetNodeId;\n $scope.insertInside = insertInside;\n\n $scope.addSelectedPlanningInstance = (templateNodeId) => {\n if ($scope.insertInside) {\n $scope.navitemCtrl.addPlanningNodeInstanceInside($scope.targetNodeId, templateNodeId);\n } else {\n $scope.navitemCtrl.addPlanningNodeInstanceAfter($scope.targetNodeId, templateNodeId);\n }\n\n $mdDialog.hide();\n };\n\n $scope.close = () => {\n $mdDialog.hide();\n };\n }\n ChoosePlanningItemController.$inject = [\"$scope\", \"$mdDialog\", \"targetNodeId\", \"insertInside\", \"navitemCtrl\"];\n };\n\n /**\n * Create a planning node instance and add it to the project after the specified nodeId\n * @param groupId the group the new planning node instance will be added to\n * @param nodeId the node id of the planning node template\n */\n addPlanningNodeInstanceAfter(nodeIdToInsertAfter, templateNodeId) {\n\n var parentGroup = this.ProjectService.getParentGroup(nodeIdToInsertAfter);\n\n if (parentGroup != null) {\n var parentGroupId = parentGroup.id;\n\n // create the planning node instance\n let nextAvailablePlanningNodeId = this.StudentDataService.getNextAvailablePlanningNodeId();\n let planningNodeInstance = this.ProjectService.createPlanningNodeInstance(parentGroupId, templateNodeId, nextAvailablePlanningNodeId);\n\n // insert planning node instance after\n this.ProjectService.addPlanningNodeInstanceAfter(nodeIdToInsertAfter, planningNodeInstance);\n\n /*\n * update the node statuses so that a node status is created for\n * the new planning node instance\n */\n this.StudentDataService.updateNodeStatuses();\n\n // perform any necessary updating\n this.planningNodeChanged();\n\n // Save add planning node event\n this.savePlanningNodeAddedEvent(planningNodeInstance);\n\n return planningNodeInstance;\n }\n }\n\n /**\n * Remove the planning node instance\n * @param planningNodeInstanceNodeId the planning node instance to remove\n * @param event the event that triggered the function call\n */\n removePlanningNodeInstance(planningNodeInstanceNodeId, event) {\n let confirm = this.$mdDialog.confirm()\n .parent(angular.element(document.body))\n .title(this.$translate('areYouSureYouWantToDeleteThisItem'))\n .textContent(this.$translate('noteAnyWorkYouHaveDoneOnThisItemWillBeLost'))\n .ariaLabel(this.$translate('deleteItemFromProject'))\n .targetEvent(event)\n .ok(this.$translate('yes'))\n .cancel(this.$translate('no'));\n\n this.$mdDialog.show(confirm).then(() => {\n // delete the node from the project\n this.ProjectService.deleteNode(planningNodeInstanceNodeId);\n\n // perform any necessary updating\n this.planningNodeChanged(this.parentGroupId);\n\n // Save remove planning node event\n let componentId = null;\n let componentType = null;\n let category = \"Planning\";\n let eventName = \"planningNodeRemoved\";\n let eventData = {\n nodeIdRemoved: planningNodeInstanceNodeId\n };\n let eventNodeId = this.nodeId;\n this.StudentDataService.saveVLEEvent(eventNodeId, componentId, componentType, category, eventName, eventData);\n }, () => {});\n }\n\n /**\n * Get the node title\n * @param nodeId get the title for this node\n * @returns the title for the node\n */\n getNodeTitle(nodeId) {\n var node = this.ProjectService.idToNode[nodeId];\n var title = null;\n\n if (node != null) {\n title = node.title;\n }\n\n return title;\n }\n\n /**\n * Get the node description\n * @param nodeId get the description for this node\n * @returns the description for the node\n */\n getNodeDescription(nodeId) {\n var node = this.ProjectService.idToNode[nodeId];\n var description = null;\n\n if (node != null) {\n description = node.description;\n }\n\n return description;\n }\n\n /**\n * Move the planning node. If the other node is a group node, we will\n * insert this node as the first node in the group. If the other node is\n * a step node, we will insert this node after the other node.\n * @param otherNodeId the other node we will move this node inside or after\n */\n movePlanningNode0(otherNodeId) {\n\n /*\n * check that this node is not the same as the other node.\n * if they are the same we don't need to do anything.\n */\n if (this.nodeId != otherNodeId) {\n if (this.ProjectService.isGroupNode(otherNodeId)) {\n // insert this node inside the group node\n this.ProjectService.movePlanningNodeInstanceInside(this.nodeId, otherNodeId);\n } else {\n // insert this node after the other node\n this.ProjectService.movePlanningNodeInstanceAfter(this.nodeId, otherNodeId);\n }\n\n // Save move planning node event\n let componentId = null;\n let componentType = null;\n let category = \"Planning\";\n let eventName = \"planningNodeMoved\";\n let eventData = {\n nodeIdMoved: this.nodeId,\n nodeIdMovedInsideOrAfter: otherNodeId\n };\n let eventNodeId = this.nodeId;\n this.StudentDataService.saveVLEEvent(eventNodeId, componentId, componentType, category, eventName, eventData);\n }\n\n // perform any necessary updating\n this.planningNodeChanged();\n }\n\n /**\n * Move the planning node. If the other node is a group node, we will\n * insert this node as the first node in the group. If the other node is\n * a step node, we will insert this node after the other node.\n * @param otherNodeId the other node we will move this node inside or after\n */\n movePlanningNode(nodeIdToMove, nodeIdToMoveAfter) {\n\n /*\n * check that this node is not the same as the other node.\n * if they are the same we don't need to do anything.\n */\n if (nodeIdToMove != nodeIdToMoveAfter) {\n if (this.ProjectService.isGroupNode(nodeIdToMoveAfter)) {\n // insert this node inside the group node\n this.ProjectService.movePlanningNodeInstanceInside(nodeIdToMove, nodeIdToMoveAfter);\n } else {\n // insert this node after the other node\n this.ProjectService.movePlanningNodeInstanceAfter(nodeIdToMove, nodeIdToMoveAfter);\n }\n }\n\n // perform any necessary updating\n this.planningNodeChanged();\n }\n\n /**\n * Something related to planning has changed in the project. This\n * means a planning node was added, moved, or deleted.\n * @param param planningNodeId planning node id\n */\n planningNodeChanged(planningNodeId) {\n this.savePlanningNodeChanges(planningNodeId);\n\n this.$rootScope.$broadcast('planningNodeChanged');\n }\n\n /**\n * Save the changed nodes in NodeState\n * @param param planningNodeId planning node id\n **/\n savePlanningNodeChanges(planningNodeId) {\n let nodeState = this.NodeService.createNewNodeState();\n let nodeId = planningNodeId ? planningNodeId : this.nodeId;\n nodeState.nodeId = nodeId;\n nodeState.isAutoSave = false;\n nodeState.isSubmit = false;\n\n var studentData = {};\n studentData.nodeId = nodeId;\n studentData.nodes = [];\n let planningNode = this.ProjectService.getNodeById(nodeId);\n studentData.nodes.push(planningNode); // add the planning node (group)\n // loop through the child ids in the planning group and save them also\n if (planningNode.ids != null) {\n for (let c = 0; c < planningNode.ids.length; c++) {\n let childPlanningNodeId = planningNode.ids[c];\n let childPlanningNode = this.ProjectService.getNodeById(childPlanningNodeId);\n studentData.nodes.push(childPlanningNode);\n }\n }\n\n nodeState.studentData = studentData;\n var nodeStates = [];\n nodeStates.push(nodeState);\n this.StudentDataService.saveNodeStates(nodeStates);\n }\n\n /**\n * Toggle the planning mode on and off. Notify child nodes that\n * the planning mode has changed so they can act accordingly.\n */\n togglePlanningMode() {\n /*if (this.StudentDataService.planningMode && !this.item.planningMode) {\n // Don't allow multiple concurrent planning modes.\n this.$translate('planningModeOnlyOnePlanningModeAllowed').then((planningModeOnlyOnePlanningModeAllowed) => {\n alert(planningModeOnlyOnePlanningModeAllowed);\n });\n\n return;\n }*/\n\n // toggle the planning mode\n //this.planningMode = !this.planningMode;\n this.item.planningMode = this.planningMode;\n\n // also toggle StudentDataService planning mode. This will be used to constrain the entire project when in planning mode.\n this.StudentDataService.planningMode = this.planningMode;\n\n // Save planning mode on/off event\n let componentId = null;\n let componentType = null;\n let category = \"Planning\";\n let eventName = this.planningMode ? \"planningModeOn\" : \"planningModeOff\";\n let eventData = {\n nodeId: this.nodeId\n };\n let eventNodeId = this.nodeId;\n this.StudentDataService.saveVLEEvent(eventNodeId, componentId, componentType, category, eventName, eventData);\n\n // notify the child nodes that the planning mode of this group node has changed\n this.$rootScope.$broadcast('togglePlanningMode', { nodeId: this.nodeId, planningMode: this.planningMode });\n }\n\n /**\n * The planning node's items array has changed\n * @param newValue the new value of the planning node's items array\n * @param oldValue the old value of the planning node's items array\n */\n planningNodeItemsChanged(nodeChangedId) {\n let index = this.item.ids.indexOf(nodeChangedId);\n let nodeIdAddedAfter = this.item.ids[index-1];\n\n if (nodeIdAddedAfter) {\n // the node was moved after another node in the group\n this.movePlanningNode(nodeChangedId, nodeIdAddedAfter);\n } else {\n // the node was moved to the beginning of the group\n this.movePlanningNode(nodeChangedId, this.nodeId);\n }\n };\n}\n\nNavItemController.$inject = [\n '$filter',\n '$rootScope',\n '$scope',\n '$element',\n 'dragulaService',\n 'NodeService',\n 'ProjectService',\n 'StudentDataService',\n '$mdDialog'\n];\n\nexport default NavItemController;\n"]} \ No newline at end of file +{"version":3,"sources":["navItemController.es6"],"names":["NavItemController","$filter","$rootScope","$scope","$element","dragulaService","NodeService","PlanningService","ProjectService","StudentDataService","$mdDialog","$translate","autoScroll","require","expanded","item","idToNode","nodeId","isGroup","isGroupNode","nodeStatuses","nodeStatus","nodeTitle","showPosition","nodeIdToNumber","title","currentNode","previousNode","isCurrentNode","id","isPlanning","availablePlanningNodes","node","getNodeById","isPlanningInstance","parentGroupId","planningMode","parentGroup","getParentGroup","isParentGroupPlanning","getAvailablePlanningNodes","$watch","value","newNode","oldNode","isPrev","isApplicationNode","previousStep","$parent","isPrevStep","prevNodeisGroup","prevNodeIsDescendant","isNodeDescendentOfGroup","zoomToElement","itemExpanded","$on","event","args","planningModeClickedNodeId","dragId","dropEvent","el","target","source","nodeChangedId","data","nodeid","planningNodeItemsChanged","options","moves","handle","sibling","getAttribute","drake","find","scroll","document","querySelector","margin","pixels","scrollWhenOutside","down","dragging","getThemePath","setTimeout","top","offsetTop","location","delay","$","animate","scrollTop","endCurrentNodeAndSetCurrentNodeByNodeId","show","alert","textContent","ariaLabel","ok","targetEvent","planningNodeAdded","componentId","componentType","category","eventName","eventData","nodeIdAdded","planningNodeTemplateId","eventNodeId","saveVLEEvent","planningNodeId","maxAddAllowed","planningGroupNode","a","length","availablePlanningNode","max","numPlanningNodesAdded","ids","c","childPlanningNodeId","childPlanningNode","getPlannindNodeMaxAllowed","getNumPlannindNodeInstances","nodeIdToInsertInside","templateNodeId","nextAvailablePlanningNodeId","getNextAvailablePlanningNodeId","planningNodeInstance","createPlanningNodeInstance","addPlanningNodeInstanceInside","updateNodeStatuses","planningNodeChanged","savePlanningNodeAddedEvent","targetNodeId","insertInside","choosePlanningItemTemplateUrl","navitemCtrl","parent","angular","element","body","locals","templateUrl","controller","ChoosePlanningItemController","addSelectedPlanningInstance","addPlanningNodeInstanceAfter","hide","close","$inject","nodeIdToInsertAfter","planningNodeInstanceNodeId","confirm","cancel","then","deleteNode","nodeIdRemoved","description","nodeIdToMove","nodeIdToMoveAfter","movePlanningNodeInstanceInside","movePlanningNodeInstanceAfter","savePlanningNodeChanges","$broadcast","nodeState","createNewNodeState","isAutoSave","isSubmit","studentData","nodes","planningNode","push","nodeStates","saveNodeStates","index","indexOf","nodeIdAddedAfter","movePlanningNode"],"mappings":"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","file":"navItemController.js","sourcesContent":["\"use strict\";\n\nclass NavItemController {\n constructor($filter,\n $rootScope,\n $scope,\n $element,\n dragulaService,\n NodeService,\n PlanningService,\n ProjectService,\n StudentDataService,\n $mdDialog) {\n\n this.$filter = $filter;\n this.$rootScope = $rootScope;\n this.$scope = $scope;\n this.$element = $element;\n this.dragulaService = dragulaService;\n this.NodeService = NodeService;\n this.PlanningService = PlanningService;\n this.ProjectService = ProjectService;\n this.StudentDataService = StudentDataService;\n this.$mdDialog = $mdDialog;\n this.$translate = this.$filter('translate');\n this.autoScroll = require('dom-autoscroller');\n\n this.expanded = false;\n\n this.item = this.ProjectService.idToNode[this.nodeId];\n this.isGroup = this.ProjectService.isGroupNode(this.nodeId);\n this.nodeStatuses = this.StudentDataService.nodeStatuses;\n this.nodeStatus = this.nodeStatuses[this.nodeId];\n\n this.nodeTitle = this.showPosition ? (this.ProjectService.nodeIdToNumber[this.nodeId] + ': ' + this.item.title) : this.item.title;\n this.currentNode = this.StudentDataService.currentNode;\n this.previousNode = null;\n this.isCurrentNode = (this.currentNode.id === this.nodeId);\n\n // whether this node is a planning node\n this.isPlanning = this.PlanningService.isPlanning(this.nodeId);\n\n // the array of nodes used for drag/drop planning sorting\n this.availablePlanningNodes = [];\n\n // whether the node is a planning node instance\n this.node = this.ProjectService.getNodeById(this.nodeId);\n this.isPlanningInstance = this.PlanningService.isPlanningInstance(this.nodeId);\n\n this.parentGroupId = null;\n\n /*\n * whether planning mode is on or off which determines if students\n * can edit planning related aspects of the project such as adding,\n * moving, or deleting planning steps.\n */\n this.planningMode = false;\n\n var parentGroup = this.ProjectService.getParentGroup(this.nodeId);\n\n if (parentGroup != null) {\n this.parentGroupId = parentGroup.id;\n this.isParentGroupPlanning = this.PlanningService.isPlanning(this.parentGroupId);\n }\n\n if (this.isPlanning) {\n /*\n * planning is enabled so we will get the available planning\n * nodes that can be used in this group\n */\n this.availablePlanningNodes = this.PlanningService.getAvailablePlanningNodes(this.nodeId);\n }\n\n if (this.isParentGroupPlanning) {\n\n if (parentGroup.planningMode) {\n // the parent is currently in planning mode\n this.planningMode = true;\n }\n\n /*\n * planning is enabled so we will get the available planning\n * nodes that can be used in this group\n */\n this.availablePlanningNodes = this.PlanningService.getAvailablePlanningNodes(this.parentGroupId);\n\n this.$scope.$watch(\n () => {\n // watch the position of this node\n return this.ProjectService.nodeIdToNumber[this.nodeId];\n },\n (value) => {\n // the position has changed for this node so we will update it in the UI\n this.nodeTitle = this.showPosition ? (this.ProjectService.nodeIdToNumber[this.nodeId] + ': ' + this.item.title) : this.item.title;\n }\n );\n }\n\n this.$scope.$watch(\n () => { return this.StudentDataService.currentNode; },\n (newNode, oldNode) => {\n this.currentNode = newNode;\n this.previousNode = oldNode;\n this.isCurrentNode = (this.nodeId === newNode.id);\n let isPrev = false;\n\n if (this.ProjectService.isApplicationNode(newNode.id)) {\n return;\n }\n\n if (oldNode) {\n isPrev = (this.nodeId === oldNode.id);\n\n if (this.StudentDataService.previousStep) {\n this.$scope.$parent.isPrevStep = (this.nodeId === this.StudentDataService.previousStep.id);\n }\n }\n\n if (this.isGroup) {\n let prevNodeisGroup = (!oldNode || this.ProjectService.isGroupNode(oldNode.id));\n let prevNodeIsDescendant = this.ProjectService.isNodeDescendentOfGroup(oldNode, this.item);\n if (this.isCurrentNode) {\n this.expanded = true;\n if (prevNodeisGroup || !prevNodeIsDescendant) {\n this.zoomToElement();\n }\n } else {\n if (!prevNodeisGroup) {\n if (prevNodeIsDescendant) {\n this.expanded = true;\n } else {\n this.expanded = false;\n }\n }\n }\n } else {\n if (isPrev && this.ProjectService.isNodeDescendentOfGroup(this.item, newNode)) {\n this.zoomToElement();\n }\n }\n }\n );\n\n this.$scope.$watch(\n () => { return this.expanded; },\n (value) => {\n this.$scope.$parent.itemExpanded = value;\n }\n );\n\n this.$scope.$watch(\n () => { return this.planningMode; },\n (value) => {\n this.$scope.$parent.planningMode = value;\n }\n );\n\n // a group node has turned on or off planning mode\n this.$rootScope.$on('togglePlanningMode', (event, args) => {\n\n // get the group node that has had its planning node changed\n let planningModeClickedNodeId = args.nodeId;\n let planningMode = args.planningMode;\n\n // get this node's parent group\n let parentGroup = this.ProjectService.getParentGroup(this.nodeId);\n let parentGroupId = null;\n\n if (parentGroup != null) {\n parentGroupId = parentGroup.id;\n }\n\n if (parentGroupId == planningModeClickedNodeId) {\n // the parent of this node has changed their planning mode\n this.planningMode = planningMode;\n }\n });\n\n let dragId = 'planning_' + this.nodeId ;\n // handle item drop events\n let dropEvent = dragId + '.drop-model';\n this.$scope.$on(dropEvent, (el, target, source) => {\n let nodeChangedId = target.data().nodeid;\n this.planningNodeItemsChanged(nodeChangedId);\n });\n\n this.dragulaService.options(this.$scope, dragId, {\n moves: (el, source, handle, sibling) => {\n if (!this.planningMode) {\n return false;\n }\n\n let nodeId = el.getAttribute('data-nodeid');\n return this.PlanningService.isPlanningInstance(nodeId);\n }\n });\n\n let drake = dragulaService.find(this.$scope, dragId).drake;\n\n // support scroll while dragging\n let scroll = this.autoScroll(\n [document.querySelector('#content')], {\n margin: 30,\n pixels: 50,\n scrollWhenOutside: true,\n autoScroll: function() {\n // Only scroll when the pointer is down, and there is a child being dragged\n return this.down && drake.dragging;\n }\n });\n }\n\n getTemplateUrl(){\n return this.ProjectService.getThemePath() + '/themeComponents/navItem/navItem.html';\n };\n\n zoomToElement() {\n setTimeout(()=> {\n // smooth scroll to expanded group's page location\n let top = this.$element[0].offsetTop;\n let location = this.isGroup ? top - 32 : top - 80;\n let delay = 350;\n $('#content').animate({\n scrollTop: location\n }, delay, 'linear');\n }, 500);\n };\n\n itemClicked(event) {\n if (this.isGroup) {\n this.expanded = !this.expanded;\n if (this.expanded) {\n if (this.isCurrentNode) {\n this.zoomToElement();\n } else {\n this.StudentDataService.endCurrentNodeAndSetCurrentNodeByNodeId(this.nodeId);\n }\n }\n } else {\n if (this.StudentDataService.planningMode) {\n // Don't allow students to enter planning steps while in planning mode\n this.$mdDialog.show(\n this.$mdDialog.alert()\n .title(this.$translate('itemLocked'))\n .textContent(this.$translate('planningModeStepsUnVisitable'))\n .ariaLabel(this.$translate('itemLocked'))\n .ok(this.$translate('ok'))\n .targetEvent(event)\n );\n } else {\n this.StudentDataService.endCurrentNodeAndSetCurrentNodeByNodeId(this.nodeId);\n }\n }\n };\n\n /**\n * Save an event when planning node is added\n * @param planningNodeAdded\n */\n savePlanningNodeAddedEvent(planningNodeAdded) {\n let componentId = null;\n let componentType = null;\n let category = \"Planning\";\n let eventName = \"planningNodeAdded\";\n let eventData = {\n nodeIdAdded: planningNodeAdded.id,\n planningNodeTemplateId: planningNodeAdded.planningNodeTemplateId\n };\n let eventNodeId = this.nodeId;\n this.StudentDataService.saveVLEEvent(eventNodeId, componentId, componentType, category, eventName, eventData);\n };\n\n /**\n * Returns the max times a planning node can be added to the project (-1 is\n * is returned if there is no limit)\n * @param planningNodeId\n */\n getPlannindNodeMaxAllowed(planningNodeId) {\n let maxAddAllowed = -1; // by default, students can add as many instances as they want\n let planningGroupNode = null;\n if (this.isParentGroupPlanning) {\n planningGroupNode = this.ProjectService.getNodeById(this.parentGroupId);\n } else {\n planningGroupNode = this.ProjectService.getNodeById(this.nodeId);\n }\n // get the maxAddAllowed value by looking up the planningNode in the project.\n if (planningGroupNode && planningGroupNode.availablePlanningNodes) {\n for (let a = 0; a < planningGroupNode.availablePlanningNodes.length; a++) {\n let availablePlanningNode = planningGroupNode.availablePlanningNodes[a];\n if (availablePlanningNode.nodeId === planningNodeId && availablePlanningNode.max != null) {\n maxAddAllowed = availablePlanningNode.max;\n }\n }\n }\n\n return maxAddAllowed;\n };\n\n /**\n * Returns the number of times a planning node has been added to the project\n * @param planningNodeId\n */\n getNumPlannindNodeInstances(planningNodeId) {\n let numPlanningNodesAdded = 0; // keep track of number of instances\n // otherwise, see how many times the planning node template has been used.\n\n let planningGroupNode = null;\n if (this.isParentGroupPlanning) {\n planningGroupNode = this.ProjectService.getNodeById(this.parentGroupId);\n } else {\n planningGroupNode = this.ProjectService.getNodeById(this.nodeId);\n }\n\n // loop through the child ids in the planning group and see how many times they've been used\n if (planningGroupNode && planningGroupNode.ids) {\n for (let c = 0; c < planningGroupNode.ids.length; c++) {\n let childPlanningNodeId = planningGroupNode.ids[c];\n let childPlanningNode = this.ProjectService.getNodeById(childPlanningNodeId);\n if (childPlanningNode != null && childPlanningNode.planningNodeTemplateId === planningNodeId) {\n numPlanningNodesAdded++;\n }\n }\n }\n\n return numPlanningNodesAdded;\n };\n\n /**\n * Returns true iff this student can add the specified planning node.\n * Limits include reaching the max allowed count\n * @param planningNodeId\n */\n canAddPlanningNode(planningNodeId) {\n let maxAddAllowed = this.getPlannindNodeMaxAllowed(planningNodeId);\n\n // if maxAddAllowed was not found or is set to 0, it means students can add as many as they want\n if (maxAddAllowed < 1) {\n return true;\n }\n\n let numPlanningNodesAdded = this.getNumPlannindNodeInstances(planningNodeId);\n\n return numPlanningNodesAdded < maxAddAllowed;\n };\n\n /**\n * Create a planning node instance and add it to the project\n * @param groupId the group the new planning node instance will be added to\n * @param templateNodeId the node id of the planning node template\n * @returns the planning node instance\n */\n addPlanningNodeInstanceInside(nodeIdToInsertInside, templateNodeId) {\n // create the planning node instance\n let nextAvailablePlanningNodeId = this.StudentDataService.getNextAvailablePlanningNodeId();\n let planningNodeInstance = this.PlanningService.createPlanningNodeInstance(templateNodeId, nextAvailablePlanningNodeId);\n\n // add the planning node instance inside\n this.PlanningService.addPlanningNodeInstanceInside(nodeIdToInsertInside, planningNodeInstance);\n\n /*\n * update the node statuses so that a node status is created for\n * the new planning node instance\n */\n this.StudentDataService.updateNodeStatuses();\n\n // perform any necessary updating\n this.planningNodeChanged();\n\n // Save add planning node event\n this.savePlanningNodeAddedEvent(planningNodeInstance);\n\n return planningNodeInstance;\n }\n\n /**\n * Open the planning mode select dialog to choose a planning node template\n * to create a new planning instance\n * @param event the trigger event\n * @param targetNodeId the node to insert the new planning instance after or inside\n * @param insertInside boolean whether to insert the new planning instance\n * inside the target node (optional; default is after)\n */\n addPlanningInstance(event, targetNodeId, insertInside) {\n // show dialog with list of planning nodes user can add to current group\n\n let choosePlanningItemTemplateUrl = this.ProjectService.getThemePath() + '/themeComponents/navItem/choosePlanningItem.html';\n let navitemCtrl = this;\n\n this.$mdDialog.show({\n parent: angular.element(document.body),\n locals: {\n targetNodeId: targetNodeId,\n insertInside: insertInside,\n navitemCtrl: navitemCtrl,\n },\n templateUrl: choosePlanningItemTemplateUrl,\n targetEvent: event,\n controller: ChoosePlanningItemController\n });\n\n function ChoosePlanningItemController($scope, $mdDialog, targetNodeId, insertInside, navitemCtrl) {\n $scope.navitemCtrl = navitemCtrl;\n $scope.targetNodeId = targetNodeId;\n $scope.insertInside = insertInside;\n\n $scope.addSelectedPlanningInstance = (templateNodeId) => {\n if ($scope.insertInside) {\n $scope.navitemCtrl.addPlanningNodeInstanceInside($scope.targetNodeId, templateNodeId);\n } else {\n $scope.navitemCtrl.addPlanningNodeInstanceAfter($scope.targetNodeId, templateNodeId);\n }\n\n $mdDialog.hide();\n };\n\n $scope.close = () => {\n $mdDialog.hide();\n };\n }\n ChoosePlanningItemController.$inject = [\"$scope\", \"$mdDialog\", \"targetNodeId\", \"insertInside\", \"navitemCtrl\"];\n };\n\n /**\n * Create a planning node instance and add it to the project after the specified nodeId\n * @param groupId the group the new planning node instance will be added to\n * @param nodeId the node id of the planning node template\n */\n addPlanningNodeInstanceAfter(nodeIdToInsertAfter, templateNodeId) {\n\n var parentGroup = this.ProjectService.getParentGroup(nodeIdToInsertAfter);\n\n if (parentGroup != null) {\n var parentGroupId = parentGroup.id;\n\n // create the planning node instance\n let nextAvailablePlanningNodeId = this.StudentDataService.getNextAvailablePlanningNodeId();\n let planningNodeInstance = this.PlanningService.createPlanningNodeInstance(templateNodeId, nextAvailablePlanningNodeId);\n\n // insert planning node instance after\n this.PlanningService.addPlanningNodeInstanceAfter(nodeIdToInsertAfter, planningNodeInstance);\n\n /*\n * update the node statuses so that a node status is created for\n * the new planning node instance\n */\n this.StudentDataService.updateNodeStatuses();\n\n // perform any necessary updating\n this.planningNodeChanged();\n\n // Save add planning node event\n this.savePlanningNodeAddedEvent(planningNodeInstance);\n\n return planningNodeInstance;\n }\n }\n\n /**\n * Remove the planning node instance\n * @param planningNodeInstanceNodeId the planning node instance to remove\n * @param event the event that triggered the function call\n */\n removePlanningNodeInstance(planningNodeInstanceNodeId, event) {\n let confirm = this.$mdDialog.confirm()\n .parent(angular.element(document.body))\n .title(this.$translate('areYouSureYouWantToDeleteThisItem'))\n .textContent(this.$translate('noteAnyWorkYouHaveDoneOnThisItemWillBeLost'))\n .ariaLabel(this.$translate('deleteItemFromProject'))\n .targetEvent(event)\n .ok(this.$translate('yes'))\n .cancel(this.$translate('no'));\n\n this.$mdDialog.show(confirm).then(() => {\n // delete the node from the project\n this.ProjectService.deleteNode(planningNodeInstanceNodeId);\n\n // perform any necessary updating\n this.planningNodeChanged(this.parentGroupId);\n\n // Save remove planning node event\n let componentId = null;\n let componentType = null;\n let category = \"Planning\";\n let eventName = \"planningNodeRemoved\";\n let eventData = {\n nodeIdRemoved: planningNodeInstanceNodeId\n };\n let eventNodeId = this.nodeId;\n this.StudentDataService.saveVLEEvent(eventNodeId, componentId, componentType, category, eventName, eventData);\n }, () => {});\n }\n\n /**\n * Get the node title\n * @param nodeId get the title for this node\n * @returns the title for the node\n */\n getNodeTitle(nodeId) {\n var node = this.ProjectService.idToNode[nodeId];\n var title = null;\n\n if (node != null) {\n title = node.title;\n }\n\n return title;\n }\n\n /**\n * Get the node description\n * @param nodeId get the description for this node\n * @returns the description for the node\n */\n getNodeDescription(nodeId) {\n var node = this.ProjectService.idToNode[nodeId];\n var description = null;\n\n if (node != null) {\n description = node.description;\n }\n\n return description;\n }\n\n /**\n * Move the planning node. If the other node is a group node, we will\n * insert this node as the first node in the group. If the other node is\n * a step node, we will insert this node after the other node.\n * @param otherNodeId the other node we will move this node inside or after\n */\n movePlanningNode(nodeIdToMove, nodeIdToMoveAfter) {\n\n /*\n * check that this node is not the same as the other node.\n * if they are the same we don't need to do anything.\n */\n if (nodeIdToMove != nodeIdToMoveAfter) {\n if (this.ProjectService.isGroupNode(nodeIdToMoveAfter)) {\n this.PlanningService.movePlanningNodeInstanceInside(nodeIdToMove, nodeIdToMoveAfter);\n } else {\n this.PlanningService.movePlanningNodeInstanceAfter(nodeIdToMove, nodeIdToMoveAfter);\n }\n }\n\n // perform any necessary updating\n this.planningNodeChanged();\n }\n\n /**\n * Something related to planning has changed in the project. This\n * means a planning node was added, moved, or deleted.\n * @param param planningNodeId planning node id\n */\n planningNodeChanged(planningNodeId) {\n this.savePlanningNodeChanges(planningNodeId);\n\n this.$rootScope.$broadcast('planningNodeChanged');\n }\n\n /**\n * Save the changed nodes in NodeState\n * @param param planningNodeId planning node id\n **/\n savePlanningNodeChanges(planningNodeId) {\n let nodeState = this.NodeService.createNewNodeState();\n let nodeId = planningNodeId ? planningNodeId : this.nodeId;\n nodeState.nodeId = nodeId;\n nodeState.isAutoSave = false;\n nodeState.isSubmit = false;\n\n var studentData = {};\n studentData.nodeId = nodeId;\n studentData.nodes = [];\n let planningNode = this.ProjectService.getNodeById(nodeId);\n studentData.nodes.push(planningNode); // add the planning node (group)\n // loop through the child ids in the planning group and save them also\n if (planningNode.ids != null) {\n for (let c = 0; c < planningNode.ids.length; c++) {\n let childPlanningNodeId = planningNode.ids[c];\n let childPlanningNode = this.ProjectService.getNodeById(childPlanningNodeId);\n studentData.nodes.push(childPlanningNode);\n }\n }\n\n nodeState.studentData = studentData;\n var nodeStates = [];\n nodeStates.push(nodeState);\n this.StudentDataService.saveNodeStates(nodeStates);\n }\n\n /**\n * Toggle the planning mode on and off. Notify child nodes that\n * the planning mode has changed so they can act accordingly.\n */\n togglePlanningMode() {\n /*if (this.StudentDataService.planningMode && !this.item.planningMode) {\n // Don't allow multiple concurrent planning modes.\n this.$translate('planningModeOnlyOnePlanningModeAllowed').then((planningModeOnlyOnePlanningModeAllowed) => {\n alert(planningModeOnlyOnePlanningModeAllowed);\n });\n\n return;\n }*/\n\n // toggle the planning mode\n //this.planningMode = !this.planningMode;\n this.item.planningMode = this.planningMode;\n\n // also toggle StudentDataService planning mode. This will be used to constrain the entire project when in planning mode.\n this.StudentDataService.planningMode = this.planningMode;\n\n // Save planning mode on/off event\n let componentId = null;\n let componentType = null;\n let category = \"Planning\";\n let eventName = this.planningMode ? \"planningModeOn\" : \"planningModeOff\";\n let eventData = {\n nodeId: this.nodeId\n };\n let eventNodeId = this.nodeId;\n this.StudentDataService.saveVLEEvent(eventNodeId, componentId, componentType, category, eventName, eventData);\n\n // notify the child nodes that the planning mode of this group node has changed\n this.$rootScope.$broadcast('togglePlanningMode', { nodeId: this.nodeId, planningMode: this.planningMode });\n }\n\n /**\n * The planning node's items array has changed\n * @param newValue the new value of the planning node's items array\n * @param oldValue the old value of the planning node's items array\n */\n planningNodeItemsChanged(nodeChangedId) {\n let index = this.item.ids.indexOf(nodeChangedId);\n let nodeIdAddedAfter = this.item.ids[index-1];\n\n if (nodeIdAddedAfter) {\n // the node was moved after another node in the group\n this.movePlanningNode(nodeChangedId, nodeIdAddedAfter);\n } else {\n // the node was moved to the beginning of the group\n this.movePlanningNode(nodeChangedId, this.nodeId);\n }\n };\n}\n\nNavItemController.$inject = [\n '$filter',\n '$rootScope',\n '$scope',\n '$element',\n 'dragulaService',\n 'NodeService',\n 'PlanningService',\n 'ProjectService',\n 'StudentDataService',\n '$mdDialog'\n];\n\nexport default NavItemController;\n"]} \ No newline at end of file diff --git a/src/main/webapp/wise5/vle/main.es6 b/src/main/webapp/wise5/vle/main.es6 index 9f75add609..83a0f27cb1 100644 --- a/src/main/webapp/wise5/vle/main.es6 +++ b/src/main/webapp/wise5/vle/main.es6 @@ -23,6 +23,7 @@ import ConceptMapComponentModule from '../components/conceptMap/conceptMapCompon import ConfigService from '../services/configService'; import CRaterService from '../services/cRaterService'; import Components from '../directives/components'; +import ComponentService from '../components/componentService'; import DiscussionComponentModule from '../components/discussion/discussionComponentModule'; import DrawComponentModule from '../components/draw/drawComponentModule'; import EmbeddedComponentModule from '../components/embedded/embeddedComponentModule'; @@ -42,6 +43,7 @@ import NotebookService from '../services/notebookService'; import NotificationService from '../services/notificationService'; import OpenResponseComponentModule from '../components/openResponse/openResponseComponentModule'; import OutsideURLComponentModule from '../components/outsideURL/outsideURLComponentModule'; +import PlanningService from '../services/planningService'; import ProjectService from '../services/projectService'; import SessionService from '../services/sessionService'; import StudentAsset from './studentAsset/studentAsset'; @@ -93,11 +95,13 @@ let vleModule = angular.module('vle', [ .service(AchievementService.name, AchievementService) .service(AnnotationService.name, AnnotationService) .service(ConfigService.name, ConfigService) + .service(ComponentService.name, ComponentService) .service(CRaterService.name, CRaterService) .service(HttpInterceptor.name, HttpInterceptor) .service(NodeService.name, NodeService) .service(NotebookService.name, NotebookService) .service(NotificationService.name, NotificationService) + .service(PlanningService.name, PlanningService) .service(ProjectService.name, VLEProjectService) .service(SessionService.name, SessionService) .service(StudentAssetService.name, StudentAssetService) diff --git a/src/main/webapp/wise5/vle/main.js b/src/main/webapp/wise5/vle/main.js index 09f254fc58..337c5f861e 100644 --- a/src/main/webapp/wise5/vle/main.js +++ b/src/main/webapp/wise5/vle/main.js @@ -96,6 +96,10 @@ var _components = require('../directives/components'); var _components2 = _interopRequireDefault(_components); +var _componentService = require('../components/componentService'); + +var _componentService2 = _interopRequireDefault(_componentService); + var _discussionComponentModule = require('../components/discussion/discussionComponentModule'); var _discussionComponentModule2 = _interopRequireDefault(_discussionComponentModule); @@ -172,6 +176,10 @@ var _outsideURLComponentModule = require('../components/outsideURL/outsideURLCom var _outsideURLComponentModule2 = _interopRequireDefault(_outsideURLComponentModule); +var _planningService = require('../services/planningService'); + +var _planningService2 = _interopRequireDefault(_planningService); + var _projectService = require('../services/projectService'); var _projectService2 = _interopRequireDefault(_projectService); @@ -230,7 +238,7 @@ var _angularSummernote2 = _interopRequireDefault(_angularSummernote); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var vleModule = _angular2.default.module('vle', [(0, _angularDragula2.default)(_angular2.default), 'angularMoment', 'angular-toArrayFilter', 'animationComponentModule', 'audioOscillatorComponentModule', 'components', 'conceptMapComponentModule', 'discussionComponentModule', 'drawComponentModule', 'embeddedComponentModule', 'filters', 'graphComponentModule', 'highcharts-ng', 'htmlComponentModule', 'labelComponentModule', 'matchComponentModule', 'multipleChoiceComponentModule', 'ngAria', 'ngFileUpload', 'ngMaterial', 'ngOnload', 'ngSanitize', 'ngWebSocket', 'oc.lazyLoad', 'openResponseComponentModule', 'outsideURLComponentModule', 'pascalprecht.translate', 'studentAsset', 'summernote', 'tableComponentModule', 'ui.router', 'ui.scrollpoint']).service(_achievementService2.default.name, _achievementService2.default).service(_annotationService2.default.name, _annotationService2.default).service(_configService2.default.name, _configService2.default).service(_cRaterService2.default.name, _cRaterService2.default).service(_httpInterceptor2.default.name, _httpInterceptor2.default).service(_nodeService2.default.name, _nodeService2.default).service(_notebookService2.default.name, _notebookService2.default).service(_notificationService2.default.name, _notificationService2.default).service(_projectService2.default.name, _vleProjectService2.default).service(_sessionService2.default.name, _sessionService2.default).service(_studentAssetService2.default.name, _studentAssetService2.default).service(_studentDataService2.default.name, _studentDataService2.default).service(_studentStatusService2.default.name, _studentStatusService2.default).service(_studentWebSocketService2.default.name, _studentWebSocketService2.default).service(_utilService2.default.name, _utilService2.default).controller(_navigationController2.default.name, _navigationController2.default).controller(_nodeController2.default.name, _nodeController2.default).controller(_vleController2.default.name, _vleController2.default).filter(_filters2.default.name, _filters2.default).config(['$urlRouterProvider', '$stateProvider', '$translateProvider', '$translatePartialLoaderProvider', '$controllerProvider', '$mdThemingProvider', '$httpProvider', '$provide', function ($urlRouterProvider, $stateProvider, $translateProvider, $translatePartialLoaderProvider, $controllerProvider, $mdThemingProvider, $httpProvider, $provide) { +var vleModule = _angular2.default.module('vle', [(0, _angularDragula2.default)(_angular2.default), 'angularMoment', 'angular-toArrayFilter', 'animationComponentModule', 'audioOscillatorComponentModule', 'components', 'conceptMapComponentModule', 'discussionComponentModule', 'drawComponentModule', 'embeddedComponentModule', 'filters', 'graphComponentModule', 'highcharts-ng', 'htmlComponentModule', 'labelComponentModule', 'matchComponentModule', 'multipleChoiceComponentModule', 'ngAria', 'ngFileUpload', 'ngMaterial', 'ngOnload', 'ngSanitize', 'ngWebSocket', 'oc.lazyLoad', 'openResponseComponentModule', 'outsideURLComponentModule', 'pascalprecht.translate', 'studentAsset', 'summernote', 'tableComponentModule', 'ui.router', 'ui.scrollpoint']).service(_achievementService2.default.name, _achievementService2.default).service(_annotationService2.default.name, _annotationService2.default).service(_configService2.default.name, _configService2.default).service(_componentService2.default.name, _componentService2.default).service(_cRaterService2.default.name, _cRaterService2.default).service(_httpInterceptor2.default.name, _httpInterceptor2.default).service(_nodeService2.default.name, _nodeService2.default).service(_notebookService2.default.name, _notebookService2.default).service(_notificationService2.default.name, _notificationService2.default).service(_planningService2.default.name, _planningService2.default).service(_projectService2.default.name, _vleProjectService2.default).service(_sessionService2.default.name, _sessionService2.default).service(_studentAssetService2.default.name, _studentAssetService2.default).service(_studentDataService2.default.name, _studentDataService2.default).service(_studentStatusService2.default.name, _studentStatusService2.default).service(_studentWebSocketService2.default.name, _studentWebSocketService2.default).service(_utilService2.default.name, _utilService2.default).controller(_navigationController2.default.name, _navigationController2.default).controller(_nodeController2.default.name, _nodeController2.default).controller(_vleController2.default.name, _vleController2.default).filter(_filters2.default.name, _filters2.default).config(['$urlRouterProvider', '$stateProvider', '$translateProvider', '$translatePartialLoaderProvider', '$controllerProvider', '$mdThemingProvider', '$httpProvider', '$provide', function ($urlRouterProvider, $stateProvider, $translateProvider, $translatePartialLoaderProvider, $controllerProvider, $mdThemingProvider, $httpProvider, $provide) { $urlRouterProvider.otherwise('/vle/'); _angular2.default.module('vle').$controllerProvider = $controllerProvider; diff --git a/src/main/webapp/wise5/vle/main.js.map b/src/main/webapp/wise5/vle/main.js.map index 61ad9fdc10..b210a707c7 100644 --- a/src/main/webapp/wise5/vle/main.js.map +++ b/src/main/webapp/wise5/vle/main.js.map @@ -1 +1 @@ -{"version":3,"sources":["main.es6"],"names":["vleModule","module","service","name","controller","filter","config","$urlRouterProvider","$stateProvider","$translateProvider","$translatePartialLoaderProvider","$controllerProvider","$mdThemingProvider","$httpProvider","$provide","otherwise","state","url","abstract","templateProvider","$http","ProjectService","themePath","getThemePath","get","then","response","data","controllerAs","resolve","ConfigService","configURL","window","retrieveConfig","project","retrieveProject","studentData","StudentDataService","retrieveStudentData","notebook","NotebookService","StudentAssetService","retrieveAssets","studentAssets","retrieveNotebookItems","getWorkgroupId","achievements","AchievementService","retrieveAchievements","notifications","NotificationService","retrieveNotifications","runStatus","retrieveRunStatus","sessionTimers","SessionService","initializeSession","webSocket","StudentWebSocketService","initialize","language","$translate","locale","getLocale","use","theme","$ocLazyLoad","$q","def","defer","System","import","themeModule","m","default","key","Object","keys","load","err","promise","views","wiseBaseURL","getWISEBaseURL","interceptors","push","addPart","useLoader","urlTemplate","fallbackLanguage","registerAvailableLanguageKeys","determinePreferredLanguage","useSanitizeValueStrategy","definePalette","undefined","primaryPalette","accentPalette","warnPalette","lightMap","extendPalette","setDefaultTheme","enableBrowserColor","updateLocale","calendar","lastDay","sameDay","nextDay","lastWeek","nextWeek","sameElse"],"mappings":"AAAA;;;;;;AAEA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;;;AAEA,IAAIA,YAAY,kBAAQC,MAAR,CAAe,KAAf,EAAsB,CAClC,gDADkC,EAElC,eAFkC,EAGlC,uBAHkC,EAIlC,0BAJkC,EAKlC,gCALkC,EAMlC,YANkC,EAOlC,2BAPkC,EAQlC,2BARkC,EASlC,qBATkC,EAUlC,yBAVkC,EAWlC,SAXkC,EAYlC,sBAZkC,EAalC,eAbkC,EAclC,qBAdkC,EAelC,sBAfkC,EAgBlC,sBAhBkC,EAiBlC,+BAjBkC,EAkBlC,QAlBkC,EAmBlC,cAnBkC,EAoBlC,YApBkC,EAqBlC,UArBkC,EAsBlC,YAtBkC,EAuBlC,aAvBkC,EAwBlC,aAxBkC,EAyBlC,6BAzBkC,EA0BlC,2BA1BkC,EA2BlC,wBA3BkC,EA4BlC,cA5BkC,EA6BlC,YA7BkC,EA8BlC,sBA9BkC,EA+BlC,WA/BkC,EAgClC,gBAhCkC,CAAtB,EAiCbC,OAjCa,CAiCL,6BAAmBC,IAjCd,gCAkCbD,OAlCa,CAkCL,4BAAkBC,IAlCb,+BAmCbD,OAnCa,CAmCL,wBAAcC,IAnCT,2BAoCbD,OApCa,CAoCL,wBAAcC,IApCT,2BAqCbD,OArCa,CAqCL,0BAAgBC,IArCX,6BAsCbD,OAtCa,CAsCL,sBAAYC,IAtCP,yBAuCbD,OAvCa,CAuCL,0BAAgBC,IAvCX,6BAwCbD,OAxCa,CAwCL,8BAAoBC,IAxCf,iCAyCbD,OAzCa,CAyCL,yBAAeC,IAzCV,+BA0CbD,OA1Ca,CA0CL,yBAAeC,IA1CV,4BA2CbD,OA3Ca,CA2CL,8BAAoBC,IA3Cf,iCA4CbD,OA5Ca,CA4CL,6BAAmBC,IA5Cd,gCA6CbD,OA7Ca,CA6CL,+BAAqBC,IA7ChB,kCA8CbD,OA9Ca,CA8CL,kCAAwBC,IA9CnB,qCA+CbD,OA/Ca,CA+CL,sBAAYC,IA/CP,yBAgDbC,UAhDa,CAgDF,+BAAqBD,IAhDnB,kCAiDbC,UAjDa,CAiDF,yBAAeD,IAjDb,4BAkDbC,UAlDa,CAkDF,wBAAcD,IAlDZ,2BAmDbE,MAnDa,CAmDN,kBAAQF,IAnDF,qBAoDbG,MApDa,CAoDN,CACJ,oBADI,EAEJ,gBAFI,EAGJ,oBAHI,EAIJ,iCAJI,EAKJ,qBALI,EAMJ,oBANI,EAOJ,eAPI,EAQJ,UARI,EASJ,UAACC,kBAAD,EACAC,cADA,EAEAC,kBAFA,EAGAC,+BAHA,EAIAC,mBAJA,EAKAC,kBALA,EAMAC,aANA,EAOAC,QAPA,EAOa;AACbP,qBAAmBQ,SAAnB,CAA6B,OAA7B;;AAEA,oBAAQd,MAAR,CAAe,KAAf,EAAsBU,mBAAtB,GAA4CA,mBAA5C;;AAEAH,iBACGQ,KADH,CACS,MADT,EACiB;AACbC,SAAK,EADQ;AAEbC,cAAU,IAFG;AAGbC,sBAAkB,CAAC,OAAD,EAAU,gBAAV,EAA4B,UAACC,KAAD,EAAQC,cAAR,EAA2B;AACvE,UAAIC,YAAYD,eAAeE,YAAf,EAAhB;AACA,aAAOH,MAAMI,GAAN,CAAUF,YAAY,WAAtB,EAAmCG,IAAnC,CACL,oBAAY;AACV,eAAOC,SAASC,IAAhB;AACD,OAHI,CAAP;AAID,KANiB,CAHL;AAUbvB,gBAAY,eAVC;AAWbwB,kBAAc,eAXD;AAYbC,aAAS;AACPvB,cAAQ,gBAACwB,aAAD,EAAmB;AACzB,YAAIC,YAAYC,OAAOD,SAAvB;AACA,eAAOD,cAAcG,cAAd,CAA6BF,SAA7B,CAAP;AACD,OAJM;AAKPG,eAAS,iBAACb,cAAD,EAAiBf,MAAjB,EAA4B;AACnC,eAAOe,eAAec,eAAf,EAAP;AACD,OAPM;AAQPC,mBAAa,qBAACC,kBAAD,EAAqB/B,MAArB,EAA6B4B,OAA7B,EAAyC;AACpD,eAAOG,mBAAmBC,mBAAnB,EAAP;AACD,OAVM;AAWPC,gBAAU,kBAACC,eAAD,EAAkBV,aAAlB,EAAiCW,mBAAjC,EAAsDL,WAAtD,EAAmE9B,MAAnE,EAA2E4B,OAA3E,EAAuF;AAC/F,eAAOO,oBAAoBC,cAApB,GAAqCjB,IAArC,CAA0C,UAACkB,aAAD,EAAmB;AAClE,iBAAOH,gBAAgBI,qBAAhB,CAAsCd,cAAce,cAAd,EAAtC,EAAsEpB,IAAtE,CAA2E,UAACc,QAAD,EAAc;AAC9F,mBAAOA,QAAP;AACD,WAFM,CAAP;AAGD,SAJM,CAAP;AAKD,OAjBM;AAkBPO,oBAAc,sBAACC,kBAAD,EAAqBX,WAArB,EAAkC9B,MAAlC,EAA0C4B,OAA1C,EAAsD;AAClE,eAAOa,mBAAmBC,oBAAnB,EAAP;AACD,OApBM;AAqBPC,qBAAe,uBAACC,mBAAD,EAAsBd,WAAtB,EAAmC9B,MAAnC,EAA2C4B,OAA3C,EAAuD;AACpE,eAAOgB,oBAAoBC,qBAApB,EAAP;AACD,OAvBM;AAwBPC,iBAAW,mBAACf,kBAAD,EAAqB/B,MAArB,EAAgC;AACzC,eAAO+B,mBAAmBgB,iBAAnB,EAAP;AACD,OA1BM;AA2BPC,qBAAe,uBAACC,cAAD,EAAiBjD,MAAjB,EAAyB4B,OAAzB,EAAkCE,WAAlC,EAAkD;AAC/D,eAAOmB,eAAeC,iBAAf,EAAP;AACD,OA7BM;AA8BPC,iBAAW,mBAACC,uBAAD,EAA0BpD,MAA1B,EAAkC4B,OAAlC,EAA8C;AACvD,eAAOwB,wBAAwBC,UAAxB,EAAP;AACD,OAhCM;AAiCPC,gBAAU,kBAACC,UAAD,EAAa/B,aAAb,EAA4BxB,MAA5B,EAAuC;AAC/C,YAAIwD,SAAShC,cAAciC,SAAd,EAAb,CAD+C,CACN;AACzCF,mBAAWG,GAAX,CAAeF,MAAf;AACD,OApCM;AAqCPG,aAAO,eAAC5C,cAAD,EAAiBf,MAAjB,EAAyB4B,OAAzB,EAAkCgC,WAAlC,EAA+CC,EAA/C,EAAsD;AAC3D,YAAIF,QAAQ5C,eAAeE,YAAf,KAAgC,WAA5C;AACA,YAAI6C,MAAMD,GAAGE,KAAH,EAAV;;AAEAC,eAAOC,MAAP,CAAcN,KAAd,EAAqBxC,IAArB,CAA0B,aAAK;AAC7B,cAAI+C,cAAcC,EAAEC,OAApB;AACA,cAAI,CAACD,EAAEC,OAAF,CAAUvE,IAAf,EAAqB;AACnB,gBAAIwE,MAAMC,OAAOC,IAAP,CAAYJ,EAAEC,OAAd,CAAV;AACAF,0BAAcC,EAAEC,OAAF,CAAUC,IAAI,CAAJ,CAAV,CAAd;AACD;;AAEDT,sBAAYY,IAAZ,CAAiBN,WAAjB,EAA8B/C,IAA9B,CAAmC,YAAM;AACvC2C,gBAAIvC,OAAJ;AACD,WAFD,EAEG,eAAO;AACR,kBAAMkD,GAAN;AACD,WAJD;AAKD,SAZD;;AAcA,eAAOX,IAAIY,OAAX;AACD;AAxDM;AAZI,GADjB,EAwEGhE,KAxEH,CAwES,UAxET,EAwEqB;AACjBC,SAAK,cADY;AAEjBgE,WAAO;AACL,kBAAY;AACV9D,0BAAkB,CAAC,OAAD,EAAU,eAAV,EAA2B,UAACC,KAAD,EAAQU,aAAR,EAA0B;AACrE,cAAIoD,cAAcpD,cAAcqD,cAAd,EAAlB;AACA,iBAAO/D,MAAMI,GAAN,CAAU0D,cAAc,4BAAxB,EAAsDzD,IAAtD,CACL,oBAAY;AACV,mBAAOC,SAASC,IAAhB;AACD,WAHI,CAAP;AAKD,SAPiB,CADR;AASVvB,oBAAY,gBATF;AAUVwB,sBAAc;AAVJ;AADP;AAFU,GAxErB,EAyFGZ,KAzFH,CAyFS,gBAzFT,EAyF2B;AACvBC,SAAK,2BADkB;AAEvBgE,WAAO;AACL,kBAAY;AACV9D,0BAAkB,CAAC,OAAD,EAAU,eAAV,EAA2B,UAACC,KAAD,EAAQU,aAAR,EAA0B;AACrE,cAAIoD,cAAcpD,cAAcqD,cAAd,EAAlB;AACA,iBAAO/D,MAAMI,GAAN,CAAU0D,cAAc,4BAAxB,EAAsDzD,IAAtD,CACL,oBAAY;AACV,mBAAOC,SAASC,IAAhB;AACD,WAHI,CAAP;AAKD,SAPiB,CADR;AASVvB,oBAAY,gBATF;AAUVwB,sBAAc;AAVJ;AADP;AAFgB,GAzF3B;;AA2GAf,gBAAcuE,YAAd,CAA2BC,IAA3B,CAAgC,iBAAhC;;AAEA;AACA3E,kCAAgC4E,OAAhC,CAAwC,MAAxC;AACA5E,kCAAgC4E,OAAhC,CAAwC,UAAxC;AACA7E,qBAAmB8E,SAAnB,CAA6B,yBAA7B,EAAwD;AACtDC,iBAAa;AADyC,GAAxD,EAGGC,gBAHH,CAGoB,CAAC,IAAD,CAHpB,EAIGC,6BAJH,CAIiC,CAAC,IAAD,EAAM,IAAN,EAAW,IAAX,EAAgB,IAAhB,EAAqB,IAArB,EAA0B,IAA1B,EAA+B,IAA/B,EAAoC,OAApC,EAA4C,OAA5C,CAJjC,EAIuF;AACnF,aAAS,IAD0E;AAEnF,aAAS;AAF0E,GAJvF,EAQGC,0BARH,GASGC,wBATH,CAS4B,oBAT5B,EASkD,QATlD;;AAWA;AACA;AACAhF,qBAAmBiF,aAAnB,CAAiC,SAAjC,EAA4C;AAC1C,UAAM,QADoC;AAE1C,WAAO,QAFmC;AAG1C,WAAO,QAHmC;AAI1C,WAAO,QAJmC;AAK1C,WAAO,QALmC;AAM1C,WAAO,QANmC;AAO1C,WAAO,QAPmC;AAQ1C,WAAO,QARmC;AAS1C,WAAO,QATmC;AAU1C,WAAO,QAVmC;AAW1C,YAAQ,QAXkC;AAY1C,YAAQ,QAZkC;AAa1C,YAAQ,QAbkC;AAc1C,YAAQ,QAdkC;AAe1C,4BAAwB,OAfkB,EAeN;AACA;AACpC,0BAAsB,CAAC,IAAD,EAAO,KAAP,EAAc;AAClC,SADoB,EACb,KADa,EACN,MADM,CAjBoB;AAmB1C,2BAAuBC,SAnBmB,CAmBN;AAnBM,GAA5C;;AAsBAlF,qBAAmBiF,aAAnB,CAAiC,QAAjC,EAA2C;AACzC,UAAM,QADmC;AAEzC,WAAO,QAFkC;AAGzC,WAAO,QAHkC;AAIzC,WAAO,QAJkC;AAKzC,WAAO,QALkC;AAMzC,WAAO,QANkC;AAOzC,WAAO,QAPkC;AAQzC,WAAO,QARkC;AASzC,WAAO,QATkC;AAUzC,WAAO,QAVkC;AAWzC,YAAQ,QAXiC;AAYzC,YAAQ,QAZiC;AAazC,YAAQ,QAbiC;AAczC,YAAQ,QAdiC;AAezC,4BAAwB,OAfiB;AAgBzC,0BAAsB,CAAC,IAAD,EAAO,KAAP,EACpB,KADoB,EACb,KADa,EACN,MADM,CAhBmB;AAkBzC,2BAAuBC;AAlBkB,GAA3C;;AAqBAlF,qBAAmBqD,KAAnB,CAAyB,SAAzB,EACG8B,cADH,CACkB,SADlB,EAEGC,aAFH,CAEiB,QAFjB,EAE4B;AACxB,eAAW;AADa,GAF5B,EAKGC,WALH,CAKe,KALf,EAKsB;AAClB,eAAW;AADO,GALtB;;AASA,MAAIC,WAAWtF,mBAAmBuF,aAAnB,CAAiC,MAAjC,EAAyC;AACtD,YAAQ;AAD8C,GAAzC,CAAf;AAGAvF,qBAAmBiF,aAAnB,CAAiC,OAAjC,EAA0CK,QAA1C;;AAEAtF,qBAAmBqD,KAAnB,CAAyB,OAAzB,EACG8B,cADH,CACkB,OADlB,EAC2B;AACvB,eAAW;AADY,GAD3B,EAIGC,aAJH,CAIiB,SAJjB;;AAMApF,qBAAmBwF,eAAnB,CAAmC,SAAnC;AACAxF,qBAAmByF,kBAAnB;;AAEA;AACA;AACA,mBAAOC,YAAP,CAAoB,IAApB,EAA0B;AACxBC,cAAU;AACRC,eAAU,mBADF;AAERC,eAAU,eAFF;AAGRC,eAAU,kBAHF;AAIRC,gBAAW,qBAJH;AAKRC,gBAAW,cALH;AAMRC,gBAAW;AANH;AADc,GAA1B;AAUD,CAhOK,CApDM,CAAhB;kBAsRe7G,S","file":"main.js","sourcesContent":["'use strict';\n\nimport $ from 'jquery';\nimport AchievementService from '../services/achievementService';\nimport angular from 'angular';\nimport angularDragula from 'angular-dragula';\nimport angularFileUpload from 'ng-file-upload';\nimport angularHighcharts from 'highcharts-ng';\nimport angularMaterial from 'angular-material';\nimport angularMoment from 'angular-moment';\nimport angularOnload from 'ng-onload';\nimport angularSanitize from 'angular-sanitize';\nimport angularToArrayFilter from 'lib/angular-toArrayFilter/toArrayFilter';\nimport angularTranslate from 'angular-translate';\nimport angularTranslateLoaderPartial from 'angular-translate-loader-partial';\nimport angularUIRouter from 'angular-ui-router';\nimport angularUIScrollpoint from 'angular-ui-scrollpoint';\nimport angularWebSocket from 'angular-websocket';\nimport AnimationComponentModule from '../components/animation/animationComponentModule';\nimport AnnotationService from '../services/annotationService';\nimport AudioOscillatorComponentModule from '../components/audioOscillator/audioOscillatorComponentModule';\nimport ConceptMapComponentModule from '../components/conceptMap/conceptMapComponentModule';\nimport ConfigService from '../services/configService';\nimport CRaterService from '../services/cRaterService';\nimport Components from '../directives/components';\nimport DiscussionComponentModule from '../components/discussion/discussionComponentModule';\nimport DrawComponentModule from '../components/draw/drawComponentModule';\nimport EmbeddedComponentModule from '../components/embedded/embeddedComponentModule';\nimport Filters from '../filters/filters';\nimport Highcharts from '../lib/highcharts@4.2.1';\nimport draggablePoints from '../lib/draggable-points/draggable-points';\nimport GraphComponentModule from '../components/graph/graphComponentModule';\nimport HTMLComponentModule from '../components/html/htmlComponentModule';\nimport HttpInterceptor from '../services/httpInterceptor';\nimport LabelComponentModule from '../components/label/labelComponentModule';\nimport MatchComponentModule from '../components/match/matchComponentModule';\nimport MultipleChoiceComponentModule from '../components/multipleChoice/multipleChoiceComponentModule';\nimport NavigationController from './navigation/navigationController';\nimport NodeController from './node/nodeController';\nimport NodeService from '../services/nodeService';\nimport NotebookService from '../services/notebookService';\nimport NotificationService from '../services/notificationService';\nimport OpenResponseComponentModule from '../components/openResponse/openResponseComponentModule';\nimport OutsideURLComponentModule from '../components/outsideURL/outsideURLComponentModule';\nimport ProjectService from '../services/projectService';\nimport SessionService from '../services/sessionService';\nimport StudentAsset from './studentAsset/studentAsset';\nimport StudentAssetService from '../services/studentAssetService';\nimport StudentDataService from '../services/studentDataService';\nimport StudentStatusService from '../services/studentStatusService';\nimport StudentWebSocketService from '../services/studentWebSocketService';\nimport TableComponentModule from '../components/table/tableComponentModule';\nimport UtilService from '../services/utilService';\nimport VLEController from './vleController';\nimport VLEProjectService from './vleProjectService';\nimport ocLazyLoad from 'oclazyload';\nimport moment from 'moment';\nimport angularSummernote from 'lib/angular-summernote/dist/angular-summernote.min';\n\nlet vleModule = angular.module('vle', [\n angularDragula(angular),\n 'angularMoment',\n 'angular-toArrayFilter',\n 'animationComponentModule',\n 'audioOscillatorComponentModule',\n 'components',\n 'conceptMapComponentModule',\n 'discussionComponentModule',\n 'drawComponentModule',\n 'embeddedComponentModule',\n 'filters',\n 'graphComponentModule',\n 'highcharts-ng',\n 'htmlComponentModule',\n 'labelComponentModule',\n 'matchComponentModule',\n 'multipleChoiceComponentModule',\n 'ngAria',\n 'ngFileUpload',\n 'ngMaterial',\n 'ngOnload',\n 'ngSanitize',\n 'ngWebSocket',\n 'oc.lazyLoad',\n 'openResponseComponentModule',\n 'outsideURLComponentModule',\n 'pascalprecht.translate',\n 'studentAsset',\n 'summernote',\n 'tableComponentModule',\n 'ui.router',\n 'ui.scrollpoint'])\n .service(AchievementService.name, AchievementService)\n .service(AnnotationService.name, AnnotationService)\n .service(ConfigService.name, ConfigService)\n .service(CRaterService.name, CRaterService)\n .service(HttpInterceptor.name, HttpInterceptor)\n .service(NodeService.name, NodeService)\n .service(NotebookService.name, NotebookService)\n .service(NotificationService.name, NotificationService)\n .service(ProjectService.name, VLEProjectService)\n .service(SessionService.name, SessionService)\n .service(StudentAssetService.name, StudentAssetService)\n .service(StudentDataService.name, StudentDataService)\n .service(StudentStatusService.name, StudentStatusService)\n .service(StudentWebSocketService.name, StudentWebSocketService)\n .service(UtilService.name, UtilService)\n .controller(NavigationController.name, NavigationController)\n .controller(NodeController.name, NodeController)\n .controller(VLEController.name, VLEController)\n .filter(Filters.name, Filters)\n .config([\n '$urlRouterProvider',\n '$stateProvider',\n '$translateProvider',\n '$translatePartialLoaderProvider',\n '$controllerProvider',\n '$mdThemingProvider',\n '$httpProvider',\n '$provide',\n ($urlRouterProvider,\n $stateProvider,\n $translateProvider,\n $translatePartialLoaderProvider,\n $controllerProvider,\n $mdThemingProvider,\n $httpProvider,\n $provide) => {\n $urlRouterProvider.otherwise('/vle/');\n\n angular.module('vle').$controllerProvider = $controllerProvider;\n\n $stateProvider\n .state('root', {\n url: '',\n abstract: true,\n templateProvider: ['$http', 'ProjectService', ($http, ProjectService) => {\n let themePath = ProjectService.getThemePath();\n return $http.get(themePath + '/vle.html').then(\n response => {\n return response.data;\n });\n }],\n controller: 'VLEController',\n controllerAs: 'vleController',\n resolve: {\n config: (ConfigService) => {\n let configURL = window.configURL;\n return ConfigService.retrieveConfig(configURL);\n },\n project: (ProjectService, config) => {\n return ProjectService.retrieveProject();\n },\n studentData: (StudentDataService, config, project) => {\n return StudentDataService.retrieveStudentData();\n },\n notebook: (NotebookService, ConfigService, StudentAssetService, studentData, config, project) => {\n return StudentAssetService.retrieveAssets().then((studentAssets) => {\n return NotebookService.retrieveNotebookItems(ConfigService.getWorkgroupId()).then((notebook) => {\n return notebook;\n });\n });\n },\n achievements: (AchievementService, studentData, config, project) => {\n return AchievementService.retrieveAchievements();\n },\n notifications: (NotificationService, studentData, config, project) => {\n return NotificationService.retrieveNotifications();\n },\n runStatus: (StudentDataService, config) => {\n return StudentDataService.retrieveRunStatus();\n },\n sessionTimers: (SessionService, config, project, studentData) => {\n return SessionService.initializeSession();\n },\n webSocket: (StudentWebSocketService, config, project) => {\n return StudentWebSocketService.initialize();\n },\n language: ($translate, ConfigService, config) => {\n let locale = ConfigService.getLocale(); // defaults to \"en\"\n $translate.use(locale);\n },\n theme: (ProjectService, config, project, $ocLazyLoad, $q) => {\n let theme = ProjectService.getThemePath() + '/theme.js';\n let def = $q.defer();\n\n System.import(theme).then(m => {\n let themeModule = m.default;\n if (!m.default.name) {\n let key = Object.keys(m.default);\n themeModule = m.default[key[0]];\n }\n\n $ocLazyLoad.load(themeModule).then(() => {\n def.resolve();\n }, err => {\n throw err;\n });\n });\n\n return def.promise;\n }\n }\n })\n .state('root.vle', {\n url: '/vle/:nodeId',\n views: {\n 'nodeView': {\n templateProvider: ['$http', 'ConfigService', ($http, ConfigService) => {\n let wiseBaseURL = ConfigService.getWISEBaseURL();\n return $http.get(wiseBaseURL + '/wise5/vle/node/index.html').then(\n response => {\n return response.data;\n }\n );\n }],\n controller: 'NodeController',\n controllerAs: 'nodeController'\n }\n }\n })\n .state('root.component', {\n url: '/vle/:nodeId/:componentId',\n views: {\n 'nodeView': {\n templateProvider: ['$http', 'ConfigService', ($http, ConfigService) => {\n let wiseBaseURL = ConfigService.getWISEBaseURL();\n return $http.get(wiseBaseURL + '/wise5/vle/node/index.html').then(\n response => {\n return response.data;\n }\n );\n }],\n controller: 'NodeController',\n controllerAs: 'nodeController'\n }\n }\n });\n\n $httpProvider.interceptors.push('HttpInterceptor');\n\n // Set up Translations\n $translatePartialLoaderProvider.addPart('i18n');\n $translatePartialLoaderProvider.addPart('vle/i18n');\n $translateProvider.useLoader('$translatePartialLoader', {\n urlTemplate: 'wise5/{part}/i18n_{lang}.json'\n })\n .fallbackLanguage(['en'])\n .registerAvailableLanguageKeys(['el','en','es','ja','ko','pt','tr','zh_CN','zh_TW'], {\n 'en_US': 'en',\n 'en_UK': 'en'\n })\n .determinePreferredLanguage()\n .useSanitizeValueStrategy('sanitizeParameters', 'escape');\n\n // ngMaterial default theme configuration\n // TODO: make dynamic and support alternate themes; allow projects to specify theme parameters and settings\n $mdThemingProvider.definePalette('primary', {\n '50': 'e1f0f4',\n '100': 'b8dbe4',\n '200': '8ec6d4',\n '300': '5faec2',\n '400': '3d9db5',\n '500': '1c8ca8',\n '600': '197f98',\n '700': '167188',\n '800': '136377',\n '900': '0e4957',\n 'A100': 'abf3ff',\n 'A200': '66e2ff',\n 'A400': '17bee5',\n 'A700': '00A1C6',\n 'contrastDefaultColor': 'light', // whether, by default, text (contrast)\n // on this palette should be dark or light\n 'contrastDarkColors': ['50', '100', //hues which contrast should be 'dark' by default\n '200', '300', 'A100'],\n 'contrastLightColors': undefined // could also specify this if default was 'dark'\n });\n\n $mdThemingProvider.definePalette('accent', {\n '50': 'fde9e6',\n '100': 'fbcbc4',\n '200': 'f8aca1',\n '300': 'f4897b',\n '400': 'f2705f',\n '500': 'f05843',\n '600': 'da503c',\n '700': 'c34736',\n '800': 'aa3e2f',\n '900': '7d2e23',\n 'A100': 'ff897d',\n 'A200': 'ff7061',\n 'A400': 'ff3829',\n 'A700': 'cc1705',\n 'contrastDefaultColor': 'light',\n 'contrastDarkColors': ['50', '100',\n '200', '300', 'A100'],\n 'contrastLightColors': undefined\n });\n\n $mdThemingProvider.theme('default')\n .primaryPalette('primary')\n .accentPalette('accent', {\n 'default': '500'\n })\n .warnPalette('red', {\n 'default': '800'\n });\n\n let lightMap = $mdThemingProvider.extendPalette('grey', {\n 'A100': 'ffffff'\n });\n $mdThemingProvider.definePalette('light', lightMap);\n\n $mdThemingProvider.theme('light')\n .primaryPalette('light', {\n 'default': 'A100'\n })\n .accentPalette('primary');\n\n $mdThemingProvider.setDefaultTheme('default');\n $mdThemingProvider.enableBrowserColor();\n\n // moment.js default overrides\n // TODO: add i18n support\n moment.updateLocale('en', {\n calendar: {\n lastDay : '[Yesterday at] LT',\n sameDay : '[Today at] LT',\n nextDay : '[Tomorrow at] LT',\n lastWeek : '[last] dddd [at] LT',\n nextWeek : 'dddd [at] LT',\n sameElse : 'll'\n }\n });\n }\n ]);\nexport default vleModule;\n"]} \ No newline at end of file +{"version":3,"sources":["main.es6"],"names":["vleModule","module","service","name","controller","filter","config","$urlRouterProvider","$stateProvider","$translateProvider","$translatePartialLoaderProvider","$controllerProvider","$mdThemingProvider","$httpProvider","$provide","otherwise","state","url","abstract","templateProvider","$http","ProjectService","themePath","getThemePath","get","then","response","data","controllerAs","resolve","ConfigService","configURL","window","retrieveConfig","project","retrieveProject","studentData","StudentDataService","retrieveStudentData","notebook","NotebookService","StudentAssetService","retrieveAssets","studentAssets","retrieveNotebookItems","getWorkgroupId","achievements","AchievementService","retrieveAchievements","notifications","NotificationService","retrieveNotifications","runStatus","retrieveRunStatus","sessionTimers","SessionService","initializeSession","webSocket","StudentWebSocketService","initialize","language","$translate","locale","getLocale","use","theme","$ocLazyLoad","$q","def","defer","System","import","themeModule","m","default","key","Object","keys","load","err","promise","views","wiseBaseURL","getWISEBaseURL","interceptors","push","addPart","useLoader","urlTemplate","fallbackLanguage","registerAvailableLanguageKeys","determinePreferredLanguage","useSanitizeValueStrategy","definePalette","undefined","primaryPalette","accentPalette","warnPalette","lightMap","extendPalette","setDefaultTheme","enableBrowserColor","updateLocale","calendar","lastDay","sameDay","nextDay","lastWeek","nextWeek","sameElse"],"mappings":"AAAA;;;;;;AAEA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;;;AAEA,IAAIA,YAAY,kBAAQC,MAAR,CAAe,KAAf,EAAsB,CAClC,gDADkC,EAElC,eAFkC,EAGlC,uBAHkC,EAIlC,0BAJkC,EAKlC,gCALkC,EAMlC,YANkC,EAOlC,2BAPkC,EAQlC,2BARkC,EASlC,qBATkC,EAUlC,yBAVkC,EAWlC,SAXkC,EAYlC,sBAZkC,EAalC,eAbkC,EAclC,qBAdkC,EAelC,sBAfkC,EAgBlC,sBAhBkC,EAiBlC,+BAjBkC,EAkBlC,QAlBkC,EAmBlC,cAnBkC,EAoBlC,YApBkC,EAqBlC,UArBkC,EAsBlC,YAtBkC,EAuBlC,aAvBkC,EAwBlC,aAxBkC,EAyBlC,6BAzBkC,EA0BlC,2BA1BkC,EA2BlC,wBA3BkC,EA4BlC,cA5BkC,EA6BlC,YA7BkC,EA8BlC,sBA9BkC,EA+BlC,WA/BkC,EAgClC,gBAhCkC,CAAtB,EAiCbC,OAjCa,CAiCL,6BAAmBC,IAjCd,gCAkCbD,OAlCa,CAkCL,4BAAkBC,IAlCb,+BAmCbD,OAnCa,CAmCL,wBAAcC,IAnCT,2BAoCbD,OApCa,CAoCL,2BAAiBC,IApCZ,8BAqCbD,OArCa,CAqCL,wBAAcC,IArCT,2BAsCbD,OAtCa,CAsCL,0BAAgBC,IAtCX,6BAuCbD,OAvCa,CAuCL,sBAAYC,IAvCP,yBAwCbD,OAxCa,CAwCL,0BAAgBC,IAxCX,6BAyCbD,OAzCa,CAyCL,8BAAoBC,IAzCf,iCA0CbD,OA1Ca,CA0CL,0BAAgBC,IA1CX,6BA2CbD,OA3Ca,CA2CL,yBAAeC,IA3CV,+BA4CbD,OA5Ca,CA4CL,yBAAeC,IA5CV,4BA6CbD,OA7Ca,CA6CL,8BAAoBC,IA7Cf,iCA8CbD,OA9Ca,CA8CL,6BAAmBC,IA9Cd,gCA+CbD,OA/Ca,CA+CL,+BAAqBC,IA/ChB,kCAgDbD,OAhDa,CAgDL,kCAAwBC,IAhDnB,qCAiDbD,OAjDa,CAiDL,sBAAYC,IAjDP,yBAkDbC,UAlDa,CAkDF,+BAAqBD,IAlDnB,kCAmDbC,UAnDa,CAmDF,yBAAeD,IAnDb,4BAoDbC,UApDa,CAoDF,wBAAcD,IApDZ,2BAqDbE,MArDa,CAqDN,kBAAQF,IArDF,qBAsDbG,MAtDa,CAsDN,CACJ,oBADI,EAEJ,gBAFI,EAGJ,oBAHI,EAIJ,iCAJI,EAKJ,qBALI,EAMJ,oBANI,EAOJ,eAPI,EAQJ,UARI,EASJ,UAACC,kBAAD,EACAC,cADA,EAEAC,kBAFA,EAGAC,+BAHA,EAIAC,mBAJA,EAKAC,kBALA,EAMAC,aANA,EAOAC,QAPA,EAOa;AACbP,qBAAmBQ,SAAnB,CAA6B,OAA7B;;AAEA,oBAAQd,MAAR,CAAe,KAAf,EAAsBU,mBAAtB,GAA4CA,mBAA5C;;AAEAH,iBACGQ,KADH,CACS,MADT,EACiB;AACbC,SAAK,EADQ;AAEbC,cAAU,IAFG;AAGbC,sBAAkB,CAAC,OAAD,EAAU,gBAAV,EAA4B,UAACC,KAAD,EAAQC,cAAR,EAA2B;AACvE,UAAIC,YAAYD,eAAeE,YAAf,EAAhB;AACA,aAAOH,MAAMI,GAAN,CAAUF,YAAY,WAAtB,EAAmCG,IAAnC,CACL,oBAAY;AACV,eAAOC,SAASC,IAAhB;AACD,OAHI,CAAP;AAID,KANiB,CAHL;AAUbvB,gBAAY,eAVC;AAWbwB,kBAAc,eAXD;AAYbC,aAAS;AACPvB,cAAQ,gBAACwB,aAAD,EAAmB;AACzB,YAAIC,YAAYC,OAAOD,SAAvB;AACA,eAAOD,cAAcG,cAAd,CAA6BF,SAA7B,CAAP;AACD,OAJM;AAKPG,eAAS,iBAACb,cAAD,EAAiBf,MAAjB,EAA4B;AACnC,eAAOe,eAAec,eAAf,EAAP;AACD,OAPM;AAQPC,mBAAa,qBAACC,kBAAD,EAAqB/B,MAArB,EAA6B4B,OAA7B,EAAyC;AACpD,eAAOG,mBAAmBC,mBAAnB,EAAP;AACD,OAVM;AAWPC,gBAAU,kBAACC,eAAD,EAAkBV,aAAlB,EAAiCW,mBAAjC,EAAsDL,WAAtD,EAAmE9B,MAAnE,EAA2E4B,OAA3E,EAAuF;AAC/F,eAAOO,oBAAoBC,cAApB,GAAqCjB,IAArC,CAA0C,UAACkB,aAAD,EAAmB;AAClE,iBAAOH,gBAAgBI,qBAAhB,CAAsCd,cAAce,cAAd,EAAtC,EAAsEpB,IAAtE,CAA2E,UAACc,QAAD,EAAc;AAC9F,mBAAOA,QAAP;AACD,WAFM,CAAP;AAGD,SAJM,CAAP;AAKD,OAjBM;AAkBPO,oBAAc,sBAACC,kBAAD,EAAqBX,WAArB,EAAkC9B,MAAlC,EAA0C4B,OAA1C,EAAsD;AAClE,eAAOa,mBAAmBC,oBAAnB,EAAP;AACD,OApBM;AAqBPC,qBAAe,uBAACC,mBAAD,EAAsBd,WAAtB,EAAmC9B,MAAnC,EAA2C4B,OAA3C,EAAuD;AACpE,eAAOgB,oBAAoBC,qBAApB,EAAP;AACD,OAvBM;AAwBPC,iBAAW,mBAACf,kBAAD,EAAqB/B,MAArB,EAAgC;AACzC,eAAO+B,mBAAmBgB,iBAAnB,EAAP;AACD,OA1BM;AA2BPC,qBAAe,uBAACC,cAAD,EAAiBjD,MAAjB,EAAyB4B,OAAzB,EAAkCE,WAAlC,EAAkD;AAC/D,eAAOmB,eAAeC,iBAAf,EAAP;AACD,OA7BM;AA8BPC,iBAAW,mBAACC,uBAAD,EAA0BpD,MAA1B,EAAkC4B,OAAlC,EAA8C;AACvD,eAAOwB,wBAAwBC,UAAxB,EAAP;AACD,OAhCM;AAiCPC,gBAAU,kBAACC,UAAD,EAAa/B,aAAb,EAA4BxB,MAA5B,EAAuC;AAC/C,YAAIwD,SAAShC,cAAciC,SAAd,EAAb,CAD+C,CACN;AACzCF,mBAAWG,GAAX,CAAeF,MAAf;AACD,OApCM;AAqCPG,aAAO,eAAC5C,cAAD,EAAiBf,MAAjB,EAAyB4B,OAAzB,EAAkCgC,WAAlC,EAA+CC,EAA/C,EAAsD;AAC3D,YAAIF,QAAQ5C,eAAeE,YAAf,KAAgC,WAA5C;AACA,YAAI6C,MAAMD,GAAGE,KAAH,EAAV;;AAEAC,eAAOC,MAAP,CAAcN,KAAd,EAAqBxC,IAArB,CAA0B,aAAK;AAC7B,cAAI+C,cAAcC,EAAEC,OAApB;AACA,cAAI,CAACD,EAAEC,OAAF,CAAUvE,IAAf,EAAqB;AACnB,gBAAIwE,MAAMC,OAAOC,IAAP,CAAYJ,EAAEC,OAAd,CAAV;AACAF,0BAAcC,EAAEC,OAAF,CAAUC,IAAI,CAAJ,CAAV,CAAd;AACD;;AAEDT,sBAAYY,IAAZ,CAAiBN,WAAjB,EAA8B/C,IAA9B,CAAmC,YAAM;AACvC2C,gBAAIvC,OAAJ;AACD,WAFD,EAEG,eAAO;AACR,kBAAMkD,GAAN;AACD,WAJD;AAKD,SAZD;;AAcA,eAAOX,IAAIY,OAAX;AACD;AAxDM;AAZI,GADjB,EAwEGhE,KAxEH,CAwES,UAxET,EAwEqB;AACjBC,SAAK,cADY;AAEjBgE,WAAO;AACL,kBAAY;AACV9D,0BAAkB,CAAC,OAAD,EAAU,eAAV,EAA2B,UAACC,KAAD,EAAQU,aAAR,EAA0B;AACrE,cAAIoD,cAAcpD,cAAcqD,cAAd,EAAlB;AACA,iBAAO/D,MAAMI,GAAN,CAAU0D,cAAc,4BAAxB,EAAsDzD,IAAtD,CACL,oBAAY;AACV,mBAAOC,SAASC,IAAhB;AACD,WAHI,CAAP;AAKD,SAPiB,CADR;AASVvB,oBAAY,gBATF;AAUVwB,sBAAc;AAVJ;AADP;AAFU,GAxErB,EAyFGZ,KAzFH,CAyFS,gBAzFT,EAyF2B;AACvBC,SAAK,2BADkB;AAEvBgE,WAAO;AACL,kBAAY;AACV9D,0BAAkB,CAAC,OAAD,EAAU,eAAV,EAA2B,UAACC,KAAD,EAAQU,aAAR,EAA0B;AACrE,cAAIoD,cAAcpD,cAAcqD,cAAd,EAAlB;AACA,iBAAO/D,MAAMI,GAAN,CAAU0D,cAAc,4BAAxB,EAAsDzD,IAAtD,CACL,oBAAY;AACV,mBAAOC,SAASC,IAAhB;AACD,WAHI,CAAP;AAKD,SAPiB,CADR;AASVvB,oBAAY,gBATF;AAUVwB,sBAAc;AAVJ;AADP;AAFgB,GAzF3B;;AA2GAf,gBAAcuE,YAAd,CAA2BC,IAA3B,CAAgC,iBAAhC;;AAEA;AACA3E,kCAAgC4E,OAAhC,CAAwC,MAAxC;AACA5E,kCAAgC4E,OAAhC,CAAwC,UAAxC;AACA7E,qBAAmB8E,SAAnB,CAA6B,yBAA7B,EAAwD;AACtDC,iBAAa;AADyC,GAAxD,EAGGC,gBAHH,CAGoB,CAAC,IAAD,CAHpB,EAIGC,6BAJH,CAIiC,CAAC,IAAD,EAAM,IAAN,EAAW,IAAX,EAAgB,IAAhB,EAAqB,IAArB,EAA0B,IAA1B,EAA+B,IAA/B,EAAoC,OAApC,EAA4C,OAA5C,CAJjC,EAIuF;AACnF,aAAS,IAD0E;AAEnF,aAAS;AAF0E,GAJvF,EAQGC,0BARH,GASGC,wBATH,CAS4B,oBAT5B,EASkD,QATlD;;AAWA;AACA;AACAhF,qBAAmBiF,aAAnB,CAAiC,SAAjC,EAA4C;AAC1C,UAAM,QADoC;AAE1C,WAAO,QAFmC;AAG1C,WAAO,QAHmC;AAI1C,WAAO,QAJmC;AAK1C,WAAO,QALmC;AAM1C,WAAO,QANmC;AAO1C,WAAO,QAPmC;AAQ1C,WAAO,QARmC;AAS1C,WAAO,QATmC;AAU1C,WAAO,QAVmC;AAW1C,YAAQ,QAXkC;AAY1C,YAAQ,QAZkC;AAa1C,YAAQ,QAbkC;AAc1C,YAAQ,QAdkC;AAe1C,4BAAwB,OAfkB,EAeN;AACA;AACpC,0BAAsB,CAAC,IAAD,EAAO,KAAP,EAAc;AAClC,SADoB,EACb,KADa,EACN,MADM,CAjBoB;AAmB1C,2BAAuBC,SAnBmB,CAmBN;AAnBM,GAA5C;;AAsBAlF,qBAAmBiF,aAAnB,CAAiC,QAAjC,EAA2C;AACzC,UAAM,QADmC;AAEzC,WAAO,QAFkC;AAGzC,WAAO,QAHkC;AAIzC,WAAO,QAJkC;AAKzC,WAAO,QALkC;AAMzC,WAAO,QANkC;AAOzC,WAAO,QAPkC;AAQzC,WAAO,QARkC;AASzC,WAAO,QATkC;AAUzC,WAAO,QAVkC;AAWzC,YAAQ,QAXiC;AAYzC,YAAQ,QAZiC;AAazC,YAAQ,QAbiC;AAczC,YAAQ,QAdiC;AAezC,4BAAwB,OAfiB;AAgBzC,0BAAsB,CAAC,IAAD,EAAO,KAAP,EACpB,KADoB,EACb,KADa,EACN,MADM,CAhBmB;AAkBzC,2BAAuBC;AAlBkB,GAA3C;;AAqBAlF,qBAAmBqD,KAAnB,CAAyB,SAAzB,EACG8B,cADH,CACkB,SADlB,EAEGC,aAFH,CAEiB,QAFjB,EAE4B;AACxB,eAAW;AADa,GAF5B,EAKGC,WALH,CAKe,KALf,EAKsB;AAClB,eAAW;AADO,GALtB;;AASA,MAAIC,WAAWtF,mBAAmBuF,aAAnB,CAAiC,MAAjC,EAAyC;AACtD,YAAQ;AAD8C,GAAzC,CAAf;AAGAvF,qBAAmBiF,aAAnB,CAAiC,OAAjC,EAA0CK,QAA1C;;AAEAtF,qBAAmBqD,KAAnB,CAAyB,OAAzB,EACG8B,cADH,CACkB,OADlB,EAC2B;AACvB,eAAW;AADY,GAD3B,EAIGC,aAJH,CAIiB,SAJjB;;AAMApF,qBAAmBwF,eAAnB,CAAmC,SAAnC;AACAxF,qBAAmByF,kBAAnB;;AAEA;AACA;AACA,mBAAOC,YAAP,CAAoB,IAApB,EAA0B;AACxBC,cAAU;AACRC,eAAU,mBADF;AAERC,eAAU,eAFF;AAGRC,eAAU,kBAHF;AAIRC,gBAAW,qBAJH;AAKRC,gBAAW,cALH;AAMRC,gBAAW;AANH;AADc,GAA1B;AAUD,CAhOK,CAtDM,CAAhB;kBAwRe7G,S","file":"main.js","sourcesContent":["'use strict';\n\nimport $ from 'jquery';\nimport AchievementService from '../services/achievementService';\nimport angular from 'angular';\nimport angularDragula from 'angular-dragula';\nimport angularFileUpload from 'ng-file-upload';\nimport angularHighcharts from 'highcharts-ng';\nimport angularMaterial from 'angular-material';\nimport angularMoment from 'angular-moment';\nimport angularOnload from 'ng-onload';\nimport angularSanitize from 'angular-sanitize';\nimport angularToArrayFilter from 'lib/angular-toArrayFilter/toArrayFilter';\nimport angularTranslate from 'angular-translate';\nimport angularTranslateLoaderPartial from 'angular-translate-loader-partial';\nimport angularUIRouter from 'angular-ui-router';\nimport angularUIScrollpoint from 'angular-ui-scrollpoint';\nimport angularWebSocket from 'angular-websocket';\nimport AnimationComponentModule from '../components/animation/animationComponentModule';\nimport AnnotationService from '../services/annotationService';\nimport AudioOscillatorComponentModule from '../components/audioOscillator/audioOscillatorComponentModule';\nimport ConceptMapComponentModule from '../components/conceptMap/conceptMapComponentModule';\nimport ConfigService from '../services/configService';\nimport CRaterService from '../services/cRaterService';\nimport Components from '../directives/components';\nimport ComponentService from '../components/componentService';\nimport DiscussionComponentModule from '../components/discussion/discussionComponentModule';\nimport DrawComponentModule from '../components/draw/drawComponentModule';\nimport EmbeddedComponentModule from '../components/embedded/embeddedComponentModule';\nimport Filters from '../filters/filters';\nimport Highcharts from '../lib/highcharts@4.2.1';\nimport draggablePoints from '../lib/draggable-points/draggable-points';\nimport GraphComponentModule from '../components/graph/graphComponentModule';\nimport HTMLComponentModule from '../components/html/htmlComponentModule';\nimport HttpInterceptor from '../services/httpInterceptor';\nimport LabelComponentModule from '../components/label/labelComponentModule';\nimport MatchComponentModule from '../components/match/matchComponentModule';\nimport MultipleChoiceComponentModule from '../components/multipleChoice/multipleChoiceComponentModule';\nimport NavigationController from './navigation/navigationController';\nimport NodeController from './node/nodeController';\nimport NodeService from '../services/nodeService';\nimport NotebookService from '../services/notebookService';\nimport NotificationService from '../services/notificationService';\nimport OpenResponseComponentModule from '../components/openResponse/openResponseComponentModule';\nimport OutsideURLComponentModule from '../components/outsideURL/outsideURLComponentModule';\nimport PlanningService from '../services/planningService';\nimport ProjectService from '../services/projectService';\nimport SessionService from '../services/sessionService';\nimport StudentAsset from './studentAsset/studentAsset';\nimport StudentAssetService from '../services/studentAssetService';\nimport StudentDataService from '../services/studentDataService';\nimport StudentStatusService from '../services/studentStatusService';\nimport StudentWebSocketService from '../services/studentWebSocketService';\nimport TableComponentModule from '../components/table/tableComponentModule';\nimport UtilService from '../services/utilService';\nimport VLEController from './vleController';\nimport VLEProjectService from './vleProjectService';\nimport ocLazyLoad from 'oclazyload';\nimport moment from 'moment';\nimport angularSummernote from 'lib/angular-summernote/dist/angular-summernote.min';\n\nlet vleModule = angular.module('vle', [\n angularDragula(angular),\n 'angularMoment',\n 'angular-toArrayFilter',\n 'animationComponentModule',\n 'audioOscillatorComponentModule',\n 'components',\n 'conceptMapComponentModule',\n 'discussionComponentModule',\n 'drawComponentModule',\n 'embeddedComponentModule',\n 'filters',\n 'graphComponentModule',\n 'highcharts-ng',\n 'htmlComponentModule',\n 'labelComponentModule',\n 'matchComponentModule',\n 'multipleChoiceComponentModule',\n 'ngAria',\n 'ngFileUpload',\n 'ngMaterial',\n 'ngOnload',\n 'ngSanitize',\n 'ngWebSocket',\n 'oc.lazyLoad',\n 'openResponseComponentModule',\n 'outsideURLComponentModule',\n 'pascalprecht.translate',\n 'studentAsset',\n 'summernote',\n 'tableComponentModule',\n 'ui.router',\n 'ui.scrollpoint'])\n .service(AchievementService.name, AchievementService)\n .service(AnnotationService.name, AnnotationService)\n .service(ConfigService.name, ConfigService)\n .service(ComponentService.name, ComponentService)\n .service(CRaterService.name, CRaterService)\n .service(HttpInterceptor.name, HttpInterceptor)\n .service(NodeService.name, NodeService)\n .service(NotebookService.name, NotebookService)\n .service(NotificationService.name, NotificationService)\n .service(PlanningService.name, PlanningService)\n .service(ProjectService.name, VLEProjectService)\n .service(SessionService.name, SessionService)\n .service(StudentAssetService.name, StudentAssetService)\n .service(StudentDataService.name, StudentDataService)\n .service(StudentStatusService.name, StudentStatusService)\n .service(StudentWebSocketService.name, StudentWebSocketService)\n .service(UtilService.name, UtilService)\n .controller(NavigationController.name, NavigationController)\n .controller(NodeController.name, NodeController)\n .controller(VLEController.name, VLEController)\n .filter(Filters.name, Filters)\n .config([\n '$urlRouterProvider',\n '$stateProvider',\n '$translateProvider',\n '$translatePartialLoaderProvider',\n '$controllerProvider',\n '$mdThemingProvider',\n '$httpProvider',\n '$provide',\n ($urlRouterProvider,\n $stateProvider,\n $translateProvider,\n $translatePartialLoaderProvider,\n $controllerProvider,\n $mdThemingProvider,\n $httpProvider,\n $provide) => {\n $urlRouterProvider.otherwise('/vle/');\n\n angular.module('vle').$controllerProvider = $controllerProvider;\n\n $stateProvider\n .state('root', {\n url: '',\n abstract: true,\n templateProvider: ['$http', 'ProjectService', ($http, ProjectService) => {\n let themePath = ProjectService.getThemePath();\n return $http.get(themePath + '/vle.html').then(\n response => {\n return response.data;\n });\n }],\n controller: 'VLEController',\n controllerAs: 'vleController',\n resolve: {\n config: (ConfigService) => {\n let configURL = window.configURL;\n return ConfigService.retrieveConfig(configURL);\n },\n project: (ProjectService, config) => {\n return ProjectService.retrieveProject();\n },\n studentData: (StudentDataService, config, project) => {\n return StudentDataService.retrieveStudentData();\n },\n notebook: (NotebookService, ConfigService, StudentAssetService, studentData, config, project) => {\n return StudentAssetService.retrieveAssets().then((studentAssets) => {\n return NotebookService.retrieveNotebookItems(ConfigService.getWorkgroupId()).then((notebook) => {\n return notebook;\n });\n });\n },\n achievements: (AchievementService, studentData, config, project) => {\n return AchievementService.retrieveAchievements();\n },\n notifications: (NotificationService, studentData, config, project) => {\n return NotificationService.retrieveNotifications();\n },\n runStatus: (StudentDataService, config) => {\n return StudentDataService.retrieveRunStatus();\n },\n sessionTimers: (SessionService, config, project, studentData) => {\n return SessionService.initializeSession();\n },\n webSocket: (StudentWebSocketService, config, project) => {\n return StudentWebSocketService.initialize();\n },\n language: ($translate, ConfigService, config) => {\n let locale = ConfigService.getLocale(); // defaults to \"en\"\n $translate.use(locale);\n },\n theme: (ProjectService, config, project, $ocLazyLoad, $q) => {\n let theme = ProjectService.getThemePath() + '/theme.js';\n let def = $q.defer();\n\n System.import(theme).then(m => {\n let themeModule = m.default;\n if (!m.default.name) {\n let key = Object.keys(m.default);\n themeModule = m.default[key[0]];\n }\n\n $ocLazyLoad.load(themeModule).then(() => {\n def.resolve();\n }, err => {\n throw err;\n });\n });\n\n return def.promise;\n }\n }\n })\n .state('root.vle', {\n url: '/vle/:nodeId',\n views: {\n 'nodeView': {\n templateProvider: ['$http', 'ConfigService', ($http, ConfigService) => {\n let wiseBaseURL = ConfigService.getWISEBaseURL();\n return $http.get(wiseBaseURL + '/wise5/vle/node/index.html').then(\n response => {\n return response.data;\n }\n );\n }],\n controller: 'NodeController',\n controllerAs: 'nodeController'\n }\n }\n })\n .state('root.component', {\n url: '/vle/:nodeId/:componentId',\n views: {\n 'nodeView': {\n templateProvider: ['$http', 'ConfigService', ($http, ConfigService) => {\n let wiseBaseURL = ConfigService.getWISEBaseURL();\n return $http.get(wiseBaseURL + '/wise5/vle/node/index.html').then(\n response => {\n return response.data;\n }\n );\n }],\n controller: 'NodeController',\n controllerAs: 'nodeController'\n }\n }\n });\n\n $httpProvider.interceptors.push('HttpInterceptor');\n\n // Set up Translations\n $translatePartialLoaderProvider.addPart('i18n');\n $translatePartialLoaderProvider.addPart('vle/i18n');\n $translateProvider.useLoader('$translatePartialLoader', {\n urlTemplate: 'wise5/{part}/i18n_{lang}.json'\n })\n .fallbackLanguage(['en'])\n .registerAvailableLanguageKeys(['el','en','es','ja','ko','pt','tr','zh_CN','zh_TW'], {\n 'en_US': 'en',\n 'en_UK': 'en'\n })\n .determinePreferredLanguage()\n .useSanitizeValueStrategy('sanitizeParameters', 'escape');\n\n // ngMaterial default theme configuration\n // TODO: make dynamic and support alternate themes; allow projects to specify theme parameters and settings\n $mdThemingProvider.definePalette('primary', {\n '50': 'e1f0f4',\n '100': 'b8dbe4',\n '200': '8ec6d4',\n '300': '5faec2',\n '400': '3d9db5',\n '500': '1c8ca8',\n '600': '197f98',\n '700': '167188',\n '800': '136377',\n '900': '0e4957',\n 'A100': 'abf3ff',\n 'A200': '66e2ff',\n 'A400': '17bee5',\n 'A700': '00A1C6',\n 'contrastDefaultColor': 'light', // whether, by default, text (contrast)\n // on this palette should be dark or light\n 'contrastDarkColors': ['50', '100', //hues which contrast should be 'dark' by default\n '200', '300', 'A100'],\n 'contrastLightColors': undefined // could also specify this if default was 'dark'\n });\n\n $mdThemingProvider.definePalette('accent', {\n '50': 'fde9e6',\n '100': 'fbcbc4',\n '200': 'f8aca1',\n '300': 'f4897b',\n '400': 'f2705f',\n '500': 'f05843',\n '600': 'da503c',\n '700': 'c34736',\n '800': 'aa3e2f',\n '900': '7d2e23',\n 'A100': 'ff897d',\n 'A200': 'ff7061',\n 'A400': 'ff3829',\n 'A700': 'cc1705',\n 'contrastDefaultColor': 'light',\n 'contrastDarkColors': ['50', '100',\n '200', '300', 'A100'],\n 'contrastLightColors': undefined\n });\n\n $mdThemingProvider.theme('default')\n .primaryPalette('primary')\n .accentPalette('accent', {\n 'default': '500'\n })\n .warnPalette('red', {\n 'default': '800'\n });\n\n let lightMap = $mdThemingProvider.extendPalette('grey', {\n 'A100': 'ffffff'\n });\n $mdThemingProvider.definePalette('light', lightMap);\n\n $mdThemingProvider.theme('light')\n .primaryPalette('light', {\n 'default': 'A100'\n })\n .accentPalette('primary');\n\n $mdThemingProvider.setDefaultTheme('default');\n $mdThemingProvider.enableBrowserColor();\n\n // moment.js default overrides\n // TODO: add i18n support\n moment.updateLocale('en', {\n calendar: {\n lastDay : '[Yesterday at] LT',\n sameDay : '[Today at] LT',\n nextDay : '[Tomorrow at] LT',\n lastWeek : '[last] dddd [at] LT',\n nextWeek : 'dddd [at] LT',\n sameElse : 'll'\n }\n });\n }\n ]);\nexport default vleModule;\n"]} \ No newline at end of file diff --git a/src/main/webapp/wise5/vle/vleProjectService.es6 b/src/main/webapp/wise5/vle/vleProjectService.es6 index 5b2f06afe3..82deed43b1 100644 --- a/src/main/webapp/wise5/vle/vleProjectService.es6 +++ b/src/main/webapp/wise5/vle/vleProjectService.es6 @@ -73,27 +73,15 @@ class VLEProjectService extends ProjectService { /** * Check if we need to display the annotation to the student * @param annotation the annotation - * @returns whether we need to display the annotation to the student + * @returns {boolean} whether we need to display the annotation to the student */ displayAnnotation(annotation) { - let result = true; - if (annotation != null) { - const nodeId = annotation.nodeId; - const componentId = annotation.componentId; - const component = this.getComponentByNodeIdAndComponentId(nodeId, componentId); - - if (component != null) { - const componentType = component.type; - - // get the component service - const componentService = this.$injector.get(componentType + 'Service'); - - if (componentService != null && componentService.displayAnnotation != null) { - result = componentService.displayAnnotation(component, annotation); - } - } + const component = this.getComponentByNodeIdAndComponentId(annotation.nodeId, annotation.componentId); + if (component != null) { + const componentService = this.$injector.get(component.type + 'Service'); + return componentService.displayAnnotation(component, annotation); } - return result; + return true; } /** diff --git a/src/main/webapp/wise5/vle/vleProjectService.js b/src/main/webapp/wise5/vle/vleProjectService.js index 5564873487..0ff4173b9e 100644 --- a/src/main/webapp/wise5/vle/vleProjectService.js +++ b/src/main/webapp/wise5/vle/vleProjectService.js @@ -141,30 +141,18 @@ var VLEProjectService = function (_ProjectService) { /** * Check if we need to display the annotation to the student * @param annotation the annotation - * @returns whether we need to display the annotation to the student + * @returns {boolean} whether we need to display the annotation to the student */ }, { key: 'displayAnnotation', value: function displayAnnotation(annotation) { - var result = true; - if (annotation != null) { - var nodeId = annotation.nodeId; - var componentId = annotation.componentId; - var component = this.getComponentByNodeIdAndComponentId(nodeId, componentId); - - if (component != null) { - var componentType = component.type; - - // get the component service - var componentService = this.$injector.get(componentType + 'Service'); - - if (componentService != null && componentService.displayAnnotation != null) { - result = componentService.displayAnnotation(component, annotation); - } - } + var component = this.getComponentByNodeIdAndComponentId(annotation.nodeId, annotation.componentId); + if (component != null) { + var componentService = this.$injector.get(component.type + 'Service'); + return componentService.displayAnnotation(component, annotation); } - return result; + return true; } /** diff --git a/src/main/webapp/wise5/vle/vleProjectService.js.map b/src/main/webapp/wise5/vle/vleProjectService.js.map index b1fa18bbca..23914afd7b 100644 --- a/src/main/webapp/wise5/vle/vleProjectService.js.map +++ b/src/main/webapp/wise5/vle/vleProjectService.js.map @@ -1 +1 @@ -{"version":3,"sources":["vleProjectService.es6"],"names":["VLEProjectService","$filter","$http","$injector","$q","$rootScope","ConfigService","UtilService","nodeId","componentId","connectedComponentId","component","getComponentByNodeIdAndComponentId","connectedComponents","connectedComponent","id","componentContent","connectedComponentParams","annotation","result","componentType","type","componentService","get","displayAnnotation","previousScore","currentScore","annotationGroup","globalAnnotationSettings","globalAnnotationGroups","globalAnnotationGroup","enableCriteria","scoreSequence","previousScoreMatch","currentScoreMatch","toString","match","notificationResult","notificationSettings","notifications","notification","scriptFilename","assetDirectoryPath","getProjectAssetsDirectoryPath","scriptPath","then","data","additionalProcessingFunction","key","additionalProcessingFunctionsMap","push","getAdditionalProcessingFunctions","$inject"],"mappings":"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","file":"vleProjectService.js","sourcesContent":["'use strict';\nimport ProjectService from '../services/projectService';\n\nclass VLEProjectService extends ProjectService {\n constructor($filter, $http, $injector, $q, $rootScope, ConfigService, UtilService) {\n super($filter, $http, $injector, $q, $rootScope, ConfigService, UtilService);\n }\n\n /**\n * Check if a component is a connected component\n * @param nodeId the node id of the component\n * @param componentId the component that is listening for connected changes\n * @param connectedComponentId the component that is broadcasting connected changes\n * @returns whether the componentId is connected to the connectedComponentId\n */\n isConnectedComponent(nodeId, componentId, connectedComponentId) {\n const component = this.getComponentByNodeIdAndComponentId(nodeId, componentId);\n if (component != null) {\n const connectedComponents = component.connectedComponents;\n if (connectedComponents != null) {\n for (let connectedComponent of connectedComponents) {\n if (connectedComponent != null) {\n /*\n * check if the connected component id matches the one\n * we are looking for. connectedComponent.id is the old\n * field we used to store the component id in so we will\n * look for that field for the sake of backwards\n * compatibility. connectedComponent.componentId is the\n * new field we store the component id in.\n */\n if (connectedComponentId === connectedComponent.id ||\n connectedComponentId === connectedComponent.componentId) {\n return true;\n }\n }\n }\n }\n }\n return false;\n }\n\n /**\n * Get a connected component params\n * @param componentId the connected component id\n * @returns the params for the connected component\n */\n getConnectedComponentParams(componentContent, componentId) {\n let connectedComponentParams = null;\n if (componentContent != null && componentId != null) {\n const connectedComponents = componentContent.connectedComponents;\n if (connectedComponents != null) {\n for (let connectedComponent of connectedComponents) {\n if (connectedComponent != null) {\n /*\n * check if the connected component id matches the one\n * we are looking for. connectedComponent.id is the old\n * field we used to store the component id in so we will\n * look for that field for the sake of backwards\n * compatibility. connectedComponent.componentId is the\n * new field we store the component id in.\n */\n if (componentId === connectedComponent.id ||\n componentId === connectedComponent.componentId) {\n connectedComponentParams = connectedComponent;\n }\n }\n }\n }\n }\n return connectedComponentParams;\n }\n\n /**\n * Check if we need to display the annotation to the student\n * @param annotation the annotation\n * @returns whether we need to display the annotation to the student\n */\n displayAnnotation(annotation) {\n let result = true;\n if (annotation != null) {\n const nodeId = annotation.nodeId;\n const componentId = annotation.componentId;\n const component = this.getComponentByNodeIdAndComponentId(nodeId, componentId);\n\n if (component != null) {\n const componentType = component.type;\n\n // get the component service\n const componentService = this.$injector.get(componentType + 'Service');\n\n if (componentService != null && componentService.displayAnnotation != null) {\n result = componentService.displayAnnotation(component, annotation);\n }\n }\n }\n return result;\n }\n\n /**\n * Get the global annotation properties for the specified component and score, if exists.\n * @param component the component content\n * @param previousScore the previousScore we want the annotation properties for, can be null, which means we just want to look at\n * the currentScore\n * @param currentScore the currentScore we want the annotation properties for\n * @returns the annotation properties for the given score\n */\n getGlobalAnnotationGroupByScore(component, previousScore, currentScore) {\n let annotationGroup = null;\n if (component.globalAnnotationSettings != null &&\n component.globalAnnotationSettings.globalAnnotationGroups != null) {\n let globalAnnotationGroups = component.globalAnnotationSettings.globalAnnotationGroups;\n for (let globalAnnotationGroup of globalAnnotationGroups) {\n if (globalAnnotationGroup.enableCriteria != null &&\n globalAnnotationGroup.enableCriteria.scoreSequence != null) {\n let scoreSequence = globalAnnotationGroup.enableCriteria.scoreSequence;\n if (scoreSequence != null) {\n /*\n * get the expected previous score and current score\n * that will satisfy the rule\n */\n let previousScoreMatch = scoreSequence[0];\n let currentScoreMatch = scoreSequence[1];\n\n if (previousScore == null) {\n // just matching on the current score\n if (previousScoreMatch == \"\" &&\n currentScore.toString().match(\"[\" + currentScoreMatch + \"]\")) {\n // found a match\n annotationGroup = globalAnnotationGroup;\n break;\n }\n } else {\n if (previousScore.toString().match(\"[\" + previousScoreMatch + \"]\") &&\n currentScore.toString().match(\"[\" + currentScoreMatch + \"]\")) {\n /*\n * the previous score and current score match the\n * expected scores so we have found the rule we want\n */\n annotationGroup = globalAnnotationGroup;\n break;\n }\n }\n }\n }\n }\n }\n return annotationGroup;\n }\n\n /**\n * Get the notification for the given score, if exists.\n * @param component the component content\n * @param previousScore the previousScore we want notification for, can be null, which means we just want to look at\n * the currentScore\n * @param currentScore the currentScore we want notification for\n * @returns the notification for the given score\n */\n getNotificationByScore(component, previousScore, currentScore) {\n let notificationResult = null;\n if (component.notificationSettings != null &&\n component.notificationSettings.notifications != null) {\n let notifications = component.notificationSettings.notifications;\n for (let notification of notifications) {\n if (notification.enableCriteria != null &&\n notification.enableCriteria.scoreSequence != null) {\n let scoreSequence = notification.enableCriteria.scoreSequence;\n if (scoreSequence != null) {\n /*\n * get the expected previous score and current score\n * that will satisfy the rule\n */\n let previousScoreMatch = scoreSequence[0];\n let currentScoreMatch = scoreSequence[1];\n\n if (previousScore == null) {\n // just matching on the current score\n if (previousScoreMatch == \"\" &&\n currentScore.toString().match(\"[\" + currentScoreMatch + \"]\")) {\n notificationResult = notification;\n break;\n }\n } else {\n if (previousScore.toString().match(\"[\" + previousScoreMatch + \"]\") &&\n currentScore.toString().match(\"[\" + currentScoreMatch + \"]\")) {\n /*\n * the previous score and current score match the\n * expected scores so we have found the rule we want\n */\n notificationResult = notification;\n break;\n }\n }\n }\n }\n }\n }\n return notificationResult;\n }\n\n /**\n * Retrieve the script with the provided script filename\n * @param scriptFilename\n */\n retrieveScript(scriptFilename) {\n let assetDirectoryPath = this.ConfigService.getProjectAssetsDirectoryPath();\n let scriptPath = assetDirectoryPath + \"/\" + scriptFilename;\n return this.$http.get(scriptPath).then((result) => {\n return result.data;\n });\n };\n\n /**\n * Registers an additionalProcessingFunction for the specified node and component\n * @param nodeId the node id\n * @param componentId the component id\n * @param additionalProcessingFunction the function to register for the node and component.\n */\n addAdditionalProcessingFunction(nodeId, componentId, additionalProcessingFunction) {\n let key = nodeId + \"_\" + componentId;\n if (this.additionalProcessingFunctionsMap[key] == null) {\n this.additionalProcessingFunctionsMap[key] = [];\n }\n this.additionalProcessingFunctionsMap[key].push(additionalProcessingFunction);\n }\n\n /**\n * Returns true iff the specified node and component has any registered additionalProcessingFunctions\n * @param nodeId the node id\n * @param componentId the component id\n * @returns true/false\n */\n hasAdditionalProcessingFunctions(nodeId, componentId) {\n return this.getAdditionalProcessingFunctions(nodeId, componentId) != null;\n }\n\n /**\n * Returns an array of registered additionalProcessingFunctions for the specified node and component\n * @param nodeId the node id\n * @param componentId the component id\n * @returns an array of additionalProcessingFunctions\n */\n getAdditionalProcessingFunctions(nodeId, componentId) {\n let key = nodeId + \"_\" + componentId;\n return this.additionalProcessingFunctionsMap[key];\n }\n}\n\nVLEProjectService.$inject = [\n '$filter',\n '$http',\n '$injector',\n '$q',\n '$rootScope',\n 'ConfigService',\n 'UtilService'\n];\n\nexport default VLEProjectService;\n"]} \ No newline at end of file +{"version":3,"sources":["vleProjectService.es6"],"names":["VLEProjectService","$filter","$http","$injector","$q","$rootScope","ConfigService","UtilService","nodeId","componentId","connectedComponentId","component","getComponentByNodeIdAndComponentId","connectedComponents","connectedComponent","id","componentContent","connectedComponentParams","annotation","componentService","get","type","displayAnnotation","previousScore","currentScore","annotationGroup","globalAnnotationSettings","globalAnnotationGroups","globalAnnotationGroup","enableCriteria","scoreSequence","previousScoreMatch","currentScoreMatch","toString","match","notificationResult","notificationSettings","notifications","notification","scriptFilename","assetDirectoryPath","getProjectAssetsDirectoryPath","scriptPath","then","result","data","additionalProcessingFunction","key","additionalProcessingFunctionsMap","push","getAdditionalProcessingFunctions","$inject"],"mappings":"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","file":"vleProjectService.js","sourcesContent":["'use strict';\nimport ProjectService from '../services/projectService';\n\nclass VLEProjectService extends ProjectService {\n constructor($filter, $http, $injector, $q, $rootScope, ConfigService, UtilService) {\n super($filter, $http, $injector, $q, $rootScope, ConfigService, UtilService);\n }\n\n /**\n * Check if a component is a connected component\n * @param nodeId the node id of the component\n * @param componentId the component that is listening for connected changes\n * @param connectedComponentId the component that is broadcasting connected changes\n * @returns whether the componentId is connected to the connectedComponentId\n */\n isConnectedComponent(nodeId, componentId, connectedComponentId) {\n const component = this.getComponentByNodeIdAndComponentId(nodeId, componentId);\n if (component != null) {\n const connectedComponents = component.connectedComponents;\n if (connectedComponents != null) {\n for (let connectedComponent of connectedComponents) {\n if (connectedComponent != null) {\n /*\n * check if the connected component id matches the one\n * we are looking for. connectedComponent.id is the old\n * field we used to store the component id in so we will\n * look for that field for the sake of backwards\n * compatibility. connectedComponent.componentId is the\n * new field we store the component id in.\n */\n if (connectedComponentId === connectedComponent.id ||\n connectedComponentId === connectedComponent.componentId) {\n return true;\n }\n }\n }\n }\n }\n return false;\n }\n\n /**\n * Get a connected component params\n * @param componentId the connected component id\n * @returns the params for the connected component\n */\n getConnectedComponentParams(componentContent, componentId) {\n let connectedComponentParams = null;\n if (componentContent != null && componentId != null) {\n const connectedComponents = componentContent.connectedComponents;\n if (connectedComponents != null) {\n for (let connectedComponent of connectedComponents) {\n if (connectedComponent != null) {\n /*\n * check if the connected component id matches the one\n * we are looking for. connectedComponent.id is the old\n * field we used to store the component id in so we will\n * look for that field for the sake of backwards\n * compatibility. connectedComponent.componentId is the\n * new field we store the component id in.\n */\n if (componentId === connectedComponent.id ||\n componentId === connectedComponent.componentId) {\n connectedComponentParams = connectedComponent;\n }\n }\n }\n }\n }\n return connectedComponentParams;\n }\n\n /**\n * Check if we need to display the annotation to the student\n * @param annotation the annotation\n * @returns {boolean} whether we need to display the annotation to the student\n */\n displayAnnotation(annotation) {\n const component = this.getComponentByNodeIdAndComponentId(annotation.nodeId, annotation.componentId);\n if (component != null) {\n const componentService = this.$injector.get(component.type + 'Service');\n return componentService.displayAnnotation(component, annotation);\n }\n return true;\n }\n\n /**\n * Get the global annotation properties for the specified component and score, if exists.\n * @param component the component content\n * @param previousScore the previousScore we want the annotation properties for, can be null, which means we just want to look at\n * the currentScore\n * @param currentScore the currentScore we want the annotation properties for\n * @returns the annotation properties for the given score\n */\n getGlobalAnnotationGroupByScore(component, previousScore, currentScore) {\n let annotationGroup = null;\n if (component.globalAnnotationSettings != null &&\n component.globalAnnotationSettings.globalAnnotationGroups != null) {\n let globalAnnotationGroups = component.globalAnnotationSettings.globalAnnotationGroups;\n for (let globalAnnotationGroup of globalAnnotationGroups) {\n if (globalAnnotationGroup.enableCriteria != null &&\n globalAnnotationGroup.enableCriteria.scoreSequence != null) {\n let scoreSequence = globalAnnotationGroup.enableCriteria.scoreSequence;\n if (scoreSequence != null) {\n /*\n * get the expected previous score and current score\n * that will satisfy the rule\n */\n let previousScoreMatch = scoreSequence[0];\n let currentScoreMatch = scoreSequence[1];\n\n if (previousScore == null) {\n // just matching on the current score\n if (previousScoreMatch == \"\" &&\n currentScore.toString().match(\"[\" + currentScoreMatch + \"]\")) {\n // found a match\n annotationGroup = globalAnnotationGroup;\n break;\n }\n } else {\n if (previousScore.toString().match(\"[\" + previousScoreMatch + \"]\") &&\n currentScore.toString().match(\"[\" + currentScoreMatch + \"]\")) {\n /*\n * the previous score and current score match the\n * expected scores so we have found the rule we want\n */\n annotationGroup = globalAnnotationGroup;\n break;\n }\n }\n }\n }\n }\n }\n return annotationGroup;\n }\n\n /**\n * Get the notification for the given score, if exists.\n * @param component the component content\n * @param previousScore the previousScore we want notification for, can be null, which means we just want to look at\n * the currentScore\n * @param currentScore the currentScore we want notification for\n * @returns the notification for the given score\n */\n getNotificationByScore(component, previousScore, currentScore) {\n let notificationResult = null;\n if (component.notificationSettings != null &&\n component.notificationSettings.notifications != null) {\n let notifications = component.notificationSettings.notifications;\n for (let notification of notifications) {\n if (notification.enableCriteria != null &&\n notification.enableCriteria.scoreSequence != null) {\n let scoreSequence = notification.enableCriteria.scoreSequence;\n if (scoreSequence != null) {\n /*\n * get the expected previous score and current score\n * that will satisfy the rule\n */\n let previousScoreMatch = scoreSequence[0];\n let currentScoreMatch = scoreSequence[1];\n\n if (previousScore == null) {\n // just matching on the current score\n if (previousScoreMatch == \"\" &&\n currentScore.toString().match(\"[\" + currentScoreMatch + \"]\")) {\n notificationResult = notification;\n break;\n }\n } else {\n if (previousScore.toString().match(\"[\" + previousScoreMatch + \"]\") &&\n currentScore.toString().match(\"[\" + currentScoreMatch + \"]\")) {\n /*\n * the previous score and current score match the\n * expected scores so we have found the rule we want\n */\n notificationResult = notification;\n break;\n }\n }\n }\n }\n }\n }\n return notificationResult;\n }\n\n /**\n * Retrieve the script with the provided script filename\n * @param scriptFilename\n */\n retrieveScript(scriptFilename) {\n let assetDirectoryPath = this.ConfigService.getProjectAssetsDirectoryPath();\n let scriptPath = assetDirectoryPath + \"/\" + scriptFilename;\n return this.$http.get(scriptPath).then((result) => {\n return result.data;\n });\n };\n\n /**\n * Registers an additionalProcessingFunction for the specified node and component\n * @param nodeId the node id\n * @param componentId the component id\n * @param additionalProcessingFunction the function to register for the node and component.\n */\n addAdditionalProcessingFunction(nodeId, componentId, additionalProcessingFunction) {\n let key = nodeId + \"_\" + componentId;\n if (this.additionalProcessingFunctionsMap[key] == null) {\n this.additionalProcessingFunctionsMap[key] = [];\n }\n this.additionalProcessingFunctionsMap[key].push(additionalProcessingFunction);\n }\n\n /**\n * Returns true iff the specified node and component has any registered additionalProcessingFunctions\n * @param nodeId the node id\n * @param componentId the component id\n * @returns true/false\n */\n hasAdditionalProcessingFunctions(nodeId, componentId) {\n return this.getAdditionalProcessingFunctions(nodeId, componentId) != null;\n }\n\n /**\n * Returns an array of registered additionalProcessingFunctions for the specified node and component\n * @param nodeId the node id\n * @param componentId the component id\n * @returns an array of additionalProcessingFunctions\n */\n getAdditionalProcessingFunctions(nodeId, componentId) {\n let key = nodeId + \"_\" + componentId;\n return this.additionalProcessingFunctionsMap[key];\n }\n}\n\nVLEProjectService.$inject = [\n '$filter',\n '$http',\n '$injector',\n '$q',\n '$rootScope',\n 'ConfigService',\n 'UtilService'\n];\n\nexport default VLEProjectService;\n"]} \ No newline at end of file diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/admin/AllTests.java b/src/test/java/org/wise/portal/presentation/web/controllers/admin/AllTests.java deleted file mode 100644 index b9315068ed..0000000000 --- a/src/test/java/org/wise/portal/presentation/web/controllers/admin/AllTests.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2007 Regents of the University of California (Regents). Created - * by TELS, Graduate School of Education, University of California at Berkeley. - * - * This software is distributed under the GNU Lesser General Public License, v2. - * - * Permission is hereby granted, without written agreement and without license - * or royalty fees, to use, copy, modify, and distribute this software and its - * documentation for any purpose, provided that the above copyright notice and - * the following two paragraphs appear in all copies of this software. - * - * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. THE SOFTWAREAND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED - * HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE - * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, - * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.wise.portal.presentation.web.controllers.admin; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * @author patrick lawler - * - */ - -@RunWith(Suite.class) -@Suite.SuiteClasses( { - org.wise.portal.presentation.web.controllers.admin.ViewAllUsersControllerTest.class, - org.wise.portal.presentation.web.controllers.admin.FindProjectRunsControllerTest.class, - org.wise.portal.presentation.web.controllers.admin.UserInfoControllerTest.class -}) -public class AllTests { - -} diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/admin/FindProjectRunsControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/admin/FindProjectRunsControllerTest.java index 4d298bded6..caa7a1f10d 100644 --- a/src/test/java/org/wise/portal/presentation/web/controllers/admin/FindProjectRunsControllerTest.java +++ b/src/test/java/org/wise/portal/presentation/web/controllers/admin/FindProjectRunsControllerTest.java @@ -1,108 +1,93 @@ -/** - * Copyright (c) 2008 Regents of the University of California (Regents). Created - * by TELS, Graduate School of Education, University of California at Berkeley. - * - * This software is distributed under the GNU Lesser General Public License, v2. - * - * Permission is hereby granted, without written agreement and without license - * or royalty fees, to use, copy, modify, and distribute this software and its - * documentation for any purpose, provided that the above copyright notice and - * the following two paragraphs appear in all copies of this software. - * - * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. THE SOFTWAREAND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED - * HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE - * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, - * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.wise.portal.presentation.web.controllers.admin; - -import static org.easymock.EasyMock.createMock; -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.replay; - -import java.util.ArrayList; - -import org.easymock.EasyMock; -import org.junit.After; -import org.junit.Before; -import org.springframework.context.ApplicationContext; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.test.web.AbstractModelAndViewTests; -import org.springframework.validation.BindException; -import org.springframework.web.servlet.ModelAndView; -import org.wise.portal.domain.project.impl.FindProjectParameters; -import org.wise.portal.domain.run.Run; -import org.wise.portal.service.run.RunService; - -/** - * @author patrick lawler - * - */ -public class FindProjectRunsControllerTest extends AbstractModelAndViewTests { - - private final static String VIEW = "admin/manageallprojectruns"; - - private MockHttpServletRequest request; - - private MockHttpServletResponse response; - - private ApplicationContext mockApplicationContext; - - private FindProjectRunsController controller; - - private BindException errors; - - private RunService runService; - - private ArrayList runList; - - private FindProjectParameters findProjectParameters; - - @Before - public void setUp() { - this.request = new MockHttpServletRequest(); - this.response = new MockHttpServletResponse(); - this.mockApplicationContext = createMock(ApplicationContext.class); - this.runService = createMock(RunService.class); - this.controller = new FindProjectRunsController(); - this.runList = new ArrayList(); - this.findProjectParameters = new FindProjectParameters(); - this.errors = new BindException(findProjectParameters, ""); - } - - @After - public void tearDown() { - this.request = null; - this.response = null; - this.mockApplicationContext = null; - this.runService = null; - this.controller = null; - this.runList = null; - this.errors = null; - this.findProjectParameters = null; - } - - public void testOnSubmitNoRuns() { - findProjectParameters.setProjectId("1"); - expect(runService.getAllRunList()).andReturn(runList); - replay(runService); - ModelAndView modelAndView = null; - try { - modelAndView = controller.onSubmit(findProjectParameters, errors); - } catch (Exception e) { - fail("unexpected exception"); - } - - assertModelAttributeValue(modelAndView, "runList", runList); - assertEquals(VIEW, modelAndView.getViewName()); - EasyMock.verify(runService); - } - -} +/** + * Copyright (c) 2008-2018 Regents of the University of California (Regents). Created + * by TELS, Graduate School of Education, University of California at Berkeley. + * + * This software is distributed under the GNU Lesser General Public License, v2. + * + * Permission is hereby granted, without written agreement and without license + * or royalty fees, to use, copy, modify, and distribute this software and its + * documentation for any purpose, provided that the above copyright notice and + * the following two paragraphs appear in all copies of this software. + * + * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. THE SOFTWAREAND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED + * HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE + * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF + * REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.wise.portal.presentation.web.controllers.admin; + +import static org.easymock.EasyMock.createMock; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; +import org.easymock.EasyMock; +import org.easymock.EasyMockRunner; +import org.easymock.Mock; +import org.easymock.TestSubject; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.ui.ModelMap; +import org.wise.portal.dao.ObjectNotFoundException; +import org.wise.portal.domain.project.Project; +import org.wise.portal.domain.project.impl.ProjectImpl; +import org.wise.portal.domain.run.Run; +import org.wise.portal.domain.run.impl.RunImpl; +import org.wise.portal.service.run.impl.RunServiceImpl; + +/** + * @author patrick lawler + */ +@RunWith(EasyMockRunner.class) +public class FindProjectRunsControllerTest extends TestCase { + + @TestSubject + private FindProjectRunsController controller = new FindProjectRunsController(); + + @Mock + private RunServiceImpl runService; + + private ModelMap modelMap = new ModelMap(); + + Run run1; + Long run1Id = 1L; + String run1Name = "Run 1"; + + @Before + public void setUp() { + run1 = new RunImpl(); + run1.setName(run1Name); + } + + @After + public void tearDown() { + run1 = null; + } + + @Test + public void handleGET_byRunId_OK() throws ObjectNotFoundException { + EasyMock.expect(runService.retrieveById(run1Id)).andReturn(run1); + EasyMock.replay(runService); + String view = controller.findRun("runId", run1Id.toString(), modelMap); + assertEquals("admin/run/manageprojectruns", view); + List resultRunList = (List) modelMap.get("runList"); + assertEquals(1, resultRunList.size()); + Run resultFirstRun = resultRunList.get(0); + assertEquals(run1Name, resultFirstRun.getName()); + EasyMock.verify(runService); + } + + // TODO: test handleGET_byProjectId_OK + // TODO: test handleGET_byTeacherUsername_OK + // TODO: test handleGET_byRunTitle_OK +} diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/admin/UserInfoControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/admin/UserInfoControllerTest.java index 8f2e411717..8bf761f94f 100644 --- a/src/test/java/org/wise/portal/presentation/web/controllers/admin/UserInfoControllerTest.java +++ b/src/test/java/org/wise/portal/presentation/web/controllers/admin/UserInfoControllerTest.java @@ -1,121 +1,160 @@ -/** - * Copyright (c) 2007 Regents of the University of California (Regents). Created - * by TELS, Graduate School of Education, University of California at Berkeley. - * - * This software is distributed under the GNU Lesser General Public License, v2. - * - * Permission is hereby granted, without written agreement and without license - * or royalty fees, to use, copy, modify, and distribute this software and its - * documentation for any purpose, provided that the above copyright notice and - * the following two paragraphs appear in all copies of this software. - * - * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. THE SOFTWAREAND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED - * HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE - * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, - * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.wise.portal.presentation.web.controllers.admin; - -import java.util.Calendar; -import java.util.HashMap; - -import javax.servlet.http.HttpSession; - -import org.easymock.EasyMock; -import org.junit.After; -import org.junit.Before; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.mock.web.MockHttpSession; -import org.springframework.test.web.AbstractModelAndViewTests; -import org.springframework.web.servlet.ModelAndView; -import org.wise.portal.domain.authentication.Schoollevel; -import org.wise.portal.domain.authentication.impl.TeacherUserDetails; -import org.wise.portal.domain.user.User; -import org.wise.portal.domain.user.impl.UserImpl; -import org.wise.portal.service.user.UserService; - -/** - * @author patrick lawler - * - */ -public class UserInfoControllerTest extends AbstractModelAndViewTests{ - - private MockHttpServletRequest request; - - private MockHttpServletResponse response; - - private UserService mockUserService; - - private UserInfoController controller; - - private User user; - - private TeacherUserDetails userDetails; - - private HashMap info; - - /** - * @see junit.framework.TestCase#setUp() - */ - @Before - public void setUp() throws Exception { - super.setUp(); - this.request = new MockHttpServletRequest(); - this.response = new MockHttpServletResponse(); - HttpSession mockSession = new MockHttpSession(); - this.user = new UserImpl(); - this.userDetails = new TeacherUserDetails(); - this.userDetails.setCity("Berkeley"); - this.userDetails.setCountry("USA"); - String[] subjects = {"physics", "astronomy"}; - this.userDetails.setCurriculumsubjects(subjects); - this.userDetails.setDisplayname("Mr. Mister"); - this.userDetails.setEmailAddress("mr@here.com"); - this.userDetails.setFirstname("John"); - this.userDetails.setLastLoginTime(Calendar.getInstance().getTime()); - this.userDetails.setLastname("Smith"); - this.userDetails.setNumberOfLogins(5); - this.userDetails.setSchoollevel(Schoollevel.HIGH_SCHOOL); - this.userDetails.setSchoolname("Berkeley"); - this.userDetails.setSignupdate(Calendar.getInstance().getTime()); - this.userDetails.setState("CA"); - this.userDetails.setUsername("JohnSmith"); - - this.user.setUserDetails(this.userDetails); - - request.setParameter("userName", "JohnSmith"); - this.request.setSession(mockSession); - this.mockUserService = EasyMock.createMock(UserService.class); - - this.controller = new UserInfoController(); - this.controller.setUserService(this.mockUserService); - this.info = this.userDetails.getInfo(); - } - - @After - public void tearDown(){ - this.info = null; - this.mockUserService = null; - this.controller = null; - this.request = null; - this.response = null; - } - - public void testHandleRequestInternal()throws Exception{ - - EasyMock.expect(this.mockUserService.retrieveUserByUsername("JohnSmith")).andReturn(this.user); - EasyMock.replay(this.mockUserService); - ModelAndView modelAndView = this.controller.handleRequestInternal(request, response); - - assertModelAttributeValue(modelAndView, this.controller.USER_INFO_MAP, this.info); - - EasyMock.verify(this.mockUserService); - } -} +/** + * Copyright (c) 2007 Regents of the University of California (Regents). Created + * by TELS, Graduate School of Education, University of California at Berkeley. + * + * This software is distributed under the GNU Lesser General Public License, v2. + * + * Permission is hereby granted, without written agreement and without license + * or royalty fees, to use, copy, modify, and distribute this software and its + * documentation for any purpose, provided that the above copyright notice and + * the following two paragraphs appear in all copies of this software. + * + * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. THE SOFTWAREAND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED + * HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE + * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF + * REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.wise.portal.presentation.web.controllers.admin; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; + +import javax.servlet.http.HttpSession; + +import junit.framework.TestCase; +import org.easymock.EasyMock; +import org.easymock.TestSubject; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.api.easymock.PowerMock; +import org.powermock.api.easymock.annotation.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.ui.ModelMap; +import org.springframework.web.servlet.ModelAndView; +import org.wise.portal.domain.authentication.Schoollevel; +import org.wise.portal.domain.authentication.impl.PersistentGrantedAuthority; +import org.wise.portal.domain.authentication.impl.TeacherUserDetails; +import org.wise.portal.domain.run.Run; +import org.wise.portal.domain.run.impl.RunImpl; +import org.wise.portal.domain.user.User; +import org.wise.portal.domain.user.impl.UserImpl; +import org.wise.portal.presentation.web.controllers.ControllerUtil; +import org.wise.portal.service.authentication.UserDetailsService; +import org.wise.portal.service.run.RunService; +import org.wise.portal.service.student.StudentService; +import org.wise.portal.service.user.UserService; + +/** + * @author patrick lawler + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest(ControllerUtil.class) +public class UserInfoControllerTest extends TestCase { + + @TestSubject + private UserInfoController controller = new UserInfoController(); + + @Mock + private UserService userService; + + @Mock + private StudentService studentService; + + @Mock + private RunService runService; + + private User teacherUser; + + private User adminUser; + + private TeacherUserDetails teacherUserDetails; + + private TeacherUserDetails adminUserDetails; + + private ModelMap modelMap = new ModelMap(); + + @Before + public void setUp() throws Exception { + initializeTeacherUser(); + initializeAdminUser(); + + PowerMock.mockStatic(ControllerUtil.class); + EasyMock.expect(ControllerUtil.getSignedInUser()).andReturn(adminUser); + PowerMock.replay(ControllerUtil.class); + } + + protected void initializeAdminUser() { + this.adminUser = new UserImpl(); + this.adminUserDetails = new TeacherUserDetails(); + PersistentGrantedAuthority adminAuthority = new PersistentGrantedAuthority(); + adminAuthority.setAuthority(UserDetailsService.ADMIN_ROLE); + GrantedAuthority[] adminAuthorities = {adminAuthority}; + this.adminUserDetails.setAuthorities(adminAuthorities); + this.adminUser.setUserDetails(this.adminUserDetails); + } + + protected void initializeTeacherUser() { + this.teacherUser = new UserImpl(); + this.teacherUserDetails = new TeacherUserDetails(); + this.teacherUserDetails.setCity("Berkeley"); + PersistentGrantedAuthority teacherAuthority = new PersistentGrantedAuthority(); + teacherAuthority.setAuthority(UserDetailsService.TEACHER_ROLE); + GrantedAuthority[] authorities = {teacherAuthority}; + this.teacherUserDetails.setAuthorities(authorities); + this.teacherUserDetails.setCountry("USA"); + String[] subjects = {"physics", "astronomy"}; + this.teacherUserDetails.setCurriculumsubjects(subjects); + this.teacherUserDetails.setDisplayname("Mr. Mister"); + this.teacherUserDetails.setEmailAddress("mr@here.com"); + this.teacherUserDetails.setFirstname("John"); + this.teacherUserDetails.setLastLoginTime(Calendar.getInstance().getTime()); + this.teacherUserDetails.setLastname("Smith"); + this.teacherUserDetails.setNumberOfLogins(5); + this.teacherUserDetails.setSchoollevel(Schoollevel.HIGH_SCHOOL); + this.teacherUserDetails.setSchoolname("Berkeley"); + this.teacherUserDetails.setSignupdate(Calendar.getInstance().getTime()); + this.teacherUserDetails.setState("CA"); + this.teacherUserDetails.setUsername("JohnSmith"); + this.teacherUser.setUserDetails(this.teacherUserDetails); + } + + @After + public void tearDown(){ + this.userService = null; + this.controller = null; + PowerMock.verify(ControllerUtil.class); + } + + @Test + public void getUserAccountInfo_teacher_OK() throws Exception { + EasyMock.expect(this.userService.retrieveUserByUsername("JohnSmith")).andReturn(this.teacherUser); + PowerMock.replay(this.userService); + List teacherRuns = new ArrayList<>(); + teacherRuns.add(new RunImpl()); + EasyMock.expect(this.runService.getRunListByOwner(this.teacherUser)).andReturn(teacherRuns); + PowerMock.replay(this.runService); + String view = this.controller.getUserAccountInfo("JohnSmith", modelMap); + assertEquals("teacher/account/info", view); + assertEquals(false, modelMap.get("isStudent")); + List resultRunList = (List) modelMap.get("runList"); + assertEquals(1, resultRunList.size()); + EasyMock.verify(this.userService); + EasyMock.verify(this.runService); + } + + // TODO: test getUserAccountInfo_student_OK + // TODO: test getUserAccountInfo_user_accessDenied +} diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/admin/ViewAllUsersControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/admin/ViewAllUsersControllerTest.java index 0ca6052a8f..1a6f38dbf6 100644 --- a/src/test/java/org/wise/portal/presentation/web/controllers/admin/ViewAllUsersControllerTest.java +++ b/src/test/java/org/wise/portal/presentation/web/controllers/admin/ViewAllUsersControllerTest.java @@ -27,94 +27,125 @@ import javax.servlet.http.HttpSession; +import junit.framework.TestCase; import org.easymock.EasyMock; +import org.easymock.EasyMockRunner; +import org.easymock.Mock; +import org.easymock.TestSubject; import org.junit.After; import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpSession; -import org.springframework.test.web.AbstractModelAndViewTests; import org.springframework.ui.ModelMap; -import org.springframework.web.servlet.ModelAndView; +import org.wise.portal.domain.authentication.impl.StudentUserDetails; +import org.wise.portal.domain.authentication.impl.TeacherUserDetails; import org.wise.portal.domain.user.User; import org.wise.portal.domain.user.impl.UserImpl; -import org.wise.portal.presentation.web.controllers.ControllerUtil; +import org.wise.portal.service.authentication.impl.UserDetailsServiceImpl; import org.wise.portal.service.user.UserService; - /** * @author Sally Ahn - * @version $Id: $ */ -public class ViewAllUsersControllerTest extends AbstractModelAndViewTests{ - - private ViewAllUsersController viewAllUsersController; - - private MockHttpServletRequest request; - - private MockHttpServletResponse response; - - private ModelMap modelMap; - - private UserService mockUserService; - - private List allUsers; - - private List teachers; - - private List students; - - private List admins; - - private List other; - - private User user; - - /** - * @see junit.framework.TestCase#setUp() - */ - @Before - public void setUp() throws Exception { - super.setUp(); - this.request = new MockHttpServletRequest(); - this.response = new MockHttpServletResponse(); - HttpSession mockSession = new MockHttpSession(); - this.user = new UserImpl(); - - mockSession.setAttribute(User.CURRENT_USER_SESSION_KEY, this.user); - this.request.setSession(mockSession); - - this.mockUserService = EasyMock.createMock(UserService.class); - - this.viewAllUsersController = new ViewAllUsersController(); - this.allUsers = new ArrayList(); - this.teachers = new ArrayList(); - this.students = new ArrayList(); - this.admins = new ArrayList(); - this.other = new ArrayList(); - } - - - public void testHandleRequestInternal() throws Exception{ - - EasyMock.expect(mockUserService.retrieveAllUsers()).andReturn(allUsers); - EasyMock.replay(mockUserService); - - String view = - viewAllUsersController.handleRequestInternal(request, response, modelMap); - - assertEquals(view, "admin/manageusers"); - EasyMock.verify(mockUserService); - } - - /** - * @see junit.framework.TestCase#tearDown() - */ - @After - public void tearDown() throws Exception { - super.tearDown(); - this.request = null; - this.response = null; - this.mockUserService = null; - } +@RunWith(EasyMockRunner.class) +public class ViewAllUsersControllerTest extends TestCase { + + @TestSubject + private ViewAllUsersController controller = new ViewAllUsersController(); + + private MockHttpServletRequest request; + + private ModelMap modelMap = new ModelMap(); + + @Mock + private UserService userService; + + @Mock + private UserDetailsServiceImpl userDetailsService; + + private List allUsers; + + private List teachers; + + private List students; + + private List admins; + + private List other; + + private User user; + + @Before + public void setUp() throws Exception { + super.setUp(); + this.request = new MockHttpServletRequest(); + HttpSession mockSession = new MockHttpSession(); + this.user = new UserImpl(); + mockSession.setAttribute(User.CURRENT_USER_SESSION_KEY, this.user); + this.request.setSession(mockSession); + } + + @After + public void tearDown() throws Exception { + super.tearDown(); + this.request = null; + this.userService = null; + } + + @Test + public void showUsers_onlyTeachers_OK() throws Exception { + List allTeacherUsernames = new ArrayList<>(); + allTeacherUsernames.add("hirokiterashima"); + allTeacherUsernames.add("geoffreykwan"); + allTeacherUsernames.add("jonathanlimbreitbart"); + EasyMock.expect(userDetailsService.retrieveAllUsernames(TeacherUserDetails.class.getName())) + .andReturn(allTeacherUsernames); + EasyMock.replay(userDetailsService); + this.request.setParameter("userType", "teacher"); + String view = controller.showUsers(request, modelMap); + assertEquals(view, "admin/account/manageusers"); + List teacherUsernamesResult = (List) modelMap.get("teachers"); + assertEquals(3, teacherUsernamesResult.size()); + EasyMock.verify(userDetailsService); + } + + @Test + public void showUsers_onlyStudents_OK() throws Exception { + List allStudentUsernames = new ArrayList<>(); + allStudentUsernames.add("hirokit0101"); + allStudentUsernames.add("geoffreyk0102"); + allStudentUsernames.add("jonathanb0103"); + EasyMock.expect(userDetailsService.retrieveAllUsernames(StudentUserDetails.class.getName())) + .andReturn(allStudentUsernames); + EasyMock.replay(userDetailsService); + this.request.setParameter("userType", "student"); + String view = controller.showUsers(request, modelMap); + assertEquals(view, "admin/account/manageusers"); + List studentUsernamesResult = (List) modelMap.get("students"); + assertEquals(3, studentUsernamesResult.size()); + EasyMock.verify(userDetailsService); + } + + @Test + public void showUsers_allUsers_OK() throws Exception { + List allUserUsernames = new ArrayList<>(); + allUserUsernames.add("hirokiterashima"); + allUserUsernames.add("geoffreykwan"); + allUserUsernames.add("jonathanlimbreitbart"); + allUserUsernames.add("hirokit0101"); + allUserUsernames.add("geoffreyk0102"); + allUserUsernames.add("jonathanb0103"); + EasyMock.expect(userService.retrieveAllUsernames()).andReturn(allUserUsernames); + EasyMock.replay(userService); + String view = controller.showUsers(request, modelMap); + assertEquals(view, "admin/account/manageusers"); + List allUserUsernamesResult = (List) modelMap.get("usernames"); + assertEquals(6, allUserUsernamesResult.size()); + EasyMock.verify(userService); + } + + // TODO: test showUsers_onlyShowUsersWhoLoggedIn_OK + // TODO: test showUsers_onlyShowLoggedInUser_OK } diff --git a/versionBump.sh b/versionBump.sh index abcbb6f820..98f9aee62f 100755 --- a/versionBump.sh +++ b/versionBump.sh @@ -25,4 +25,16 @@ sed -i.bak "1,/\"version\": \".*\"/{s/\"version\": \".*\"/\"version\": \"${NEW_V # Note: this assumes that WISE version is the first ... tag in pom.xml sed -i.bak "1,/.*<\/version>/{s/.*<\/version>/${NEW_VERSION_NUMBER}<\/version>/;}" pom.xml && rm pom.xml.bak +# Note: this assumes that WISE version is in the ?v=versionNumber in jsp +sed -i.bak "1,/config\.js\?v\=.*\""/{s/config\.js\?v\=.*\"/config\.js\?v\=${NEW_VERSION_NUMBER}\""/;}" src/main/webapp/portal/author.jsp + +# Note: this assumes that WISE version is in the ?v=versionNumber in jsp +sed -i.bak "1,/config\.js\?v\=.*\""/{s/config\.js\?v\=.*\"/config\.js\?v\=${NEW_VERSION_NUMBER}\""/;}" src/main/webapp/portal/classroomMonitor.jsp + +# Note: this assumes that WISE version is in the ?v=versionNumber in jsp +sed -i.bak "1,/config\.js\?v\=.*\""/{s/config\.js\?v\=.*\"/config\.js\?v\=${NEW_VERSION_NUMBER}\""/;}" src/main/webapp/portal/student.jsp + +# Note: this assumes that WISE version is in the ?v=versionNumber in config.js +sed -i.bak "1,/\'\?v\=.*\'"/{s/\'\?v\=.*\'/\'\?v\=${NEW_VERSION_NUMBER}\'"/;}" src/main/webapp/wise5/config.js + echo "Bumped version number to ${NEW_VERSION_NUMBER}.\nYou might want to commit changes now:\ngit commit -a -m \"Bumped version number to ${NEW_VERSION_NUMBER}\""