[pricelist] add search

This commit is contained in:
Tim Gröger 2021-03-31 14:18:55 +02:00
parent 6cdc143aa9
commit fb14df0c43
4 changed files with 144 additions and 21 deletions

View File

@ -9,6 +9,8 @@
row-key="id" row-key="id"
virtual-scroll virtual-scroll
:rows-per-page-options="[0]" :rows-per-page-options="[0]"
:filter="search"
:filter-method="filter"
> >
<template #header="props"> <template #header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -20,6 +22,7 @@
</template> </template>
<template #top-right> <template #top-right>
<div class="row justify-end q-gutter-sm"> <div class="row justify-end q-gutter-sm">
<search-input v-model="search" :keys="[...columns, ...column_calc, ...column_prices]" />
<q-btn label="Aufpreise"> <q-btn label="Aufpreise">
<q-menu anchor="center middle" self="center middle"> <q-menu anchor="center middle" self="center middle">
<min-price-setting /> <min-price-setting />
@ -331,6 +334,8 @@ import { Drink, usePricelistStore } from 'src/plugins/pricelist/store';
import MinPriceSetting from 'src/plugins/pricelist/components/MinPriceSetting.vue'; import MinPriceSetting from 'src/plugins/pricelist/components/MinPriceSetting.vue';
import NewDrink from 'src/plugins/pricelist/components/CalculationTable/NewDrink.vue'; import NewDrink from 'src/plugins/pricelist/components/CalculationTable/NewDrink.vue';
import BuildManual from 'src/plugins/pricelist/components/CalculationTable/BuildManual.vue'; import BuildManual from 'src/plugins/pricelist/components/CalculationTable/BuildManual.vue';
import SearchInput from './SearchInput.vue';
import { filter } from '../utils/filter';
import { Notify } from 'quasar'; import { Notify } from 'quasar';
function sort(a: string | number, b: string | number) { function sort(a: string | number, b: string | number) {
@ -341,7 +346,7 @@ function sort(a: string | number, b: string | number) {
export default defineComponent({ export default defineComponent({
name: 'CalculationTable', name: 'CalculationTable',
components: { BuildManual, MinPriceSetting, DrinkPriceVolumesTable, NewDrink }, components: { SearchInput, BuildManual, MinPriceSetting, DrinkPriceVolumesTable, NewDrink },
setup() { setup() {
const mainStore = useMainStore(); const mainStore = useMainStore();
const store = usePricelistStore(); const store = usePricelistStore();
@ -523,6 +528,11 @@ export default defineComponent({
updateDrink(drink); updateDrink(drink);
} }
const search = ref({
value: '',
key: '',
label: '',
});
return { return {
drinks: computed(() => store.drinks), drinks: computed(() => store.drinks),
pagination, pagination,
@ -540,6 +550,8 @@ export default defineComponent({
addStep, addStep,
deleteStep, deleteStep,
console, console,
search,
filter,
}; };
}, },
}); });

View File

@ -1,13 +1,21 @@
<template> <template>
<div> <div>
<q-table <q-table
class="full-width"
title="Getränke" title="Getränke"
:columns="columns_drinks" :columns="columns_drinks"
:rows="drinks" :rows="drinks"
row-key="name" row-key="name"
:visible-columns="visibleColumn" :visible-columns="visibleColumn"
:filter="search"
:filter-method="filter"
> >
<template #top-right> <template #top-right>
<div class="row q-gutter-sm">
<search-input
v-model="search"
:keys="[...columns_drinks, ...columns_volumes, ...columns_prices]"
/>
<q-select <q-select
v-model="visibleColumn" v-model="visibleColumn"
multiple multiple
@ -21,6 +29,7 @@
option-value="name" option-value="name"
options-cover options-cover
/> />
</div>
</template> </template>
<template #body-cell-volumes="props"> <template #body-cell-volumes="props">
<q-td :props="props"> <q-td :props="props">
@ -63,6 +72,8 @@
: 'no-image.svg' : 'no-image.svg'
" "
placeholder-src="no-image.svg" placeholder-src="no-image.svg"
fit="contain"
style="max-height: 300px"
> >
<template #error> <template #error>
<div class="absolute-full flex flex-center bg-negative text-white"> <div class="absolute-full flex flex-center bg-negative text-white">
@ -79,6 +90,8 @@
import { defineComponent, onBeforeMount, computed, ref } from 'vue'; import { defineComponent, onBeforeMount, computed, ref } from 'vue';
import { usePricelistStore } from '../store'; import { usePricelistStore } from '../store';
import { useMainStore } from 'src/stores'; import { useMainStore } from 'src/stores';
import SearchInput from './SearchInput.vue';
import { filter } from '../utils/filter';
function sort(a: string | number, b: string | number) { function sort(a: string | number, b: string | number) {
if (a > b) return 1; if (a > b) return 1;
if (b > a) return -1; if (b > a) return -1;
@ -86,6 +99,7 @@ function sort(a: string | number, b: string | number) {
} }
export default defineComponent({ export default defineComponent({
name: 'Pricelist', name: 'Pricelist',
components: { SearchInput },
filters: { filters: {
setVolume(volume: number) { setVolume(volume: number) {
if (volume * 10 > 1) { if (volume * 10 > 1) {
@ -105,12 +119,6 @@ export default defineComponent({
}, },
setup() { setup() {
let user: string | null; let user: string | null;
onBeforeMount(() => {
if (user) {
store.getPriceCalcColumn(user);
}
});
const store = usePricelistStore();
onBeforeMount(() => { onBeforeMount(() => {
void store.getDrinks(); void store.getDrinks();
try { try {
@ -118,7 +126,12 @@ export default defineComponent({
} catch { } catch {
user = null; user = null;
} }
if (user) {
store.getPriceCalcColumn(user);
}
}); });
const store = usePricelistStore();
const drinks = computed(() => store.drinks); const drinks = computed(() => store.drinks);
const columns_drinks = [ const columns_drinks = [
{ {
@ -210,7 +223,17 @@ export default defineComponent({
}); });
return retVal; return retVal;
} }
return { columns_drinks, columns_volumes, columns_prices, drinks, visibleColumn }; const search = ref({ label: '', value: '', key: '' });
return {
columns_drinks,
columns_volumes,
columns_prices,
drinks,
visibleColumn,
search,
filter,
};
}, },
}); });
</script> </script>

View File

@ -0,0 +1,61 @@
<template>
<q-input v-model="v_model" filled dense>
<template #append>
<q-icon name="mdi-magnify" />
</template>
</q-input>
</template>
<script lang="ts">
import { defineComponent, computed, PropType } from 'vue';
export default defineComponent({
name: 'SearchInput',
props: {
modelValue: {
type: Object as PropType<{
value: string;
key: string | undefined;
label: string | undefined;
}>,
default: { value: '', key: undefined, label: '' },
},
keys: {
type: Object as PropType<Array<{ name: string; label: string }>>,
required: true,
},
},
emits: {
'update:modelValue': (val: {
value: string;
key: string | undefined;
label: string | undefined;
}) => val,
},
setup(props, { emit }) {
const v_model = computed<string>({
get: () => {
if (!props.modelValue.label || props.modelValue.label === '') {
return `${props.modelValue.value}`;
}
return `${props.modelValue.value}@${props.modelValue.label}`;
},
set: (val: string) => {
const split = val.toLowerCase().split('@');
if (split.length < 2) {
emit('update:modelValue', { value: split[0], label: undefined, key: undefined });
} else {
props.keys.find((key) => {
if (key.label.toLowerCase() === split[1]) {
console.log(key.name);
emit('update:modelValue', { value: split[0], label: split[1], key: key.name });
return true;
}
return false;
});
//emit('update:modelValue', {value: split[0], label: split[1], key: undefined})
}
},
});
return { v_model };
},
});
</script>

View File

@ -0,0 +1,27 @@
import { Drink } from '../store';
function filter(
rows: Array<Drink>,
terms: { value: string; key: string },
cols: Array<{ name: string; label: string; field: string }>,
cellValue: { (col: { name: string; label: string; field: string }, row: Drink): string }
) {
if (terms.value) {
return rows.filter((row) => {
if (!terms.key || terms.key === '') {
return cols.some((col) => {
const val = cellValue(col, row) + '';
const haystack = val === 'undefined' || val === 'null' ? '' : val.toLowerCase();
return haystack.indexOf(terms.value) !== -1;
});
}
const index = cols.findIndex((col) => col.name === terms.key);
const val = cellValue(cols[index], row) + '';
const haystack = val === 'undefined' || val === 'null' ? '' : val.toLowerCase();
return haystack.indexOf(terms.value) !== -1;
});
}
return rows;
}
export { filter };