Skip to content
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
5 changes: 4 additions & 1 deletion src/app/doubtfire.states.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,10 @@ const AdministerUnits: NgHybridStateDeclaration = {
const ProjectDashboardState: NgHybridStateDeclaration = {
name: 'dashboard2',
parent: 'projects2',
url: '/dashboard2',
url: '/dashboard2/:taskAbbreviation?',
params: {
taskAbbreviation: {value: null, squash: true, dynamic: true},
},
views: {
projectView: {
component: ProjectDashboardComponent,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,50 @@
<div class="w-full h-full overflow-auto">
<!-- <f-project-progress></f-project-progress> -->

<mat-tab-group
[(selectedIndex)]="currentIndex"
dynamicHeight
(selectedTabChange)="onTabChange($event)"
>
<mat-tab label="Task Details"></mat-tab>
<mat-tab label="Task Sheet" [disabled]="!task.definition.hasTaskSheet"></mat-tab>
<mat-tab label="Submission" [disabled]="!task.hasPdf"></mat-tab>
</mat-tab-group>
<ng-container [ngSwitch]="currentView">
<ng-template [ngSwitchCase]="DashboardViews.details">
<div class="flex flex-col gap-5 p-5">
<f-task-scorm-card [task]="task"></f-task-scorm-card>
<f-task-status-card [task]="task"></f-task-status-card>
<f-task-due-card [task]="task"></f-task-due-card>
<f-task-description-card
[taskDef]="task.definition"
[task]="task"
[unit]="task.unit"
></f-task-description-card>
<f-task-assessment-card [task]="task"></f-task-assessment-card>
<f-task-submission-card [task]="task"></f-task-submission-card>
</div>
</ng-template>

<ng-template [ngSwitchCase]="DashboardViews.task">
<ng-container
*ngIf="selectedTaskService.hasTaskSheet; then pdfViewer; else noPdfUrl"
></ng-container>
@if (task.definition.hasTaskSheet) {
<f-pdf-viewer [pdfUrl]="task.definition.getTaskPDFUrl()"></f-pdf-viewer>
} @else {
<div class="flex flex-col w-full h-full justify-center items-center">
<mat-icon>subtitles_off</mat-icon>
</div>
<!-- <ng-container noPdfUrl></ng-container> -->
}
</ng-template>

<ng-template [ngSwitchCase]="DashboardViews.submission">
<ng-container
*ngIf="selectedTaskService.hasSubmissionPdf; then pdfViewer; else noPdfUrl"
></ng-container>
@if (task.hasPdf) {
<f-pdf-viewer [pdfUrl]="task.submissionUrl()"></f-pdf-viewer>
} @else {
<div class="flex flex-col w-full h-full justify-center items-center">
<mat-icon>subtitles_off</mat-icon>
</div>
<!-- <ng-container noPdfUrl></ng-container> -->
}
</ng-template>

<ng-template [ngSwitchCase]="DashboardViews.similarity">
Expand All @@ -20,9 +53,9 @@
</ng-container>

<!-- The PDF Viewer -->
<ng-template #pdfViewer>
<!-- <ng-template #pdfViewer>
<f-pdf-viewer [pdfUrl]="pdfUrl"></f-pdf-viewer>
</ng-template>
</ng-template> -->

<!-- Render if no PDF URL is available for the current view -->
<ng-template #noPdfUrl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {DoubtfireConstants} from 'src/app/config/constants/doubtfire-constants';
import {SelectedTaskService} from '../../selected-task.service';
import {DashboardViews} from '../../selected-task.service';
import {TooltipService} from '@swimlane/ngx-charts';
import {SelectionChange} from '@angular/cdk/collections';
import {MatTabChangeEvent} from '@angular/material/tabs';

@Component({
selector: 'f-task-dashboard',
Expand All @@ -42,18 +44,38 @@ export class TaskDashboardComponent implements OnInit, OnChanges {
public overseerEnabledObs = this.doubtfire.IsOverseerEnabled;
public currentView: DashboardViews;

public currentIndex;

onTabChange(event: MatTabChangeEvent) {
switch (event.index) {
case 0:
this.currentView = DashboardViews.details;
break;
case 1:
this.currentView = DashboardViews.task;
break;
case 2:
this.currentView = DashboardViews.submission;
break;
case 3:
this.currentView = DashboardViews.similarity;
break;
}

console.log(this.currentView);
}

constructor(
private doubtfire: DoubtfireConstants,
private taskService: TaskService,
private taskAssessmentModal: TaskAssessmentModalService,
private fileDownloader: FileDownloaderService,
private router: UIRouter,
public selectedTaskService: SelectedTaskService,
) {
}
) {}

ngOnInit(): void {
this.selectedTaskService.currentView$.next(DashboardViews.submission);
this.selectedTaskService.currentView$.next(DashboardViews.details);
this.selectedTaskService.currentView$.subscribe((view) => {
this.currentView = view;
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,44 @@
<div class="w-full h-full" *ngIf="project$ | async as project">
<div class="flex flex-row">
<f-unit-task-list
class="min-w-[300px] w-1/2"
*ngIf="project.unit.taskDefinitions.length > 0"
[mode]="'project'"
[taskDefinitions]="project.unit.taskDefinitions"
[tasks]="project.tasks"
[selectedTaskDefinition$]="selectedTaskDefinition$"
></f-unit-task-list>

<div class="w-full h-[calc(100vh-100px)]" *ngIf="project$ | async as project">
<div class="flex flex-row h-full">
@if (subs$ | async) {
<f-unit-task-list
class="flex-none w-1/4 p-2"
[style.width.px]="leftWidth"
#leftPanel
*ngIf="project.unit.taskDefinitions.length > 0"
[mode]="'project'"
[taskDefinitions]="project.unit.taskDefinitions"
[tasks]="project.tasks"
[selectedTaskDefinition$]="selectedTaskDefinition$"
></f-unit-task-list>
<div
id="leftResizerEl"
#leftResizerEl
class="resizer"
class="w-[10px] z-50, bg-slate-100 cursor-w-resize"
cdkDragLockAxis="x"
cdkDrag
(cdkDragMoved)="dragging($event, leftComponent)"
(cdkDragEnded)="stoppedDragging($event, leftComponent)"
(cdkDragStarted)="startedDragging($event, leftComponent)"
(cdkDragMoved)="dragging($event, leftPanel)"
(cdkDragStarted)="startedDragging($event, leftPanel)"
></div>
}

<f-project-progress-dashboard
class="w-full"
[project$]="project$"
[selectedTaskDefinition$]="selectedTaskDefinition$"
></f-project-progress-dashboard>
@if (selectedTaskDefinition$.value) {
<div class="flex-1 p-2 bg-white rounded-lg">
<f-task-dashboard
[task]="project.findTaskForDefinition(selectedTaskDefinition$.value.id)"
></f-task-dashboard>
</div>
<div #commentspanel class="flex-none w-1/4 p-2 bg-white rounded-lg">
<task-comments-viewer
[task]="project.findTaskForDefinition(selectedTaskDefinition$.value.id)"
>
</task-comments-viewer>
</div>
} @else {
<div class="flex-1 p-2">
<f-progress-dashboard class="w-full" [project]="project"></f-progress-dashboard>
</div>
}
</div>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
withLatestFrom,
} from 'rxjs';
import {ProjectService} from 'src/app/api/services/project.service';
import {GlobalStateService} from '../../index/global-state.service';
import {GlobalStateService, ViewType} from '../../index/global-state.service';
import {UserService} from 'src/app/api/services/user.service';
import {Project, TaskDefinition} from 'src/app/api/models/doubtfire-model';

Expand Down Expand Up @@ -65,6 +65,7 @@ export class ProjectDashboardComponent implements OnInit {
// projectTasks = this.projectService.loadProject
this.project$.subscribe((project) => {
console.log(project);
this.globalStateService.setView(ViewType.PROJECT, project);
});

this.dragMoveAudited$ = this.dragMove$.pipe(
Expand Down
1 change: 1 addition & 0 deletions src/app/projects/states/dashboard/selected-task.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {TaskService} from 'src/app/api/services/task.service';
import {GlobalStateService} from '../index/global-state.service';

export enum DashboardViews {
details,
submission,
task,
similarity,
Expand Down
3 changes: 3 additions & 0 deletions src/app/units/states/tasks/inbox/inbox.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
}

<div fxFlex class="inbox-panel">
<!-- TODO: Separate this with a new f-inbox-dashboard -->
<!-- TODO: inbox dashboard can have: Submission | Task Sheet | Staff Notes | Plagiarism | Overseer -->
<!-- TODO: alternative: Submission | Staff Notes | Plagiarism | Overseer -->
<f-task-dashboard [task]="taskData.selectedTask" [pdfUrl]="visiblePdfUrl"></f-task-dashboard>
</div>
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,44 @@
</div>

<!-- Scrollable Unit Task List -->
<div class="tasks-viewport scrollable" itemSize="60">
<div class="h-screen scrollable" itemSize="60">
<mat-nav-list #taskDefinitions>
@if (filteredTaskDefinitions.length === 0) {
<div class="text-center text-muted">No tasks to display</div>
}
@for (taskDef of filteredTaskDefinitions; track taskDef) {
<mat-list-item class="clearfix p-0 h-[60px]" [disableRipple]="true">
<mat-list-item
class="flex w-full item-content items-center hover:bg-gray-50 p-0 px-2 h-[60px] cursor-pointer"
[disableRipple]="true"
(click)="setSelectedTaskDefinition(taskDef)"
[ngClass]="{
selected: isSelectedTaskDefinition(taskDef),
}"
>
@if (taskDef) {
<div
class="flex w-full item-content items-center hover:bg-gray-50"
(click)="setSelectedTaskDefinition(taskDef)"
[ngClass]="{
selected: isSelectedTaskDefinition(taskDef),
}"
>
<div class="task-entry w-full flex items-center">
<div class="task-list-data flex items-center justify-center">
<div class="flex justify-between items-center w-fill">
<div class="flex items-center gap-5 flex-1 min-w-0">
<div class="flex items-center gap-5 min-w-0 truncate text-ellipsis">
<f-task-badge [taskDef]="taskDef"></f-task-badge>
<div class="flex-col ml-4">
<h4 class="task-title line-clamp-1 mt-1">{{ taskDef.name }}</h4>
<div class="flex flex-col justify-start truncate text-ellipsis">
<div class="truncate text-ellipsis">{{ taskDef.name }}</div>

<span class="flex">
<div class="flex items-center gap-2">
@if (taskDef.isGroupTask()) {
<mat-icon class="text-gray-400 scale-75">group</mat-icon>
} @else {
<mat-icon class="text-gray-400 scale-75">person</mat-icon>
}
<div class="task-details">{{ gradeNames[taskDef.targetGrade] }} Task</div>
@if (hasTasks && taskForTaskDef(taskDef)) {
<p style="background-color: red">{{ taskForTaskDef(taskDef).status }}</p>
}
</span>

<div></div>
</div>
</div>
</div>
</div>
@if (hasTasks && taskForTaskDef(taskDef)) {
<status-icon [status]="taskForTaskDef(taskDef).status"></status-icon>
}
</div>
}
</mat-list-item>
} @empty {
<div class="text-center text-muted">No tasks to display</div>
}
</mat-nav-list>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ $my-palette: mat.m2-define-palette($md-formatif);
cursor: pointer;
}

.mat-mdc-list-item .item-content.selected {
.mat-mdc-list-item.selected {
background-color: var(--background-gray);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {Grade} from 'src/app/api/models/grade';
import {TaskDefinition, Task} from 'src/app/api/models/doubtfire-model';
import {TaskDefinitionNamePipe} from 'src/app/common/filters/task-definition-name.pipe';
import {BehaviorSubject} from 'rxjs';
import {StateService, UIRouter} from '@uirouter/core';

@Component({
selector: 'f-unit-task-list',
Expand All @@ -25,6 +26,11 @@ export class FUnitTaskListComponent implements OnInit {
taskDefinitionNamePipe = new TaskDefinitionNamePipe();
protected gradeNames: string[] = Grade.GRADES;

constructor(
private router: UIRouter,
private stateService: StateService,
) {}

applyFilters() {
this.filteredTaskDefinitions = this.taskDefinitionNamePipe.transform(
this.taskDefinitions,
Expand All @@ -44,6 +50,12 @@ export class FUnitTaskListComponent implements OnInit {
return this.tasks.find((task) => task.definition.id === taskDef?.id);
}

/*
TODO: There's still an issue where loading the route for the first time will cause child components (like task-dashboard) to load trigger OnInit and OnChanges twice...
Causing duplicate queries to submission_details and task comments.
One hack would be to always keep the task-dashboard rendered using [hidden].
*/

ngOnInit(): void {
this.applyFilters();

Expand All @@ -65,13 +77,31 @@ export class FUnitTaskListComponent implements OnInit {
// if (this.taskDefinitions.length > 0) {
// this.setSelectedTaskDefinition(this.taskDefinitions[0]);
// }

// Load selected task from URL
const current = this.selectedTaskDefinition$.value;
const param = this.router.globals.params.taskAbbreviation;

if (param) {
const taskDef = this.taskDefinitions.find((t) => t.abbreviation === param);

if (taskDef !== current) {
this.selectedTaskDefinition$.next(taskDef);
}
} else {
if (current !== null) {
this.selectedTaskDefinition$.next(null);
}
}
}

setSelectedTaskDefinition(taskDef: TaskDefinition) {
if (this.isSelectedTaskDefinition(taskDef)) {
this.selectedTaskDefinition$.next(null);
this.stateService.go('.', {taskAbbreviation: null}, {location: 'replace'});
} else {
this.selectedTaskDefinition$.next(taskDef);
this.stateService.go('.', {taskAbbreviation: taskDef.abbreviation}, {location: 'replace'});
}

// this.selectedTaskDefinition.emit(taskDef);
Expand Down