flaschengeist-pricelist/src/pages/Receipts.vue

177 lines
4.5 KiB
Vue
Raw Normal View History

<template>
<q-table
grid
title="Rezepte"
:rows="drinks"
row-key="id"
hide-header
:filter="search"
:filter-method="filter"
:columns="options"
>
<template #top-right>
<search-input v-model="search" :keys="search_keys" />
</template>
<template #item="props">
<div class="q-pa-xs col-xs-12 col-sm-6 col-md-4">
<q-card>
<q-img
style="max-height: 256px"
loading="lazy"
:src="image(props.row.uuid)"
placeholder-src="no-image.svg"
>
<div class="absolute-bottom-right justify-end">
<div class="text-subtitle1 text-right">
{{ props.row.name }}
</div>
<div class="text-caption text-right">
{{ props.row.type.name }}
</div>
</div>
</q-img>
<q-card-section>
<q-badge
v-for="tag in props.row.tags"
:key="`${props.row.id}-${tag.id}`"
class="text-caption"
rounded
:style="`background-color: ${tag.color}`"
>
{{ tag.name }}
</q-badge>
</q-card-section>
<build-manual-volume :volumes="props.row.volumes" />
<q-card-section>
<div class="text-h6">Anleitung</div>
<build-manual :steps="props.row.receipt" :editable="false" />
</q-card-section>
</q-card>
</div>
</template>
</q-table>
</template>
<script lang="ts">
import { computed, defineComponent, onBeforeMount, ref } from 'vue';
import BuildManualVolume from '../components/BuildManual/BuildManualVolume.vue';
2021-05-25 19:43:32 +00:00
import BuildManual from '../components/CalculationTable/BuildManual.vue';
import SearchInput from '../components/SearchInput.vue';
import { filter, Search } from '../utils/filter';
import { usePricelistStore } from '../store';
import { sort } from '../utils/sort';
import { api } from '@flaschengeist/api';
export default defineComponent({
name: 'Reciepts',
components: { BuildManual, BuildManualVolume, SearchInput },
setup() {
const store = usePricelistStore();
onBeforeMount(() => {
void store.getDrinks();
});
const drinks = computed(() =>
store.drinks.filter((drink) => {
return drink.volumes.some((volume) => volume.ingredients.length > 0);
})
);
const columns_drinks = [
{
name: 'picture',
label: 'Bild',
align: 'center',
},
{
name: 'name',
label: 'Name',
field: 'name',
align: 'center',
sortable: true,
filterable: true,
},
{
name: 'drink_type',
label: 'Kategorie',
field: 'type',
format: (val: FG.DrinkType) => `${val.name}`,
sortable: true,
sort: (a: FG.DrinkType, b: FG.DrinkType) => sort(a.name, b.name),
filterable: true,
},
{
name: 'tags',
label: 'Tag',
field: 'tags',
format: (val: Array<FG.Tag>) => {
let retVal = '';
val.forEach((tag, index) => {
if (index > 0) {
retVal += ', ';
}
retVal += tag.name;
});
return retVal;
},
filterable: true,
},
{
name: 'volumes',
label: 'Preise',
field: 'volumes',
align: 'center',
},
];
const columns_volumes = [
{
name: 'volume',
label: 'Inhalt',
field: 'volume',
align: 'left',
},
{
name: 'prices',
label: 'Preise',
field: 'prices',
},
];
const columns_prices = [
{
name: 'price',
label: 'Preis',
field: 'price',
},
{
name: 'description',
label: 'Beschreibung',
field: 'description',
},
{
name: 'public',
label: 'Öffentlich',
field: 'public',
},
];
const search = ref<Search>({ value: '', key: '', label: '' });
const search_keys = computed(() => columns_drinks.filter((column) => column.filterable));
function image(uuid: string | undefined) {
if (uuid) {
2021-11-12 09:44:18 +00:00
return `${api.defaults.baseURL || ''}/pricelist/picture/${uuid}?size=256`;
}
return 'no-image.svg';
}
return {
drinks,
options: [...columns_drinks, ...columns_volumes, ...columns_prices],
search,
filter,
search_keys,
image,
};
},
});
</script>
<style scoped></style>