diff --git a/package-lock.json b/package-lock.json index 75ec5fab57..6d53a740ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "wise", - "version": "5.18.3", + "version": "5.18.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 6f244ac2bc..23d097c2a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wise", - "version": "5.18.3", + "version": "5.18.4", "description": "Web-based Inquiry Science Environment", "main": "app.js", "browserslist": [ diff --git a/pom.xml b/pom.xml index 18bf86b28d..aacbbc7e07 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ wise war Web-based Inquiry Science Environment - 5.18.3 + 5.18.4 http://wise5.org diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/user/UserAPIController.java b/src/main/java/org/wise/portal/presentation/web/controllers/user/UserAPIController.java index 50c9eeb233..633d4ace40 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/user/UserAPIController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/user/UserAPIController.java @@ -133,6 +133,7 @@ protected HashMap getConfig(HttpServletRequest request) { config.put("isGoogleClassroomEnabled", isGoogleClassroomEnabled()); config.put("logOutURL", contextPath + "/logout"); config.put("recaptchaPublicKey", appProperties.get("recaptcha_public_key")); + config.put("wiseHostname", appProperties.get("wise.hostname")); config.put("wise4Hostname", appProperties.get("wise4.hostname")); return config; } diff --git a/src/main/resources/version.txt b/src/main/resources/version.txt index 716cd660e0..e4df8b80ba 100644 --- a/src/main/resources/version.txt +++ b/src/main/resources/version.txt @@ -1 +1 @@ -5.18.3 +5.18.4 diff --git a/src/main/webapp/site/src/app/common-hybrid-angular.module.ts b/src/main/webapp/site/src/app/common-hybrid-angular.module.ts index 4faae0ac9c..6f79f3ff09 100644 --- a/src/main/webapp/site/src/app/common-hybrid-angular.module.ts +++ b/src/main/webapp/site/src/app/common-hybrid-angular.module.ts @@ -49,6 +49,7 @@ import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatSelectModule } from '@angular/material/select'; import { HelpIconComponent } from '../../../wise5/themes/default/themeComponents/helpIcon/help-icon.component'; import { NodeStatusIcon } from '../../../wise5/themes/default/themeComponents/nodeStatusIcon/node-status-icon.component'; +import { MomentModule } from 'ngx-moment'; @Component({template: ``}) export class EmptyComponent {} @@ -75,6 +76,7 @@ export class EmptyComponent {} MatListModule, MatSelectModule, MatTooltipModule, + MomentModule, ReactiveFormsModule, RouterModule.forChild([ {path: '**', component: EmptyComponent} @@ -127,6 +129,7 @@ export class EmptyComponent {} MatListModule, MatSelectModule, MatTooltipModule, + MomentModule, NodeIconComponent, ReactiveFormsModule ] diff --git a/src/main/webapp/site/src/app/domain/config.ts b/src/main/webapp/site/src/app/domain/config.ts index 0e982145d4..d22e021b6e 100644 --- a/src/main/webapp/site/src/app/domain/config.ts +++ b/src/main/webapp/site/src/app/domain/config.ts @@ -6,5 +6,6 @@ export class Config { recaptchaPublicKey?: string; logOutURL: string; currentTime: number; + wiseHostname?: string; wise4Hostname?: string; } diff --git a/src/main/webapp/site/src/app/features/features.component.scss b/src/main/webapp/site/src/app/features/features.component.scss index ae98b61c8d..a507123603 100644 --- a/src/main/webapp/site/src/app/features/features.component.scss +++ b/src/main/webapp/site/src/app/features/features.component.scss @@ -115,7 +115,3 @@ margin-left: -16%; } } - -.mat-divider { - margin: 16px 0; -} diff --git a/src/main/webapp/site/src/app/modules/library/copy-project-dialog/copy-project-dialog.component.ts b/src/main/webapp/site/src/app/modules/library/copy-project-dialog/copy-project-dialog.component.ts index 3792d2f106..054eb89ccc 100644 --- a/src/main/webapp/site/src/app/modules/library/copy-project-dialog/copy-project-dialog.component.ts +++ b/src/main/webapp/site/src/app/modules/library/copy-project-dialog/copy-project-dialog.component.ts @@ -1,17 +1,18 @@ -import { Component, OnInit, Inject } from '@angular/core'; +import { Component, Inject } from '@angular/core'; import { LibraryProjectDetailsComponent } from "../library-project-details/library-project-details.component"; import { MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog'; import { finalize } from 'rxjs/operators'; import { LibraryProject } from "../libraryProject"; import { LibraryService } from "../../../services/library.service"; import { MatSnackBar } from '@angular/material/snack-bar'; +import { Subscription } from 'rxjs'; @Component({ selector: 'app-copy-project-dialog', templateUrl: './copy-project-dialog.component.html', styleUrls: ['./copy-project-dialog.component.scss'] }) -export class CopyProjectDialogComponent implements OnInit { +export class CopyProjectDialogComponent { isCopying: boolean = false; @@ -20,15 +21,11 @@ export class CopyProjectDialogComponent implements OnInit { @Inject(MAT_DIALOG_DATA) public data: any, private libraryService: LibraryService, private snackBar: MatSnackBar) { - this.libraryService.newProjectSource$.subscribe(() => { this.dialog.closeAll(); }); } - ngOnInit() { - } - copy() { this.isCopying = true; this.libraryService.copyProject(this.data.project.id) diff --git a/src/main/webapp/site/src/app/modules/library/library-project-menu/library-project-menu.component.ts b/src/main/webapp/site/src/app/modules/library/library-project-menu/library-project-menu.component.ts index 974f7ba9e6..9202ac757b 100644 --- a/src/main/webapp/site/src/app/modules/library/library-project-menu/library-project-menu.component.ts +++ b/src/main/webapp/site/src/app/modules/library/library-project-menu/library-project-menu.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Project } from '../../../domain/project'; import { TeacherService } from '../../../teacher/teacher.service'; @@ -13,7 +13,7 @@ import { EditRunWarningDialogComponent } from '../../../teacher/edit-run-warning templateUrl: './library-project-menu.component.html', styleUrls: ['./library-project-menu.component.scss'] }) -export class LibraryProjectMenuComponent implements OnInit { +export class LibraryProjectMenuComponent { @Input() project: Project; @@ -27,10 +27,10 @@ export class LibraryProjectMenuComponent implements OnInit { isChild: boolean = false; constructor( - public dialog: MatDialog, - public teacherService: TeacherService, - public userService: UserService, - public configService: ConfigService + private dialog: MatDialog, + private teacherService: TeacherService, + private userService: UserService, + private configService: ConfigService ) {} ngOnInit() { @@ -59,10 +59,7 @@ export class LibraryProjectMenuComponent implements OnInit { } copyProject() { - this.dialog.open(CopyProjectDialogComponent, { - data: { project: this.project }, - panelClass: 'mat-dialog--sm' - }); + this.teacherService.copyProject(this.project, this.dialog); } editProject() { diff --git a/src/main/webapp/site/src/app/modules/library/library/library.component.scss b/src/main/webapp/site/src/app/modules/library/library/library.component.scss index c1f220bb3a..52b3a10de8 100644 --- a/src/main/webapp/site/src/app/modules/library/library/library.component.scss +++ b/src/main/webapp/site/src/app/modules/library/library/library.component.scss @@ -17,6 +17,10 @@ margin-right: 8px; } } + + .mat-divider { + margin: 0; + } } .library__header { diff --git a/src/main/webapp/site/src/app/modules/library/personal-library/personal-library.component.ts b/src/main/webapp/site/src/app/modules/library/personal-library/personal-library.component.ts index 6976f57e54..110582080f 100644 --- a/src/main/webapp/site/src/app/modules/library/personal-library/personal-library.component.ts +++ b/src/main/webapp/site/src/app/modules/library/personal-library/personal-library.component.ts @@ -3,6 +3,7 @@ import { LibraryProject } from "../libraryProject"; import { LibraryService } from "../../../services/library.service"; import { LibraryComponent } from "../library/library.component"; import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { Subscription } from 'rxjs'; @Component({ selector: 'app-personal-library', @@ -15,20 +16,27 @@ export class PersonalLibraryComponent extends LibraryComponent { filteredProjects: LibraryProject[] = []; personalProjects: LibraryProject[] = []; sharedProjects: LibraryProject[] = []; + personalLibraryProjectsSourceSubscription: Subscription; + sharedLibraryProjectsSourceSubscription: Subscription; + newProjectSourceSubscription: Subscription; - constructor(libraryService: LibraryService, public dialog: MatDialog) { + constructor(libraryService: LibraryService, private dialog: MatDialog) { super(libraryService); this.libraryService = libraryService; + } - this.libraryService.personalLibraryProjectsSource$.subscribe((personalProjects: LibraryProject[]) => { + ngOnInit() { + this.personalLibraryProjectsSourceSubscription = + this.libraryService.personalLibraryProjectsSource$.subscribe((personalProjects: LibraryProject[]) => { this.personalProjects = personalProjects; this.updateProjects(); }); - this.libraryService.sharedLibraryProjectsSource$.subscribe((sharedProjects: LibraryProject[]) => { + this.sharedLibraryProjectsSourceSubscription = + this.libraryService.sharedLibraryProjectsSource$.subscribe((sharedProjects: LibraryProject[]) => { this.sharedProjects = sharedProjects; this.updateProjects(); }); - this.libraryService.newProjectSource$.subscribe(project => { + this.newProjectSourceSubscription = this.libraryService.newProjectSource$.subscribe(project => { if (project) { project.isHighlighted = true; this.projects.unshift(project); @@ -37,7 +45,10 @@ export class PersonalLibraryComponent extends LibraryComponent { }); } - ngOnInit() { + ngOnDestroy() { + this.personalLibraryProjectsSourceSubscription.unsubscribe(); + this.sharedLibraryProjectsSourceSubscription.unsubscribe(); + this.newProjectSourceSubscription.unsubscribe(); } combinePersonalAndSharedProjects() { diff --git a/src/main/webapp/site/src/app/modules/library/share-project-dialog/share-project-dialog.component.html b/src/main/webapp/site/src/app/modules/library/share-project-dialog/share-project-dialog.component.html index 3ef5b66779..3f260395fa 100644 --- a/src/main/webapp/site/src/app/modules/library/share-project-dialog/share-project-dialog.component.html +++ b/src/main/webapp/site/src/app/modules/library/share-project-dialog/share-project-dialog.component.html @@ -3,8 +3,11 @@

Share Unit

{{ project.name }} (Unit ID: {{ project.id }})

+

Sharing a curriculum unit allows other WISE teachers to use it with their own students and optionally edit the unit's content.

+

Shared units appear in a teacher's "My Units" library.

+ - Enter teacher username + Find a teacher search Team Sign In - + diff --git a/src/main/webapp/site/src/app/student/team-sign-in-dialog/team-sign-in-dialog.component.scss b/src/main/webapp/site/src/app/student/team-sign-in-dialog/team-sign-in-dialog.component.scss index a799c4a492..caa3b197f3 100644 --- a/src/main/webapp/site/src/app/student/team-sign-in-dialog/team-sign-in-dialog.component.scss +++ b/src/main/webapp/site/src/app/student/team-sign-in-dialog/team-sign-in-dialog.component.scss @@ -2,10 +2,6 @@ display: block !important; } -.mat-divider { - margin: 16px 0 16px; -} - .mat-form-field { display: block; } diff --git a/src/main/webapp/site/src/app/teacher-hybrid-angular.module.ts b/src/main/webapp/site/src/app/teacher-hybrid-angular.module.ts index c9a288d62a..d7024e7ef5 100644 --- a/src/main/webapp/site/src/app/teacher-hybrid-angular.module.ts +++ b/src/main/webapp/site/src/app/teacher-hybrid-angular.module.ts @@ -26,6 +26,7 @@ import { StatusIconComponent } from './classroom-monitor/status-icon/status-icon import { AngularJSModule } from './common-hybrid-angular.module'; import { NodeAdvancedJsonAuthoringComponent } from '../../../wise5/authoringTool/node/advanced/json/node-advanced-json-authoring.component'; import { WorkgroupInfoComponent } from '../../../wise5/classroomMonitor/classroomMonitorComponents/nodeGrading/workgroupInfo/workgroup-info.component'; +import { NodeAdvancedGeneralAuthoringComponent } from '../../../wise5/authoringTool/node/advanced/general/node-advanced-general-authoring.component'; @NgModule({ declarations: [ @@ -37,6 +38,7 @@ import { WorkgroupInfoComponent } from '../../../wise5/classroomMonitor/classroo ComponentNewWorkBadgeComponent, ManageStudentsComponent, MilestoneReportDataComponent, + NodeAdvancedGeneralAuthoringComponent, NodeAdvancedJsonAuthoringComponent, StatusIconComponent, WorkgroupInfoComponent, diff --git a/src/main/webapp/site/src/app/teacher/create-run-dialog/create-run-dialog.component.scss b/src/main/webapp/site/src/app/teacher/create-run-dialog/create-run-dialog.component.scss index fdf1067694..b254716669 100644 --- a/src/main/webapp/site/src/app/teacher/create-run-dialog/create-run-dialog.component.scss +++ b/src/main/webapp/site/src/app/teacher/create-run-dialog/create-run-dialog.component.scss @@ -1,7 +1,3 @@ -.mat-divider { - margin: 20px 0 16px; -} - .period-select { margin-right: 24px; } diff --git a/src/main/webapp/site/src/app/teacher/list-classroom-courses-dialog/list-classroom-courses-dialog.component.scss b/src/main/webapp/site/src/app/teacher/list-classroom-courses-dialog/list-classroom-courses-dialog.component.scss index f2afbb25af..d1b0584a65 100644 --- a/src/main/webapp/site/src/app/teacher/list-classroom-courses-dialog/list-classroom-courses-dialog.component.scss +++ b/src/main/webapp/site/src/app/teacher/list-classroom-courses-dialog/list-classroom-courses-dialog.component.scss @@ -4,10 +4,6 @@ '~style/abstracts/variables', '~style/abstracts/mixins'; -.mat-divider { - margin: 20px 0 16px; -} - h2 { .mat-icon { @include mat-icon-size(mat-font-size($config, display-1)); diff --git a/src/main/webapp/site/src/app/teacher/run-menu/run-menu.component.html b/src/main/webapp/site/src/app/teacher/run-menu/run-menu.component.html index ae8ba6dbb4..c889d8b443 100644 --- a/src/main/webapp/site/src/app/teacher/run-menu/run-menu.component.html +++ b/src/main/webapp/site/src/app/teacher/run-menu/run-menu.component.html @@ -18,13 +18,8 @@ Unit Info - share - Share - - - - Share to Google Classroom + supervised_user_circle + Share Access edit diff --git a/src/main/webapp/site/src/app/teacher/run-menu/run-menu.component.ts b/src/main/webapp/site/src/app/teacher/run-menu/run-menu.component.ts index 0643ae51b5..7b0414e8fb 100644 --- a/src/main/webapp/site/src/app/teacher/run-menu/run-menu.component.ts +++ b/src/main/webapp/site/src/app/teacher/run-menu/run-menu.component.ts @@ -8,7 +8,6 @@ import { TeacherRun } from '../teacher-run'; import { ConfigService } from '../../services/config.service'; import { RunSettingsDialogComponent } from '../run-settings-dialog/run-settings-dialog.component'; import { EditRunWarningDialogComponent } from '../edit-run-warning-dialog/edit-run-warning-dialog.component'; -import { ListClassroomCoursesDialogComponent } from '../list-classroom-courses-dialog/list-classroom-courses-dialog.component'; import { Router } from '@angular/router'; @Component({ @@ -45,36 +44,6 @@ export class RunMenuComponent implements OnInit { }); } - checkClassroomAuthorization() { - this.teacherService - .getClassroomAuthorizationUrl(this.userService.getUser().getValue().username) - .subscribe(({ authorizationUrl }) => { - if (authorizationUrl == null) { - this.getClassroomCourses(); - } else { - const authWindow = window.open(authorizationUrl, 'authorize', 'width=600,height=800'); - const timer = setInterval(() => { - if (authWindow.closed) { - clearInterval(timer); - this.checkClassroomAuthorization(); - } - }, 1000); - } - }); - } - - getClassroomCourses() { - this.teacherService - .getClassroomCourses(this.userService.getUser().getValue().username) - .subscribe(courses => { - const panelClass = courses.length ? 'mat-dialog--md' : ''; - this.dialog.open(ListClassroomCoursesDialogComponent, { - data: { run: this.run, courses }, - panelClass: panelClass - }); - }); - } - showUnitDetails() { const project = this.run.project; this.dialog.open(LibraryProjectDetailsComponent, { @@ -95,14 +64,6 @@ export class RunMenuComponent implements OnInit { return this.run.isOwner(this.userService.getUserId()); } - isGoogleUser() { - return this.userService.isGoogleUser(); - } - - isGoogleClassroomEnabled() { - return this.configService.isGoogleClassroomEnabled(); - } - isRunCompleted() { return this.run.isCompleted(this.configService.getCurrentServerTime()); } diff --git a/src/main/webapp/site/src/app/teacher/run-settings-dialog/run-settings-dialog.component.scss b/src/main/webapp/site/src/app/teacher/run-settings-dialog/run-settings-dialog.component.scss index 622f822f70..3e3b1ea891 100644 --- a/src/main/webapp/site/src/app/teacher/run-settings-dialog/run-settings-dialog.component.scss +++ b/src/main/webapp/site/src/app/teacher/run-settings-dialog/run-settings-dialog.component.scss @@ -1,7 +1,3 @@ -.mat-divider { - margin: 20px 0 16px; -} - .info-block { margin-bottom: 16px; padding: 4px; diff --git a/src/main/webapp/site/src/app/teacher/share-run-code-dialog/share-run-code-dialog.component.html b/src/main/webapp/site/src/app/teacher/share-run-code-dialog/share-run-code-dialog.component.html new file mode 100644 index 0000000000..6fad3ad93d --- /dev/null +++ b/src/main/webapp/site/src/app/teacher/share-run-code-dialog/share-run-code-dialog.component.html @@ -0,0 +1,45 @@ +

Share with Students

+ +
+

+ {{ run.project.name }} (Run ID: {{ run.id }}) +

+

+ Copy this link to share with your students:
+ +

+

+ Students with WISE accounts can also select Add Unit+ and type the Access Code:
+ +

+

+ Add as an assignment in Google Classroom:
+ +

+
+
+ + + diff --git a/src/main/webapp/site/src/app/teacher/share-run-code-dialog/share-run-code-dialog.component.scss b/src/main/webapp/site/src/app/teacher/share-run-code-dialog/share-run-code-dialog.component.scss new file mode 100644 index 0000000000..c325c00c53 --- /dev/null +++ b/src/main/webapp/site/src/app/teacher/share-run-code-dialog/share-run-code-dialog.component.scss @@ -0,0 +1,19 @@ +.share { + display: block; + text-align: center; +} + +.mat-raised-button, .mat-button { + text-transform: none; + white-space: normal; +} + +.mat-raised-button { + margin-top: 8px; + + img { + width: 32px; + margin-right: 8px; + padding: 4px 8px 4px 0; + } +} \ No newline at end of file diff --git a/src/main/webapp/site/src/app/teacher/share-run-code-dialog/share-run-code-dialog.component.spec.ts b/src/main/webapp/site/src/app/teacher/share-run-code-dialog/share-run-code-dialog.component.spec.ts new file mode 100644 index 0000000000..3dccdfb090 --- /dev/null +++ b/src/main/webapp/site/src/app/teacher/share-run-code-dialog/share-run-code-dialog.component.spec.ts @@ -0,0 +1,81 @@ +import { async, ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ShareRunCodeDialogComponent } from './share-run-code-dialog.component'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { MatDialogModule, MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog"; +import { MatSnackBarModule } from '@angular/material/snack-bar'; +import { NO_ERRORS_SCHEMA } from "@angular/core"; +import { ConfigService } from "../../services/config.service"; +import { TeacherService } from "../teacher.service"; +import { UserService } from "../../services/user.service"; +import { TeacherRun } from "../teacher-run"; +import { Project } from '../../domain/project'; + +const runObj = new TeacherRun(); +runObj.id = 1; +runObj.runCode = 'Dog123' +const project = new Project(); +project.id = 1; +project.name = "Photosynthesis"; +runObj.project = project; + +export class MockConfigService { + getWISEHostname(): string { + return 'http://localhost:8080'; + } + + getContextPath(): string { + return ''; + } + + isGoogleClassroomEnabled() { + return true; + } +} + +export class MockTeacherService { + +} + +export class MockUserService { + isGoogleUser() { + return true; + } +} + +describe('ShareRunCodeDialogComponent', () => { + let component: ShareRunCodeDialogComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ ShareRunCodeDialogComponent ], + imports: [ BrowserAnimationsModule, MatDialogModule, MatSnackBarModule ], + providers: [ + { provide: ConfigService, useClass: MockConfigService }, + { provide: TeacherService, useClass: MockTeacherService }, + { provide: UserService, useClass: MockUserService }, + { provide: MatDialogRef, useValue: {} }, + { provide: MAT_DIALOG_DATA, useValue: { run: runObj } }, + ], + schemas: [ NO_ERRORS_SCHEMA ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ShareRunCodeDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should show run info and sharing url', () => { + const compiled = fixture.debugElement.nativeElement; + expect(compiled.textContent).toContain('Photosynthesis (Run ID: 1)'); + const url = `http://localhost:8080/login?accessCode=${component.run.runCode}`; + expect(compiled.textContent).toContain(url); + }); +}); diff --git a/src/main/webapp/site/src/app/teacher/share-run-code-dialog/share-run-code-dialog.component.ts b/src/main/webapp/site/src/app/teacher/share-run-code-dialog/share-run-code-dialog.component.ts new file mode 100644 index 0000000000..f691f67e20 --- /dev/null +++ b/src/main/webapp/site/src/app/teacher/share-run-code-dialog/share-run-code-dialog.component.ts @@ -0,0 +1,77 @@ +import { Component, Inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef, MatDialog } from '@angular/material/dialog'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { ConfigService } from '../../services/config.service'; +import { UserService } from '../../services/user.service'; +import { TeacherRun } from '../teacher-run'; +import { TeacherService } from '../teacher.service'; +import { ListClassroomCoursesDialogComponent } from '../list-classroom-courses-dialog/list-classroom-courses-dialog.component'; + +@Component({ + selector: 'app-share-run-code-dialog', + templateUrl: './share-run-code-dialog.component.html', + styleUrls: ['./share-run-code-dialog.component.scss'] +}) +export class ShareRunCodeDialogComponent { + run: TeacherRun; + code: string; + link: string; + + constructor(private dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) private data: any, + private dialog: MatDialog, + private snackBar: MatSnackBar, + private teacherService: TeacherService, + private userService: UserService, + private configService: ConfigService) { + } + + ngOnInit() { + this.run = new TeacherRun(this.data.run); + this.code = this.run.runCode; + const host = this.configService.getWISEHostname() + this.configService.getContextPath(); + this.link = `${host}/login?accessCode=${this.code}`; + } + + copyMsg() { + this.snackBar.open($localize`Copied to clipboard.`); + } + + isGoogleUser() { + return this.userService.isGoogleUser(); + } + + isGoogleClassroomEnabled() { + return this.configService.isGoogleClassroomEnabled(); + } + + checkClassroomAuthorization() { + this.teacherService + .getClassroomAuthorizationUrl(this.userService.getUser().getValue().username) + .subscribe(({ authorizationUrl }) => { + if (authorizationUrl == null) { + this.getClassroomCourses(); + } else { + const authWindow = window.open(authorizationUrl, 'authorize', 'width=600,height=800'); + const timer = setInterval(() => { + if (authWindow.closed) { + clearInterval(timer); + this.checkClassroomAuthorization(); + } + }, 1000); + } + }); + } + + getClassroomCourses() { + this.teacherService + .getClassroomCourses(this.userService.getUser().getValue().username) + .subscribe(courses => { + const panelClass = courses.length ? 'mat-dialog--md' : ''; + this.dialog.open(ListClassroomCoursesDialogComponent, { + data: { run: this.run, courses }, + panelClass: panelClass + }); + }); + } +} diff --git a/src/main/webapp/site/src/app/teacher/share-run-dialog/share-run-dialog.component.html b/src/main/webapp/site/src/app/teacher/share-run-dialog/share-run-dialog.component.html index 50caa14ea4..a1335c2bdd 100644 --- a/src/main/webapp/site/src/app/teacher/share-run-dialog/share-run-dialog.component.html +++ b/src/main/webapp/site/src/app/teacher/share-run-dialog/share-run-dialog.component.html @@ -1,4 +1,4 @@ -

Share Classroom Unit

+

Share Classroom Access

Share Classroom Unit

{{ run.name }} (Run ID: {{ run.id }})

+ +

Sharing access allows other WISE teachers to view student work and optionally view student names, grade, manage teams, and edit unit content.

+

If you have customized the content in this unit and want to share so other teachers can use with their students, make a copy of the unit.

+ + - Enter teacher username + Find a teacher search { { provide: TeacherService, useClass: MockTeacherService }, { provide: MatDialogRef, useValue: {} }, { provide: MAT_DIALOG_DATA, useValue: { run: runObj } }, + { provide: MatDialog, useValue: { + closeAll: () => { + } + }}, { provide: UserService, useClass: MockUserService } ], schemas: [ NO_ERRORS_SCHEMA ] @@ -95,6 +99,7 @@ describe('ShareRunDialogComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(ShareRunDialogComponent); component = fixture.componentInstance; + component.dialog = TestBed.get(MatDialog); fixture.detectChanges(); }); diff --git a/src/main/webapp/site/src/app/teacher/share-run-dialog/share-run-dialog.component.ts b/src/main/webapp/site/src/app/teacher/share-run-dialog/share-run-dialog.component.ts index eaed297606..921a9999ca 100644 --- a/src/main/webapp/site/src/app/teacher/share-run-dialog/share-run-dialog.component.ts +++ b/src/main/webapp/site/src/app/teacher/share-run-dialog/share-run-dialog.component.ts @@ -1,6 +1,6 @@ import { Component, Inject } from '@angular/core'; import { TeacherService } from "../teacher.service"; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { MAT_DIALOG_DATA, MatDialogRef, MatDialog } from '@angular/material/dialog'; import { MatSnackBar } from '@angular/material/snack-bar'; import { MatTableDataSource } from "@angular/material/table"; import { ShareItemDialogComponent } from "../../modules/library/share-item-dialog/share-item-dialog.component"; @@ -28,7 +28,8 @@ export class ShareRunDialogComponent extends ShareItemDialogComponent { public teacherService: TeacherService, private userService: UserService, private utilService: UtilService, - public snackBar: MatSnackBar) { + public snackBar: MatSnackBar, + public dialog: MatDialog) { super(dialogRef, data, teacherService, snackBar); this.teacherService.getRun(this.data.run.id).subscribe((run: TeacherRun) => { this.run = new TeacherRun(run); @@ -182,4 +183,8 @@ export class ShareRunDialogComponent extends ShareItemDialogComponent { this.transferRunWarning = false; this.teacherSearchControl.setValue(''); } + + copyProject() { + this.teacherService.copyProject(this.project, this.dialog); + } } diff --git a/src/main/webapp/site/src/app/teacher/teacher-run-list-item/teacher-run-list-item.component.html b/src/main/webapp/site/src/app/teacher/teacher-run-list-item/teacher-run-list-item.component.html index e353343d85..90be4e46d0 100644 --- a/src/main/webapp/site/src/app/teacher/teacher-run-list-item/teacher-run-list-item.component.html +++ b/src/main/webapp/site/src/app/teacher/teacher-run-list-item/teacher-run-list-item.component.html @@ -28,7 +28,10 @@ -
Access Code: {{ run.runCode }}
+
+ Access Code: {{ run.runCode }} (Share with students) +
Shared by {{run.owner.firstName}} {{run.owner.lastName}}
diff --git a/src/main/webapp/site/src/app/teacher/teacher-run-list-item/teacher-run-list-item.component.spec.ts b/src/main/webapp/site/src/app/teacher/teacher-run-list-item/teacher-run-list-item.component.spec.ts index d6acd3fc2b..1ab2531602 100644 --- a/src/main/webapp/site/src/app/teacher/teacher-run-list-item/teacher-run-list-item.component.spec.ts +++ b/src/main/webapp/site/src/app/teacher/teacher-run-list-item/teacher-run-list-item.component.spec.ts @@ -6,6 +6,7 @@ import { TeacherRun } from "../teacher-run"; import { ConfigService } from "../../services/config.service"; import { NO_ERRORS_SCHEMA } from "@angular/core"; import { MomentModule } from "ngx-moment"; +import { MatDialogModule } from "@angular/material/dialog"; import { configureTestSuite } from 'ng-bullet'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { RouterTestingModule } from '@angular/router/testing'; @@ -33,7 +34,7 @@ describe('TeacherRunListItemComponent', () => { configureTestSuite(() => { TestBed.configureTestingModule({ declarations: [ TeacherRunListItemComponent ], - imports: [ MomentModule, BrowserAnimationsModule, RouterTestingModule ], + imports: [ MatDialogModule, MomentModule, BrowserAnimationsModule, RouterTestingModule ], providers: [ { provide: TeacherService, useClass: MockTeacherService }, { provide: ConfigService, useClass: MockConfigService } @@ -52,6 +53,7 @@ describe('TeacherRunListItemComponent', () => { run.endTime = new Date('2018-10-18T23:59:59.0').getTime(); run.numStudents = 30; run.periods = ['1', '2']; + run.runCode = 'Dog123' const project = new Project(); project.id = 1; project.name = "Photosynthesis"; @@ -68,5 +70,8 @@ describe('TeacherRunListItemComponent', () => { it('should show run info', () => { const compiled = fixture.debugElement.nativeElement; expect(compiled.textContent).toContain('Photosynthesis'); + expect(compiled.textContent).toContain('2 periods'); + expect(compiled.textContent).toContain('30 students'); + expect(compiled.textContent).toContain('Access Code: Dog123'); }); }); diff --git a/src/main/webapp/site/src/app/teacher/teacher-run-list-item/teacher-run-list-item.component.ts b/src/main/webapp/site/src/app/teacher/teacher-run-list-item/teacher-run-list-item.component.ts index 12332a8278..57f0177d6d 100644 --- a/src/main/webapp/site/src/app/teacher/teacher-run-list-item/teacher-run-list-item.component.ts +++ b/src/main/webapp/site/src/app/teacher/teacher-run-list-item/teacher-run-list-item.component.ts @@ -5,7 +5,8 @@ import { TeacherRun } from "../teacher-run"; import { ConfigService } from "../../services/config.service"; import { flash } from '../../animations'; import { Router } from '@angular/router'; - +import { MatDialog } from '@angular/material/dialog'; +import { ShareRunCodeDialogComponent } from '../share-run-code-dialog/share-run-code-dialog.component'; @Component({ selector: 'app-teacher-run-list-item', @@ -28,7 +29,8 @@ export class TeacherRunListItemComponent implements OnInit { constructor(private sanitizer: DomSanitizer, private configService: ConfigService, private router: Router, - private elRef: ElementRef) { + private elRef: ElementRef, + private dialog: MatDialog,) { this.sanitizer = sanitizer; } @@ -94,4 +96,11 @@ export class TeacherRunListItemComponent implements OnInit { isRunCompleted(run) { return run.isCompleted(this.configService.getCurrentServerTime()); } + + shareCode() { + this.dialog.open(ShareRunCodeDialogComponent, { + data: { run: this.run }, + panelClass: 'mat-dialog--sm' + }); + } } diff --git a/src/main/webapp/site/src/app/teacher/teacher.module.ts b/src/main/webapp/site/src/app/teacher/teacher.module.ts index b98c020540..cf56de3c28 100644 --- a/src/main/webapp/site/src/app/teacher/teacher.module.ts +++ b/src/main/webapp/site/src/app/teacher/teacher.module.ts @@ -26,6 +26,7 @@ import { MatSnackBarModule } from '@angular/material/snack-bar'; import { MatTableModule } from '@angular/material/table'; import { MatTabsModule } from '@angular/material/tabs'; import { MatTooltipModule } from '@angular/material/tooltip'; +import { ClipboardModule } from '@angular/cdk/clipboard'; import { RunMenuComponent } from './run-menu/run-menu.component'; import { CreateRunDialogComponent } from './create-run-dialog/create-run-dialog.component'; import { LibraryModule } from "../modules/library/library.module"; @@ -37,6 +38,7 @@ import { RunSettingsDialogComponent } from './run-settings-dialog/run-settings-d import { UseWithClassWarningDialogComponent } from './use-with-class-warning-dialog/use-with-class-warning-dialog.component'; import { EditRunWarningDialogComponent } from './edit-run-warning-dialog/edit-run-warning-dialog.component'; import { ListClassroomCoursesDialogComponent } from './list-classroom-courses-dialog/list-classroom-courses-dialog.component'; +import { ShareRunCodeDialogComponent } from './share-run-code-dialog/share-run-code-dialog.component'; const materialModules = [ MatAutocompleteModule, MatButtonModule, MatCardModule, MatCheckboxModule, @@ -54,7 +56,8 @@ const materialModules = [ MomentModule, SharedModule, TeacherRoutingModule, - TimelineModule + TimelineModule, + ClipboardModule ], declarations: [ CreateRunDialogComponent, @@ -69,7 +72,8 @@ const materialModules = [ EditProfileComponent, UseWithClassWarningDialogComponent, EditRunWarningDialogComponent, - ListClassroomCoursesDialogComponent + ListClassroomCoursesDialogComponent, + ShareRunCodeDialogComponent ], providers: [ AuthGuard diff --git a/src/main/webapp/site/src/app/teacher/teacher.service.spec.ts b/src/main/webapp/site/src/app/teacher/teacher.service.spec.ts index fae91a72b3..2bd812bd84 100644 --- a/src/main/webapp/site/src/app/teacher/teacher.service.spec.ts +++ b/src/main/webapp/site/src/app/teacher/teacher.service.spec.ts @@ -1,13 +1,17 @@ import { TestBed, inject } from '@angular/core/testing'; import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { HttpParams } from '@angular/common/http'; +import { MatDialog } from '@angular/material/dialog'; import { TeacherService } from './teacher.service'; describe('TeacherService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [ HttpClientTestingModule ], - providers: [ TeacherService ] + providers: [ + TeacherService, + { provide: MatDialog, useValue: {}} + ] }); }); diff --git a/src/main/webapp/site/src/app/teacher/teacher.service.ts b/src/main/webapp/site/src/app/teacher/teacher.service.ts index 7b96cde044..9e3409fc95 100644 --- a/src/main/webapp/site/src/app/teacher/teacher.service.ts +++ b/src/main/webapp/site/src/app/teacher/teacher.service.ts @@ -1,10 +1,12 @@ import { Injectable } from '@angular/core'; import { Observable, Subject } from 'rxjs'; import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; +import { MatDialog } from '@angular/material/dialog'; import { Project } from '../domain/project'; import { Teacher } from '../domain/teacher'; import { Run } from '../domain/run'; import { Course } from '../domain/course'; +import { CopyProjectDialogComponent } from '../modules/library/copy-project-dialog/copy-project-dialog.component'; @Injectable() export class TeacherService { @@ -41,6 +43,13 @@ export class TeacherService { constructor(private http: HttpClient) { } + copyProject(project: Project, dialog: MatDialog) { + dialog.open(CopyProjectDialogComponent, { + data: { project: project }, + panelClass: 'mat-dialog--sm' + }); + } + getRuns(): Observable { const headers = new HttpHeaders({ 'Cache-Control': 'no-cache' }); return this.http.get(this.runsUrl, { headers: headers }); diff --git a/src/main/webapp/site/src/assets/img/icons/google-classroom.svg b/src/main/webapp/site/src/assets/img/icons/google-classroom.svg index 8715120da9..541b7039b6 100644 --- a/src/main/webapp/site/src/assets/img/icons/google-classroom.svg +++ b/src/main/webapp/site/src/assets/img/icons/google-classroom.svg @@ -1,16 +1,28 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/site/src/messages-code.xlf b/src/main/webapp/site/src/messages-code.xlf index 1523829291..40563e0a3f 100644 --- a/src/main/webapp/site/src/messages-code.xlf +++ b/src/main/webapp/site/src/messages-code.xlf @@ -338,6 +338,9 @@ The JSON is invalid. Invalid JSON will not be saved.\nClick "OK" to revert back to the last valid JSON.\nClick "Cancel" to keep the invalid JSON open so you can fix it. + + Copied to clipboard. + \ No newline at end of file diff --git a/src/main/webapp/site/src/messages.xlf b/src/main/webapp/site/src/messages.xlf index 91e736e203..f725d63e46 100644 --- a/src/main/webapp/site/src/messages.xlf +++ b/src/main/webapp/site/src/messages.xlf @@ -218,11 +218,11 @@ app/modules/library/share-project-dialog/share-project-dialog.component.html - 19 + 22 app/teacher/share-run-dialog/share-run-dialog.component.html - 29 + 34 @@ -533,6 +533,10 @@ app/modules/library/personal-library/personal-library-details.html 9 + + app/teacher/share-run-code-dialog/share-run-code-dialog.component.html + 44 + WISE Terms of Use & Privacy Policy @@ -1039,6 +1043,89 @@ 8 + + Copy Unit + + app/modules/library/copy-project-dialog/copy-project-dialog.component.html + 1 + + + + (Unit ID: ) + + app/modules/library/copy-project-dialog/copy-project-dialog.component.html + 5 + + + + Copying creates a duplicate that will appear in “My Units”. You will be the owner and can edit the content and share the new unit with other WISE users. + + app/modules/library/copy-project-dialog/copy-project-dialog.component.html + 7 + + + + Cancel + + app/modules/library/copy-project-dialog/copy-project-dialog.component.html + 11 + + + app/teacher/list-classroom-courses-dialog/list-classroom-courses-dialog.component.html + 47 + + + app/teacher/create-run-dialog/create-run-dialog.component.html + 63 + + + app/teacher/use-with-class-warning-dialog/use-with-class-warning-dialog.component.html + 15 + + + app/teacher/edit-run-warning-dialog/edit-run-warning-dialog.component.html + 20 + + + app/student/add-project-dialog/add-project-dialog.component.html + 23 + + + app/student/team-sign-in-dialog/team-sign-in-dialog.component.html + 68 + + + app/teacher/share-run-dialog/share-run-dialog.component.html + 100 + + + app/authoring-tool/import-step/choose-import-step/choose-import-step.component.html + 62 + + + app/authoring-tool/import-step/choose-import-step-location/choose-import-step-location.component.html + 40 + + + app/authoring-tool/add-component/choose-new-component/choose-new-component.component.html + 23 + + + app/authoring-tool/add-component/choose-new-component-location/choose-new-component-location.component.html + 41 + + + + Copy + + app/modules/library/copy-project-dialog/copy-project-dialog.component.html + 17 + + + app/modules/library/library-project-menu/library-project-menu.component.html + 11 + + Share to Google Classroom @@ -1046,8 +1133,8 @@ 6 - app/teacher/run-menu/run-menu.component.html - 27 + app/teacher/share-run-code-dialog/share-run-code-dialog.component.html + 34 @@ -1124,57 +1211,6 @@ 39 - - Cancel - - app/teacher/list-classroom-courses-dialog/list-classroom-courses-dialog.component.html - 47 - - - app/teacher/create-run-dialog/create-run-dialog.component.html - 63 - - - app/teacher/use-with-class-warning-dialog/use-with-class-warning-dialog.component.html - 15 - - - app/modules/library/copy-project-dialog/copy-project-dialog.component.html - 11 - - - app/teacher/edit-run-warning-dialog/edit-run-warning-dialog.component.html - 20 - - - app/student/add-project-dialog/add-project-dialog.component.html - 23 - - - app/student/team-sign-in-dialog/team-sign-in-dialog.component.html - 68 - - - app/teacher/share-run-dialog/share-run-dialog.component.html - 95 - - - app/authoring-tool/import-step/choose-import-step/choose-import-step.component.html - 62 - - - app/authoring-tool/import-step/choose-import-step-location/choose-import-step-location.component.html - 40 - - - app/authoring-tool/add-component/choose-new-component/choose-new-component.component.html - 23 - - - app/authoring-tool/add-component/choose-new-component-location/choose-new-component-location.component.html - 41 - - Add @@ -1212,11 +1248,11 @@ app/modules/library/share-project-dialog/share-project-dialog.component.html - 67 + 70 app/teacher/share-run-dialog/share-run-dialog.component.html - 97 + 102 app/teacher/run-settings-dialog/run-settings-dialog.component.html @@ -1374,7 +1410,7 @@ app/teacher/teacher-run-list-item/teacher-run-list-item.component.html - 31 + 32 @@ -1466,7 +1502,7 @@ app/teacher/teacher-run-list-item/teacher-run-list-item.component.html - 52 + 55 @@ -1571,33 +1607,47 @@ 1 - - Enter teacher username + + Sharing a curriculum unit allows other WISE teachers to use it with their own students and optionally edit the unit's content. + + app/modules/library/share-project-dialog/share-project-dialog.component.html + 6 + + + + Shared units appear in a teacher's "My Units" library. app/modules/library/share-project-dialog/share-project-dialog.component.html 7 + + + Find a teacher + + app/modules/library/share-project-dialog/share-project-dialog.component.html + 10 + app/teacher/share-run-dialog/share-run-dialog.component.html - 17 + 22 Teacher is already on shared list. app/modules/library/share-project-dialog/share-project-dialog.component.html - 24 + 27 app/teacher/share-run-dialog/share-run-dialog.component.html - 35 + 40 Name app/modules/library/share-project-dialog/share-project-dialog.component.html - 34 + 37 app/contact/contact-form/contact-form.component.html @@ -1605,90 +1655,58 @@ app/teacher/share-run-dialog/share-run-dialog.component.html - 46 + 51 Revoke app/modules/library/share-project-dialog/share-project-dialog.component.html - 40 + 43 app/teacher/share-run-dialog/share-run-dialog.component.html - 52 + 57 Permissions app/modules/library/share-project-dialog/share-project-dialog.component.html - 45 + 48 app/teacher/share-run-dialog/share-run-dialog.component.html - 57 + 62 Owner. Full permissions. app/modules/library/share-project-dialog/share-project-dialog.component.html - 47 + 50 app/teacher/share-run-dialog/share-run-dialog.component.html - 59 + 64 View & Use with Students app/modules/library/share-project-dialog/share-project-dialog.component.html - 52 + 55 Edit Unit Content app/modules/library/share-project-dialog/share-project-dialog.component.html - 56 + 59 app/teacher/share-run-dialog/share-run-dialog.component.html - 76 - - - - Copy Unit - - app/modules/library/copy-project-dialog/copy-project-dialog.component.html - 1 - - - - (Unit ID: ) - - app/modules/library/copy-project-dialog/copy-project-dialog.component.html - 5 - - - - Copying creates a duplicate that will appear in “My Units”. You will be the owner and can edit the content and share the new unit with other WISE users. - - app/modules/library/copy-project-dialog/copy-project-dialog.component.html - 7 - - - - Copy - - app/modules/library/copy-project-dialog/copy-project-dialog.component.html - 17 - - - app/modules/library/library-project-menu/library-project-menu.component.html - 11 + 81 @@ -1704,6 +1722,10 @@ app/teacher/edit-run-warning-dialog/edit-run-warning-dialog.component.html 9 + + app/teacher/share-run-code-dialog/share-run-code-dialog.component.html + 5 + app/teacher/share-run-dialog/share-run-dialog.component.html 14 @@ -1735,7 +1757,7 @@ app/teacher/share-run-dialog/share-run-dialog.component.html - 96 + 101 @@ -1758,10 +1780,6 @@ app/modules/library/library-project-menu/library-project-menu.component.html 17 - - app/teacher/run-menu/run-menu.component.html - 22 - Toggle filters @@ -5108,7 +5126,7 @@ Launch Unit app/student/team-sign-in-dialog/team-sign-in-dialog.component.html - 69 + 70 @@ -5166,7 +5184,7 @@ app/teacher/run-menu/run-menu.component.html - 35 + 30 @@ -5177,7 +5195,7 @@ app/teacher/teacher-run-list-item/teacher-run-list-item.component.html - 83 + 86 @@ -5264,6 +5282,28 @@ 120 + + New + + ../../wise5/directives/componentAnnotations/component-annotations.component.html + 9 + + + app/classroom-monitor/component-new-work-badge/component-new-work-badge.component.ts + 1 + + + ../../wise5/classroomMonitor/classroomMonitorComponents/nodeGrading/workgroupInfo/workgroup-info.component.html + 10 + + + + Score: + + ../../wise5/directives/componentAnnotations/component-annotations.component.html + 18 + + point @@ -5359,6 +5399,34 @@ 30 + + Share with Students + + app/teacher/share-run-code-dialog/share-run-code-dialog.component.html + 1 + + + + Copy this link to share with your students: + + app/teacher/share-run-code-dialog/share-run-code-dialog.component.html + 8 + + + + Students with WISE accounts can also select Add Unit+ and type the Access Code: + + app/teacher/share-run-code-dialog/share-run-code-dialog.component.html + 19 + + + + Add as an assignment in Google Classroom: + + app/teacher/share-run-code-dialog/share-run-code-dialog.component.html + 30 + + periods @@ -5407,36 +5475,43 @@ 26 + + Share with students + + app/teacher/teacher-run-list-item/teacher-run-list-item.component.html + 33 + + Shared by app/teacher/teacher-run-list-item/teacher-run-list-item.component.html - 32 + 35 (Legacy Unit) app/teacher/teacher-run-list-item/teacher-run-list-item.component.html - 54 + 57 Last student login: app/teacher/teacher-run-list-item/teacher-run-list-item.component.html - 77 + 80 Teacher Tools app/teacher/teacher-run-list-item/teacher-run-list-item.component.html - 91 + 94 - - Share Classroom Unit + + Share Classroom Access app/teacher/share-run-dialog/share-run-dialog.component.html 1 @@ -5449,46 +5524,60 @@ 6 + + Sharing access allows other WISE teachers to view student work and optionally view student names, grade, manage teams, and edit unit content. + + app/teacher/share-run-dialog/share-run-dialog.component.html + 17 + + + + If you have customized the content in this unit and want to share so other teachers can use with their students, make a copy of the unit. + + app/teacher/share-run-dialog/share-run-dialog.component.html + 18 + + View Student Work app/teacher/share-run-dialog/share-run-dialog.component.html - 64 + 69 View Student Names app/teacher/share-run-dialog/share-run-dialog.component.html - 68 + 73 Grade and Manage app/teacher/share-run-dialog/share-run-dialog.component.html - 72 + 77 Are you sure you want to make the new owner of this unit? app/teacher/share-run-dialog/share-run-dialog.component.html - 86 + 91 You will still be able to access the unit but the new owner will have the ability to take away or change your access permissions. app/teacher/share-run-dialog/share-run-dialog.component.html - 87 + 92 Transfer Ownership app/teacher/share-run-dialog/share-run-dialog.component.html - 94 + 99 @@ -5596,11 +5685,18 @@ 18 + + Share Access + + app/teacher/run-menu/run-menu.component.html + 22 + + Edit Content app/teacher/run-menu/run-menu.component.html - 31 + 26 @@ -5815,15 +5911,18 @@ 36 - - New + + Show Save Button - app/classroom-monitor/component-new-work-badge/component-new-work-badge.component.ts - 1 + ../../wise5/authoringTool/node/advanced/general/node-advanced-general-authoring.component.html + 6 + + + Show Submit Button - ../../wise5/classroomMonitor/classroomMonitorComponents/nodeGrading/workgroupInfo/workgroup-info.component.html - 10 + ../../wise5/authoringTool/node/advanced/general/node-advanced-general-authoring.component.html + 14 @@ -6257,6 +6356,9 @@ Click "OK" to revert back to the last valid JSON. Click "Cancel" to keep the invalid JSON open so you can fix it. + + Copied to clipboard. + diff --git a/src/main/webapp/site/src/style/abstracts/_mixins.scss b/src/main/webapp/site/src/style/abstracts/_mixins.scss index 814fc295a3..cfc4de9e92 100644 --- a/src/main/webapp/site/src/style/abstracts/_mixins.scss +++ b/src/main/webapp/site/src/style/abstracts/_mixins.scss @@ -91,6 +91,10 @@ } } + .mat-divider { + margin: 16px 0; + } + .mat-card-actions { margin-left: 0; margin-right: 0; @@ -103,6 +107,10 @@ >.mat-card-actions:last-child { margin-bottom: 0; } + + .mat-divider { + margin: 0; + } } .mat-card--button { diff --git a/src/main/webapp/site/src/style/components/_dialog.scss b/src/main/webapp/site/src/style/components/_dialog.scss index d64d43bd69..6457d35ee8 100644 --- a/src/main/webapp/site/src/style/components/_dialog.scss +++ b/src/main/webapp/site/src/style/components/_dialog.scss @@ -5,6 +5,7 @@ .mat-dialog-content { margin: 0 -16px; padding: 0 16px; + font-size: mat-font-size($config, body-1); } .mat-dialog-content--scroll { @@ -35,6 +36,6 @@ .cdk-overlay-pane { @media (max-width: breakpoint('xs.max')) { - max-width: 90vw; + max-width: 95vw; } } diff --git a/src/main/webapp/site/src/style/components/_menu.scss b/src/main/webapp/site/src/style/components/_menu.scss index 5d76b28a7b..8b13789179 100644 --- a/src/main/webapp/site/src/style/components/_menu.scss +++ b/src/main/webapp/site/src/style/components/_menu.scss @@ -1,5 +1 @@ -.mat-menu-content { - .mat-divider { - margin: 8px 0; - } -} + diff --git a/src/main/webapp/wise5/authoringTool/node/advanced/general/node-advanced-general-authoring.component.html b/src/main/webapp/wise5/authoringTool/node/advanced/general/node-advanced-general-authoring.component.html index 0d2ee67ca0..0a2e80e644 100644 --- a/src/main/webapp/wise5/authoringTool/node/advanced/general/node-advanced-general-authoring.component.html +++ b/src/main/webapp/wise5/authoringTool/node/advanced/general/node-advanced-general-authoring.component.html @@ -1,16 +1,18 @@
- - {{ ::"SHOW_SAVE_BUTTON" | translate }} - + + Show Save Button +
- - {{ ::"SHOW_SUBMIT_BUTTON" | translate }} - + + Show Submit Button +
diff --git a/src/main/webapp/wise5/authoringTool/node/advanced/general/node-advanced-general-authoring.component.ts b/src/main/webapp/wise5/authoringTool/node/advanced/general/node-advanced-general-authoring.component.ts index 6ebf66ac44..e6fec69742 100644 --- a/src/main/webapp/wise5/authoringTool/node/advanced/general/node-advanced-general-authoring.component.ts +++ b/src/main/webapp/wise5/authoringTool/node/advanced/general/node-advanced-general-authoring.component.ts @@ -1,27 +1,23 @@ +import { Component } from "@angular/core"; import { TeacherDataService } from "../../../../services/teacherDataService"; import { TeacherProjectService } from "../../../../services/teacherProjectService"; -class NodeAdvancedGeneralAuthoringController { +@Component({ + templateUrl: 'node-advanced-general-authoring.component.html' +}) +export class NodeAdvancedGeneralAuthoringComponent { node: any; - static $inject = ['ProjectService', 'TeacherDataService']; - constructor(private ProjectService: TeacherProjectService, private TeacherDataService: TeacherDataService) { } - $onInit() { - const nodeId = this.TeacherDataService.getCurrentNodeId(); - this.node = this.ProjectService.getNodeById(nodeId); + ngOnInit() { + this.node = this.TeacherDataService.getCurrentNode(); } saveProject() { return this.ProjectService.saveProject(); } } - -export const NodeAdvancedGeneralAuthoringComponent = { - templateUrl: `/wise5/authoringTool/node/advanced/general/node-advanced-general-authoring.component.html`, - controller: NodeAdvancedGeneralAuthoringController -} diff --git a/src/main/webapp/wise5/components/animation/index.html b/src/main/webapp/wise5/components/animation/index.html index 9edaca04c7..0f2b78cabe 100644 --- a/src/main/webapp/wise5/components/animation/index.html +++ b/src/main/webapp/wise5/components/animation/index.html @@ -169,8 +169,8 @@ + [annotations]='animationController.latestAnnotations' + [max-score]='animationController.componentContent.maxScore'> diff --git a/src/main/webapp/wise5/components/audioOscillator/index.html b/src/main/webapp/wise5/components/audioOscillator/index.html index 63f8221e02..5cede81d06 100644 --- a/src/main/webapp/wise5/components/audioOscillator/index.html +++ b/src/main/webapp/wise5/components/audioOscillator/index.html @@ -132,8 +132,8 @@ + [annotations]='audioOscillatorController.latestAnnotations' + [max-score]='audioOscillatorController.componentContent.maxScore'> diff --git a/src/main/webapp/wise5/components/conceptMap/index.html b/src/main/webapp/wise5/components/conceptMap/index.html index db9222c167..279c365176 100644 --- a/src/main/webapp/wise5/components/conceptMap/index.html +++ b/src/main/webapp/wise5/components/conceptMap/index.html @@ -195,7 +195,7 @@ + [annotations]='conceptMapController.latestAnnotations' + [max-score]='conceptMapController.componentContent.maxScore'> diff --git a/src/main/webapp/wise5/components/discussion/index.html b/src/main/webapp/wise5/components/discussion/index.html index 358c18e70a..c9fc293912 100644 --- a/src/main/webapp/wise5/components/discussion/index.html +++ b/src/main/webapp/wise5/components/discussion/index.html @@ -59,8 +59,8 @@
+ [annotations]='discussionController.latestAnnotations' + [max-score]='::discussionController.componentContent.maxScore'>
diff --git a/src/main/webapp/wise5/components/draw/index.html b/src/main/webapp/wise5/components/draw/index.html index e693999536..fd4a57ef68 100644 --- a/src/main/webapp/wise5/components/draw/index.html +++ b/src/main/webapp/wise5/components/draw/index.html @@ -127,8 +127,8 @@

API examples:

+ [annotations]='drawController.latestAnnotations' + [max-score]='drawController.componentContent.maxScore'>
diff --git a/src/main/webapp/wise5/components/embedded/index.html b/src/main/webapp/wise5/components/embedded/index.html index 2a671f8730..36d72bc44f 100644 --- a/src/main/webapp/wise5/components/embedded/index.html +++ b/src/main/webapp/wise5/components/embedded/index.html @@ -73,8 +73,8 @@ + [annotations]='embeddedController.latestAnnotations' + [max-score]='embeddedController.componentContent.maxScore'> diff --git a/src/main/webapp/wise5/components/graph/index.html b/src/main/webapp/wise5/components/graph/index.html index 7c5828ca49..06f81bdc30 100644 --- a/src/main/webapp/wise5/components/graph/index.html +++ b/src/main/webapp/wise5/components/graph/index.html @@ -197,8 +197,8 @@ + [annotations]='graphController.latestAnnotations' + [max-score]='graphController.componentContent.maxScore'>
diff --git a/src/main/webapp/wise5/components/label/index.html b/src/main/webapp/wise5/components/label/index.html index 3a80cc9def..d8d7ffbfbd 100644 --- a/src/main/webapp/wise5/components/label/index.html +++ b/src/main/webapp/wise5/components/label/index.html @@ -189,8 +189,8 @@ + [annotations]='labelController.latestAnnotations' + [max-score]='labelController.componentContent.maxScore'> diff --git a/src/main/webapp/wise5/components/match/index.html b/src/main/webapp/wise5/components/match/index.html index 30698a68f8..0c5a978486 100644 --- a/src/main/webapp/wise5/components/match/index.html +++ b/src/main/webapp/wise5/components/match/index.html @@ -174,8 +174,8 @@
+ [annotations]='matchController.latestAnnotations' + [max-score]='matchController.componentContent.maxScore'>
diff --git a/src/main/webapp/wise5/components/multipleChoice/index.html b/src/main/webapp/wise5/components/multipleChoice/index.html index deaed51295..174ed85e2d 100644 --- a/src/main/webapp/wise5/components/multipleChoice/index.html +++ b/src/main/webapp/wise5/components/multipleChoice/index.html @@ -188,8 +188,8 @@
+ [annotations]='multipleChoiceController.latestAnnotations' + [max-score]='multipleChoiceController.componentContent.maxScore'>
diff --git a/src/main/webapp/wise5/components/openResponse/index.html b/src/main/webapp/wise5/components/openResponse/index.html index 6eab8e760b..844178ca66 100644 --- a/src/main/webapp/wise5/components/openResponse/index.html +++ b/src/main/webapp/wise5/components/openResponse/index.html @@ -155,7 +155,7 @@ + [annotations]='openResponseController.latestAnnotations' + [max-score]='openResponseController.componentContent.maxScore'> diff --git a/src/main/webapp/wise5/components/table/index.html b/src/main/webapp/wise5/components/table/index.html index 6dda718eaa..a45fd38546 100644 --- a/src/main/webapp/wise5/components/table/index.html +++ b/src/main/webapp/wise5/components/table/index.html @@ -191,8 +191,8 @@ + [annotations]='tableController.latestAnnotations' + [max-score]='tableController.componentContent.maxScore'> diff --git a/src/main/webapp/wise5/directives/componentAnnotations/component-annotations.component.html b/src/main/webapp/wise5/directives/componentAnnotations/component-annotations.component.html new file mode 100644 index 0000000000..9d2c55671d --- /dev/null +++ b/src/main/webapp/wise5/directives/componentAnnotations/component-annotations.component.html @@ -0,0 +1,26 @@ + + +
+ {{icon}} +
+
+ {{label}} + New +
+
+ +
+
+
+ Score: {{annotations.score.data.value}}{{maxScoreDisplay}} + + + {{ getLatestAnnotationTime() | amTimeAgo }} + +
+
+
diff --git a/src/main/webapp/wise5/directives/componentAnnotations/component-annotations.component.scss b/src/main/webapp/wise5/directives/componentAnnotations/component-annotations.component.scss new file mode 100644 index 0000000000..7bb5ef784a --- /dev/null +++ b/src/main/webapp/wise5/directives/componentAnnotations/component-annotations.component.scss @@ -0,0 +1,7 @@ +mat-card.annotations { + padding: 0; +} + +.annotations__title { + font-size: 15px; +} diff --git a/src/main/webapp/wise5/directives/componentAnnotations/component-annotations.component.ts b/src/main/webapp/wise5/directives/componentAnnotations/component-annotations.component.ts new file mode 100644 index 0000000000..e01bb86bc0 --- /dev/null +++ b/src/main/webapp/wise5/directives/componentAnnotations/component-annotations.component.ts @@ -0,0 +1,143 @@ +'use strict'; + +import { Component, Input } from "@angular/core"; +import { UpgradeModule } from "@angular/upgrade/static"; +import { Subscription } from "rxjs"; +import { ConfigService } from "../../services/configService"; +import { StudentDataService } from "../../services/studentDataService"; +import { VLEProjectService } from "../../vle/vleProjectService"; + +@Component({ + selector: 'component-annotations', + styleUrls: ['component-annotations.component.scss'], + templateUrl: 'component-annotations.component.html' +}) +export class ComponentAnnotationsComponent { + + @Input() + annotations: any; + maxScoreDisplay: string; + nodeId: string = null; + componentId: string = null + latestAnnotationTime: any = null; + isNew: boolean; + label: string = ''; + + @Input() + maxScore: string; + icon: string = 'person'; + showScore: boolean = true; + showComment: boolean = true; + studentWorkSavedToServerSubscription: Subscription; + + constructor(private upgrade: UpgradeModule, + private ConfigService: ConfigService, + private ProjectService: VLEProjectService, + private StudentDataService: StudentDataService) { + } + + ngOnInit() { + this.maxScoreDisplay = (parseInt(this.maxScore) > 0) ? '/' + this.maxScore : ''; + this.studentWorkSavedToServerSubscription = + this.StudentDataService.studentWorkSavedToServer$.subscribe(({studentWork}) => { + if (studentWork.nodeId === this.nodeId && studentWork.componentId === this.componentId) { + this.isNew = false; + } + }); + } + + ngOnChanges() { + this.processAnnotations(); + } + + ngOnDestroy() { + this.studentWorkSavedToServerSubscription.unsubscribe(); + } + + processAnnotations() { + if (this.annotations.comment || this.annotations.score) { + this.nodeId = this.annotations.comment ? + this.annotations.comment.nodeId : this.annotations.score.nodeId; + this.componentId = this.annotations.comment ? + this.annotations.comment.componentId : this.annotations.score.nodeId; + this.showScore = this.annotations.score != null && + this.ProjectService.displayAnnotation(this.annotations.score); + this.showComment = this.annotations.comment != null && + this.ProjectService.displayAnnotation(this.annotations.comment); + this.setLabelAndIcon(); + } + } + + getLatestAnnotation() { + let latest = null; + if (this.annotations.comment || this.annotations.score) { + let commentSaveTime = this.annotations.comment ? this.annotations.comment.serverSaveTime : 0; + let scoreSaveTime = this.annotations.score ? this.annotations.score.serverSaveTime : 0; + if (commentSaveTime >= scoreSaveTime) { + latest = this.annotations.comment; + } else if (scoreSaveTime > commentSaveTime) { + latest = this.annotations.score; + } + } + return latest; + } + + getLatestAnnotationTime() { + const latest = this.getLatestAnnotation(); + if (latest) { + return this.ConfigService.convertToClientTimestamp(latest.serverSaveTime) + } + return null; + } + + getLatestVisitTime() { + let nodeEvents = this.StudentDataService.getEventsByNodeId(this.nodeId); + let n = nodeEvents.length - 1; + let visitTime = null; + for (let i = n; i > 0; i--) { + let event = nodeEvents[i]; + if (event.event === 'nodeExited') { + visitTime = this.ConfigService.convertToClientTimestamp(event.serverSaveTime); + break; + } + } + return visitTime; + } + + getLatestSaveTime() { + const latestState = this.StudentDataService.getLatestComponentStateByNodeIdAndComponentId( + this.nodeId, this.componentId); + let saveTime = null; + if (latestState) { + saveTime = this.ConfigService.convertToClientTimestamp(latestState.serverSaveTime); + } + return saveTime; + } + + isNewAnnotation() { + let latestVisitTime = this.getLatestVisitTime(); + let latestSaveTime = this.getLatestSaveTime(); + let latestAnnotationTime = this.getLatestAnnotationTime(); + let isNew = true; + if (latestVisitTime && (latestVisitTime > latestAnnotationTime)) { + isNew = false; + } + if (latestSaveTime && (latestSaveTime > latestAnnotationTime)) { + isNew = false; + } + return isNew; + } + + setLabelAndIcon() { + const latest = this.getLatestAnnotation(); + if (latest) { + if (latest.type === 'autoComment' || latest.type === 'autoScore') { + this.label = this.upgrade.$injector.get('$filter')('translate')('automatedFeedbackLabel'); + this.icon = 'keyboard'; + } else { + this.label = this.upgrade.$injector.get('$filter')('translate')('teacherFeedbackLabel'); + this.icon = 'person'; + } + } + } +} diff --git a/src/main/webapp/wise5/directives/componentAnnotations/componentAnnotations.html b/src/main/webapp/wise5/directives/componentAnnotations/componentAnnotations.html deleted file mode 100644 index 83e7eb4f3a..0000000000 --- a/src/main/webapp/wise5/directives/componentAnnotations/componentAnnotations.html +++ /dev/null @@ -1,27 +0,0 @@ - - -
- {{componentAnnotationsCtrl.icon}} -
-
- {{componentAnnotationsCtrl.label}} - -
-
- -
-
-
- - - - - {{ componentAnnotationsCtrl.getLatestAnnotationTime() | amDateFormat:'ddd, MMM D YYYY, h:mm a' }} - -
-
-
diff --git a/src/main/webapp/wise5/directives/componentAnnotations/componentAnnotations.js b/src/main/webapp/wise5/directives/componentAnnotations/componentAnnotations.js deleted file mode 100644 index 75ac6dda09..0000000000 --- a/src/main/webapp/wise5/directives/componentAnnotations/componentAnnotations.js +++ /dev/null @@ -1,231 +0,0 @@ -'use strict'; - -class ComponentAnnotationsController { - constructor($scope, - $element, // TODO remove after verifying that this is not being used - $filter, - $mdDialog, - $timeout, - ConfigService, - ProjectService, - StudentDataService) { - this.$scope = $scope; - this.$filter = $filter; - this.$mdDialog = $mdDialog; - this.ConfigService = ConfigService; - this.ProjectService = ProjectService; - this.StudentDataService = StudentDataService; - this.$translate = this.$filter('translate'); - this.maxScoreDisplay = (parseInt(this.maxScore) > 0) ? '/' + this.maxScore : ''; - this.themeSettings = this.ProjectService.getThemeSettings(); - this.hideComponentScores = this.themeSettings.hideComponentScores; - this.nodeId = null; - this.componentId = null; - this.latestAnnotationTime = null; - this.isNew = false; - this.label = ''; - this.icon = 'person'; // (default to person/teacher) - this.showScore = true; - this.showComment = true; - - this.studentWorkSavedToServerSubscription = - this.StudentDataService.studentWorkSavedToServer$.subscribe((args) => { - let nodeId = args.studentWork.nodeId; - let componentId = args.studentWork.componentId; - if (nodeId === this.nodeId && componentId === this.componentId) { - this.isNew = false; - } - }); - - /* used to pop up annotation - $timeout(() => { - this.$mdDialog.show({ - contentElement: '#componentAnnotationsCard', - parent: angular.element(document.body) - }); - }); - */ - - /* uncomment me and use me instead of timeout when we switch to angular 2 - this.$onAfterViewInit = () => { - this.$mdDialog.show({ - contentElement: '#componentAnnotationsCard', - parent: angular.element(document.body) - }); - }; - */ - - this.$onChanges = (changes) => { - //if (changes.annotations) { - //this.annotations = angular.copy(changes.annotations.currentValue); - this.processAnnotations(); - //} - }; - - this.$scope.$on('$destroy', () => { - this.ngOnDestroy(); - }); - } - - ngOnDestroy() { - this.unsubscribeAll(); - } - - unsubscribeAll() { - this.studentWorkSavedToServerSubscription.unsubscribe(); - } - - closeDialog() { - this.$mdDialog.hide(); - } - - /** - * Get the most recent annotation (from the current score and comment annotations) - * @return Object (latest annotation) - */ - getLatestAnnotation() { - let latest = null; - - if (this.annotations.comment || this.annotations.score) { - let commentSaveTime = this.annotations.comment ? this.annotations.comment.serverSaveTime : 0; - let scoreSaveTime = this.annotations.score ? this.annotations.score.serverSaveTime : 0; - - if (commentSaveTime >= scoreSaveTime) { - latest = this.annotations.comment; - } else if (scoreSaveTime > commentSaveTime) { - latest = this.annotations.score; - } - } - - return latest; - } - - /** - * Calculate the save time of the latest annotation - * @return Number (latest annotation post time) - */ - getLatestAnnotationTime() { - let latest = this.getLatestAnnotation(); - let time = null; - - if (latest) { - let serverSaveTime = latest.serverSaveTime; - time = this.ConfigService.convertToClientTimestamp(serverSaveTime) - } - - return time; - } - - /** - * Find nodeExited time of the latest node visit for this component - * @return Number (latest node exit time) - */ - getLatestVisitTime() { - let nodeEvents = this.StudentDataService.getEventsByNodeId(this.nodeId); - let n = nodeEvents.length - 1; - let visitTime = null; - - for (let i = n; i > 0; i--) { - let event = nodeEvents[i]; - if (event.event === 'nodeExited') { - visitTime = this.ConfigService.convertToClientTimestamp(event.serverSaveTime); - break; - } - } - - return visitTime; - } - - /** - * Find and the latest save time for this component - * @return Number (latest save time) - */ - getLatestSaveTime() { - let latestState = this.StudentDataService.getLatestComponentStateByNodeIdAndComponentId(this.nodeId, this.componentId); - let saveTime = null; - - if (latestState) { - saveTime = this.ConfigService.convertToClientTimestamp(latestState.serverSaveTime); - } - - return saveTime; - } - - /** - * Check whether the current annotation for this component is new to the - * workgroup (i.e. if the workgroup hasn't seen the annotation on a previous - * node visit and the latest annotation came after the latest component state) - * @return Boolean (true or false) - */ - isNewAnnotation() { - let latestVisitTime = this.getLatestVisitTime(); - let latestSaveTime = this.getLatestSaveTime(); - let latestAnnotationTime = this.getLatestAnnotationTime(); - let isNew = true; - - if (latestVisitTime && (latestVisitTime > latestAnnotationTime)) { - isNew = false; - } - - if (latestSaveTime && (latestSaveTime > latestAnnotationTime)) { - isNew = false; - } - - return isNew; - } - - /** - * Set the label based on whether this is an automated or teacher annotation - **/ - setLabelAndIcon() { - const latest = this.getLatestAnnotation(); - if (latest) { - if (latest.type === 'autoComment' || latest.type === 'autoScore') { - this.label = this.$translate('automatedFeedbackLabel'); - this.icon = 'keyboard'; - } else { - this.label = this.$translate('teacherFeedbackLabel'); - this.icon = 'person'; - } - } - } - - processAnnotations() { - if (this.annotations != null) { - if (this.annotations.comment || this.annotations.score) { - this.nodeId = this.annotations.comment ? - this.annotations.comment.nodeId : this.annotations.score.nodeId; - this.componentId = this.annotations.comment ? - this.annotations.comment.componentId : this.annotations.score.nodeId; - this.showScore = this.annotations.score != null && - this.ProjectService.displayAnnotation(this.annotations.score); - this.showComment = this.annotations.comment != null && - this.ProjectService.displayAnnotation(this.annotations.comment); - this.setLabelAndIcon(); - } - } - } -} - -ComponentAnnotationsController.$inject = [ - '$scope', - '$element', - '$filter', - '$mdDialog', - '$timeout', - 'ConfigService', - 'ProjectService', - 'StudentDataService' -]; - -const ComponentAnnotations = { - bindings: { - annotations: '<', - maxScore: '<' - }, - templateUrl: 'wise5/directives/componentAnnotations/componentAnnotations.html', - controller: ComponentAnnotationsController, - controllerAs: 'componentAnnotationsCtrl' -}; - -export default ComponentAnnotations; diff --git a/src/main/webapp/wise5/directives/components.ts b/src/main/webapp/wise5/directives/components.ts index 0c83aa3d72..5e032fde70 100644 --- a/src/main/webapp/wise5/directives/components.ts +++ b/src/main/webapp/wise5/directives/components.ts @@ -3,7 +3,6 @@ import * as angular from 'angular'; import Compile from './compile/compile'; import Component from './component/component'; -import ComponentAnnotations from './componentAnnotations/componentAnnotations'; import DisableDeleteKeypress from './disableDeleteKeypress/disableDeleteKeypress'; import Draggable from './draggable/draggable'; import GlobalAnnotations from './globalAnnotations/globalAnnotations'; @@ -22,7 +21,6 @@ const Components = angular.module('components', []); Components.component('compile', Compile); Components.component('component', Component); -Components.component('componentAnnotations', ComponentAnnotations); Components.component('disableDeleteKeypress', DisableDeleteKeypress); Components.component('draggable', Draggable); Components.component('globalAnnotations', GlobalAnnotations); @@ -32,7 +30,7 @@ Components.directive('milestoneReportData', downgradeComponent({ component: MilestoneReportDataComponent}) as angular.IDirectiveFactory); Components.component('milestoneReportGraph', MilestoneReportGraph); Components.directive('nodeIcon', - downgradeComponent({ component: NodeIconComponent}) as angular.IDirectiveFactory) + downgradeComponent({ component: NodeIconComponent}) as angular.IDirectiveFactory); Components.directive('possibleScore', downgradeComponent({ component: PossibleScoreComponent}) as angular.IDirectiveFactory); Components.component('summaryDisplay', SummaryDisplay); diff --git a/src/main/webapp/wise5/teacher/teacher-angular-js-module.ts b/src/main/webapp/wise5/teacher/teacher-angular-js-module.ts index a2b83e547c..671d78deaa 100644 --- a/src/main/webapp/wise5/teacher/teacher-angular-js-module.ts +++ b/src/main/webapp/wise5/teacher/teacher-angular-js-module.ts @@ -101,7 +101,8 @@ import '../lib/summernoteExtensions/summernote-ext-print.js' .component('nodeAdvancedAuthoringComponent', NodeAdvancedAuthoringComponent) .component('nodeAdvancedBranchAuthoringComponent', NodeAdvancedBranchAuthoringComponent) .component('nodeAdvancedConstraintAuthoringComponent', NodeAdvancedConstraintAuthoringComponent) - .component('nodeAdvancedGeneralAuthoringComponent', NodeAdvancedGeneralAuthoringComponent) + .directive('nodeAdvancedGeneralAuthoringComponent', downgradeComponent( + { component: NodeAdvancedGeneralAuthoringComponent }) as angular.IDirectiveFactory) .directive('nodeAdvancedJsonAuthoringComponent', downgradeComponent( { component: NodeAdvancedJsonAuthoringComponent }) as angular.IDirectiveFactory) .component('nodeAdvancedPathAuthoringComponent', NodeAdvancedPathAuthoringComponent) diff --git a/src/main/webapp/wise5/vle/student-angular-js-module.ts b/src/main/webapp/wise5/vle/student-angular-js-module.ts index 9ed38e53a4..4ef4953585 100644 --- a/src/main/webapp/wise5/vle/student-angular-js-module.ts +++ b/src/main/webapp/wise5/vle/student-angular-js-module.ts @@ -1,7 +1,7 @@ import '../lib/jquery/jquery-global'; import '../lib/bootstrap/js/bootstrap.min' import * as angular from 'angular'; -import { downgradeInjectable } from '@angular/upgrade/static'; +import { downgradeComponent, downgradeInjectable } from '@angular/upgrade/static'; import '../common-angular-js-module'; import NavigationController from '../vle/navigation/navigationController'; import NodeController from '../vle/node/nodeController'; @@ -11,6 +11,7 @@ import { VLEProjectService } from '../vle/vleProjectService'; import '../lib/summernote/dist/summernote.min'; import '../lib/summernoteExtensions/summernote-ext-addNote.js'; import '../lib/summernoteExtensions/summernote-ext-print.js' +import { ComponentAnnotationsComponent } from '../directives/componentAnnotations/component-annotations.component'; export function createStudentAngularJSModule(type = 'preview') { return angular.module(type, [ @@ -26,6 +27,8 @@ export function createStudentAngularJSModule(type = 'preview') { .controller('NavigationController', NavigationController) .controller('NodeController', NodeController) .controller('VLEController', VLEController) + .directive('componentAnnotations', + downgradeComponent({ component: ComponentAnnotationsComponent }) as angular.IDirectiveFactory) .config([ '$stateProvider', '$translatePartialLoaderProvider', diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/user/UserAPIControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/user/UserAPIControllerTest.java index 47ab8e7357..11c392e136 100644 --- a/src/test/java/org/wise/portal/presentation/web/controllers/user/UserAPIControllerTest.java +++ b/src/test/java/org/wise/portal/presentation/web/controllers/user/UserAPIControllerTest.java @@ -64,6 +64,7 @@ public void getConfig_WISEContextPath_ReturnConfig() { expect(appProperties.get("google_analytics_id")).andReturn("UA-XXXXXX-1"); expect(appProperties.get("recaptcha_public_key")).andReturn("recaptcha-123-abc"); expect(appProperties.get("wise4.hostname")).andReturn("http://localhost:8080/legacy"); + expect(appProperties.get("wise.hostname")).andReturn("http://localhost:8080"); replay(appProperties); HashMap config = userAPIController.getConfig(request); assertEquals("wise", config.get("contextPath"));