Skip to content

Commit 358d956

Browse files
Merge pull request #2944 from WISE-Community/issue-2943-extract-label-grading
Extract grading view from Label component
2 parents fca14e4 + a2f79ae commit 358d956

14 files changed

Lines changed: 951 additions & 641 deletions

File tree

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

Lines changed: 178 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,29 @@ let service: LabelService;
1515
let utilService: UtilService;
1616
let label1: any;
1717
let label2: any;
18+
let label1Text: any = 'Label 1';
19+
let label2Text: any = 'Label 2';
20+
let label1PointX: number = 1;
21+
let label1PointY: number = 11;
22+
let label1TextX: number = 111;
23+
let label1TextY: number = 1111;
24+
let label2PointX: number = 2;
25+
let label2PointY: number = 22;
26+
let label2TextX: number = 222;
27+
let label2TextY: number = 2222;
28+
let color1: string = 'blue';
29+
let color2: string = 'red';
30+
let width: number = 400;
31+
let height: number = 400;
32+
let pointSize: number = 5;
33+
let fontSize: number = 12;
34+
let labelWidth: number = 20;
35+
let enableCircles: boolean = true;
36+
let studentDataVersion: number = 2;
37+
let canEditBoolean: boolean = true;
38+
let canDeleteBoolean: boolean = true;
1839

