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

DRAFT feat/add-recently-interacted #860

Open
wants to merge 12 commits into
base: 8.0.x
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
5,453 changes: 3,481 additions & 1,972 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"ngx-bootstrap": "^6.1.0",
"ngx-entity-service": "^0.0.38",
"ngx-lottie": "^11.0.2",
"ngx-reactive-storage": "^1.2.2",
"nvd3": "1.8.6",
"rxjs": "~7.4.0",
"ts-md5": "^1.3.1",
Expand Down
31 changes: 31 additions & 0 deletions src/app/api/services/local-storage.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {Injectable} from '@angular/core';
import {RxStorage} from 'ngx-reactive-storage';

@Injectable({
providedIn: 'root',
})
export class LocalStorageService {
private storage = new RxStorage();

constructor() {}

// Add
public setItem(key: string, data: any) {
return this.storage.set(key, data);
}

// Get
public getItem(key: string) {
return this.storage.get(key);
}

// Delete
public removeItem(key: string) {
return this.storage.remove(key);
}

// Clear
public clear() {
return this.storage.clear();
}
}
62 changes: 62 additions & 0 deletions src/app/api/services/recently-interacted-task.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {Injectable} from '@angular/core';
import { LocalStorageService } from './local-storage.service';

interface RecentlyInteractedTask {
task_id: number;
date: number;
}

interface RecentlyInteractedTasks {
[unitId: number]: RecentlyInteractedTask[];
}

@Injectable({
providedIn: 'root',
})
export class RecentlyInteractedTaskService {
private recentlyInteractedTasks: RecentlyInteractedTasks = {};

constructor(
private localStorageService: LocalStorageService,
) {
this.onInit()
}

private async onInit() {
const data = await this.localStorageService.getItem('recentlyInteractedTasks')
if (data && typeof data === 'object') this.recentlyInteractedTasks = data;
}

public addInteractedTask(taskId: number, unitId: number): void {
const dateStamp = new Date().getTime();
const recentTask = {task_id: taskId, date: dateStamp}
// If the unit's key doesn't exist: create it.
if (!this.recentlyInteractedTasks[unitId]) {
this.recentlyInteractedTasks[unitId] = [recentTask]
this.syncTaskIdsToLocalStorage();
} else {
const unit = this.recentlyInteractedTasks[unitId];
if (!unit.some((task) => task.task_id === taskId)) {
unit.push(recentTask)
this.syncTaskIdsToLocalStorage();
}
}
}

public clearAllRecentlyInteractedTasks(): void {
this.recentlyInteractedTasks = {};
this.syncTaskIdsToLocalStorage();
}

public getRecentlyInteractedTasksIdsByUnitId(unitId): RecentlyInteractedTask[] {
return this.recentlyInteractedTasks[unitId];
}

public getAllRecentlyInteractedTasksIds(): RecentlyInteractedTasks {
return this.recentlyInteractedTasks;
}

private syncTaskIdsToLocalStorage(): void {
this.localStorageService.setItem('recentlyInteractedTasks', this.recentlyInteractedTasks)
}
}
27 changes: 26 additions & 1 deletion src/app/common/footer/footer.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@
>
<mat-icon class="small-icon">more_vert</mat-icon>
</button>

<mat-menu #aboveMenu="matMenu" yPosition="above">
<button mat-menu-item (click)="viewTaskSheet()" [disabled]="!selectedTaskService.hasTaskSheet">
<mat-icon matListItemIcon aria-label="View Task Sheet">description</mat-icon>
Expand All @@ -118,6 +117,32 @@
Mark as fail
</button>
</mat-menu>

<button
[disabled]="selectedTask === undefined"
mat-icon-button
matTooltip="View Recently Interacted"
matTooltipPosition="above"
aria-label=""
class="button small-button"
[matMenuTriggerFor]="recentlyInteractedMenu"
(click)="viewRecentlyInteracted()"
>
<mat-icon class="small-icon">recent_actors</mat-icon>
</button>

<mat-menu #recentlyInteractedMenu="matMenu" yPosition="above">
@for (t of filteredTasks; track t) {
<map-option [value]="t.task_id">
<span class="truncate" (click)="setSelectedTask(t.task_id)">{{ t.task_id }}</span>
</map-option>
}
<button mat-menu-item (click)="viewTaskSheet()" [disabled]="!selectedTaskService.hasTaskSheet">
<mat-icon matListItemIcon aria-label="View Task Sheet">description</mat-icon>
View task sheet
</button>
</mat-menu>

