Skip to content

Commit

Permalink
Merge pull request #380 from jakerenzella/enhance/add-task-inbox-sorting
Browse files Browse the repository at this point in the history
Enhance/add task inbox sorting
  • Loading branch information
jakerenzella authored Jun 24, 2021
2 parents e029385 + e24763c commit 78f0e9a
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 124 deletions.
4 changes: 2 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@
"error",
{
"type": "attribute",
"prefix": "app",
"prefix": "df",
"style": "camelCase"
}
],
"@angular-eslint/component-selector": [
"error",
{
"type": "element",
"prefix": "app",
"prefix": "df",
"style": "kebab-case"
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,59 +6,30 @@
<mat-icon>search</mat-icon>
</button>

<mat-form-field
appearance="none"
style="width: 100%; margin-top: -0.4em; margin-bottom: -30px"
floatLabel="never"
>
<input
matInput
autocomplete="off"
spellcheck="false"
type="text"
placeholder="Search Inbox"
[(ngModel)]="filters.studentName"
(ngModelChange)="applyFilters()"
/>
<mat-form-field appearance="none" style="width: 100%; margin-top: -0.4em; margin-bottom: -30px"
floatLabel="never">
<input matInput autocomplete="off" spellcheck="false" type="text" placeholder="Search Inbox"
[(ngModel)]="filters.studentName" (ngModelChange)="applyFilters()" />
</mat-form-field>
<button
*ngIf="collapsable"
matTooltip="Filter options"
matTooltipPosition="above"
mat-icon-button
aria-label="Inbox search dropdown"
(click)="showSearchOptions = !showSearchOptions"
>
<button *ngIf="collapsable" matTooltip="Filter options" matTooltipPosition="above" mat-icon-button
aria-label="Inbox search dropdown" (click)="showSearchOptions = !showSearchOptions">
<mat-icon>{{ showSearchOptions ? 'arrow_drop_up' : 'arrow_drop_down' }}</mat-icon>
</button>

<button
matTooltip="Refresh the task inbox"
matTooltipPosition="above"
mat-icon-button
aria-label="Refresh Inbox"
(click)="refreshTasks()"
>
<button matTooltip="Refresh the task inbox" matTooltipPosition="above" mat-icon-button aria-label="Refresh Inbox"
(click)="refreshTasks()">
<mat-icon>refresh</mat-icon>
</button>
</div>

<mat-accordion>
<mat-expansion-panel
class="search-settings-panel mat-elevation-z0"
disabled
hideToggle
[expanded]="!collapsable || showSearchOptions"
>
<mat-expansion-panel class="search-settings-panel mat-elevation-z0" disabled hideToggle
[expanded]="!collapsable || showSearchOptions">
<form class="search-options">
<div class="task-definition">
<div class="dropdown" dropdown>
<i
*ngIf="isTaskDefMode"
class="fa fa-download pull-right dropdown-toggle"
style="cursor: pointer; padding-top: 8px; padding-right: 8px"
dropdown-toggle
></i>
<i *ngIf="isTaskDefMode" class="fa fa-download pull-right dropdown-toggle"
style="cursor: pointer; padding-top: 8px; padding-right: 8px" dropdown-toggle></i>
<ul class="dropdown-menu pull-right">
<li>
<a [href]="submissionsPdfsUrl">Bulk Export Submission PDFs</a>
Expand All @@ -68,37 +39,40 @@
</li>
</ul>
</div>
<mat-form-field class="full-width">
<mat-label>Task Definition</mat-label>
<mat-select
[(ngModel)]="filters.taskDefinitionIdSelected"
name="taskDefID"
(selectionChange)="taskDefinitionIdChanged()"
>
<mat-option value="" [hidden]="isTaskDefMode">All Task Definitions</mat-option>
<mat-option *ngFor="let td of unit.task_definitions" [value]="td.id">
{{ td.abbreviation + ' - ' + td.name }}
<div fxLayout="row" fxLayoutAlign="space-between center">
<mat-form-field fxFlex>
<mat-label>Task Definition</mat-label>
<mat-select [(ngModel)]="filters.taskDefinitionIdSelected" name="taskDefID"
(selectionChange)="taskDefinitionIdChanged()">
<mat-option value="" [hidden]="isTaskDefMode">All Task Definitions</mat-option>
<mat-option *ngFor="let td of unit.task_definitions" [value]="td.id">
{{ td.abbreviation + ' - ' + td.name }}
</mat-option>
</mat-select>
<mat-hint> Display specific task definitions. </mat-hint>
</mat-form-field>
<button [disabled]="(filters.taskDefinitionIdSelected || !filters.taskDefinitionIdSelected === '')"
mat-icon-button aria-label="Sort by task definition icon"(click)="toggleTaskDefSort()">
<mat-icon>{{states[taskDefSort].icon}}</mat-icon>
</button>
</div>
</div>
<!--/task-definition-->
<div fxLayout="row" fxLayoutAlign="space-between center">
<mat-form-field fxFlex>
<mat-label>Tutorials</mat-label>
<mat-select [(ngModel)]="filters.tutorialIdSelected" name="tutorial"
(selectionChange)="tutorialIdChanged()">
<mat-option *ngFor="let t of tutorials" [value]="t.id">
{{ t.inbox_description }}
</mat-option>
</mat-select>
<mat-hint> Display specific task definitions. </mat-hint>
<mat-hint> Filter tutorials. </mat-hint>
</mat-form-field>
<button disabled mat-icon-button aria-label="Sort by tutorial icon" (click)="toggleTutorialSort()">
<mat-icon>{{states[tutorialSort].icon}}</mat-icon>
</button>
</div>
<!--/task-definition-->

<mat-form-field class="full-width">
<mat-label>Tutorials</mat-label>
<mat-select
[(ngModel)]="filters.tutorialIdSelected"
name="tutorial"
(selectionChange)="tutorialIdChanged()"
>
<mat-option *ngFor="let t of tutorials" [value]="t.id">
{{ t.inbox_description }}
</mat-option>
</mat-select>
<mat-hint> Filter tutorials. </mat-hint>
</mat-form-field>

<!--/tutorial-->
</form>
</mat-expansion-panel>
Expand Down Expand Up @@ -135,30 +109,15 @@
</div>

<!--/search-options-->
<cdk-virtual-scroll-viewport
*ngIf="filteredTasks"
class="tasks-viewport scrollable"
itemSize="60"
minBufferPx="200"
maxBufferPx="400"
>
<cdk-virtual-scroll-viewport *ngIf="filteredTasks" class="tasks-viewport scrollable" itemSize="60" minBufferPx="200"
maxBufferPx="400">
<mat-list>
<mat-list-item class="clearfix" *cdkVirtualFor="let task of filteredTasks; templateCacheSize: 0" style="padding: 0">
<div
style="width: 100%"
id="{{ task.taskKeyToIdString() }}"
*ngIf="task"
[ngClass]="{ selected: isSelectedTask(task), 'item-content': task.statusClass() }"
>
<div
(click)="setSelectedTask(task)"
class="inbox-entry"
fxLayout="row"
fxLayoutAlign="start center"
[ngClass]="{ hover: task.hover }"
(mouseover)="task.hover = true"
(mouseout)="task.hover = false"
>
<mat-list-item class="clearfix" *cdkVirtualFor="let task of filteredTasks; templateCacheSize: 0"
style="padding: 0">
<div style="width: 100%" id="{{ task.taskKeyToIdString() }}" *ngIf="task"
[ngClass]="{ selected: isSelectedTask(task), 'item-content': task.statusClass() }">
<div (click)="setSelectedTask(task)" class="inbox-entry" fxLayout="row" fxLayoutAlign="start center"
[ngClass]="{ hover: task.hover }" (mouseover)="task.hover = true" (mouseout)="task.hover = false">
<user-icon fxFlexAlign="center" [user]="task.project()" [size]="30"> </user-icon>
<div class="task-list-data truncate" fxFlex [hidden]="isNarrow">
<h4 class="mat-h4">{{ task.project().name }}</h4>
Expand All @@ -179,25 +138,16 @@ <h4 class="mat-h4">{{ task.project().name }}</h4>
<div *ngIf="task.hasGrade()" matTooltip="The grade assigned to the submission" matTooltipPosition="above">
<mat-chip style="margin-right: 6px" [hidden]="isNarrow">{{ task.gradeDesc() }} </mat-chip>
</div>
<status-icon
[hidden]="isNarrow"
matBadge="{{ task.quality_pts }}/{{ task.definition.max_quality_pts }}"
[matBadgeHidden]="!task.hasQualityPoints() || !task.quality_pts"
matBadgePosition="before"
[status]="task.status"
></status-icon>
<status-icon [hidden]="isNarrow" matBadge="{{ task.quality_pts }}/{{ task.definition.max_quality_pts }}"
[matBadgeHidden]="!task.hasQualityPoints() || !task.quality_pts" matBadgePosition="before"
[status]="task.status"></status-icon>
<div class="overflow" [hidden]="isNarrow" *ngIf="!isTaskDefMode">
<button [hidden]="task.hover" mat-icon-button aria-label="task-overflow">
<mat-icon class="warn-icon" *ngIf="task.plagiarismDetected()">remove_red_eye</mat-icon>

<div
*ngIf="task.pinned"
matBadge="{{ task.num_new_comments }}"
[matBadgeHidden]="task.num_new_comments <= 0 || task.plagiarismDetected()"
matBadgePosition="before"
matBadgeSize="small"
matBadgeColor="warn"
>
<div *ngIf="task.pinned" matBadge="{{ task.num_new_comments }}"
[matBadgeHidden]="task.num_new_comments <= 0 || task.plagiarismDetected()" matBadgePosition="before"
matBadgeSize="small" matBadgeColor="warn">
<mat-icon class="pin-icon">push_pin</mat-icon>
</div>

Expand All @@ -207,13 +157,8 @@ <h4 class="mat-h4">{{ task.project().name }}</h4>
</div>
</div>
</button>
<!-- Disable button until pin feature actice on backend -->
<button
[hidden]="!task.hover"
mat-icon-button
aria-label="task overflow"
[matMenuTriggerFor]="overflowMenu"
>
<button [hidden]="!task.hover" mat-icon-button aria-label="task overflow"
[matMenuTriggerFor]="overflowMenu">
<mat-icon>more_horiz</mat-icon>
</button>
<mat-menu #overflowMenu="matMenu" yPosition="below">
Expand All @@ -231,4 +176,4 @@ <h4 class="mat-h4">{{ task.project().name }}</h4>
<!--/task-->
</mat-list>
</cdk-virtual-scroll-viewport>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ $warn-color: #f44336;
background-color: transparent;
}

:host ::ng-deep div.mat-expansion-panel-body{
padding-right: 0 !important;
}

user-icon {
margin-right: 10px;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';
import { MatDialog } from '@angular/material/dialog';

@Component({
selector: 'staff-task-list',
selector: 'df-staff-task-list',
templateUrl: './staff-task-list.component.html',
styleUrls: ['./staff-task-list.component.scss'],
})
Expand Down Expand Up @@ -53,11 +53,21 @@ export class StaffTaskListComponent implements OnInit, OnChanges {

definedTasksPipe = new TasksOfTaskDefinitionPipe();
tasksInTutorialsPipe = new TasksInTutorialsPipe();
taskWithSTudentNamePipe = new TasksForInboxSearchPipe();
taskWithStudentNamePipe = new TasksForInboxSearchPipe();
// Let's call having a source of tasksForDefinition plus having a task definition
// auto-selected with the search options open task def mode -- i.e., the mode
// for selecting tasks by task definitions

states = [
{ sort: 'default', icon: 'horizontal_rule' },
{ sort: 'ascending', icon: 'arrow_upward' },
{ sort: 'descending', icon: 'arrow_downward' }
]

taskDefSort = 0
tutorialSort = 0
originalFilteredTasks: any[] = null;

@HostListener('document:keydown', ['$event'])
handleKeyDown(event: KeyboardEvent) {
if (event.metaKey) {
Expand All @@ -83,7 +93,7 @@ export class StaffTaskListComponent implements OnInit, OnChanges {
@Inject(groupService) private groupService,
@Inject(alertService) private alertService,
public dialog: MatDialog
) {}
) { }

ngOnChanges(changes: SimpleChanges): void {
if (
Expand Down Expand Up @@ -162,9 +172,16 @@ export class StaffTaskListComponent implements OnInit, OnChanges {
applyFilters() {
let filteredTasks = this.definedTasksPipe.transform(this.tasks, this.filters.taskDefinition);
filteredTasks = this.tasksInTutorialsPipe.transform(filteredTasks, this.filters.tutorials);
filteredTasks = this.taskWithSTudentNamePipe.transform(filteredTasks, this.filters.studentName);
filteredTasks = this.taskWithStudentNamePipe.transform(filteredTasks, this.filters.studentName);
this.filteredTasks = filteredTasks;

if (this.filteredTasks != null) {
this.originalFilteredTasks = [...this.filteredTasks];
}

this.taskDefSort = 0
this.tutorialSort = 0

// Fix selected task.
if (this.taskData.selectedTask && filteredTasks?.includes(this.taskData.selectedTask)) {
this.setSelectedTask(null);
Expand Down Expand Up @@ -286,8 +303,8 @@ export class StaffTaskListComponent implements OnInit, OnChanges {
const funcName = taskEl.scrollIntoViewIfNeeded
? 'scrollIntoViewIfNeeded'
: taskEl.scrollIntoView
? 'scrollIntoView'
: '';
? 'scrollIntoView'
: '';
if (!funcName) {
return;
}
Expand Down Expand Up @@ -322,19 +339,40 @@ export class StaffTaskListComponent implements OnInit, OnChanges {
}
}

toggleTaskDefSort() {
this.taskDefSort = this.taskDefSort < 2 ? ++this.taskDefSort : 0;
if (this.originalFilteredTasks == null) {
this.originalFilteredTasks = [...this.filteredTasks];
}
if (this.states[this.taskDefSort].sort == 'ascending') {
this.filteredTasks = [...this.filteredTasks.sort((a, b) => a.definition.seq - b.definition.seq)]
}

else if (this.states[this.taskDefSort].sort == 'descending') {
this.filteredTasks = [...this.filteredTasks.sort((a, b) => b.definition.seq - a.definition.seq)]
}

else {
this.filteredTasks = [...this.originalFilteredTasks]
}
}

// toggleTutorialSort() {
// }

togglePin(task) {
if (task.pinned) {
task.unpin(
task.id,
(sucess: any) => {},
(sucess: any) => { },
(error: any) => {
this.alertService.add('danger', error.data.error, 6000);
}
);
} else {
task.pin(
task.id,
(sucess: any) => {},
(sucess: any) => { },
(error: any) => {
this.alertService.add('danger', error.data.error, 6000);
}
Expand Down

0 comments on commit 78f0e9a

Please sign in to comment.