[pricelist][#6] draggable change of order of pricelist columns

This commit is contained in:
Tim Gröger 2021-04-17 18:26:21 +02:00
parent be347225c4
commit 18d0098bb3
4 changed files with 142 additions and 10 deletions

View File

@ -18,7 +18,8 @@
"axios": "^0.21.1", "axios": "^0.21.1",
"cordova": "^10.0.0", "cordova": "^10.0.0",
"pinia": "^2.0.0-alpha.10", "pinia": "^2.0.0-alpha.10",
"quasar": "^2.0.0-beta.12" "quasar": "^2.0.0-beta.12",
"vuedraggable": "^4.0.1"
}, },
"devDependencies": { "devDependencies": {
"@quasar/app": "^3.0.0-beta.13", "@quasar/app": "^3.0.0-beta.13",

View File

@ -26,6 +26,20 @@
option-value="name" option-value="name"
options-cover options-cover
/> />
<q-btn round icon="mdi-backburger">
<q-tooltip anchor='top middle' self='bottom middle'> Reihenfolge ändern </q-tooltip>
<q-menu anchor="bottom middle" self="top middle">
<drag v-model="order" class="q-list" ghost-class="ghost" group="people" item-key="id">
<template #item="{ element }">
<q-item>
<q-item-section>
{{ element.label }}
</q-item-section>
</q-item>
</template>
</drag>
</q-menu>
</q-btn>
<slot></slot> <slot></slot>
<q-btn <q-btn
round round
@ -61,14 +75,27 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, onBeforeMount, ref } from 'vue'; import { computed, defineComponent, onBeforeMount, ref, ComponentPublicInstance } from 'vue';
import { usePricelistStore } from '../store'; import { usePricelistStore, Order } from '../store';
import { useMainStore } from 'src/stores'; import { useMainStore } from 'src/stores';
import { Search, filter } from 'src/plugins/pricelist/utils/filter'; import { Search, filter } from 'src/plugins/pricelist/utils/filter';
import SearchInput from 'src/plugins/pricelist/components/SearchInput.vue'; import SearchInput from 'src/plugins/pricelist/components/SearchInput.vue';
import draggable from 'vuedraggable';
const drag: ComponentPublicInstance = <ComponentPublicInstance>draggable;
interface Row {
name: string;
label: string;
field: string;
sortable?: boolean;
filterable?: boolean;
format?: (val: never) => string;
align?: string;
}
export default defineComponent({ export default defineComponent({
name: 'Pricelist', name: 'Pricelist',
components: { SearchInput }, components: { SearchInput, drag },
props: { props: {
public: { public: {
type: Boolean, type: Boolean,
@ -82,6 +109,7 @@ export default defineComponent({
onBeforeMount(() => { onBeforeMount(() => {
if (!props.public) { if (!props.public) {
user.value = useMainStore().currentUser.userid; user.value = useMainStore().currentUser.userid;
void store.getPriceListColumnOrder(user.value);
void store.getDrinks(); void store.getDrinks();
void store.getPriceCalcColumn(user.value); void store.getPriceCalcColumn(user.value);
} else { } else {
@ -89,7 +117,57 @@ export default defineComponent({
} }
}); });
const columns = [ const _order = ref<Array<Order>>([
{
name: 'name',
label: 'Name',
},
{
name: 'type',
label: 'Kategorie',
},
{
name: 'tags',
label: 'Tags',
},
{
name: 'volume',
label: 'Inhalt',
},
{
name: 'price',
label: 'Preis',
},
{
name: 'public',
label: 'Öffentlich',
},
{
name: 'description',
label: 'Beschreibung',
},
]);
const order = computed<Array<Order>>({
get: () => {
if (props.public) {
return _order.value;
}
if (store.pricelist_columns_order.length === 0) {
return _order.value;
}
return store.pricelist_columns_order;
},
set: (val: Array<Order>) => {
if (!props.public) {
void store.updatePriceListColumnOrder(user.value, val);
} else {
_order.value = val;
}
},
});
const _columns: Array<Row> = [
{ {
name: 'name', name: 'name',
label: 'Name', label: 'Name',
@ -153,9 +231,29 @@ export default defineComponent({
}, },
]; ];
const columns = computed(() => {
const retVal: Array<Row> = [];
if (order.value) {
order.value.forEach((col) => {
const _col = _columns.find((a) => a.name === col.name);
if (_col) {
retVal.push(_col);
}
});
retVal.forEach((element, index) => {
element.align = 'right';
if (index === 0) {
element.align = 'left';
}
});
return retVal;
}
return _columns;
});
const _options = computed(() => { const _options = computed(() => {
const retVal: Array<{ name: string; label: string; field: string }> = []; const retVal: Array<{ name: string; label: string; field: string }> = [];
columns.forEach((col) => { columns.value.forEach((col) => {
if (props.public) { if (props.public) {
if (col.name !== 'public') { if (col.name !== 'public') {
retVal.push(col); retVal.push(col);
@ -169,7 +267,7 @@ export default defineComponent({
const _colums = computed<Array<string>>(() => { const _colums = computed<Array<string>>(() => {
const retVal: Array<string> = []; const retVal: Array<string> = [];
columns.forEach((col) => { columns.value.forEach((col) => {
if (props.public) { if (props.public) {
if (col.name !== 'public') { if (col.name !== 'public') {
retVal.push(col.name); retVal.push(col.name);
@ -210,6 +308,7 @@ export default defineComponent({
return { return {
drinks: computed(() => store.pricelist), drinks: computed(() => store.pricelist),
columns, columns,
order,
visibleColumns, visibleColumns,
options: _options, options: _options,
search, search,
@ -221,4 +320,8 @@ export default defineComponent({
}); });
</script> </script>
<style scoped></style> <style scoped lang="sass">
.ghost
opacity: 0.5
background: $accent
</style>

View File

@ -68,6 +68,11 @@ class Drink {
} }
} }
interface Order {
label: string;
name: string;
}
export const usePricelistStore = defineStore({ export const usePricelistStore = defineStore({
id: 'pricelist', id: 'pricelist',
@ -79,6 +84,7 @@ export const usePricelistStore = defineStore({
tags: [] as Array<FG.Tag>, tags: [] as Array<FG.Tag>,
pricecalc_columns: [] as Array<string>, pricecalc_columns: [] as Array<string>,
pricelist_view: false as boolean, pricelist_view: false as boolean,
pricelist_columns_order: [] as Array<Order>,
}), }),
actions: { actions: {
@ -270,6 +276,16 @@ export const usePricelistStore = defineStore({
await api.put<Array<string>>(`pricelist/users/${userid}/pricelist`, { value: data }); await api.put<Array<string>>(`pricelist/users/${userid}/pricelist`, { value: data });
this.pricelist_view = data; this.pricelist_view = data;
}, },
async getPriceListColumnOrder(userid: string) {
const { data } = await api.get<Array<Order>>(
`pricelist/users/${userid}/pricecalc_columns_order`
);
this.pricelist_columns_order = data;
},
async updatePriceListColumnOrder(userid: string, data: Array<Order>) {
await api.put<Array<string>>(`pricelist/users/${userid}/pricecalc_columns_order`, data);
this.pricelist_columns_order = data;
},
}, },
getters: { getters: {
pricelist() { pricelist() {
@ -294,4 +310,4 @@ export const usePricelistStore = defineStore({
}, },
}); });
export { DrinkPriceVolume, Drink }; export { DrinkPriceVolume, Drink, Order };

View File

@ -1155,7 +1155,7 @@
"@quasar/quasar-app-extension-qcalendar@file:deps/quasar-ui-qcalendar/app-extension": "@quasar/quasar-app-extension-qcalendar@file:deps/quasar-ui-qcalendar/app-extension":
version "4.0.0-alpha.1" version "4.0.0-alpha.1"
dependencies: dependencies:
"@quasar/quasar-ui-qcalendar" "link:../../Library/Caches/Yarn/v6/npm-@quasar-quasar-app-extension-qcalendar-4.0.0-alpha.1-5c1bc627-3876-4022-8043-d12aa47b1a6c-1618600205818/node_modules/@quasar/ui" "@quasar/quasar-ui-qcalendar" "link:../../Library/Caches/Yarn/v6/npm-@quasar-quasar-app-extension-qcalendar-4.0.0-alpha.1-c42f9f4b-6777-438d-bf23-9bdcfb44ae8c-1618669700018/node_modules/@quasar/ui"
"@quasar/quasar-ui-qcalendar@link:deps/quasar-ui-qcalendar/ui": "@quasar/quasar-ui-qcalendar@link:deps/quasar-ui-qcalendar/ui":
version "0.0.0" version "0.0.0"
@ -9525,6 +9525,11 @@ sort-keys@^1.0.0:
dependencies: dependencies:
is-plain-obj "^1.0.0" is-plain-obj "^1.0.0"
sortablejs@1.10.2:
version "1.10.2"
resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.10.2.tgz#6e40364d913f98b85a14f6678f92b5c1221f5290"
integrity sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A==
source-list-map@^2.0.0, source-list-map@^2.0.1: source-list-map@^2.0.0, source-list-map@^2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
@ -10647,6 +10652,13 @@ vue@3.0.11:
"@vue/runtime-dom" "3.0.11" "@vue/runtime-dom" "3.0.11"
"@vue/shared" "3.0.11" "@vue/shared" "3.0.11"
vuedraggable@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-4.0.1.tgz#3bcaab0808b7944030b7d9a29f9a63d59dfa12c5"
integrity sha512-7qN5jhB1SLfx5P+HCm3JUW+pvgA1bSLgYLSVOeLWBDH9z+zbaEH0OlyZBVMLOxFR+JUHJjwDD0oy7T4r9TEgDA==
dependencies:
sortablejs "1.10.2"
vuex@4.0.0: vuex@4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/vuex/-/vuex-4.0.0.tgz#ac877aa76a9c45368c979471e461b520d38e6cf5" resolved "https://registry.yarnpkg.com/vuex/-/vuex-4.0.0.tgz#ac877aa76a9c45368c979471e461b520d38e6cf5"