From ac52afd741ce421908f9a7d3c2c90ddad9d1149f Mon Sep 17 00:00:00 2001 From: Geoffrey Kwan Date: Mon, 19 Oct 2020 17:29:22 -0400 Subject: [PATCH 01/14] Made SummaryAuthoringController extend ComponentAuthoringController. #2722 --- .../wise5/components/summary/authoring.html | 25 ++---- .../summary/summaryAuthoringController.ts | 77 +++++-------------- .../summaryAuthoringController.spec.js | 6 +- 3 files changed, 30 insertions(+), 78 deletions(-) diff --git a/src/main/webapp/wise5/components/summary/authoring.html b/src/main/webapp/wise5/components/summary/authoring.html index 65cfa1aa4f..5b4c295da6 100644 --- a/src/main/webapp/wise5/components/summary/authoring.html +++ b/src/main/webapp/wise5/components/summary/authoring.html @@ -148,7 +148,7 @@
{{ ::'advancedAuthoringOptions' | translate }}
{{ ::'advancedAuthoringOptions' | translate }} {{ ::'summary.customLabelColors' | translate }} -
-
+
+
{{ ::'studentPreview' | translate }}
-
-
- +
+
- - -
diff --git a/src/main/webapp/wise5/components/summary/summaryAuthoringController.ts b/src/main/webapp/wise5/components/summary/summaryAuthoringController.ts index 3012e40b60..307b5f48a4 100644 --- a/src/main/webapp/wise5/components/summary/summaryAuthoringController.ts +++ b/src/main/webapp/wise5/components/summary/summaryAuthoringController.ts @@ -1,81 +1,53 @@ 'use strict'; -import SummaryController from './summaryController'; +import { ComponentAuthoringController } from '../componentAuthoringController'; -class SummaryAuthoringController extends SummaryController { - $injector: any; - isResponsesOptionAvailable: boolean; - isHighlightCorrectAnswerAvailable: boolean; - isPieChartAllowed: boolean; +class SummaryAuthoringController extends ComponentAuthoringController { + isResponsesOptionAvailable: boolean = false; + isHighlightCorrectAnswerAvailable: boolean = false; + isPieChartAllowed: boolean = true; static $inject = [ '$filter', '$injector', - '$q', - '$mdDialog', - '$rootScope', '$scope', - 'AnnotationService', - 'AudioRecorderService', 'ConfigService', 'NodeService', - 'NotebookService', 'NotificationService', + 'ProjectAssetService', 'ProjectService', - 'StudentAssetService', - 'StudentDataService', 'SummaryService', 'UtilService' ]; constructor( - $filter, - $injector, - $q, - $mdDialog, - $rootScope, - $scope, - AnnotationService, - AudioRecorderService, - ConfigService, - NodeService, - NotebookService, - NotificationService, - ProjectService, - StudentAssetService, - StudentDataService, - SummaryService, - UtilService + protected $filter, + protected $injector, + protected $scope, + protected ConfigService, + protected NodeService, + protected NotificationService, + protected ProjectAssetService, + protected ProjectService, + protected SummaryService, + protected UtilService ) { super( - $filter, - $injector, - $mdDialog, - $q, - $rootScope, $scope, - AnnotationService, - AudioRecorderService, + $filter, ConfigService, NodeService, - NotebookService, NotificationService, + ProjectAssetService, ProjectService, - StudentAssetService, - StudentDataService, - SummaryService, UtilService ); - this.$injector = $injector; - this.isResponsesOptionAvailable = false; - this.isHighlightCorrectAnswerAvailable = false; - this.isPieChartAllowed = true; this.updateStudentDataTypeOptionsIfNecessary(); this.updateHasCorrectAnswerIfNecessary(); this.updateChartTypeOptionsIfNecessary(); } - authoringSummaryNodeIdChanged() { + summaryNodeIdChanged() { this.authoringComponentContent.summaryComponentId = null; const components = this.getComponentsByNodeId(this.authoringComponentContent.summaryNodeId); const allowedComponents = []; @@ -95,7 +67,7 @@ class SummaryAuthoringController extends SummaryController { return this.SummaryService.isComponentTypeAllowed(componentType); } - authoringSummaryComponentIdChanged() { + summaryComponentIdChanged() { this.performUpdatesIfNecessary(); this.authoringViewComponentChanged(); } @@ -107,20 +79,12 @@ class SummaryAuthoringController extends SummaryController { } performUpdatesIfNecessary() { - this.updateOtherPrompt(); this.updateStudentDataTypeOptionsIfNecessary(); this.updateStudentDataTypeIfNecessary(); this.updateHasCorrectAnswerIfNecessary(); this.updateChartTypeOptionsIfNecessary(); } - updateOtherPrompt() { - this.otherPrompt = this.getOtherPrompt( - this.authoringComponentContent.summaryNodeId, - this.authoringComponentContent.summaryComponentId - ); - } - updateStudentDataTypeOptionsIfNecessary() { const nodeId = this.authoringComponentContent.summaryNodeId; const componentId = this.authoringComponentContent.summaryComponentId; @@ -175,7 +139,6 @@ class SummaryAuthoringController extends SummaryController { } showPromptFromOtherComponentChanged() { - this.updateOtherPrompt(); this.authoringViewComponentChanged(); } diff --git a/src/main/webapp/wise5/test-unit/components/summary/summaryAuthoringController.spec.js b/src/main/webapp/wise5/test-unit/components/summary/summaryAuthoringController.spec.js index a1a0ab9656..4ac2daa8a4 100644 --- a/src/main/webapp/wise5/test-unit/components/summary/summaryAuthoringController.spec.js +++ b/src/main/webapp/wise5/test-unit/components/summary/summaryAuthoringController.spec.js @@ -83,7 +83,7 @@ function shouldCheckThatTheComponentIdIsNotAutomaticallySetWhenNoComponents() { 'zptq1ndv4h' ); spyOn(summaryAuthoringController, 'getComponentsByNodeId').and.returnValue(components); - summaryAuthoringController.authoringSummaryNodeIdChanged(); + summaryAuthoringController.summaryNodeIdChanged(); expect(summaryAuthoringController.authoringComponentContent.summaryComponentId).toBe(null); }); } @@ -100,7 +100,7 @@ function shouldCheckThatTheComponentIdIsNotAutomaticallySetWhenMultipleComponent 'zptq1ndv4h' ); spyOn(summaryAuthoringController, 'getComponentsByNodeId').and.returnValue(components); - summaryAuthoringController.authoringSummaryNodeIdChanged(); + summaryAuthoringController.summaryNodeIdChanged(); expect(summaryAuthoringController.authoringComponentContent.summaryComponentId).toBe(null); }); } @@ -117,7 +117,7 @@ function shouldCheckThatTheComponentIdIsAutomaticallySet() { 'zptq1ndv4h' ); spyOn(summaryAuthoringController, 'getComponentsByNodeId').and.returnValue(components); - summaryAuthoringController.authoringSummaryNodeIdChanged(); + summaryAuthoringController.summaryNodeIdChanged(); expect(summaryAuthoringController.authoringComponentContent.summaryComponentId).toBe( 'dghm45su45' ); From c2c0ee919d50b8e3ff6d1d1367129b1bb743a615 Mon Sep 17 00:00:00 2001 From: breity Date: Mon, 19 Oct 2020 16:35:23 -0700 Subject: [PATCH 02/14] Insert custom unit styles to VLE. #2727 --- src/main/webapp/wise5/themes/default/vle.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/webapp/wise5/themes/default/vle.html b/src/main/webapp/wise5/themes/default/vle.html index 2fc894a0e3..9c0690f81e 100644 --- a/src/main/webapp/wise5/themes/default/vle.html +++ b/src/main/webapp/wise5/themes/default/vle.html @@ -7,7 +7,8 @@
+ ng-class="::{'notebook-enabled': vleController.notebookEnabled}" + ng-style="::vleController.projectStyle"> From bcfa75af95d9ac61c3df45dfef3c6bf2a41f6264 Mon Sep 17 00:00:00 2001 From: Hiroki Terashima Date: Mon, 19 Oct 2020 17:37:32 -0700 Subject: [PATCH 03/14] Moved SnipImage subscription code to ComponentController. #2729 --- .../wise5/components/componentController.ts | 11 ++++++++ .../wise5/directives/component/component.js | 26 ------------------- 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/src/main/webapp/wise5/components/componentController.ts b/src/main/webapp/wise5/components/componentController.ts index 571879cf94..e4fb7ca1ca 100644 --- a/src/main/webapp/wise5/components/componentController.ts +++ b/src/main/webapp/wise5/components/componentController.ts @@ -72,6 +72,7 @@ class ComponentController { nodeSubmitClickedSubscription: Subscription; audioRecordedSubscription: Subscription; notebookItemChosenSubscription: Subscription; + snipImageSubscription: Subscription; studentWorkSavedToServerSubscription: Subscription; starterStateRequestSubscription: Subscription; @@ -192,6 +193,15 @@ class ComponentController { } $onInit() { + this.snipImageSubscription = + this.ProjectService.snipImage$.subscribe(({ target, componentId }) => { + if (componentId === this.componentId) { + const imageObject = this.UtilService.getImageObjectFromImageElement(target); + if (imageObject != null) { + this.NotebookService.addNote(imageObject); + } + } + }); this.starterStateRequestSubscription = this.NodeService.starterStateRequest$.subscribe((args: any) => { if (this.isForThisComponent(args)) { @@ -263,6 +273,7 @@ class ComponentController { if (this.notebookItemChosenSubscription != null) { this.notebookItemChosenSubscription.unsubscribe(); } + this.snipImageSubscription.unsubscribe(); this.starterStateRequestSubscription.unsubscribe(); } diff --git a/src/main/webapp/wise5/directives/component/component.js b/src/main/webapp/wise5/directives/component/component.js index 76d05b132b..a2939a3239 100644 --- a/src/main/webapp/wise5/directives/component/component.js +++ b/src/main/webapp/wise5/directives/component/component.js @@ -11,18 +11,6 @@ class ComponentController { this.ProjectService = ProjectService; this.StudentDataService = StudentDataService; this.UtilService = UtilService; - - this.$scope.$on('$destroy', () => { - this.ngOnDestroy(); - }); - } - - ngOnDestroy() { - this.unsubscribeAll(); - } - - unsubscribeAll() { - this.snipImageSubscription.unsubscribe(); } $onInit() { @@ -32,20 +20,6 @@ class ComponentController { this.$scope.mode = 'student'; } - /** - * Snip an image from the VLE - * @param $event the click event from the student clicking on the image - */ - this.snipImageSubscription = this.ProjectService.snipImage$.subscribe( - ({ target, componentId }) => { - if (this.componentId === componentId) { - const imageObject = this.UtilService.getImageObjectFromImageElement(target); - if (imageObject != null) { - this.NotebookService.addNote(imageObject); - } - } - }); - if (this.workgroupId != null) { try { this.workgroupId = parseInt(this.workgroupId); From 959d94b9affd4c7012163a4bdb72f8bdf55fb660 Mon Sep 17 00:00:00 2001 From: Hiroki Terashima Date: Tue, 20 Oct 2020 08:19:58 -0700 Subject: [PATCH 04/14] Changed server and client save times returned from the server to a long instead of a timestamp. #2716 --- .../vle/domain/annotation/wise5/AnnotationSerializer.java | 6 +++--- src/main/java/org/wise/vle/domain/work/EventSerializer.java | 6 +++--- .../org/wise/vle/domain/work/StudentWorkSerializer.java | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/wise/vle/domain/annotation/wise5/AnnotationSerializer.java b/src/main/java/org/wise/vle/domain/annotation/wise5/AnnotationSerializer.java index d56a6e8b89..f71bf08c1b 100644 --- a/src/main/java/org/wise/vle/domain/annotation/wise5/AnnotationSerializer.java +++ b/src/main/java/org/wise/vle/domain/annotation/wise5/AnnotationSerializer.java @@ -18,7 +18,7 @@ public void serialize(Annotation annotation, JsonGenerator gen, SerializerProvid throws IOException { gen.writeStartObject(); gen.writeObjectField("id", annotation.getId()); - gen.writeObjectField("clientSaveTime", annotation.getClientSaveTime()); + gen.writeObjectField("clientSaveTime", annotation.getClientSaveTime().getTime()); gen.writeObjectField("componentId", annotation.getComponentId()); ObjectMapper objectMapper = new ObjectMapper(); gen.writeObjectField("data", objectMapper.readTree(annotation.getData())); @@ -35,7 +35,7 @@ public void serialize(Annotation annotation, JsonGenerator gen, SerializerProvid } gen.writeObjectField("periodId", annotation.getPeriod().getId()); gen.writeObjectField("runId", annotation.getRun().getId()); - gen.writeObjectField("serverSaveTime", annotation.getServerSaveTime()); + gen.writeObjectField("serverSaveTime", annotation.getServerSaveTime().getTime()); StudentWork studentWork = annotation.getStudentWork(); if (studentWork != null) { gen.writeObjectField("studentWorkId", studentWork.getId()); @@ -43,4 +43,4 @@ public void serialize(Annotation annotation, JsonGenerator gen, SerializerProvid gen.writeObjectField("type", annotation.getType()); gen.writeEndObject(); } -} \ No newline at end of file +} diff --git a/src/main/java/org/wise/vle/domain/work/EventSerializer.java b/src/main/java/org/wise/vle/domain/work/EventSerializer.java index 91c4ff793f..94ca30f627 100644 --- a/src/main/java/org/wise/vle/domain/work/EventSerializer.java +++ b/src/main/java/org/wise/vle/domain/work/EventSerializer.java @@ -21,7 +21,7 @@ public void serialize(Event event, JsonGenerator gen, SerializerProvider seriali gen.writeStartObject(); gen.writeObjectField("id", event.getId()); gen.writeObjectField("category", event.getCategory()); - gen.writeObjectField("clientSaveTime", event.getClientSaveTime()); + gen.writeObjectField("clientSaveTime", event.getClientSaveTime().getTime()); gen.writeObjectField("componentId", event.getComponentId()); gen.writeObjectField("componentType", event.getComponentType()); gen.writeObjectField("context", event.getContext()); @@ -41,7 +41,7 @@ public void serialize(Event event, JsonGenerator gen, SerializerProvider seriali if (run != null) { gen.writeObjectField("runId", run.getId()); } - gen.writeObjectField("serverSaveTime", event.getServerSaveTime()); + gen.writeObjectField("serverSaveTime", event.getServerSaveTime().getTime()); Workgroup workgroup = event.getWorkgroup(); if (workgroup != null) { gen.writeObjectField("workgroupId", workgroup.getId()); @@ -52,4 +52,4 @@ public void serialize(Event event, JsonGenerator gen, SerializerProvider seriali } gen.writeEndObject(); } -} \ No newline at end of file +} diff --git a/src/main/java/org/wise/vle/domain/work/StudentWorkSerializer.java b/src/main/java/org/wise/vle/domain/work/StudentWorkSerializer.java index 0cb0d7485f..f51b3b47ab 100644 --- a/src/main/java/org/wise/vle/domain/work/StudentWorkSerializer.java +++ b/src/main/java/org/wise/vle/domain/work/StudentWorkSerializer.java @@ -14,7 +14,7 @@ public void serialize(StudentWork studentWork, JsonGenerator gen, SerializerProv throws IOException { gen.writeStartObject(); gen.writeObjectField("id", studentWork.getId()); - gen.writeObjectField("clientSaveTime", studentWork.getClientSaveTime()); + gen.writeObjectField("clientSaveTime", studentWork.getClientSaveTime().getTime()); gen.writeObjectField("componentId", studentWork.getComponentId()); gen.writeObjectField("componentType", studentWork.getComponentType()); gen.writeObjectField("isAutoSave", studentWork.getIsAutoSave()); @@ -22,10 +22,10 @@ public void serialize(StudentWork studentWork, JsonGenerator gen, SerializerProv gen.writeObjectField("nodeId", studentWork.getNodeId()); gen.writeObjectField("periodId", studentWork.getPeriod().getId()); gen.writeObjectField("runId", studentWork.getRun().getId()); - gen.writeObjectField("serverSaveTime", studentWork.getServerSaveTime()); + gen.writeObjectField("serverSaveTime", studentWork.getServerSaveTime().getTime()); ObjectMapper objectMapper = new ObjectMapper(); gen.writeObjectField("studentData", objectMapper.readTree(studentWork.getStudentData())); gen.writeObjectField("workgroupId", studentWork.getWorkgroup().getId()); gen.writeEndObject(); } -} \ No newline at end of file +} From fcb143ecb2e3cd01574b0f282aebab4ce67ff3de Mon Sep 17 00:00:00 2001 From: Hiroki Terashima Date: Tue, 20 Oct 2020 08:34:39 -0700 Subject: [PATCH 05/14] Fixed issue where lock/unlock commands were not being sent to students in real time. #2726 --- .../nodeProgress/navItem/navItem.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/webapp/wise5/classroomMonitor/classroomMonitorComponents/nodeProgress/navItem/navItem.ts b/src/main/webapp/wise5/classroomMonitor/classroomMonitorComponents/nodeProgress/navItem/navItem.ts index 13d5cbfef4..28383a5964 100644 --- a/src/main/webapp/wise5/classroomMonitor/classroomMonitorComponents/nodeProgress/navItem/navItem.ts +++ b/src/main/webapp/wise5/classroomMonitor/classroomMonitorComponents/nodeProgress/navItem/navItem.ts @@ -290,11 +290,9 @@ class NavItemController { } else { this.lockNode(node); } - this.ProjectService.saveProject().then(response => { - if (response.status === 'success') { - this.sendNodeToClass(node); - this.showToggleLockNodeConfirmation(!isLocked); - } + this.ProjectService.saveProject().then(() => { + this.sendNodeToClass(node); + this.showToggleLockNodeConfirmation(!isLocked); }); } From 9046fb22ecb2d42207818a9173c09b5eb9c1821f Mon Sep 17 00:00:00 2001 From: breity Date: Tue, 20 Oct 2020 10:55:04 -0700 Subject: [PATCH 06/14] Fixed custom unit style insertion; sanitize custom styles, #2727 --- src/main/webapp/wise5/themes/default/vle.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/webapp/wise5/themes/default/vle.html b/src/main/webapp/wise5/themes/default/vle.html index 9c0690f81e..aed78d44db 100644 --- a/src/main/webapp/wise5/themes/default/vle.html +++ b/src/main/webapp/wise5/themes/default/vle.html @@ -3,12 +3,12 @@ +
+ ng-class="::{'notebook-enabled': vleController.notebookEnabled}"> From 93a4211ca5b661c8fc543d8d0ad7b84b737f0dc6 Mon Sep 17 00:00:00 2001 From: Hiroki Terashima Date: Tue, 20 Oct 2020 11:14:47 -0700 Subject: [PATCH 07/14] Changed server and client save times returned from the server to a long instead of a timestamp for Notification and NotebookItem. #2716 --- .../domain/notification/NotificationSerializer.java | 8 +++++--- .../wise/vle/domain/work/NotebookItemSerializer.java | 12 ++++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/wise/vle/domain/notification/NotificationSerializer.java b/src/main/java/org/wise/vle/domain/notification/NotificationSerializer.java index c4458a65d1..d639895293 100644 --- a/src/main/java/org/wise/vle/domain/notification/NotificationSerializer.java +++ b/src/main/java/org/wise/vle/domain/notification/NotificationSerializer.java @@ -33,9 +33,11 @@ public void serialize(Notification notification, JsonGenerator gen, } else { gen.writeObjectField("data", null); } - gen.writeObjectField("timeGenerated", notification.getTimeGenerated()); - gen.writeObjectField("serverSaveTime", notification.getServerSaveTime()); - gen.writeObjectField("timeDismissed", notification.getTimeDismissed()); + gen.writeObjectField("timeGenerated", notification.getTimeGenerated().getTime()); + gen.writeObjectField("serverSaveTime", notification.getServerSaveTime().getTime()); + if (notification.getTimeDismissed() != null) { + gen.writeObjectField("timeDismissed", notification.getTimeDismissed().getTime()); + } gen.writeEndObject(); } diff --git a/src/main/java/org/wise/vle/domain/work/NotebookItemSerializer.java b/src/main/java/org/wise/vle/domain/work/NotebookItemSerializer.java index 8693948aed..02f338247d 100644 --- a/src/main/java/org/wise/vle/domain/work/NotebookItemSerializer.java +++ b/src/main/java/org/wise/vle/domain/work/NotebookItemSerializer.java @@ -19,10 +19,14 @@ public void serialize(NotebookItem item, JsonGenerator gen, SerializerProvider s gen.writeStringField("type", item.getType()); gen.writeStringField("localNotebookItemId", item.getLocalNotebookItemId()); gen.writeStringField("content", item.getContent()); - gen.writeObjectField("clientSaveTime", item.getClientSaveTime()); - gen.writeObjectField("serverSaveTime", item.getServerSaveTime()); - gen.writeObjectField("clientDeleteTime", item.getClientDeleteTime()); - gen.writeObjectField("serverDeleteTime", item.getServerDeleteTime()); + gen.writeObjectField("clientSaveTime", item.getClientSaveTime().getTime()); + gen.writeObjectField("serverSaveTime", item.getServerSaveTime().getTime()); + if (item.getClientDeleteTime() != null) { + gen.writeObjectField("clientDeleteTime", item.getClientDeleteTime().getTime()); + } + if (item.getServerDeleteTime() != null) { + gen.writeObjectField("serverDeleteTime", item.getServerDeleteTime().getTime()); + } if (item.getType().equals("note")) { addNoteFields(gen, item); } From cc5e99a2b6bda5b10cafee5da782379c29410041 Mon Sep 17 00:00:00 2001 From: Hiroki Terashima Date: Tue, 20 Oct 2020 11:25:21 -0700 Subject: [PATCH 08/14] Updated unit test. #2716 --- src/test/java/org/wise/portal/domain/work/NotebookItemTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/org/wise/portal/domain/work/NotebookItemTest.java b/src/test/java/org/wise/portal/domain/work/NotebookItemTest.java index 90eace443e..de18db7039 100644 --- a/src/test/java/org/wise/portal/domain/work/NotebookItemTest.java +++ b/src/test/java/org/wise/portal/domain/work/NotebookItemTest.java @@ -55,7 +55,6 @@ public void serialize() throws Exception { ",\"localNotebookItemId\":\"ooacs8tls7\"" + ",\"content\":\"{\\\"text\\\":\\\"my note!\\\"}\"" + ",\"clientSaveTime\":1582337976000,\"serverSaveTime\":1582338031000" + - ",\"clientDeleteTime\":null,\"serverDeleteTime\":null" + ",\"periodId\":100,\"nodeId\":\"node78\",\"title\":\"Note from first step\"}", json); } From 50a5a137b230953db4c75bfc6b6e77b72b337425 Mon Sep 17 00:00:00 2001 From: Geoffrey Kwan Date: Tue, 20 Oct 2020 16:42:42 -0400 Subject: [PATCH 09/14] Graph Component: Changing the graph plot type now updates the x axis and series parameters to appropriate matching values. #2719 --- .../wise5/components/graph/authoring.html | 4 +- .../graph/graphAuthoringController.ts | 80 ++++++++++++++----- .../wise5/components/graph/i18n/i18n_en.json | 2 + 3 files changed, 66 insertions(+), 20 deletions(-) diff --git a/src/main/webapp/wise5/components/graph/authoring.html b/src/main/webapp/wise5/components/graph/authoring.html index bfb88a8597..38f9d28602 100644 --- a/src/main/webapp/wise5/components/graph/authoring.html +++ b/src/main/webapp/wise5/components/graph/authoring.html @@ -452,7 +452,7 @@
{{ ::'graph.seriesNumbers' | translate }}
@@ -789,7 +789,7 @@
{{ ::'graph.series' | translate }}
ng-if='graphController.authoringComponentContent.graphType == "line" || graphController.authoringComponentContent.graphType == "scatter"'> diff --git a/src/main/webapp/wise5/components/graph/graphAuthoringController.ts b/src/main/webapp/wise5/components/graph/graphAuthoringController.ts index 60fce91e37..6d0f1eec70 100644 --- a/src/main/webapp/wise5/components/graph/graphAuthoringController.ts +++ b/src/main/webapp/wise5/components/graph/graphAuthoringController.ts @@ -9,8 +9,10 @@ class GraphAuthoringController extends ComponentAuthoringController { availableSeriesTypes: any[]; availableLineTypes: any[]; availableXAxisTypes: any[]; + plotTypeToLimitType: object; numYAxes: number; enableMultipleYAxes: boolean; + defaultDashStyle: string = 'Solid'; static $inject = [ '$filter', @@ -154,6 +156,12 @@ class GraphAuthoringController extends ComponentAuthoringController { { type: 'Table' } ]; + this.plotTypeToLimitType = { + line: 'limits', + scatter: 'limits', + column: 'categories' + } + this.numYAxes = 0; this.enableMultipleYAxes = this.isMultipleYAxesEnabled(); if (this.enableMultipleYAxes) { @@ -310,24 +318,23 @@ class GraphAuthoringController extends ComponentAuthoringController { this.authoringViewComponentChanged(); } - xAxisTypeChanged(newValue, oldValue) { - if (confirm(this.$translate('graph.areYouSureYouWantToChangeTheXAxisType'))) { - if (oldValue === 'categories' && newValue === 'limits') { - delete this.authoringComponentContent.xAxis.categories; - this.authoringComponentContent.xAxis.min = 0; - this.authoringComponentContent.xAxis.max = 10; - this.convertAllSeriesDataPoints(newValue); - } else if ((oldValue === 'limits' || oldValue === '' || oldValue == null) && - newValue === 'categories') { - delete this.authoringComponentContent.xAxis.min; - delete this.authoringComponentContent.xAxis.max; - delete this.authoringComponentContent.xAxis.units; - delete this.authoringComponentContent.yAxis.units; - this.authoringComponentContent.xAxis.categories = []; - this.convertAllSeriesDataPoints(newValue); - } - } else { - this.authoringComponentContent.xAxis.type = oldValue; + xAxisTypeChanged(newValue: string, oldValue: string): void { + if (oldValue === 'categories' && newValue === 'limits') { + delete this.authoringComponentContent.xAxis.categories; + this.authoringComponentContent.xAxis.min = 0; + this.authoringComponentContent.xAxis.max = 10; + this.convertAllSeriesDataPoints(newValue); + } else if ((oldValue === 'limits' || oldValue === '' || oldValue == null) && + newValue === 'categories') { + delete this.authoringComponentContent.xAxis.min; + delete this.authoringComponentContent.xAxis.max; + delete this.authoringComponentContent.xAxis.units; + delete this.authoringComponentContent.yAxis.units; + this.authoringComponentContent.xAxis.categories = [ + this.$translate('graph.categoryOne'), + this.$translate('graph.categoryTwo') + ]; + this.convertAllSeriesDataPoints(newValue); } this.authoringViewComponentChanged(); } @@ -713,6 +720,43 @@ class GraphAuthoringController extends ComponentAuthoringController { this.setSeriesColorToMatchYAxisColor(series); this.authoringViewComponentChanged(); } + + graphTypeChanged(): void { + const graphType = this.authoringComponentContent.graphType; + this.updateAllSeriesPlotTypes(graphType); + this.changeXAxisTypeIfNecessary(graphType); + this.authoringViewComponentChanged(); + } + + updateAllSeriesPlotTypes(plotType: string): void { + const multipleSeries = this.authoringComponentContent.series; + for (const singleSeries of multipleSeries) { + singleSeries.type = plotType; + this.updateDashStyleField(singleSeries); + } + } + + changeXAxisTypeIfNecessary(graphType: string): void { + const oldXAxisType = this.authoringComponentContent.xAxis.type; + const newXAxisType = this.plotTypeToLimitType[graphType]; + if (oldXAxisType != newXAxisType) { + this.authoringComponentContent.xAxis.type = newXAxisType; + this.xAxisTypeChanged(newXAxisType, oldXAxisType); + } + } + + seriesTypeChanged(series: any): void { + this.updateDashStyleField(series); + this.authoringViewComponentChanged(); + } + + updateDashStyleField(series: any): void { + if (series.type === 'line') { + series.dashStyle = this.defaultDashStyle; + } else { + delete series.dashStyle; + } + } } export default GraphAuthoringController; diff --git a/src/main/webapp/wise5/components/graph/i18n/i18n_en.json b/src/main/webapp/wise5/components/graph/i18n/i18n_en.json index 449ac8f74e..8249c3b987 100644 --- a/src/main/webapp/wise5/components/graph/i18n/i18n_en.json +++ b/src/main/webapp/wise5/components/graph/i18n/i18n_en.json @@ -23,6 +23,8 @@ "graph.canStudentHideSeriesOnLegendClick": "Can Student Hide Series By Clicking On Legend", "graph.categories": "Categories", "graph.categoryName": "Category Name", + "graph.categoryOne": "Category One", + "graph.categoryTwo": "Category Two", "graph.circle": "Circle", "graph.color": "Color", "graph.columnPlot": "Column Plot", From 2c26a1be1e4b8eeda9f13c4f4145e362f3f733ee Mon Sep 17 00:00:00 2001 From: Hiroki Terashima Date: Tue, 20 Oct 2020 13:38:00 -0700 Subject: [PATCH 10/14] Extracted EditComponent from component.js and cleaned up code. --- .../edit-component/editComponent.ts | 43 +++++++++++++++++++ .../authoringTool/components/shared/shared.ts | 2 + .../webapp/wise5/authoringTool/node/node.html | 2 +- .../wise5/directives/component/component.js | 17 ++------ 4 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 src/main/webapp/wise5/authoringTool/components/edit-component/editComponent.ts diff --git a/src/main/webapp/wise5/authoringTool/components/edit-component/editComponent.ts b/src/main/webapp/wise5/authoringTool/components/edit-component/editComponent.ts new file mode 100644 index 0000000000..d20cae9b20 --- /dev/null +++ b/src/main/webapp/wise5/authoringTool/components/edit-component/editComponent.ts @@ -0,0 +1,43 @@ +import { ConfigService } from "../../../services/configService"; +import { NodeService } from "../../../services/nodeService"; +import { TeacherProjectService } from "../../../services/teacherProjectService"; + +class EditComponentController { + + componentId: string; + nodeId: string; + + static $inject = ['$scope', 'ConfigService', 'NodeService', 'ProjectService']; + + constructor(private $scope: any, private ConfigService: ConfigService, + private NodeService: NodeService, private ProjectService: TeacherProjectService) { + } + + $onInit() { + this.$scope.mode = 'authoring'; + const authoringComponentContent = this.ProjectService.getComponentByNodeIdAndComponentId(this.nodeId, this.componentId); + const componentContent = this.ConfigService.replaceStudentNames( + this.ProjectService.injectAssetPaths(authoringComponentContent)); + this.$scope.authoringComponentContent = authoringComponentContent; + this.$scope.nodeAuthoringController = this.$scope.$parent.nodeAuthoringController; + this.$scope.componentTemplatePath = this.NodeService.getComponentAuthoringTemplatePath(componentContent.type); + this.$scope.componentContent = componentContent; + this.$scope.nodeId = this.nodeId; + this.$scope.type = componentContent.type; + } +} + +const EditComponent = { + bindings: { + componentId: '@', + nodeId: '@' + }, + scope: true, + controller: EditComponentController, + template: + `
+
+
` +}; + +export default EditComponent; diff --git a/src/main/webapp/wise5/authoringTool/components/shared/shared.ts b/src/main/webapp/wise5/authoringTool/components/shared/shared.ts index 762818f2a1..95a2df76f0 100644 --- a/src/main/webapp/wise5/authoringTool/components/shared/shared.ts +++ b/src/main/webapp/wise5/authoringTool/components/shared/shared.ts @@ -6,9 +6,11 @@ import StepTools from './stepTools/stepTools'; import Toolbar from './toolbar/toolbar'; import TopBar from './topBar/topBar'; import * as angular from 'angular'; +import EditComponent from '../edit-component/editComponent'; const SharedComponents = angular .module('sharedComponents', []) + .component('editComponent', EditComponent) .component('atMainMenu', MainMenu) .component('atSideMenu', SideMenu) .component('atStepTools', StepTools) diff --git a/src/main/webapp/wise5/authoringTool/node/node.html b/src/main/webapp/wise5/authoringTool/node/node.html index 103675aca4..24f5bee477 100644 --- a/src/main/webapp/wise5/authoringTool/node/node.html +++ b/src/main/webapp/wise5/authoringTool/node/node.html @@ -177,7 +177,7 @@
{{ :: {{ ::"insertAfter" | translate }}
- +
diff --git a/src/main/webapp/wise5/directives/component/component.js b/src/main/webapp/wise5/directives/component/component.js index a2939a3239..ed7e36b85a 100644 --- a/src/main/webapp/wise5/directives/component/component.js +++ b/src/main/webapp/wise5/directives/component/component.js @@ -1,7 +1,7 @@ class ComponentController { - constructor($injector, $scope, $compile, $element, ConfigService, NodeService, NotebookService, ProjectService, StudentDataService, UtilService) { - this.$injector = $injector; + + constructor($scope, $compile, $element, ConfigService, NodeService, NotebookService, ProjectService, StudentDataService) { this.$scope = $scope; this.$element = $element; this.$compile = $compile; @@ -10,7 +10,6 @@ class ComponentController { this.NotebookService = NotebookService; this.ProjectService = ProjectService; this.StudentDataService = StudentDataService; - this.UtilService = UtilService; } $onInit() { @@ -62,14 +61,7 @@ class ComponentController { componentContent = this.ProjectService.injectClickToSnipImage(componentContent); } - if (this.$scope.mode === 'authoring') { - this.$scope.authoringComponentContent = authoringComponentContent; - this.$scope.nodeAuthoringController = this.$scope.$parent.nodeAuthoringController; - this.$scope.componentTemplatePath = this.NodeService.getComponentAuthoringTemplatePath(componentContent.type); - } else { - this.$scope.componentTemplatePath = this.NodeService.getComponentTemplatePath(componentContent.type); - } - + this.$scope.componentTemplatePath = this.NodeService.getComponentTemplatePath(componentContent.type); this.$scope.componentContent = componentContent; this.$scope.componentState = this.componentState; this.$scope.nodeId = this.nodeId; @@ -99,8 +91,7 @@ class ComponentController { this.$compile(this.$element.contents())(this.$scope); } } - -ComponentController.$inject = ['$injector', '$scope', '$compile', '$element', 'ConfigService', 'NodeService', 'NotebookService', 'ProjectService', 'StudentDataService', 'UtilService']; +ComponentController.$inject = ['$scope', '$compile', '$element', 'ConfigService', 'NodeService', 'NotebookService', 'ProjectService', 'StudentDataService']; const Component = { bindings: { From fe0561255b8c823ef2a687849c90291fa99e78de Mon Sep 17 00:00:00 2001 From: Geoffrey Kwan Date: Wed, 21 Oct 2020 13:00:11 -0400 Subject: [PATCH 11/14] Made MatchAuthoringController extend ComponentAuthoringController. #2735 --- .../src/app/services/matchService.spec.ts | 18 +- .../wise5/components/match/authoring.html | 203 ++---------------- .../webapp/wise5/components/match/index.html | 8 +- .../match/matchAuthoringController.ts | 158 ++++++-------- .../wise5/components/match/matchController.ts | 66 +----- .../wise5/components/match/matchService.ts | 17 ++ 6 files changed, 125 insertions(+), 345 deletions(-) diff --git a/src/main/webapp/site/src/app/services/matchService.spec.ts b/src/main/webapp/site/src/app/services/matchService.spec.ts index 88a8b0499d..9f6ac9ebbb 100644 --- a/src/main/webapp/site/src/app/services/matchService.spec.ts +++ b/src/main/webapp/site/src/app/services/matchService.spec.ts @@ -38,6 +38,7 @@ describe('MatchService', () => { isCompleted(); componentStateHasStudentWork(); hasCorrectAnswer(); + getItemById(); }); function createMatchComponent(choices: any[], buckets: any[], feedback: any[]) { @@ -67,7 +68,7 @@ function createChoice(id: string, value: string) { return { id: id, value: value, - type: 'string' + type: 'choice' }; } @@ -185,4 +186,19 @@ function hasCorrectAnswer() { component.feedback[0].choices[1].isCorrect = true; expectHasCorrectAnswer(component, true); }); +} + +function getItemById() { + const item1 = createChoice('item1', 'Item 1'); + const item2 = createChoice('item2', 'Item 2'); + const items: any[] = [ + item1, + item2 + ]; + it('should get the item by id when the id exists', () => { + expect(service.getItemById('item1', items)).toEqual(item1); + }); + it('should return null when the item id does not exist', () => { + expect(service.getItemById('item3', items)).toEqual(null); + }); } \ No newline at end of file diff --git a/src/main/webapp/wise5/components/match/authoring.html b/src/main/webapp/wise5/components/match/authoring.html index d74e4e8a1a..86f933a8b5 100644 --- a/src/main/webapp/wise5/components/match/authoring.html +++ b/src/main/webapp/wise5/components/match/authoring.html @@ -253,7 +253,7 @@
{{ ::'advancedAuthoringOptions' | translate }}
style='height: 50; margin-top: 0;'>
{{ ::'match.choices' | translate }}
+ ng-click='matchController.addChoice()'> add @@ -282,7 +282,7 @@
{{ ::'match.choices' | translate }}
+ ng-click='matchController.moveChoiceUp($index)'> arrow_upward @@ -290,7 +290,7 @@
{{ ::'match.choices' | translate }}
+ ng-click='matchController.moveChoiceDown($index)'> arrow_downward @@ -298,7 +298,7 @@
{{ ::'match.choices' | translate }}
+ ng-click='matchController.deleteChoice($index)'> delete @@ -319,7 +319,7 @@
{{ ::'match.choices' | translate }}
style='height: 50; margin-top: 0;'>
{{ ::'match.targetBuckets' | translate }}
+ ng-click='matchController.addBucket()'> add @@ -348,7 +348,7 @@
{{ ::'match.targetBuckets' | translate }}
+ ng-click='matchController.moveBucketUp($index)'> arrow_upward @@ -356,7 +356,7 @@
{{ ::'match.targetBuckets' | translate }}
+ ng-click='matchController.moveBucketDown($index)'> arrow_downward @@ -364,7 +364,7 @@
{{ ::'match.targetBuckets' | translate }}
+ ng-click='matchController.deleteBucket($index)'> delete @@ -383,13 +383,13 @@
{{ ::'FEEDBACK' | translate }}

- {{matchController.getBucketValueById(bucketFeedback.bucketId)}} + {{matchController.getBucketNameById(bucketFeedback.bucketId)}}

- {{matchController.getChoiceValueById(choiceFeedback.choiceId)}} + {{matchController.getChoiceTextById(choiceFeedback.choiceId)}}
@@ -397,14 +397,14 @@
{{ ::'FEEDBACK' | translate }}
{{ ::'IS_CORRECT' | translate }} @@ -433,184 +433,13 @@
{{ ::'FEEDBACK' | translate }}
-
-
+
+
{{ ::'studentPreview' | translate }}
-
-
-
- -
-
-
-
-
- - - - - - - - -
- -
-
- - - - - open_with -
-

- - check - - - warning - - - clear - - - - -

-
-
-
-
-
-
- -
-
-
- - - - - - - - -
- -
-
- - - - - open_with -
-

- - check - - - warning - - - clear - - - - -

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-   -
-
- {{ ::'CORRECT' | translate }}! -
-
- {{ ::'INCORRECT' | translate }} -
-
-
- - {{ ::'SAVE' | translate }} - - - {{ ::'SUBMIT' | translate }} - - - {{matchController.saveMessage.text}} - - - {{ matchController.saveMessage.time | amDateFormat:'ddd, MMM D YYYY, h:mm a' }} - - - - -
-
+
diff --git a/src/main/webapp/wise5/components/match/index.html b/src/main/webapp/wise5/components/match/index.html index d43bd76cb9..30698a68f8 100644 --- a/src/main/webapp/wise5/components/match/index.html +++ b/src/main/webapp/wise5/components/match/index.html @@ -41,7 +41,7 @@

+ ng-class='{"success-bg": !matchController.hasCorrectAnswer || item.isCorrect, "info-bg": item.isIncorrectPosition, "warn-bg": matchController.hasCorrectAnswer && !item.isCorrect}'> check @@ -92,7 +92,7 @@

+ ng-class='::{"success-bg": !matchController.hasCorrectAnswer || item.isCorrect, "info-bg": item.isIncorrectPosition, "warn-bg": matchController.hasCorrectAnswer && !item.isCorrect}'> check @@ -225,7 +225,7 @@

+ ng-class='{"success-bg": !matchController.hasCorrectAnswer || item.isCorrect, "info-bg": item.isIncorrectPosition, "warn-bg": matchController.hasCorrectAnswer && !item.isCorrect}'> check @@ -287,7 +287,7 @@

+ ng-class='{"success-bg": !matchController.hasCorrectAnswer || item.isCorrect, "info-bg": item.isIncorrectPosition, "warn-bg": matchController.hasCorrectAnswer && !item.isCorrect}'> check diff --git a/src/main/webapp/wise5/components/match/matchAuthoringController.ts b/src/main/webapp/wise5/components/match/matchAuthoringController.ts index 0beea9b4e4..11c5da9f4c 100644 --- a/src/main/webapp/wise5/components/match/matchAuthoringController.ts +++ b/src/main/webapp/wise5/components/match/matchAuthoringController.ts @@ -1,106 +1,49 @@ 'use strict'; -import { ProjectAssetService } from '../../../site/src/app/services/projectAssetService'; -import MatchController from './matchController'; +import { ComponentAuthoringController } from '../componentAuthoringController'; -class MatchAuthoringController extends MatchController { - ProjectAssetService: ProjectAssetService; - $mdDialog: any; - allowedConnectedComponentTypes: any[]; +class MatchAuthoringController extends ComponentAuthoringController { + allowedConnectedComponentTypes: any[] = [{ type: 'Match' }]; + defaultSourceBucketId: string = '0'; static $inject = [ - '$filter', - '$injector', - '$mdDialog', - '$mdMedia', - '$q', - '$rootScope', '$scope', - 'AnnotationService', - 'AudioRecorderService', + '$filter', 'ConfigService', - 'dragulaService', 'MatchService', 'NodeService', 'NotebookService', 'NotificationService', 'ProjectAssetService', 'ProjectService', - 'StudentAssetService', - 'StudentDataService', 'UtilService' ]; constructor( - $filter, - $injector, - $mdDialog, - $mdMedia, - $q, - $rootScope, $scope, - AnnotationService, - AudioRecorderService, + $filter, ConfigService, - dragulaService, - MatchService, + private MatchService, NodeService, - NotebookService, + private NotebookService, NotificationService, - ProjectAssetService, + protected ProjectAssetService, ProjectService, - StudentAssetService, - StudentDataService, UtilService ) { super( - $filter, - $injector, - $mdDialog, - $mdMedia, - $q, - $rootScope, $scope, - AnnotationService, - AudioRecorderService, + $filter, ConfigService, - dragulaService, - MatchService, NodeService, - NotebookService, NotificationService, + ProjectAssetService, ProjectService, - StudentAssetService, - StudentDataService, UtilService ); - this.ProjectAssetService = ProjectAssetService; - this.allowedConnectedComponentTypes = [ - { - type: 'Match' - } - ]; - $scope.$watch( - function() { - return this.authoringComponentContent; - }.bind(this), - function(newValue, oldValue) { - this.componentContent = this.ProjectService.injectAssetPaths(newValue); - this.isHorizontal = this.componentContent.horizontal; - this.isSaveButtonVisible = this.componentContent.showSaveButton; - this.isSubmitButtonVisible = this.componentContent.showSubmitButton; - this.isCorrect = null; - this.submitCounter = 0; - this.isDisabled = false; - this.isSubmitButtonDisabled = false; - this.initializeChoices(); - this.initializeBuckets(); - }.bind(this), - true - ); } - authoringAddChoice() { + addChoice(): void { const newChoice = { id: this.UtilService.generateKey(10), value: '', @@ -111,7 +54,7 @@ class MatchAuthoringController extends MatchController { this.authoringViewComponentChanged(); } - authoringAddBucket() { + addBucket(): void { const newBucket = { id: this.UtilService.generateKey(10), value: '', @@ -122,7 +65,7 @@ class MatchAuthoringController extends MatchController { this.authoringViewComponentChanged(); } - authoringMoveChoiceUp(index) { + moveChoiceUp(index: number): void { if (index != 0) { const choice = this.authoringComponentContent.choices[index]; this.authoringComponentContent.choices.splice(index, 1); @@ -144,7 +87,7 @@ class MatchAuthoringController extends MatchController { } } - authoringMoveChoiceDown(index) { + moveChoiceDown(index: number): void { if (index < this.authoringComponentContent.choices.length - 1) { const choice = this.authoringComponentContent.choices[index]; this.authoringComponentContent.choices.splice(index, 1); @@ -166,7 +109,7 @@ class MatchAuthoringController extends MatchController { } } - authoringDeleteChoice(index) { + deleteChoice(index: number): void { if (confirm(this.$translate('match.areYouSureYouWantToDeleteThisChoice'))) { const deletedChoice = this.authoringComponentContent.choices.splice(index, 1); if (deletedChoice != null && deletedChoice.length > 0) { @@ -176,7 +119,7 @@ class MatchAuthoringController extends MatchController { } } - authoringMoveBucketUp(index) { + moveBucketUp(index: number): void { if (index > 0) { const bucket = this.authoringComponentContent.buckets[index]; this.authoringComponentContent.buckets.splice(index, 1); @@ -197,7 +140,7 @@ class MatchAuthoringController extends MatchController { } } - authoringMoveBucketDown(index) { + moveBucketDown(index: number): void { if (index < this.authoringComponentContent.buckets.length - 1) { const bucket = this.authoringComponentContent.buckets[index]; this.authoringComponentContent.buckets.splice(index, 1); @@ -222,7 +165,7 @@ class MatchAuthoringController extends MatchController { * Delete a bucket * @param index the index of the bucket in the bucket array */ - authoringDeleteBucket(index) { + deleteBucket(index: number): void { if (confirm(this.$translate('match.areYouSureYouWantToDeleteThisBucket'))) { const deletedBucket = this.authoringComponentContent.buckets.splice(index, 1); if (deletedBucket != null && deletedBucket.length > 0) { @@ -232,7 +175,7 @@ class MatchAuthoringController extends MatchController { } } - addChoiceToFeedback(choiceId) { + addChoiceToFeedback(choiceId: string): void { const feedback = this.authoringComponentContent.feedback; if (feedback != null) { for (const bucketFeedback of feedback) { @@ -243,7 +186,7 @@ class MatchAuthoringController extends MatchController { } } - addBucketToFeedback(bucketId) { + addBucketToFeedback(bucketId: string): void { const feedback = this.authoringComponentContent.feedback; if (feedback != null) { const bucket = { @@ -272,12 +215,12 @@ class MatchAuthoringController extends MatchController { * @returns the feedback object */ createFeedbackObject( - choiceId, - feedback, - isCorrect, - position = null, - incorrectPositionFeedback = null - ) { + choiceId: string, + feedback: string, + isCorrect: boolean, + position: number = null, + incorrectPositionFeedback: string = null + ): any { return { choiceId: choiceId, feedback: feedback, @@ -291,7 +234,7 @@ class MatchAuthoringController extends MatchController { * Remove a choice from the feedback * @param choiceId the choice id to remove */ - removeChoiceFromFeedback(choiceId) { + removeChoiceFromFeedback(choiceId: string): void { const feedback = this.authoringComponentContent.feedback; if (feedback != null) { for (const bucketFeedback of feedback) { @@ -311,7 +254,7 @@ class MatchAuthoringController extends MatchController { * Remove a bucket from the feedback * @param bucketId the bucket id to remove */ - removeBucketFromFeedback(bucketId) { + removeBucketFromFeedback(bucketId: string): void { const feedback = this.authoringComponentContent.feedback; if (feedback != null) { for (let f = 0; f < feedback.length; f++) { @@ -326,7 +269,7 @@ class MatchAuthoringController extends MatchController { } } - authoringViewFeedbackChanged() { + feedbackChanged(): void { let show = true; if (this.componentHasFeedback()) { show = true; @@ -341,7 +284,7 @@ class MatchAuthoringController extends MatchController { * Check if this component has been authored to have feedback or a correct choice * @return whether this component has feedback or a correct choice */ - componentHasFeedback() { + componentHasFeedback(): boolean { const feedback = this.authoringComponentContent.feedback; if (feedback != null) { for (const tempFeedback of feedback) { @@ -365,7 +308,7 @@ class MatchAuthoringController extends MatchController { * The "Is Correct" checkbox for a choice feedback has been clicked. * @param feedback The choice feedback. */ - authoringViewIsCorrectClicked(feedback) { + isCorrectClicked(feedback: any): void { if (!feedback.isCorrect) { delete feedback.position; delete feedback.incorrectPositionFeedback; @@ -377,7 +320,7 @@ class MatchAuthoringController extends MatchController { * Show the asset popup to allow the author to choose an image for the choice * @param choice the choice object to set the image into */ - chooseChoiceAsset(choice) { + chooseChoiceAsset(choice: any): void { const params = { isPopup: true, nodeId: this.nodeId, @@ -392,7 +335,7 @@ class MatchAuthoringController extends MatchController { * Show the asset popup to allow the author to choose an image for the bucket * @param bucket the bucket object to set the image into */ - chooseBucketAsset(bucket) { + chooseBucketAsset(bucket: any): void { const params = { isPopup: true, nodeId: this.nodeId, @@ -403,13 +346,13 @@ class MatchAuthoringController extends MatchController { this.openAssetChooser(params); } - openAssetChooser(params: any) { + openAssetChooser(params: any): void { this.ProjectAssetService.openAssetChooser(params).then( (data: any) => { this.assetSelected(data) } ); } - assetSelected({ nodeId, componentId, assetItem, target, targetObject }) { + assetSelected({ nodeId, componentId, assetItem, target, targetObject }): void { const fileName = assetItem.fileName; const fullFilePath = `${this.ConfigService.getProjectAssetsDirectoryPath()}/${fileName}`; if (target === 'rubric') { @@ -427,6 +370,35 @@ class MatchAuthoringController extends MatchController { } } + getChoiceTextById(choiceId: string): string { + const choice = this.MatchService.getChoiceById( + choiceId, + this.authoringComponentContent.choices + ); + if (choice != null) { + return choice.value; + } + return null; + } + + getBucketNameById(bucketId: string): string { + if (bucketId === this.defaultSourceBucketId) { + const choicesLabel = this.authoringComponentContent.choicesLabel; + return choicesLabel ? choicesLabel : this.$translate('match.choices'); + } + const bucket = this.MatchService.getBucketById( + bucketId, + this.authoringComponentContent.buckets + ); + if (bucket != null) { + return bucket.value; + } + return null; + } + + isNotebookEnabled() { + return this.NotebookService.isNotebookEnabled(); + } } export default MatchAuthoringController; diff --git a/src/main/webapp/wise5/components/match/matchController.ts b/src/main/webapp/wise5/components/match/matchController.ts index 7c39b99995..e9058e7483 100644 --- a/src/main/webapp/wise5/components/match/matchController.ts +++ b/src/main/webapp/wise5/components/match/matchController.ts @@ -227,7 +227,7 @@ class MatchController extends ComponentController { addNotebookItemToSourceBucket(notebookItem) { const choice = this.createChoiceFromNotebookItem(notebookItem); this.choices.push(choice); - const sourceBucket = this.getBucketById(this.sourceBucketId); + const sourceBucket = this.MatchService.getBucketById(this.sourceBucketId, this.buckets); sourceBucket.items.push(choice); } @@ -291,7 +291,7 @@ class MatchController extends ComponentController { setStudentWork(componentState) { const studentData = componentState.studentData; const componentStateBuckets = studentData.buckets; - const sourceBucket = this.getBucketById(this.sourceBucketId); + const sourceBucket = this.MatchService.getBucketById(this.sourceBucketId, this.buckets); sourceBucket.items = []; // clear the source bucket const bucketIds = this.getBucketIds(); const choiceIds = this.getChoiceIds(); @@ -302,12 +302,12 @@ class MatchController extends ComponentController { for (let currentChoice of componentStateBucket.items) { const currentChoiceId = currentChoice.id; const currentChoiceLocation = choiceIds.indexOf(currentChoiceId); - const bucket = this.getBucketById(componentStateBucketId); + const bucket = this.MatchService.getBucketById(componentStateBucketId, this.buckets); if (currentChoiceLocation > -1) { // choice is valid and used by student in a valid bucket, so add it to that bucket // content for choice with this id may have changed, so get updated content - const updatedChoice = this.getChoiceById(currentChoiceId); + const updatedChoice = this.MatchService.getChoiceById(currentChoiceId, this.choices); bucket.items.push(updatedChoice); choiceIds.splice(currentChoiceLocation, 1); } else { @@ -319,7 +319,7 @@ class MatchController extends ComponentController { // add unused choices to the source bucket for (let choiceId of choiceIds) { - sourceBucket.items.push(this.getChoiceById(choiceId)); + sourceBucket.items.push(this.MatchService.getChoiceById(choiceId, this.choices)); } const submitCounter = studentData.submitCounter; @@ -447,7 +447,7 @@ class MatchController extends ComponentController { const currentComponentStateBucketChoiceIds = currentComponentStateBucket.items.map(choice => { return choice.id; }); - let bucketFromSubmitComponentState = this.getBucketById( + let bucketFromSubmitComponentState = this.MatchService.getBucketById( currentComponentStateBucket.id, latestSubmitComponentStateBuckets ); @@ -782,20 +782,6 @@ class MatchController extends ComponentController { return deferred.promise; } - /** - * Get the choice by id from the authoring component content - * @param {string} id the choice id - * @returns {object} the choice object from the authoring component content - */ - getChoiceById(id) { - for (let choice of this.componentContent.choices) { - if (choice.id === id) { - return choice; - } - } - return null; - } - /** * Get the choice with the given text. * @param {string} text look for a choice with this text @@ -810,46 +796,6 @@ class MatchController extends ComponentController { return null; } - /** - * Get the bucket by id from the authoring component content. - * @param {string} id the bucket id - * @param {array} buckets (optional) the buckets to get the bucket from - * @returns {object} the bucket object from the authoring component content - */ - getBucketById(id, buckets = this.buckets) { - for (let bucket of buckets) { - if (bucket.id == id) { - return bucket; - } - } - return null; - } - - /** - * Get the choice value by id from the authoring component content - * @param {string} choiceId the choice id - * @returns {string} the choice value from the authoring component content - */ - getChoiceValueById(choiceId) { - const choice = this.getChoiceById(choiceId); - if (choice != null) { - return choice.value; - } - return null; - } - - /** - * Get the bucket value by id from the authoring component content - * @param {string} bucketId the bucket id - * @returns {string} the bucket value from the authoring component content - */ - getBucketValueById(bucketId) { - const bucket = this.getBucketById(bucketId); - if (bucket != null) { - return bucket.value; - } - return null; - } /** * Check if the component has been authored with a correct choice diff --git a/src/main/webapp/wise5/components/match/matchService.ts b/src/main/webapp/wise5/components/match/matchService.ts index 78390ed0bd..a145b003af 100644 --- a/src/main/webapp/wise5/components/match/matchService.ts +++ b/src/main/webapp/wise5/components/match/matchService.ts @@ -68,4 +68,21 @@ export class MatchService extends ComponentService { } return false; } + + getChoiceById(id: string, choices: any[]): any { + return this.getItemById(id, choices); + } + + getBucketById(id: string, buckets: any[]): any { + return this.getItemById(id, buckets); + } + + getItemById(id: string, items: any[]): any { + for (const item of items) { + if (item.id === id) { + return item; + } + } + return null; + } } From 6e5cb39bf78f14c87f43a132dd284f4a7006b924 Mon Sep 17 00:00:00 2001 From: Hiroki Terashima Date: Wed, 21 Oct 2020 11:48:15 -0700 Subject: [PATCH 12/14] Fixed issue where current user was adding to authors and causing a cyclic exception when adding lock constraint in CM mode. #2726 --- .../src/app/services/projectService.spec.ts | 16 ++++++++++ .../webapp/wise5/services/projectService.ts | 31 ++++++++++--------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/main/webapp/site/src/app/services/projectService.spec.ts b/src/main/webapp/site/src/app/services/projectService.spec.ts index 1c2e433a39..bdb4cc0ffd 100644 --- a/src/main/webapp/site/src/app/services/projectService.spec.ts +++ b/src/main/webapp/site/src/app/services/projectService.spec.ts @@ -86,6 +86,7 @@ describe('ProjectService', () => { deleteTheLastStepInAnActivity(); deleteAllStepsInAnActivity(); getTags(); + addCurrentUserToAuthors_CM_shouldAddUserInfo(); // TODO: add test for service.getFlattenedProjectAsNodeIds() // TODO: add test for service.getAllPaths() // TODO: add test for service.consolidatePaths() @@ -1044,3 +1045,18 @@ function getTags() { expect(tags[1].name).toEqual('Group 2'); }); } + +function addCurrentUserToAuthors_CM_shouldAddUserInfo() { + it('should add current user to authors in CM mode', () => { + spyOn(configService, 'getMyUserInfo').and.returnValue({ + userIds: [1], + firstName: 'wise', + lastName: 'panda', + username: 'wisepanda' + }); + spyOn(configService, 'isClassroomMonitor').and.returnValue(true); + const authors = service.addCurrentUserToAuthors([]); + expect(authors.length).toEqual(1); + expect(authors[0].id).toEqual(1); + }); +} diff --git a/src/main/webapp/wise5/services/projectService.ts b/src/main/webapp/wise5/services/projectService.ts index a66839834d..6a3cb97be1 100644 --- a/src/main/webapp/wise5/services/projectService.ts +++ b/src/main/webapp/wise5/services/projectService.ts @@ -1138,30 +1138,33 @@ export class ProjectService { } this.broadcastSavingProject(); this.cleanupBeforeSave(); - this.project.metadata.authors = this.getUniqueAuthors(this.getAuthors()); + this.project.metadata.authors = this.getUniqueAuthors(this.addCurrentUserToAuthors( + this.getAuthors())); return this.http.post(this.ConfigService.getConfigParam('saveProjectURL'), angular.toJson(this.project, false)).toPromise().then((response: any) => { this.handleSaveProjectResponse(response); }); } - getAuthors() { - const authors = this.project.metadata.authors ? this.project.metadata.authors : []; - const userInfo = this.ConfigService.getMyUserInfo(); - let exists = false; - for (const author of authors) { - if (author.id === userInfo.id) { - exists = true; - break; - } - } - if (!exists) { - authors.push(userInfo); + getAuthors(): any[] { + return this.project.metadata.authors ? this.project.metadata.authors : []; + } + + addCurrentUserToAuthors(authors: any[]): any[] { + let userInfo = this.ConfigService.getMyUserInfo(); + if (this.ConfigService.isClassroomMonitor()) { + userInfo = { + id: userInfo.userIds[0], + firstName: userInfo.firstName, + lastName: userInfo.lastName, + username: userInfo.username + }; } + authors.push(userInfo); return authors; } - getUniqueAuthors(authors = []) { + getUniqueAuthors(authors = []): any[] { const idToAuthor = {}; const uniqueAuthors = []; for (const author of authors) { From 1ec210b8360994f40feb2df7745202b12d3da5e8 Mon Sep 17 00:00:00 2001 From: Hiroki Terashima Date: Wed, 21 Oct 2020 12:13:11 -0700 Subject: [PATCH 13/14] Removed code that is implemented in the parent class. #2735 --- .../components/match/matchAuthoringController.ts | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/main/webapp/wise5/components/match/matchAuthoringController.ts b/src/main/webapp/wise5/components/match/matchAuthoringController.ts index 11c5da9f4c..77aeda8a11 100644 --- a/src/main/webapp/wise5/components/match/matchAuthoringController.ts +++ b/src/main/webapp/wise5/components/match/matchAuthoringController.ts @@ -346,22 +346,10 @@ class MatchAuthoringController extends ComponentAuthoringController { this.openAssetChooser(params); } - openAssetChooser(params: any): void { - this.ProjectAssetService.openAssetChooser(params).then( - (data: any) => { this.assetSelected(data) } - ); - } - assetSelected({ nodeId, componentId, assetItem, target, targetObject }): void { + super.assetSelected({ nodeId, componentId, assetItem, target }); const fileName = assetItem.fileName; - const fullFilePath = `${this.ConfigService.getProjectAssetsDirectoryPath()}/${fileName}`; - if (target === 'rubric') { - this.UtilService.insertFileInSummernoteEditor( - `summernoteRubric_${this.nodeId}_${this.componentId}`, - fullFilePath, - fileName - ); - } else if (target === 'choice') { + if (target === 'choice') { targetObject.value = ''; this.authoringViewComponentChanged(); } else if (target === 'bucket') { From 94e92fce757679596b4f7b8acc783f073d673733 Mon Sep 17 00:00:00 2001 From: Hiroki Terashima Date: Wed, 21 Oct 2020 14:55:37 -0700 Subject: [PATCH 14/14] Bumped version number to 5.17.4 --- package-lock.json | 2 +- package.json | 2 +- pom.xml | 2 +- src/main/resources/version.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index f739bcf04d..c274103e88 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "wise", - "version": "5.17.3", + "version": "5.17.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index fcbe8fbd30..0c87277e35 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wise", - "version": "5.17.3", + "version": "5.17.4", "description": "Web-based Inquiry Science Environment", "main": "app.js", "browserslist": [ diff --git a/pom.xml b/pom.xml index 03b7b39d6e..3cb4a364c7 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ wise war Web-based Inquiry Science Environment - 5.17.3 + 5.17.4 http://wise5.org diff --git a/src/main/resources/version.txt b/src/main/resources/version.txt index 997dfff826..da932512e1 100644 --- a/src/main/resources/version.txt +++ b/src/main/resources/version.txt @@ -1 +1 @@ -5.17.3 +5.17.4