Skip to content

Commit dd65a31

Browse files
Merge pull request #2946 from WISE-Community/issue-2945-extract-draw-grading
Extract grading view from Draw component
2 parents 358d956 + 9474d10 commit dd65a31

12 files changed

Lines changed: 286 additions & 215 deletions

File tree

src/main/webapp/site/src/app/services/drawService.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ describe('DrawService', () => {
4343
isDrawDataContainsObjects();
4444
isStarterDrawDataExists();
4545
isStudentDrawDataDifferentFromStarterData();
46+
initializeDrawingTool();
4647
});
4748

4849
function createComponentState(drawData: string, isSubmit: boolean = false) {
@@ -262,3 +263,24 @@ function isStudentDrawDataDifferentFromStarterData() {
262263
);
263264
});
264265
}
266+
267+
function initializeDrawingTool() {
268+
it('should initialize the drawing tool', () => {
269+
const drawingToolId: string = 'drawing-tool';
270+
const stamps = {};
271+
const width: number = 400;
272+
const height: number = 300;
273+
const isHideDrawingTools: boolean = false;
274+
const drawingTool = service.initializeDrawingTool(
275+
drawingToolId,
276+
stamps,
277+
width,
278+
height,
279+
isHideDrawingTools
280+
);
281+
expect(drawingTool).not.toBeNull();
282+
expect(drawingTool.options.stamps).toEqual(stamps);
283+
expect(drawingTool.canvas.width).toEqual(width);
284+
expect(drawingTool.canvas.height).toEqual(height);
285+
});
286+
}

src/main/webapp/site/src/app/teacher-hybrid-angular.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ import { OpenResponseGrading } from '../../../wise5/components/openResponse/open
6363
import { MultipleChoiceGrading } from '../../../wise5/components/multipleChoice/multiple-choice-grading/multiple-choice-grading.component';
6464
import { MatchGrading } from '../../../wise5/components/match/match-grading/match-grading.component';
6565
import { LabelGrading } from '../../../wise5/components/label/label-grading/label-grading.component';
66+
import { DrawGrading } from '../../../wise5/components/draw/draw-grading/draw-grading.component';
6667

