implement auto reconnect

This commit is contained in:
marlon-erler
2026-04-01 08:29:39 +00:00
parent c52d7b7685
commit 9d400a9929
82 changed files with 8340 additions and 7641 deletions
+66 -66
View File
@@ -3,74 +3,74 @@ 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[];
// 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>;
// state
appliedQuery: React.State<string> = new React.State("");
searchInput: React.State<string> = new React.State("");
matchingObjects: React.ListState<T>;
suggestions: React.ListState<string>;
suggestions: React.ListState<string>;
// guards
cannotApplySearch: React.State<boolean> = React.createProxyState(
[this.searchInput, this.appliedQuery],
() => this.searchInput.value == this.appliedQuery.value
);
// methods
search = (searchTerm: string): void => {
this.searchInput.value = searchTerm;
this.applySearch();
};
applySearch = (): void => {
this.appliedQuery.value = this.searchInput.value;
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[],
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);
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
// guards
cannotApplySearch: React.State<boolean> = React.createProxyState(
[this.searchInput, this.appliedQuery],
() => this.searchInput.value == this.appliedQuery.value,
);
};
// methods
search = (searchTerm: string): void => {
this.searchInput.value = searchTerm;
this.applySearch();
};
applySearch = (): void => {
this.appliedQuery.value = this.searchInput.value;
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[],
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);
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,
);
};
}
@@ -3,70 +3,72 @@ import * as React from "bloatless-react";
import TaskViewModel from "../Pages/taskViewModel";
export default class TaskPropertyBulkChangeViewModel {
taskViewModels: React.ListState<TaskViewModel>;
taskViewModels: React.ListState<TaskViewModel>;
// state
inputValue: React.State<string> = new React.State("");
// state
inputValue: React.State<string> = new React.State("");
// guards
cannotSet: React.State<boolean>;
// guards
cannotSet: React.State<boolean>;
// methods
set = (): void => {
if (this.cannotSet.value == true) return;
this.taskViewModels.value.forEach((taskViewModel: TaskViewModel) => {
this.setValue(this.inputValue.value, taskViewModel);
});
};
// methods
set = (): void => {
if (this.cannotSet.value == true) return;
this.taskViewModels.value.forEach((taskViewModel: TaskViewModel) => {
this.setValue(this.inputValue.value, taskViewModel);
});
};
setValue: (newValue: string, taskViewModel: TaskViewModel) => void;
setValue: (newValue: string, taskViewModel: TaskViewModel) => void;
// init
constructor(
taskViewModels: React.ListState<TaskViewModel>,
valueSetter: (newValue: string, taskViewModel: TaskViewModel) => void,
initialValue: string
) {
this.taskViewModels = taskViewModels;
this.inputValue.value = initialValue;
// init
constructor(
taskViewModels: React.ListState<TaskViewModel>,
valueSetter: (newValue: string, taskViewModel: TaskViewModel) => void,
initialValue: string,
) {
this.taskViewModels = taskViewModels;
this.inputValue.value = initialValue;
this.setValue = valueSetter;
this.setValue = valueSetter;
this.cannotSet = React.createProxyState(
[this.inputValue],
() => this.inputValue.value == "" || this.inputValue.value == initialValue
);
}
this.cannotSet = React.createProxyState(
[this.inputValue],
() =>
this.inputValue.value == "" ||
this.inputValue.value == initialValue,
);
}
}
export class TaskCategoryBulkChangeViewModel extends TaskPropertyBulkChangeViewModel {
constructor(
taskViewModels: React.ListState<TaskViewModel>,
initialValue: string
) {
super(
taskViewModels,
(newCategory: string, taskViewModel: TaskViewModel) => {
taskViewModel.category.value = newCategory;
taskViewModel.save();
},
initialValue
);
}
constructor(
taskViewModels: React.ListState<TaskViewModel>,
initialValue: string,
) {
super(
taskViewModels,
(newCategory: string, taskViewModel: TaskViewModel) => {
taskViewModel.category.value = newCategory;
taskViewModel.save();
},
initialValue,
);
}
}
export class TaskStatusBulkChangeViewModel extends TaskPropertyBulkChangeViewModel {
constructor(
taskViewModels: React.ListState<TaskViewModel>,
initialValue: string
) {
super(
taskViewModels,
(newStatus: string, taskViewModel: TaskViewModel) => {
taskViewModel.status.value = newStatus;
taskViewModel.save();
},
initialValue
);
}
constructor(
taskViewModels: React.ListState<TaskViewModel>,
initialValue: string,
) {
super(
taskViewModels,
(newStatus: string, taskViewModel: TaskViewModel) => {
taskViewModel.status.value = newStatus;
taskViewModel.save();
},
initialValue,
);
}
}