feat: search page functionality
This commit is contained in:
@@ -215,7 +215,7 @@ const shortcutForEnter = () => {
|
||||
const navigateTo = (route: string) => {
|
||||
show.value = false
|
||||
query.value = ''
|
||||
router.push({ name: route.name, params: route.params, query: route.query })
|
||||
router.replace({ name: route.name, params: route.params, query: route.query })
|
||||
}
|
||||
|
||||
const jumpToOptions = ref([
|
||||
|
||||
@@ -240,7 +240,14 @@ const showPageModal = ref(false)
|
||||
const isModerator = ref(false)
|
||||
const isInstructor = ref(false)
|
||||
const pageToEdit = ref(null)
|
||||
const { settings, sidebarSettings, activeTab, isSettingsOpen } = useSettings()
|
||||
const {
|
||||
settings,
|
||||
sidebarSettings,
|
||||
activeTab,
|
||||
isSettingsOpen,
|
||||
isCommandPaletteOpen,
|
||||
} = useSettings()
|
||||
const settingsStore = useSettings()
|
||||
const showOnboarding = ref(false)
|
||||
const showIntermediateModal = ref(false)
|
||||
const currentStep = ref({})
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
>
|
||||
<Breadcrumbs :items="[{ label: __('Search') }]" />
|
||||
</header>
|
||||
<div class="w-3/4 mx-auto py-5">
|
||||
<div class="w-4/6 mx-auto py-5">
|
||||
<div class="px-2.5">
|
||||
<TextInput
|
||||
ref="searchInput"
|
||||
@@ -13,7 +13,6 @@
|
||||
autocomplete="off"
|
||||
:model-value="query"
|
||||
@update:model-value="updateQuery"
|
||||
@keydown="newSearch = true"
|
||||
@keydown.enter="() => submit()"
|
||||
>
|
||||
<template #prefix>
|
||||
@@ -31,44 +30,63 @@
|
||||
</div>
|
||||
</template>
|
||||
</TextInput>
|
||||
<div v-if="query" class="text-sm text-ink-gray-5 mt-2">
|
||||
<div
|
||||
v-if="query && searchResults.length"
|
||||
class="text-sm text-ink-gray-5 mt-2"
|
||||
>
|
||||
{{ searchResults.length }}
|
||||
{{ searchResults.length === 1 ? __('match') : __('matches') }}
|
||||
</div>
|
||||
<div v-else-if="queryChanged" class="text-sm text-ink-gray-5 mt-2">
|
||||
{{ __('Press enter to search') }}
|
||||
</div>
|
||||
<div
|
||||
v-else-if="query && !searchResults.length"
|
||||
class="text-sm text-ink-gray-5 mt-2"
|
||||
>
|
||||
{{ __('No results found') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-5">
|
||||
<div v-if="searchResults.length" class="divide-y">
|
||||
<div v-if="searchResults.length" class="">
|
||||
<div
|
||||
v-for="result in searchResults"
|
||||
v-for="(result, index) in searchResults"
|
||||
@click="navigate(result)"
|
||||
class="flex space-x-2 hover:bg-surface-gray-2 rounded-md cursor-pointer px-2.5 py-3"
|
||||
class="rounded-md cursor-pointer hover:bg-surface-gray-2 px-2"
|
||||
>
|
||||
<Tooltip :text="result.author_info.full_name">
|
||||
<Avatar
|
||||
:label="result.author_info.full_name"
|
||||
:image="result.author_info.user_image"
|
||||
size="md"
|
||||
/>
|
||||
</Tooltip>
|
||||
<div class="space-y-1 w-full">
|
||||
<div class="flex items-center">
|
||||
<div class="font-medium" v-html="result.title"></div>
|
||||
<div class="text-sm text-ink-gray-5 ml-2">
|
||||
{{ result.doctype == 'LMS Course' ? 'Course' : 'Batch' }}
|
||||
</div>
|
||||
<div
|
||||
v-if="result.published_on || result.start_date"
|
||||
class="ml-auto text-sm text-ink-gray-5"
|
||||
>
|
||||
{{
|
||||
dayjs(result.published_on || result.start_date).format(
|
||||
'DD MMM YYYY'
|
||||
)
|
||||
}}
|
||||
<div
|
||||
class="flex space-x-2 py-3"
|
||||
:class="{
|
||||
'border-b': index !== searchResults.length - 1,
|
||||
}"
|
||||
>
|
||||
<Tooltip :text="result.instructors_info.full_name">
|
||||
<Avatar
|
||||
:label="result.instructors_info.full_name"
|
||||
:image="result.instructors_info.user_image"
|
||||
size="md"
|
||||
/>
|
||||
</Tooltip>
|
||||
<div class="space-y-1 w-full">
|
||||
<div class="flex items-center">
|
||||
<div class="font-medium" v-html="result.title"></div>
|
||||
<div class="text-sm text-ink-gray-5 ml-2">
|
||||
{{ result.doctype == 'LMS Course' ? 'Course' : 'Batch' }}
|
||||
</div>
|
||||
<div
|
||||
v-if="result.published_on || result.start_date"
|
||||
class="ml-auto text-sm text-ink-gray-5"
|
||||
>
|
||||
{{
|
||||
dayjs(result.published_on || result.start_date).format(
|
||||
'DD MMM YYYY'
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="leading-5" v-html="result.content"></div>
|
||||
</div>
|
||||
<div class="leading-5" v-html="result.content"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -85,23 +103,23 @@ import {
|
||||
Tooltip,
|
||||
usePageMeta,
|
||||
} from 'frappe-ui'
|
||||
import { inject, onMounted, ref } from 'vue'
|
||||
import { inject, onMounted, ref, watch } from 'vue'
|
||||
import { Search, X } from 'lucide-vue-next'
|
||||
import { sessionStore } from '@/stores/session'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
|
||||
const query = ref('')
|
||||
const searchInput = ref<HTMLInputElement | null>(null)
|
||||
const newSearch = ref(false)
|
||||
const searchResults = ref<Array<any>>([])
|
||||
const { brand } = sessionStore()
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const queryChanged = ref(false)
|
||||
const dayjs = inject<any>('$dayjs')
|
||||
|
||||
onMounted(() => {
|
||||
if (router.currentRoute.value.query.q) {
|
||||
query.value = router.currentRoute.value.query.q as string
|
||||
searchInput.value.el.focus()
|
||||
submit()
|
||||
}
|
||||
})
|
||||
@@ -130,12 +148,12 @@ const search = createResource({
|
||||
const generateSearchResults = () => {
|
||||
searchResults.value = []
|
||||
if (search.data) {
|
||||
queryChanged.value = false
|
||||
search.data.forEach((group: any) => {
|
||||
group.items.forEach((item: any) => {
|
||||
searchResults.value.push(item)
|
||||
})
|
||||
})
|
||||
// sort Search results by item.score descending
|
||||
searchResults.value.sort((a, b) => b.score - a.score)
|
||||
}
|
||||
}
|
||||
@@ -158,9 +176,28 @@ const navigate = (result: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
watch(query, () => {
|
||||
if (query.value && query.value != search.params?.query) {
|
||||
queryChanged.value = true
|
||||
} else if (!query.value) {
|
||||
queryChanged.value = false
|
||||
searchResults.value = []
|
||||
}
|
||||
})
|
||||
|
||||
watch(
|
||||
() => route.query.q,
|
||||
(newQ) => {
|
||||
if (newQ && newQ !== query.value) {
|
||||
query.value = newQ as string
|
||||
submit()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const clearSearch = () => {
|
||||
query.value = ''
|
||||
searchInput.value?.focus()
|
||||
updateQuery('')
|
||||
}
|
||||
|
||||
usePageMeta(() => {
|
||||
|
||||
Reference in New Issue
Block a user