173 lines
3.9 KiB
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>
|