forked from potsda.mn/mobilizon
Search improvements
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
5d507ecf69
commit
be33c3b213
20
js/src/components/Event/SkeletonEventResultList.vue
Normal file
20
js/src/components/Event/SkeletonEventResultList.vue
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<template>
|
||||||
|
<div class="bg-white dark:bg-slate-800 shadow rounded-md w-full mx-auto">
|
||||||
|
<div class="animate-pulse flex flex-col sm:flex-row space-3-4 items-center">
|
||||||
|
<div class="object-cover h-40 w-72 bg-slate-700 m-2 md:m-4 shrink-0" />
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="flex gap-3 flex self-start flex-col justify-between m-2 md:m-4 w-full px-2 md:px-4"
|
||||||
|
>
|
||||||
|
<div class="h-3 bg-slate-700 w-52 hidden sm:block"></div>
|
||||||
|
<div class="h-5 bg-slate-700 w-72 lg:w-96"></div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div
|
||||||
|
class="rounded-full object-cover h-6 w-6 bg-slate-700 mx-2 shrink-0"
|
||||||
|
/>
|
||||||
|
<div class="h-3 bg-slate-700 w-52"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
16
js/src/components/Group/SkeletonGroupResultList.vue
Normal file
16
js/src/components/Group/SkeletonGroupResultList.vue
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<template>
|
||||||
|
<div class="bg-white dark:bg-slate-800 shadow rounded-md w-full mx-auto">
|
||||||
|
<div class="animate-pulse flex flex-col sm:flex-row space-3-4 items-center">
|
||||||
|
<div
|
||||||
|
class="object-cover h-40 w-40 rounded-full bg-slate-700 m-2 md:m-4 shrink-0"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="flex gap-3 flex self-start flex-col justify-between m-2 md:m-4 self-center w-full px-2 md:px-4"
|
||||||
|
>
|
||||||
|
<div class="h-5 bg-slate-700 w-64"></div>
|
||||||
|
<div class="h-3 bg-slate-700 w-52"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -1425,5 +1425,15 @@
|
||||||
"Message body": "Message body",
|
"Message body": "Message body",
|
||||||
"Describe your event": "Describe your event",
|
"Describe your event": "Describe your event",
|
||||||
"A few lines about your group": "A few lines about your group",
|
"A few lines about your group": "A few lines about your group",
|
||||||
"Write your post": "Write your post"
|
"Write your post": "Write your post",
|
||||||
|
"Suggestions:": "Suggestions:",
|
||||||
|
"Make sure that all words are spelled correctly.": "Make sure that all words are spelled correctly.",
|
||||||
|
"Try different keywords.": "Try different keywords.",
|
||||||
|
"Try more general keywords.": "Try more general keywords.",
|
||||||
|
"Try fewer keywords.": "Try fewer keywords.",
|
||||||
|
"Change the filters.": "Change the filters.",
|
||||||
|
"No results found for {search}": "No results found for {search}",
|
||||||
|
"No events found for {search}": "No events found for {search}",
|
||||||
|
"No groups found for {search}": "No groups found for {search}",
|
||||||
|
"No event found at this address": "No event found at this address"
|
||||||
}
|
}
|
|
@ -1423,5 +1423,15 @@
|
||||||
"Message body": "Corps du message",
|
"Message body": "Corps du message",
|
||||||
"Describe your event": "Décrivez votre événement",
|
"Describe your event": "Décrivez votre événement",
|
||||||
"A few lines about your group": "Quelques lignes à propos de votre groupe",
|
"A few lines about your group": "Quelques lignes à propos de votre groupe",
|
||||||
"Write your post": "Écrivez votre billet"
|
"Write your post": "Écrivez votre billet",
|
||||||
|
"Suggestions:": "Suggestions :",
|
||||||
|
"Make sure that all words are spelled correctly.": "Vérifiez l’orthographe des termes de recherche.",
|
||||||
|
"Try different keywords.": "Essayez d'autres mots.",
|
||||||
|
"Try more general keywords.": "Utilisez des mots clés plus généraux.",
|
||||||
|
"Try fewer keywords.": "Spécifiez un moins grand nombre de mots-clés.",
|
||||||
|
"Change the filters.": "Changez les filtres.",
|
||||||
|
"No results found for {search}": "Aucun résultat trouvé pour {search}",
|
||||||
|
"No events found for {search}": "Aucun événement trouvé pour {search}",
|
||||||
|
"No groups found for {search}": "Aucun groupe trouvé pour {search}",
|
||||||
|
"No event found at this address": "Aucun événement trouvé à cette addresse"
|
||||||
}
|
}
|
||||||
|
|
|
@ -500,11 +500,16 @@
|
||||||
</div>
|
</div>
|
||||||
<div v-if="mode === ViewMode.LIST">
|
<div v-if="mode === ViewMode.LIST">
|
||||||
<template v-if="contentType === ContentType.ALL">
|
<template v-if="contentType === ContentType.ALL">
|
||||||
|
<template v-if="searchLoading">
|
||||||
|
<SkeletonGroupResultList v-for="i in 2" :key="i" />
|
||||||
|
<SkeletonEventResultList v-for="i in 4" :key="i" />
|
||||||
|
</template>
|
||||||
<o-notification v-if="features && !features.groups" variant="danger">
|
<o-notification v-if="features && !features.groups" variant="danger">
|
||||||
{{ t("Groups are not enabled on this instance.") }}
|
{{ t("Groups are not enabled on this instance.") }}
|
||||||
</o-notification>
|
</o-notification>
|
||||||
<div v-else-if="searchGroups && searchGroups?.total > 0">
|
<div v-else-if="searchGroups && searchGroups?.total > 0">
|
||||||
<GroupCard
|
<GroupCard
|
||||||
|
class="my-2"
|
||||||
v-for="group in searchGroups?.elements"
|
v-for="group in searchGroups?.elements"
|
||||||
:group="group"
|
:group="group"
|
||||||
:key="group.id"
|
:key="group.id"
|
||||||
|
@ -513,9 +518,6 @@
|
||||||
mode="row"
|
mode="row"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<o-notification v-else-if="searchLoading === false" variant="danger">
|
|
||||||
{{ t("No groups found") }}
|
|
||||||
</o-notification>
|
|
||||||
<div v-if="searchEvents && searchEvents.total > 0">
|
<div v-if="searchEvents && searchEvents.total > 0">
|
||||||
<event-card
|
<event-card
|
||||||
mode="row"
|
mode="row"
|
||||||
|
@ -529,16 +531,40 @@
|
||||||
class="my-4"
|
class="my-4"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<o-notification v-else-if="searchLoading === false" variant="info">
|
<EmptyContent v-else-if="searchLoading === false" icon="magnify">
|
||||||
<p>{{ t("No events found") }}</p>
|
<span v-if="searchIsUrl">
|
||||||
<p v-if="searchIsUrl && !currentUser?.id">
|
{{ t("No event found at this address") }}
|
||||||
|
</span>
|
||||||
|
<span v-else-if="!search">
|
||||||
|
{{ t("No results found") }}
|
||||||
|
</span>
|
||||||
|
<i18n-t keypath="No results found for {search}" tag="span" v-else>
|
||||||
|
<template #search>
|
||||||
|
<b class="">{{ search }}</b>
|
||||||
|
</template>
|
||||||
|
</i18n-t>
|
||||||
|
<template #desc v-if="searchIsUrl && !currentUser?.id">
|
||||||
{{
|
{{
|
||||||
t(
|
t(
|
||||||
"Only registered users may fetch remote events from their URL."
|
"Only registered users may fetch remote events from their URL."
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
</p>
|
</template>
|
||||||
</o-notification>
|
<template #desc v-else>
|
||||||
|
<p class="my-2 text-start">
|
||||||
|
{{ t("Suggestions:") }}
|
||||||
|
</p>
|
||||||
|
<ul class="list-disc list-inside text-start">
|
||||||
|
<li>
|
||||||
|
{{ t("Make sure that all words are spelled correctly.") }}
|
||||||
|
</li>
|
||||||
|
<li>{{ t("Try different keywords.") }}</li>
|
||||||
|
<li>{{ t("Try more general keywords.") }}</li>
|
||||||
|
<li>{{ t("Try fewer keywords.") }}</li>
|
||||||
|
<li>{{ t("Change the filters.") }}</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
</EmptyContent>
|
||||||
<o-pagination
|
<o-pagination
|
||||||
v-if="
|
v-if="
|
||||||
(searchEvents && searchEvents?.total > EVENT_PAGE_LIMIT) ||
|
(searchEvents && searchEvents?.total > EVENT_PAGE_LIMIT) ||
|
||||||
|
@ -556,6 +582,9 @@
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="contentType === ContentType.EVENTS">
|
<template v-else-if="contentType === ContentType.EVENTS">
|
||||||
|
<template v-if="searchLoading">
|
||||||
|
<SkeletonEventResultList v-for="i in 8" :key="i" />
|
||||||
|
</template>
|
||||||
<template v-if="searchEvents && searchEvents.total > 0">
|
<template v-if="searchEvents && searchEvents.total > 0">
|
||||||
<event-card
|
<event-card
|
||||||
mode="row"
|
mode="row"
|
||||||
|
@ -580,24 +609,51 @@
|
||||||
>
|
>
|
||||||
</o-pagination>
|
</o-pagination>
|
||||||
</template>
|
</template>
|
||||||
<o-notification v-else-if="searchLoading === false" variant="info">
|
<EmptyContent v-else-if="searchLoading === false" icon="calendar">
|
||||||
<p>{{ t("No events found") }}</p>
|
<span v-if="searchIsUrl">
|
||||||
<p v-if="searchIsUrl && !currentUser?.id">
|
{{ t("No event found at this address") }}
|
||||||
|
</span>
|
||||||
|
<span v-else-if="!search">
|
||||||
|
{{ t("No events found") }}
|
||||||
|
</span>
|
||||||
|
<i18n-t keypath="No events found for {search}" tag="span" v-else>
|
||||||
|
<template #search>
|
||||||
|
<b>{{ search }}</b>
|
||||||
|
</template>
|
||||||
|
</i18n-t>
|
||||||
|
<template #desc v-if="searchIsUrl && !currentUser?.id">
|
||||||
{{
|
{{
|
||||||
t(
|
t(
|
||||||
"Only registered users may fetch remote events from their URL."
|
"Only registered users may fetch remote events from their URL."
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
</p>
|
</template>
|
||||||
</o-notification>
|
<template #desc v-else>
|
||||||
|
<p class="my-2 text-start">
|
||||||
|
{{ t("Suggestions:") }}
|
||||||
|
</p>
|
||||||
|
<ul class="list-disc list-inside text-start">
|
||||||
|
<li>
|
||||||
|
{{ t("Make sure that all words are spelled correctly.") }}
|
||||||
|
</li>
|
||||||
|
<li>{{ t("Try different keywords.") }}</li>
|
||||||
|
<li>{{ t("Try more general keywords.") }}</li>
|
||||||
|
<li>{{ t("Try fewer keywords.") }}</li>
|
||||||
|
<li>{{ t("Change the filters.") }}</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
</EmptyContent>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="contentType === ContentType.GROUPS">
|
<template v-else-if="contentType === ContentType.GROUPS">
|
||||||
<o-notification v-if="features && !features.groups" variant="danger">
|
<o-notification v-if="features && !features.groups" variant="danger">
|
||||||
{{ t("Groups are not enabled on this instance.") }}
|
{{ t("Groups are not enabled on this instance.") }}
|
||||||
</o-notification>
|
</o-notification>
|
||||||
|
<template v-else-if="searchLoading">
|
||||||
|
<SkeletonGroupResultList v-for="i in 6" :key="i" />
|
||||||
|
</template>
|
||||||
<template v-else-if="searchGroups && searchGroups?.total > 0">
|
<template v-else-if="searchGroups && searchGroups?.total > 0">
|
||||||
<GroupCard
|
<GroupCard
|
||||||
|
class="my-2"
|
||||||
v-for="group in searchGroups?.elements"
|
v-for="group in searchGroups?.elements"
|
||||||
:group="group"
|
:group="group"
|
||||||
:key="group.id"
|
:key="group.id"
|
||||||
|
@ -617,9 +673,33 @@
|
||||||
>
|
>
|
||||||
</o-pagination>
|
</o-pagination>
|
||||||
</template>
|
</template>
|
||||||
<o-notification v-else-if="searchLoading === false" variant="danger">
|
<EmptyContent
|
||||||
{{ t("No groups found") }}
|
v-else-if="searchLoading === false"
|
||||||
</o-notification>
|
icon="account-multiple"
|
||||||
|
>
|
||||||
|
<span v-if="!search">
|
||||||
|
{{ t("No events found") }}
|
||||||
|
</span>
|
||||||
|
<i18n-t keypath="No groups found for {search}" tag="span" v-else>
|
||||||
|
<template #search>
|
||||||
|
<b>{{ search }}</b>
|
||||||
|
</template>
|
||||||
|
</i18n-t>
|
||||||
|
<template #desc>
|
||||||
|
<p class="my-2 text-start">
|
||||||
|
{{ t("Suggestions:") }}
|
||||||
|
</p>
|
||||||
|
<ul class="list-disc list-inside text-start">
|
||||||
|
<li>
|
||||||
|
{{ t("Make sure that all words are spelled correctly.") }}
|
||||||
|
</li>
|
||||||
|
<li>{{ t("Try different keywords.") }}</li>
|
||||||
|
<li>{{ t("Try more general keywords.") }}</li>
|
||||||
|
<li>{{ t("Try fewer keywords.") }}</li>
|
||||||
|
<li>{{ t("Change the filters.") }}</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
</EmptyContent>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<event-marker-map
|
<event-marker-map
|
||||||
|
@ -693,6 +773,9 @@ import { IConfig } from "@/types/config.model";
|
||||||
import { TypeNamed } from "@/types/apollo";
|
import { TypeNamed } from "@/types/apollo";
|
||||||
import { LatLngBounds } from "leaflet";
|
import { LatLngBounds } from "leaflet";
|
||||||
import lodashSortBy from "lodash/sortBy";
|
import lodashSortBy from "lodash/sortBy";
|
||||||
|
import EmptyContent from "@/components/Utils/EmptyContent.vue";
|
||||||
|
import SkeletonGroupResultList from "@/components/Group/SkeletonGroupResultList.vue";
|
||||||
|
import SkeletonEventResultList from "@/components/Event/SkeletonEventResultList.vue";
|
||||||
|
|
||||||
const EventMarkerMap = defineAsyncComponent(
|
const EventMarkerMap = defineAsyncComponent(
|
||||||
() => import("@/components/Search/EventMarkerMap.vue")
|
() => import("@/components/Search/EventMarkerMap.vue")
|
||||||
|
@ -764,6 +847,10 @@ const arrayTransformer: RouteQueryTransformer<string[]> = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
tag?: string;
|
||||||
|
}>();
|
||||||
|
|
||||||
const page = useRouteQuery("page", 1, integerTransformer);
|
const page = useRouteQuery("page", 1, integerTransformer);
|
||||||
const eventPage = useRouteQuery("eventPage", 1, integerTransformer);
|
const eventPage = useRouteQuery("eventPage", 1, integerTransformer);
|
||||||
const groupPage = useRouteQuery("groupPage", 1, integerTransformer);
|
const groupPage = useRouteQuery("groupPage", 1, integerTransformer);
|
||||||
|
@ -775,7 +862,7 @@ const distance = useRouteQuery("distance", "10_km");
|
||||||
const when = useRouteQuery("when", "any");
|
const when = useRouteQuery("when", "any");
|
||||||
const contentType = useRouteQuery(
|
const contentType = useRouteQuery(
|
||||||
"contentType",
|
"contentType",
|
||||||
ContentType.ALL,
|
props.tag ? ContentType.EVENTS : ContentType.ALL,
|
||||||
enumTransformer(ContentType)
|
enumTransformer(ContentType)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -819,10 +906,6 @@ const EVENT_PAGE_LIMIT = 16;
|
||||||
|
|
||||||
const GROUP_PAGE_LIMIT = 16;
|
const GROUP_PAGE_LIMIT = 16;
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
tag?: string;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const { features } = useFeatures();
|
const { features } = useFeatures();
|
||||||
const { eventCategories } = useEventCategories();
|
const { eventCategories } = useEventCategories();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue