Fix search behaviour of theme index, fix #1385

This commit is contained in:
Pieter Vander Vennet 2023-04-23 13:22:57 +02:00
parent aa6902a25c
commit 102fe2c5e8
2 changed files with 90 additions and 104 deletions

View file

@ -1,17 +1,17 @@
import Svg from "../../Svg" import Svg from "../../Svg"
import Combine from "../Base/Combine" import Combine from "../Base/Combine"
import { SubtleButton } from "../Base/SubtleButton" import {SubtleButton} from "../Base/SubtleButton"
import Translations from "../i18n/Translations" import Translations from "../i18n/Translations"
import BaseUIElement from "../BaseUIElement" import BaseUIElement from "../BaseUIElement"
import LayoutConfig, { LayoutInformation } from "../../Models/ThemeConfig/LayoutConfig" import LayoutConfig, {LayoutInformation} from "../../Models/ThemeConfig/LayoutConfig"
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource" import {ImmutableStore, Store, UIEventSource} from "../../Logic/UIEventSource"
import Loc from "../../Models/Loc" import Loc from "../../Models/Loc"
import UserRelatedState from "../../Logic/State/UserRelatedState" import UserRelatedState from "../../Logic/State/UserRelatedState"
import { Utils } from "../../Utils" import {Utils} from "../../Utils"
import Title from "../Base/Title" import Title from "../Base/Title"
import themeOverview from "../../assets/generated/theme_overview.json" import themeOverview from "../../assets/generated/theme_overview.json"
import { Translation } from "../i18n/Translation" import {Translation} from "../i18n/Translation"
import { TextField } from "../Input/TextField" import {TextField} from "../Input/TextField"
import Locale from "../i18n/Locale" import Locale from "../i18n/Locale"
import SvelteUIElement from "../Base/SvelteUIElement" import SvelteUIElement from "../Base/SvelteUIElement"
import ThemesList from "./ThemesList.svelte" import ThemesList from "./ThemesList.svelte"
@ -37,7 +37,7 @@ export default class MoreScreen extends Combine {
searchTerm = searchTerm.toLowerCase() searchTerm = searchTerm.toLowerCase()
if (searchTerm === "personal") { if (searchTerm === "personal") {
window.location.href = MoreScreen.createUrlFor( window.location.href = MoreScreen.createUrlFor(
{ id: "personal" }, {id: "personal"},
false, false,
state state
).data ).data
@ -59,13 +59,13 @@ export default class MoreScreen extends Combine {
(th) => (th) =>
th.hideFromOverview == false && th.hideFromOverview == false &&
th.id !== "personal" && th.id !== "personal" &&
MoreScreen.MatchesLayoutFunc(th)(searchTerm) MoreScreen.MatchesLayout(th, searchTerm)
) )
if (publicTheme !== undefined) { if (publicTheme !== undefined) {
window.location.href = MoreScreen.createUrlFor(publicTheme, false, state).data window.location.href = MoreScreen.createUrlFor(publicTheme, false, state).data
} }
const hiddenTheme = MoreScreen.officialThemes.find( const hiddenTheme = MoreScreen.officialThemes.find(
(th) => th.id !== "personal" && MoreScreen.MatchesLayoutFunc(th)(searchTerm) (th) => th.id !== "personal" && MoreScreen.MatchesLayout(th, searchTerm)
) )
if (hiddenTheme !== undefined) { if (hiddenTheme !== undefined) {
window.location.href = MoreScreen.createUrlFor(hiddenTheme, false, state).data window.location.href = MoreScreen.createUrlFor(hiddenTheme, false, state).data
@ -109,6 +109,85 @@ export default class MoreScreen extends Combine {
]) ])
} }
/**
* Creates a button linking to the given theme
* @private
*/
public static createLinkButton(
state: {
locationControl?: UIEventSource<Loc>
layoutToUse?: LayoutConfig
},
layout: {
id: string
icon: string
title: any
shortDescription: any
definition?: any
mustHaveLanguage?: boolean
},
isCustom: boolean = false
): BaseUIElement {
const url = MoreScreen.createUrlFor(layout, isCustom, state)
let content = new Combine([
new Translation(
layout.title,
!isCustom && !layout.mustHaveLanguage ? "themes:" + layout.id + ".title" : undefined
),
new Translation(layout.shortDescription)?.SetClass("subtle") ?? "",
]).SetClass("overflow-hidden flex flex-col")
if (state.layoutToUse === undefined) {
// Currently on the index screen: we style the buttons equally large
content = new Combine([content]).SetClass("flex flex-col justify-center h-24")
}
return new SubtleButton(layout.icon, content, {url, newTab: false})
}
public static CreateProffessionalSerivesButton() {
const t = Translations.t.professional.indexPage
return new Combine([
new Title(t.hook, 4),
t.hookMore,
new SubtleButton(undefined, t.button, {url: "./professional.html"}),
]).SetClass("flex flex-col border border-gray-300 p-2 rounded-lg")
}
public static MatchesLayout(layout: {
id: string
title: any
shortDescription: any
keywords?: any[]
}, search: string): boolean {
if(search === undefined){
return true
}
search = search.toLocaleLowerCase()
if (search.length > 3 && layout.id.toLowerCase().indexOf(search) >= 0) {
return true
}
if(layout.id === "personal"){
return false
}
const entitiesToSearch = [
layout.shortDescription,
layout.title,
...(layout.keywords ?? []),
]
for (const entity of entitiesToSearch) {
if (entity === undefined) {
continue
}
const term = entity["*"] ?? entity[Locale.language.data]
if (term?.toLowerCase()?.indexOf(search) >= 0) {
return true
}
}
return false
}
private static createUrlFor( private static createUrlFor(
layout: { id: string; definition?: string }, layout: { id: string; definition?: string },
isCustom: boolean, isCustom: boolean,
@ -164,79 +243,4 @@ export default class MoreScreen extends Combine {
}) ?? new ImmutableStore<string>(`${linkPrefix}`) }) ?? new ImmutableStore<string>(`${linkPrefix}`)
) )
} }
/**
* Creates a button linking to the given theme
* @private
*/
public static createLinkButton(
state: {
locationControl?: UIEventSource<Loc>
layoutToUse?: LayoutConfig
},
layout: {
id: string
icon: string
title: any
shortDescription: any
definition?: any
mustHaveLanguage?: boolean
},
isCustom: boolean = false
): BaseUIElement {
const url = MoreScreen.createUrlFor(layout, isCustom, state)
let content = new Combine([
new Translation(
layout.title,
!isCustom && !layout.mustHaveLanguage ? "themes:" + layout.id + ".title" : undefined
),
new Translation(layout.shortDescription)?.SetClass("subtle") ?? "",
]).SetClass("overflow-hidden flex flex-col")
if (state.layoutToUse === undefined) {
// Currently on the index screen: we style the buttons equally large
content = new Combine([content]).SetClass("flex flex-col justify-center h-24")
}
return new SubtleButton(layout.icon, content, { url, newTab: false })
}
public static CreateProffessionalSerivesButton() {
const t = Translations.t.professional.indexPage
return new Combine([
new Title(t.hook, 4),
t.hookMore,
new SubtleButton(undefined, t.button, { url: "./professional.html" }),
]).SetClass("flex flex-col border border-gray-300 p-2 rounded-lg")
}
private static MatchesLayoutFunc(layout: {
id: string
title: any
shortDescription: any
keywords?: any[]
}): (search: string) => boolean {
return (search: string) => {
search = search.toLocaleLowerCase()
if (layout.id.toLowerCase().indexOf(search) >= 0) {
return true
}
const entitiesToSearch = [
layout.shortDescription,
layout.title,
...(layout.keywords ?? []),
]
for (const entity of entitiesToSearch) {
if (entity === undefined) {
continue
}
const term = entity["*"] ?? entity[Locale.language.data]
if (term?.toLowerCase()?.indexOf(search) >= 0) {
return true
}
}
return false
}
}
} }

