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:
Rijk van Zanten
2021-02-25 19:13:36 -05:00
committed by GitHub
parent f088074d48
commit db30acbb8a
23 changed files with 611 additions and 754 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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,

View File

@@ -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>

View File

@@ -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
);