[pricelist][#6] draggable change of order of pricelist columns
This commit is contained in:
parent
be347225c4
commit
18d0098bb3
|
@ -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",
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
14
yarn.lock
14
yarn.lock
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue