|
|
|
|
@@ -7,208 +7,217 @@ import { v4 as uuidv4 } from 'uuid';
|
|
|
|
|
import { filter } from 'rxjs/operators';
|
|
|
|
|
import { Store } from "../entity/store";
|
|
|
|
|
import { Router } from "@angular/router";
|
|
|
|
|
import { MatSnackBar } from "@angular/material/snack-bar";
|
|
|
|
|
|
|
|
|
|
@Injectable({
|
|
|
|
|
providedIn: 'root'
|
|
|
|
|
providedIn: 'root'
|
|
|
|
|
})
|
|
|
|
|
export class TaskListService {
|
|
|
|
|
private _store: BehaviorSubject<Store> = new BehaviorSubject<Store>(undefined as unknown as Store);
|
|
|
|
|
private _store: BehaviorSubject<Store> = new BehaviorSubject<Store>(undefined as unknown as Store);
|
|
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
|
private _router: Router,
|
|
|
|
|
private _storePersistenceService: StorePersistenceService
|
|
|
|
|
) {
|
|
|
|
|
this.store$.subscribe(store => {
|
|
|
|
|
this.saveStore(store, true);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
constructor(
|
|
|
|
|
private _router: Router,
|
|
|
|
|
private _snackBar: MatSnackBar,
|
|
|
|
|
private _storePersistenceService: StorePersistenceService
|
|
|
|
|
) {
|
|
|
|
|
this.store$.subscribe(store => {
|
|
|
|
|
this.saveStore(store, true);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get store$(): Observable<Store> {
|
|
|
|
|
return this._store.asObservable()
|
|
|
|
|
.pipe(filter(store => !!store));
|
|
|
|
|
}
|
|
|
|
|
get store$(): Observable<Store> {
|
|
|
|
|
return this._store.asObservable()
|
|
|
|
|
.pipe(filter(store => !!store));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private get store(): Store {
|
|
|
|
|
let result = this._store.value;
|
|
|
|
|
private get store(): Store {
|
|
|
|
|
let result = this._store.value;
|
|
|
|
|
|
|
|
|
|
if (!result) {
|
|
|
|
|
result = this._storePersistenceService.load();
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
if (!result) {
|
|
|
|
|
result = this._storePersistenceService.load();
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private saveStore(store: Store, silent: boolean = false): void {
|
|
|
|
|
if (silent) {
|
|
|
|
|
this._storePersistenceService.save(store);
|
|
|
|
|
} else {
|
|
|
|
|
// We send the store into the subject because there is an observable on in, that saves the store at every single value.
|
|
|
|
|
this._store.next(store);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private saveStore(store: Store, silent: boolean = false): void {
|
|
|
|
|
if (silent) {
|
|
|
|
|
this._storePersistenceService.save(store);
|
|
|
|
|
} else {
|
|
|
|
|
// We send the store into the subject because there is an observable on in, that saves the store at every single value.
|
|
|
|
|
this._store.next(store);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addTask(taskTitle: string): void {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
const activeTaskList = store.taskLists.find(taskList => taskList.id === store.activeTaskListId);
|
|
|
|
|
if (!activeTaskList) {
|
|
|
|
|
throw new Error("No active tasklist");
|
|
|
|
|
}
|
|
|
|
|
addTask(taskTitle: string): void {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
const activeTaskList = store.taskLists.find(taskList => taskList.id === store.activeTaskListId);
|
|
|
|
|
if (!activeTaskList) {
|
|
|
|
|
throw new Error("No active tasklist");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!activeTaskList.tasks) {
|
|
|
|
|
activeTaskList.tasks = [];
|
|
|
|
|
}
|
|
|
|
|
if (!activeTaskList.tasks) {
|
|
|
|
|
activeTaskList.tasks = [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const newTask = {
|
|
|
|
|
id: uuidv4(),
|
|
|
|
|
title: taskTitle,
|
|
|
|
|
creationDate: new Date(),
|
|
|
|
|
description: undefined as unknown as string
|
|
|
|
|
} as Task;
|
|
|
|
|
const newTask = {
|
|
|
|
|
id: uuidv4(),
|
|
|
|
|
title: taskTitle,
|
|
|
|
|
creationDate: new Date(),
|
|
|
|
|
description: undefined as unknown as string
|
|
|
|
|
} as Task;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
activeTaskList?.tasks.push(newTask);
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
}
|
|
|
|
|
activeTaskList?.tasks.push(newTask);
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
this._snackBar.open('Tâche ajoutée.', 'Fermer', {duration: 2000});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
updateTask(taskToUpdate: Task) {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
const activeTaskList = store.taskLists.find(taskList => taskList.id === store.activeTaskListId);
|
|
|
|
|
if (!activeTaskList) {
|
|
|
|
|
throw new Error("No active tasklist");
|
|
|
|
|
}
|
|
|
|
|
updateTask(taskToUpdate: Task) {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
const activeTaskList = store.taskLists.find(taskList => taskList.id === store.activeTaskListId);
|
|
|
|
|
if (!activeTaskList) {
|
|
|
|
|
throw new Error("No active tasklist");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const task = activeTaskList?.tasks.find(task => task.id === taskToUpdate.id);
|
|
|
|
|
if (!task) {
|
|
|
|
|
throw new Error('Unknown task to update');
|
|
|
|
|
}
|
|
|
|
|
const task = activeTaskList?.tasks.find(task => task.id === taskToUpdate.id);
|
|
|
|
|
if (!task) {
|
|
|
|
|
throw new Error('Unknown task to update');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
task.title = taskToUpdate.title;
|
|
|
|
|
task.description = taskToUpdate.description;
|
|
|
|
|
task.title = taskToUpdate.title;
|
|
|
|
|
task.description = taskToUpdate.description;
|
|
|
|
|
|
|
|
|
|
// If the store is saved loudly, all views will be refreshed and the user will lose the focus of its input,
|
|
|
|
|
// so we save the store silently here.
|
|
|
|
|
this.saveStore(store, true);
|
|
|
|
|
}
|
|
|
|
|
// If the store is saved loudly, all views will be refreshed and the user will lose the focus of its input,
|
|
|
|
|
// so we save the store silently here.
|
|
|
|
|
this.saveStore(store, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete(taskToDelete: Task) {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
const activeTaskList = store.taskLists.find(taskList => taskList.id === store.activeTaskListId);
|
|
|
|
|
if (!activeTaskList) {
|
|
|
|
|
throw new Error("No active tasklist");
|
|
|
|
|
}
|
|
|
|
|
delete(taskToDelete: Task) {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
const activeTaskList = store.taskLists.find(taskList => taskList.id === store.activeTaskListId);
|
|
|
|
|
if (!activeTaskList) {
|
|
|
|
|
throw new Error("No active tasklist");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const taskIndex = activeTaskList?.tasks.findIndex(task => task.id === taskToDelete.id);
|
|
|
|
|
if (!taskIndex && taskIndex !== 0) {
|
|
|
|
|
throw new Error('Unknown task to delete');
|
|
|
|
|
}
|
|
|
|
|
const taskIndex = activeTaskList?.tasks.findIndex(task => task.id === taskToDelete.id);
|
|
|
|
|
if (!taskIndex && taskIndex !== 0) {
|
|
|
|
|
throw new Error('Unknown task to delete');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
activeTaskList?.tasks.splice(taskIndex, 1);
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
}
|
|
|
|
|
activeTaskList?.tasks.splice(taskIndex, 1);
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
this._snackBar.open('Tâche supprimée.', 'Fermer', {duration: 2000});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
createTaskList(taskListName: string): void {
|
|
|
|
|
const newTaskList = {
|
|
|
|
|
id: uuidv4(),
|
|
|
|
|
name: taskListName,
|
|
|
|
|
tasks: []
|
|
|
|
|
} as TaskList;
|
|
|
|
|
createTaskList(taskListName: string): void {
|
|
|
|
|
const newTaskList = {
|
|
|
|
|
id: uuidv4(),
|
|
|
|
|
name: taskListName,
|
|
|
|
|
tasks: []
|
|
|
|
|
} as TaskList;
|
|
|
|
|
|
|
|
|
|
const store = this.store;
|
|
|
|
|
store.taskLists.push(newTaskList);
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
}
|
|
|
|
|
const store = this.store;
|
|
|
|
|
store.taskLists.push(newTaskList);
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
updateTaskListName(taskListToUpdate: TaskList): void {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
const matchingTaskList = store.taskLists.find(taskList => taskList.id === taskListToUpdate.id);
|
|
|
|
|
if (matchingTaskList) {
|
|
|
|
|
matchingTaskList.name = taskListToUpdate.name;
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
this.disableSelectionMode();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
updateTaskListName(taskListToUpdate: TaskList): void {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
const matchingTaskList = store.taskLists.find(taskList => taskList.id === taskListToUpdate.id);
|
|
|
|
|
if (matchingTaskList) {
|
|
|
|
|
matchingTaskList.name = taskListToUpdate.name;
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
this.disableSelectionMode();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
deleteSelectedTaskLists(): void {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
const nonSelectedTaskLists = store.taskLists.filter(taskList => !store.selectedTaskLists.some(selectedTaskList => selectedTaskList.id === taskList.id));
|
|
|
|
|
store.taskLists = nonSelectedTaskLists;
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
this.disableSelectionMode();
|
|
|
|
|
}
|
|
|
|
|
deleteSelectedTaskLists(): void {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
const nonSelectedTaskLists = store.taskLists.filter(taskList => !store.selectedTaskLists.some(selectedTaskList => selectedTaskList.id === taskList.id));
|
|
|
|
|
store.taskLists = nonSelectedTaskLists;
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
this.disableSelectionMode();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getAll(): TaskList[] {
|
|
|
|
|
return this.store.taskLists ?? [];
|
|
|
|
|
}
|
|
|
|
|
getAll(): TaskList[] {
|
|
|
|
|
return this.store.taskLists ?? [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setActive(taskList: TaskList): void {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
store.activeTaskListId = taskList.id;
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
this._router.navigate(['/task-lists/active']);
|
|
|
|
|
}
|
|
|
|
|
setActive(taskList: TaskList): void {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
store.activeTaskListId = taskList.id;
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
this._router.navigate(['/task-lists/active']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
removeActiveTaskList(): void {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
delete store.activeTaskListId;
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
this._router.navigate(['/']);
|
|
|
|
|
}
|
|
|
|
|
removeActiveTaskList(): void {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
delete store.activeTaskListId;
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
this._router.navigate(['/']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
selectTaskList(taskList: TaskList): void {
|
|
|
|
|
this.enableSelectionMode();
|
|
|
|
|
selectTaskList(taskList: TaskList): void {
|
|
|
|
|
this.enableSelectionMode();
|
|
|
|
|
|
|
|
|
|
const store = this.store;
|
|
|
|
|
const store = this.store;
|
|
|
|
|
|
|
|
|
|
if (!store.selectedTaskLists) {
|
|
|
|
|
store.selectedTaskLists = [];
|
|
|
|
|
}
|
|
|
|
|
if (!store.selectedTaskLists) {
|
|
|
|
|
store.selectedTaskLists = [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (store.selectedTaskLists.some(tl => tl.id === taskList.id)) {
|
|
|
|
|
const selectedTaskListIndex = store.selectedTaskLists.findIndex(tl => tl.id === taskList.id);
|
|
|
|
|
store.selectedTaskLists.splice(selectedTaskListIndex, 1);
|
|
|
|
|
if (store.selectedTaskLists.some(tl => tl.id === taskList.id)) {
|
|
|
|
|
const selectedTaskListIndex = store.selectedTaskLists.findIndex(tl => tl.id === taskList.id);
|
|
|
|
|
store.selectedTaskLists.splice(selectedTaskListIndex, 1);
|
|
|
|
|
|
|
|
|
|
if (!store.selectedTaskLists.length) {
|
|
|
|
|
store.selectionMode = false;
|
|
|
|
|
}
|
|
|
|
|
if (!store.selectedTaskLists.length) {
|
|
|
|
|
store.selectionMode = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
} else {
|
|
|
|
|
store.selectedTaskLists.push(taskList);
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
} else {
|
|
|
|
|
store.selectedTaskLists.push(taskList);
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isSelected(taskList: TaskList): boolean {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
return store.selectedTaskLists && store.selectedTaskLists.some(tl => tl.id === taskList.id);
|
|
|
|
|
}
|
|
|
|
|
isSelected(taskList: TaskList): boolean {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
return store.selectedTaskLists && store.selectedTaskLists.some(tl => tl.id === taskList.id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isSelectionModeEnabled(): boolean {
|
|
|
|
|
return this.store.selectionMode;
|
|
|
|
|
}
|
|
|
|
|
isSelectionModeEnabled(): boolean {
|
|
|
|
|
return this.store.selectionMode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enableSelectionMode(): void {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
store.selectionMode = true;
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
}
|
|
|
|
|
enableSelectionMode(): void {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
store.selectionMode = true;
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
disableSelectionMode(): void {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
store.selectionMode = false;
|
|
|
|
|
store.selectedTaskLists = [];
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
}
|
|
|
|
|
disableSelectionMode(): void {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
store.selectionMode = false;
|
|
|
|
|
store.selectedTaskLists = [];
|
|
|
|
|
this.saveStore(store);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isThereMultipleTaskListsSelected(): boolean {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
return (store.selectedTaskLists?.length ?? 0) > 1;
|
|
|
|
|
}
|
|
|
|
|
isThereMultipleTaskListsSelected(): boolean {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
return (store.selectedTaskLists?.length ?? 0) > 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get selectedTaskList(): TaskList {
|
|
|
|
|
return this._store.value?.selectedTaskLists[0];
|
|
|
|
|
}
|
|
|
|
|
get selectedTaskList(): TaskList {
|
|
|
|
|
return this._store.value?.selectedTaskLists[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isNoAnyTaskList(): boolean {
|
|
|
|
|
return !this.store?.taskLists?.length;
|
|
|
|
|
}
|
|
|
|
|
isNoAnyTaskList(): boolean {
|
|
|
|
|
return !this.store?.taskLists?.length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get activeTaskList(): TaskList | undefined {
|
|
|
|
|
const store = this.store;
|
|
|
|
|
return store.taskLists.find(taskList => taskList.id === store.activeTaskListId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|