mirror of
https://github.com/directus/directus.git
synced 2026-01-31 14:07:56 -05:00
Merge branch 'main' of https://github.com/directus/directus into main
This commit is contained in:
@@ -84,6 +84,10 @@ export default defineComponent({
|
||||
type: [String, Number],
|
||||
default: null,
|
||||
},
|
||||
nullable: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
slug: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
@@ -197,6 +201,11 @@ export default defineComponent({
|
||||
function emitValue(event: InputEvent) {
|
||||
let value = (event.target as HTMLInputElement).value;
|
||||
|
||||
if (props.nullable === true && !value) {
|
||||
emit('input', null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (props.type === 'number') {
|
||||
emit('input', Number(value));
|
||||
} else {
|
||||
|
||||
@@ -20,13 +20,15 @@ export default defineDisplay(({ i18n }) => ({
|
||||
options: options,
|
||||
types: ['alias', 'string', 'uuid', 'integer', 'bigInteger', 'json'],
|
||||
groups: ['m2m', 'm2o', 'o2m'],
|
||||
fields: (options: Options, { field, collection }) => {
|
||||
fields: (options: Options | null, { field, collection }) => {
|
||||
const relatedCollection = getRelatedCollection(collection, field);
|
||||
const { primaryKeyField } = useCollection(ref(relatedCollection as string));
|
||||
|
||||
if (!relatedCollection) return [];
|
||||
|
||||
const fields = adjustFieldsForDisplays(getFieldsFromTemplate(options.template), relatedCollection);
|
||||
const fields = options?.template
|
||||
? adjustFieldsForDisplays(getFieldsFromTemplate(options.template), relatedCollection)
|
||||
: [];
|
||||
|
||||
if (fields.includes(primaryKeyField.value.field) === false) {
|
||||
fields.push(primaryKeyField.value.field);
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<template>
|
||||
<value-null v-if="!relatedCollection" />
|
||||
<v-menu v-else-if="type.toLowerCase() === 'o2m' || type.toLowerCase() === 'm2m'" show-arrow :disabled="value.length === 0">
|
||||
<v-menu
|
||||
v-else-if="type.toLowerCase() === 'o2m' || type.toLowerCase() === 'm2m'"
|
||||
show-arrow
|
||||
:disabled="value.length === 0"
|
||||
>
|
||||
<template #activator="{ toggle }">
|
||||
<span @click.stop="toggle" class="toggle" :class="{ subdued: value.length === 0 }">
|
||||
<span class="label">{{ $tc('item_count', value.length) }}</span>
|
||||
@@ -10,7 +14,7 @@
|
||||
<v-list>
|
||||
<v-list-item v-for="item in value" :key="item[primaryKeyField]" :to="getLinkForItem(item)">
|
||||
<v-list-item-content>
|
||||
<render-template :template="template" :item="item" :collection="relatedCollection" />
|
||||
<render-template :template="_template" :item="item" :collection="relatedCollection" />
|
||||
</v-list-item-content>
|
||||
<v-list-item-icon>
|
||||
<v-icon name="launch" small />
|
||||
@@ -18,7 +22,7 @@
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
<render-template v-else :template="template" :item="value" :collection="relatedCollection" />
|
||||
<render-template v-else :template="_template" :item="value" :collection="relatedCollection" />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -44,7 +48,7 @@ export default defineComponent({
|
||||
},
|
||||
template: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: null,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
@@ -62,7 +66,11 @@ export default defineComponent({
|
||||
}
|
||||
});
|
||||
|
||||
return { relatedCollection, primaryKeyField, getLinkForItem };
|
||||
const _template = computed(() => {
|
||||
return props.template || `{{ ${primaryKeyField.value!.field} }}`;
|
||||
});
|
||||
|
||||
return { relatedCollection, primaryKeyField, getLinkForItem, _template };
|
||||
|
||||
function getLinkForItem(item: any) {
|
||||
if (!relatedCollection.value || !primaryKeyField.value) return null;
|
||||
|
||||
@@ -256,7 +256,7 @@ export default defineComponent({
|
||||
function useDisplayValue() {
|
||||
const displayValue = ref<string | null>(null);
|
||||
|
||||
watch(_value, setDisplayValue);
|
||||
watch(_value, setDisplayValue, { immediate: true });
|
||||
|
||||
return { displayValue };
|
||||
|
||||
|
||||
@@ -87,5 +87,20 @@ export default defineInterface(({ i18n }) => ({
|
||||
default_value: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'nullable',
|
||||
name: i18n.t('interfaces.text-input.nullable'),
|
||||
type: 'boolean',
|
||||
meta: {
|
||||
width: 'half',
|
||||
interface: 'toggle',
|
||||
options: {
|
||||
label: i18n.t('interfaces.text-input.nullable_label'),
|
||||
},
|
||||
},
|
||||
schema: {
|
||||
default_value: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<v-input
|
||||
:value="value"
|
||||
:nullable="nullable"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:trim="trim"
|
||||
@@ -38,6 +39,10 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
nullable: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
|
||||
@@ -917,6 +917,8 @@ interfaces:
|
||||
trim_label: Trim the start and end
|
||||
mask: Masked
|
||||
mask_label: Hide the real value
|
||||
nullable: Nullable
|
||||
nullable_label: Save empty value as NULL
|
||||
textarea:
|
||||
textarea: Textarea
|
||||
description: Enter multiline plain-text
|
||||
|
||||
Reference in New Issue
Block a user