Skip to content

Commit

Permalink
refactor: task definition editor task list progress
Browse files Browse the repository at this point in the history
  • Loading branch information
macite committed Jul 20, 2023
1 parent 7d137c8 commit 82425c7
Show file tree
Hide file tree
Showing 8 changed files with 229 additions and 67 deletions.
57 changes: 57 additions & 0 deletions src/app/api/models/task-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Observable, tap } from 'rxjs';
import { AppInjector } from 'src/app/app-injector';
import { DoubtfireConstants } from 'src/app/config/constants/doubtfire-constants';
import { Grade, GroupSet, TutorialStream, Unit } from './doubtfire-model';
import { TaskDefinitionService } from '../services/task-definition.service';

export type UploadRequirement = { key: string; name: string; type: string; tiiCheck?: boolean; tiiPct?: number };

Expand Down Expand Up @@ -50,6 +51,62 @@ export class TaskDefinition extends Entity {
};
}

/**
* Save the task definition
*/
public save(): Observable<TaskDefinition> {
const svc = AppInjector.get(TaskDefinitionService);

if (this.isNew) {
// TODO: add progress modal
return svc.create(
{
unitId: this.unit.id,
},
{
entity: this,
cache: this.unit.taskDefinitionCache,
constructorParams: this.unit,
}
);
} else {
return svc.update(
{
unitId: this.unit.id,
id: this.id,
},
{ entity: this }
);
}
}

private originalSaveData: string;

/**
* To check if things have changed, we need to get the initial save data... as it
* isn't empty by default. We can then use
* this to check if there are changes.
*
* @param mapping the mapping to get changes
*/
public setOriginalSaveData(mapping: EntityMapping<TaskDefinition>) {
if (!this.originalSaveData) {
this.originalSaveData = JSON.stringify(this.toJson(mapping));
}
}

public hasChanges<T extends Entity>(mapping: EntityMapping<T>): boolean {
if (!this.originalSaveData) {
return false;
}

return this.originalSaveData != JSON.stringify(this.toJson(mapping));
}

public get isNew(): boolean {
return !this.id;
}

