mirror of
https://github.com/directus/directus.git
synced 2026-01-29 11:17:57 -05:00
add O2M options and change v-field-select to use tags
This commit is contained in:
@@ -1,31 +1,25 @@
|
||||
<template>
|
||||
<div class="v-field-select">
|
||||
<draggable v-model="activeFields" handle=".drag-handle" :set-data="hideDragImage">
|
||||
<div
|
||||
v-for="(field, index) in activeFields"
|
||||
:key="index"
|
||||
:value="field.field"
|
||||
:label="field.name"
|
||||
class="field"
|
||||
>
|
||||
<v-icon @click.stop="removeField(field.field)" name="close" />
|
||||
<span class="name">{{ field.name }}</span>
|
||||
<v-icon @click.stop name="drag_handle" class="drag-handle" />
|
||||
</div>
|
||||
</draggable>
|
||||
<v-menu attached v-model="menuActive" v-show="selectableFields.length > 0">
|
||||
<draggable v-model="activeFields" draggable=".draggable" :set-data="hideDragImage" class="v-field-select">
|
||||
<v-chip
|
||||
v-for="(field, index) in activeFields"
|
||||
:key="index"
|
||||
class="field draggable"
|
||||
@click.stop="removeField(field.field)"
|
||||
>
|
||||
{{ field.name }}
|
||||
</v-chip>
|
||||
<v-menu showArrow v-model="menuActive" v-show="selectableFields.length > 0" slot="footer" class="add">
|
||||
<template #activator="{ toggle }">
|
||||
<div class="field" @click="toggle">
|
||||
<v-chip class="field" @click="toggle">
|
||||
<v-icon name="add" />
|
||||
<span class="name">Add field</span>
|
||||
</div>
|
||||
</v-chip>
|
||||
</template>
|
||||
|
||||
<v-list dense>
|
||||
<field-list-item @add="addField" v-for="field in selectableFields" :key="field.field" :field="field" />
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</div>
|
||||
</draggable>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -66,7 +60,7 @@ export default defineComponent({
|
||||
|
||||
const _value = computed({
|
||||
get() {
|
||||
return props.value;
|
||||
return props.value || [];
|
||||
},
|
||||
set(newVal: string[]) {
|
||||
emit('input', newVal);
|
||||
@@ -122,17 +116,12 @@ export default defineComponent({
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.field {
|
||||
.v-field-select {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.name {
|
||||
flex: 1;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.v-icon {
|
||||
--v-icon-color: var(--foreground-subdued);
|
||||
}
|
||||
.v-chip.field {
|
||||
margin-right: 5px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { defineInterface } from '../define';
|
||||
import InterfaceOneToMany from './one-to-many.vue';
|
||||
import Options from './options.vue';
|
||||
|
||||
export default defineInterface(({ i18n }) => ({
|
||||
id: 'one-to-many',
|
||||
@@ -9,19 +10,6 @@ export default defineInterface(({ i18n }) => ({
|
||||
component: InterfaceOneToMany,
|
||||
types: ['alias'],
|
||||
relationship: 'o2m',
|
||||
options: [
|
||||
{
|
||||
field: 'fields',
|
||||
type: 'json',
|
||||
name: i18n.tc('field', 0),
|
||||
meta: {
|
||||
interface: 'tags',
|
||||
width: 'full',
|
||||
options: {
|
||||
placeholder: i18n.t('interfaces.one-to-many.readable_fields_copy'),
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
options: Options,
|
||||
recommendedDisplays: ['related-values'],
|
||||
}));
|
||||
|
||||
47
app/src/interfaces/one-to-many/options.vue
Normal file
47
app/src/interfaces/one-to-many/options.vue
Normal file
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<v-notice type="warning" v-if="fieldData.meta.collection == null">
|
||||
{{ $t('interfaces.one-to-many.no_collection') }}
|
||||
</v-notice>
|
||||
<div v-else>
|
||||
<p class="type-label">{{ $t('select_fields') }}</p>
|
||||
<v-field-select :collection="fieldData.meta.collection" v-model="fields"></v-field-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Field } from '@/types';
|
||||
import { defineComponent, PropType, computed } from '@vue/composition-api';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
fieldData: {
|
||||
type: Object as PropType<Field>,
|
||||
default: null,
|
||||
},
|
||||
value: {
|
||||
type: Object as PropType<any>,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const fields = computed({
|
||||
get() {
|
||||
return props.value?.fields;
|
||||
},
|
||||
set(newTemplate: string) {
|
||||
emit('input', {
|
||||
...(props.value || {}),
|
||||
fields: newTemplate,
|
||||
});
|
||||
},
|
||||
});
|
||||
return { fields };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.type-label {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,11 +1,6 @@
|
||||
<template>
|
||||
<div class="layout-tabular">
|
||||
<portal to="layout-options">
|
||||
<div class="layout-option">
|
||||
<div class="option-label">Test</div>
|
||||
<v-field-select :collection="collection" v-model="selectedFields" />
|
||||
</div>
|
||||
|
||||
<div class="layout-option">
|
||||
<div class="option-label">{{ $t('layouts.tabular.spacing') }}</div>
|
||||
<v-select
|
||||
@@ -216,7 +211,6 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const selectedFields = ref(['title']);
|
||||
const table = ref<Vue | null>(null);
|
||||
const mainElement = inject('main-element', ref<Element | null>(null));
|
||||
|
||||
@@ -296,7 +290,6 @@ export default defineComponent({
|
||||
activeFilterCount,
|
||||
refresh,
|
||||
resetPresetAndRefresh,
|
||||
selectedFields,
|
||||
};
|
||||
|
||||
async function resetPresetAndRefresh() {
|
||||
|
||||
Reference in New Issue
Block a user