Fix v-field-select dropdown

Ref #852
This commit is contained in:
rijkvanzanten
2020-11-03 15:16:07 -05:00
parent abadf0956a
commit dca7df6fb2
7 changed files with 127 additions and 49 deletions

View File

@@ -26,7 +26,7 @@
<v-list>
<field-list-item
v-for="field in availableFields"
:key="field.field"
:key="field.key"
:field="field"
:depth="depth"
@add="addField"
@@ -137,6 +137,7 @@ export default defineComponent({
return {
name: field.name,
field: field.field,
key: field.key,
disabled: _value.value.includes(prefix + field.field),
children: parseTree(field.children, prefix + field.field + '.'),
};

View File

@@ -10,7 +10,7 @@
<template #activator>{{ field.name || formatTitle(field.field) }}</template>
<field-list-item
v-for="childField in field.children"
:key="field.field + childField.field"
:key="childField.key"
:parent="`${parent ? parent + '.' : ''}${field.field}`"
:field="childField"
:depth="depth - 1"

View File

@@ -1,9 +1,9 @@
import { Field } from '@/types';
import { TranslateResult } from 'vue-i18n';
export type FieldTree = {
field: string;
name: string | TranslateResult;
key: string;
disabled?: boolean;
children?: FieldTree[];
};

View File

@@ -3,5 +3,6 @@ import { TranslateResult } from 'vue-i18n';
export type FieldTree = {
field: string;
name: string | TranslateResult;
key: string;
children?: FieldTree[];
};

View File

@@ -2,66 +2,110 @@ import { Ref, computed } from '@vue/composition-api';
import { FieldTree } from './types';
import { useFieldsStore, useRelationsStore } from '@/stores/';
import { Field, Relation } from '@/types';
import { cloneDeep } from 'lodash';
import { getRelationType } from '@/utils/get-relation-type';
export default function useFieldTree(collection: Ref<string>, inject?: { fields: Field[]; relations: Relation[] }) {
const fieldsStore = useFieldsStore();
const relationsStore = useRelationsStore();
const tree = computed<FieldTree[]>(() => {
return [...fieldsStore.getFieldsForCollection(collection.value), ...(inject?.fields || [])]
const tree = computed(() => parseLevel(collection.value, null));
return { tree };
function parseLevel(collection: string, parentPath: string | null, level = 0) {
const fieldsInLevel = cloneDeep(fieldsStore.getFieldsForCollection(collection))
.filter((field: Field) => {
const shown =
field.meta?.special?.includes('alias') !== true &&
field.meta?.special?.includes('no-data') !== true;
return shown;
})
.map((field: Field) => parseField(field, []));
function parseField(field: Field, parents: Field[]) {
const fieldInfo: FieldTree = {
field: field.field,
.map((field: Field) => ({
name: field.name,
};
field: field.field,
key: parentPath ? `${parentPath}.${field.field}` : field.field,
}));
if (parents.length === 2) {
return fieldInfo;
if (level >= 3) return fieldsInLevel;
for (const field of fieldsInLevel) {
const relations = relationsStore.getRelationsForField(collection, field.field);
const relation = relations.find(
(relation: Relation) =>
(relation.many_collection === collection && relation.many_field === field.field) ||
(relation.one_collection === collection && relation.one_field === field.field)
);
if (!relation) continue;
const relationType = getRelationType({ relation, collection, field: field.field });
if (relationType === 'm2o') {
field.children = parseLevel(
relation.one_collection,
parentPath ? `${parentPath}.${field.field}` : field.field,
level + 1
);
}
const relations = [
...relationsStore.getRelationsForField(field.collection, field.field),
...(inject?.relations || []).filter(
(relation) =>
(relation.many_collection === field.collection && relation.many_field === field.field) ||
(relation.one_collection === field.collection && relation.one_field === field.field)
),
];
if (relations.length > 0) {
const relatedFields = relations
.map((relation: Relation) => {
const relatedCollection =
relation.many_collection === field.collection
? relation.one_collection
: relation.many_collection;
if (relation.junction_field === field.field) return [];
return fieldsStore.getFieldsForCollection(relatedCollection).filter((field: Field) => {
const shown =
field.meta?.special?.includes('alias') !== true &&
field.meta?.special?.includes('no-data') !== true;
return shown;
});
})
.flat()
.map((childField: Field) => parseField(childField, [...parents, field]));
fieldInfo.children = relatedFields;
}
return fieldInfo;
}
});
return { tree };
return fieldsInLevel;
}
// const tree = computed<FieldTree[]>(() => {
// return [...fieldsStore.getFieldsForCollection(collection.value), ...(inject?.fields || [])]
// .filter((field: Field) => {
// const shown =
// field.meta?.special?.includes('alias') !== true &&
// field.meta?.special?.includes('no-data') !== true;
// return shown;
// })
// .map((field: Field) => parseField(field, []));
// function parseField(field: Field, parents: Field[]) {
// const fieldInfo: FieldTree = {
// field: field.field,
// name: field.name,
// };
// if (parents.length === 2) {
// return fieldInfo;
// }
// const relations = [
// ...relationsStore.getRelationsForField(field.collection, field.field),
// ...(inject?.relations || []).filter(
// (relation) =>
// (relation.many_collection === field.collection && relation.many_field === field.field) ||
// (relation.one_collection === field.collection && relation.one_field === field.field)
// ),
// ];
// if (relations.length > 0) {
// const relatedFields = relations
// .map((relation: Relation) => {
// const relatedCollection =
// relation.many_collection === field.collection
// ? relation.one_collection
// : relation.many_collection;
// if (relation.junction_field === field.field) return [];
// return fieldsStore.getFieldsForCollection(relatedCollection).filter((field: Field) => {
// const shown =
// field.meta?.special?.includes('alias') !== true &&
// field.meta?.special?.includes('no-data') !== true;
// return shown;
// });
// })
// .flat()
// .map((childField: Field) => parseField(childField, [...parents, field]));
// fieldInfo.children = relatedFields;
// }
// return fieldInfo;
// }
// });
// return { tree };
}

View File

@@ -7,4 +7,6 @@ export type Relation = {
one_field: null | string;
one_primary: string;
junction_field: null | string;
one_collection_field: null | string;
one_allowed_collections: null | string[];
};

View File

@@ -0,0 +1,30 @@
import { Relation } from '@/types';
export function getRelationType(getRelationOptions: {
relation: Relation;
collection: string | null;
field: string;
}): 'm2o' | 'o2m' | 'm2a' | null {
const { relation, collection, field } = getRelationOptions;
if (!relation) return null;
if (
relation.many_collection === collection &&
relation.many_field === field &&
relation.one_collection_field &&
relation.one_allowed_collections
) {
return 'm2a';
}
if (relation.many_collection === collection && relation.many_field === field) {
return 'm2o';
}
if (relation.one_collection === collection && relation.one_field === field) {
return 'o2m';
}
return null;
}