6768
@NgModule({
6869
declarations: [
@@ -78,6 +79,7 @@ import { LabelGrading } from '../../../wise5/components/label/label-grading/labe
7879
ComponentSelectComponent,
7980
ConceptMapAuthoring,
8081
DrawAuthoring,
82+
DrawGrading,
8183
DiscussionAuthoring,
8284
EditComponentRubricComponent,
8385
EditComponentJsonComponent,

src/main/webapp/wise5/classroomMonitor/classroomMonitorComponents/shared/workgroupComponentRevisions/workgroupComponentRevisions.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,16 @@ const WorkgroupComponentRevisions = {
158158
</h3>
159159
<div style="padding: 20px;">
160160
<ng-content ng-switch="item.componentState.componentType">
161-
<div ng-switch-when="Label|Match|MultipleChoice|OpenResponse" ng-switch-when-separator="|" class="component__content" layout="row" layout-wrap>
161+
<div ng-switch-when="Draw|Label|Match|MultipleChoice|OpenResponse" ng-switch-when-separator="|" class="component__content" layout="row" layout-wrap>
162162
<div flex="100" flex-gt-sm="66" layout="column" class="component--grading__response">
163+
<draw-grading
164+
ng-if="item.componentState.componentType === 'Draw'"
165+
node-id="{{::$ctrl.nodeId}}"
166+
component-id="{{::$ctrl.componentId}}"
167+
component-state="{{ item.componentState }}"
168+
workgroup-id="::$ctrl.workgroupId"
169+
is-revision="true">
170+
</draw-grading>
163171
<label-grading
164172
ng-if="item.componentState.componentType === 'Label'"
165173
node-id="{{::$ctrl.nodeId}}"

src/main/webapp/wise5/classroomMonitor/classroomMonitorComponents/shared/workgroupNodeGrading/workgroupNodeGrading.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,15 @@ const WorkgroupNodeGrading = {
138138
</h3>
139139
<ng-content ng-switch="::component.type">
140140
{{latestComponentState = $ctrl.getLatestComponentStateByWorkgroupIdAndComponentId($ctrl.workgroupId, component.id); ""}}
141-
<div ng-switch-when="Label|Match|MultipleChoice|OpenResponse" ng-switch-when-separator="|" class="component__content" layout="row" layout-wrap>
141+
<div ng-switch-when="Draw|Label|Match|MultipleChoice|OpenResponse" ng-switch-when-separator="|" class="component__content" layout="row" layout-wrap>
142142
<div flex="100" flex-gt-sm="66" layout="column" class="component--grading__response">
143143
<ng-content ng-if="latestComponentState != null && latestComponentState !== ''">
144+
<draw-grading
145+
ng-if="component.type === 'Draw'"
146+
node-id="{{::$ctrl.nodeId}}"
147+
component-id="{{::component.id}}"
148+
component-state="{{latestComponentState}}">
149+
</draw-grading>
144150
<label-grading
145151
ng-if="component.type === 'Label'"
146152
node-id="{{::$ctrl.nodeId}}"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<div class='component--grading__response__content'>
2+
<div id='{{drawingToolId}}' class='drawing-tool'>
3+
</div>
4+
</div>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.drawing-tool {
2+
border: 1px solid black;
3+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { Component } from '@angular/core';
2+
import { ComponentGrading } from '../../../classroomMonitor/classroomMonitorComponents/shared/component-grading.component';
3+
import { ProjectService } from '../../../services/projectService';
4+
import { DrawService } from '../drawService';
5+
6+
@Component({
7+
selector: 'draw-grading',
8+
templateUrl: 'draw-grading.component.html',
9+
styleUrls: ['draw-grading.component.scss']
10+
})
11+
export class DrawGrading extends ComponentGrading {
12+
drawingToolId: string;
13+
drawingTool: any;
14+
15+
constructor(private DrawService: DrawService, protected ProjectService: ProjectService) {
16+
super(ProjectService);
17+
}
18+
19+
ngOnInit(): void {
20+
super.ngOnInit();
21+
this.drawingToolId = this.getDrawingToolId();
22+
// wait for angular to completely render the html before we initialize the canvas
23+
setTimeout(() => {
24+
this.initializeDrawingTool();
25+
this.setStudentWork();
26+
});
27+
}
28+
29+
getDrawingToolId(): string {
30+
return this.getDrawingToolIdPrefix() + this.componentState.id;
31+
}
32+
33+
getDrawingToolIdPrefix(): string {
34+
if (this.isRevision) {
35+
return 'drawing-tool-revision-';
36+
} else {
37+
return 'drawing-tool-';
38+
}
39+
}
40+
41+
initializeDrawingTool(): void {
42+
const isHideDrawingTools: boolean = true;
43+
this.drawingTool = this.DrawService.initializeDrawingTool(
44+
this.drawingToolId,
45+
this.componentContent.stamps,
46+
this.componentContent.width,
47+
this.componentContent.height,
48+
isHideDrawingTools
49+
);
50+
this.drawingTool.canvas.removeListeners();
51+
}
52+
53+
setStudentWork(): void {
54+
this.drawingTool.load(this.componentState.studentData.drawData);
55+
}
56+
}

src/main/webapp/wise5/components/draw/drawController.ts

Lines changed: 31 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ window['fabric'] = fabric.fabric;
77
import ComponentController from '../componentController';
88
import * as EventEmitter2 from 'eventemitter2';
99
window['EventEmitter2'] = EventEmitter2;
10-
import DrawingTool from '../../lib/drawingTool/drawing-tool';
1110
import { DrawService } from './drawService';
1211

1312
class DrawController extends ComponentController {
@@ -106,21 +105,10 @@ class DrawController extends ComponentController {
106105

107106
this.componentType = this.componentContent.type;
108107

109-
if (this.isStudentMode() || this.isAuthoringComponentPreviewMode()) {
110-
this.isSaveButtonVisible = this.componentContent.showSaveButton;
111-
this.isSubmitButtonVisible = this.componentContent.showSubmitButton;
112-
this.isResetButtonVisible = true;
113-
this.drawingToolId = 'drawingtool_' + this.nodeId + '_' + this.componentId;
114-
} else if (this.isGradingMode() || this.isGradingRevisionMode()) {
115-
const componentState = this.$scope.componentState;
116-
if (componentState != null) {
117-
if (this.isGradingRevisionMode()) {
118-
this.drawingToolId = 'drawingtool_gradingRevision_' + componentState.id;
119-
} else {
120-
this.drawingToolId = 'drawingtool_' + componentState.id;
121-
}
122-
}
123-
}
108+
this.isSaveButtonVisible = this.componentContent.showSaveButton;
109+
this.isSubmitButtonVisible = this.componentContent.showSubmitButton;
110+
this.isResetButtonVisible = true;
111+
this.drawingToolId = 'drawingtool_' + this.nodeId + '_' + this.componentId;
124112

125113
/*
126114
* Running this inside a timeout ensures that the code only runs after the markup is rendered.
@@ -193,67 +181,31 @@ class DrawController extends ComponentController {
193181
}
194182

195183
initializeDrawingTool() {
196-
this.drawingTool = new DrawingTool('#' + this.drawingToolId, {
197-
stamps: this.componentContent.stamps || {},
198-
parseSVG: true,
199-
width: this.width,
200-
height: this.height
201-
});
202-
let state = null;
203-
$('#set-background').on('click', () => {
204-
this.drawingTool.setBackgroundImage($('#background-src').val());
205-
});
206-
$('#resize-background').on('click', () => {
207-
this.drawingTool.resizeBackgroundToCanvas();
208-
});
209-
$('#resize-canvas').on('click', () => {
210-
this.drawingTool.resizeCanvasToBackground();
211-
});
212-
$('#shrink-background').on('click', () => {
213-
this.drawingTool.shrinkBackgroundToCanvas();
214-
});
215-
$('#clear').on('click', () => {
216-
this.drawingTool.clear(true);
217-
});
218-
$('#save').on('click', () => {
219-
state = this.drawingTool.save();
220-
$('#load').removeAttr('disabled');
221-
});
222-
$('#load').on('click', () => {
223-
if (state === null) return;
224-
this.drawingTool.load(state);
225-
});
226-
184+
this.drawingTool = this.DrawService.initializeDrawingTool(
185+
this.drawingToolId,
186+
this.componentContent.stamps,
187+
this.width,
188+
this.height
189+
);
227190
const componentState = this.$scope.componentState;
228-
if (this.isStudentMode()) {
229-
if (this.UtilService.hasShowWorkConnectedComponent(this.componentContent)) {
230-
this.handleConnectedComponents();
231-
} else if (
232-
this.DrawService.componentStateHasStudentWork(componentState, this.componentContent)
233-
) {
234-
this.setStudentWork(componentState);
235-
} else if (this.UtilService.hasConnectedComponent(this.componentContent)) {
236-
this.handleConnectedComponents();
237-
} else if (
238-
componentState == null ||
239-
!this.DrawService.componentStateHasStudentWork(componentState, this.componentContent)
240-
) {
241-
if (this.componentContent.starterDrawData != null) {
242-
this.drawingTool.load(this.componentContent.starterDrawData);
243-
}
244-
if (this.componentContent.background != null) {
245-
this.drawingTool.setBackgroundImage(this.componentContent.background);
246-
}
247-
}
248-
} else if (this.isAuthoringComponentPreviewMode()) {
191+
if (this.UtilService.hasShowWorkConnectedComponent(this.componentContent)) {
192+
this.handleConnectedComponents();
193+
} else if (
194+
this.DrawService.componentStateHasStudentWork(componentState, this.componentContent)
195+
) {
196+
this.setStudentWork(componentState);
197+
} else if (this.UtilService.hasConnectedComponent(this.componentContent)) {
198+
this.handleConnectedComponents();
199+
} else if (
200+
componentState == null ||
201+
!this.DrawService.componentStateHasStudentWork(componentState, this.componentContent)
202+
) {
249203
if (this.componentContent.starterDrawData != null) {
250204
this.drawingTool.load(this.componentContent.starterDrawData);
251205
}
252206
if (this.componentContent.background != null) {
253207
this.drawingTool.setBackgroundImage(this.componentContent.background);
254208
}
255-
} else {
256-
this.setStudentWork(componentState);
257209
}
258210

259211
if (this.hasMaxSubmitCount() && this.hasSubmitsLeft()) {
@@ -278,24 +230,16 @@ class DrawController extends ComponentController {
278230
500
279231
);
280232

281-
if (this.isStudentMode()) {
282-
this.drawingTool.on('tool:changed', (toolName) => {
283-
const category = 'Tool';
284-
const event = 'toolSelected';
285-
const data = {
286-
selectedToolName: toolName
287-
};
288-
this.StudentDataService.saveComponentEvent(this, category, event, data);
289-
});
290-
}
233+
this.drawingTool.on('tool:changed', (toolName) => {
234+
const category = 'Tool';
235+
const event = 'toolSelected';
236+
const data = {
237+
selectedToolName: toolName
238+
};
239+
this.StudentDataService.saveComponentEvent(this, category, event, data);
240+
});
291241

292-
if (this.isGradingMode() || this.isGradingRevisionMode()) {
293-
$('#' + this.drawingToolId)
294-
.find('.dt-tools')
295-
.hide();
296-
} else {
297-
this.setupTools();
298-
}
242+
this.setupTools();
299243

300244
if (this.isDisabled) {
301245
this.drawingTool.canvas.removeListeners();
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
'use strict';
2+
3+
import * as angular from 'angular';
4+
import { downgradeComponent } from '@angular/upgrade/static';
5+
import { DrawGrading } from './draw-grading/draw-grading.component';
6+
7+
const drawGradingComponentModule = angular
8+
.module('drawGradingComponentModule', ['pascalprecht.translate'])
9+
.directive(
10+
'drawGrading',
11+
downgradeComponent({ component: DrawGrading }) as angular.IDirectiveFactory
12+
);
13+
14+
export default drawGradingComponentModule;

src/main/webapp/wise5/components/draw/drawService.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
'use strict';
22

33
import * as angular from 'angular';
4+
import * as $ from 'jquery';
5+
import * as fabric from 'fabric';
6+
window['fabric'] = fabric.fabric;
7+
import * as EventEmitter2 from 'eventemitter2';
8+
window['EventEmitter2'] = EventEmitter2;
9+
import DrawingTool from '../../lib/drawingTool/drawing-tool';
410
import { ComponentService } from '../componentService';
511
import { StudentAssetService } from '../../services/studentAssetService';
612
import { Injectable } from '@angular/core';
@@ -157,4 +163,49 @@ export class DrawService extends ComponentService {
157163
}
158164
return null;
159165
}
166+
167+
initializeDrawingTool(
168+
drawingToolId: string,
169+
stamps: any = {},
170+
width: number = 800,
171+
height: number = 600,
172+
isHideDrawingTools: boolean = false
173+
): any {
174+
const drawingTool = new DrawingTool('#' + drawingToolId, {
175+
stamps: stamps,
176+
parseSVG: true,
177+
width: width,
178+
height: height
179+
});
180+
let state = null;
181+
$('#set-background').on('click', () => {
182+
drawingTool.setBackgroundImage($('#background-src').val());
183+
});
184+
$('#resize-background').on('click', () => {
185+
drawingTool.resizeBackgroundToCanvas();
186+
});
187+
$('#resize-canvas').on('click', () => {
188+
drawingTool.resizeCanvasToBackground();
189+
});
190+
$('#shrink-background').on('click', () => {
191+
drawingTool.shrinkBackgroundToCanvas();
192+
});
193+
$('#clear').on('click', () => {
194+
drawingTool.clear(true);
195+
});
196+
$('#save').on('click', () => {
197+
state = drawingTool.save();
198+
$('#load').removeAttr('disabled');
199+
});
200+
$('#load').on('click', () => {
201+
if (state === null) return;
202+
drawingTool.load(state);
203+
});
204+
if (isHideDrawingTools) {
205+
$('#' + drawingToolId)
206+
.find('.dt-tools')
207+
.hide();
208+
}
209+
return drawingTool;
210+
}
160211
}

0 commit comments

Comments
 (0)