View file

@ -9,6 +9,7 @@
import ProfessionalServicesButton from "./ProfessionalServicesButton.svelte" import ProfessionalServicesButton from "./ProfessionalServicesButton.svelte"
import ThemeButton from "./ThemeButton.svelte" import ThemeButton from "./ThemeButton.svelte"
import { LayoutInformation } from "../../Models/ThemeConfig/LayoutConfig" import { LayoutInformation } from "../../Models/ThemeConfig/LayoutConfig"
import MoreScreen from "./MoreScreen";
export let search: UIEventSource<string> export let search: UIEventSource<string>
export let themes: LayoutInformation[] export let themes: LayoutInformation[]
@ -18,26 +19,7 @@
export let hideThemes: boolean = true export let hideThemes: boolean = true
// Filter theme based on search value // Filter theme based on search value
$: filteredThemes = themes.filter((theme) => { $: filteredThemes = themes.filter((theme) => MoreScreen.MatchesLayout(theme, $search))
if ($search === undefined || $search === "") return true
const srch = $search.toLocaleLowerCase()
if (theme.id.toLowerCase().indexOf(srch) >= 0) {
return true
}
const entitiesToSearch = [theme.shortDescription, theme.title, ...(theme.keywords ?? [])]
for (const entity of entitiesToSearch) {
if (entity === undefined) {
continue
}
const term = entity["*"] ?? entity[Locale.language.data]
if (term?.toLowerCase()?.indexOf(search) >= 0) {
return true
}
}
return false
})
</script> </script>
<section> <section>