184 lines
4.1 KiB
Vue
184 lines
4.1 KiB
Vue
<script setup>
|
|
import { onMounted, ref, watch } from 'vue';
|
|
import { useQuasar } from 'quasar';
|
|
import { useArrayData } from 'composables/useArrayData';
|
|
import VnInput from 'src/components/common/VnInput.vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { useStateStore } from 'src/stores/useStateStore';
|
|
|
|
const quasar = useQuasar();
|
|
const { t } = useI18n();
|
|
const state = useStateStore();
|
|
|
|
const props = defineProps({
|
|
dataKey: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
label: {
|
|
type: String,
|
|
default: 'Search',
|
|
},
|
|
info: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
redirect: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
url: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
filter: {
|
|
type: Object,
|
|
default: null,
|
|
},
|
|
where: {
|
|
type: Object,
|
|
default: null,
|
|
},
|
|
order: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
limit: {
|
|
type: Number,
|
|
default: 20,
|
|
},
|
|
userParams: {
|
|
type: Object,
|
|
default: null,
|
|
},
|
|
staticParams: {
|
|
type: Array,
|
|
default: () => [],
|
|
},
|
|
exprBuilder: {
|
|
type: Function,
|
|
default: null,
|
|
},
|
|
customRouteRedirectName: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
whereFilter: {
|
|
type: Function,
|
|
default: undefined,
|
|
},
|
|
});
|
|
|
|
const searchText = ref();
|
|
let arrayDataProps = { ...props };
|
|
if (props.redirect)
|
|
arrayDataProps = {
|
|
...props,
|
|
...{
|
|
navigate: {
|
|
customRouteRedirectName: props.customRouteRedirectName,
|
|
searchText: searchText.value,
|
|
},
|
|
},
|
|
};
|
|
let arrayData = useArrayData(props.dataKey, arrayDataProps);
|
|
let store = arrayData.store;
|
|
|
|
watch(
|
|
() => props.dataKey,
|
|
(val) => {
|
|
arrayData = useArrayData(val, { ...props });
|
|
store = arrayData.store;
|
|
}
|
|
);
|
|
|
|
onMounted(() => {
|
|
const params = store.userParams;
|
|
if (params && params.search) {
|
|
searchText.value = params.search;
|
|
}
|
|
});
|
|
|
|
async function search() {
|
|
const staticParams = Object.entries(store.userParams);
|
|
arrayData.reset(['skip', 'page']);
|
|
|
|
const filter = {
|
|
params: {
|
|
...Object.fromEntries(staticParams),
|
|
search: searchText.value,
|
|
},
|
|
...{ filter: props.filter },
|
|
};
|
|
|
|
if (props.whereFilter) {
|
|
filter.filter = {
|
|
where: props.whereFilter(searchText.value),
|
|
};
|
|
delete filter.params.search;
|
|
}
|
|
await arrayData.applyFilter(filter);
|
|
}
|
|
</script>
|
|
<template>
|
|
<Teleport to="#searchbar" v-if="state.isHeaderMounted()">
|
|
<QForm @submit="search" id="searchbarForm">
|
|
<VnInput
|
|
id="searchbar"
|
|
v-model.trim="searchText"
|
|
:placeholder="t(props.label)"
|
|
dense
|
|
standout
|
|
autofocus
|
|
data-cy="vnSearchBar"
|
|
>
|
|
<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>{{ t(props.info) }}</QTooltip>
|
|
</QIcon>
|
|
</template>
|
|
</VnInput>
|
|
</QForm>
|
|
</Teleport>
|
|
</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>
|