salix-front/src/components/ui/VnSearchbar.vue

173 lines
3.9 KiB
Vue

<script setup>
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { useQuasar } from 'quasar';
import { useArrayData } from 'composables/useArrayData';
import VnInput from 'src/components/common/VnInput.vue';
const quasar = useQuasar();
const props = defineProps({
dataKey: {
type: String,
required: true,
},
label: {
type: String,
required: false,
default: 'Search',
},
info: {
type: String,
required: false,
default: '',
},
redirect: {
type: Boolean,
required: false,
default: true,
},
url: {
type: String,
default: '',
},
filter: {
type: Object,
default: null,
},
where: {
type: Object,
default: null,
},
order: {
type: String,
default: '',
},
limit: {
type: Number,
default: 10,
},
userParams: {
type: Object,
default: null,
},
staticParams: {
type: Array,
default: () => [],
},
exprBuilder: {
type: Function,
default: null,
},
customRouteRedirectName: {
type: String,
default: '',
},
});
const router = useRouter();
const arrayData = useArrayData(props.dataKey, { ...props });
const { store } = arrayData;
const searchText = ref('');
onMounted(() => {
const params = store.userParams;
if (params && params.search) {
searchText.value = params.search;
}
});
async function search() {
const staticParams = Object.entries(store.userParams).filter(
([key, value]) => value && (props.staticParams || []).includes(key)
);
await arrayData.applyFilter({
params: {
...Object.fromEntries(staticParams),
search: searchText.value,
},
});
if (!props.redirect) return;
if (props.customRouteRedirectName)
return router.push({
name: props.customRouteRedirectName,
params: { id: searchText.value },
});
const { matched: matches } = router.currentRoute.value;
const { path } = matches.at(-1);
const [, moduleName] = path.split('/');
if (!store.data.length || store.data.length > 1)
return router.push({ path: `/${moduleName}/list` });
const targetId = store.data[0].id;
let targetUrl;
if (path.endsWith('/list')) targetUrl = path.replace('/list', `/${targetId}/summary`);
else if (path.includes(':id')) targetUrl = path.replace(':id', targetId);
await router.push({ path: targetUrl });
}
</script>
<template>
<QForm @submit="search" id="searchbarForm">
<VnInput
id="searchbar"
v-model="searchText"
:placeholder="props.label"
dense
standout
autofocus
>
<template #prepend>
<QIcon
v-if="!quasar.platform.is.mobile"
class="cursor-pointer"
name="search"
@click="search"
/>
</template>
<template #append>
<QIcon
v-if="props.info && $q.screen.gt.xs"
name="info"
class="cursor-info"
>
<QTooltip>{{ props.info }}</QTooltip>
</QIcon>
</template>
</VnInput>
</QForm>
</template>
<style lang="scss" scoped>
@media screen and (min-width: $breakpoint-sm-max) {
.q-field {
width: 450px;
}
}
.q-field {
transition: width 0.36s;
}
</style>
<style lang="scss">
.cursor-info {
cursor: help;
}
#searchbar {
.q-field--standout.q-field--highlighted .q-field__control {
background-color: white;
color: black;
.q-field__native,
.q-icon {
color: black !important;
}
}
}
</style>