19-
describe('LabelServiceService', () => {
40+
describe('LabelService', () => {
2041
beforeEach(() => {
2142
TestBed.configureTestingModule({
2243
imports: [HttpClientTestingModule, UpgradeModule],
@@ -34,8 +55,8 @@ describe('LabelServiceService', () => {
3455
});
3556
service = TestBed.get(LabelService);
3657
utilService = TestBed.get(UtilService);
37-
label1 = createLabel('Label 1', 1, 11, 111, 1111, 'blue');
38-
label2 = createLabel('Label 2', 2, 22, 222, 2222, 'red');
58+
label1 = createLabel(label1Text, label1PointX, label1PointY, label1TextX, label1TextY, color1);
59+
label2 = createLabel(label2Text, label2PointX, label2PointY, label2TextX, label2TextY, color2);
3960
});
4061
createComponent();
4162
isCompleted();
@@ -48,6 +69,11 @@ describe('LabelServiceService', () => {
4869
labelsAreTheSame();
4970
getTSpans();
5071
getSVGTextElementString();
72+
initializeCanvas();
73+
addLabelsToCanvas();
74+
addLabelToCanvas();
75+
createLabelServiceFunction();
76+
makeSureValueIsWithinLimit();
5177
});
5278

5379
function createComponentState(labels: any[], isSubmit: boolean = false) {
@@ -68,23 +94,54 @@ function createObjectWithLabels(labels: any[]) {
6894
}
6995

7096
function createLabel(
71-
text: string,
72-
pointX: number,
73-
pointY: number,
74-
textX: number,
75-
textY: number,
76-
color: string
77-
) {
97+
text: string = '',
98+
pointX: number = 100,
99+
pointY: number = 100,
100+
textX: number = 200,
101+
textY: number = 200,
102+
color: string = color1,
103+
canEdit: boolean = true,
104+
canDelete: boolean = true
105+
): any {
78106
return {
79107
text: text,
108+
color: color,
80109
pointX: pointX,
81110
pointY: pointY,
82111
textX: textX,
83112
textY: textY,
84-
color: color
113+
canEdit: canEdit,
114+
canDelete: canDelete
85115
};
86116
}
87117

118+
function createFabricLabel() {
119+
const pointX: number = 100;
120+
const pointY: number = 100;
121+
const textX: number = 200;
122+
const textY: number = 200;
123+
const textString: string = label1Text;
124+
const color: string = color1;
125+
const canEdit: boolean = true;
126+
const canDelete: boolean = true;
127+
return service.createLabel(
128+
pointX,
129+
pointY,
130+
textX,
131+
textY,
132+
textString,
133+
color,
134+
canEdit,
135+
canDelete,
136+
width,
137+
height,
138+
pointSize,
139+
fontSize,
140+
labelWidth,
141+
studentDataVersion
142+
);
143+
}
144+
88145
function createComponent() {
89146
it('should create a label component', () => {
90147
const component: any = service.createComponent();
@@ -127,7 +184,8 @@ function isCompleted() {
127184
componentStates.push(createComponentState([label1]));
128185
expectIsCompleted(component, componentStates, node, true);
129186
});
130-
it(`should check if is completed when submit is required and there are labels but not submitted`, () => {
187+
it(`should check if is completed when submit is required and there are labels but not
188+
submitted`, () => {
131189
node.showSubmitButton = true;
132190
componentStates.push(createComponentState([label1]));
133191
expectIsCompleted(component, componentStates, node, false);
@@ -144,14 +202,17 @@ function componentStateHasSubmitWithLabel() {
144202
beforeEach(() => {
145203
componentState = createComponentState([]);
146204
});
147-
it('should check if a component state has a submit with label when it does not have any labels', () => {
205+
it(`should check if a component state has a submit with label when it does not have any
206+
labels`, () => {
148207
expect(service.componentStateHasSubmitWithLabel(componentState)).toEqual(false);
149208
});
150-
it('should check if a component state has a submit with label when it has a label but no submit', () => {
209+
it(`should check if a component state has a submit with label when it has a label but no
210+
submit`, () => {
151211
componentState.studentData.labels.push(label1);
152212
expect(service.componentStateHasSubmitWithLabel(componentState)).toEqual(false);
153213
});
154-
it('should check if a component state has a submit with label when it has a label and submit', () => {
214+
it(`should check if a component state has a submit with label when it has a label and
215+
submit`, () => {
155216
componentState.studentData.labels.push(label1);
156217
componentState.isSubmit = true;
157218
expect(service.componentStateHasSubmitWithLabel(componentState)).toEqual(true);
@@ -292,11 +353,20 @@ function labelsAreTheSame() {
292353
it('should check if labels are the same when one is null and one is not null', () => {
293354
expectLabelsAreTheSame({}, null, false);
294355
});
295-
it(`should check if labels are the same when both are not null and do not have the same values`, () => {
356+
it(`should check if labels are the same when both are not null and do not have the same
357+
values`, () => {
296358
expectLabelsAreTheSame(label1, label2, false);
297359
});
298-
it(`should check if labels are the same when both are not null and do have the same values`, () => {
299-
const label3 = createLabel('Label 1', 1, 11, 111, 1111, 'blue');
360+
it(`should check if labels are the same when both are not null and do have the same
361+
values`, () => {
362+
const label3 = createLabel(
363+
label1Text,
364+
label1PointX,
365+
label1PointY,
366+
label1TextX,
367+
label1TextY,
368+
color1
369+
);
300370
expectLabelsAreTheSame(label1, label3, true);
301371
});
302372
}
@@ -326,3 +396,93 @@ function getSVGTextElementString() {
326396
expect(textElementString).toEqual(expectedResult);
327397
});
328398
}
399+
400+
function createCanvas() {
401+
return service.initializeCanvas('label-canvas', 400, 300, false);
402+
}
403+
404+
function initializeCanvas() {
405+
it('should initialize the canvas', () => {
406+
const canvas: any = createCanvas();
407+
expect(canvas).not.toBeNull();
408+
});
409+
}
410+
411+
function addLabelsToCanvas() {
412+
it('should add labels to canvas', () => {
413+
const canvas: any = createCanvas();
414+
const labels: any[] = [label1, label2];
415+
const fabricLabels: any = service.addLabelsToCanvas(
416+
canvas,
417+
labels,
418+
width,
419+
height,
420+
pointSize,
421+
fontSize,
422+
labelWidth,
423+
enableCircles,
424+
studentDataVersion
425+
);
426+
const canvasTextObjects = getCanvasTextObjects(canvas);
427+
expect(fabricLabels.length).toEqual(2);
428+
expect(fabricLabels[0].text.text).toEqual(label1Text);
429+
expect(fabricLabels[1].text.text).toEqual(label2Text);
430+
// sort the canvas text objects because their order is not guaranteed to be in the same order
431+
// we added them
432+
canvasTextObjects.sort(sortByTextField);
433+
expect(canvasTextObjects.length).toEqual(2);
434+
expect(canvasTextObjects[0].text).toMatch('Label 1');
435+
expect(canvasTextObjects[1].text).toMatch('Label 2');
436+
});
437+
}
438+
439+
function addLabelToCanvas() {
440+
it('should add label to canvas', () => {
441+
const canvas: any = createCanvas();
442+
const label: any = createFabricLabel();
443+
const enableCircles: boolean = true;
444+
service.addLabelToCanvas(canvas, label, enableCircles);
445+
const canvasTextObjects = getCanvasTextObjects(canvas);
446+
expect(canvasTextObjects.length).toEqual(1);
447+
expect(canvasTextObjects[0].text).toMatch(label1Text);
448+
});
449+
}
450+
451+
function getCanvasTextObjects(canvas: any): any[] {
452+
return canvas.getObjects().filter((obj: any) => {
453+
return typeof obj.text === 'string';
454+
});
455+
}
456+
457+
function sortByTextField(a: any, b: any): number {
458+
return a.text.localeCompare(b.text);
459+
}
460+
461+
function createLabelServiceFunction() {
462+
it('shoud create a label', () => {
463+
const label: any = createFabricLabel();
464+
expect(label.circle).not.toBeNull();
465+
expect(label.line).not.toBeNull();
466+
expect(label.text).not.toBeNull();
467+
expect(label.text.text).toEqual(label1Text);
468+
expect(label.canEdit).toEqual(canEditBoolean);
469+
expect(label.canDelete).toEqual(canDeleteBoolean);
470+
});
471+
}
472+
473+
function makeSureValueIsWithinLimit() {
474+
const limit: number = 100;
475+
it('should make sure value is within limit when it is negative', () => {
476+
expectMakeSureValueIsWithinLimit(-1, limit, 0);
477+
});
478+
it('should make sure value is within limit when it is between zero and limit', () => {
479+
expectMakeSureValueIsWithinLimit(50, limit, 50);
480+
});
481+
it('should make sure value is within limit when it is greater than limit', () => {
482+
expectMakeSureValueIsWithinLimit(101, limit, 100);
483+
});
484+
}
485+
486+
function expectMakeSureValueIsWithinLimit(x: number, width: number, expectedValue: number) {
487+
expect(service.makeSureValueIsWithinLimit(x, width)).toEqual(expectedValue);
488+
}

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
@@ -62,6 +62,7 @@ import { AnimationAuthoring } from '../../../wise5/components/animation/animatio
6262
import { OpenResponseGrading } from '../../../wise5/components/openResponse/open-response-grading/open-response-grading.component';
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';
65+
import { LabelGrading } from '../../../wise5/components/label/label-grading/label-grading.component';
6566

6667
@NgModule({
6768
declarations: [
@@ -89,6 +90,7 @@ import { MatchGrading } from '../../../wise5/components/match/match-grading/matc
8990
GraphAuthoring,
9091
HtmlAuthoring,
9192
LabelAuthoring,
93+
LabelGrading,
9294
ManageStudentsComponent,
9395
MatchAuthoring,
9496
MatchGrading,

src/main/webapp/site/src/messages.xlf

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8196,6 +8196,39 @@
81968196
<context context-type="linenumber">213</context>
81978197
</context-group>
81988198
</trans-unit>
8199+
<trans-unit datatype="html" id="f80d8048e1a73a4f0c35681cc5f8a250754eaf4b">
8200+
<source> You have used <x equiv-text="{{componentState.studentData.submitCounter}}" id="INTERPOLATION"/> of <x equiv-text="{{componentContent.maxSubmitCount}}" id="INTERPOLATION_1"/> attempt(s) </source>
8201+
<context-group purpose="location">
8202+
<context context-type="sourcefile">../../wise5/components/match/match-grading/match-grading.component.html</context>
8203+
<context context-type="linenumber">103</context>
8204+
</context-group>
8205+
<context-group purpose="location">
8206+
<context context-type="sourcefile">../../wise5/components/multipleChoice/multiple-choice-grading/multiple-choice-grading.component.html</context>
8207+
<context context-type="linenumber">38</context>
8208+
</context-group>
8209+
</trans-unit>
8210+
<trans-unit datatype="html" id="00a48b9fab48a5ccc0ebf0a2793495ee1cc9f968">
8211+
<source> Correct </source>
8212+
<context-group purpose="location">
8213+
<context context-type="sourcefile">../../wise5/components/match/match-grading/match-grading.component.html</context>
8214+
<context context-type="linenumber">108</context>
8215+
</context-group>
8216+
<context-group purpose="location">
8217+
<context context-type="sourcefile">../../wise5/components/multipleChoice/multiple-choice-grading/multiple-choice-grading.component.html</context>
8218+
<context context-type="linenumber">43</context>
8219+
</context-group>
8220+
</trans-unit>
8221+
<trans-unit datatype="html" id="49a3371af0eb58f02e541105eb395340048527ec">
8222+
<source> Incorrect </source>
8223+
<context-group purpose="location">
8224+
<context context-type="sourcefile">../../wise5/components/match/match-grading/match-grading.component.html</context>
8225+
<context context-type="linenumber">113</context>
8226+
</context-group>
8227+
<context-group purpose="location">
8228+
<context context-type="sourcefile">../../wise5/components/multipleChoice/multiple-choice-grading/multiple-choice-grading.component.html</context>
8229+
<context context-type="linenumber">48</context>
8230+
</context-group>
8231+
</trans-unit>
81998232
<trans-unit datatype="html" id="e9f75e02d7db72cd425f81c273a721c62a617dc4">
82008233
<source>~ Report Available ~</source>
82018234
<context-group purpose="location">
@@ -8259,27 +8292,6 @@
82598292
<context context-type="linenumber">90</context>
82608293
</context-group>
82618294
</trans-unit>
8262-
<trans-unit datatype="html" id="f80d8048e1a73a4f0c35681cc5f8a250754eaf4b">
8263-
<source> You have used <x equiv-text="{{componentState.studentData.submitCounter}}" id="INTERPOLATION"/> of <x equiv-text="{{componentContent.maxSubmitCount}}" id="INTERPOLATION_1"/> attempt(s) </source>
8264-
<context-group purpose="location">
8265-
<context context-type="sourcefile">../../wise5/components/multipleChoice/multiple-choice-grading/multiple-choice-grading.component.html</context>
8266-
<context context-type="linenumber">38</context>
8267-
</context-group>
8268-
</trans-unit>
8269-
<trans-unit datatype="html" id="00a48b9fab48a5ccc0ebf0a2793495ee1cc9f968">
8270-
<source> Correct </source>
8271-
<context-group purpose="location">
8272-
<context context-type="sourcefile">../../wise5/components/multipleChoice/multiple-choice-grading/multiple-choice-grading.component.html</context>
8273-
<context context-type="linenumber">43</context>
8274-
</context-group>
8275-
</trans-unit>
8276-
<trans-unit datatype="html" id="49a3371af0eb58f02e541105eb395340048527ec">
8277-
<source> Incorrect </source>
8278-
<context-group purpose="location">
8279-
<context context-type="sourcefile">../../wise5/components/multipleChoice/multiple-choice-grading/multiple-choice-grading.component.html</context>
8280-
<context context-type="linenumber">48</context>
8281-
</context-group>
8282-
</trans-unit>
82838295
<trans-unit datatype="html" id="6817513ddcee06a7cb2a7b2708e5616b861db81c">
82848296
<source><x equiv-text="{{nodeCompletion}}" id="INTERPOLATION"/>% completed (All periods)</source>
82858297
<context-group purpose="location">

src/main/webapp/wise5/classroomMonitor/classroomMonitorComponents/shared/component-grading.component.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ export abstract class ComponentGrading {
1212
@Input()
1313
componentState: any;
1414

15+
@Input()
16+
isRevision: any = false;
17+
1518
componentContent: any;
1619

1720
constructor(protected ProjectService: ProjectService) {}
@@ -22,5 +25,6 @@ export abstract class ComponentGrading {
2225
this.nodeId,
2326
this.componentId
2427
);
28+
this.isRevision = this.isRevision === 'true';
2529
}
2630
}

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="Match|MultipleChoice|OpenResponse" ng-switch-when-separator="|" class="component__content" layout="row" layout-wrap>
161+
<div ng-switch-when="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+
<label-grading
164+
ng-if="item.componentState.componentType === 'Label'"
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+
</label-grading>
163171
<match-grading
164172
ng-if="item.componentState.componentType === 'Match'"
165173
node-id="{{::$ctrl.nodeId}}"

0 commit comments

Comments
 (0)