Compare commits

...

4 Commits

5 changed files with 221 additions and 28 deletions

View File

@ -5,7 +5,8 @@
<div v-if="ingredient.drink_ingredient"> <div v-if="ingredient.drink_ingredient">
<div class="full-width row q-gutter-sm q-py-sm"> <div class="full-width row q-gutter-sm q-py-sm">
<div class="col"> <div class="col">
{{ name(ingredient.drink_ingredient?.ingredient_id) }} <!--{{ name(ingredient.drink_ingredient?.ingredient_id) }}-->
{{ ingredient.drink_ingredient?.name }}
</div> </div>
<div class="col"> <div class="col">
{{ {{

View File

@ -6,11 +6,14 @@
:rows="drinks" :rows="drinks"
dense dense
row-key="id" row-key="id"
:filter="search"
:filter-method="filter"
grid grid
:rows-per-page-options="[0]" :loading="loading"
:filter="search"
@request="onRequest"
> >
<!--
:filter-method="filter"
-->
<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="search_keys" /> <search-input v-model="search" :keys="search_keys" />
@ -166,7 +169,7 @@
<script lang="ts"> <script lang="ts">
import DrinkPriceVolumes from '../components/CalculationTable/DrinkPriceVolumes.vue'; import DrinkPriceVolumes from '../components/CalculationTable/DrinkPriceVolumes.vue';
import { defineComponent, onBeforeMount, ComputedRef, computed, ref } from 'vue'; import { defineComponent, onMounted, ComputedRef, computed, ref } from 'vue';
import { Drink, usePricelistStore, DrinkPriceVolume } from '../store'; import { Drink, usePricelistStore, DrinkPriceVolume } from '../store';
import MinPriceSetting from '../components/MinPriceSetting.vue'; import MinPriceSetting from '../components/MinPriceSetting.vue';
import { api, hasPermission } from '@flaschengeist/api'; import { api, hasPermission } from '@flaschengeist/api';
@ -203,8 +206,12 @@ export default defineComponent({
setup(props) { setup(props) {
const store = usePricelistStore(); const store = usePricelistStore();
onBeforeMount(() => { onMounted(() => {
void store.getDrinks(); //void store.getDrinks();
onRequest({
pagination: pagination.value,
filter: undefined,
});
}); });
const columns = [ const columns = [
@ -321,7 +328,7 @@ export default defineComponent({
}); });
return retVal; return retVal;
}, },
filterable: true, filterable: false,
sortable: false, sortable: false,
public: false, public: false,
}, },
@ -371,9 +378,46 @@ export default defineComponent({
const pagination = ref({ const pagination = ref({
sortBy: 'name', sortBy: 'name',
descending: false, descending: false,
rowsPerPage: store.drinks.length, page: 1,
rowsPerPage: 10,
rowsNumber: 10,
}); });
interface PaginationInterface {
sortBy: string;
descending: boolean;
page: number;
rowsPerPage: number;
rowsNumber: number;
}
const loading = ref(false);
async function onRequest(props: { pagination: PaginationInterface; filter?: Search }) {
const { page, rowsPerPage, sortBy, descending } = props.pagination;
loading.value = true;
console.log('search_keys', search_keys);
const fetchCount = rowsPerPage === 0 ? pagination.value.rowsNumber : rowsPerPage;
const startRow = (page - 1) * rowsPerPage;
try {
const result = await store.getDrinks({
offset: startRow,
limit: fetchCount,
descending,
search_name: props.filter.value,
search_key: props.filter.key,
});
pagination.value.page = page;
pagination.value.rowsPerPage = rowsPerPage;
pagination.value.sortBy = sortBy;
pagination.value.descending = descending;
if (result.count) pagination.value.rowsNumber = result.count;
} catch (error) {
//..
}
loading.value = false;
}
const drinkTypes = computed(() => store.drinkTypes); const drinkTypes = computed(() => store.drinkTypes);
function updateDrink(drink: Drink) { function updateDrink(drink: Drink) {
@ -527,6 +571,8 @@ export default defineComponent({
hasPermission, hasPermission,
PERMISSIONS, PERMISSIONS,
image, image,
loading,
onRequest,
}; };
}, },
}); });

View File

@ -9,7 +9,8 @@
<div v-if="ingredient.drink_ingredient" class="col"> <div v-if="ingredient.drink_ingredient" class="col">
<div class="full-width row justify-evenly q-py-xs"> <div class="full-width row justify-evenly q-py-xs">
<div class="col"> <div class="col">
{{ get_drink_ingredient_name(ingredient.drink_ingredient.ingredient_id) }} <!--{{ get_drink_ingredient_name(ingredient.drink_ingredient.ingredient_id) }}-->
{{ ingredient.drink_ingredient.name }}
<q-popup-edit <q-popup-edit
v-if="editable" v-if="editable"
v-slot="scope" v-slot="scope"
@ -25,6 +26,8 @@
label="Getränk" label="Getränk"
filled filled
dense dense
use-input
@filter="filter_drinks"
:options="drinks" :options="drinks"
option-label="name" option-label="name"
option-value="id" option-value="id"
@ -78,6 +81,8 @@
v-model="ingredient.extra_ingredient" v-model="ingredient.extra_ingredient"
filled filled
dense dense
use-input
@filter="filter_extra_ingredients"
:options="extra_ingredients" :options="extra_ingredients"
option-label="name" option-label="name"
/> />
@ -107,8 +112,10 @@
v-model="newIngredient" v-model="newIngredient"
filled filled
dense dense
use-input
label="Zutat" label="Zutat"
:options="[...drinks, ...extra_ingredients]" :options="[...drinks, ...extra_ingredients]"
@filter="filter"
option-label="name" option-label="name"
/> />
</div> </div>
@ -155,7 +162,7 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, PropType, ref, onBeforeMount, unref } from 'vue'; import { computed, defineComponent, PropType, ref, onBeforeMount, unref } from 'vue';
import { usePricelistStore } from '../../store'; import { usePricelistStore, Drink } from '../../store';
import { clone } from '../../utils/utils'; import { clone } from '../../utils/utils';
export default defineComponent({ export default defineComponent({
@ -236,13 +243,50 @@ export default defineComponent({
emit('update:modelValue', unref(edit_ingredients)); emit('update:modelValue', unref(edit_ingredients));
update(); update();
} }
const drinks = computed(() => //const drinks = computed(() =>
store.drinks.filter((drink) => { // store.drinks.filter((drink) => {
console.log('computed drinks', drink.name, drink.cost_per_volume); // console.log('computed drinks', drink.name, drink.cost_per_volume);
return drink.cost_per_volume; // return drink.cost_per_volume;
}) // })
); //);
const extra_ingredients = computed(() => store.extraIngredients); const drinks = ref<Array<Drink>>([]);
const _extra_ingredients = computed(() => store.extraIngredients);
const extra_ingredients = ref(_extra_ingredients.value);
async function filter_drinks(val, update) {
let result = <Array<Drink>>[];
if (val === '') {
result = await store.getDrinks_no_store({ limit: 5, ingredient: true });
} else {
result = await store.getDrinks_no_store({
limit: 5,
search_name: val,
search_key: 'name',
ingredient: true,
});
}
update(() => {
drinks.value = result;
});
}
function filter_extra_ingredients(val, update) {
if (val === '') {
update(() => {
extra_ingredients.value = _extra_ingredients.value;
});
} else {
update(() => {
extra_ingredients.value = _extra_ingredients.value.filter((ingredient) => {
return ingredient.name.toLowerCase().includes(val.toLowerCase());
});
});
}
}
async function filter(val, update) {
await filter_drinks(val, update);
filter_extra_ingredients(val, update);
}
function get_drink_ingredient_name(id: number) { function get_drink_ingredient_name(id: number) {
return store.drinks.find((a) => a.id === id)?.name; return store.drinks.find((a) => a.id === id)?.name;
@ -265,6 +309,9 @@ export default defineComponent({
deleteIngredient, deleteIngredient,
get_drink_ingredient_name, get_drink_ingredient_name,
edit_ingredients, edit_ingredients,
filter,
filter_drinks,
filter_extra_ingredients,
}; };
}, },
}); });

View File

@ -1,14 +1,17 @@
<template> <template>
<q-table <q-table
v-model:pagination="pagination"
grid grid
title="Rezepte" title="Rezepte"
:rows="drinks" :rows="drinks"
row-key="id" row-key="id"
hide-header hide-header
:filter="search" @request="onRequest"
:filter-method="filter"
:columns="options" :columns="options"
:filter="search"
> >
<!--:filter="search"
:filter-method="filter"-->
<template #top-right> <template #top-right>
<search-input v-model="search" :keys="search_keys" /> <search-input v-model="search" :keys="search_keys" />
</template> </template>
@ -68,12 +71,18 @@ export default defineComponent({
setup() { setup() {
const store = usePricelistStore(); const store = usePricelistStore();
onBeforeMount(() => { onBeforeMount(() => {
void store.getDrinks(); //void store.getDrinks();
onRequest({
pagination: pagination.value,
filter: { limit: 10, receipt: true },
});
}); });
const drinks = computed(() => const drinks = computed(
store.drinks.filter((drink) => { () =>
return drink.volumes.some((volume) => volume.ingredients.length > 0); //store.drinks.filter((drink) => {
}) // return drink.volumes.some((volume) => volume.ingredients.length > 0);
//})
store.drinks
); );
const columns_drinks = [ const columns_drinks = [
@ -81,6 +90,7 @@ export default defineComponent({
name: 'picture', name: 'picture',
label: 'Bild', label: 'Bild',
align: 'center', align: 'center',
filterable: false,
}, },
{ {
name: 'name', name: 'name',
@ -120,6 +130,7 @@ export default defineComponent({
label: 'Preise', label: 'Preise',
field: 'volumes', field: 'volumes',
align: 'center', align: 'center',
filterable: false,
}, },
]; ];
const columns_volumes = [ const columns_volumes = [
@ -161,6 +172,47 @@ export default defineComponent({
} }
return 'no-image.svg'; return 'no-image.svg';
} }
const loading = ref(false);
const pagination = ref({
sortBy: 'name',
descending: false,
page: 1,
rowsPerPage: 10,
rowsNumber: 10,
});
async function onRequest(props: { pagination: PaginationInterface; filter?: Search }) {
const { page, rowsPerPage, sortBy, descending } = props.pagination;
loading.value = true;
console.log('search_keys', search_keys);
const fetchCount = rowsPerPage === 0 ? pagination.value.rowsNumber : rowsPerPage;
const startRow = (page - 1) * rowsPerPage;
try {
const result = await store.getDrinks({
offset: startRow,
limit: fetchCount,
descending,
search_name: props.filter.value,
search_key: props.filter.key,
receipt: true,
});
pagination.value.page = page;
pagination.value.rowsPerPage = rowsPerPage;
pagination.value.sortBy = sortBy;
pagination.value.descending = descending;
if (result.count) pagination.value.rowsNumber = result.count;
} catch (error) {
//..
}
loading.value = false;
}
interface PaginationInterface {
sortBy: string;
descending: boolean;
page: number;
rowsPerPage: number;
rowsNumber: number;
}
return { return {
drinks, drinks,
options: [...columns_drinks, ...columns_volumes, ...columns_prices], options: [...columns_drinks, ...columns_volumes, ...columns_prices],
@ -168,6 +220,9 @@ export default defineComponent({
filter, filter,
search_keys, search_keys,
image, image,
onRequest,
loading,
pagination,
}; };
}, },
}); });

View File

@ -138,10 +138,21 @@ export const usePricelistStore = defineStore({
this.extraIngredients.splice(index, 1); this.extraIngredients.splice(index, 1);
} }
}, },
async getDrinks() { async getDrinks(filter: {
const { data } = await api.get<Array<FG.Drink>>('pricelist/drinks'); limit?: number;
offset?: number;
descending?: boolean;
search_name?: string;
search_key?: string;
receipt?: boolean;
}) {
if (!filter) filter = { limit: 10 };
console.log('filter_api', filter);
const { data } = await api.get<Array<FG.Drink>>('pricelist/drinks', {
params: filter,
});
this.drinks = []; this.drinks = [];
data.forEach((drink) => { data.drinks.forEach((drink) => {
const _drink = new Drink(drink); const _drink = new Drink(drink);
drink.volumes.forEach((volume) => { drink.volumes.forEach((volume) => {
const _volume = new DrinkPriceVolume(volume); const _volume = new DrinkPriceVolume(volume);
@ -150,6 +161,39 @@ export const usePricelistStore = defineStore({
this.drinks.push(_drink); this.drinks.push(_drink);
}); });
calc_all_min_prices(this.drinks, this.min_prices); calc_all_min_prices(this.drinks, this.min_prices);
return data;
},
sortPrices(volume: DrinkPriceVolume) {
volume.prices.sort((a, b) => {
if (a.price > b.price) return 1;
if (b.price > a.price) return -1;
return 0;
});
},
async getDrinks_no_store(filter: {
limit?: number;
offset?: number;
descending?: boolean;
search_name?: string;
search_key?: string;
ingredient?: boolean;
}) {
if (!filter) filter = { limit: 10 };
console.log('filter_api', filter);
const { data } = await api.get<Array<FG.Drink>>('pricelist/drinks', {
params: filter,
});
const drinks = [];
data.drinks.forEach((drink) => {
const _drink = new Drink(drink);
drink.volumes.forEach((volume) => {
const _volume = new DrinkPriceVolume(volume);
_drink.volumes.push(_volume);
});
drinks.push(_drink);
});
calc_all_min_prices(drinks, this.min_prices);
return drinks;
}, },
sortPrices(volume: DrinkPriceVolume) { sortPrices(volume: DrinkPriceVolume) {
volume.prices.sort((a, b) => { volume.prices.sort((a, b) => {