mirror of
https://github.com/directus/directus.git
synced 2026-01-24 23:58:02 -05:00
Combine formatted-text and format-title to formatted-value
This commit is contained in:
@@ -1,27 +0,0 @@
|
||||
import { withKnobs, text } from '@storybook/addon-knobs';
|
||||
import readme from './readme.md';
|
||||
import withPadding from '../../../.storybook/decorators/with-padding';
|
||||
import { defineComponent, computed } from '@vue/composition-api';
|
||||
import handler from './handler';
|
||||
|
||||
export default {
|
||||
title: 'Displays / Format Title',
|
||||
parameters: { notes: readme },
|
||||
decorators: [withPadding, withKnobs],
|
||||
};
|
||||
|
||||
export const basic = () =>
|
||||
defineComponent({
|
||||
props: {
|
||||
val: {
|
||||
default: text('Value', 'hello-world'),
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const value = computed<string | null>(() => handler(props.val, null, { type: 'string' }));
|
||||
return { value };
|
||||
},
|
||||
template: `
|
||||
<div>{{ value }}</div>
|
||||
`,
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
import handler from './handler';
|
||||
import formatTitle from '@directus/format-title';
|
||||
|
||||
jest.mock('@directus/format-title');
|
||||
|
||||
describe('Displays / Format Title', () => {
|
||||
it('Runs the value through the title formatter', () => {
|
||||
handler('test', null, { type: 'string' });
|
||||
expect(formatTitle).toHaveBeenCalledWith('test');
|
||||
});
|
||||
|
||||
it('Does not pass the value if the value is falsy', () => {
|
||||
handler(null, null, { type: 'string' });
|
||||
expect(formatTitle).not.toHaveBeenCalledWith(null);
|
||||
});
|
||||
});
|
||||
@@ -1,5 +0,0 @@
|
||||
import formatTitle from '@directus/format-title';
|
||||
import { DisplayHandlerFunction } from '@/displays/types';
|
||||
|
||||
const handler: DisplayHandlerFunction = (value) => (value ? formatTitle(value) : null);
|
||||
export default handler;
|
||||
@@ -1,11 +0,0 @@
|
||||
import { defineDisplay } from '@/displays/define';
|
||||
import handler from './handler';
|
||||
|
||||
export default defineDisplay({
|
||||
id: 'format-title',
|
||||
name: 'Format Title',
|
||||
icon: 'text_format',
|
||||
handler: handler,
|
||||
options: null,
|
||||
types: ['string'],
|
||||
});
|
||||
@@ -1,5 +0,0 @@
|
||||
# Format Title (Function)
|
||||
|
||||
Runs the raw database value through the [Title Formatter](https://github.com/directus/format-title/)
|
||||
and displays the result.
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
import withPadding from '../../../.storybook/decorators/with-padding';
|
||||
import { withKnobs, text, select, boolean } from '@storybook/addon-knobs';
|
||||
import readme from './readme.md';
|
||||
import { defineComponent } from '@vue/composition-api';
|
||||
|
||||
export default {
|
||||
title: 'Displays / Formatted Text',
|
||||
decorators: [withPadding, withKnobs],
|
||||
parameters: {
|
||||
notes: readme,
|
||||
},
|
||||
};
|
||||
|
||||
export const basic = () =>
|
||||
defineComponent({
|
||||
props: {
|
||||
value: {
|
||||
default: text('Value', 'This is the value of the field'),
|
||||
},
|
||||
bold: {
|
||||
default: boolean('Bold', false),
|
||||
},
|
||||
subdued: {
|
||||
default: boolean('Subdued', false),
|
||||
},
|
||||
font: {
|
||||
default: select('Font', ['sans-serif', 'serif', 'monospace'], 'sans-serif'),
|
||||
},
|
||||
},
|
||||
template: `
|
||||
<display-formatted-text
|
||||
:value="value"
|
||||
:bold="bold"
|
||||
:subdued="subdued"
|
||||
:font="font"
|
||||
/>
|
||||
`,
|
||||
});
|
||||
@@ -1,20 +0,0 @@
|
||||
import DisplayFormattedText from './formatted-text.vue';
|
||||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||
import VueCompositionAPI from '@vue/composition-api';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(VueCompositionAPI);
|
||||
|
||||
describe('Displays / Formatted Text', () => {
|
||||
it('Strips out HTML', () => {
|
||||
const component = shallowMount(DisplayFormattedText, {
|
||||
localVue,
|
||||
propsData: {
|
||||
value: '<p>Test</p>',
|
||||
},
|
||||
});
|
||||
|
||||
expect((component.vm as any).displayValue).toBe('Test');
|
||||
expect(component.text()).toBe('Test');
|
||||
});
|
||||
});
|
||||
@@ -1,37 +0,0 @@
|
||||
import { defineDisplay } from '@/displays/define';
|
||||
import DisplayFormattedText from './formatted-text.vue';
|
||||
|
||||
export default defineDisplay(({ i18n }) => ({
|
||||
id: 'formatted-text',
|
||||
name: i18n.t('formatted_text'),
|
||||
types: ['string', 'text'],
|
||||
icon: 'text_format',
|
||||
handler: DisplayFormattedText,
|
||||
options: [
|
||||
{
|
||||
field: 'bold',
|
||||
name: i18n.t('bold'),
|
||||
width: 'half',
|
||||
interface: 'toggle',
|
||||
},
|
||||
{
|
||||
field: 'subdued',
|
||||
name: i18n.t('subdued'),
|
||||
width: 'half',
|
||||
interface: 'toggle',
|
||||
},
|
||||
{
|
||||
field: 'font',
|
||||
name: i18n.t('font'),
|
||||
width: 'half',
|
||||
interface: 'dropdown',
|
||||
options: {
|
||||
choices: [
|
||||
{ text: i18n.t('sans_serif'), value: 'sans-serif' },
|
||||
{ text: i18n.t('serif'), value: 'serif' },
|
||||
{ text: i18n.t('monospace'), value: 'monospace' },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
}));
|
||||
@@ -1,20 +1,14 @@
|
||||
<template>
|
||||
<span
|
||||
class="display-formatted-text"
|
||||
:class="[
|
||||
{
|
||||
bold,
|
||||
subdued,
|
||||
},
|
||||
font,
|
||||
]"
|
||||
>
|
||||
<value-null v-if="!displayValue" />
|
||||
|
||||
<span v-else class="display-formatted-text" :class="[{ bold }, font]" :style="{ color }">
|
||||
{{ displayValue }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed } from '@vue/composition-api';
|
||||
import formatTitle from '@directus/format-title';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@@ -22,17 +16,17 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
interfaceOptions: {
|
||||
type: Object,
|
||||
default: null,
|
||||
formatTitle: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
bold: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
subdued: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
color: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
font: {
|
||||
type: String,
|
||||
@@ -41,7 +35,17 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const displayValue = computed(() => props.value.replace(/(<([^>]+)>)/gi, ''));
|
||||
const displayValue = computed(() => {
|
||||
if (!props.value) return null;
|
||||
let value = String(props.value);
|
||||
value = props.value.replace(/(<([^>]+)>)/gi, '');
|
||||
|
||||
if (props.formatTitle) {
|
||||
value = formatTitle(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
});
|
||||
|
||||
return { displayValue };
|
||||
},
|
||||
60
app/src/displays/formatted-value/index.ts
Normal file
60
app/src/displays/formatted-value/index.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { defineDisplay } from '@/displays/define';
|
||||
import DisplayFormattedValue from './formatted-value.vue';
|
||||
|
||||
export default defineDisplay(({ i18n }) => ({
|
||||
id: 'formatted-value',
|
||||
name: i18n.t('formatted_value'),
|
||||
types: ['string', 'text'],
|
||||
icon: 'text_format',
|
||||
handler: DisplayFormattedValue,
|
||||
options: [
|
||||
{
|
||||
field: 'formatTitle',
|
||||
name: i18n.t('format_title'),
|
||||
meta: {
|
||||
width: 'half',
|
||||
interface: 'toggle',
|
||||
options: {
|
||||
label: i18n.t('auto_format_casing'),
|
||||
},
|
||||
},
|
||||
schema: {
|
||||
default_value: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'bold',
|
||||
name: i18n.t('bold'),
|
||||
meta: {
|
||||
width: 'half',
|
||||
interface: 'toggle',
|
||||
options: {
|
||||
label: i18n.t('use_bold_style'),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'color',
|
||||
name: i18n.t('color'),
|
||||
meta: {
|
||||
width: 'half',
|
||||
interface: 'color',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'font',
|
||||
name: i18n.t('font'),
|
||||
meta: {
|
||||
width: 'half',
|
||||
interface: 'dropdown',
|
||||
options: {
|
||||
choices: [
|
||||
{ text: i18n.t('sans_serif'), value: 'sans-serif' },
|
||||
{ text: i18n.t('serif'), value: 'serif' },
|
||||
{ text: i18n.t('monospace'), value: 'monospace' },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}));
|
||||
@@ -3,8 +3,7 @@ import DisplayCollection from './collection';
|
||||
import DisplayDateTime from './datetime';
|
||||
import DisplayFile from './file';
|
||||
import DisplayFilesize from './filesize';
|
||||
import DisplayFormattedText from './formatted-text';
|
||||
import DisplayFormatTitle from './format-title/';
|
||||
import DisplayFormattedValue from './formatted-value';
|
||||
import DisplayIcon from './icon/';
|
||||
import DisplayImage from './image';
|
||||
import DisplayMimeType from './mime-type';
|
||||
@@ -18,13 +17,12 @@ import DisplayUser from './user';
|
||||
|
||||
export const displays = [
|
||||
DisplayRaw,
|
||||
DisplayFormattedValue,
|
||||
DisplayBadge,
|
||||
DisplayCollection,
|
||||
DisplayDateTime,
|
||||
DisplayFile,
|
||||
DisplayFilesize,
|
||||
DisplayFormattedText,
|
||||
DisplayFormatTitle,
|
||||
DisplayIcon,
|
||||
DisplayImage,
|
||||
DisplayMimeType,
|
||||
|
||||
@@ -420,6 +420,12 @@
|
||||
|
||||
"enabled": "Enabled",
|
||||
|
||||
"use_bold_style": "Use bold style",
|
||||
|
||||
"formatted_value": "Formatted Value",
|
||||
"format_title": "Format Title",
|
||||
"auto_format_casing": "Auto-format casing",
|
||||
|
||||
"errors": {
|
||||
"3": "Only super admins have access to this",
|
||||
"4": "Super Admin Token not provided",
|
||||
@@ -641,7 +647,6 @@
|
||||
"status_dot": "Status (Dot)",
|
||||
"status_badge": "Status (Badge)",
|
||||
"tags": "Tags",
|
||||
"formatted_text": "Formatted Text",
|
||||
"format_text": "Format Text",
|
||||
|
||||
"bold": "Bold",
|
||||
|
||||
Reference in New Issue
Block a user