0
0
Fork 0

Added searchbar panel

This commit is contained in:
Joan Sanchez 2023-01-17 14:57:12 +01:00
parent a89856c5e0
commit b583d8b12e
5 changed files with 221 additions and 90 deletions

View File

@ -38,7 +38,9 @@ function onToggleDrawer() {
</q-tooltip> </q-tooltip>
</q-btn> </q-btn>
</router-link> </router-link>
<q-toolbar-title shrink class="text-weight-bold">{{ appName }}</q-toolbar-title> <q-toolbar-title shrink class="text-weight-bold" v-if="$q.screen.gt.xs">
{{ appName }}
</q-toolbar-title>
<q-space></q-space> <q-space></q-space>
<div id="searchbar"></div> <div id="searchbar"></div>
<q-space></q-space> <q-space></q-space>

View File

@ -49,8 +49,13 @@ export function useArrayData(key, userOptions) {
store.filter = filter; store.filter = filter;
const requestOptions = { params: { filter: filter } }; const params = {
const response = await axios.get(store.url, requestOptions); filter: filter,
};
Object.assign(params, store.userParams);
const response = await axios.get(store.url, { params });
const { limit } = filter; const { limit } = filter;

View File

@ -25,7 +25,7 @@ function viewSummary(id) {
<template> <template>
<q-page class="q-pa-md"> <q-page class="q-pa-md">
<paginate url="/Clients" order="id DESC" auto-load> <paginate url="/Clients/filter" order="id DESC" auto-load>
<template #body="{ rows }"> <template #body="{ rows }">
<q-card class="card" v-for="row of rows" :key="row.id"> <q-card class="card" v-for="row of rows" :key="row.id">
<q-item class="q-pa-none items-start cursor-pointer q-hoverable" v-ripple clickable> <q-item class="q-pa-none items-start cursor-pointer q-hoverable" v-ripple clickable>

View File

@ -1,114 +1,234 @@
<script setup> <script setup>
import { ref } from 'vue'; import { ref, reactive, computed } from 'vue';
import { useSession } from 'src/composables/useSession';
import { useState } from 'composables/useState'; import { useState } from 'composables/useState';
import { useArrayData } from 'composables/useArrayData'; import { useArrayData } from 'composables/useArrayData';
import LeftMenu from 'components/LeftMenu.vue'; import LeftMenu from 'components/LeftMenu.vue';
import FetchData from 'components/FetchData.vue';
import TeleportSlot from 'components/ui/TeleportSlot.vue'; import TeleportSlot from 'components/ui/TeleportSlot.vue';
const state = useState(); const state = useState();
const arrayData = useArrayData('customers'); const arrayData = useArrayData('customers');
const session = useSession();
const token = session.getToken();
const searchBackdrop = ref(false);
const provinces = ref([]);
const workers = ref([]);
const workersCopy = ref([]);
const zones = ref([]);
const searchPanel = ref();
const userParams = reactive({});
const tags = computed(() => {
const params = [];
for (const param in userParams) {
params.push({
label: param,
value: userParams[param],
});
}
return params;
});
const search = ref('');
async function doSearch() { async function doSearch() {
let filter = {}; // let filter = {};
if (search.value != '') { // if (search.value != '') {
filter = { // filter = {
where: { // where: {
id: search.value, // id: search.value,
}, // },
}; // };
} // }
await arrayData.apply({ filter }); const params = userParams;
await arrayData.apply({ filter: {}, params });
searchPanel.value.hide();
} }
const searchRows = ref([]) // const searchRows = ref([])
async function pre(value) { // async function pre(value) {
let filter = {}; // let filter = {};
if (value != '') { // if (value != '') {
filter = { // filter = {
where: { // where: {
id: value, // id: value,
}, // },
}; // };
} // }
console.log(filter) // console.log(filter)
const rows = await arrayData.request({ userFilter: filter }); // const rows = await arrayData.request({ userFilter: filter });
searchRows.value = rows // searchRows.value = rows
// }
function setWorkers(data) {
workers.value = data;
workersCopy.value = data;
} }
</script> </script>
<template> <template>
<fetch-data url="Provinces" @on-fetch="(data) => (provinces = data)" auto-load />
<fetch-data url="Zones" @on-fetch="(data) => (zones = data)" auto-load />
<fetch-data
url="Workers/activeWithInheritedRole"
:filter="{ where: { role: 'salesPerson' } }"
@on-fetch="setWorkers"
auto-load
/>
<teleport-slot to="#searchbar"> <teleport-slot to="#searchbar">
<q-form @submit="doSearch"> <q-form @submit="doSearch">
<q-input id="searchbar" v-model="search" label="Search" @update:model-value="pre" dark dense standout> <q-input id="searchbar" v-model="userParams.search" label="Search" dark dense standout autofocus>
<template #prepend> <template #prepend>
<q-icon name="search" /> <q-icon name="search" />
</template> </template>
<template #append> <template #append>
<q-btn icon="filter_alt" flat dense /> <q-btn @click="searchBackdrop = !searchBackdrop" icon="filter_alt" flat dense>
<q-tooltip>Apply search filters</q-tooltip>
<div class="q-dialog__backdrop fixed-full" v-if="searchBackdrop"></div>
<q-popup-proxy
ref="searchPanel"
v-model="searchBackdrop"
target="#searchbar"
no-parent-event
fit
>
<q-card class="q-pa-md">
<q-form @submit="doSearch" class="q-gutter-y-md">
<div class="row truncate-chip-labels">
<q-chip
v-for="chip of tags"
:key="chip.label"
@remove="log('Icecream')"
icon="label"
color="primary"
size="sm"
removable
>
<strong>{{ chip.label }}: </strong>
<span>"{{ chip.value }}"</span>
</q-chip>
</div>
<div class="row q-gutter-x-md">
<div class="col">
<q-input
v-model="userParams.search"
label="Search"
hint="Search by id or name"
lazy-rules
autofocus
/>
</div>
</div>
<div class="row q-gutter-x-md">
<div class="col">
<q-input label="Name" v-model="userParams.name" lazy-rules />
</div>
<div class="col">
<q-input label="Fiscal ID" v-model="userParams.fi" lazy-rules />
</div>
<div class="col">
<q-input label="Phone" v-model="userParams.phone" lazy-rules />
</div>
</div>
<div class="row q-gutter-x-md">
<div class="col">
<q-input label="Phone" v-model="userParams.phone" lazy-rules />
</div>
<div class="col">
<q-input label="Email" v-model="userParams.email" lazy-rules />
</div>
</div>
<div class="row q-gutter-x-md">
<div class="col">
<q-select
label="Province"
v-model="userParams.provinceFk"
:options="provinces"
option-value="id"
option-label="name"
emit-value
map-options
/>
</div>
<div class="col">
<q-input label="City" v-model="userParams.city" lazy-rules />
</div>
</div>
<div class="row q-gutter-x-md">
<div class="col">
<q-select
label="Zone"
v-model="userParams.zoneFk"
:options="zones"
option-value="id"
option-label="name"
emit-value
map-options
/>
</div>
<div class="col">
<q-input label="Postcode" v-model="userParams.postcode" lazy-rules />
</div>
</div>
<div class="row q-gutter-x-md">
<div class="col">
<q-select
v-model="userParams.salesPersonFk"
:options="workers"
option-value="id"
option-label="name"
emit-value
label="Salesperson"
map-options
use-input
:input-debounce="0"
>
<template #before>
<q-avatar color="orange">
<q-img
v-if="userParams.salesPersonFk"
:src="`/api/Images/user/160x160/${userParams.salesPersonFk}/download?access_token=${token}`"
spinner-color="white"
/>
</q-avatar>
</template> </template>
<q-popup-proxy v-if="searchRows.length === 1"> </q-select>
<q-list> </div>
<q-item v-for="row of searchRows" :key="row.id" v-ripple clickable> </div>
<q-item-section avatar>
<q-img src="http://localhost:9000/api/Images/user/160x160/9/download?access_token=qBo7qT6T24FasiG74QTfFZfXstxTVLZdmvHz7uqvhxpAG1G0dIF6RRGVeoS3NGiA" /> <!-- <q-input
</q-item-section> label="Phone"
<q-item-section> hint="The customer phone"
<q-item-label>{{ row.name }}</q-item-label> lazy-rules
</q-item-section> :rules="[(val) => (val && val.length > 0) || 'Please type something']"
</q-item> /> -->
</q-list>
<div>
<q-btn
label="Search"
type="submit"
color="primary"
class="full-width"
rounded
/>
</div>
</q-form>
</q-card>
</q-popup-proxy> </q-popup-proxy>
</q-btn>
</template>
</q-input> </q-input>
</q-form> </q-form>
</teleport-slot> </teleport-slot>
<!-- <teleport-slot to="#searchbar">
<q-select
ref="search"
dark
dense
standout
use-input
hide-selected
color="black"
:stack-label="false"
label="Search or jump to..."
v-model="search"
@input-value="doSearch"
style="width: 400px"
>
<template #append>
<img src="https://cdn.quasar.dev/img/layout-gallery/img-github-search-key-slash.svg" />
</template>
<template #no-option>
<q-item>
<q-item-section>
<div class="text-center">
<q-spinner-pie color="grey-5" size="24px" />
</div>
</q-item-section>
</q-item>
</template>
<template #option="scope">
<q-item v-bind="scope.itemProps" class="GL__select-GL__menu-link">
<q-item-section side>
<q-icon name="collections_bookmark" />
</q-item-section>
<q-item-section>
<q-item-label>{{ scope.opt.label }}</q-item-label>
</q-item-section>
<q-item-section side :class="{ 'default-type': !scope.opt.type }">
<q-btn outline dense no-caps text-color="blue-grey-5" size="12px" class="bg-grey-1 q-px-sm">
{{ scope.opt.type || 'Jump to' }}
<q-icon name="subdirectory_arrow_left" size="14px" />
</q-btn>
</q-item-section>
</q-item>
</template>
</q-select>
</teleport-slot> -->
<q-drawer v-model="state.drawer.value" show-if-above :width="256" :breakpoint="500"> <q-drawer v-model="state.drawer.value" show-if-above :width="256" :breakpoint="500">
<q-scroll-area class="fit text-grey-8"> <q-scroll-area class="fit text-grey-8">
<LeftMenu /> <LeftMenu />
@ -120,7 +240,8 @@ async function pre(value) {
</template> </template>
<style lang="scss"> <style lang="scss">
#searchbar { #searchbar,
.search-panel {
width: 400px; width: 400px;
} }
</style> </style>

View File

@ -0,0 +1,3 @@
<template>
test
</template>