mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
Show fields inside groups correctly in display templates for relational interfaces (#13187)
* added a tree with the groups filtered out for rendering the display templates * don't walk the tree unnecessarily * fix for groups after nested relations as often seen in M2M * moved the tree function to utils and updated references * [WIP] writing tests for the flatten-field-groups utility * tests for the flatten-field-groups utility
This commit is contained in:
@@ -29,11 +29,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, toRefs, ref, watch, onMounted, onUnmounted, PropType } from 'vue';
|
||||
import { defineComponent, toRefs, ref, watch, onMounted, onUnmounted, PropType, computed } from 'vue';
|
||||
import FieldListItem from './field-list-item.vue';
|
||||
import { FieldTree } from './types';
|
||||
import { Field, Relation } from '@directus/shared/types';
|
||||
import { useFieldTree } from '@/composables/use-field-tree';
|
||||
import { flattenFieldGroups } from '@/utils/flatten-field-groups';
|
||||
|
||||
export default defineComponent({
|
||||
components: { FieldListItem },
|
||||
@@ -78,6 +79,10 @@ export default defineComponent({
|
||||
|
||||
watch(() => props.modelValue, setContent, { immediate: true });
|
||||
|
||||
const grouplessTree = computed(() => {
|
||||
return flattenFieldGroups(treeList.value);
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
if (contentEl.value) {
|
||||
contentEl.value.addEventListener('selectstart', onSelect);
|
||||
@@ -279,7 +284,7 @@ export default defineComponent({
|
||||
loadFieldRelations(fieldPath.slice(0, i).join('.'));
|
||||
}
|
||||
|
||||
const field = findTree(treeList.value, fieldPath);
|
||||
const field = findTree(grouplessTree.value, fieldPath);
|
||||
|
||||
if (!field) return '';
|
||||
|
||||
|
||||
20
app/src/utils/flatten-field-groups.ts
Normal file
20
app/src/utils/flatten-field-groups.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { FieldNode } from '@/composables/use-field-tree';
|
||||
|
||||
/**
|
||||
* Returns the given tree without FieldNodes that have the "group" flag set.
|
||||
*/
|
||||
export function flattenFieldGroups(tree: FieldNode[]): FieldNode[] {
|
||||
function flattenGroups(list: FieldNode[]): FieldNode[] {
|
||||
return list.flatMap((item: FieldNode) => {
|
||||
if (Array.isArray(item.children) && item.children.length > 0) {
|
||||
if (item.group === true) {
|
||||
return flattenGroups(item.children);
|
||||
} else {
|
||||
item.children = flattenGroups(item.children);
|
||||
}
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}
|
||||
return flattenGroups(tree);
|
||||
}
|
||||
122
app/tests/utils/flatten-field-groups.test.ts
Normal file
122
app/tests/utils/flatten-field-groups.test.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import { flattenFieldGroups } from '../../src/utils/flatten-field-groups';
|
||||
import { FieldNode } from '@/composables/use-field-tree';
|
||||
|
||||
describe('utils/flatten-field-groups', () => {
|
||||
it('Returns the original tree when no groups are present', () => {
|
||||
const TreeWithoutGroups: FieldNode[] = [
|
||||
{ name: 'ID', field: 'id', collection: 'test', key: 'id', path: 'id', type: 'integer' },
|
||||
{ name: 'Test Field', field: 'test', collection: 'test', key: 'test', path: 'test', type: 'string' },
|
||||
];
|
||||
expect(flattenFieldGroups(TreeWithoutGroups)).toEqual(TreeWithoutGroups);
|
||||
});
|
||||
it('Returns a tree without groups', () => {
|
||||
const TreeWithGroups: FieldNode[] = [
|
||||
{ name: 'ID', field: 'id', collection: 'test', key: 'id', path: 'id', type: 'integer' },
|
||||
{
|
||||
name: 'Group',
|
||||
field: 'group',
|
||||
collection: 'test',
|
||||
key: '',
|
||||
path: 'group',
|
||||
group: true,
|
||||
type: 'alias',
|
||||
children: [
|
||||
{
|
||||
name: 'Nested Field',
|
||||
field: 'nested_field',
|
||||
collection: 'test',
|
||||
key: 'nested_field',
|
||||
path: 'group.nested_field',
|
||||
type: 'string',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
const TreeWithoutGroups: FieldNode[] = [
|
||||
{ name: 'ID', field: 'id', collection: 'test', key: 'id', path: 'id', type: 'integer' },
|
||||
{
|
||||
name: 'Nested Field',
|
||||
field: 'nested_field',
|
||||
collection: 'test',
|
||||
key: 'nested_field',
|
||||
path: 'group.nested_field',
|
||||
type: 'string',
|
||||
},
|
||||
];
|
||||
expect(flattenFieldGroups(TreeWithGroups)).toEqual(TreeWithoutGroups);
|
||||
});
|
||||
it('Returns a tree without deeply nested groups', () => {
|
||||
const TreeWithNestedGroups: FieldNode[] = [
|
||||
{ name: 'ID', field: 'id', collection: 'test', key: 'id', path: 'id', type: 'integer' },
|
||||
{
|
||||
name: 'Group',
|
||||
field: 'group1',
|
||||
collection: 'test',
|
||||
key: '',
|
||||
path: 'group1',
|
||||
group: true,
|
||||
type: 'alias',
|
||||
children: [
|
||||
{
|
||||
name: 'Group',
|
||||
field: 'group2',
|
||||
collection: 'test',
|
||||
key: '',
|
||||
path: 'group2',
|
||||
group: true,
|
||||
type: 'alias',
|
||||
children: [
|
||||
{
|
||||
name: 'Nested Field 1',
|
||||
field: 'nested_field_1',
|
||||
collection: 'test',
|
||||
key: 'nested_field',
|
||||
path: 'group.nested_field_1',
|
||||
type: 'string',
|
||||
},
|
||||
{
|
||||
name: 'Group',
|
||||
field: 'group3',
|
||||
collection: 'test',
|
||||
key: '',
|
||||
path: 'group3',
|
||||
group: true,
|
||||
type: 'alias',
|
||||
children: [
|
||||
{
|
||||
name: 'Nested Field 2',
|
||||
field: 'nested_field_2',
|
||||
collection: 'test',
|
||||
key: 'nested_field',
|
||||
path: 'group.nested_field_2',
|
||||
type: 'string',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
const TreeWithoutGroups: FieldNode[] = [
|
||||
{ name: 'ID', field: 'id', collection: 'test', key: 'id', path: 'id', type: 'integer' },
|
||||
{
|
||||
name: 'Nested Field 1',
|
||||
field: 'nested_field_1',
|
||||
collection: 'test',
|
||||
key: 'nested_field',
|
||||
path: 'group.nested_field_1',
|
||||
type: 'string',
|
||||
},
|
||||
{
|
||||
name: 'Nested Field 2',
|
||||
field: 'nested_field_2',
|
||||
collection: 'test',
|
||||
key: 'nested_field',
|
||||
path: 'group.nested_field_2',
|
||||
type: 'string',
|
||||
},
|
||||
];
|
||||
expect(flattenFieldGroups(TreeWithNestedGroups)).toEqual(TreeWithoutGroups);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user