From 45e6141e8c2b68f33b7f5687bfbd33a9c929973f Mon Sep 17 00:00:00 2001 From: Boink <40929320+b0ink@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:39:46 +1100 Subject: [PATCH 01/15] refactor: confirm recursive fix and resubmit for dependent tasks (#1132) * refactor: confirm recursive fix and resubmit for dependent tasks * refactor: move logic to task model --- src/app/api/models/task.ts | 65 ++++++++++++++++++- src/app/common/footer/footer.component.html | 2 +- src/app/common/footer/footer.component.ts | 36 ++++++++++ .../confirmation-modal.component.html | 4 +- .../confirmation-modal.component.ts | 17 ++++- .../confirmation-modal.service.ts | 8 ++- 6 files changed, 124 insertions(+), 8 deletions(-) diff --git a/src/app/api/models/task.ts b/src/app/api/models/task.ts index 2d7d995792..1ef90ca39e 100644 --- a/src/app/api/models/task.ts +++ b/src/app/api/models/task.ts @@ -24,10 +24,11 @@ import { import {Grade} from './grade'; import {LOCALE_ID} from '@angular/core'; import {HttpClient} from '@angular/common/http'; -import {Observable, map} from 'rxjs'; +import {Observable, firstValueFrom, map} from 'rxjs'; import {gradeTaskModal, uploadSubmissionModal} from 'src/app/ajs-upgraded-providers'; import {AlertService} from 'src/app/common/services/alert.service'; import {MappingFunctions} from '../services/mapping-fn'; +import {TaskPrerequisite} from './task-prerequisite'; export const FeedbackModerationAction = { ShowMore: 'show_more', @@ -681,6 +682,58 @@ export class Task extends Entity { ); } + private mapUnitTaskPrerequisites(prerequisites: TaskPrerequisite[]): TaskPrerequisite[] { + const definitions = this.unit.taskDefinitions; + + return prerequisites.map((prerequisite) => { + prerequisite.taskDefinition = definitions.find( + (td) => td.id === prerequisite.taskDefinitionId, + ); + prerequisite.prerequisite = definitions.find((td) => td.id === prerequisite.prerequisiteId); + return prerequisite; + }); + } + + private buildProjectTaskForDefinition(definition: TaskDefinition): Task { + const dependentTask = new Task(this.project); + dependentTask.project = this.project; + dependentTask.definition = definition; + return dependentTask; + } + + private async dependentTaskNeedsRecursiveFix(definition: TaskDefinition): Promise { + const cachedTask = this.project.findTaskForDefinition(definition.id); + if (cachedTask) { + return cachedTask.status === 'ready_for_feedback'; + } + + const dependentTask = this.buildProjectTaskForDefinition(definition); + const taskWithSubmissionDetails = await firstValueFrom(dependentTask.getSubmissionDetails()); + return taskWithSubmissionDetails.status === 'ready_for_feedback'; + } + + public async hasReadyForFeedbackDependents(): Promise { + const allPrerequisites = await firstValueFrom(this.unit.getTaskPrerequisites()); + const dependentPrerequisites = this.mapUnitTaskPrerequisites(allPrerequisites).filter( + (prerequisite) => prerequisite.prerequisiteId === this.definition.id, + ); + + for (const prerequisite of dependentPrerequisites) { + if (!prerequisite.taskDefinition) { + continue; + } + + const shouldTriggerRecursiveFix = await this.dependentTaskNeedsRecursiveFix( + prerequisite.taskDefinition, + ); + if (shouldTriggerRecursiveFix) { + return true; + } + } + + return false; + } + public get overseerEnabled(): boolean { return this.unit.overseerEnabled && this.definition.assessmentEnabled; } @@ -826,7 +879,11 @@ export class Task extends Entity { }); } - public updateTaskStatus(status: TaskStatusEnum, markAsDiscussed?: boolean) { + public updateTaskStatus( + status: TaskStatusEnum, + markAsDiscussed?: boolean, + triggerRecursiveFix?: boolean, + ) { const oldStatus = this.status; const alerts: AlertService = AppInjector.get(AlertService); @@ -851,6 +908,10 @@ export class Task extends Entity { options.body['discussed'] = true; } + if (triggerRecursiveFix === true) { + options.body['trigger_recursive_fix'] = true; + } + const hasId: boolean = this.id > 0; taskService diff --git a/src/app/common/footer/footer.component.html b/src/app/common/footer/footer.component.html index cb6e238c38..fb9eca0065 100644 --- a/src/app/common/footer/footer.component.html +++ b/src/app/common/footer/footer.component.html @@ -45,7 +45,7 @@ matTooltipPosition="above" aria-label="" class="button large-button" - (click)="selectedTask?.updateTaskStatus('fix')" + (click)="markAsResubmit(selectedTask)" > construction diff --git a/src/app/common/footer/footer.component.ts b/src/app/common/footer/footer.component.ts index 7626b63a6d..aab80e6fd5 100644 --- a/src/app/common/footer/footer.component.ts +++ b/src/app/common/footer/footer.component.ts @@ -7,6 +7,9 @@ import {FileDownloaderService} from '../file-downloader/file-downloader.service' import {TaskAssessmentModalService} from '../modals/task-assessment-modal/task-assessment-modal.service'; import {UnitRole} from 'src/app/api/models/unit-role'; import {UserService} from 'src/app/api/services/user.service'; +import {ProjectService} from 'src/app/api/services/project.service'; +import {ConfirmationModalService} from '../modals/confirmation-modal/confirmation-modal.service'; +import {AlertService} from '../services/alert.service'; @Component({ selector: 'f-footer', @@ -20,6 +23,9 @@ export class FooterComponent implements OnInit { private fileDownloader: FileDownloaderService, private taskAssessmentModal: TaskAssessmentModalService, private userService: UserService, + private projectService: ProjectService, + private confirmationModalService: ConfirmationModalService, + private alertService: AlertService, ) {} @Input() viewType: 'inbox' | 'explorer' | 'moderation' | 'overflow'; @@ -191,4 +197,34 @@ export class FooterComponent implements OnInit { public toggleModerationStatusButtons() { this.showModerationStatusButtons = !this.showModerationStatusButtons; } + + async markAsResubmit(task: Task) { + if (!task?.definition || !task?.project) { + return; + } + + try { + const hasReadyDependents = await task.hasReadyForFeedbackDependents(); + if (!hasReadyDependents) { + task.updateTaskStatus('fix_and_resubmit'); + return; + } + + this.confirmationModalService.show( + 'Move dependent tasks to Fix and Resubmit?', + 'This task is a prerequisite for one or more other tasks submitted by this student that are Ready for Feedback. Do you want to move those tasks to Fix and Resubmit as well?', + () => { + task.updateTaskStatus('fix_and_resubmit', false, true); + }, + () => { + task.updateTaskStatus('fix_and_resubmit'); + }, + 'Yes, update dependent tasks', + 'No, just this task', + ); + } catch (error) { + this.alertService.error(`Failed to check dependent task statuses: ${error}`, 6000); + task.updateTaskStatus('fix_and_resubmit'); + } + } } diff --git a/src/app/common/modals/confirmation-modal/confirmation-modal.component.html b/src/app/common/modals/confirmation-modal/confirmation-modal.component.html index 3ec07fc729..c976c7c75a 100644 --- a/src/app/common/modals/confirmation-modal/confirmation-modal.component.html +++ b/src/app/common/modals/confirmation-modal/confirmation-modal.component.html @@ -13,8 +13,8 @@

- + diff --git a/src/app/common/modals/confirmation-modal/confirmation-modal.component.ts b/src/app/common/modals/confirmation-modal/confirmation-modal.component.ts index f9506e5b8b..d0ef5a3691 100644 --- a/src/app/common/modals/confirmation-modal/confirmation-modal.component.ts +++ b/src/app/common/modals/confirmation-modal/confirmation-modal.component.ts @@ -5,7 +5,10 @@ import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; export interface ConfirmationModalData { title: string; message: string; - action?: any; + action?: () => void; + cancelAction?: () => void; + confirmText?: string; + cancelText?: string; } @Component({ @@ -17,6 +20,9 @@ export class ConfirmationModalComponent implements OnInit { @Input() title: string; @Input() message: string; @Input() action: () => void; + @Input() cancelActionFn: () => void; + @Input() confirmText: string; + @Input() cancelText: string; constructor( @Inject(AlertService) private alertService: AlertService, @@ -29,6 +35,9 @@ export class ConfirmationModalComponent implements OnInit { this.title = this.data.title; this.message = this.data.message; this.action = this.data.action; + this.cancelActionFn = this.data.cancelAction; + this.confirmText = this.data.confirmText ?? 'Confirm'; + this.cancelText = this.data.cancelText ?? 'Cancel'; } public confirmAction() { @@ -41,7 +50,11 @@ export class ConfirmationModalComponent implements OnInit { } public cancelAction() { - this.alertService.success(`${this.title} action cancelled.`); + if (typeof this.cancelActionFn === 'function') { + this.cancelActionFn(); + } else { + this.alertService.success(`${this.title} action cancelled.`); + } this.dialogRef.close(); } } diff --git a/src/app/common/modals/confirmation-modal/confirmation-modal.service.ts b/src/app/common/modals/confirmation-modal/confirmation-modal.service.ts index 660ddec60c..b14d252ebb 100644 --- a/src/app/common/modals/confirmation-modal/confirmation-modal.service.ts +++ b/src/app/common/modals/confirmation-modal/confirmation-modal.service.ts @@ -11,7 +11,10 @@ export class ConfirmationModalService { public show( title: string, message: string, - action?: any, + action?: () => void, + cancelAction?: () => void, + confirmText?: string, + cancelText?: string, ): MatDialogRef { return this.dialog.open( ConfirmationModalComponent, @@ -20,6 +23,9 @@ export class ConfirmationModalService { title, message, action, + cancelAction, + confirmText, + cancelText, }, position: {top: '2.5%'}, width: '100%', From 04f4d30043acf3d363acac2b141e84bdc4c11e41 Mon Sep 17 00:00:00 2001 From: b0ink <40929320+b0ink@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:40:24 +1100 Subject: [PATCH 02/15] chore(release): 10.0.1-23 --- CHANGELOG.md | 2 ++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a119c3b7d..7131db231d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [10.0.1-23](https://github.com/b0ink/doubtfire-deploy/compare/v10.0.1-22...v10.0.1-23) (2026-03-24) + ### [10.0.1-22](https://github.com/b0ink/doubtfire-deploy/compare/v10.0.1-21...v10.0.1-22) (2026-03-23) diff --git a/package-lock.json b/package-lock.json index 19291ceb8e..a94f140396 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "doubtfire", - "version": "10.0.1-22", + "version": "10.0.1-23", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "doubtfire", - "version": "10.0.1-22", + "version": "10.0.1-23", "license": "AGPL-3.0", "dependencies": { "@angular/animations": "^17.3.6", diff --git a/package.json b/package.json index 6a353dbcaa..b352e08f51 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "doubtfire", - "version": "10.0.1-22", + "version": "10.0.1-23", "homepage": "https://github.com/doubtfire-lms/", "description": "Learning and feedback tool.", "license": "AGPL-3.0", From b64601a425c7a64bccfaf47c1e4fccb0343b1589 Mon Sep 17 00:00:00 2001 From: b0ink <40929320+b0ink@users.noreply.github.com> Date: Tue, 24 Mar 2026 14:31:42 +1100 Subject: [PATCH 03/15] feat: confirm recursive fix in mobile tutor view --- .../tutor-discussion.component.ts | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/app/projects/states/tutor-discussion/tutor-discussion.component.ts b/src/app/projects/states/tutor-discussion/tutor-discussion.component.ts index 43416b60c1..84095a5436 100644 --- a/src/app/projects/states/tutor-discussion/tutor-discussion.component.ts +++ b/src/app/projects/states/tutor-discussion/tutor-discussion.component.ts @@ -17,6 +17,7 @@ import { UnitService, UserService, } from 'src/app/api/models/doubtfire-model'; +import {ConfirmationModalService} from 'src/app/common/modals/confirmation-modal/confirmation-modal.service'; import {AlertService} from 'src/app/common/services/alert.service'; import {GradeService} from 'src/app/common/services/grade.service'; @@ -66,6 +67,7 @@ export class TutorDiscussionComponent implements AfterViewInit { private gradeService: GradeService, private state: StateService, private alertService: AlertService, + private confirmationModalService: ConfirmationModalService, private route: UIRouter, private taskCommentService: TaskCommentService, private taskService: TaskService, @@ -262,7 +264,7 @@ export class TutorDiscussionComponent implements AfterViewInit { this.selectedTask = task; } - public setSelectedTasksStatus(status: TaskStatusEnum) { + public async setSelectedTasksStatus(status: TaskStatusEnum) { const selectedTasks = this.tasksList.selectedOptions.selected.map((taskOption) => { return taskOption.value as Task; }); @@ -279,6 +281,44 @@ export class TutorDiscussionComponent implements AfterViewInit { } } + if (status === 'fix_and_resubmit') { + try { + const hasReadyDependents = ( + await Promise.all( + selectedTasks.map((task) => + task?.definition && task?.project ? task.hasReadyForFeedbackDependents() : false, + ), + ) + ).some(Boolean); + + if (hasReadyDependents) { + this.confirmationModalService.show( + 'Move dependent tasks to Fix and Resubmit?', + 'One or more selected tasks are prerequisites for other tasks submitted by this student that are Ready for Feedback. Do you want to move those tasks to Fix and Resubmit as well?', + () => { + this.updateSelectedTasksStatus(selectedTasks, status, true); + }, + () => { + this.updateSelectedTasksStatus(selectedTasks, status, false); + }, + 'Yes, update dependent tasks', + 'No, just selected tasks', + ); + return; + } + } catch (error) { + this.alertService.error(`Failed to check dependent task statuses: ${error}`, 6000); + } + } + + this.updateSelectedTasksStatus(selectedTasks, status, false); + } + + private updateSelectedTasksStatus( + selectedTasks: Task[], + status: TaskStatusEnum, + moveDependentTasks: boolean, + ) { for (const task of selectedTasks) { if ( status === 'complete' && @@ -290,6 +330,8 @@ export class TutorDiscussionComponent implements AfterViewInit { if (task.definition.assessInPortfolioOnly) { task.updateTaskStatus(status === 'complete' ? 'working_on_it' : status, true); + } else if (status === 'fix_and_resubmit') { + task.updateTaskStatus(status, true, moveDependentTasks); } else { task.updateTaskStatus(status, true); } From f50a58e9737ce32eef772c48ef936f7819a1b9e1 Mon Sep 17 00:00:00 2001 From: b0ink <40929320+b0ink@users.noreply.github.com> Date: Tue, 24 Mar 2026 14:32:08 +1100 Subject: [PATCH 04/15] chore(release): 10.0.1-24 --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7131db231d..876c5cdbf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [10.0.1-24](https://github.com/b0ink/doubtfire-deploy/compare/v10.0.1-23...v10.0.1-24) (2026-03-24) + + +### Features + +* confirm recursive fix in mobile tutor view ([b64601a](https://github.com/b0ink/doubtfire-deploy/commit/b64601a425c7a64bccfaf47c1e4fccb0343b1589)) + ### [10.0.1-23](https://github.com/b0ink/doubtfire-deploy/compare/v10.0.1-22...v10.0.1-23) (2026-03-24) ### [10.0.1-22](https://github.com/b0ink/doubtfire-deploy/compare/v10.0.1-21...v10.0.1-22) (2026-03-23) diff --git a/package-lock.json b/package-lock.json index a94f140396..92ccf1dec9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "doubtfire", - "version": "10.0.1-23", + "version": "10.0.1-24", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "doubtfire", - "version": "10.0.1-23", + "version": "10.0.1-24", "license": "AGPL-3.0", "dependencies": { "@angular/animations": "^17.3.6", diff --git a/package.json b/package.json index b352e08f51..17bf3a09bd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "doubtfire", - "version": "10.0.1-23", + "version": "10.0.1-24", "homepage": "https://github.com/doubtfire-lms/", "description": "Learning and feedback tool.", "license": "AGPL-3.0", From 34fed4772fc2ed14586f53b6fac4ad695a18eb90 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2026 04:42:37 +0000 Subject: [PATCH 05/15] build(deps): bump angular-sanitize from 1.5.11 to 1.8.3 Bumps [angular-sanitize](https://github.com/angular/angular.js) from 1.5.11 to 1.8.3. - [Changelog](https://github.com/angular/angular.js/blob/master/CHANGELOG.md) - [Commits](https://github.com/angular/angular.js/compare/v1.5.11...v1.8.3) --- updated-dependencies: - dependency-name: angular-sanitize dependency-version: 1.8.3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 +++++--- package.json | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 92ccf1dec9..484310a5bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,7 +40,7 @@ "angular-mocks": "1.8.3", "angular-nvd3": "1.0.9", "angular-resource": "1.5.11", - "angular-sanitize": "1.5.11", + "angular-sanitize": "1.8.3", "angular-ui-bootstrap": "0.13.4", "angular-ui-codemirror": "0.3.0", "angular-xeditable": "0.9.0", @@ -6611,7 +6611,10 @@ "license": "MIT" }, "node_modules/angular-sanitize": { - "version": "1.5.11", + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/angular-sanitize/-/angular-sanitize-1.8.3.tgz", + "integrity": "sha512-2rxdqzlUVafUeWOwvY/FtyWk1pFTyCtzreeiTytG9m4smpuAEKaIJAjYeVwWsoV+nlTOcgpwV4W1OCmR+BQbUg==", + "deprecated": "For the actively supported Angular, see https://www.npmjs.com/package/@angular/core. AngularJS support has officially ended. For extended AngularJS support options, see https://goo.gle/angularjs-path-forward.", "license": "MIT" }, "node_modules/angular-ui-bootstrap": { @@ -11200,7 +11203,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ diff --git a/package.json b/package.json index 17bf3a09bd..4f08306194 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "angular-mocks": "1.8.3", "angular-nvd3": "1.0.9", "angular-resource": "1.5.11", - "angular-sanitize": "1.5.11", + "angular-sanitize": "1.8.3", "angular-ui-bootstrap": "0.13.4", "angular-ui-codemirror": "0.3.0", "angular-xeditable": "0.9.0", From 248c992f46488f61916e00a87ca32ed987721f31 Mon Sep 17 00:00:00 2001 From: b0ink <40929320+b0ink@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:19:11 +1100 Subject: [PATCH 06/15] feat: display sso redirecting state --- src/app/sessions/states/sign-in/sign-in.component.html | 9 ++++++++- src/app/sessions/states/sign-in/sign-in.component.ts | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/app/sessions/states/sign-in/sign-in.component.html b/src/app/sessions/states/sign-in/sign-in.component.html index 74fd6b7b99..29b7743d41 100644 --- a/src/app/sessions/states/sign-in/sign-in.component.html +++ b/src/app/sessions/states/sign-in/sign-in.component.html @@ -57,7 +57,14 @@

type="form" [disabled]="form.invalid" > - Sign In +
+ @if (redirectingSSO) { + Signing In... + + } @else { + Sign In + } +
diff --git a/src/app/sessions/states/sign-in/sign-in.component.ts b/src/app/sessions/states/sign-in/sign-in.component.ts index 8f047489d4..2196ee83c9 100644 --- a/src/app/sessions/states/sign-in/sign-in.component.ts +++ b/src/app/sessions/states/sign-in/sign-in.component.ts @@ -54,6 +54,8 @@ export class SignInComponent implements OnInit { public isLoading: boolean = true; public authMethodFailed: boolean = false; + public redirectingSSO: boolean = false; + // Get query params from the resolve in the router state @Input() username: string; @Input() authToken: string; @@ -163,10 +165,13 @@ export class SignInComponent implements OnInit { }); } else if (this.SSOLoginUrl) { if (this.autoLogin) { + this.redirectingSSO = true; return wait.then(() => { // Double check in case changed in the meantime if (this.autoLogin) { this.redirectToSSO(); + } else { + this.redirectingSSO = false; } }); } else { From 12fbf8147107dc185a9a9cbea940efac93a0f316 Mon Sep 17 00:00:00 2001 From: Boink <40929320+b0ink@users.noreply.github.com> Date: Thu, 26 Mar 2026 13:05:50 +1100 Subject: [PATCH 07/15] feat: pause feedback threshold during teaching period breaks (#1138) * feat: pause feedback threshold during teaching period breaks * chore: round down days --- src/app/api/models/task.ts | 43 +++++++++++++++++++ .../staff-task-list.component.ts | 5 +-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/app/api/models/task.ts b/src/app/api/models/task.ts index 1ef90ca39e..26488452d3 100644 --- a/src/app/api/models/task.ts +++ b/src/app/api/models/task.ts @@ -152,6 +152,49 @@ export class Task extends Entity { return this.project.unit; } + private getBreakOverlapMilliseconds( + startTime: number, + endTime: number, + breaks: readonly {startDate: Date; numberOfWeeks: number}[], + ): number { + const millisecondsPerDay = 1000 * 60 * 60 * 24; + + return breaks.reduce((overlap, teachingBreak) => { + const breakStart = new Date(teachingBreak.startDate).getTime(); + const breakDuration = (teachingBreak.numberOfWeeks ?? 0) * 7 * millisecondsPerDay; + const breakEnd = breakStart + breakDuration; + + if (!Number.isFinite(breakStart) || breakDuration <= 0) { + return overlap; + } + + const overlapStart = Math.max(startTime, breakStart); + const overlapEnd = Math.min(endTime, breakEnd); + + return overlap + Math.max(0, overlapEnd - overlapStart); + }, 0); + } + + public daysSinceSubmission(nowTime = Date.now()): number { + const millisecondsPerDay = 1000 * 60 * 60 * 24; + const submissionTime = new Date(this.submissionDate).getTime(); + + if (!Number.isFinite(submissionTime) || nowTime <= submissionTime) { + return 0; + } + + const teachingBreaks = this.unit.teachingPeriod?.breaks ?? []; + const pausedMilliseconds = this.getBreakOverlapMilliseconds( + submissionTime, + nowTime, + teachingBreaks, + ); + + return Math.floor( + Math.max(0, nowTime - submissionTime - pausedMilliseconds) / millisecondsPerDay, + ); + } + /** * Determine if a task matches a given search text. * diff --git a/src/app/units/states/tasks/inbox/directives/staff-task-list/staff-task-list.component.ts b/src/app/units/states/tasks/inbox/directives/staff-task-list/staff-task-list.component.ts index 1d3c166609..3b65b4247e 100644 --- a/src/app/units/states/tasks/inbox/directives/staff-task-list/staff-task-list.component.ts +++ b/src/app/units/states/tasks/inbox/directives/staff-task-list/staff-task-list.component.ts @@ -572,10 +572,7 @@ export class StaffTaskListComponent implements OnInit, OnChanges, OnDestroy { return null; } - const now = Date.now(); - const submission = new Date(task.submissionDate).getTime(); - - const daysSinceSubmission = (now - submission) / (1000 * 60 * 60 * 24); + const daysSinceSubmission = task.daysSinceSubmission(); if (daysSinceSubmission >= task.unit.feedbackOverflowThresholdDays) { return 'overflow'; From 01a407e99ecaf66ea4fed5babba5a9ae091ab80f Mon Sep 17 00:00:00 2001 From: b0ink <40929320+b0ink@users.noreply.github.com> Date: Fri, 27 Mar 2026 10:41:15 +1100 Subject: [PATCH 08/15] chore: ensure tasks not in overflow are filtered out - this may be due to the breaks re-calculated client-side --- src/app/api/services/task.service.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/app/api/services/task.service.ts b/src/app/api/services/task.service.ts index 8aaa3805a2..d3d517fe1e 100644 --- a/src/app/api/services/task.service.ts +++ b/src/app/api/services/task.service.ts @@ -188,6 +188,9 @@ export class TaskService extends CachedEntityService { constructorParams: unit, }, ).pipe( + map((tasks: Task[]) => + tasks.filter((t) => t.daysSinceSubmission() >= t.unit.feedbackOverflowThresholdDays), + ), tap((tasks: Task[]) => { unit.incorporateTasks(tasks); }), From 5eb855fb03273e1bcc73ffb983ab3f2e44e7ddb9 Mon Sep 17 00:00:00 2001 From: b0ink <40929320+b0ink@users.noreply.github.com> Date: Fri, 27 Mar 2026 10:42:30 +1100 Subject: [PATCH 09/15] chore(release): 10.0.1-25 --- CHANGELOG.md | 8 ++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 876c5cdbf4..466f028547 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [10.0.1-25](https://github.com/b0ink/doubtfire-deploy/compare/v10.0.1-24...v10.0.1-25) (2026-03-26) + + +### Features + +* display sso redirecting state ([248c992](https://github.com/b0ink/doubtfire-deploy/commit/248c992f46488f61916e00a87ca32ed987721f31)) +* pause feedback threshold during teaching period breaks ([#1138](https://github.com/b0ink/doubtfire-deploy/issues/1138)) ([12fbf81](https://github.com/b0ink/doubtfire-deploy/commit/12fbf8147107dc185a9a9cbea940efac93a0f316)) + ### [10.0.1-24](https://github.com/b0ink/doubtfire-deploy/compare/v10.0.1-23...v10.0.1-24) (2026-03-24) diff --git a/package-lock.json b/package-lock.json index 92ccf1dec9..f5b9dd4f50 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "doubtfire", - "version": "10.0.1-24", + "version": "10.0.1-25", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "doubtfire", - "version": "10.0.1-24", + "version": "10.0.1-25", "license": "AGPL-3.0", "dependencies": { "@angular/animations": "^17.3.6", diff --git a/package.json b/package.json index 17bf3a09bd..2385105a13 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "doubtfire", - "version": "10.0.1-24", + "version": "10.0.1-25", "homepage": "https://github.com/doubtfire-lms/", "description": "Learning and feedback tool.", "license": "AGPL-3.0", From a9bd5c6ad1cb9d63ad5e7e9c67ff86b9496f8875 Mon Sep 17 00:00:00 2001 From: b0ink <40929320+b0ink@users.noreply.github.com> Date: Fri, 27 Mar 2026 10:50:41 +1100 Subject: [PATCH 10/15] chore: display days since submission in tooltip --- .../staff-task-list/staff-task-list.component.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/app/units/states/tasks/inbox/directives/staff-task-list/staff-task-list.component.html b/src/app/units/states/tasks/inbox/directives/staff-task-list/staff-task-list.component.html index 5912585804..2f96b676bb 100644 --- a/src/app/units/states/tasks/inbox/directives/staff-task-list/staff-task-list.component.html +++ b/src/app/units/states/tasks/inbox/directives/staff-task-list/staff-task-list.component.html @@ -269,7 +269,11 @@

} @else if (getWarningIcon(task) === 'overflow') { watch_later From 6d283c805d209447821526b785d7341272aac544 Mon Sep 17 00:00:00 2001 From: b0ink <40929320+b0ink@users.noreply.github.com> Date: Fri, 27 Mar 2026 10:51:47 +1100 Subject: [PATCH 11/15] chore(release): 10.0.1-26 --- CHANGELOG.md | 2 ++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 466f028547..9f6d6fd1f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [10.0.1-26](https://github.com/b0ink/doubtfire-deploy/compare/v10.0.1-25...v10.0.1-26) (2026-03-26) + ### [10.0.1-25](https://github.com/b0ink/doubtfire-deploy/compare/v10.0.1-24...v10.0.1-25) (2026-03-26) diff --git a/package-lock.json b/package-lock.json index f5b9dd4f50..fafb6cfb40 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "doubtfire", - "version": "10.0.1-25", + "version": "10.0.1-26", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "doubtfire", - "version": "10.0.1-25", + "version": "10.0.1-26", "license": "AGPL-3.0", "dependencies": { "@angular/animations": "^17.3.6", diff --git a/package.json b/package.json index 2385105a13..7fb9743a25 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "doubtfire", - "version": "10.0.1-25", + "version": "10.0.1-26", "homepage": "https://github.com/doubtfire-lms/", "description": "Learning and feedback tool.", "license": "AGPL-3.0", From fe1813f2bcf63fb1d448bc5e1606e09d557048f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 00:47:30 +0000 Subject: [PATCH 12/15] build(deps-dev): bump node-forge from 1.3.3 to 1.4.0 Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.3.3 to 1.4.0. - [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md) - [Commits](https://github.com/digitalbazaar/forge/compare/v1.3.3...v1.4.0) --- updated-dependencies: - dependency-name: node-forge dependency-version: 1.4.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index fafb6cfb40..ca3c60ad20 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11200,7 +11200,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -16396,9 +16395,9 @@ } }, "node_modules/node-forge": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz", - "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", + "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", "dev": true, "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { From 27e9733193afc41f353e2f773edb7bb63ebe2fce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 13:55:39 +0000 Subject: [PATCH 13/15] build(deps-dev): bump brace-expansion from 1.1.11 to 1.1.13 Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 1.1.11 to 1.1.13. - [Release notes](https://github.com/juliangruber/brace-expansion/releases) - [Commits](https://github.com/juliangruber/brace-expansion/compare/1.1.11...v1.1.13) --- updated-dependencies: - dependency-name: brace-expansion dependency-version: 1.1.13 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 57 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index fafb6cfb40..b185c46c35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3413,7 +3413,9 @@ "license": "Python-2.0" }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -3495,7 +3497,9 @@ } }, "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -7580,7 +7584,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "2.0.1", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -10081,7 +10087,9 @@ } }, "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -10253,7 +10261,9 @@ "license": "Python-2.0" }, "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -11200,7 +11210,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -11446,7 +11455,9 @@ "license": "BSD-2-Clause" }, "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "devOptional": true, "license": "MIT", "dependencies": { @@ -11591,7 +11602,9 @@ } }, "node_modules/globule/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -12761,7 +12774,9 @@ } }, "node_modules/grunt/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -14232,7 +14247,9 @@ "license": "MIT" }, "node_modules/jake/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -14550,7 +14567,9 @@ } }, "node_modules/jshint/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -14867,7 +14886,9 @@ } }, "node_modules/karma-coverage-istanbul-reporter/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -14938,7 +14959,9 @@ } }, "node_modules/karma/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -16062,7 +16085,9 @@ } }, "node_modules/multimatch/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -21543,7 +21568,9 @@ } }, "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { From 821504a83cd7535b0b05f0e81be7464e563bd9f1 Mon Sep 17 00:00:00 2001 From: Sujay-Deakin Date: Mon, 13 Apr 2026 19:14:09 +1000 Subject: [PATCH 14/15] docs: investigate migration of unit-task-list to f-unit-task-list --- package-lock.json | 9 +++++---- package.json | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 169f01ca68..036b9f4b95 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,7 +40,7 @@ "angular-mocks": "1.8.3", "angular-nvd3": "1.0.9", "angular-resource": "1.5.11", - "angular-sanitize": "1.8.3", + "angular-sanitize": "1.5.11", "angular-ui-bootstrap": "0.13.4", "angular-ui-codemirror": "0.3.0", "angular-xeditable": "0.9.0", @@ -6615,9 +6615,9 @@ "license": "MIT" }, "node_modules/angular-sanitize": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/angular-sanitize/-/angular-sanitize-1.8.3.tgz", - "integrity": "sha512-2rxdqzlUVafUeWOwvY/FtyWk1pFTyCtzreeiTytG9m4smpuAEKaIJAjYeVwWsoV+nlTOcgpwV4W1OCmR+BQbUg==", + "version": "1.5.11", + "resolved": "https://registry.npmjs.org/angular-sanitize/-/angular-sanitize-1.5.11.tgz", + "integrity": "sha512-9yVOr8YOefo0/4q+ImqNdGcbfGzelQIoHW0OoaoU/U5wpRZNn5IqlkdLW9udieSiprYzuXeqiS1V7ZiHurYisw==", "deprecated": "For the actively supported Angular, see https://www.npmjs.com/package/@angular/core. AngularJS support has officially ended. For extended AngularJS support options, see https://goo.gle/angularjs-path-forward.", "license": "MIT" }, @@ -11213,6 +11213,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ diff --git a/package.json b/package.json index 03f925ec90..7fb9743a25 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "angular-mocks": "1.8.3", "angular-nvd3": "1.0.9", "angular-resource": "1.5.11", - "angular-sanitize": "1.8.3", + "angular-sanitize": "1.5.11", "angular-ui-bootstrap": "0.13.4", "angular-ui-codemirror": "0.3.0", "angular-xeditable": "0.9.0", From ff4ae20a1b8e66618c5aa3528d228f09505f118f Mon Sep 17 00:00:00 2001 From: Sujay-Deakin Date: Sun, 3 May 2026 14:59:43 +1000 Subject: [PATCH 15/15] feat: remove dead code unit-task-list replaced by f-unit-task-list --- .../unit-task-list/unit-task-list.coffee | 41 ------------------- .../unit-task-list/unit-task-list.scss | 3 -- .../unit-task-list/unit-task-list.tpl.html | 30 -------------- 3 files changed, 74 deletions(-) delete mode 100644 src/app/units/states/tasks/viewer/directives/unit-task-list/unit-task-list.coffee delete mode 100644 src/app/units/states/tasks/viewer/directives/unit-task-list/unit-task-list.scss delete mode 100644 src/app/units/states/tasks/viewer/directives/unit-task-list/unit-task-list.tpl.html diff --git a/src/app/units/states/tasks/viewer/directives/unit-task-list/unit-task-list.coffee b/src/app/units/states/tasks/viewer/directives/unit-task-list/unit-task-list.coffee deleted file mode 100644 index aa30c611e4..0000000000 --- a/src/app/units/states/tasks/viewer/directives/unit-task-list/unit-task-list.coffee +++ /dev/null @@ -1,41 +0,0 @@ -angular.module('doubtfire.units.states.tasks.viewer.directives.unit-task-list', []) - -.directive('unitTaskList', -> - restrict: 'E' - templateUrl: 'units/states/tasks/viewer/directives/unit-task-list/unit-task-list.tpl.html' - scope: - unit: '=' - # Function to invoke to refresh tasks - refreshTasks: '=?' - unitTasks: '=' - selectedTaskDef: '=' - controller: ($scope, $timeout, $filter, gradeService, listenerService) -> - listeners = listenerService.listenTo($scope) - # Set up initial filtered tasks - $scope.filteredTasks = [] - # Set up filters - $scope.filters = { - taskSearch:null - } - # Sets new filteredTasks variable - applyFilters = -> - filteredTasks = $filter('taskDefinitionName')($scope.unitTasks, $scope.filters.taskSearch) - filteredTasks = $filter('orderBy')(filteredTasks, 'task.seq') - $scope.filteredTasks = filteredTasks - # Apply filters first-time - applyFilters() - # When refreshing tasks, we are just reloading the active tasks - $scope.refreshTasks = applyFilters - # Expose grade service names - $scope.gradeNames = gradeService.grades - # On task name change, reapply filters - $scope.taskNameChanged = applyFilters - # UI call to change currently selected task - $scope.setSelectedTask = (task) -> - $scope.selectedTaskDef = task - - - $scope.isSelectedTask = (task) -> - # Compare by definition - task.id == $scope.selectedTaskDef?.id -) diff --git a/src/app/units/states/tasks/viewer/directives/unit-task-list/unit-task-list.scss b/src/app/units/states/tasks/viewer/directives/unit-task-list/unit-task-list.scss deleted file mode 100644 index b17c5d3b7b..0000000000 --- a/src/app/units/states/tasks/viewer/directives/unit-task-list/unit-task-list.scss +++ /dev/null @@ -1,3 +0,0 @@ -unit-task-list { - @include task-list(); -} diff --git a/src/app/units/states/tasks/viewer/directives/unit-task-list/unit-task-list.tpl.html b/src/app/units/states/tasks/viewer/directives/unit-task-list/unit-task-list.tpl.html deleted file mode 100644 index 4a0db812c4..0000000000 --- a/src/app/units/states/tasks/viewer/directives/unit-task-list/unit-task-list.tpl.html +++ /dev/null @@ -1,30 +0,0 @@ -
-
- -
-
    -
  • -
    -

    {{task.name}}

    -

    - {{task.abbreviation}} - {{gradeNames[task.targetGrade]}} Task -

    -
    - -
  • - -
  • No tasks to display.
  • -
-