finish relations

This commit is contained in:
Nitwel
2020-09-23 11:29:38 +02:00
committed by rijkvanzanten
parent 09d35b0f88
commit 07ba2d4bd0
4 changed files with 68 additions and 51 deletions

View File

@@ -1,15 +1,16 @@
<template>
<draggable v-model="activeFields" draggable=".draggable" :set-data="hideDragImage" class="v-field-select">
<draggable v-model="selectedFields" draggable=".draggable" :set-data="hideDragImage" class="v-field-select">
<v-chip
v-for="(field, index) in activeFields"
v-for="(field, index) in selectedFields"
:key="index"
class="field draggable"
v-tooltip="field.field"
@click.stop="removeField(field.field)"
>
{{ field.name }}
</v-chip>
<v-menu
showArrow
show-arrow
v-model="menuActive"
v-show="selectableFields.length > 0"
slot="footer"
@@ -70,10 +71,10 @@ export default defineComponent({
const fieldsStore = useFieldsStore();
const menuActive = ref(false);
const { collection } = toRefs(props);
const { tree } = useFieldTree(collection);
const { info, primaryKeyField, fields: fieldsInCollection, sortField } = useCollection(collection);
const { tree } = useFieldTree(collection, true);
const _value = computed({
get() {
@@ -84,40 +85,53 @@ export default defineComponent({
},
});
const treeFlattened = computed(() => {
const fields: FieldTree[] = [];
const stack: FieldTree[] = tree.value;
while (stack.length > 0) {
const field = stack.shift();
if (field === undefined) continue;
fields.push(field);
if (field.children === undefined) continue;
stack.push(...field.children);
}
return fields;
});
const activeFields = computed({
const selectedFields = computed({
get() {
const list = _value.value.map((field) => fieldsInCollection.value.find((f) => f.field === field));
const filteredList: Field[] = [];
list.forEach((field) => {
if (field !== undefined) filteredList.push(field);
});
return filteredList;
return props.value.map((field) => ({
field,
name: findTree(tree.value, field.split('.'))?.name as string,
}));
},
set(newVal: Field[]) {
set(newVal: { field: string; name: string }[]) {
_value.value = newVal.map((field) => field.field);
},
});
const selectableFields = computed(() => {
return fieldsInCollection.value.filter((field) => _value.value.includes(field.field) === false);
return filterTree(tree.value, (field, prefix) => props.value.includes(prefix + field.field) === false);
});
return { tree, menuActive, addField, activeFields, removeField, selectableFields, hideDragImage };
return { menuActive, addField, removeField, selectableFields, selectedFields, hideDragImage, tree };
function findTree(tree: FieldTree[] | undefined, fieldSections: string[]): FieldTree | undefined {
if (tree === undefined) return undefined;
const fieldObject = tree.find((f) => f.field === fieldSections[0]);
if (fieldObject === undefined) return undefined;
if (fieldSections.length === 1) return fieldObject;
return findTree(fieldObject.children, fieldSections.slice(1));
}
function filterTree(
tree: FieldTree[] | undefined,
f: (field: FieldTree, prefix: string) => boolean,
prefix = ''
) {
if (tree === undefined) return undefined;
const newTree: FieldTree[] = [];
tree.forEach((field) => {
if (f(field, prefix)) {
newTree.push({
field: field.field,
name: field.name,
children: filterTree(field.children, f, prefix + field.field + '.'),
});
}
});
return newTree.length === 0 ? undefined : newTree;
}
function removeField(field: string) {
_value.value = _value.value.filter((f) => f !== field);
@@ -126,7 +140,7 @@ export default defineComponent({
function addField(field: string) {
const newArray = _value.value;
newArray.push(field);
_value.value = newArray;
_value.value = [...new Set(newArray)];
}
},
});

View File

@@ -3,7 +3,7 @@ import { FieldTree } from './types';
import { useFieldsStore, useRelationsStore } from '@/stores/';
import { Field, Relation } from '@/types';
export default function useFieldTree(collection: Ref<string>) {
export default function useFieldTree(collection: Ref<string>, showHidden = false) {
const fieldsStore = useFieldsStore();
const relationsStore = useRelationsStore();
@@ -12,7 +12,8 @@ export default function useFieldTree(collection: Ref<string>) {
.getFieldsForCollection(collection.value)
.filter(
(field: Field) =>
field.meta?.hidden === false && (field.meta?.special || []).includes('alias') === false
showHidden ||
(field.meta?.hidden === false && (field.meta?.special || []).includes('alias') === false)
)
.map((field: Field) => parseField(field, []));

View File

@@ -12,6 +12,7 @@
import { Field } from '@/types';
import { defineComponent, PropType, computed } from '@vue/composition-api';
import { useRelationsStore } from '@/stores/';
import { Relation } from '@/types';
export default defineComponent({
props: {
@@ -31,27 +32,26 @@ export default defineComponent({
get() {
return props.value?.fields;
},
set(newTemplate: string) {
set(newFields: string) {
emit('input', {
...(props.value || {}),
fields: newTemplate,
fields: newFields,
});
},
});
const collection = computed(() => {
if (props.fieldData.field == null || props.fieldData.meta?.collection == null) return null;
const junction = relationsStore.getRelationsForField(
props.fieldData.meta.collection,
props.fieldData.field
)?.[0];
const relationData = relationsStore.getRelationsForField(
junction.many_collection,
junction.junction_field
)?.[0];
const collection = props.fieldData.meta.collection;
const field = props.fieldData.field;
return relationData.one_collection;
const relations: Relation[] = relationsStore.getRelationsForField(collection, field);
const junction = relations.find((r) => r.one_collection === collection && r.one_field === field);
if (junction === undefined) return null;
return junction.many_collection;
});
return { fields, collection };

View File

@@ -11,7 +11,7 @@
</template>
<script lang="ts">
import { Field } from '@/types';
import { Field, Relation } from '@/types';
import { defineComponent, PropType, computed } from '@vue/composition-api';
import { useRelationsStore } from '@/stores/';
@@ -42,12 +42,14 @@ export default defineComponent({
});
const collection = computed(() => {
if (props.fieldData.field == null || props.fieldData.meta?.collection == null) return null;
const relationData = relationsStore.getRelationsForField(
props.fieldData.meta.collection,
props.fieldData.field
)?.[0];
return relationData.many_collection;
const collection = props.fieldData.meta?.collection;
const field = props.fieldData.field;
if (collection == null || field == null) return null;
const relationData: Relation[] = relationsStore.getRelationsForField(collection, field);
return relationData.find((r) => r.one_collection === collection && r.one_field === field)?.many_collection;
});
return { fields, collection };