auto_awesome
diff --git a/src/assets/wise5/components/dialogGuidance/detected-ideas/detected-ideas.component.ts b/src/assets/wise5/components/dialogGuidance/detected-ideas/detected-ideas.component.ts
index 2889495445e..10c83930c1d 100644
--- a/src/assets/wise5/components/dialogGuidance/detected-ideas/detected-ideas.component.ts
+++ b/src/assets/wise5/components/dialogGuidance/detected-ideas/detected-ideas.component.ts
@@ -1,15 +1,17 @@
import { Component, Input } from '@angular/core';
+import { CommonModule } from '@angular/common';
import { CRaterRubric, getUniqueIdeas } from '../../common/cRater/CRaterRubric';
import { CRaterIdea } from '../../common/cRater/CRaterIdea';
import { MatIconModule } from '@angular/material/icon';
@Component({
- imports: [MatIconModule],
+ imports: [CommonModule, MatIconModule],
selector: 'detected-ideas',
styleUrl: './detected-ideas.component.scss',
templateUrl: './detected-ideas.component.html'
})
export class DetectedIdeasComponent {
+ @Input() alignEnd: boolean = false;
@Input() cRaterRubric: CRaterRubric;
protected ideas: CRaterIdea[];
@Input() responses: any;
diff --git a/src/assets/wise5/components/dialogGuidance/dialog-responses/dialog-responses.component.html b/src/assets/wise5/components/dialogGuidance/dialog-responses/dialog-responses.component.html
index 4e70be940b2..3a9cc090655 100644
--- a/src/assets/wise5/components/dialogGuidance/dialog-responses/dialog-responses.component.html
+++ b/src/assets/wise5/components/dialogGuidance/dialog-responses/dialog-responses.component.html
@@ -1,17 +1,11 @@
-@if (showDetectedIdeas && hasRubricData) {
-
-
auto_awesome Detectable ideas
+@if (showDetectedIdeas) {
+
+
}
@for (response of responses; track response.timestamp) {
@if (response.user === 'Computer' && showDetectedIdeas && cRaterRubric.ideas.length) {
-
+
}
}
diff --git a/src/assets/wise5/components/dialogGuidance/dialog-responses/dialog-responses.component.ts b/src/assets/wise5/components/dialogGuidance/dialog-responses/dialog-responses.component.ts
index ba694fa1b70..34ccc9caedd 100644
--- a/src/assets/wise5/components/dialogGuidance/dialog-responses/dialog-responses.component.ts
+++ b/src/assets/wise5/components/dialogGuidance/dialog-responses/dialog-responses.component.ts
@@ -1,16 +1,19 @@
import { Component, Input } from '@angular/core';
import { ComputerAvatar } from '../../../common/computer-avatar/ComputerAvatar';
import { CRaterRubric } from '../../common/cRater/CRaterRubric';
-import { CRaterRubricComponent } from '../../common/cRater/crater-rubric/crater-rubric.component';
import { DetectedIdeasComponent } from '../detected-ideas/detected-ideas.component';
import { DialogResponse } from '../DialogResponse';
import { DialogResponseComponent } from '../dialog-response/dialog-response.component';
-import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon';
-import { RubricEventService } from '../../common/cRater/crater-rubric/RubricEventService';
+import { ShowCRaterRubricComponent } from '../../../../../app/classroom-monitor/show-crater-rubric/show-crater-rubric.component';
@Component({
- imports: [DetectedIdeasComponent, DialogResponseComponent, MatIconModule],
+ imports: [
+ DetectedIdeasComponent,
+ DialogResponseComponent,
+ MatIconModule,
+ ShowCRaterRubricComponent
+ ],
selector: 'dialog-responses',
styleUrl: './dialog-responses.component.scss',
templateUrl: './dialog-responses.component.html'
@@ -18,36 +21,7 @@ import { RubricEventService } from '../../common/cRater/crater-rubric/RubricEven
export class DialogResponsesComponent {
@Input() computerAvatar: ComputerAvatar;
@Input() cRaterRubric: CRaterRubric;
- protected hasRubricData: boolean;
@Input() isWaitingForComputerResponse: boolean;
@Input() responses: DialogResponse[] = [];
- private rubricDialog: MatDialogRef
;
@Input() showDetectedIdeas: boolean = false;
-
- constructor(
- protected dialog: MatDialog,
- protected rubricEventService: RubricEventService
- ) {}
-
- ngOnInit(): void {
- this.hasRubricData = this.cRaterRubric?.hasRubricData() ?? false;
- }
-
- ngOnDestroy(): void {
- if (this.rubricEventService.getIsRubricOpen()) {
- this.rubricDialog.close();
- }
- }
-
- protected openIdeasRubric(): void {
- if (!this.rubricEventService.getIsRubricOpen()) {
- this.rubricDialog = this.dialog.open(CRaterRubricComponent, {
- panelClass: 'dialog-sm',
- position: { right: '0', bottom: '0' },
- hasBackdrop: false,
- data: this.cRaterRubric,
- autoFocus: false
- });
- }
- }
}
diff --git a/src/assets/wise5/components/openResponse/open-response-show-work/open-response-show-work.component.html b/src/assets/wise5/components/openResponse/open-response-show-work/open-response-show-work.component.html
index 7f0786e7712..6bbffd2fc1b 100644
--- a/src/assets/wise5/components/openResponse/open-response-show-work/open-response-show-work.component.html
+++ b/src/assets/wise5/components/openResponse/open-response-show-work/open-response-show-work.component.html
@@ -1,3 +1,8 @@
+@if (showDetectedIdeas) {
+
+
+
+}
@for (audioAttachment of audioAttachments; track audioAttachment) {
@@ -11,3 +16,10 @@
}
+@if (showDetectedIdeas) {
+
+}
diff --git a/src/assets/wise5/components/openResponse/open-response-show-work/open-response-show-work.component.spec.ts b/src/assets/wise5/components/openResponse/open-response-show-work/open-response-show-work.component.spec.ts
new file mode 100644
index 00000000000..7d3f9841c33
--- /dev/null
+++ b/src/assets/wise5/components/openResponse/open-response-show-work/open-response-show-work.component.spec.ts
@@ -0,0 +1,106 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { StudentTeacherCommonServicesModule } from '../../../../../app/student-teacher-common-services.module';
+import { OpenResponseShowWorkComponent } from './open-response-show-work.component';
+import { AnnotationService } from '../../../services/annotationService';
+import { UserService } from '../../../../../app/services/user.service';
+import { ProjectService } from '../../../services/projectService';
+import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
+
+describe('OpenResponseShowWorkComponent', () => {
+ let component: OpenResponseShowWorkComponent;
+ let fixture: ComponentFixture;
+ let annotationService: AnnotationService;
+ let userService: UserService;
+ let projectService: ProjectService;
+ const mockComponentState = {
+ id: 1,
+ studentData: {
+ response: 'Student answer',
+ attachments: [
+ { type: 'audio', url: 'audio1.mp3' },
+ { type: 'audio', url: 'audio2.mp3' },
+ { type: 'image', url: 'image1.png' },
+ { type: 'file', url: 'document.pdf' }
+ ]
+ }
+ };
+ const mockCRaterAnnotation = {
+ id: 1,
+ type: 'autoScore',
+ data: {
+ ideas: [{ name: 'idea1', detected: true }]
+ },
+ studentWorkId: 1
+ };
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [OpenResponseShowWorkComponent, StudentTeacherCommonServicesModule],
+ providers: [
+ { provide: UserService, useValue: { isTeacher() {} } },
+ provideHttpClient(withInterceptorsFromDi())
+ ]
+ }).compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OpenResponseShowWorkComponent);
+ component = fixture.componentInstance;
+ annotationService = TestBed.inject(AnnotationService);
+ userService = TestBed.inject(UserService);
+ projectService = TestBed.inject(ProjectService);
+ component.componentState = mockComponentState;
+ component.nodeId = 'node1';
+ component.componentId = 'component1';
+ spyOn(projectService, 'getComponent').and.returnValue({
+ id: 'component1',
+ type: 'OpenResponse',
+ cRater: {
+ rubric: {
+ ideas: [{ name: 'idea1' }]
+ }
+ }
+ } as any);
+ spyOn(projectService, 'injectAssetPaths').and.callFake((arg) => arg);
+ });
+
+ it('should create', () => {
+ fixture.detectChanges();
+ expect(component).toBeTruthy();
+ });
+
+ describe('ngOnInit', () => {
+ it('should initialize student response and process attachments', () => {
+ spyOn(annotationService, 'getAnnotationsByStudentWorkId').and.returnValue([]);
+ fixture.detectChanges();
+ expect(component['studentResponse']).toBe('Student answer');
+ expect(component['audioAttachments'].length).toBe(2);
+ expect(component['otherAttachments'].length).toBe(2);
+ });
+
+ it('should set up CRater rubric and annotations when CRater is configured', () => {
+ spyOn(annotationService, 'getAnnotationsByStudentWorkId').and.returnValue([
+ mockCRaterAnnotation
+ ] as any);
+ spyOn(userService, 'isTeacher').and.returnValue(true);
+ fixture.detectChanges();
+ expect(annotationService.getAnnotationsByStudentWorkId).toHaveBeenCalledWith(1);
+ });
+
+ it('should show detected ideas when user is teacher and CRater annotation exists', () => {
+ spyOn(annotationService, 'getAnnotationsByStudentWorkId').and.returnValue([
+ mockCRaterAnnotation
+ ] as any);
+ spyOn(userService, 'isTeacher').and.returnValue(true);
+ fixture.detectChanges();
+ expect(component['showDetectedIdeas']).toBe(true);
+ });
+
+ it('should not show detected ideas when user is not a teacher', () => {
+ spyOn(annotationService, 'getAnnotationsByStudentWorkId').and.returnValue([]);
+ spyOn(userService, 'isTeacher').and.returnValue(false);
+ fixture.detectChanges();
+ expect(component['showDetectedIdeas']).toBe(false);
+ });
+ });
+});
diff --git a/src/assets/wise5/components/openResponse/open-response-show-work/open-response-show-work.component.ts b/src/assets/wise5/components/openResponse/open-response-show-work/open-response-show-work.component.ts
index eda21f04977..882fabf2256 100644
--- a/src/assets/wise5/components/openResponse/open-response-show-work/open-response-show-work.component.ts
+++ b/src/assets/wise5/components/openResponse/open-response-show-work/open-response-show-work.component.ts
@@ -1,20 +1,53 @@
-import { Component } from '@angular/core';
+import { Component, Input } from '@angular/core';
import { ComponentShowWorkDirective } from '../../component-show-work.directive';
import { CommonModule } from '@angular/common';
+import { CRaterRubric } from '../../common/cRater/CRaterRubric';
+import { DetectedIdeasComponent } from '../../dialogGuidance/detected-ideas/detected-ideas.component';
+import { NodeService } from '../../../services/nodeService';
+import { ProjectService } from '../../../services/projectService';
+import { AnnotationService } from '../../../services/annotationService';
+import { Annotation } from '../../../common/Annotation';
+import { ShowCRaterRubricComponent } from '../../../../../app/classroom-monitor/show-crater-rubric/show-crater-rubric.component';
+import { UserService } from '../../../../../app/services/user.service';
@Component({
- imports: [CommonModule],
+ imports: [CommonModule, DetectedIdeasComponent, ShowCRaterRubricComponent],
selector: 'open-response-show-work',
templateUrl: 'open-response-show-work.component.html'
})
export class OpenResponseShowWorkComponent extends ComponentShowWorkDirective {
+ private annotations: Annotation[] = [];
protected audioAttachments: any[] = [];
+ private cRaterAnnotation: Annotation;
+ protected cRaterRubric: CRaterRubric;
protected otherAttachments: any[] = [];
+ protected showDetectedIdeas: boolean = false;
protected studentResponse: string = '';
+ constructor(
+ private annotationService: AnnotationService,
+ nodeService: NodeService,
+ projectService: ProjectService,
+ protected userService: UserService
+ ) {
+ super(nodeService, projectService);
+ }
+
ngOnInit(): void {
if (this.componentState != null && this.componentState !== '') {
this.studentResponse = this.componentState.studentData.response;
+ this.componentContent = this.projectService.getComponent(this.nodeId, this.componentId);
+ if (this.componentContent.cRater) {
+ this.cRaterRubric = new CRaterRubric(this.componentContent.cRater.rubric);
+ this.annotations = this.annotationService.getAnnotationsByStudentWorkId(
+ this.componentState.id
+ );
+ this.cRaterAnnotation = this.annotations.find((annotation) => annotation.type === 'autoScore' && annotation.data.ideas);
+ }
+ this.showDetectedIdeas =
+ this.userService.isTeacher() &&
+ this.cRaterRubric?.ideas.length &&
+ this.cRaterAnnotation != null;
this.processAttachments();
}
}
diff --git a/src/assets/wise5/components/showMyWork/show-my-work-grading/show-my-work-grading.component.spec.ts b/src/assets/wise5/components/showMyWork/show-my-work-grading/show-my-work-grading.component.spec.ts
index 73137c2bc5b..e83b84dcc14 100644
--- a/src/assets/wise5/components/showMyWork/show-my-work-grading/show-my-work-grading.component.spec.ts
+++ b/src/assets/wise5/components/showMyWork/show-my-work-grading/show-my-work-grading.component.spec.ts
@@ -5,6 +5,8 @@ import { ProjectService } from '../../../services/projectService';
import { MockComponent, MockProviders } from 'ng-mocks';
import { OpenResponseShowWorkComponent } from '../../openResponse/open-response-show-work/open-response-show-work.component';
import { NodeService } from '../../../services/nodeService';
+import { AnnotationService } from '../../../services/annotationService';
+import { UserService } from '../../../../../app/services/user.service';
let component: ShowMyWorkGradingComponent;
const componentId: string = 'component1';
@@ -17,7 +19,15 @@ describe('ShowMyWorkGradingComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ShowMyWorkGradingComponent, MockComponent(OpenResponseShowWorkComponent)],
- providers: [MockProviders(TeacherDataService, ProjectService, NodeService)]
+ providers: [
+ MockProviders(
+ AnnotationService,
+ NodeService,
+ ProjectService,
+ TeacherDataService,
+ UserService
+ )
+ ]
});
projectService = TestBed.inject(ProjectService);
spyOn(projectService, 'getComponent').and.returnValue({
diff --git a/src/assets/wise5/components/showWork/show-work-student/show-work-student.component.spec.ts b/src/assets/wise5/components/showWork/show-work-student/show-work-student.component.spec.ts
index 5650a4cee47..6b8d8bbfc9c 100644
--- a/src/assets/wise5/components/showWork/show-work-student/show-work-student.component.spec.ts
+++ b/src/assets/wise5/components/showWork/show-work-student/show-work-student.component.spec.ts
@@ -4,6 +4,9 @@ import { MockComponent, MockProviders } from 'ng-mocks';
import { OpenResponseShowWorkComponent } from '../../openResponse/open-response-show-work/open-response-show-work.component';
import { NodeService } from '../../../services/nodeService';
import { ProjectService } from '../../../services/projectService';
+import { AnnotationService } from '../../../services/annotationService';
+import { ConfigService } from '../../../../../app/services/config.service';
+import { UserService } from '../../../../../app/services/user.service';
describe('ShowWorkStudentComponent', () => {
let component: ShowWorkStudentComponent;
@@ -12,7 +15,9 @@ describe('ShowWorkStudentComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [MockComponent(OpenResponseShowWorkComponent), ShowWorkStudentComponent],
- providers: [MockProviders(NodeService, ProjectService)]
+ providers: [
+ MockProviders(AnnotationService, ConfigService, NodeService, ProjectService, UserService)
+ ]
}).compileComponents();
});
diff --git a/src/assets/wise5/directives/teacher-summary-display/ideas-summary-display/ideas-summary.component.ts b/src/assets/wise5/directives/teacher-summary-display/ideas-summary-display/ideas-summary.component.ts
index ce2f993d5f0..0e1369b477d 100644
--- a/src/assets/wise5/directives/teacher-summary-display/ideas-summary-display/ideas-summary.component.ts
+++ b/src/assets/wise5/directives/teacher-summary-display/ideas-summary-display/ideas-summary.component.ts
@@ -66,11 +66,7 @@ export class IdeasSummaryComponent extends TeacherSummaryDisplayComponent {
}
ngOnInit(): void {
- this.ideaDescriptions = this.cRaterService.getCRaterRubric(
- this.nodeId,
- this.componentId,
- this.componentType
- );
+ this.ideaDescriptions = this.cRaterService.getCRaterRubric(this.nodeId, this.componentId);
this.generateIdeasSummary();
}
diff --git a/src/assets/wise5/services/cRaterService.ts b/src/assets/wise5/services/cRaterService.ts
index cda0e800f89..d244c9fe8e4 100644
--- a/src/assets/wise5/services/cRaterService.ts
+++ b/src/assets/wise5/services/cRaterService.ts
@@ -260,10 +260,10 @@ export class CRaterService {
return ideas;
}
- getCRaterRubric(nodeId: string, componentId: string, componentType?: string): CRaterRubric {
+ getCRaterRubric(nodeId: string, componentId: string): CRaterRubric {
const componentContent = this.projectService.getComponent(nodeId, componentId);
let rubricContent;
- if (componentType === 'OpenResponse') {
+ if (componentContent.type === 'OpenResponse') {
rubricContent = (componentContent as OpenResponseContent).cRater?.rubric;
} else {
rubricContent = componentContent.cRaterRubric;
diff --git a/src/messages.xlf b/src/messages.xlf
index 57fb072b317..80d53987af0 100644
--- a/src/messages.xlf
+++ b/src/messages.xlf
@@ -2050,6 +2050,13 @@ Click "Cancel" to keep the invalid JSON open so you can fix it.54,55
+
+ Detectable ideas
+
+ src/app/classroom-monitor/show-crater-rubric/show-crater-rubric.component.html
+ 8,12
+
+
Has new alert(s)
@@ -17945,13 +17952,6 @@ Category Name:
7,9
-
- Detectable ideas
-
- src/assets/wise5/components/dialogGuidance/dialog-responses/dialog-responses.component.html
- 8,12
-
-
Use Global Computer Avatar