public get unitId(): number {
return this.unit.id;
}
Expand Down
6 changes: 3 additions & 3 deletions src/app/api/services/mapping-fn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ export class MappingFunctions {
public static mapDayToJson<T>(entity: T, key: string): string {
if (entity[key]) {
const month = entity[key].getMonth() + 1;
return `${entity[key].getFullYear()}-${month < 10 ? '0' : ''}${month}-${entity[key].getDate()}`;
}
else {
const day = entity[key].getDate();
return `${entity[key].getFullYear()}-${month < 10 ? '0' : ''}${month}-${day < 10 ? '0' : ''}${day}`;
} else {
return undefined;
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/app/api/services/task-definition.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,11 @@ export class TaskDefinitionService extends CachedEntityService<TaskDefinition> {
{
keys: ['groupSet', 'group_set_id'],
toEntityFn: (data: object, key: string, taskDef: TaskDefinition, params?: any) => {
return taskDef.unit.groupSetsCache.get(data[key]);
if (data[key]) {
return taskDef.unit.groupSetsCache.get(data[key]);
} else {
return data[key];
}
},
toJsonFn: (taskDef: TaskDefinition, key: string) => {
return taskDef.groupSet?.id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ <h3 class="flex-grow">Name the task and indicate its target grade</h3>
<div class="flex flex-col">
<div class="flex flex-row gap-4">
<mat-icon class="basis-auto">school</mat-icon>
<h3 class="flex-grow">Who assesses and submits this task?</h3>
<h3 class="flex-grow">Who assesses {{ unit.hasGroupwork() ? 'and submits ' : '' }}this task?</h3>
</div>
<f-task-definition-who [taskDefinition]="taskDefinition"></f-task-definition-who>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,16 @@ import { AlertService } from 'src/app/common/services/alert.service';
export class TaskDefinitionEditorComponent {
@Input() taskDefinition: TaskDefinition;
@Input() unit: Unit;
@Input() isNew: boolean;

constructor(private taskDefinitionService: TaskDefinitionService, private alerts: AlertService) {}

public save() {
if (this.isNew) {
// TODO: add progress modal
this.taskDefinitionService
.create(
{
unitId: this.unit.id,
},
{
entity: this.taskDefinition,
cache: this.unit.taskDefinitionCache,
constructorParams: this.unit,
}
)
.subscribe({
next: (response) => this.alerts.success('Task Added', 2000),
error: (message) => this.alerts.error(message, 6000),
});
} else {
this.taskDefinitionService
.update(
{
unitId: this.unit.id,
id: this.taskDefinition.id,
},
{ entity: this.taskDefinition }
)
.subscribe({
next: (response) => this.alerts.success('Task Updated', 2000),
error: (message) => this.alerts.error(message, 6000),
});
}
this.taskDefinition.save().subscribe({
next: (response) => {
this.alerts.success('Task Saved');
response.setOriginalSaveData(this.taskDefinitionService.mapping);
},
error: (message) => this.alerts.error(message),
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<div class="flex-grow" appDragDrop (fileDropped)="uploadTaskSheet($event)" style="background-color: red;"><mat-icon>upload</mat-icon> Task Sheet</div>
<div *ngIf="taskDefinition.hasTaskSheet">
<button mat-flat-button (click)="downloadTaskSheet()" class="flex-grow">Download Task Sheet</button>
<button mat-flat-button color="warn" (click)="removeTaskSheet()" class="flex-grow">Delete</button>
<button mat-flat-button color="warn" (click)="removeTaskSheet()" class="flex-grow">Delete Task Sheet</button>
</div>
</div>
<div class="basis-1/2 flex flex-col">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,98 @@
<div class="flex flex-row gap-8">
<div class="flex-grow flex flex-col gap-8">
<div class="flex-grow flex flex-row">
<div class="flex flex-row">
<div>
<h3>Task List</h3>
<p>Plan the list of tasks for students to complete.</p>
</div>
<span class="flex-grow"></span>
<mat-form-field appearance="outline">
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter" [(ngModel)]="filter" />
</mat-form-field>
<div>
<mat-form-field appearance="outline">
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter" [(ngModel)]="filter" />
</mat-form-field>
</div>
</div>

<table class="flex-grow" mat-table [dataSource]="taskDefinitionSource" matSort (matSortChange)="sortData($event)">
<table class="flex-grow f-table" mat-table [dataSource]="taskDefinitionSource" matSort (matSortChange)="sortData($event)">
<ng-container matColumnDef="name" sticky>
<th mat-header-cell *matHeaderCellDef mat-sort-header>Task Name</th>
<td mat-cell *matCellDef="let taskDefinition">
<td mat-cell *matCellDef="let taskDefinition" (click)="selectTaskDefinition(taskDefinition)">
{{ taskDefinition.abbreviation }} {{ taskDefinition.name }}
</td>
</ng-container>
<ng-container matColumnDef="grade" sticky>
<th mat-header-cell *matHeaderCellDef mat-sort-header>Grade</th>
<td mat-cell *matCellDef="let taskDefinition" (click)="selectTaskDefinition(taskDefinition)">
{{ taskDefinition.targetGradeText }}
</td>
</ng-container>
<ng-container matColumnDef="startDate" sticky>
<th mat-header-cell *matHeaderCellDef mat-sort-header>Start Date</th>
<td mat-cell *matCellDef="let taskDefinition" (click)="selectTaskDefinition(taskDefinition)">
{{ taskDefinition.startDate | date : 'd LLL y' }}
</td>
</ng-container>
<ng-container matColumnDef="targetDate" sticky>
<th mat-header-cell *matHeaderCellDef mat-sort-header>Due Date</th>
<td mat-cell *matCellDef="let taskDefinition" (click)="selectTaskDefinition(taskDefinition)">
{{ taskDefinition.targetDate | date : 'd LLL y' }}
</td>
</ng-container>
<ng-container matColumnDef="deadlineDate" sticky>
<th mat-header-cell *matHeaderCellDef mat-sort-header>Deadline</th>
<td mat-cell *matCellDef="let taskDefinition" (click)="selectTaskDefinition(taskDefinition)">
{{ taskDefinition.dueDate | date : 'd LLL y' }}
</td>
</ng-container>
<ng-container matColumnDef="taskDefAction" sticky>
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let taskDefinition">
<button
mat-icon-button
aria-label="save task definition"
color="primary"
(click)="saveTaskDefinition(taskDefinition)"
*ngIf="taskDefinitionHasChanges(taskDefinition)"
>
<mat-icon>save</mat-icon>
</button>
<button
mat-icon-button
aria-label="delete task definition"
color="warn"
(click)="deleteTaskDefinition(taskDefinition)"
>
<mat-icon>delete</mat-icon>
</button>
</td>
</ng-container>

<!-- Action footer row -->
<ng-container matColumnDef="actions">
<td mat-footer-cell *matFooterCellDef [colSpan]="columns.length">
<mat-toolbar>
<mat-toolbar-row>
<mat-paginator class="mat-elevation-z0" [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
<span class="flex-grow"></span>
<button mat-raised-button color="primary" (click)="createTaskDefinition()">Add Task</button>
</mat-toolbar-row>
</mat-toolbar>
</td>
</ng-container>

<tr mat-header-row *matHeaderRowDef="columns"></tr>
<tr mat-row *matRowDef="let row; columns: columns;" (click)="selectTaskDefinition(row)" [style.background]="selectedTaskDefinition === row ? 'lightblue' : ''"></tr>
<tr
mat-row
*matRowDef="let row; columns: columns"
[style.background]="selectedTaskDefinition === row ? 'lightblue' : ''"
></tr>
<tr mat-footer-row *matFooterRowDef="['actions']"></tr>
</table>
<f-task-definition-editor *ngIf="selectedTaskDefinition" [taskDefinition]="selectedTaskDefinition" [unit]="unit" [isNew]="false"></f-task-definition-editor>
<f-task-definition-editor
*ngIf="selectedTaskDefinition"
[taskDefinition]="selectedTaskDefinition"
[unit]="unit"
></f-task-definition-editor>
</div>
<div class="flex flex-col gap-4">
<h3>Batch Upload Tasks</h3>
Expand All @@ -43,8 +101,8 @@ <h3>Batch Upload Tasks</h3>

<h3>Download Tasks</h3>
<p>Download all task definitions for this unit.</p>
<button mat-flat-button (click)="downloadTaskDefinitions()">Download Tasks CSV</button>
<button mat-flat-button (click)="downladTaskDefinitionsZip()">Download Tasks and Resources</button>
<button mat-flat-button color="accent" (click)="downloadTaskDefinitions()">Download Tasks CSV</button>
<button mat-flat-button color="accent" (click)="downladTaskDefinitionsZip()">Download Tasks and Resources</button>

<h3>Batch Upload Task PDFs</h3>
<p>Upload all of the task PDFs in a Zip file.</p>
Expand Down
Loading

0 comments on commit 82425c7

Please sign in to comment.