<button
[disabled]="selectedTask === undefined"
mat-icon-button
Expand Down
21 changes: 19 additions & 2 deletions src/app/common/footer/footer.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,26 @@ import { Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular
import { Observable } from 'rxjs';
import { Task } from 'src/app/api/models/task';
import { SelectedTaskService } from 'src/app/projects/states/dashboard/selected-task.service';

import { FileDownloaderService } from '../file-downloader/file-downloader.service';
import { RecentlyInteractedTaskService } from 'src/app/api/services/recently-interacted-task.service';

@Component({
selector: 'f-footer',
templateUrl: './footer.component.html',
styleUrls: ['./footer.component.scss'],
})
export class FooterComponent implements OnInit {
constructor(public selectedTaskService: SelectedTaskService, private fileDownloader: FileDownloaderService) {}
constructor(
public selectedTaskService: SelectedTaskService,
private fileDownloader: FileDownloaderService,
private recentlyInteractedTaskService: RecentlyInteractedTaskService,
) {}

selectedTask$: Observable<Task>;
selectedTask: Task;

filteredTasks: any[]

@ViewChild('similaritiesButton', { static: false, read: ElementRef }) similaritiesButton: ElementRef;
@ViewChild('warningText', { static: false, read: ElementRef }) warningText: ElementRef;
public leftOffset: number;
Expand Down Expand Up @@ -78,4 +84,15 @@ export class FooterComponent implements OnInit {
viewSimilarity() {
this.selectedTaskService.showSimilarity();
}

viewRecentlyInteracted() {
// TODO: Add a way to view recently interacted tasks based on the unitId
const unitId = 2;
const tasks = this.recentlyInteractedTaskService.getAllRecentlyInteractedTasksIds()[unitId];
this.filteredTasks = tasks;
}

setSelectedTask(taskId: number) {
this.selectedTaskService.setSelectedTask(taskId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
Input,
OnChanges,
SimpleChanges,
HostListener,
ViewChild,
TemplateRef,
OnDestroy,
Expand All @@ -31,6 +30,7 @@ import {DoubtfireConstants} from 'src/app/config/constants/doubtfire-constants';
import {SelectedTaskService} from 'src/app/projects/states/dashboard/selected-task.service';
import {AlertService} from 'src/app/common/services/alert.service';
import {HotkeysService} from '@ngneat/hotkeys';
import { RecentlyInteractedTaskService } from 'src/app/api/services/recently-interacted-task.service';

@Component({
selector: 'df-staff-task-list',
Expand Down Expand Up @@ -101,6 +101,7 @@ export class StaffTaskListComponent implements OnInit, OnChanges, OnDestroy {
allowHover = true;

constructor(
private recentlyInteractedTaskService: RecentlyInteractedTaskService,
private selectedTaskService: SelectedTaskService,
private alertService: AlertService,
private fileDownloaderService: FileDownloaderService,
Expand Down Expand Up @@ -167,6 +168,7 @@ export class StaffTaskListComponent implements OnInit, OnChanges, OnDestroy {
taskDefinitionIdSelected: null,
taskDefinition: null,
forceStream: true,
useCache: false,
},
this.filters,
);
Expand Down Expand Up @@ -238,6 +240,7 @@ export class StaffTaskListComponent implements OnInit, OnChanges, OnDestroy {

applyFilters() {
let filteredTasks = this.definedTasksPipe.transform(this.tasks, this.filters.taskDefinition);

if (this.filters.tutorials) {
filteredTasks = this.tasksInTutorialsPipe.transform(
filteredTasks,
Expand Down Expand Up @@ -352,8 +355,10 @@ export class StaffTaskListComponent implements OnInit, OnChanges, OnDestroy {
}

setSelectedTask(task: Task) {
if (task === null || task === undefined) return;
this.selectedTaskService.setSelectedTask(task);
this.taskData.selectedTask = task;
this.recentlyInteractedTaskService.addInteractedTask(task.id, task.unit.id);
if (this.taskData.onSelectedTaskChange) {
this.taskData.onSelectedTaskChange(task);
}
Expand Down
Loading