implement task filter

This commit is contained in:
marlon-erler
2024-07-25 15:31:27 +02:00
parent 8b47bb74e8
commit be6f609ea2
10 changed files with 321 additions and 20 deletions
+18 -3
View File
@@ -30,8 +30,6 @@ export default class BoardViewModel {
index: React.State<number> = new React.State(0);
taskViewModels: React.MapState<TaskViewModel> = new React.MapState();
selectedPage: React.State<BoardPageType> = new React.State<BoardPageType>(
BoardPageType.List
);
@@ -42,6 +40,10 @@ export default class BoardViewModel {
isPresentingSettingsModal: React.State<boolean> = new React.State(false);
isPresentingFilterModal: React.State<boolean> = new React.State(false);
taskViewModels: React.MapState<TaskViewModel> = new React.MapState();
filteredTaskViewModels: React.ListState<TaskViewModel> =
new React.ListState();
// paths
getBasePath = (): string[] => {
return [...this.taskPageViewModel.getBoardViewPath(this.boardInfo.fileId)];
@@ -162,6 +164,19 @@ export default class BoardViewModel {
}
};
// filter
getStringsFromTaskViewModel = (taskViewModel: TaskViewModel): string[] => {
return [
taskViewModel.task.name,
taskViewModel.task.description ?? "",
taskViewModel.task.category ?? "",
taskViewModel.task.status ?? "",
taskViewModel.task.priority ?? "",
taskViewModel.task.date ?? "",
taskViewModel.task.time ?? "",
];
};
// load
loadListRelevantData = (): void => {
this.name.value = this.boardInfo.name;
@@ -174,7 +189,7 @@ export default class BoardViewModel {
);
for (const taskId of taskIds) {
if (this.taskViewModels.value.has(taskId)) return;
const taskFileContent: TaskFileContent | null =
this.boardModel.getLatestTaskFileContent(taskId);
if (taskFileContent == null) continue;
+68
View File
@@ -0,0 +1,68 @@
import * as React from "bloatless-react";
import { checkDoesObjectMatchSearch } from "../../Model/Utility/utility";
export default class SearchViewModel<T> {
// data
allObjects: React.ListState<T> | React.MapState<T>;
getStringsOfObject: (object: T) => string[];
// state
appliedQuery: React.State<string> = new React.State("");
searchInput: React.State<string> = new React.State("");
matchingObjects: React.ListState<T>;
// guards
cannotApplySearch: React.State<boolean> = React.createProxyState(
[this.searchInput, this.appliedQuery],
() => this.searchInput.value == this.appliedQuery.value
);
// methods
applySearch = (): void => {
this.appliedQuery.value = this.searchInput.value;
console.log("applying search");
this.matchingObjects.clear();
for (const object of this.allObjects.value.values()) {
const doesMatch: boolean = this.checkDoesMatchSearch(object);
if (doesMatch == false) continue;
this.matchingObjects.add(object);
}
};
// init
constructor(
allObjects: React.ListState<T> | React.MapState<T>,
matchingObjects: React.ListState<T>,
getStringsOfObject: (object: T) => string[]
) {
this.allObjects = allObjects;
this.matchingObjects = matchingObjects;
this.getStringsOfObject = getStringsOfObject;
// handle new objects
this.allObjects.handleAddition((newObject: T) => {
const doesMatch: boolean = this.checkDoesMatchSearch(newObject);
if (doesMatch == false) {
this.matchingObjects.remove(newObject);
} else {
if (this.matchingObjects.value.has(newObject)) return;
this.matchingObjects.add(newObject);
this.allObjects.handleRemoval(newObject, () => {
this.matchingObjects.remove(newObject);
});
}
});
}
// utility
checkDoesMatchSearch = (object: T): boolean => {
return checkDoesObjectMatchSearch(
this.appliedQuery.value,
this.getStringsOfObject,
object
);
};
}
@@ -1,6 +1,6 @@
import * as React from "bloatless-react";
import TaskViewModel from "./taskViewModel";
import TaskViewModel from "../Pages/taskViewModel";
export default class TaskPropertyBulkChangeViewModel {
taskViewModels: React.ListState<TaskViewModel>;