implement better hanlding of filter search suggestions

This commit is contained in:
marlon-erler
2026-09-21 21:23:49 +02:00
parent ea422b3de6
commit deaa784148
94 changed files with 778 additions and 3415 deletions
Binary file not shown.
-3
View File
@@ -83,9 +83,6 @@ export default class CoreViewModel {
// SUGGESTIONS
// boards & tasks
boardFilterStringSuggestions: React.ListState<string> =
new React.ListState();
taskCategorySuggestions: React.ListState<string> = new React.ListState();
taskStatusSuggestions: React.ListState<string> = new React.ListState();
Binary file not shown.
+15 -5
View File
@@ -28,6 +28,7 @@ export default class BoardViewModel extends TaskContainingPageViewModel {
isPresentingFilterModal: React.State<boolean> = new React.State(false);
searchViewModel: SearchViewModel<TaskViewModel>;
searchSuggestions = new React.ListState<string>();
filteredTaskViewModels: React.ListState<TaskViewModel> =
new React.ListState();
isFilterActive: React.State<boolean>;
@@ -115,17 +116,25 @@ export default class BoardViewModel extends TaskContainingPageViewModel {
];
this.coreViewModel.storageModel.write(suggestionPath, "");
if (
!this.coreViewModel.boardFilterStringSuggestions.value.has(
!this.searchSuggestions.value.has(
searchTerm,
)
) && searchTerm != ""
) {
this.coreViewModel.boardFilterStringSuggestions.add(searchTerm);
this.searchSuggestions.add(searchTerm);
}
const lastSearchPath: string[] = this.getLastSearchPath();
this.coreViewModel.storageModel.write(lastSearchPath, searchTerm);
};
handleSearchRemoved = (searchTerm: string): void => {
const suggestionPath: string[] = [
...this.getPreviousSearchesPath(),
searchTerm,
];
this.coreViewModel.storageModel.remove(suggestionPath);
}
// view
showTask = (taskFileContent: TaskFileContent): void => {
if (taskFileContent.boardId != this.boardInfo.fileId) {
@@ -224,7 +233,7 @@ export default class BoardViewModel extends TaskContainingPageViewModel {
const dirPath: string[] = this.getPreviousSearchesPath();
const searches: string[] =
this.coreViewModel.storageModel.list(dirPath);
this.coreViewModel.boardFilterStringSuggestions.add(...searches);
this.searchSuggestions.add(...searches.filter(x => x != ""));
};
restoreSearch = (): void => {
@@ -297,12 +306,13 @@ export default class BoardViewModel extends TaskContainingPageViewModel {
this.taskViewModels,
this.filteredTaskViewModels,
TaskViewModel.getStringsForFilter,
this.coreViewModel.boardFilterStringSuggestions,
this.searchSuggestions,
);
this.searchViewModel.appliedQuery.subscribeSilent((newQuery) => {
this.handleNewSearch(newQuery);
});
this.restoreSearch();
this.searchSuggestions.handleRemovals(this.handleSearchRemoved);
this.isFilterActive = React.createProxyState(
[this.searchViewModel.appliedQuery],
Binary file not shown.
+8 -16
View File
@@ -2,16 +2,9 @@ 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 = new React.State<string>("");
searchInput = new React.State<string>("");
matchingObjects: React.ListState<T>;
suggestions: React.ListState<string>;
// guards
cannotApplySearch: React.State<boolean> = React.createProxyState(
@@ -45,18 +38,17 @@ export default class SearchViewModel<T> {
this.searchInput.value = "";
}
deleteSuggestion = (suggestion: string): void => {
this.suggestions.remove(suggestion);
}
// init
constructor(
allObjects: React.ListState<T> | React.MapState<T>,
matchingObjects: React.ListState<T>,
getStringsOfObject: (object: T) => string[],
suggestions: React.ListState<string>,
public allObjects: React.ListState<T> | React.MapState<T>,
public matchingObjects: React.ListState<T>,
public getStringsOfObject: (object: T) => string[],
public suggestions: React.ListState<string>,
) {
this.allObjects = allObjects;
this.matchingObjects = matchingObjects;
this.getStringsOfObject = getStringsOfObject;
this.suggestions = suggestions;
// handle new objects
this.allObjects.handleAddition((newObject: T) => {
const doesMatch: boolean = this.checkDoesMatchSearch(newObject);