mirror of
https://github.com/directus/directus.git
synced 2026-01-28 09:57:54 -05:00
Date display (#541)
* Add datetime display * Pass type to displays * Fix types
This commit is contained in:
48
src/displays/datetime/datetime.vue
Normal file
48
src/displays/datetime/datetime.vue
Normal file
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<span>{{ displayValue }}</span>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, watch } from '@vue/composition-api';
|
||||
import formatLocalized from '@/utils/localized-format';
|
||||
import i18n from '@/lang';
|
||||
import parse from 'date-fns/parse';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const displayValue = ref<string>(null);
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
async (newValue) => {
|
||||
if (newValue === null) {
|
||||
displayValue.value = null;
|
||||
return;
|
||||
}
|
||||
|
||||
let format = `${i18n.t('date-fns_date')} ${i18n.t('date-fns_time')}`;
|
||||
|
||||
if (props.type === 'date') format = String(i18n.t('date-fns_date'));
|
||||
if (props.type === 'time') format = String(i18n.t('date-fns_time'));
|
||||
|
||||
displayValue.value = await formatLocalized(
|
||||
parse(props.value, 'yyyy-MM-dd HH:mm:ss', new Date()),
|
||||
format
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
return { displayValue };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
11
src/displays/datetime/index.ts
Normal file
11
src/displays/datetime/index.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { defineDisplay } from '@/displays/define';
|
||||
import DisplayDateTime from './datetime.vue';
|
||||
|
||||
export default defineDisplay(({ i18n }) => ({
|
||||
id: 'datetime',
|
||||
name: i18n.t('datetime'),
|
||||
icon: 'query_builder',
|
||||
handler: DisplayDateTime,
|
||||
options: [],
|
||||
types: ['datetime', 'date', 'time'],
|
||||
}));
|
||||
@@ -18,7 +18,9 @@ export const basic = () =>
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const value = computed<string | null>(() => handler(props.val, null));
|
||||
const value = computed<string | null>(() =>
|
||||
handler(props.val, null, { type: 'string' })
|
||||
);
|
||||
return { value };
|
||||
},
|
||||
template: `
|
||||
|
||||
@@ -5,12 +5,12 @@ jest.mock('@directus/format-title');
|
||||
|
||||
describe('Displays / Format Title', () => {
|
||||
it('Runs the value through the title formatter', () => {
|
||||
handler('test', null);
|
||||
handler('test', null, { type: 'string' });
|
||||
expect(formatTitle).toHaveBeenCalledWith('test');
|
||||
});
|
||||
|
||||
it('Does not pass the value if the value is falsy', () => {
|
||||
handler(null, null);
|
||||
handler(null, null, { type: 'string' });
|
||||
expect(formatTitle).not.toHaveBeenCalledWith(null);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ import DisplayFormattedText from './formatted-text';
|
||||
import DisplayImage from './image';
|
||||
import DisplayUser from './user';
|
||||
import DisplayRating from './rating';
|
||||
import DisplayDateTime from './datetime';
|
||||
|
||||
export const displays = [
|
||||
DisplayIcon,
|
||||
@@ -18,5 +19,6 @@ export const displays = [
|
||||
DisplayImage,
|
||||
DisplayUser,
|
||||
DisplayRating,
|
||||
DisplayDateTime,
|
||||
];
|
||||
export default displays;
|
||||
|
||||
@@ -2,7 +2,15 @@ import VueI18n from 'vue-i18n';
|
||||
import { Component } from 'vue';
|
||||
import { Field } from '@/stores/fields/types';
|
||||
|
||||
export type DisplayHandlerFunction = (value: any, options: any) => string | null;
|
||||
export type DisplayHandlerFunctionContext = {
|
||||
type: string;
|
||||
};
|
||||
|
||||
export type DisplayHandlerFunction = (
|
||||
value: any,
|
||||
options: any,
|
||||
context: DisplayHandlerFunctionContext
|
||||
) => string | null;
|
||||
|
||||
export type DisplayConfig = {
|
||||
id: string;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
:options="header.field.displayOptions"
|
||||
:interface="header.field.interface"
|
||||
:interface-options="header.field.interfaceOptions"
|
||||
:type="header.field.type"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -334,6 +335,7 @@ export default defineComponent({
|
||||
displayOptions: field.display_options,
|
||||
interface: field.interface,
|
||||
interfaceOptions: field.options,
|
||||
type: field.type,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
:options="header.field.displayOptions"
|
||||
:interface="header.field.interface"
|
||||
:interface-options="header.field.interfaceOptions"
|
||||
:type="header.field.type"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -427,6 +428,7 @@ export default defineComponent({
|
||||
displayOptions: field.display_options,
|
||||
interface: field.interface,
|
||||
interfaceOptions: field.options,
|
||||
type: field.type,
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
@@ -12,7 +12,7 @@ export default defineComponent({
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: 'tabular',
|
||||
},
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<value-null v-if="value === null || value === undefined" />
|
||||
<span v-else-if="displayInfo === null">{{ value }}</span>
|
||||
<span v-else-if="typeof displayInfo.handler === 'function'">
|
||||
{{ display.handler(value, options) }}
|
||||
{{ display.handler(value, options, { type }) }}
|
||||
</span>
|
||||
<component
|
||||
v-else
|
||||
@@ -11,6 +11,7 @@
|
||||
:interface="$props.interface"
|
||||
:interface-options="interfaceOptions"
|
||||
:value="value"
|
||||
:type="type"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -42,6 +43,10 @@ export default defineComponent({
|
||||
type: [String, Number, Object, Array],
|
||||
default: null,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const displayInfo = computed(
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
:value="part.value"
|
||||
:interface="part.interface"
|
||||
:interface-options="part.interfaceOptions"
|
||||
:type="part.type"
|
||||
v-bind="part.options"
|
||||
/>
|
||||
<template v-else>{{ part }}</template>
|
||||
@@ -80,6 +81,7 @@ export default defineComponent({
|
||||
value: value,
|
||||
interface: field.interface,
|
||||
interfaceOptions: field.options,
|
||||
type: field.type,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user