search by fields, exclude words

This commit is contained in:
Marlon Erler
2024-07-17 14:25:11 +00:00
parent 94799e7e3e
commit e41bbd5acb
5 changed files with 506 additions and 469 deletions
+31 -15
View File
@@ -508,9 +508,9 @@
createObject: "create object", createObject: "create object",
untitledObject: "Untitled Object", untitledObject: "Untitled Object",
filterObjects: "Filter Objects", filterObjects: "Filter Objects",
searchByTitle: "Search by title", searchTitle: "Search",
searchByTitlePlaceholder: "My Object", searchPlaceholder: "Note 2000-12-31",
searchTitleText: (term, resultCount) => term == "" ? `Objects in total: ${resultCount}` : `Objects containing "${term}": ${resultCount}`, searchTitleText: (term, resultCount) => term == "" ? `Objects in total: ${resultCount}` : `Matches for "${term}": ${resultCount}`,
viewAll: "All", viewAll: "All",
viewNotes: "Notes", viewNotes: "Notes",
viewKanban: "Kanban", viewKanban: "Kanban",
@@ -613,8 +613,8 @@
createObject: "a\xF1adir nuevo objeto", createObject: "a\xF1adir nuevo objeto",
untitledObject: "Sin T\xEDtulo", untitledObject: "Sin T\xEDtulo",
filterObjects: "Filtrar objetos", filterObjects: "Filtrar objetos",
searchByTitle: "Buscar por t\xEDtulo", searchTitle: "Buscar",
searchByTitlePlaceholder: "Mi Objeto", searchPlaceholder: "Nota 2000-12-31",
searchTitleText: (term, resultCount) => term == "" ? `Objetos en total: ${resultCount}` : `Resultados por "${term}": ${resultCount}`, searchTitleText: (term, resultCount) => term == "" ? `Objetos en total: ${resultCount}` : `Resultados por "${term}": ${resultCount}`,
viewAll: "Todos", viewAll: "Todos",
viewNotes: "Notas", viewNotes: "Notas",
@@ -716,8 +716,8 @@
createObject: "Neues Objekt erstellen", createObject: "Neues Objekt erstellen",
untitledObject: "Unbenannt", untitledObject: "Unbenannt",
filterObjects: "Objekte filtern", filterObjects: "Objekte filtern",
searchByTitle: "Nach Titel suchen", searchTitle: "Suchen",
searchByTitlePlaceholder: "Mein Objekt", searchPlaceholder: "Notiz 2000-12-31",
searchTitleText: (term, resultCount) => term == "" ? `Objekte insgesamt: ${resultCount}` : `Ergebnisse f\xFCr "${term}": ${resultCount}`, searchTitleText: (term, resultCount) => term == "" ? `Objekte insgesamt: ${resultCount}` : `Ergebnisse f\xFCr "${term}": ${resultCount}`,
viewAll: "Alle", viewAll: "Alle",
viewNotes: "Notizen", viewNotes: "Notizen",
@@ -1573,7 +1573,7 @@
"span", "span",
{ {
class: "grid height-100 flex secondary", class: "grid height-100 flex secondary",
style: "grid-template-columns: 1fr 1fr" style: "grid-template-columns: 1fr 1fr; grid-template-rows: repeat(3, 1.7rem)"
}, },
...fieldElements ...fieldElements
)) ))
@@ -2086,7 +2086,7 @@
() => translation.searchTitleText(appliedFilter.value, resultCount.value) () => translation.searchTitleText(appliedFilter.value, resultCount.value)
); );
const showingMessageObjects = new MapState(); const showingMessageObjects = new MapState();
const cannotReset = createProxyState( const isFilterEmpty = createProxyState(
[appliedFilter], [appliedFilter],
() => appliedFilter.value == "" () => appliedFilter.value == ""
); );
@@ -2112,9 +2112,25 @@
}); });
}); });
function checkMatchesFilter(messageObject) { function checkMatchesFilter(messageObject) {
let objectTitle = messageObject.title || translation.untitledObject; if (isFilterEmpty.value == true) return true;
const regex = new RegExp(appliedFilter.value.toLowerCase()); const wordsOfObject = [];
return regex.test(objectTitle.toLowerCase()); const objectTitle = messageObject.title || translation.untitledObject;
wordsOfObject.push(...objectTitle.toLowerCase().split(" "));
const latest = chat.getMostRecentContent(messageObject);
if (latest) {
Object.values(latest).forEach((value) => {
wordsOfObject.push(value.toLowerCase());
});
}
const wordsOfSearchTerm = appliedFilter.value.toLowerCase().split(" ");
for (const word of wordsOfSearchTerm) {
if (word[0] == "-") {
const wordContent = word.substring(1);
console.log(wordContent);
if (wordsOfObject.includes(wordContent)) return false;
} else if (!wordsOfObject.includes(word)) return false;
}
return true;
} }
applyFilter(); applyFilter();
const objectModal = createProxyState( const objectModal = createProxyState(
@@ -2172,19 +2188,19 @@
class: "object-content width-100 height-100 flex scroll-no", class: "object-content width-100 height-100 flex scroll-no",
"children:set": mainView "children:set": mainView
} }
), /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isShowingFilterModel }, /* @__PURE__ */ createElement("div", { style: "max-width: 2084px" }, /* @__PURE__ */ createElement("main", { class: "gap" }, /* @__PURE__ */ createElement("h2", null, translation.filterObjects), /* @__PURE__ */ createElement("div", { class: "flex-column" }, /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "search"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.searchByTitle), /* @__PURE__ */ createElement( ), /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isShowingFilterModel }, /* @__PURE__ */ createElement("div", { style: "max-width: 2084px" }, /* @__PURE__ */ createElement("main", { class: "gap" }, /* @__PURE__ */ createElement("h2", null, translation.filterObjects), /* @__PURE__ */ createElement("div", { class: "flex-column" }, /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "search"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.searchTitle), /* @__PURE__ */ createElement(
"input", "input",
{ {
"bind:value": filterInput, "bind:value": filterInput,
"on:enter": applyFilter, "on:enter": applyFilter,
placeholder: translation.searchByTitlePlaceholder placeholder: translation.searchPlaceholder
} }
)))), /* @__PURE__ */ createElement("div", { class: "flex-row width-input" }, /* @__PURE__ */ createElement( )))), /* @__PURE__ */ createElement("div", { class: "flex-row width-input" }, /* @__PURE__ */ createElement(
"button", "button",
{ {
class: "width-50 flex", class: "width-50 flex",
"on:click": resetFilter, "on:click": resetFilter,
"toggle:disabled": cannotReset "toggle:disabled": isFilterEmpty
}, },
translation.reset translation.reset
), /* @__PURE__ */ createElement("button", { class: "width-50 flex primary", "on:click": applyFilter }, translation.search, /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_forward"))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("b", { class: "secondary", "subscribe:innerText": resultText }), ObjectGridView( ), /* @__PURE__ */ createElement("button", { class: "width-50 flex primary", "on:click": applyFilter }, translation.search, /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_forward"))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("b", { class: "secondary", "subscribe:innerText": resultText }), ObjectGridView(
+10 -10
View File
@@ -1,13 +1,13 @@
{ {
"name": "udn-broadcast", "name": "udn-comms",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"dependencies": { "dependencies": {
"bloatless-react": "^1.2.0", "bloatless-react": "^1.3.8",
"esbuild": "latest", "esbuild": "^0.23.0",
"udn-frontend": "^1.0.1" "udn-frontend": "^1.0.7-beta1"
} }
}, },
"node_modules/@esbuild/aix-ppc64": { "node_modules/@esbuild/aix-ppc64": {
@@ -371,9 +371,9 @@
} }
}, },
"node_modules/bloatless-react": { "node_modules/bloatless-react": {
"version": "1.2.1", "version": "1.3.8",
"resolved": "https://registry.npmjs.org/bloatless-react/-/bloatless-react-1.2.1.tgz", "resolved": "https://registry.npmjs.org/bloatless-react/-/bloatless-react-1.3.8.tgz",
"integrity": "sha512-VxJ2XYTS7Aw3mgjfKrLtR471bg2KHzsj2nUtEeY5Ml4R82XQBL+B4o3EYM9u4TStokHMywm+Pa+qNTNbRDZw/g==", "integrity": "sha512-cq4pqO7KauxSBP7QbpJxsDgg/O6TK1lkrpqGYw10uxDPG5gn26jSjCrywFhEEfwyaNwKu6g+VljjTJIQLzNdWA==",
"dependencies": { "dependencies": {
"uuid": "^10.0.0" "uuid": "^10.0.0"
} }
@@ -417,9 +417,9 @@
} }
}, },
"node_modules/udn-frontend": { "node_modules/udn-frontend": {
"version": "1.0.2", "version": "1.0.7-beta1",
"resolved": "https://registry.npmjs.org/udn-frontend/-/udn-frontend-1.0.2.tgz", "resolved": "https://registry.npmjs.org/udn-frontend/-/udn-frontend-1.0.7-beta1.tgz",
"integrity": "sha512-CNLJOHg0CNujDIjMABUM9rUsR6ZJ2rFfxU4GwO6e/6rgWzxmy5AilZZeeQAEr8aldHgoQAiS7DC1xXsR+Dimbg==" "integrity": "sha512-Q9PS5SEtn1myYnQOQuv6U+ro9Thvc6CyiitBIKWE2TMDG652kU5l7dznW5ebi6htVtHiZrJcBiBSIx1jBpR2qg=="
}, },
"node_modules/uuid": { "node_modules/uuid": {
"version": "10.0.0", "version": "10.0.0",
+3 -3
View File
@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"bloatless-react": "latest", "bloatless-react": "^1.3.8",
"esbuild": "latest", "esbuild": "^0.23.0",
"udn-frontend": "latest" "udn-frontend": "^1.0.7-beta1"
}, },
"scripts": { "scripts": {
"build": "esbuild src/index.tsx --bundle --outdir=dist" "build": "esbuild src/index.tsx --bundle --outdir=dist"
+31 -10
View File
@@ -49,7 +49,7 @@ export function ObjectPane(chat: Chat) {
translation.searchTitleText(appliedFilter.value, resultCount.value) translation.searchTitleText(appliedFilter.value, resultCount.value)
); );
const showingMessageObjects = new React.MapState<MessageObject>(); const showingMessageObjects = new React.MapState<MessageObject>();
const cannotReset = React.createProxyState( const isFilterEmpty = React.createProxyState(
[appliedFilter], [appliedFilter],
() => appliedFilter.value == "" () => appliedFilter.value == ""
); );
@@ -70,18 +70,39 @@ export function ObjectPane(chat: Chat) {
matchingObjects.forEach((entry) => showingMessageObjects.set(...entry)); matchingObjects.forEach((entry) => showingMessageObjects.set(...entry));
} }
chat.objects.handleAddition(messageObject => { chat.objects.handleAddition((messageObject) => {
if (checkMatchesFilter(messageObject) == false) return; if (checkMatchesFilter(messageObject) == false) return;
showingMessageObjects.set(messageObject.id, messageObject); showingMessageObjects.set(messageObject.id, messageObject);
chat.objects.handleRemoval(messageObject, () => { chat.objects.handleRemoval(messageObject, () => {
showingMessageObjects.remove(messageObject.id); showingMessageObjects.remove(messageObject.id);
}) });
}) });
function checkMatchesFilter(messageObject: MessageObject) { function checkMatchesFilter(messageObject: MessageObject) {
let objectTitle = messageObject.title || translation.untitledObject; if (isFilterEmpty.value == true) return true;
const regex = new RegExp(appliedFilter.value.toLowerCase());
return regex.test(objectTitle.toLowerCase()); const wordsOfObject: string[] = [];
const objectTitle = messageObject.title || translation.untitledObject;
wordsOfObject.push(...objectTitle.toLowerCase().split(" "));
const latest = chat.getMostRecentContent(messageObject);
if (latest) {
Object.values(latest).forEach((value) => {
wordsOfObject.push(value.toLowerCase());
});
}
const wordsOfSearchTerm = appliedFilter.value.toLowerCase().split(" ");
for (const word of wordsOfSearchTerm) {
if (word[0] == "-") {
// exclusion
const wordContent = word.substring(1);
console.log(wordContent);
if (wordsOfObject.includes(wordContent)) return false;
} else if (!wordsOfObject.includes(word)) return false;
}
return true;
} }
applyFilter(); applyFilter();
@@ -162,11 +183,11 @@ export function ObjectPane(chat: Chat) {
<label class="tile"> <label class="tile">
<span class="icon">search</span> <span class="icon">search</span>
<div> <div>
<span>{translation.searchByTitle}</span> <span>{translation.searchTitle}</span>
<input <input
bind:value={filterInput} bind:value={filterInput}
on:enter={applyFilter} on:enter={applyFilter}
placeholder={translation.searchByTitlePlaceholder} placeholder={translation.searchPlaceholder}
></input> ></input>
</div> </div>
</label> </label>
@@ -175,7 +196,7 @@ export function ObjectPane(chat: Chat) {
<button <button
class="width-50 flex" class="width-50 flex"
on:click={resetFilter} on:click={resetFilter}
toggle:disabled={cannotReset} toggle:disabled={isFilterEmpty}
> >
{translation.reset} {translation.reset}
</button> </button>
+7 -7
View File
@@ -102,12 +102,12 @@ const englishTranslations = {
untitledObject: "Untitled Object", untitledObject: "Untitled Object",
filterObjects: "Filter Objects", filterObjects: "Filter Objects",
searchByTitle: "Search by title", searchTitle: "Search",
searchByTitlePlaceholder: "My Object", searchPlaceholder: "Note 2000-12-31",
searchTitleText: (term: string, resultCount: number) => searchTitleText: (term: string, resultCount: number) =>
term == "" term == ""
? `Objects in total: ${resultCount}` ? `Objects in total: ${resultCount}`
: `Objects containing "${term}": ${resultCount}`, : `Matches for "${term}": ${resultCount}`,
viewAll: "All", viewAll: "All",
viewNotes: "Notes", viewNotes: "Notes",
@@ -241,8 +241,8 @@ const allTranslations: { [key: string]: typeof englishTranslations } = {
untitledObject: "Sin Título", untitledObject: "Sin Título",
filterObjects: "Filtrar objetos", filterObjects: "Filtrar objetos",
searchByTitle: "Buscar por título", searchTitle: "Buscar",
searchByTitlePlaceholder: "Mi Objeto", searchPlaceholder: "Nota 2000-12-31",
searchTitleText: (term: string, resultCount: number) => searchTitleText: (term: string, resultCount: number) =>
term == "" term == ""
? `Objetos en total: ${resultCount}` ? `Objetos en total: ${resultCount}`
@@ -377,8 +377,8 @@ const allTranslations: { [key: string]: typeof englishTranslations } = {
untitledObject: "Unbenannt", untitledObject: "Unbenannt",
filterObjects: "Objekte filtern", filterObjects: "Objekte filtern",
searchByTitle: "Nach Titel suchen", searchTitle: "Suchen",
searchByTitlePlaceholder: "Mein Objekt", searchPlaceholder: "Notiz 2000-12-31",
searchTitleText: (term: string, resultCount: number) => searchTitleText: (term: string, resultCount: number) =>
term == "" term == ""
? `Objekte insgesamt: ${resultCount}` ? `Objekte insgesamt: ${resultCount}`