mirror of
https://github.com/directus/directus.git
synced 2026-01-30 02:47:59 -05:00
finish junction support on m2m
This commit is contained in:
@@ -21,35 +21,32 @@
|
||||
:interface="header.field.interface"
|
||||
:interface-options="header.field.interfaceOptions"
|
||||
:type="header.field.type"
|
||||
:collection="relationFields.junctionCollection"
|
||||
:collection="relationInfo.junctionCollection"
|
||||
:field="header.field.field"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #item-append="{ item }" v-if="!disabled">
|
||||
<v-icon
|
||||
name="close"
|
||||
v-tooltip="$t('deselect')"
|
||||
class="deselect"
|
||||
@click.stop="deleteItem(item, items)"
|
||||
/>
|
||||
<v-icon name="close" v-tooltip="$t('deselect')" class="deselect" @click.stop="deleteItem(item)" />
|
||||
</template>
|
||||
</v-table>
|
||||
|
||||
<div class="actions" v-if="!disabled">
|
||||
<v-button class="new" @click="currentlyEditing = '+'">{{ $t('create_new') }}</v-button>
|
||||
<v-button class="new" @click="editModalActive = true">{{ $t('create_new') }}</v-button>
|
||||
<v-button class="existing" @click="selectModalActive = true">
|
||||
{{ $t('add_existing') }}
|
||||
</v-button>
|
||||
</div>
|
||||
|
||||
<pre>{{ JSON.stringify(value, null, 4) }}</pre>
|
||||
|
||||
<modal-item
|
||||
v-if="!disabled"
|
||||
:active="currentlyEditing !== null"
|
||||
:collection="relationFields.junctionCollection"
|
||||
:active="editModalActive"
|
||||
:collection="relationInfo.junctionCollection"
|
||||
:primary-key="currentlyEditing || '+'"
|
||||
:related-primary-key="relatedPrimaryKey || '+'"
|
||||
:junction-field="relationFields.junctionRelation"
|
||||
:junction-field="relationInfo.junctionField"
|
||||
:edits="editsAtStart"
|
||||
@input="stageEdits"
|
||||
@update:active="cancelEdit"
|
||||
@@ -114,7 +111,7 @@ export default defineComponent({
|
||||
emit('input', newVal);
|
||||
}
|
||||
|
||||
const { junction, junctionCollection, relation, relationCollection, relationFields } = useRelation(
|
||||
const { junction, junctionCollection, relation, relationCollection, relationInfo } = useRelation(
|
||||
collection,
|
||||
field
|
||||
);
|
||||
@@ -127,28 +124,32 @@ export default defineComponent({
|
||||
getNewSelectedItems,
|
||||
getJunctionItem,
|
||||
getJunctionFromRelatedId,
|
||||
} = useActions(value, relationFields, emitter);
|
||||
} = useActions(value, relationInfo, emitter);
|
||||
|
||||
const { tableHeaders, items, loading, error } = usePreview(
|
||||
value,
|
||||
fields,
|
||||
relationFields,
|
||||
relationInfo,
|
||||
getNewSelectedItems,
|
||||
getUpdatedItems,
|
||||
getNewItems,
|
||||
getPrimaryKeys
|
||||
);
|
||||
|
||||
const { currentlyEditing, editItem, editsAtStart, stageEdits, cancelEdit, relatedPrimaryKey } = useEdit(
|
||||
value,
|
||||
relationFields,
|
||||
emitter
|
||||
);
|
||||
const {
|
||||
currentlyEditing,
|
||||
editItem,
|
||||
editsAtStart,
|
||||
stageEdits,
|
||||
cancelEdit,
|
||||
relatedPrimaryKey,
|
||||
editModalActive,
|
||||
} = useEdit(value, relationInfo, emitter);
|
||||
|
||||
const { stageSelection, selectModalActive, selectionFilters } = useSelection(
|
||||
value,
|
||||
items,
|
||||
relationFields,
|
||||
relationInfo,
|
||||
emitter
|
||||
);
|
||||
|
||||
@@ -169,9 +170,10 @@ export default defineComponent({
|
||||
deleteItem,
|
||||
selectionFilters,
|
||||
items,
|
||||
relationFields,
|
||||
relationInfo,
|
||||
relatedPrimaryKey,
|
||||
get,
|
||||
editModalActive,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Ref } from '@vue/composition-api';
|
||||
import { RelationInfo } from './use-relation';
|
||||
import { get, has } from 'lodash';
|
||||
import { get, has, isEqual } from 'lodash';
|
||||
|
||||
export default function useActions(
|
||||
value: Ref<(string | number | Record<string, any>)[] | null>,
|
||||
@@ -19,31 +19,32 @@ export default function useActions(
|
||||
}
|
||||
|
||||
function getNewSelectedItems() {
|
||||
const { junctionRelation } = relation.value;
|
||||
const { junctionField } = relation.value;
|
||||
|
||||
if (value.value === null || junctionRelation === null) return [];
|
||||
if (value.value === null || junctionField === null) return [];
|
||||
|
||||
return value.value.filter(
|
||||
(item) => typeof item === 'object' && junctionRelation in item && typeof item[junctionRelation] !== 'object'
|
||||
(item) => typeof item === 'object' && junctionField in item && typeof item[junctionField] !== 'object'
|
||||
) as Record<string, any>[];
|
||||
}
|
||||
|
||||
function getNewItems() {
|
||||
const { junctionRelation, relationPkField } = relation.value;
|
||||
const { junctionField, relationPkField } = relation.value;
|
||||
|
||||
if (value.value === null || junctionRelation === null) return [];
|
||||
if (value.value === null || junctionField === null) return [];
|
||||
|
||||
return value.value.filter(
|
||||
(item) => has(item, junctionRelation) && has(item, [junctionRelation, relationPkField]) === false
|
||||
(item) =>
|
||||
typeof get(item, junctionField) === 'object' && has(item, [junctionField, relationPkField]) === false
|
||||
) as Record<string, any>[];
|
||||
}
|
||||
|
||||
function getUpdatedItems() {
|
||||
const { junctionRelation, relationPkField } = relation.value;
|
||||
const { junctionField, relationPkField } = relation.value;
|
||||
|
||||
if (value.value === null || junctionRelation === null) return [];
|
||||
if (value.value === null || junctionField === null) return [];
|
||||
|
||||
return value.value.filter((item) => has(item, [junctionRelation, relationPkField])) as Record<string, any>[];
|
||||
return value.value.filter((item) => has(item, [junctionField, relationPkField])) as Record<string, any>[];
|
||||
}
|
||||
|
||||
function getExistingItems() {
|
||||
@@ -57,112 +58,69 @@ export default function useActions(
|
||||
|
||||
if (value.value === null) return [];
|
||||
|
||||
return value.value
|
||||
.map((item) => {
|
||||
if (typeof item === 'object') {
|
||||
if (junctionPkField in item) return item[junctionPkField];
|
||||
} else {
|
||||
return item;
|
||||
}
|
||||
})
|
||||
.filter((i) => i);
|
||||
return value.value.reduce((acc: any[], item) => {
|
||||
const deepId = get(item, [junctionPkField]) as number | string | undefined;
|
||||
|
||||
if (['string', 'number'].includes(typeof item)) acc.push(item);
|
||||
else if (deepId !== undefined) acc.push(deepId);
|
||||
return acc;
|
||||
}, []) as (string | number)[];
|
||||
}
|
||||
|
||||
function getRelatedPrimaryKeys(): (string | number)[] {
|
||||
function getRelatedPrimaryKeys() {
|
||||
if (value.value === null) return [];
|
||||
const { junctionRelation, relationPkField } = relation.value;
|
||||
return value.value
|
||||
.map((junctionItem) => {
|
||||
if (
|
||||
typeof junctionItem !== 'object' ||
|
||||
junctionRelation === null ||
|
||||
junctionRelation in junctionItem === false
|
||||
)
|
||||
return undefined;
|
||||
const item = junctionItem[junctionRelation];
|
||||
|
||||
const { junctionField, relationPkField } = relation.value;
|
||||
|
||||
return value.value.reduce((acc: any[], item) => {
|
||||
const relatedId = get(item, junctionField) as number | string | undefined;
|
||||
const deepRelatedId = get(item, [junctionField, relationPkField]) as number | string | undefined;
|
||||
|
||||
if (relatedId !== undefined) acc.push(relatedId);
|
||||
else if (deepRelatedId !== undefined) acc.push(deepRelatedId);
|
||||
return acc;
|
||||
}, []) as (string | number)[];
|
||||
}
|
||||
|
||||
function deleteItem(deletingItem: Record<string, any>) {
|
||||
if (value.value === null) return;
|
||||
const { junctionField, relationPkField, junctionPkField } = relation.value;
|
||||
|
||||
const junctionId = get(deletingItem, junctionPkField) as number | string | undefined;
|
||||
const relatedId = get(deletingItem, [junctionField, relationPkField]) as number | string | undefined;
|
||||
|
||||
console.log(junctionId, relatedId);
|
||||
|
||||
const newValue = value.value.filter((item) => {
|
||||
if (junctionId !== undefined) {
|
||||
if (typeof item === 'object') {
|
||||
if (junctionRelation in item) return item[relationPkField];
|
||||
return get(item, [junctionPkField]) !== junctionId;
|
||||
} else {
|
||||
return item;
|
||||
return item !== junctionId;
|
||||
}
|
||||
})
|
||||
.filter((i) => i);
|
||||
}
|
||||
|
||||
function deleteItem(item: Record<string, any>, items: Record<string, any>[]) {
|
||||
if (value.value === null) return;
|
||||
const { junctionRelation, relationPkField } = relation.value;
|
||||
|
||||
const id = item[relationPkField] as number | string | undefined;
|
||||
|
||||
if (id !== undefined) return deleteItemWithId(id, items);
|
||||
if (junctionRelation === null) return;
|
||||
|
||||
const newVal = value.value.filter((junctionItem) => {
|
||||
if (typeof junctionItem !== 'object' || junctionRelation in junctionItem === false) return true;
|
||||
return junctionItem[junctionRelation] !== item;
|
||||
});
|
||||
|
||||
if (newVal.length === 0) emit(null);
|
||||
else emit(newVal);
|
||||
}
|
||||
|
||||
function deleteItemWithId(id: string | number, items: Record<string, any>[]) {
|
||||
if (value.value === null) return;
|
||||
const { junctionRelation, relationPkField, junctionPkField } = relation.value;
|
||||
|
||||
const junctionItem = items.find(
|
||||
(item) =>
|
||||
junctionRelation in item &&
|
||||
relationPkField in item[junctionRelation] &&
|
||||
item[junctionRelation][relationPkField] === id
|
||||
);
|
||||
|
||||
if (junctionItem === undefined) return;
|
||||
|
||||
// If it is a newly selected Item
|
||||
if (junctionPkField in junctionItem === false) {
|
||||
const newVal = value.value.filter((item) => {
|
||||
if (typeof item === 'object' && junctionRelation in item) {
|
||||
const jItem = item[junctionRelation];
|
||||
return typeof jItem === 'object' ? jItem[relationPkField] !== id : jItem !== id;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (newVal.length === 0) emit(null);
|
||||
else emit(newVal);
|
||||
return;
|
||||
}
|
||||
|
||||
// If it is an already existing item
|
||||
const newVal = value.value.filter((item) => {
|
||||
if (typeof item === 'object' && junctionPkField in item) {
|
||||
return junctionItem[junctionPkField] !== item[junctionPkField];
|
||||
} else {
|
||||
return junctionItem[junctionPkField] !== item;
|
||||
}
|
||||
});
|
||||
|
||||
if (newVal.length === 0) emit(null);
|
||||
else emit(newVal);
|
||||
if (relatedId !== undefined) {
|
||||
const itemRelatedId = get(item, [junctionField, relationPkField]);
|
||||
if (['string', 'number'].includes(typeof itemRelatedId)) {
|
||||
return itemRelatedId !== relatedId;
|
||||
}
|
||||
|
||||
const junctionFieldId = get(item, [junctionField]);
|
||||
if (['string', 'number'].includes(typeof junctionFieldId)) {
|
||||
return junctionFieldId !== relatedId;
|
||||
}
|
||||
}
|
||||
|
||||
return isEqual(item, deletingItem) === false;
|
||||
});
|
||||
emit(newValue);
|
||||
}
|
||||
|
||||
function getJunctionFromRelatedId(id: string | number, items: Record<string, any>[]) {
|
||||
const { relationPkField, junctionRelation } = relation.value;
|
||||
const { relationPkField, junctionField } = relation.value;
|
||||
|
||||
return (
|
||||
items.find((item) => {
|
||||
return (
|
||||
typeof item === 'object' &&
|
||||
junctionRelation in item &&
|
||||
typeof item[junctionRelation] === 'object' &&
|
||||
relationPkField in item[junctionRelation] &&
|
||||
item[junctionRelation][relationPkField] === id
|
||||
);
|
||||
}) || null
|
||||
);
|
||||
return items.find((item) => get(item, [junctionField, relationPkField]) === id) || null;
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -175,6 +133,5 @@ export default function useActions(
|
||||
getRelatedPrimaryKeys,
|
||||
getJunctionFromRelatedId,
|
||||
deleteItem,
|
||||
deleteItemWithId,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,8 +7,7 @@ export default function useEdit(
|
||||
relation: Ref<RelationInfo>,
|
||||
emit: (newVal: any[] | null) => void
|
||||
) {
|
||||
// Primary key of the item we're currently editing. If null, the edit modal should be
|
||||
// closed
|
||||
const editModalActive = ref(false);
|
||||
const currentlyEditing = ref<string | number | null>(null);
|
||||
const relatedPrimaryKey = ref<string | number | null>(null);
|
||||
|
||||
@@ -16,15 +15,16 @@ export default function useEdit(
|
||||
const editsAtStart = ref<Record<string, any>>({});
|
||||
|
||||
function editItem(item: any) {
|
||||
const { relationPkField, junctionRelation, junctionPkField } = relation.value;
|
||||
const { relationPkField, junctionField, junctionPkField } = relation.value;
|
||||
|
||||
editModalActive.value = true;
|
||||
editsAtStart.value = item;
|
||||
relatedPrimaryKey.value = get(item, [junctionRelation, relationPkField], null);
|
||||
currentlyEditing.value = get(item, [junctionPkField], null);
|
||||
relatedPrimaryKey.value = get(item, [junctionField, relationPkField], null);
|
||||
}
|
||||
|
||||
function stageEdits(edits: any) {
|
||||
const { relationPkField, junctionRelation, junctionPkField } = relation.value;
|
||||
const { relationPkField, junctionField, junctionPkField } = relation.value;
|
||||
|
||||
const newValue = (value.value || []).map((item) => {
|
||||
if (currentlyEditing.value !== null) {
|
||||
@@ -40,8 +40,8 @@ export default function useEdit(
|
||||
if (relatedPrimaryKey.value != null) {
|
||||
const id = relatedPrimaryKey.value;
|
||||
|
||||
if (get(item, [junctionRelation], null) === id) return edits;
|
||||
if (get(item, [junctionRelation, relationPkField], null) === id) return edits;
|
||||
if (get(item, [junctionField], null) === id) return edits;
|
||||
if (get(item, [junctionField, relationPkField], null) === id) return edits;
|
||||
}
|
||||
|
||||
if (isEqual(editsAtStart.value, item)) {
|
||||
@@ -57,13 +57,16 @@ export default function useEdit(
|
||||
|
||||
if (newValue.length === 0) emit(null);
|
||||
else emit(newValue);
|
||||
|
||||
cancelEdit();
|
||||
}
|
||||
|
||||
function cancelEdit() {
|
||||
editModalActive.value = false;
|
||||
editsAtStart.value = {};
|
||||
currentlyEditing.value = null;
|
||||
relatedPrimaryKey.value = null;
|
||||
}
|
||||
|
||||
return { currentlyEditing, editItem, editsAtStart, stageEdits, cancelEdit, relatedPrimaryKey };
|
||||
return { currentlyEditing, editItem, editsAtStart, stageEdits, cancelEdit, relatedPrimaryKey, editModalActive };
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { RelationInfo } from './use-relation';
|
||||
import { useFieldsStore } from '@/stores/';
|
||||
import { Field, Collection } from '@/types';
|
||||
import api from '@/api';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { cloneDeep, get } from 'lodash';
|
||||
|
||||
export default function usePreview(
|
||||
value: Ref<(string | number | Record<string, any>)[] | null>,
|
||||
@@ -25,14 +25,13 @@ export default function usePreview(
|
||||
const error = ref(null);
|
||||
|
||||
function getRelatedFields(fields: string[]) {
|
||||
const { junctionRelation } = relation.value;
|
||||
const { junctionField } = relation.value;
|
||||
|
||||
return fields
|
||||
.map((field) => {
|
||||
const sections = field.split('.');
|
||||
if (junctionRelation === sections[0] && sections.length === 2) return sections[1];
|
||||
})
|
||||
.filter((i) => i);
|
||||
return fields.reduce((acc: string[], field) => {
|
||||
const sections = field.split('.');
|
||||
if (junctionField === sections[0] && sections.length === 2) acc.push(sections[1]);
|
||||
return acc;
|
||||
}, []);
|
||||
}
|
||||
|
||||
function getJunctionFields() {
|
||||
@@ -48,12 +47,17 @@ export default function usePreview(
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
const { junctionRelation, relationPkField, junctionPkField } = relation.value;
|
||||
if (junctionRelation === null) return;
|
||||
const { junctionField, relationPkField, junctionPkField, relationCollection } = relation.value;
|
||||
if (junctionField === null) return;
|
||||
|
||||
// Load the junction items so we have access to the id's in the related collection
|
||||
const junctionItems = await loadRelatedIds();
|
||||
const relatedPrimaryKeys = junctionItems.map((junction) => junction[junctionRelation]);
|
||||
|
||||
const relatedPrimaryKeys = junctionItems.reduce((acc, junction) => {
|
||||
const id = get(junction, junctionField);
|
||||
if (id !== null) acc.push(id);
|
||||
return acc;
|
||||
}, []) as (string | number)[];
|
||||
|
||||
const filteredFields = [...(fields.value.length > 0 ? getRelatedFields(fields.value) : getDefaultFields())];
|
||||
|
||||
@@ -63,35 +67,36 @@ export default function usePreview(
|
||||
let responseData: Record<string, any>[] = [];
|
||||
|
||||
if (relatedPrimaryKeys.length > 0) {
|
||||
const endpoint = relation.value.relationCollection.startsWith('directus_')
|
||||
? `/${relation.value.relationCollection.substring(9)}`
|
||||
: `/items/${relation.value.relationCollection}`;
|
||||
|
||||
const response = await api.get(endpoint, {
|
||||
params: {
|
||||
fields: filteredFields,
|
||||
[`filter[${relationPkField}][_in]`]: relatedPrimaryKeys.join(','),
|
||||
},
|
||||
});
|
||||
responseData = response?.data.data as Record<string, any>[];
|
||||
responseData = await request(
|
||||
relationCollection,
|
||||
filteredFields,
|
||||
relationPkField,
|
||||
relatedPrimaryKeys
|
||||
);
|
||||
}
|
||||
|
||||
console.log('responseData1', responseData);
|
||||
// Insert the related items into the junction items
|
||||
const existingItems = responseData.map((data) => {
|
||||
const id = data[relationPkField];
|
||||
const junction = junctionItems.find((junction) => junction[junctionRelation] === id);
|
||||
if (junction === undefined) return;
|
||||
responseData = responseData.map((data) => {
|
||||
const id = get(data, relationPkField);
|
||||
const junction = junctionItems.find((junction) => junction[junctionField] === id);
|
||||
|
||||
if (junction === undefined || id === undefined) return;
|
||||
|
||||
const newJunction = cloneDeep(junction);
|
||||
newJunction[junctionRelation] = data;
|
||||
newJunction[junctionField] = data;
|
||||
return newJunction;
|
||||
}) as Record<string, any>[];
|
||||
|
||||
const updatedItems = getUpdatedItems();
|
||||
const newItems = getNewItems();
|
||||
|
||||
console.log('updatedItems', updatedItems);
|
||||
console.log('newItems', newItems);
|
||||
console.log('responseData2', responseData);
|
||||
|
||||
// Replace existing items with it's updated counterparts
|
||||
const newVal = existingItems
|
||||
responseData = responseData
|
||||
.map((item) => {
|
||||
const updatedItem = updatedItems.find(
|
||||
(updated) => updated[junctionPkField] === item[junctionPkField]
|
||||
@@ -100,7 +105,9 @@ export default function usePreview(
|
||||
return item;
|
||||
})
|
||||
.concat(...newItems);
|
||||
items.value = newVal;
|
||||
|
||||
console.log('responseData3', responseData);
|
||||
items.value = responseData;
|
||||
} catch (err) {
|
||||
error.value = err;
|
||||
} finally {
|
||||
@@ -111,33 +118,24 @@ export default function usePreview(
|
||||
);
|
||||
|
||||
async function loadRelatedIds() {
|
||||
const { junctionPkField, junctionRelation, relationPkField } = relation.value;
|
||||
const { junctionPkField, junctionField, relationPkField, junctionCollection } = relation.value;
|
||||
|
||||
try {
|
||||
let data: Record<string, any>[] = [];
|
||||
const primaryKeys = getPrimaryKeys();
|
||||
console.log('PKS', primaryKeys);
|
||||
|
||||
if (primaryKeys.length > 0) {
|
||||
const filteredFields = getJunctionFields();
|
||||
|
||||
if (filteredFields.includes(junctionPkField) === false) filteredFields.push(junctionPkField);
|
||||
if (filteredFields.includes(junctionRelation) === false) filteredFields.push(junctionRelation);
|
||||
if (filteredFields.includes(junctionField) === false) filteredFields.push(junctionField);
|
||||
|
||||
const endpoint = relation.value.junctionCollection.startsWith('directus_')
|
||||
? `/${relation.value.junctionCollection.substring(9)}`
|
||||
: `/items/${relation.value.junctionCollection}`;
|
||||
|
||||
const response = await api.get(endpoint, {
|
||||
params: {
|
||||
fields: filteredFields,
|
||||
[`filter[${junctionPkField}][_in]`]: getPrimaryKeys().join(','),
|
||||
},
|
||||
});
|
||||
data = response?.data.data as Record<string, any>[];
|
||||
data = await request(junctionCollection, filteredFields, junctionPkField, primaryKeys);
|
||||
}
|
||||
|
||||
const updatedItems = getUpdatedItems().map((item) => ({
|
||||
[junctionRelation]: item[junctionRelation][relationPkField],
|
||||
[junctionField]: item[junctionField][relationPkField],
|
||||
}));
|
||||
|
||||
// Add all items that already had the id of it's related item
|
||||
@@ -148,16 +146,35 @@ export default function usePreview(
|
||||
return [];
|
||||
}
|
||||
|
||||
async function request(
|
||||
collection: string,
|
||||
fields: string[] | null,
|
||||
filteredField: string,
|
||||
primaryKeys: (string | number)[] | null
|
||||
) {
|
||||
if (fields === null || fields.length === 0 || primaryKeys === null || primaryKeys.length === 0) return [];
|
||||
|
||||
const endpoint = collection.startsWith('directus_') ? `/${collection.substring(9)}` : `/items/${collection}`;
|
||||
|
||||
const response = await api.get(endpoint, {
|
||||
params: {
|
||||
fields: fields,
|
||||
[`filter[${filteredField}][_in]`]: primaryKeys.join(','),
|
||||
},
|
||||
});
|
||||
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 { junctionRelation, junctionCollection } = relation.value;
|
||||
const { junctionField, junctionCollection } = relation.value;
|
||||
|
||||
tableHeaders.value = (fields.value.length > 0
|
||||
? fields.value
|
||||
: getDefaultFields().map((field) => `${junctionRelation}.${field}`)
|
||||
: getDefaultFields().map((field) => `${junctionField}.${field}`)
|
||||
)
|
||||
.map((fieldKey) => {
|
||||
let field = fieldsStore.getField(junctionCollection, fieldKey);
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Relation } from '@/types';
|
||||
export type RelationInfo = {
|
||||
junctionPkField: string;
|
||||
relationPkField: string;
|
||||
junctionRelation: string;
|
||||
junctionField: string;
|
||||
junctionCollection: string;
|
||||
relationCollection: string;
|
||||
};
|
||||
@@ -38,11 +38,11 @@ export default function useRelation(collection: Ref<string>, field: Ref<string>)
|
||||
const { primaryKeyField: junctionPrimaryKeyField } = useCollection(junctionCollection.value.collection);
|
||||
const { primaryKeyField: relationPrimaryKeyField } = useCollection(relationCollection.value.collection);
|
||||
|
||||
const relationFields = computed(() => {
|
||||
const relationInfo = computed(() => {
|
||||
return {
|
||||
junctionPkField: junctionPrimaryKeyField.value.field,
|
||||
relationPkField: relationPrimaryKeyField.value.field,
|
||||
junctionRelation: junction.value.junction_field as string,
|
||||
junctionField: junction.value.junction_field as string,
|
||||
junctionCollection: junctionCollection.value.collection,
|
||||
relationCollection: relationCollection.value.collection,
|
||||
} as RelationInfo;
|
||||
@@ -53,7 +53,7 @@ export default function useRelation(collection: Ref<string>, field: Ref<string>)
|
||||
junctionCollection,
|
||||
relation,
|
||||
relationCollection,
|
||||
relationFields,
|
||||
relationInfo,
|
||||
junctionPrimaryKeyField,
|
||||
relationPrimaryKeyField,
|
||||
};
|
||||
|
||||
@@ -14,11 +14,13 @@ export default function useSelection(
|
||||
const selectedPrimaryKeys = computed(() => {
|
||||
if (items.value === null) return [];
|
||||
|
||||
const { relationPkField, junctionRelation } = relation.value;
|
||||
const { relationPkField, junctionField } = relation.value;
|
||||
|
||||
const selectedKeys: (number | string)[] = items.value
|
||||
.map((currentItem) => get(currentItem, [junctionRelation, relationPkField]))
|
||||
.filter((i) => i);
|
||||
const selectedKeys = items.value.reduce((acc, current) => {
|
||||
const key = get(current, [junctionField, relationPkField]);
|
||||
if (key !== undefined) acc.push(key);
|
||||
return acc;
|
||||
}, []) as (number | string)[];
|
||||
|
||||
return selectedKeys;
|
||||
});
|
||||
@@ -40,7 +42,12 @@ export default function useSelection(
|
||||
});
|
||||
|
||||
function stageSelection(newSelection: (number | string)[]) {
|
||||
const selection = newSelection.filter((item) => selectedPrimaryKeys.value.includes(item) === false);
|
||||
const { junctionField } = relation.value;
|
||||
|
||||
const selection = newSelection.reduce((acc, item) => {
|
||||
if (selectedPrimaryKeys.value.includes(item) === false) acc.push({ [junctionField]: item });
|
||||
return acc;
|
||||
}, new Array());
|
||||
|
||||
const newVal = [...selection, ...(value.value || [])];
|
||||
if (newVal.length === 0) emit(null);
|
||||
|
||||
Reference in New Issue
Block a user