Fix o2m not rendering nested m2o data

Fixes #841
This commit is contained in:
rijkvanzanten
2020-11-02 15:33:26 -05:00
parent 7b20911b5a
commit ec98d072d4
2 changed files with 60 additions and 58 deletions

View File

@@ -1,8 +1,8 @@
import { Ref, ref, watch, computed } from '@vue/composition-api';
import { Ref, ref, watch } from '@vue/composition-api';
import { Header } from '@/components/v-table/types';
import { RelationInfo } from './use-relation';
import { useFieldsStore } from '@/stores/';
import { Field, Collection } from '@/types';
import { Field } from '@/types';
import api from '@/api';
import { cloneDeep, get } from 'lodash';
@@ -25,20 +25,6 @@ export default function usePreview(
const items = ref<Record<string, any>[]>([]);
const error = ref(null);
function getRelatedFields(fields: string[]) {
const { junctionField } = relation.value;
return fields.reduce((acc: string[], field) => {
const sections = field.split('.');
if (junctionField === sections[0] && sections.length >= 2) acc.push(sections.slice(1).join('.'));
return acc;
}, []);
}
function getJunctionFields() {
return (fields.value || []).filter((field) => field.includes('.') === false);
}
watch(
() => value.value,
async (newVal) => {
@@ -112,6 +98,61 @@ export default function usePreview(
{ immediate: true }
);
// Seeing we don't care about saving those tableHeaders, we can reset it whenever the
// fields prop changes (most likely when we're navigating to a different o2m context)
watch(
() => fields.value,
() => {
const { junctionField, junctionCollection } = relation.value;
tableHeaders.value = (fields.value.length > 0
? fields.value
: getDefaultFields().map((field) => `${junctionField}.${field}`)
)
.map((fieldKey) => {
let field = fieldsStore.getField(junctionCollection, fieldKey);
if (!field) return null;
const header: Header = {
text: field.name,
value: fieldKey,
align: 'left',
sortable: true,
width: null,
field: {
display: field.meta?.display,
displayOptions: field.meta?.display_options,
interface: field.meta?.interface,
interfaceOptions: field.meta?.options,
type: field.type,
field: field.field,
},
};
return header;
})
.filter((h) => h) as Header[];
},
{ immediate: true }
);
return { tableHeaders, items, loading, error };
function getRelatedFields(fields: string[]) {
const { junctionField } = relation.value;
return fields.reduce((acc: string[], field) => {
const sections = field.split('.');
if (junctionField === sections[0] && sections.length >= 2) acc.push(sections.slice(1).join('.'));
return acc;
}, []);
}
function getJunctionFields() {
return (fields.value || []).filter((field) => field.includes('.') === false);
}
async function loadRelatedIds() {
const { junctionPkField, junctionField, relationPkField, junctionCollection } = relation.value;
@@ -162,49 +203,8 @@ export default function usePreview(
return response?.data.data as Record<string, any>[];
}
// Seeing we don't care about saving those tableHeaders, we can reset it whenever the
// fields prop changes (most likely when we're navigating to a different o2m context)
watch(
() => fields.value,
() => {
const { junctionField, junctionCollection } = relation.value;
tableHeaders.value = (fields.value.length > 0
? fields.value
: getDefaultFields().map((field) => `${junctionField}.${field}`)
)
.map((fieldKey) => {
let field = fieldsStore.getField(junctionCollection, fieldKey);
if (!field) return null;
const header: Header = {
text: field.name,
value: fieldKey,
align: 'left',
sortable: true,
width: null,
field: {
display: field.meta?.display,
displayOptions: field.meta?.display_options,
interface: field.meta?.interface,
interfaceOptions: field.meta?.options,
type: field.type,
field: field.field,
},
};
return header;
})
.filter((h) => h) as Header[];
},
{ immediate: true }
);
function getDefaultFields(): string[] {
const fields = fieldsStore.getFieldsForCollection(relation.value.relationCollection);
return fields.slice(0, 3).map((field: Field) => field.field);
}
return { tableHeaders, items, loading, error };
}

View File

@@ -19,7 +19,7 @@
<template v-for="header in tableHeaders" v-slot:[`item.${header.value}`]="{ item }">
<render-display
:key="header.value"
:value="item[header.value]"
:value="get(item, header.value)"
:display="header.field.display"
:options="header.field.displayOptions"
:interface="header.field.interface"
@@ -74,6 +74,7 @@ import DrawerCollection from '@/views/private/components/drawer-collection';
import { Filter, Field } from '@/types';
import { Header, Sort } from '@/components/v-table/types';
import { isEqual, sortBy } from 'lodash';
import { get } from 'lodash';
export default defineComponent({
components: { DrawerItem, DrawerCollection },
@@ -136,6 +137,7 @@ export default defineComponent({
selectionFilters,
sort,
sortedItems,
get,
};
function getItem(id: string | number) {