Compare commits
4 Commits
ad7ab825c8
...
f5c6bcff6f
Author | SHA1 | Date |
---|---|---|
Tim Gröger | f5c6bcff6f | |
Tim Gröger | 672124385a | |
Tim Gröger | ab92f16177 | |
Tim Gröger | 955f777aac |
|
@ -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">
|
||||||
{{
|
{{
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
50
src/store.ts
50
src/store.ts
|
@ -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) => {
|
||||||
|
|
Loading…
Reference in New Issue