mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
Move sortField to relationship setup (#4304)
* Add migration * Add sort field to relation types * Remove sortfield options in favor of relationship * Add sort field configuration to relational setup * Save m2a sortfield on the correct row * Add default sort field to system data
This commit is contained in:
@@ -192,13 +192,47 @@
|
||||
<v-icon class="arrow" name="arrow_backward" />
|
||||
</div>
|
||||
|
||||
<div class="sort-field">
|
||||
<v-divider large :inline-title="false">{{ $t('sort_field') }}</v-divider>
|
||||
|
||||
<v-input
|
||||
:class="{ matches: junctionFieldExists(relations[0].sort_field) }"
|
||||
v-model="relations[0].sort_field"
|
||||
:nullable="false"
|
||||
:placeholder="$t('add_sort_field') + '...'"
|
||||
db-safe
|
||||
>
|
||||
<template #append v-if="junctionCollectionExists">
|
||||
<v-menu show-arrow placement="bottom-end">
|
||||
<template #activator="{ toggle }">
|
||||
<v-icon name="list_alt" @click="toggle" v-tooltip="$t('select_existing')" />
|
||||
</template>
|
||||
|
||||
<v-list class="monospace">
|
||||
<v-list-item
|
||||
v-for="item in junctionFields"
|
||||
:key="item.value"
|
||||
:active="relations[0].sort_field === item.value"
|
||||
:disabled="item.disabled"
|
||||
@click="relations[0].sort_field = item.value"
|
||||
>
|
||||
<v-list-item-content>
|
||||
{{ item.text }}
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</template>
|
||||
</v-input>
|
||||
</div>
|
||||
|
||||
<v-notice class="generated-data" v-if="generationInfo.length > 0" type="warning">
|
||||
<span>
|
||||
{{ $t('new_data_alert') }}
|
||||
<ul>
|
||||
<li v-for="(data, index) in generationInfo" :key="index">
|
||||
<span class="field-name">{{ data.name }}</span>
|
||||
({{ $t(data.isField ? 'new_field' : 'new_collection') }})
|
||||
({{ $t(data.type === 'field' ? 'new_field' : 'new_collection') }})
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
@@ -207,13 +241,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed, ref } from '@vue/composition-api';
|
||||
import { defineComponent, computed } from '@vue/composition-api';
|
||||
import { orderBy } from 'lodash';
|
||||
import { useCollectionsStore, useFieldsStore } from '@/stores/';
|
||||
import { Field } from '@/types';
|
||||
import i18n from '@/lang';
|
||||
|
||||
import { state } from '../store';
|
||||
import { state, generationInfo } from '../store';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@@ -230,7 +263,7 @@ export default defineComponent({
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
setup() {
|
||||
const collectionsStore = useCollectionsStore();
|
||||
const fieldsStore = useFieldsStore();
|
||||
|
||||
@@ -290,38 +323,6 @@ export default defineComponent({
|
||||
}));
|
||||
});
|
||||
|
||||
const generationInfo = computed(() => {
|
||||
const message: { name: string; isField: boolean }[] = [];
|
||||
|
||||
if (state.relations[0].many_collection) {
|
||||
if (junctionCollectionExists.value === false)
|
||||
message.push({ name: state.relations[0].many_collection, isField: false });
|
||||
|
||||
if (junctionFieldExists(state.relations[0].many_field) === false && state.relations[0].many_field !== '')
|
||||
message.push({
|
||||
name: state.relations[0].many_collection + '.' + state.relations[0].many_field,
|
||||
isField: true,
|
||||
});
|
||||
|
||||
if (
|
||||
junctionFieldExists(state.relations[1].one_collection_field) === false &&
|
||||
state.relations[1].one_collection_field !== ''
|
||||
)
|
||||
message.push({
|
||||
name: state.relations[0].many_collection + '.' + state.relations[1].one_collection_field,
|
||||
isField: true,
|
||||
});
|
||||
|
||||
if (junctionFieldExists(state.relations[1].many_field) === false && state.relations[1].many_field !== '')
|
||||
message.push({
|
||||
name: state.relations[0].many_collection + '.' + state.relations[1].many_field,
|
||||
isField: true,
|
||||
});
|
||||
}
|
||||
|
||||
return message;
|
||||
});
|
||||
|
||||
return {
|
||||
relations: state.relations,
|
||||
autoFill,
|
||||
@@ -353,10 +354,6 @@ export default defineComponent({
|
||||
gap: 12px 28px;
|
||||
margin-top: 48px;
|
||||
|
||||
.v-input.matches {
|
||||
--v-input-color: var(--primary);
|
||||
}
|
||||
|
||||
.v-icon.arrow {
|
||||
--v-icon-color: var(--primary);
|
||||
|
||||
@@ -381,6 +378,10 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
.v-input.matches {
|
||||
--v-input-color: var(--primary);
|
||||
}
|
||||
|
||||
.type-label {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
@@ -407,8 +408,8 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
.related-collections-preview {
|
||||
grid-row: 2 / span 2;
|
||||
grid-column: 3;
|
||||
grid-row: 2 / span 2;
|
||||
padding: var(--input-padding);
|
||||
overflow: auto;
|
||||
color: var(--foreground-subdued);
|
||||
@@ -421,4 +422,13 @@ export default defineComponent({
|
||||
.one-collection-field {
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.sort-field {
|
||||
--v-input-font-family: var(--family-monospace);
|
||||
|
||||
.v-divider {
|
||||
margin-top: 48px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -219,6 +219,40 @@
|
||||
<v-icon name="arrow_forward" class="arrow" />
|
||||
</div>
|
||||
|
||||
<div class="sort-field">
|
||||
<v-divider large :inline-title="false">{{ $t('sort_field') }}</v-divider>
|
||||
|
||||
<v-input
|
||||
:class="{ matches: junctionFieldExists(relations[0].sort_field) }"
|
||||
v-model="relations[0].sort_field"
|
||||
:nullable="false"
|
||||
:placeholder="$t('add_sort_field') + '...'"
|
||||
db-safe
|
||||
>
|
||||
<template #append v-if="junctionCollectionExists">
|
||||
<v-menu show-arrow placement="bottom-end">
|
||||
<template #activator="{ toggle }">
|
||||
<v-icon name="list_alt" @click="toggle" v-tooltip="$t('select_existing')" />
|
||||
</template>
|
||||
|
||||
<v-list class="monospace">
|
||||
<v-list-item
|
||||
v-for="item in junctionFields"
|
||||
:key="item.value"
|
||||
:active="relations[0].sort_field === item.value"
|
||||
:disabled="item.disabled"
|
||||
@click="relations[0].sort_field = item.value"
|
||||
>
|
||||
<v-list-item-content>
|
||||
{{ item.text }}
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</template>
|
||||
</v-input>
|
||||
</div>
|
||||
|
||||
<v-notice class="generated-data" v-if="generationInfo.length > 0" type="warning">
|
||||
<span>
|
||||
{{ $t('new_data_alert') }}
|
||||
@@ -226,7 +260,7 @@
|
||||
<ul>
|
||||
<li v-for="(data, index) in generationInfo" :key="index">
|
||||
<span class="field-name">{{ data.name }}</span>
|
||||
({{ $t(data.isField ? 'new_field' : 'new_collection') }})
|
||||
({{ $t(data.type === 'field' ? 'new_field' : 'new_collection') }})
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
@@ -235,13 +269,13 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed, ref } from '@vue/composition-api';
|
||||
import { defineComponent, computed } from '@vue/composition-api';
|
||||
import { orderBy } from 'lodash';
|
||||
import { useCollectionsStore, useFieldsStore } from '@/stores/';
|
||||
import { Field } from '@/types';
|
||||
import i18n from '@/lang';
|
||||
|
||||
import { state } from '../store';
|
||||
import { state, generationInfo } from '../store';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@@ -324,44 +358,6 @@ export default defineComponent({
|
||||
|
||||
const { hasCorresponding, correspondingField, correspondingLabel } = useCorresponding();
|
||||
|
||||
const generationInfo = computed(() => {
|
||||
const message: { name: string; isField: boolean }[] = [];
|
||||
|
||||
if (state.relations[1].one_collection !== '') {
|
||||
if (relatedCollectionExists.value === false) {
|
||||
message.push({ name: state.relations[1].one_collection, isField: false });
|
||||
|
||||
if (state.relations[1].one_primary !== '')
|
||||
message.push({
|
||||
name: state.relations[1].one_collection + '.' + state.relations[1].one_primary,
|
||||
isField: true,
|
||||
});
|
||||
}
|
||||
|
||||
if (hasCorresponding.value === true && correspondingField.value !== null)
|
||||
message.push({ name: state.relations[1].one_collection + '.' + correspondingField.value, isField: true });
|
||||
}
|
||||
|
||||
if (state.relations[0].many_collection) {
|
||||
if (junctionCollectionExists.value === false)
|
||||
message.push({ name: state.relations[0].many_collection, isField: false });
|
||||
|
||||
if (junctionFieldExists(state.relations[0].many_field) === false && state.relations[0].many_field !== '')
|
||||
message.push({
|
||||
name: state.relations[0].many_collection + '.' + state.relations[0].many_field,
|
||||
isField: true,
|
||||
});
|
||||
|
||||
if (junctionFieldExists(state.relations[1].many_field) === false && state.relations[1].many_field !== '')
|
||||
message.push({
|
||||
name: state.relations[0].many_collection + '.' + state.relations[1].many_field,
|
||||
isField: true,
|
||||
});
|
||||
}
|
||||
|
||||
return message;
|
||||
});
|
||||
|
||||
return {
|
||||
relations: state.relations,
|
||||
autoFill,
|
||||
@@ -379,7 +375,7 @@ export default defineComponent({
|
||||
};
|
||||
|
||||
function junctionFieldExists(fieldKey: string) {
|
||||
if (!junctionCollection.value) return false;
|
||||
if (!junctionCollection.value || !fieldKey) return false;
|
||||
return !!fieldsStore.getField(junctionCollection.value, fieldKey);
|
||||
}
|
||||
|
||||
@@ -457,10 +453,6 @@ export default defineComponent({
|
||||
gap: 12px 28px;
|
||||
margin-top: 48px;
|
||||
|
||||
.v-input.matches {
|
||||
--v-input-color: var(--primary);
|
||||
}
|
||||
|
||||
.v-icon.arrow {
|
||||
--v-icon-color: var(--primary);
|
||||
|
||||
@@ -480,12 +472,16 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
.v-input.matches {
|
||||
--v-input-color: var(--primary);
|
||||
}
|
||||
|
||||
.type-label {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.v-divider {
|
||||
margin: 48px 0;
|
||||
margin: 48px 0 24px;
|
||||
}
|
||||
|
||||
.v-list {
|
||||
@@ -497,7 +493,6 @@ export default defineComponent({
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 12px 32px;
|
||||
margin-top: 48px;
|
||||
|
||||
.arrow {
|
||||
--v-icon-color: var(--primary);
|
||||
@@ -525,4 +520,13 @@ export default defineComponent({
|
||||
font-family: var(--family-monospace);
|
||||
}
|
||||
}
|
||||
|
||||
.sort-field {
|
||||
--v-input-font-family: var(--family-monospace);
|
||||
|
||||
.v-divider {
|
||||
margin-top: 48px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
<ul>
|
||||
<li v-for="(data, index) in generationInfo" :key="index">
|
||||
<span class="field-name">{{ data.name }}</span>
|
||||
({{ $t(data.isField ? 'new_field' : 'new_collection') }})
|
||||
({{ $t(data.type === 'field' ? 'new_field' : 'new_collection') }})
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
@@ -102,15 +102,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed, watch } from '@vue/composition-api';
|
||||
import { Relation } from '@/types';
|
||||
import { Field } from '@/types';
|
||||
import { defineComponent, computed } from '@vue/composition-api';
|
||||
import { orderBy } from 'lodash';
|
||||
import useSync from '@/composables/use-sync';
|
||||
import { useCollectionsStore, useFieldsStore } from '@/stores';
|
||||
import { useCollectionsStore } from '@/stores';
|
||||
import i18n from '@/lang';
|
||||
|
||||
import { state } from '../store';
|
||||
import { state, generationInfo } from '../store';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@@ -127,9 +124,8 @@ export default defineComponent({
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
setup() {
|
||||
const collectionsStore = useCollectionsStore();
|
||||
const fieldsStore = useFieldsStore();
|
||||
|
||||
const { availableCollections, systemCollections } = useRelation();
|
||||
const { hasCorresponding, correspondingField, correspondingLabel } = useCorresponding();
|
||||
@@ -138,30 +134,6 @@ export default defineComponent({
|
||||
return !!collectionsStore.getCollection(state.relations[0].one_collection);
|
||||
});
|
||||
|
||||
const generationInfo = computed(() => {
|
||||
const message: { name: string; isField: boolean }[] = [];
|
||||
|
||||
if (relatedCollectionExists.value === false && state.relations[0].one_collection !== '') {
|
||||
message.push({ name: state.relations[0].one_collection, isField: false });
|
||||
|
||||
if (state.relations[0].one_primary !== '')
|
||||
message.push({
|
||||
name: state.relations[0].one_collection + '.' + state.relations[0].one_primary,
|
||||
isField: true,
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
hasCorresponding.value === true &&
|
||||
state.relations[0].one_collection !== '' &&
|
||||
correspondingField.value !== null
|
||||
) {
|
||||
message.push({ name: state.relations[0].one_collection + '.' + correspondingField.value, isField: true });
|
||||
}
|
||||
|
||||
return message;
|
||||
});
|
||||
|
||||
return {
|
||||
relations: state.relations,
|
||||
availableCollections,
|
||||
|
||||
@@ -103,6 +103,40 @@
|
||||
<v-icon name="arrow_forward" class="arrow" />
|
||||
</div>
|
||||
|
||||
<div class="sort-field">
|
||||
<v-divider large :inline-title="false">{{ $t('sort_field') }}</v-divider>
|
||||
|
||||
<v-input
|
||||
:class="{ matches: sortFieldExists }"
|
||||
v-model="relations[0].sort_field"
|
||||
:nullable="false"
|
||||
:placeholder="$t('add_sort_field') + '...'"
|
||||
db-safe
|
||||
>
|
||||
<template #append v-if="fields && fields.length > 0">
|
||||
<v-menu show-arrow placement="bottom-end">
|
||||
<template #activator="{ toggle }">
|
||||
<v-icon name="list_alt" @click="toggle" v-tooltip="$t('select_existing')" />
|
||||
</template>
|
||||
|
||||
<v-list class="monospace">
|
||||
<v-list-item
|
||||
v-for="item in fields"
|
||||
:key="item.value"
|
||||
:active="relations[0].sort_field === item.value"
|
||||
:disabled="item.disabled"
|
||||
@click="relations[0].sort_field = item.value"
|
||||
>
|
||||
<v-list-item-content>
|
||||
{{ item.text }}
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</template>
|
||||
</v-input>
|
||||
</div>
|
||||
|
||||
<v-notice class="generated-data" v-if="generationInfo.length > 0" type="warning">
|
||||
<span>
|
||||
{{ $t('new_data_alert') }}
|
||||
@@ -110,7 +144,7 @@
|
||||
<ul>
|
||||
<li v-for="(data, index) in generationInfo" :key="index">
|
||||
<span class="field-name">{{ data.name }}</span>
|
||||
({{ $t(data.isField ? 'new_field' : 'new_collection') }})
|
||||
({{ $t(data.type === 'field' ? 'new_field' : 'new_collection') }})
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
@@ -119,13 +153,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType, computed } from '@vue/composition-api';
|
||||
import { Relation, Field } from '@/types';
|
||||
import useSync from '@/composables/use-sync';
|
||||
import { defineComponent, computed } from '@vue/composition-api';
|
||||
import { Field } from '@/types';
|
||||
import { useFieldsStore, useCollectionsStore } from '@/stores';
|
||||
import { orderBy } from 'lodash';
|
||||
import i18n from '@/lang';
|
||||
import { state } from '../store';
|
||||
import { state, generationInfo } from '../store';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@@ -142,7 +175,7 @@ export default defineComponent({
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
setup(props) {
|
||||
const collectionsStore = useCollectionsStore();
|
||||
const fieldsStore = useFieldsStore();
|
||||
|
||||
@@ -167,22 +200,9 @@ export default defineComponent({
|
||||
return !!fieldsStore.getField(state.relations[0].many_collection, state.relations[0].many_field);
|
||||
});
|
||||
|
||||
const generationInfo = computed(() => {
|
||||
const message: { name: string; isField: boolean }[] = [];
|
||||
|
||||
if (state.relations[0].many_collection !== '') {
|
||||
if (relatedCollectionExists.value === false)
|
||||
message.push({ name: state.relations[0].many_collection, isField: false });
|
||||
|
||||
if (relatedFieldExists.value === false && state.relations[0].many_field !== '') {
|
||||
message.push({
|
||||
name: state.relations[0].many_collection + '.' + state.relations[0].many_field,
|
||||
isField: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
const sortFieldExists = computed(() => {
|
||||
if (!state?.relations?.[0].many_collection || !state?.relations?.[0].sort_field) return false;
|
||||
return !!fieldsStore.getField(state.relations[0].many_collection, state.relations[0].sort_field);
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -197,6 +217,7 @@ export default defineComponent({
|
||||
relatedCollectionExists,
|
||||
relatedFieldExists,
|
||||
generationInfo,
|
||||
sortFieldExists,
|
||||
};
|
||||
|
||||
function useRelation() {
|
||||
@@ -355,10 +376,6 @@ export default defineComponent({
|
||||
gap: 12px 32px;
|
||||
margin-top: 48px;
|
||||
|
||||
.v-input.matches {
|
||||
--v-input-color: var(--primary);
|
||||
}
|
||||
|
||||
.v-icon.arrow {
|
||||
--v-icon-color: var(--primary);
|
||||
|
||||
@@ -369,6 +386,10 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
.v-input.matches {
|
||||
--v-input-color: var(--primary);
|
||||
}
|
||||
|
||||
.v-list {
|
||||
--v-list-item-content-font-family: var(--family-monospace);
|
||||
}
|
||||
@@ -414,4 +435,13 @@ export default defineComponent({
|
||||
font-family: var(--family-monospace);
|
||||
}
|
||||
}
|
||||
|
||||
.sort-field {
|
||||
--v-input-font-family: var(--family-monospace);
|
||||
|
||||
.v-divider {
|
||||
margin-top: 48px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -19,11 +19,17 @@ const fieldsStore = useFieldsStore();
|
||||
const relationsStore = useRelationsStore();
|
||||
const collectionsStore = useCollectionsStore();
|
||||
|
||||
type GenerationInfo = {
|
||||
name: string;
|
||||
type: 'collection' | 'field';
|
||||
};
|
||||
|
||||
let state: any;
|
||||
let availableInterfaces: ComputedRef<InterfaceConfig[]>;
|
||||
let availableDisplays: ComputedRef<DisplayConfig[]>;
|
||||
let generationInfo: ComputedRef<GenerationInfo[]>;
|
||||
|
||||
export { state, availableInterfaces, availableDisplays, initLocalStore, clearLocalStore };
|
||||
export { state, availableInterfaces, availableDisplays, generationInfo, initLocalStore, clearLocalStore };
|
||||
|
||||
function initLocalStore(collection: string, field: string, type: typeof localTypes[number]) {
|
||||
const interfaces = getInterfaces();
|
||||
@@ -85,6 +91,28 @@ function initLocalStore(collection: string, field: string, type: typeof localTyp
|
||||
.sort((a, b) => (a.name > b.name ? 1 : -1));
|
||||
});
|
||||
|
||||
generationInfo = computed(() => {
|
||||
return [
|
||||
...state.newCollections.map((newCollection: any) => ({
|
||||
name: newCollection.collection,
|
||||
type: 'collection',
|
||||
})),
|
||||
...state.newCollections
|
||||
.map((newCollection: any) =>
|
||||
newCollection.fields.map((field: any) => ({ ...field, collection: newCollection.collection }))
|
||||
)
|
||||
.flat()
|
||||
.map((newField: any) => ({
|
||||
name: `${newField.collection}.${newField.field}`,
|
||||
type: 'field',
|
||||
})),
|
||||
...state.newFields.map((newField: any) => ({
|
||||
name: `${newField.collection}.${newField.field}`,
|
||||
type: 'field',
|
||||
})),
|
||||
];
|
||||
});
|
||||
|
||||
const isExisting = field !== '+';
|
||||
|
||||
if (isExisting) {
|
||||
@@ -231,59 +259,58 @@ function initLocalStore(collection: string, field: string, type: typeof localTyp
|
||||
delete state.fieldData.schema;
|
||||
state.fieldData.type = null;
|
||||
|
||||
const syncNewCollectionsO2M = throttle(() => {
|
||||
const collectionName = state.relations[0].many_collection;
|
||||
const fieldName = state.relations[0].many_field;
|
||||
const syncNewCollectionsO2M = throttle(([collectionName, fieldName, sortField]) => {
|
||||
state.newCollections = state.newCollections.filter((col: any) => ['related'].includes(col.$type) === false);
|
||||
|
||||
if (collectionExists(collectionName)) {
|
||||
state.newCollections = [];
|
||||
} else {
|
||||
state.newCollections = [
|
||||
{
|
||||
collection: collectionName,
|
||||
fields: [
|
||||
{
|
||||
field: 'id',
|
||||
type: 'integer',
|
||||
schema: {
|
||||
has_auto_increment: true,
|
||||
is_primary_key: true,
|
||||
},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
state.newFields = state.newFields.filter(
|
||||
(field: Partial<Field> & { $type: string }) => ['manyRelated', 'sort'].includes(field.$type) === false
|
||||
);
|
||||
|
||||
if (collectionExists(collectionName) === false) {
|
||||
state.newCollections.push({
|
||||
$type: 'related',
|
||||
collection: collectionName,
|
||||
fields: [
|
||||
{
|
||||
field: 'id',
|
||||
type: 'integer',
|
||||
schema: {
|
||||
has_auto_increment: true,
|
||||
is_primary_key: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
state.relations[0].many_primary = 'id';
|
||||
}
|
||||
|
||||
if (collectionExists(collectionName)) {
|
||||
if (fieldExists(collectionName, fieldName)) {
|
||||
state.newFields = [];
|
||||
} else {
|
||||
state.newFields = [
|
||||
{
|
||||
$type: 'manyRelated',
|
||||
collection: collectionName,
|
||||
field: fieldName,
|
||||
type: fieldsStore.getPrimaryKeyFieldForCollection(collection)?.type,
|
||||
schema: {},
|
||||
},
|
||||
];
|
||||
}
|
||||
} else {
|
||||
state.newFields = [
|
||||
{
|
||||
$type: 'manyRelated',
|
||||
collection: collectionName,
|
||||
field: fieldName,
|
||||
type: 'integer',
|
||||
schema: {},
|
||||
if (fieldExists(collectionName, fieldName) === false) {
|
||||
state.newFields.push({
|
||||
$type: 'manyRelated',
|
||||
collection: collectionName,
|
||||
field: fieldName,
|
||||
type: collectionExists(collectionName)
|
||||
? fieldsStore.getPrimaryKeyFieldForCollection(collectionName)?.type
|
||||
: 'integer',
|
||||
schema: {},
|
||||
});
|
||||
}
|
||||
|
||||
if (sortField && fieldExists(collectionName, sortField) === false) {
|
||||
state.newFields.push({
|
||||
$type: 'sort',
|
||||
collection: collectionName,
|
||||
field: sortField,
|
||||
type: 'integer',
|
||||
schema: {},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
}, 50);
|
||||
|
||||
@@ -321,134 +348,41 @@ function initLocalStore(collection: string, field: string, type: typeof localTyp
|
||||
}
|
||||
);
|
||||
|
||||
watch([() => state.relations[0].many_collection, () => state.relations[0].many_field], syncNewCollectionsO2M);
|
||||
watch(
|
||||
[
|
||||
() => state.relations[0].many_collection,
|
||||
() => state.relations[0].many_field,
|
||||
() => state.relations[0].sort_field,
|
||||
],
|
||||
syncNewCollectionsO2M
|
||||
);
|
||||
}
|
||||
|
||||
function useM2M() {
|
||||
delete state.fieldData.schema;
|
||||
state.fieldData.type = null;
|
||||
|
||||
const syncNewCollectionsM2M = throttle(([junctionCollection, manyCurrent, manyRelated, relatedCollection]) => {
|
||||
state.newCollections = state.newCollections.filter(
|
||||
(col: any) => ['junction', 'related'].includes(col.$type) === false
|
||||
);
|
||||
state.newFields = state.newFields.filter(
|
||||
(field: Partial<Field> & { $type: string }) => ['manyCurrent', 'manyRelated'].includes(field.$type) === false
|
||||
);
|
||||
const syncNewCollectionsM2M = throttle(
|
||||
([junctionCollection, manyCurrent, manyRelated, relatedCollection, sortField]) => {
|
||||
state.newCollections = state.newCollections.filter(
|
||||
(col: any) => ['junction', 'related'].includes(col.$type) === false
|
||||
);
|
||||
state.newFields = state.newFields.filter(
|
||||
(field: Partial<Field> & { $type: string }) =>
|
||||
['manyCurrent', 'manyRelated', 'sort'].includes(field.$type) === false
|
||||
);
|
||||
|
||||
if (collectionExists(junctionCollection) === false) {
|
||||
state.newCollections.push({
|
||||
$type: 'junction',
|
||||
collection: junctionCollection,
|
||||
meta: {
|
||||
hidden: true,
|
||||
icon: 'import_export',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
field: 'id',
|
||||
type: 'integer',
|
||||
schema: {
|
||||
has_auto_increment: true,
|
||||
},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
state.relations[0].many_primary = 'id';
|
||||
state.relations[1].many_primary = 'id';
|
||||
}
|
||||
|
||||
if (fieldExists(junctionCollection, manyCurrent) === false) {
|
||||
state.newFields.push({
|
||||
$type: 'manyCurrent',
|
||||
collection: junctionCollection,
|
||||
field: manyCurrent,
|
||||
type: fieldsStore.getPrimaryKeyFieldForCollection(collection)!.type,
|
||||
schema: {},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (fieldExists(junctionCollection, manyRelated) === false) {
|
||||
if (type === 'translations') {
|
||||
state.newFields.push({
|
||||
$type: 'manyRelated',
|
||||
collection: junctionCollection,
|
||||
field: manyRelated,
|
||||
type: collectionExists(relatedCollection)
|
||||
? fieldsStore.getPrimaryKeyFieldForCollection(relatedCollection)?.type
|
||||
: 'string',
|
||||
schema: {},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
state.newFields.push({
|
||||
$type: 'manyRelated',
|
||||
collection: junctionCollection,
|
||||
field: manyRelated,
|
||||
type: collectionExists(relatedCollection)
|
||||
? fieldsStore.getPrimaryKeyFieldForCollection(relatedCollection)?.type
|
||||
: 'integer',
|
||||
schema: {},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (collectionExists(relatedCollection) === false) {
|
||||
if (type === 'translations') {
|
||||
if (collectionExists(junctionCollection) === false) {
|
||||
state.newCollections.push({
|
||||
$type: 'related',
|
||||
collection: relatedCollection,
|
||||
$type: 'junction',
|
||||
collection: junctionCollection,
|
||||
meta: {
|
||||
icon: 'translate',
|
||||
hidden: true,
|
||||
icon: 'import_export',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
field: state.relations[1].one_primary,
|
||||
type: 'string',
|
||||
schema: {
|
||||
is_primary_key: true,
|
||||
},
|
||||
meta: {
|
||||
interface: 'text-input',
|
||||
options: {
|
||||
iconLeft: 'vpn_key',
|
||||
},
|
||||
width: 'half',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
type: 'string',
|
||||
schema: {},
|
||||
meta: {
|
||||
interface: 'text-input',
|
||||
options: {
|
||||
iconLeft: 'translate',
|
||||
},
|
||||
width: 'half',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
} else {
|
||||
state.newCollections.push({
|
||||
$type: 'related',
|
||||
collection: relatedCollection,
|
||||
fields: [
|
||||
{
|
||||
field: state.relations[1].one_primary,
|
||||
field: 'id',
|
||||
type: 'integer',
|
||||
schema: {
|
||||
has_auto_increment: true,
|
||||
@@ -459,48 +393,165 @@ function initLocalStore(collection: string, field: string, type: typeof localTyp
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (type === 'translations') {
|
||||
if (collectionExists(relatedCollection) === false) {
|
||||
state.newRows = {
|
||||
[relatedCollection]: [
|
||||
{
|
||||
code: 'en-US',
|
||||
name: 'English',
|
||||
},
|
||||
{
|
||||
code: 'de-DE',
|
||||
name: 'German',
|
||||
},
|
||||
{
|
||||
code: 'fr-FR',
|
||||
name: 'French',
|
||||
},
|
||||
{
|
||||
code: 'ru-RU',
|
||||
name: 'Russian',
|
||||
},
|
||||
{
|
||||
code: 'es-ES',
|
||||
name: 'Spanish',
|
||||
},
|
||||
{
|
||||
code: 'it-IT',
|
||||
name: 'Italian',
|
||||
},
|
||||
{
|
||||
code: 'pt-BR',
|
||||
name: 'Portuguese',
|
||||
},
|
||||
],
|
||||
};
|
||||
} else {
|
||||
state.newRows = {};
|
||||
state.relations[0].many_primary = 'id';
|
||||
state.relations[1].many_primary = 'id';
|
||||
}
|
||||
}
|
||||
}, 50);
|
||||
|
||||
if (fieldExists(junctionCollection, manyCurrent) === false) {
|
||||
state.newFields.push({
|
||||
$type: 'manyCurrent',
|
||||
collection: junctionCollection,
|
||||
field: manyCurrent,
|
||||
type: fieldsStore.getPrimaryKeyFieldForCollection(collection)!.type,
|
||||
schema: {},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (fieldExists(junctionCollection, manyRelated) === false) {
|
||||
if (type === 'translations') {
|
||||
state.newFields.push({
|
||||
$type: 'manyRelated',
|
||||
collection: junctionCollection,
|
||||
field: manyRelated,
|
||||
type: collectionExists(relatedCollection)
|
||||
? fieldsStore.getPrimaryKeyFieldForCollection(relatedCollection)?.type
|
||||
: 'string',
|
||||
schema: {},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
state.newFields.push({
|
||||
$type: 'manyRelated',
|
||||
collection: junctionCollection,
|
||||
field: manyRelated,
|
||||
type: collectionExists(relatedCollection)
|
||||
? fieldsStore.getPrimaryKeyFieldForCollection(relatedCollection)?.type
|
||||
: 'integer',
|
||||
schema: {},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (collectionExists(relatedCollection) === false) {
|
||||
if (type === 'translations') {
|
||||
state.newCollections.push({
|
||||
$type: 'related',
|
||||
collection: relatedCollection,
|
||||
meta: {
|
||||
icon: 'translate',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
field: state.relations[1].one_primary,
|
||||
type: 'string',
|
||||
schema: {
|
||||
is_primary_key: true,
|
||||
},
|
||||
meta: {
|
||||
interface: 'text-input',
|
||||
options: {
|
||||
iconLeft: 'vpn_key',
|
||||
},
|
||||
width: 'half',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
type: 'string',
|
||||
schema: {},
|
||||
meta: {
|
||||
interface: 'text-input',
|
||||
options: {
|
||||
iconLeft: 'translate',
|
||||
},
|
||||
width: 'half',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
} else {
|
||||
state.newCollections.push({
|
||||
$type: 'related',
|
||||
collection: relatedCollection,
|
||||
fields: [
|
||||
{
|
||||
field: state.relations[1].one_primary,
|
||||
type: 'integer',
|
||||
schema: {
|
||||
has_auto_increment: true,
|
||||
},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (type === 'translations') {
|
||||
if (collectionExists(relatedCollection) === false) {
|
||||
state.newRows = {
|
||||
[relatedCollection]: [
|
||||
{
|
||||
code: 'en-US',
|
||||
name: 'English',
|
||||
},
|
||||
{
|
||||
code: 'de-DE',
|
||||
name: 'German',
|
||||
},
|
||||
{
|
||||
code: 'fr-FR',
|
||||
name: 'French',
|
||||
},
|
||||
{
|
||||
code: 'ru-RU',
|
||||
name: 'Russian',
|
||||
},
|
||||
{
|
||||
code: 'es-ES',
|
||||
name: 'Spanish',
|
||||
},
|
||||
{
|
||||
code: 'it-IT',
|
||||
name: 'Italian',
|
||||
},
|
||||
{
|
||||
code: 'pt-BR',
|
||||
name: 'Portuguese',
|
||||
},
|
||||
],
|
||||
};
|
||||
} else {
|
||||
state.newRows = {};
|
||||
}
|
||||
}
|
||||
|
||||
if (sortField && fieldExists(junctionCollection, sortField) === false) {
|
||||
state.newFields.push({
|
||||
$type: 'sort',
|
||||
collection: junctionCollection,
|
||||
field: sortField,
|
||||
type: 'integer',
|
||||
schema: {},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
50
|
||||
);
|
||||
|
||||
if (!isExisting) {
|
||||
state.fieldData.meta.special = [type];
|
||||
@@ -567,6 +618,7 @@ function initLocalStore(collection: string, field: string, type: typeof localTyp
|
||||
() => state.relations[0].many_field,
|
||||
() => state.relations[1].many_field,
|
||||
() => state.relations[1].one_collection,
|
||||
() => state.relations[0].sort_field,
|
||||
],
|
||||
syncNewCollectionsM2M
|
||||
);
|
||||
@@ -691,83 +743,99 @@ function initLocalStore(collection: string, field: string, type: typeof localTyp
|
||||
delete state.fieldData.schema;
|
||||
state.fieldData.type = null;
|
||||
|
||||
const syncNewCollectionsM2A = throttle(([junctionCollection, manyCurrent, manyRelated, oneCollectionField]) => {
|
||||
state.newCollections = state.newCollections.filter(
|
||||
(col: any) => ['junction', 'related'].includes(col.$type) === false
|
||||
);
|
||||
const syncNewCollectionsM2A = throttle(
|
||||
([junctionCollection, manyCurrent, manyRelated, oneCollectionField, sortField]) => {
|
||||
state.newCollections = state.newCollections.filter(
|
||||
(col: any) => ['junction', 'related'].includes(col.$type) === false
|
||||
);
|
||||
|
||||
state.newFields = state.newFields.filter(
|
||||
(field: Partial<Field> & { $type: string }) =>
|
||||
['manyCurrent', 'manyRelated', 'collectionField'].includes(field.$type) === false
|
||||
);
|
||||
state.newFields = state.newFields.filter(
|
||||
(field: Partial<Field> & { $type: string }) =>
|
||||
['manyCurrent', 'manyRelated', 'collectionField', 'sort'].includes(field.$type) === false
|
||||
);
|
||||
|
||||
if (collectionExists(junctionCollection) === false) {
|
||||
state.newCollections.push({
|
||||
$type: 'junction',
|
||||
collection: junctionCollection,
|
||||
meta: {
|
||||
hidden: true,
|
||||
icon: 'import_export',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
field: 'id',
|
||||
type: 'integer',
|
||||
schema: {
|
||||
has_auto_increment: true,
|
||||
},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
if (collectionExists(junctionCollection) === false) {
|
||||
state.newCollections.push({
|
||||
$type: 'junction',
|
||||
collection: junctionCollection,
|
||||
meta: {
|
||||
hidden: true,
|
||||
icon: 'import_export',
|
||||
},
|
||||
],
|
||||
});
|
||||
fields: [
|
||||
{
|
||||
field: 'id',
|
||||
type: 'integer',
|
||||
schema: {
|
||||
has_auto_increment: true,
|
||||
},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
state.relations[0].many_primary = 'id';
|
||||
state.relations[1].many_primary = 'id';
|
||||
}
|
||||
state.relations[0].many_primary = 'id';
|
||||
state.relations[1].many_primary = 'id';
|
||||
}
|
||||
|
||||
if (fieldExists(junctionCollection, manyCurrent) === false) {
|
||||
state.newFields.push({
|
||||
$type: 'manyCurrent',
|
||||
collection: junctionCollection,
|
||||
field: manyCurrent,
|
||||
type: fieldsStore.getPrimaryKeyFieldForCollection(collection)!.type,
|
||||
schema: {},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
if (fieldExists(junctionCollection, manyCurrent) === false) {
|
||||
state.newFields.push({
|
||||
$type: 'manyCurrent',
|
||||
collection: junctionCollection,
|
||||
field: manyCurrent,
|
||||
type: fieldsStore.getPrimaryKeyFieldForCollection(collection)!.type,
|
||||
schema: {},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (fieldExists(junctionCollection, manyRelated) === false) {
|
||||
state.newFields.push({
|
||||
$type: 'manyRelated',
|
||||
collection: junctionCollection,
|
||||
field: manyRelated,
|
||||
// We'll have to save the foreign key as a string, as that's the only way to safely
|
||||
// be able to store the PK of multiple typed collections
|
||||
type: 'string',
|
||||
schema: {},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
if (fieldExists(junctionCollection, manyRelated) === false) {
|
||||
state.newFields.push({
|
||||
$type: 'manyRelated',
|
||||
collection: junctionCollection,
|
||||
field: manyRelated,
|
||||
// We'll have to save the foreign key as a string, as that's the only way to safely
|
||||
// be able to store the PK of multiple typed collections
|
||||
type: 'string',
|
||||
schema: {},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (fieldExists(junctionCollection, oneCollectionField) === false) {
|
||||
state.newFields.push({
|
||||
$type: 'collectionField',
|
||||
collection: junctionCollection,
|
||||
field: oneCollectionField,
|
||||
type: 'string', // directus_collections.collection is a string
|
||||
schema: {},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
}, 50);
|
||||
if (fieldExists(junctionCollection, oneCollectionField) === false) {
|
||||
state.newFields.push({
|
||||
$type: 'collectionField',
|
||||
collection: junctionCollection,
|
||||
field: oneCollectionField,
|
||||
type: 'string', // directus_collections.collection is a string
|
||||
schema: {},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (sortField && fieldExists(junctionCollection, sortField) === false) {
|
||||
state.newFields.push({
|
||||
$type: 'sort',
|
||||
collection: junctionCollection,
|
||||
field: sortField,
|
||||
type: 'integer',
|
||||
schema: {},
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
50
|
||||
);
|
||||
|
||||
if (!isExisting) {
|
||||
state.fieldData.meta.special = [type];
|
||||
@@ -825,6 +893,7 @@ function initLocalStore(collection: string, field: string, type: typeof localTyp
|
||||
() => state.relations[0].many_field,
|
||||
() => state.relations[1].many_field,
|
||||
() => state.relations[1].one_collection_field,
|
||||
() => state.relations[0].sort_field,
|
||||
],
|
||||
syncNewCollectionsM2A
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user