merge badge and tags display

This commit is contained in:
Nitwel
2020-09-07 19:58:19 +02:00
parent a41d711884
commit 048c1c57bf
7 changed files with 63 additions and 90 deletions

View File

@@ -1,26 +1,31 @@
<template>
<div>
<value-null v-if="value === null" />
<div class="badge" :style="styles">{{ displayValue }}</div>
<div class="display-tags">
<v-chip v-for="item in items" :key="item.value" :style="getStyles(item)" small disabled label>
{{ getText(item) }}
</v-chip>
</div>
</template>
<script lang="ts">
import { defineComponent, PropType, computed } from '@vue/composition-api';
import { defineComponent, computed, PropType } from '@vue/composition-api';
import formatTitle from '@directus/format-title';
type Choice = {
value: string;
text: string;
foreground: string | null;
background: string | null;
text?: string;
foreground?: string | null;
background?: string | null;
};
export default defineComponent({
props: {
value: {
type: String,
default: null,
type: String || (Array as PropType<string[]>),
required: true,
},
format: {
type: Boolean,
default: true,
},
choices: {
type: Array as PropType<Choice[]>,
@@ -36,35 +41,53 @@ export default defineComponent({
},
},
setup(props) {
const currentChoice = computed(() => {
return props.choices.find((choice) => {
return choice.value === props.value;
const items = computed(() => {
let items: string[];
if (typeof props.value === 'string') {
if (props.value === null) return [];
items = [props.value];
} else {
items = props.value;
}
return items.map((item) => {
const choise = props.choices.find((choise) => choise.value === item);
if (choise === undefined) {
return {
value: item,
};
} else {
return choise;
}
});
});
const displayValue = computed(() => {
if (!currentChoice.value) return formatTitle(props.value);
return currentChoice.value.text;
});
const styles = computed(() => {
function getStyles(item: Choice) {
return {
color: currentChoice.value?.foreground || props.defaultForeground,
backgroundColor: currentChoice.value?.background || props.defaultBackground,
'--v-chip-color': item?.foreground || props.defaultForeground,
'--v-chip-background-color': item?.background || props.defaultBackground,
};
});
}
return { displayValue, styles };
function getText(item: Choice) {
if (item.text === undefined) {
return props.format ? formatTitle(item.value) : item.value;
} else {
return props.format ? formatTitle(item.text) : item.text;
}
}
return { getStyles, items, getText };
},
});
</script>
<style lang="scss" scoped>
.badge {
.display-tags {
display: inline-block;
padding: 8px;
line-height: 1;
vertical-align: middle;
border-radius: var(--border-radius);
}
.v-chip + .v-chip {
margin-left: 4px;
}
</style>

View File

@@ -4,10 +4,22 @@ import DisplayBadge from './badge.vue';
export default defineDisplay(({ i18n }) => ({
id: 'badge',
name: i18n.t('badge'),
types: ['string'],
types: ['string', 'json'],
icon: 'flag',
handler: DisplayBadge,
options: [
{
field: 'format',
name: i18n.t('format_text'),
type: 'boolean',
meta: {
width: 'half',
interface: 'toggle',
},
schema: {
default_value: true,
},
},
{
field: 'defaultForeground',
name: i18n.t('default_foreground'),

View File

@@ -1,24 +0,0 @@
import { defineDisplay } from '@/displays/define';
import DisplayTags from './tags.vue';
export default defineDisplay(({ i18n }) => ({
id: 'tags',
name: i18n.t('tags'),
types: ['json'],
icon: 'label',
handler: DisplayTags,
options: [
{
field: 'format',
name: i18n.t('format_text'),
type: 'boolean',
meta: {
width: 'half',
interface: 'toggle',
},
schema: {
default_value: true,
},
},
],
}));

View File

@@ -1,38 +0,0 @@
<template>
<div class="display-tags">
<v-chip v-for="val in value" :key="val" small disabled label>
{{ format ? formatTitle(val) : val }}
</v-chip>
</div>
</template>
<script lang="ts">
import { defineComponent, PropType } from '@vue/composition-api';
import formatTitle from '@directus/format-title';
export default defineComponent({
props: {
value: {
type: Array as PropType<string[]>,
required: true,
},
format: {
type: Boolean,
default: true,
},
},
setup() {
return { formatTitle };
},
});
</script>
<style lang="scss" scoped>
.display-tags {
display: inline-block;
}
.v-chip + .v-chip {
margin-left: 4px;
}
</style>