add separate message filter modal, clean styles

This commit is contained in:
marlon-erler
2026-04-11 20:37:19 +00:00
parent 240c307418
commit 45e3ed31ee
5 changed files with 118 additions and 46 deletions
+60 -38
View File
@@ -2221,6 +2221,9 @@
this.openFilterModal = () => { this.openFilterModal = () => {
this.isFilterModalOpen.value = true; this.isFilterModalOpen.value = true;
}; };
this.closeFilterModal = () => {
this.isFilterModalOpen.value = false;
};
// load // load
this.loadData = () => { this.loadData = () => {
this.chatMessageViewModels.clear(); this.chatMessageViewModels.clear();
@@ -3607,50 +3610,25 @@
); );
} }
// src/View/Modals/searchModal.tsx // src/View/Modals/messageFilterModal.tsx
function SearchModal(coreViewModel2, searchViewModel, headline, converter, isOpen) { function MessageFilterModal(coreViewModel2, messagePageViewModel, converter) {
function close() { return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": messagePageViewModel.isFilterModalOpen }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.chatPage.message.messageFilterHeadline), /* @__PURE__ */ createElement("div", { class: "flex-row width-input" }, /* @__PURE__ */ createElement(
isOpen.value = false;
}
const suggestionId = v4_default();
return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isOpen }, /* @__PURE__ */ createElement("div", { style: "max-width: 64rem" }, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("h2", null, headline), /* @__PURE__ */ createElement("div", { class: "flex-row width-input" }, /* @__PURE__ */ createElement(
"input", "input",
{ {
placeholder: coreViewModel2.translations.general.searchLabel, placeholder: coreViewModel2.translations.general.searchLabel,
"bind:value": searchViewModel.searchInput, "bind:value": messagePageViewModel.searchViewModel.searchInput,
"on:enter": searchViewModel.applySearch, "on:enter": messagePageViewModel.searchViewModel.applySearch
list: suggestionId
}
), /* @__PURE__ */ createElement(
"datalist",
{
hidden: true,
id: suggestionId,
"children:append": [
searchViewModel.suggestions,
StringToOption
]
} }
), /* @__PURE__ */ createElement( ), /* @__PURE__ */ createElement(
"button", "button",
{ {
class: "primary", class: "primary",
"aria-label": coreViewModel2.translations.general.searchButtonAudioLabel, "aria-label": coreViewModel2.translations.general.searchButtonAudioLabel,
"on:click": searchViewModel.applySearch, "on:click": messagePageViewModel.searchViewModel.applySearch,
"toggle:disabled": searchViewModel.cannotApplySearch "toggle:disabled": messagePageViewModel.searchViewModel.cannotApplySearch
}, },
/* @__PURE__ */ createElement("span", { class: "icon" }, "search") /* @__PURE__ */ createElement("span", { class: "icon" }, "search")
)), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement( )), /* @__PURE__ */ createElement("hr", null)), /* @__PURE__ */ createElement("button", { "on:click": messagePageViewModel.closeFilterModal }, coreViewModel2.translations.general.closeButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "close"))));
"div",
{
class: "grid gap",
style: "grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr))",
"children:append": [
searchViewModel.matchingObjects,
converter
]
}
)), /* @__PURE__ */ createElement("button", { "on:click": close }, coreViewModel2.translations.general.closeButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "close"))));
} }
// src/View/ChatPages/messagePage.tsx // src/View/ChatPages/messagePage.tsx
@@ -3709,12 +3687,10 @@
"toggle:disabled": messagePageViewModel.cannotSendMessage "toggle:disabled": messagePageViewModel.cannotSendMessage
}, },
/* @__PURE__ */ createElement("span", { class: "icon" }, "send") /* @__PURE__ */ createElement("span", { class: "icon" }, "send")
))))))), SearchModal( ))))))), MessageFilterModal(
coreViewModel2, coreViewModel2,
messagePageViewModel.searchViewModel, messagePageViewModel,
coreViewModel2.translations.chatPage.message.messageFilterHeadline, ChatMessageViewModelToView
ChatMessageViewModelToView,
messagePageViewModel.isFilterModalOpen
)); ));
} }
@@ -4235,6 +4211,52 @@
return RibbonButton(label, icon, isSelected, select); return RibbonButton(label, icon, isSelected, select);
} }
// src/View/Modals/searchModal.tsx
function SearchModal(coreViewModel2, searchViewModel, headline, converter, isOpen) {
function close() {
isOpen.value = false;
}
const suggestionId = v4_default();
return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isOpen, extended: true }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("h2", null, headline), /* @__PURE__ */ createElement("div", { class: "flex-row width-input" }, /* @__PURE__ */ createElement(
"input",
{
placeholder: coreViewModel2.translations.general.searchLabel,
"bind:value": searchViewModel.searchInput,
"on:enter": searchViewModel.applySearch,
list: suggestionId
}
), /* @__PURE__ */ createElement(
"datalist",
{
hidden: true,
id: suggestionId,
"children:append": [
searchViewModel.suggestions,
StringToOption
]
}
), /* @__PURE__ */ createElement(
"button",
{
class: "primary",
"aria-label": coreViewModel2.translations.general.searchButtonAudioLabel,
"on:click": searchViewModel.applySearch,
"toggle:disabled": searchViewModel.cannotApplySearch
},
/* @__PURE__ */ createElement("span", { class: "icon" }, "search")
)), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement(
"div",
{
class: "grid gap",
style: "grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr))",
"children:append": [
searchViewModel.matchingObjects,
converter
]
}
)), /* @__PURE__ */ createElement("button", { "on:click": close }, coreViewModel2.translations.general.closeButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "close"))));
}
// src/View/ChatPages/boardPage.tsx // src/View/ChatPages/boardPage.tsx
function BoardPage(coreViewModel2, boardViewModel) { function BoardPage(coreViewModel2, boardViewModel) {
boardViewModel.loadData(); boardViewModel.loadData();
+3 -6
View File
@@ -6,7 +6,7 @@ import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel";
import CoreViewModel from "../../ViewModel/Global/coreViewModel"; import CoreViewModel from "../../ViewModel/Global/coreViewModel";
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel"; import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
import { ChatMessage } from "../Components/chatMessage"; import { ChatMessage } from "../Components/chatMessage";
import { SearchModal } from "../Modals/searchModal"; import { MessageFilterModal } from "../Modals/messageFilterModal";
export function MessagePage( export function MessagePage(
coreViewModel: CoreViewModel, coreViewModel: CoreViewModel,
@@ -114,13 +114,10 @@ export function MessagePage(
</div> </div>
</div> </div>
{SearchModal( {MessageFilterModal(
coreViewModel, coreViewModel,
messagePageViewModel.searchViewModel, messagePageViewModel,
coreViewModel.translations.chatPage.message
.messageFilterHeadline,
ChatMessageViewModelToView, ChatMessageViewModelToView,
messagePageViewModel.isFilterModalOpen,
)} )}
</div> </div>
); );
+49
View File
@@ -0,0 +1,49 @@
import * as React from "bloatless-react";
import SearchViewModel from "../../ViewModel/Utility/searchViewModel";
import { StringToOption } from "../Components/option";
import { v4 } from "uuid";
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel";
export function MessageFilterModal<T>(
coreViewModel: CoreViewModel,
messagePageViewModel: MessagePageViewModel,
converter: React.StateItemConverter<T>,
) {
return (
<div class="modal" toggle:open={messagePageViewModel.isFilterModalOpen}>
<div>
<main>
<h2>{coreViewModel.translations.chatPage.message.messageFilterHeadline}</h2>
<div class="flex-row width-input">
<input
placeholder={
coreViewModel.translations.general.searchLabel
}
bind:value={messagePageViewModel.searchViewModel.searchInput}
on:enter={messagePageViewModel.searchViewModel.applySearch}
></input>
<button
class="primary"
aria-label={
coreViewModel.translations.general
.searchButtonAudioLabel
}
on:click={messagePageViewModel.searchViewModel.applySearch}
toggle:disabled={messagePageViewModel.searchViewModel.cannotApplySearch}
>
<span class="icon">search</span>
</button>
</div>
<hr></hr>
</main>
<button on:click={messagePageViewModel.closeFilterModal}>
{coreViewModel.translations.general.closeButton}
<span class="icon">close</span>
</button>
</div>
</div>
);
}
+2 -2
View File
@@ -19,8 +19,8 @@ export function SearchModal<T>(
const suggestionId = v4(); const suggestionId = v4();
return ( return (
<div class="modal" toggle:open={isOpen}> <div class="modal" toggle:open={isOpen} extended>
<div style="max-width: 64rem"> <div>
<main> <main>
<h2>{headline}</h2> <h2>{headline}</h2>
<div class="flex-row width-input"> <div class="flex-row width-input">
@@ -90,6 +90,10 @@ export default class MessagePageViewModel {
this.isFilterModalOpen.value = true; this.isFilterModalOpen.value = true;
}; };
closeFilterModal = (): void => {
this.isFilterModalOpen.value = false;
};
// load // load
loadData = (): void => { loadData = (): void => {
this.chatMessageViewModels.clear(); this.chatMessageViewModels.clear();