From 5a745b0c4d816ffc2cbb1cd4cc5167bc3cfa0f5d Mon Sep 17 00:00:00 2001 From: Rijk van Zanten Date: Fri, 12 Jun 2020 16:51:12 -0400 Subject: [PATCH] Interface grouping (#717) * Manage types * Fix typing * Unset interface on local type change * Add note * Limit available displays based on localType * Filter displays based on localtype * Only show displays that fit the type * Limit type options for interface selection * Dont import unused type --- .../use-collection/use-collection.ts | 6 +- src/displays/mime-type/index.ts | 2 +- src/displays/template/index.ts | 2 +- src/displays/types.ts | 3 +- src/interfaces/types.ts | 36 +--------- src/lang/en-US/index.json | 3 + .../new-collection/new-collection.vue | 2 +- .../field-setup/field-setup-advanced.vue | 23 ++++++- .../field-setup/field-setup-display.vue | 28 ++++++-- .../field-setup/field-setup-field.vue | 20 ++++-- .../field-setup/field-setup-interface.vue | 54 +++++++++++++-- .../components/field-setup/field-setup.vue | 22 +++---- .../fields/components/field-setup/index.ts | 17 +++++ .../permissions-row/permissions-row.vue | 16 ++--- src/stores/fields/types.ts | 65 ++++++++++++++++++- 15 files changed, 214 insertions(+), 85 deletions(-) diff --git a/src/composables/use-collection/use-collection.ts b/src/composables/use-collection/use-collection.ts index 65bef8f15c..8762ca22e8 100644 --- a/src/composables/use-collection/use-collection.ts +++ b/src/composables/use-collection/use-collection.ts @@ -21,8 +21,8 @@ export function useCollection(collection: Ref) { return fields.value?.find((field) => field.collection === collection.value && field.primary_key === true)!; }); - const ownerField = computed(() => { - return fields.value?.find((field) => field.type === 'owner') || null; + const userCreatedField = computed(() => { + return fields.value?.find((field) => field.type === 'user_created') || null; }); const statusField = computed(() => { @@ -54,5 +54,5 @@ export function useCollection(collection: Ref) { ); }); - return { info, fields, primaryKeyField, ownerField, statusField, softDeleteStatus, sortField }; + return { info, fields, primaryKeyField, userCreatedField, statusField, softDeleteStatus, sortField }; } diff --git a/src/displays/mime-type/index.ts b/src/displays/mime-type/index.ts index 4c388277ae..fe5a9de50f 100644 --- a/src/displays/mime-type/index.ts +++ b/src/displays/mime-type/index.ts @@ -4,7 +4,7 @@ import { defineDisplay } from '@/displays/define'; export default defineDisplay(({ i18n }) => ({ id: 'mime-type', - name: i18n.t('mime-type'), + name: i18n.t('mime_type'), icon: 'picture_as_pdf', options: [ { diff --git a/src/displays/template/index.ts b/src/displays/template/index.ts index 97bee61ff6..ad06a04e34 100644 --- a/src/displays/template/index.ts +++ b/src/displays/template/index.ts @@ -23,7 +23,7 @@ export default defineDisplay(({ i18n }) => ({ width: 'full', }, ], - types: ['string'], + types: ['m2o', 'o2m', 'm2m'], fields: (options: Options, { field, collection }) => { const relatedCollection = getRelatedCollection(collection, field); const { primaryKeyField } = useCollection(ref(relatedCollection as string)); diff --git a/src/displays/types.ts b/src/displays/types.ts index 75f2e3669f..6d2bf22b0d 100644 --- a/src/displays/types.ts +++ b/src/displays/types.ts @@ -1,7 +1,6 @@ import VueI18n from 'vue-i18n'; import { Component } from 'vue'; -import { Field } from '@/stores/fields/types'; -import { Type } from '@/interfaces/types'; +import { Field, Type } from '@/stores/fields/types'; export type DisplayHandlerFunctionContext = { type: string; diff --git a/src/interfaces/types.ts b/src/interfaces/types.ts index 2c4cfa72c6..ef6aac680a 100644 --- a/src/interfaces/types.ts +++ b/src/interfaces/types.ts @@ -1,40 +1,6 @@ import VueI18n from 'vue-i18n'; import { Component } from 'vue'; -import { Field } from '@/stores/fields/types'; - -const types = [ - 'alias', - 'array', - 'boolean', - 'binary', - 'datetime', - 'date', - 'time', - 'file', - 'files', - 'hash', - 'group', - 'integer', - 'decimal', - 'json', - 'lang', - 'm2o', - 'o2m', - 'm2m', - 'slug', - 'sort', - 'status', - 'string', - 'translation', - 'uuid', - 'datetime_created', - 'datetime_updated', - 'user_created', - 'user_updated', - 'user', -] as const; - -export type Type = typeof types[number]; +import { Field, Type } from '@/stores/fields/types'; export type InterfaceConfig = { id: string; diff --git a/src/lang/en-US/index.json b/src/lang/en-US/index.json index 66c63076f7..76f5924614 100644 --- a/src/lang/en-US/index.json +++ b/src/lang/en-US/index.json @@ -76,6 +76,9 @@ "confirm_revert": "Confirm Revert", "confirm_revert_body": "This will revert the item to the selected state.", + "mime_type": "MIME Type", + "filesize": "Filesize", + "editing_role": "{role} Role", "adding_webhook": "Adding Webhook", diff --git a/src/modules/settings/routes/data-model/collections/components/new-collection/new-collection.vue b/src/modules/settings/routes/data-model/collections/components/new-collection/new-collection.vue index cbcdd48898..9b0973c1ad 100644 --- a/src/modules/settings/routes/data-model/collections/components/new-collection/new-collection.vue +++ b/src/modules/settings/routes/data-model/collections/components/new-collection/new-collection.vue @@ -325,7 +325,7 @@ export default defineComponent({ if (systemFields[2].enabled === true) { fields.push({ - type: 'owner', + type: 'user_created', datatype: 'INT', field: systemFields[2].name, interface: 'owner', diff --git a/src/modules/settings/routes/data-model/fields/components/field-setup/field-setup-advanced.vue b/src/modules/settings/routes/data-model/fields/components/field-setup/field-setup-advanced.vue index 54698ff2c8..a514f32e55 100644 --- a/src/modules/settings/routes/data-model/fields/components/field-setup/field-setup-advanced.vue +++ b/src/modules/settings/routes/data-model/fields/components/field-setup/field-setup-advanced.vue @@ -10,7 +10,8 @@ import { defineComponent, computed, PropType } from '@vue/composition-api'; import i18n from '@/lang'; import { FormField } from '@/components/v-form/types'; -import { Field } from '@/stores/fields/types'; +import { Field, types } from '@/stores/fields/types'; +import interfaces from '@/interfaces'; export default defineComponent({ props: { @@ -24,6 +25,21 @@ export default defineComponent({ }, }, setup(props) { + const selectedInterface = computed(() => interfaces.find((inter) => inter.id === props.value.interface)); + + const typeChoices = computed(() => { + let availableTypes = types; + + if (selectedInterface.value) { + availableTypes = selectedInterface.value.types; + } + + return availableTypes.map((type) => ({ + text: i18n.t(type), + value: type, + })); + }); + const fields = computed(() => { const fields: FormField[] = [ { @@ -127,8 +143,11 @@ export default defineComponent({ { field: 'type', name: i18n.t('directus_type'), - interface: 'text-input', + interface: 'dropdown', width: 'half', + options: { + choices: typeChoices.value, + }, }, { field: 'datatype', diff --git a/src/modules/settings/routes/data-model/fields/components/field-setup/field-setup-display.vue b/src/modules/settings/routes/data-model/fields/components/field-setup/field-setup-display.vue index b2aec4570e..60c6751053 100644 --- a/src/modules/settings/routes/data-model/fields/components/field-setup/field-setup-display.vue +++ b/src/modules/settings/routes/data-model/fields/components/field-setup/field-setup-display.vue @@ -29,6 +29,8 @@ import { defineComponent, computed, PropType } from '@vue/composition-api'; import displays from '@/displays/'; import { FancySelectItem } from '@/components/v-fancy-select/types'; import { Field } from '@/stores/fields/types'; +import { localTypeGroups } from './index'; +import { LocalType } from './types'; export default defineComponent({ props: { @@ -40,14 +42,30 @@ export default defineComponent({ type: Object as PropType, required: true, }, + localType: { + type: String as PropType, + required: true, + }, }, setup(props, { emit }) { const items = computed(() => { - return displays.map((inter) => ({ - text: inter.name, - value: inter.id, - icon: inter.icon, - })); + return ( + displays + // Filter interfaces based on the localType that was selected + .filter((display) => { + return display.types.some((type) => localTypeGroups[props.localType].includes(type)); + }) + // When choosing an interface, the type is preset. We can safely assume that a + // type has been set when you reach the display pane + .filter((display) => { + return display.types.includes(props.value.type); + }) + .map((inter) => ({ + text: inter.name, + value: inter.id, + icon: inter.icon, + })) + ); }); const selectedDisplay = computed(() => { diff --git a/src/modules/settings/routes/data-model/fields/components/field-setup/field-setup-field.vue b/src/modules/settings/routes/data-model/fields/components/field-setup/field-setup-field.vue index 6d882299b0..58806707a3 100644 --- a/src/modules/settings/routes/data-model/fields/components/field-setup/field-setup-field.vue +++ b/src/modules/settings/routes/data-model/fields/components/field-setup/field-setup-field.vue @@ -14,12 +14,7 @@ :disabled="isNew === false" /> - + @@ -69,7 +64,7 @@ export default defineComponent({ }, ]); - return { emitValue, items }; + return { emitValue, items, setLocalType }; function emitValue(key: string, value: any) { emit('input', { @@ -77,6 +72,17 @@ export default defineComponent({ [key]: value, }); } + + function setLocalType(newType: string) { + emit('update:localType', newType); + + // Reset the interface when changing the localtype. If you change localType, the previously + // selected interface most likely doesn't exist in the new selection anyways + emit('input', { + ...props.value, + interface: null, + }); + } }, }); diff --git a/src/modules/settings/routes/data-model/fields/components/field-setup/field-setup-interface.vue b/src/modules/settings/routes/data-model/fields/components/field-setup/field-setup-interface.vue index ea60bcba3b..3b39ee5343 100644 --- a/src/modules/settings/routes/data-model/fields/components/field-setup/field-setup-interface.vue +++ b/src/modules/settings/routes/data-model/fields/components/field-setup/field-setup-interface.vue @@ -2,7 +2,7 @@

{{ $t('interface_setup_title') }}

- +