add filter modal, implement search
This commit is contained in:
@@ -20,7 +20,58 @@ export const viewTypes = {
|
||||
export function ObjectPane(chat: Chat) {
|
||||
// selection and modal
|
||||
const isShowingObjectModal = new React.State(false);
|
||||
const isShowingFilterModel = new React.State(false);
|
||||
|
||||
const selectedObject = new React.State<MessageObject | undefined>(undefined);
|
||||
|
||||
// methods
|
||||
function createObject() {
|
||||
const newObject = chat.createObjectFromTitle("");
|
||||
chat.addObjectAndSend(newObject);
|
||||
selectedObject.value = newObject;
|
||||
isShowingObjectModal.value = true;
|
||||
}
|
||||
|
||||
function showFilters() {
|
||||
isShowingFilterModel.value = true;
|
||||
}
|
||||
|
||||
function closeFilters() {
|
||||
isShowingFilterModel.value = false;
|
||||
}
|
||||
|
||||
// filter
|
||||
const filterInput = new React.State("");
|
||||
const appliedFilter = new React.State("");
|
||||
const resultCount = new React.State(0);
|
||||
const resultText = React.createProxyState([appliedFilter, resultCount], () =>
|
||||
translation.searchTitleText(appliedFilter.value, resultCount.value)
|
||||
);
|
||||
const messageObjects = new React.MapState<MessageObject>();
|
||||
const cannotReset = React.createProxyState(
|
||||
[appliedFilter],
|
||||
() => appliedFilter.value == ""
|
||||
);
|
||||
|
||||
function resetFilter() {
|
||||
filterInput.value = "";
|
||||
applyFilter();
|
||||
}
|
||||
function applyFilter() {
|
||||
appliedFilter.value = filterInput.value;
|
||||
}
|
||||
|
||||
appliedFilter.subscribe((filterTerm) => {
|
||||
const allObjects = [...chat.objects.value.entries()];
|
||||
const matchingObjects = allObjects.filter(
|
||||
(entry) => entry[1].title.indexOf(filterTerm) != -1
|
||||
);
|
||||
resultCount.value = matchingObjects.length;
|
||||
messageObjects.clear();
|
||||
matchingObjects.forEach((entry) => messageObjects.set(...entry));
|
||||
});
|
||||
|
||||
// view
|
||||
const objectModal = React.createProxyState(
|
||||
[chat.objects, selectedObject],
|
||||
() => {
|
||||
@@ -34,7 +85,6 @@ export function ObjectPane(chat: Chat) {
|
||||
}
|
||||
);
|
||||
|
||||
// view type
|
||||
const mainView = React.createProxyState([chat.viewType], () => {
|
||||
function getViewFunction() {
|
||||
switch (chat.viewType.value) {
|
||||
@@ -49,17 +99,14 @@ export function ObjectPane(chat: Chat) {
|
||||
}
|
||||
}
|
||||
|
||||
return getViewFunction()(chat, selectedObject, isShowingObjectModal);
|
||||
return getViewFunction()(
|
||||
chat,
|
||||
messageObjects,
|
||||
selectedObject,
|
||||
isShowingObjectModal
|
||||
);
|
||||
});
|
||||
|
||||
// methods
|
||||
function createObject() {
|
||||
const newObject = chat.createObjectFromTitle("");
|
||||
chat.addObjectAndSend(newObject);
|
||||
selectedObject.value = newObject;
|
||||
isShowingObjectModal.value = true;
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="chat-object-view flex-column scroll-no padding-0">
|
||||
<div class="flex-row align-center border-bottom">
|
||||
@@ -77,8 +124,12 @@ export function ObjectPane(chat: Chat) {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<button class="height-100" disabled>
|
||||
<span class="icon">visibility</span>
|
||||
<button
|
||||
class="height-100"
|
||||
aria-label={translation.filterObjects}
|
||||
on:click={showFilters}
|
||||
>
|
||||
<span class="icon">filter_list</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -88,6 +139,46 @@ export function ObjectPane(chat: Chat) {
|
||||
></div>
|
||||
|
||||
<div children:set={objectModal}></div>
|
||||
<div class="modal" toggle:open={isShowingFilterModel}>
|
||||
<div>
|
||||
<main>
|
||||
<h2>{translation.filterObjects}</h2>
|
||||
|
||||
<label class="tile">
|
||||
<span class="icon">search</span>
|
||||
<div>
|
||||
<span>{translation.searchByTitle}</span>
|
||||
<input
|
||||
bind:value={filterInput}
|
||||
on:enter={applyFilter}
|
||||
placeholder={translation.searchByTitlePlaceholder}
|
||||
></input>
|
||||
</div>
|
||||
</label>
|
||||
<div class="flex-row width-input">
|
||||
<button
|
||||
class="width-50 flex"
|
||||
on:click={resetFilter}
|
||||
toggle:disabled={cannotReset}
|
||||
>
|
||||
{translation.reset}
|
||||
</button>
|
||||
<button class="width-50 flex primary" on:click={applyFilter}>
|
||||
{translation.search}
|
||||
<span class="icon">arrow_forward</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<hr></hr>
|
||||
|
||||
<span class="secondary" subscribe:innerText={resultText}></span>
|
||||
</main>
|
||||
<button on:click={closeFilters}>
|
||||
{translation.close}
|
||||
<span class="icon">close</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user