mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
Rename badge->labels, final tweaks to codestyle
This commit is contained in:
@@ -1,93 +0,0 @@
|
||||
<template>
|
||||
<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, computed, PropType } from '@vue/composition-api';
|
||||
import formatTitle from '@directus/format-title';
|
||||
|
||||
type Choice = {
|
||||
value: string;
|
||||
text?: string;
|
||||
foreground?: string | null;
|
||||
background?: string | null;
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
value: {
|
||||
type: String || (Array as PropType<string[]>),
|
||||
required: true,
|
||||
},
|
||||
format: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
choices: {
|
||||
type: Array as PropType<Choice[]>,
|
||||
default: () => [],
|
||||
},
|
||||
defaultBackground: {
|
||||
type: String,
|
||||
default: '#eceff1',
|
||||
},
|
||||
defaultForeground: {
|
||||
type: String,
|
||||
default: '#263238',
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
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;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function getStyles(item: Choice) {
|
||||
return {
|
||||
'--v-chip-color': item?.foreground || props.defaultForeground,
|
||||
'--v-chip-background-color': item?.background || props.defaultBackground,
|
||||
};
|
||||
}
|
||||
|
||||
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>
|
||||
.display-tags {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.v-chip + .v-chip {
|
||||
margin-left: 4px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,3 +0,0 @@
|
||||
# Tags
|
||||
|
||||
Renders a CSV of strings as individual chips.
|
||||
@@ -1,24 +0,0 @@
|
||||
import withPadding from '../../../.storybook/decorators/with-padding';
|
||||
import { withKnobs, array } from '@storybook/addon-knobs';
|
||||
import readme from './readme.md';
|
||||
import { defineComponent } from '@vue/composition-api';
|
||||
|
||||
export default {
|
||||
title: 'Displays / Tags',
|
||||
decorators: [withPadding, withKnobs],
|
||||
parameters: {
|
||||
notes: readme,
|
||||
},
|
||||
};
|
||||
|
||||
export const basic = () =>
|
||||
defineComponent({
|
||||
props: {
|
||||
value: {
|
||||
default: array('Value', ['vip', 'executive']),
|
||||
},
|
||||
},
|
||||
template: `
|
||||
<display-tags :value="value" />
|
||||
`,
|
||||
});
|
||||
@@ -1,21 +0,0 @@
|
||||
import DisplayTags from './tags.vue';
|
||||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||
import VueCompositionAPI from '@vue/composition-api';
|
||||
import VChip from '@/components/v-chip';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(VueCompositionAPI);
|
||||
localVue.component('v-chip', VChip);
|
||||
|
||||
describe('Displays / Tags', () => {
|
||||
it('Renders a chip for every value', () => {
|
||||
const component = shallowMount(DisplayTags, {
|
||||
localVue,
|
||||
propsData: {
|
||||
value: ['tag 1', 'tag 2', 'tag 3'],
|
||||
},
|
||||
});
|
||||
|
||||
expect(component.findAll(VChip).length).toBe(3);
|
||||
});
|
||||
});
|
||||
@@ -1,25 +1,13 @@
|
||||
import { defineDisplay } from '@/displays/define';
|
||||
import DisplayBadge from './badge.vue';
|
||||
import DisplayLabels from './labels.vue';
|
||||
|
||||
export default defineDisplay(({ i18n }) => ({
|
||||
id: 'badge',
|
||||
name: i18n.t('badge'),
|
||||
id: 'labels',
|
||||
name: i18n.t('labels'),
|
||||
types: ['string', 'json'],
|
||||
icon: 'flag',
|
||||
handler: DisplayBadge,
|
||||
handler: DisplayLabels,
|
||||
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'),
|
||||
@@ -44,6 +32,18 @@ export default defineDisplay(({ i18n }) => ({
|
||||
default_value: '#eceff1',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'format',
|
||||
name: i18n.t('format_text'),
|
||||
type: 'boolean',
|
||||
meta: {
|
||||
width: 'half-left',
|
||||
interface: 'toggle',
|
||||
},
|
||||
schema: {
|
||||
default_value: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'choices',
|
||||
name: i18n.t('choices'),
|
||||
99
app/src/displays/labels/labels.vue
Normal file
99
app/src/displays/labels/labels.vue
Normal file
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<div class="display-tags">
|
||||
<v-chip
|
||||
v-for="item in items"
|
||||
:key="item.value"
|
||||
:style="{
|
||||
'--v-chip-color': item.foreground,
|
||||
'--v-chip-background-color': item.background,
|
||||
}"
|
||||
small
|
||||
disabled
|
||||
label
|
||||
>
|
||||
{{ item.text }}
|
||||
</v-chip>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
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;
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Array] as PropType<string | string[]>,
|
||||
required: true,
|
||||
},
|
||||
format: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
choices: {
|
||||
type: Array as PropType<Choice[]>,
|
||||
default: () => [],
|
||||
},
|
||||
defaultBackground: {
|
||||
type: String,
|
||||
default: '#eceff1',
|
||||
},
|
||||
defaultForeground: {
|
||||
type: String,
|
||||
default: '#263238',
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
validator: (val: string) => ['json', 'string'].includes(val),
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const items = computed(() => {
|
||||
let items: string[];
|
||||
|
||||
if (props.value === null) items = [];
|
||||
else if (props.type === 'string') items = [props.value as string];
|
||||
else items = props.value as string[];
|
||||
|
||||
return items.map((item) => {
|
||||
const choice = props.choices.find((choice) => choice.value === item);
|
||||
|
||||
if (choice === undefined) {
|
||||
return {
|
||||
value: item,
|
||||
text: props.format ? formatTitle(item) : item,
|
||||
foreground: props.defaultForeground,
|
||||
background: props.defaultBackground,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
value: item,
|
||||
text: choice.text || (props.format ? formatTitle(item) : item),
|
||||
foreground: choice.foreground || props.defaultForeground,
|
||||
background: choice.background || props.defaultBackground,
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return { items };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.display-tags {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.v-chip + .v-chip {
|
||||
margin-left: 4px;
|
||||
}
|
||||
</style>
|
||||
@@ -103,6 +103,8 @@
|
||||
"color_dot": "Color Dot",
|
||||
"default_color": "Default Color",
|
||||
|
||||
"labels": "Labels",
|
||||
|
||||
"global": "Global",
|
||||
|
||||
"admins_have_all_permissions": "Admins have all permissions",
|
||||
|
||||
Reference in New Issue
Block a user