fix: search component & data

This commit is contained in:
puri-ph4tt 2023-11-28 16:57:14 +07:00 committed by Methapon2001
parent 6e77d30236
commit 231b203a23
No known key found for this signature in database
GPG key ID: 849924FEF46BD132
2 changed files with 228 additions and 282 deletions

View file

@ -1,7 +1,11 @@
divdivdivdivdivdiv
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
import { storeToRefs } from 'pinia'
const isAdvncSearchClick = ref<boolean>(false) import { useSearchDataStore } from '@/stores/searched-data'
const { isAdvSearchCall } = storeToRefs(useSearchDataStore())
const optionsField = [ const optionsField = [
{ label: 'ชื่อเรื่อง (title)', value: 'title' }, { label: 'ชื่อเรื่อง (title)', value: 'title' },
{ label: 'คำสำคัญ (keyword)', value: 'keyword' }, { label: 'คำสำคัญ (keyword)', value: 'keyword' },
@ -10,23 +14,32 @@ const optionsOp = [
{ label: 'และ', value: 'AND' }, { label: 'และ', value: 'AND' },
{ label: 'หรือ', value: 'OR' }, { label: 'หรือ', value: 'OR' },
] ]
const advSearchData = ref< const advSearchDataRow = ref<
{ {
op: 'AND' | 'OR' op: 'AND' | 'OR'
field: 'title' | 'keyword' field: 'title' | 'keyword'
value: string value: string
}[] }[]
>([]) >([
{
op: 'AND',
field: 'title',
value: '',
},
])
const advSearchDataField = ref<{
keyword: string
description: string
}>({
keyword: '',
description: '',
})
const props = defineProps<{ const props = defineProps<{
field: string
value: string
keyword?: string
description?: string
searchSubmit: Function searchSubmit: Function
submitSearchData: { submitSearchData: {
AND: { AND: {
field?: string field: string
value?: string value: string
}[] }[]
OR: { OR: {
field: string field: string
@ -36,185 +49,164 @@ const props = defineProps<{
}>() }>()
defineExpose({ defineExpose({
clearAdvData, advSearchDataRow,
advSearchData, advSearchDataField,
}) })
defineEmits([ function addAdvSearchData() {
'update:field', advSearchDataRow.value.push({
'update:value',
'update:keyword',
'update:description',
])
function addSearchData() {
advSearchData.value.push({
op: 'AND', op: 'AND',
field: 'title', field: 'title',
value: '', value: '',
}) })
} }
function delAdvSearchData(index: number) {
function clearAdvData() { advSearchDataRow.value.length > 1 && advSearchDataRow.value.splice(index, 1)
advSearchData.value = [] }
function clearAdvSearchData() {
isAdvSearchCall.value = false
advSearchDataRow.value = [
{
op: 'AND',
field: 'title',
value: '',
},
]
advSearchDataField.value = {
keyword: '',
description: '',
}
} }
</script> </script>
<template> <template>
<div> <div>
<q-btn <q-btn
outline flat
color="primary" color="primary"
icon="mdi-tools" icon="mdi-tools"
label="ค้นหาขั้นสูง" label="ค้นหาขั้นสูง"
@click="() => (isAdvncSearchClick = true)" class="q-mt-sm"
style="width: 148px"
v-if="isAdvSearchCall === false"
@click="() => (isAdvSearchCall = true)"
/> />
</div> </div>
<q-dialog v-model="isAdvncSearchClick"> <div v-if="isAdvSearchCall === true">
<q-card style="width: 1000px; max-width: 80vw"> <div class="column bg-white q-pa-sm">
<q-toolbar class="bg-grey-1 q-py-sm q-px-lg"> <div class="row items-center justify-between q-pb-md">
<q-toolbar-title> <span class="text-primary text-weight-medium q-pl-md q-pt-xs"
<span class="text-weight-bold">นหาขนส</span> ><q-icon name="mdi-tools" class="q-pr-sm" size="sm" />
</q-toolbar-title> นหาขนส</span
<q-btn flat round dense icon="close" v-close-popup color="red" /> >
</q-toolbar> <q-btn
<q-separator /> flat
dense
color="red"
icon="close"
@click="clearAdvSearchData"
/>
</div>
<div class="col"> <div class="column q-px-lg">
<q-card-section class="row q-mt-sm"> <div
<div class="col"> class="row items-center q-pb-xs q-col-gutter-md"
<div class="row q-col-gutter-md q-mb-md items-center"> v-for="(item, index) in advSearchDataRow"
<div class="col-12 col-md-3"> :key="index"
<q-select >
dense <div class="row items-center" style="width: 45px; height: 45px">
outlined
emit-value
map-options
:options="optionsField"
:model-value="props.field"
@update:model-value="(value) => $emit('update:field', value)"
/>
</div>
<div class="col-12 col-md-8">
<q-input
dense
outlined
placeholder="เอกสาร"
:model-value="props.value"
@update:model-value="(value) => $emit('update:value', value)"
/>
</div>
<div class="col-1">
<q-btn
dense
color="teal"
icon="mdi-plus"
v-if="advSearchData.length === 0"
@click="addSearchData"
/>
</div>
</div>
<div
class="row q-col-gutter-md q-mb-md items-center"
v-for="(_, index) in advSearchData"
>
<div class="col-4 col-md-2">
<q-select
dense
outlined
emit-value
map-options
v-model="advSearchData[index].op"
:options="optionsOp"
/>
</div>
<div class="col-8 col-md-3">
<q-select
dense
outlined
emit-value
map-options
v-model="advSearchData[index].field"
:options="optionsField"
/>
</div>
<div class="col-12 col-md-6">
<q-input
dense
outlined
v-model="advSearchData[index].value"
placeholder="เอกสาร"
/>
</div>
<div class="col-1">
<q-btn
dense
color="teal"
icon="mdi-plus"
v-if="index === advSearchData.length - 1"
@click="addSearchData"
/>
<q-btn
dense
flat
icon="mdi-minus"
color="red"
v-if="index === advSearchData.length - 1"
@click="() => advSearchData.pop()"
/>
</div>
</div>
</div>
</q-card-section>
<q-card-section class="row q-mb-md">
<div class="col">
<span> </span>
<q-separator class="q-mb-lg" />
<div class="row q-col-gutter-md">
<div class="col-12 col-md-3 q-gutter-y-sm">
<span class="text-weight-bold">คำสำค</span>
<q-input
dense
outlined
placeholder="กรอกคำสำคัญ"
:model-value="props.keyword"
@update:model-value="
(value) => $emit('update:keyword', value)
"
/>
</div>
<div class="col-12 col-md-4 q-gutter-y-sm">
<span class="text-weight-bold">รายละเอยดของเอกสาร</span>
<q-input
dense
outlined
placeholder="กรอกรายละเอียด"
:model-value="props.description"
@update:model-value="
(value) => $emit('update:description', value)
"
/>
</div>
</div>
</div>
</q-card-section>
<q-separator />
<q-toolbar class="row justify-end">
<div class="q-py-md">
<q-btn <q-btn
color="primary" dense
label="ค้นหา" color="teal"
icon="mdi-magnify" icon="mdi-plus"
v-close-popup v-if="index === advSearchDataRow.length - 1"
@click="() => props.searchSubmit()" @click="addAdvSearchData"
/> />
</div> </div>
</q-toolbar> <div class="col-4 col-md-2">
<q-select
dense
outlined
emit-value
map-options
v-model="item.op"
:options="optionsOp"
/>
</div>
<div class="col-grow col-md-3">
<q-select
dense
outlined
emit-value
map-options
v-model="item.field"
:options="optionsField"
/>
</div>
<div class="col-grow">
<q-input dense outlined v-model="item.value" placeholder="เอกสาร"
><template v-slot:append>
<q-icon
name="close"
@click="() => (item.value = '')"
class="cursor-pointer"
/>
</template>
</q-input>
</div>
<div>
<q-btn
dense
flat
icon="mdi-trash-can-outline"
color="red"
@click="() => delAdvSearchData(index)"
>
<q-tooltip
class="bg-red"
anchor="top middle"
self="bottom middle"
:offset="[10, 10]"
v-if="advSearchDataRow.length === 1"
>
<strong>ไมสามารถลบได</strong>
</q-tooltip>
</q-btn>
</div>
</div>
<q-separator class="q-mb-md q-mt-sm" />
<div class="row q-col-gutter-md q-pb-md">
<div class="col-12 col-md-5">
<q-input
dense
outlined
placeholder="คำสำคัญ:"
v-model="advSearchDataField.keyword"
/>
</div>
<div class="col-12 col-md-grow">
<q-input
dense
outlined
placeholder="รายละเอียด:"
v-model="advSearchDataField.description"
/>
</div>
</div>
</div> </div>
</q-card> </div>
</q-dialog> <div class="row justify-end">
<q-btn
class="q-mt-md"
style="width: 150px"
color="primary"
label="ค้นหา"
icon="mdi-magnify"
@click="() => props.searchSubmit()"
/>
</div>
</div>
</template> </template>

View file

@ -5,9 +5,9 @@ import { storeToRefs } from 'pinia'
import type { EhrFile } from '@/stores/tree-data' import type { EhrFile } from '@/stores/tree-data'
import AdvancedSearch from '@/modules/01_user/components/AdvancedSearch.vue'
import { useSearchDataStore } from '@/stores/searched-data' import { useSearchDataStore } from '@/stores/searched-data'
import { useLoader } from '@/stores/loader' import { useLoader } from '@/stores/loader'
import AdvancedSearch from '@/modules/01_user/components/AdvancedSearch.vue'
const loaderStore = useLoader() const loaderStore = useLoader()
const { isSearch, isAdvSearchCall } = storeToRefs(useSearchDataStore()) const { isSearch, isAdvSearchCall } = storeToRefs(useSearchDataStore())
@ -20,106 +20,71 @@ const optionsField = [
const searchData = ref<{ const searchData = ref<{
field: string field: string
value: string value: string
keyword?: string
description?: string
}>({ }>({
field: 'title', field: 'title',
value: '', value: '',
keyword: '',
description: '',
}) })
const submitSearchData = ref<{ const submitSearchData = ref<{
AND: { AND: { field: string; value: string }[]
field?: string
value?: string
}[]
OR: { field: string; value: string }[] OR: { field: string; value: string }[]
}>({ }>({
AND: [], AND: [],
OR: [], OR: [],
}) })
function clearSearchData() {
searchData.value = {
field: 'title',
value: '',
keyword: '',
description: '',
}
submitSearchData.value = {
AND: [],
OR: [],
}
advSearchComp.value?.clearAdvData()
isAdvSearchCall.value = false
isSearch.value = false
}
async function searchSubmit() { async function searchSubmit() {
submitSearchData.value = { if (searchData.value.value.trim() !== '') {
AND: [], submitSearchData.value = { AND: [], OR: [] }
OR: [],
} submitSearchData.value.AND.push({
if (searchData.value.field && searchData.value) {
submitSearchData.value?.AND.push({
field: searchData.value.field, field: searchData.value.field,
value: searchData.value.value, value: searchData.value.value,
}) })
if (searchData.value.keyword) {
submitSearchData.value?.AND.push({
field: 'keyword',
value: searchData.value.keyword,
})
}
if (searchData.value.description) {
submitSearchData.value?.AND.push({
field: 'description',
value: searchData.value.description,
})
}
}
if (isAdvSearchCall.value) { if (isAdvSearchCall.value && advSearchComp.value) {
if ( const advField = advSearchComp.value.advSearchDataField
advSearchComp.value?.advSearchData && const advRow = advSearchComp.value.advSearchDataRow
advSearchComp.value.advSearchData.length > 0
) { advRow.forEach((d: { field: string; value: string; op: string }) => {
advSearchComp.value?.advSearchData.forEach( if (d.field && d.value.trim() !== '') {
(d: { field: string; value: string; op: string }) => { const op = d.op === 'AND' ? 'AND' : 'OR'
if (d.field && d.value) { submitSearchData.value[op].push({ field: d.field, value: d.value })
if (d.op === 'AND') {
submitSearchData.value.AND.push({
field: d.field,
value: d.value,
})
} else if (d.op === 'OR') {
submitSearchData.value.OR.push({ field: d.field, value: d.value })
}
}
} }
) })
if (advField.keyword.trim() !== '') {
submitSearchData.value.AND.push({
field: 'keyword',
value: advField.keyword,
})
}
if (advField.description.trim() !== '') {
submitSearchData.value.AND.push({
field: 'description',
value: advField.description,
})
}
}
try {
loaderStore.show()
const res = await axios.post<EhrFile[]>(
`${import.meta.env.VITE_API_ENDPOINT}/search`,
submitSearchData.value
)
getFoundFile(res.data)
isSearch.value = true
} catch (error) {
console.error('Error during the request', error)
} finally {
loaderStore.hide()
} }
}
try {
loaderStore.show()
isAdvSearchCall.value = true
const res = await axios.post<EhrFile[]>(
`${import.meta.env.VITE_API_ENDPOINT}/search`,
submitSearchData.value
)
getFoundFile(res.data)
isSearch.value = true
} catch (error) {
console.error('Error during the request', error)
} finally {
loaderStore.hide()
} }
} }
</script> </script>
<template> <template>
<div class="q-py-lg q-px-md bg-grey-1"> <div class="q-pa-md bg-grey-1">
<div class="row items-center q-gutter-md"> <div class="row items-center q-col-gutter-md">
<div class="col-12 col-md-3"> <div class="col-12 col-md-3">
<q-select <q-select
dense dense
@ -139,47 +104,36 @@ async function searchSubmit() {
v-model="searchData.value" v-model="searchData.value"
placeholder="เอกสาร" placeholder="เอกสาร"
@keydown.enter.prevent="searchSubmit" @keydown.enter.prevent="searchSubmit"
/> >
</div> <template v-slot:append>
<div v-if="isAdvSearchCall === false"> <q-icon
<q-btn name="close"
class="col-12 col-md-2" @click="() => (searchData.value = '')"
color="primary" class="cursor-pointer"
label="ค้นหา" />
icon="mdi-magnify" </template>
@click="searchSubmit" </q-input>
/>
</div> </div>
</div> </div>
<div <div class="column">
v-if="isAdvSearchCall" <div class="row items-center justify-between q-gutter-y-md q-pt-sm">
class="row items-center justify-between q-gutter-y-md q-mt-xs" <div class="column col-grow">
> <advanced-search
<div> ref="advSearchComp"
<advanced-search :searchSubmit="searchSubmit"
ref="advSearchComp" :submit-search-data="submitSearchData"
:searchSubmit="searchSubmit" />
:submit-search-data="submitSearchData" </div>
v-model:field="searchData.field" <div v-if="isAdvSearchCall === false">
v-model:value="searchData.value" <q-btn
v-model:keyword="searchData.keyword" style="width: 150px"
v-model:description="searchData.description" color="primary"
/> label="ค้นหา"
</div> icon="mdi-magnify"
<div class="q-gutter-x-md"> @click="searchSubmit"
<q-btn />
color="primary" </div>
label="ค้นหา"
icon="mdi-magnify"
@click="searchSubmit"
/>
<q-btn
color="orange-12"
label="ล้างข้อมูล"
icon="close"
@click="clearSearchData"
/>
</div> </div>
</div> </div>
</div> </div>