ff-admin/src/components/queryBuilder/OrderStructure.vue

146 lines
4.6 KiB
Vue
Raw Normal View History

2024-12-16 15:39:49 +01:00
<template>
<div class="flex flex-row gap-2 items-center w-full">
2025-04-15 09:35:08 +02:00
<div class="flex flex-col min-w-fit">
<ChevronUpIcon v-if="notFirst" class="w-4 h-4 stroke-2 cursor-pointer" @click.prevent="$emit('up')" />
<ChevronDownIcon v-if="notLast" class="w-4 h-4 stroke-2 cursor-pointer" @click.prevent="$emit('down')" />
</div>
2024-12-16 15:39:49 +01:00
<select v-model="column" class="w-full">
<option value="" disabled>Spalte auswählen</option>
2025-04-15 09:26:25 +02:00
<option
v-for="selectable in selectableColumns"
:value="`${selectable.id}_${selectable.column}`"
:disabled="
alreadySorted.some((as) => as.id == selectable.id && as.col == selectable.column) &&
`${selectable.id}_${selectable.column}` != column
"
>
{{ [...selectable.path, selectable.table].join("-") }} -> {{ selectable.column }}
2024-12-16 15:39:49 +01:00
</option>
</select>
<select v-model="order">
<option value="" disabled>Sortierung auswählen</option>
2025-04-15 09:26:25 +02:00
<option v-for="order in orderable" :value="order.key">
{{ order.val }}
2024-12-16 15:39:49 +01:00
</option>
</select>
<div class="p-1 border border-gray-400 hover:bg-gray-200 rounded-md" @click="$emit('remove')">
<TrashIcon class="text-gray-500 h-6 w-6 cursor-pointer" />
</div>
</div>
</template>
<script setup lang="ts">
import { defineComponent, type PropType } from "vue";
import { mapActions, mapState } from "pinia";
2024-12-26 12:34:36 +01:00
import type { OrderByStructure, OrderByType } from "@/types/dynamicQueries";
2025-01-02 18:28:13 +01:00
import { useQueryBuilderStore } from "@/stores/admin/club/queryBuilder";
2025-04-15 09:35:08 +02:00
import { TrashIcon, ChevronDownIcon, ChevronUpIcon } from "@heroicons/vue/24/outline";
2024-12-16 15:39:49 +01:00
</script>
<script lang="ts">
export default defineComponent({
props: {
2025-04-15 09:35:08 +02:00
notFirst: {
type: Boolean,
defailt: false,
},
notLast: {
type: Boolean,
defailt: false,
},
2024-12-16 15:39:49 +01:00
table: {
type: String,
default: "",
},
2025-04-15 09:26:25 +02:00
// columns: {
// type: [Array, String] as PropType<"*" | Array<string>>,
// default: "*",
// },
2024-12-16 15:39:49 +01:00
columns: {
2025-04-15 09:26:25 +02:00
type: Array as PropType<
Array<{ table: string; id: string; depth: number; path: string[]; columns: "*" | string[] }>
>,
default: [],
2024-12-16 15:39:49 +01:00
},
modelValue: {
type: Object as PropType<OrderByStructure>,
default: {},
},
2025-04-15 09:26:25 +02:00
alreadySorted: {
type: Array as PropType<Array<{ id: string; col: string }>>,
default: [],
},
2024-12-16 15:39:49 +01:00
},
2025-04-15 09:35:08 +02:00
emits: ["update:model-value", "remove", "up", "down"],
2025-04-15 09:26:25 +02:00
watch: {
columns() {
if (!this.columns.some((c) => c.id == this.modelValue.id)) {
this.$emit("remove");
}
},
},
2024-12-16 15:39:49 +01:00
data() {
2025-04-15 09:26:25 +02:00
return {
orderable: [
{ key: "ASC", val: "Aufsteigend (ABC)" },
{ key: "DESC", val: "Absteigend (CBA)" },
],
};
2024-12-16 15:39:49 +01:00
},
computed: {
...mapState(useQueryBuilderStore, ["tableMetas"]),
2025-04-15 09:26:25 +02:00
// selectableColumns() {
// if (this.columns == "*") {
// let meta = this.tableMetas.find((tm) => tm.tableName == this.table);
// if (!meta) return [];
// let relCols = meta.relations.map((r) => r.column);
// return meta.columns.map((c) => c.column).filter((c) => !relCols.includes(c));
// } else {
// return this.columns;
// }
// },
2024-12-16 15:39:49 +01:00
selectableColumns() {
2025-04-15 09:26:25 +02:00
return this.columns.reduce(
(acc, curr) => {
if (curr.columns == "*") {
2025-04-15 10:02:30 +02:00
let meta = this.tableMetas.find((tm) => tm.tableName == curr.table);
2025-04-15 09:26:25 +02:00
if (meta) {
let relCols = meta.relations.map((r) => r.column);
meta.columns
.map((c) => c.column)
.filter((c) => !relCols.includes(c))
.forEach((c) =>
acc.push({ id: curr.id, depth: curr.depth, table: curr.table, column: c, path: curr.path })
);
}
} else {
curr.columns.forEach((c) =>
acc.push({ id: curr.id, depth: curr.depth, table: curr.table, column: c, path: curr.path })
);
}
return acc;
},
[] as Array<{ id: string; depth: number; table: string; column: string; path: string[] }>
);
2024-12-16 15:39:49 +01:00
},
column: {
get() {
2025-04-15 09:26:25 +02:00
return `${this.modelValue.id}_${this.modelValue.column}`;
2024-12-16 15:39:49 +01:00
},
2025-04-15 09:26:25 +02:00
set(val: `${string}_${string}`) {
let col = this.selectableColumns.find((sc) => sc.id == val.split("_")[0] && sc.column == val.split("_")[1]);
this.$emit("update:model-value", { ...this.modelValue, ...col });
2024-12-16 15:39:49 +01:00
},
},
order: {
get() {
return this.modelValue.order;
},
set(val: OrderByType) {
this.$emit("update:model-value", { ...this.modelValue, order: val });
},
},
},
});
</script>