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
+2 -2
View File
@@ -3,7 +3,7 @@ import * as React from "bloatless-react";
import BoardViewModel from "../../ViewModel/Pages/boardViewModel";
import { FilteredList } from "../Components/filteredList";
import { PropertyValueList } from "../Components/propertyList";
import { TaskCategoryBulkChangeViewModel } from "../../ViewModel/Pages/taskPropertyBulkChangeViewModel";
import { TaskCategoryBulkChangeViewModel } from "../../ViewModel/Utility/taskPropertyBulkChangeViewModel";
import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
import { TaskViewModelToEntry } from "../Components/taskEntry";
import { translations } from "../translations";
@@ -34,7 +34,7 @@ function KanbanBoard(categoryName: string, boardViewModel: BoardViewModel) {
return FilteredList(
{ category: categoryName },
(taskViewModel: TaskViewModel) => taskViewModel.task,
boardViewModel.taskViewModels,
boardViewModel.filteredTaskViewModels,
(taskViewModels: React.ListState<TaskViewModel>) => {
const viewModel: TaskCategoryBulkChangeViewModel =
new TaskCategoryBulkChangeViewModel(taskViewModels, categoryName);
+13 -1
View File
@@ -8,13 +8,16 @@ import { BoardKanbanPage } from "./boardKanbanPage";
import { BoardSettingsModal } from "../Modals/boardSettingsModal";
import { BoardStatusGridPage } from "./boardStatusGridPage";
import { BoardViewToggleButton } from "../Components/boardViewToggleButton";
import { SearchModal } from "../Modals/searchModal";
import { TaskSettingsModal } from "../Modals/taskSettingsModal";
import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
import { TaskViewModelToEntry } from "../Components/taskEntry";
import { translations } from "../translations";
export function BoardPage(boardViewModel: BoardViewModel) {
boardViewModel.loadData();
// main content
const mainContent = React.createProxyState(
[boardViewModel.selectedPage],
() => {
@@ -30,7 +33,7 @@ export function BoardPage(boardViewModel: BoardViewModel) {
<div
class="task-grid"
children:append={[
boardViewModel.taskViewModels,
boardViewModel.filteredTaskViewModels,
TaskViewModelToEntry,
]}
></div>
@@ -40,6 +43,7 @@ export function BoardPage(boardViewModel: BoardViewModel) {
}
);
// task modal
const taskSettingsModal = React.createProxyState(
[boardViewModel.selectedTaskViewModel],
() => {
@@ -110,6 +114,14 @@ export function BoardPage(boardViewModel: BoardViewModel) {
<div class="content main-content" children:set={mainContent}></div>
{BoardSettingsModal(boardViewModel)}
{SearchModal(
translations.chatPage.task.filterTasksHeadline,
boardViewModel.taskViewModels,
boardViewModel.filteredTaskViewModels,
TaskViewModelToEntry,
boardViewModel.getStringsFromTaskViewModel,
boardViewModel.isPresentingFilterModal
)}
<div children:set={taskSettingsModal}></div>
</div>
);
+2 -2
View File
@@ -3,7 +3,7 @@ import * as React from "bloatless-react";
import {
TaskCategoryBulkChangeViewModel,
TaskStatusBulkChangeViewModel,
} from "../../ViewModel/Pages/taskPropertyBulkChangeViewModel";
} from "../../ViewModel/Utility/taskPropertyBulkChangeViewModel";
import BoardViewModel from "../../ViewModel/Pages/boardViewModel";
import { FilteredList } from "../Components/filteredList";
@@ -46,7 +46,7 @@ export function BoardStatusGridPage(boardViewModel: BoardViewModel) {
{PropertyValueList(
"category",
(taskViewModel: TaskViewModel) => taskViewModel.task,
boardViewModel.taskViewModels,
boardViewModel.filteredTaskViewModels,
(categories: React.ListState<string>) => {
return (
<div
+59
View File
@@ -0,0 +1,59 @@
import * as React from "bloatless-react";
import SearchViewModel from "../../ViewModel/Utility/searchViewModel";
import { translations } from "../translations";
export function SearchModal<T>(
headline: string,
allObjects: React.ListState<T> | React.MapState<T>,
filteredObjects: React.ListState<T>,
converter: React.StateItemConverter<T>,
getStringsOfObject: (object: T) => string[],
isOpen: React.State<boolean>
) {
const viewModel: SearchViewModel<T> = new SearchViewModel(
allObjects,
filteredObjects,
getStringsOfObject
);
function close() {
isOpen.value = false;
}
return (
<div class="modal" toggle:open={isOpen}>
<div style="max-width: 64rem">
<main>
<h2>{headline}</h2>
<div class="flex-row width-input">
<input
placeholder={translations.general.searchLabel}
bind:value={viewModel.searchInput}
on:enter={viewModel.applySearch}
></input>
<button
class="primary"
aria-label={translations.general.searchButtonAudioLabel}
on:click={viewModel.applySearch}
toggle:disabled={viewModel.cannotApplySearch}
>
<span class="icon">search</span>
</button>
</div>
<hr></hr>
<div
class="grid gap"
children:append={[filteredObjects, converter]}
></div>
</main>
<button on:click={close}>
{translations.general.closeButton}
<span class="icon">close</span>
</button>
</div>
</div>
);
}
+6
View File
@@ -1,6 +1,7 @@
const englishTranslations = {
general: {
deleteItemButtonAudioLabel: "delete item",
searchButtonAudioLabel: "search",
abortButton: "Abort",
closeButton: "Close",
@@ -10,6 +11,7 @@ const englishTranslations = {
setButton: "Set",
fileVersionLabel: "Version",
searchLabel: "Search",
},
regional: {
@@ -177,6 +179,10 @@ const englishTranslations = {
///
filterTasksHeadline: "Filter Tasks",
///
renameCategoryInputPlaceholder: "Rename category,"
},
},