Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable linking SCORE run to CK Board project #28

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 63 additions & 60 deletions src/app/teacher/create-run-dialog/create-run-dialog.component.html
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
<h2 class="mat-dialog-title" i18n>Use with Class</h2>
<form *ngIf="!isCreated" [formGroup]="form" (ngSubmit)="create()">
<mat-dialog-content class="dialog-content-scroll">
<p class="mat-subheading-2 accent-1">
{{ project.metadata.title }} <span class="mat-caption" i18n>(Unit ID: {{ project.id }})</span>
</p>
<h3 i18n>1. Choose Periods</h3>
<p formArrayName="selectedPeriods">
<span *ngFor="let control of selectedPeriodsControl.controls" [formGroup]="control">
<mat-checkbox formControlName="checkbox" class="period-select">
{{ control.controls.name.value }}
<ng-container *ngIf="!isCreated">
<h2 class="mat-dialog-title" i18n>Use with Class</h2>
<form *ngIf="!isCreated" [formGroup]="form" (ngSubmit)="create()">
<mat-dialog-content class="dialog-content-scroll">
<p class="mat-subheading-2 accent-1">
{{ project.metadata.title }} <span class="mat-caption" i18n>(Unit ID: {{ project.id }})</span>
</p>
<h3 i18n>1. Choose Periods</h3>
<p formArrayName="selectedPeriods">
<span *ngFor="let control of selectedPeriodsControl.controls" [formGroup]="control">
<mat-checkbox formControlName="checkbox" class="period-select">
{{ control.controls.name.value }}
</mat-checkbox>
</span>
</p>
<mat-form-field appearance="fill" class="period-input form-field-long-hint">
<mat-label i18n>Add your own periods</mat-label>
<input matInput id="customPeriods" name="customPeriods" formControlName="customPeriods" />
<mat-hint i18n>For "Period 9", just enter the number 9. Separate periods with commas (e.g. "Section 1, Section
2"). Manually named periods should be no more than 16 characters long.
</mat-hint>
</mat-form-field>
<p></p>
<p>
<mat-checkbox formControlName="isRandomPeriodAssignment" i18n>
Randomly assign students to periods
</mat-checkbox>
</span>
</p>
<mat-form-field appearance="fill" class="period-input form-field-long-hint">
<mat-label i18n>Add your own periods</mat-label>
<input matInput id="customPeriods" name="customPeriods" formControlName="customPeriods" />
<mat-hint i18n
>For "Period 9", just enter the number 9. Separate periods with commas (e.g. "Section 1,
Section 2"). Manually named periods should be no more than 16 characters long.
</mat-hint>
</mat-form-field>
<p></p>
<p>
<mat-checkbox formControlName="isRandomPeriodAssignment" i18n>
Randomly assign students to periods
</mat-checkbox>
</p>
<mat-divider></mat-divider>
<h3 i18n>2. Choose Students Per Team</h3>
Expand All @@ -36,40 +36,20 @@ <h3 i18n>2. Choose Students Per Team</h3>
<h3 i18n>3. Set Schedule</h3>
<div fxLayout="row wrap" fxLayout.xs="column" fxLayoutGap.gt-xs="16px">
<div>
<mat-form-field
appearance="fill"
fxFlexAlign="start"
fxFlex="0 0 auto"
fxFlex.xs="0 0 100%"
>
<mat-form-field appearance="fill" fxFlexAlign="start" fxFlex="0 0 auto" fxFlex.xs="0 0 100%">
<mat-label i18n>Start date</mat-label>
<input
matInput
[matDatepicker]="startDatePicker"
formControlName="startDate"
(dateChange)="setDateRange()"
[max]="maxStartDate"
/>
<input matInput [matDatepicker]="startDatePicker" formControlName="startDate" (dateChange)="setDateRange()"
[max]="maxStartDate" />
<mat-datepicker-toggle matSuffix [for]="startDatePicker"></mat-datepicker-toggle>
<mat-datepicker #startDatePicker></mat-datepicker>
<mat-error i18n>Start date is required</mat-error>
</mat-form-field>
</div>
<div>
<mat-form-field
appearance="fill"
fxFlexAlign="start"
fxFlex="0 0 auto"
fxFlex.xs="0 0 100%"
>
<mat-form-field appearance="fill" fxFlexAlign="start" fxFlex="0 0 auto" fxFlex.xs="0 0 100%">
<mat-label i18n>End date</mat-label>
<input
matInput
[matDatepicker]="endDatePicker"
formControlName="endDate"
(dateChange)="setDateRange()"
[min]="minEndDate"
/>
<input matInput [matDatepicker]="endDatePicker" formControlName="endDate" (dateChange)="setDateRange()"
[min]="minEndDate" />
<mat-datepicker-toggle matSuffix [for]="endDatePicker"></mat-datepicker-toggle>
<mat-datepicker #endDatePicker></mat-datepicker>
</mat-form-field>
Expand Down Expand Up @@ -101,6 +81,7 @@ <h3 i18n>3. Set Schedule</h3>
</mat-dialog-actions>
</form>
<ng-container *ngIf="isCreated">
<h2 class="mat-dialog-title" i18n>Run Created.</h2>
<mat-dialog-content>
<div class="info-block">
<p class="mat-body-2" i18n>Success! This unit has been added to your Class Schedule.</p>
Expand All @@ -115,18 +96,40 @@ <h3 i18n>3. Set Schedule</h3>
<p i18n>
You can always find the Access Code for each classroom unit in your Class Schedule.
</p>
<br />
<mat-expansion-panel (opened)="openLinkRunToCkProjectPanel()" #linkRunPanel>
<mat-expansion-panel-header>
<mat-panel-title i18n>
<ng-container *ngIf="!linkedCkProjectControl.disabled">Link to a CK Board Project</ng-container>
<ng-container *ngIf="linkedCkProjectControl.disabled">Connected to CK Board Project</ng-container>
</mat-panel-title>
<mat-panel-description>
<ng-container *ngIf="!linkedCkProjectControl.disabled" i18n>Click to connect to a CK Board Project</ng-container>
<ng-container *ngIf="linkedCkProjectControl.disabled" i18n>Code: {{linkedCkProjectControl.value}}</ng-container>
</mat-panel-description>
</mat-expansion-panel-header>
<div>
<mat-form-field appearance="fill" fxFlexAlign="start">
<mat-label i18n>SCORE-CK Connect Code</mat-label>
<input matInput [formControl]="linkedCkProjectControl" #CkCodeInput>
<button color="primary" *ngIf="!linkedCkProjectControl.disabled" type="button" mat-icon-button matSuffix (click)="linkRunToCkProject()">
<mat-icon>add_circle</mat-icon>
</button>
<button color="accent" *ngIf="linkedCkProjectControl.disabled" type="button" mat-icon-button matSuffix (click)="unlinkRunFromCkProject()">
<mat-icon>close</mat-icon>
</button>
<mat-progress-bar mode="indeterminate" *ngIf="showProcessingLink"></mat-progress-bar>
</mat-form-field>
<p>Note: You can always manage CK Board Project linkining in Run Settings.</p>
</div>
</mat-expansion-panel>
</div>
</mat-dialog-content>
<mat-dialog-actions fxLayoutAlign="end">
<button
mat-button
color="primary"
(click)="checkClassroomAuthorization()"
*ngIf="isGoogleUser() && isGoogleClassroomEnabled()"
i18n
>
<button mat-button color="primary" (click)="checkClassroomAuthorization()"
*ngIf="isGoogleUser() && isGoogleClassroomEnabled()" i18n>
Share to Google Classroom
</button>
<button mat-button (click)="closeAll()" i18n>Done</button>
</mat-dialog-actions>
</ng-container>
</ng-container>
57 changes: 55 additions & 2 deletions src/app/teacher/create-run-dialog/create-run-dialog.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, Inject } from '@angular/core';
import { Component, ElementRef, Inject, ViewChild } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { finalize } from 'rxjs/operators';
Expand All @@ -9,6 +9,8 @@ import { ConfigService } from '../../services/config.service';
import { ListClassroomCoursesDialogComponent } from '../list-classroom-courses-dialog/list-classroom-courses-dialog.component';
import { TeacherRun } from '../teacher-run';
import { Router } from '@angular/router';
import { MatSnackBar } from '@angular/material/snack-bar';
import { MatExpansionPanel } from '@angular/material/expansion';

@Component({
selector: 'create-run-dialog',
Expand All @@ -28,6 +30,10 @@ export class CreateRunDialogComponent {
isCreating: boolean = false;
isCreated: boolean = false;
run: TeacherRun = null;
linkedCkProjectControl: FormControl;
@ViewChild('CkCodeInput') ckInput: ElementRef;
@ViewChild('linkRunPanel') linkPanel: MatExpansionPanel;
showProcessingLink: boolean = false;

constructor(
private configService: ConfigService,
Expand All @@ -37,7 +43,8 @@ export class CreateRunDialogComponent {
private fb: FormBuilder,
private router: Router,
private teacherService: TeacherService,
private userService: UserService
private userService: UserService,
private snackBar: MatSnackBar
) {
this.project = data.project;
this.maxStudentsPerTeam = 3;
Expand Down Expand Up @@ -66,6 +73,7 @@ export class CreateRunDialogComponent {
this.endDateControl.valueChanges.subscribe((v) => {
this.updateLockedAfterEndDateCheckbox();
});
this.linkedCkProjectControl = new FormControl('');
this.form = this.fb.group({
selectedPeriods: this.periodsGroup,
customPeriods: this.customPeriods,
Expand Down Expand Up @@ -102,6 +110,51 @@ export class CreateRunDialogComponent {
return selectedPeriods.length ? selectedPeriods : [];
}

openLinkRunToCkProjectPanel() {
if (!this.linkedCkProjectControl.disabled) {
setTimeout(() => this.ckInput.nativeElement.focus(), 200);
}
}

linkRunToCkProject() {
this.showProcessingLink = true;
this.linkedCkProjectControl.disable();
this.teacherService
.linkRunToCkProject(this.run.id, this.linkedCkProjectControl.value)
.pipe(
finalize(() => {
this.showProcessingLink = false;
})
)
.subscribe(({ code, message }) => {
if (!!code) {
setTimeout(() => this.linkPanel.close(), 200);
} else {
this.linkedCkProjectControl.enable();
this.ckInput.nativeElement.focus();
}
this.snackBar.open($localize`${message}`);
});
}

unlinkRunFromCkProject() {
this.showProcessingLink = true;
this.teacherService
.unlinkRunFromCkProject(this.run.id, this.linkedCkProjectControl.value)
.pipe(
finalize(() => {
this.showProcessingLink = false;
})
)
.subscribe(({ code, message }) => {
if (!!code) {
this.linkedCkProjectControl.enable();
this.ckInput.nativeElement.focus();
}
this.snackBar.open($localize`${message}`);
});
}

create() {
this.isCreating = true;
const combinedPeriods = this.getPeriodsString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,23 @@ <h3>
>
</div>
</div>
<mat-divider></mat-divider>
<h3>
<ng-container i18n>CK Board Project Linking</ng-container>
</h3>
<div>
<mat-form-field appearance="fill" fxFlexAlign="start">
<mat-label i18n>SCORE-CK Connect Code</mat-label>
<input matInput [formControl]="linkedCkProjectControl" #CkCodeInput>
<button color="primary" *ngIf="!linkedCkProjectControl.disabled" type="button" mat-icon-button matSuffix (click)="linkRunToCkProject()">
<mat-icon>add_circle</mat-icon>
</button>
<button color="accent" *ngIf="linkedCkProjectControl.disabled" type="button" mat-icon-button matSuffix (click)="unlinkRunFromCkProject()">
<mat-icon>close</mat-icon>
</button>
<mat-progress-bar mode="indeterminate" *ngIf="showProcessingLink"></mat-progress-bar>
</mat-form-field>
</div>
</mat-dialog-content>
<mat-dialog-actions fxLayoutAlign="end">
<button mat-flat-button color="primary" mat-dialog-close i18n>Done</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { LibraryProjectDetailsComponent } from '../../modules/library/library-pr
import { TeacherService } from '../teacher.service';
import { formatDate } from '@angular/common';
import { TeacherRun } from '../teacher-run';
import { FormControl } from '@angular/forms';
import { finalize } from 'rxjs/operators';

@Component({
selector: 'app-run-settings-dialog',
Expand Down Expand Up @@ -32,6 +34,8 @@ export class RunSettingsDialogComponent implements OnInit {
minEndDate: Date;
targetEndDate: Date;
messageCodeToMessage: any;
linkedCkProjectControl: FormControl;
showProcessingLink: boolean = false;

constructor(
public dialog: MatDialog,
Expand Down Expand Up @@ -71,7 +75,13 @@ export class RunSettingsDialogComponent implements OnInit {
};
}

ngOnInit() {}
ngOnInit() {
this.linkedCkProjectControl = new FormControl('');
if (!!this.run.connectCode) {
this.linkedCkProjectControl.setValue(this.run.connectCode);
this.linkedCkProjectControl.disable();
}
}

newPeriodNameKeyUp(event) {
if (this.isEnterKeyWithNewPeriodName(event)) {
Expand Down Expand Up @@ -286,6 +296,53 @@ export class RunSettingsDialogComponent implements OnInit {
});
}

linkRunToCkProject() {
this.showProcessingLink = true;
this.linkedCkProjectControl.disable();
this.teacherService
.linkRunToCkProject(this.run.id, this.linkedCkProjectControl.value)
.pipe(
finalize(() => {
this.showProcessingLink = false;
})
)
.subscribe(({ code, message }) => {
if (!!code) {
this.run.connectCode = code;
this.teacherService.broadcastRunChanges(new TeacherRun(this.run));
} else {
this.linkedCkProjectControl.enable();
}
this.snackBar.open($localize`${message}`);
});
}

unlinkRunFromCkProject() {
if (
confirm(
`Are you sure you want to unlink CK Board project: ${this.linkedCkProjectControl.value}`
)
) {
this.showProcessingLink = true;
this.teacherService
.unlinkRunFromCkProject(this.run.id, this.linkedCkProjectControl.value)
.pipe(
finalize(() => {
this.showProcessingLink = false;
})
)
.subscribe(({ code, message }) => {
if (!!code) {
this.linkedCkProjectControl.setValue('');
this.linkedCkProjectControl.enable();
this.run.connectCode = '';
this.teacherService.broadcastRunChanges(new TeacherRun(this.run));
}
this.snackBar.open($localize`${message}`);
});
}
}

private rollbackRandomPeriodAssignment() {
this.isRandomPeriodAssignment = this.run.isRandomPeriodAssignment;
}
Expand Down
1 change: 1 addition & 0 deletions src/app/teacher/teacher-run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Run } from '../domain/run';
export class TeacherRun extends Run {
isHighlighted: boolean;
shared: boolean;
connectCode: string;

constructor(jsonObject: any = {}) {
super(jsonObject);
Expand Down
Loading