2
0
mirror of https://github.com/frappe/books.git synced 2025-01-02 22:50:14 +00:00

fix(ux): switch Datetime to use native input

This commit is contained in:
18alantom 2023-06-08 09:57:45 +05:30
parent 3416327635
commit cee5264777
2 changed files with 120 additions and 82 deletions

View File

@ -1,93 +1,25 @@
<template>
<Popover>
<!-- Datetime Selected Display -->
<template #target="{ togglePopover }">
<div :class="labelClasses" v-if="showLabel">
{{ df?.label }}
</div>
<div
:class="[containerClasses, sizeClasses]"
class="flex"
@click="() => !isReadOnly && togglePopover()"
>
<p
:class="[baseInputClasses]"
class="overflow-auto no-scrollbar whitespace-nowrap"
v-if="!isEmpty"
>
{{ formattedValue }}
</p>
<p v-else-if="inputPlaceholder" class="text-base text-gray-500 w-full">
{{ inputPlaceholder }}
</p>
<button v-if="!isReadOnly" class="p-0.5 rounded -me-1 ms-1">
<FeatherIcon
name="calendar"
class="w-4 h-4"
:class="showMandatory ? 'text-red-600' : 'text-gray-600'"
/>
</button>
</div>
</template>
<!-- Datetime Input Popover -->
<template #content>
<DatetimePicker
:show-clear="!isRequired"
:select-time="selectTime"
:model-value="internalValue"
:format-value="formatValue"
@update:model-value="(value) => triggerChange(value)"
/>
</template>
</Popover>
</template>
<script lang="ts">
import { Field } from 'schemas/types';
import { defineComponent, PropType } from 'vue';
import DatetimePicker from './DatetimePicker.vue';
import FeatherIcon from '../FeatherIcon.vue';
import Popover from '../Popover.vue';
import Base from './Base.vue';
import { defineComponent } from 'vue';
import DateVue from './Date.vue';
import { DateTime } from 'luxon';
export default defineComponent({
extends: Base,
props: { value: [Date, String], df: Object as PropType<Field> },
components: { Popover, FeatherIcon, DatetimePicker },
data() {
return { selectTime: true };
},
extends: DateVue,
computed: {
internalValue() {
if (this.value == null) {
return undefined;
inputType() {
return 'datetime-local';
},
inputValue(): string {
let value = this.value;
if (typeof value === 'string') {
value = new Date(value);
}
if (typeof this.value === 'string') {
return new Date(this.value);
if (value instanceof Date && !Number.isNaN(value.valueOf())) {
return DateTime.fromJSDate(value).toISO().split('.')[0];
}
return this.value;
},
formattedValue() {
return this.formatValue(this.internalValue);
},
},
methods: {
triggerChange(value: Date | null) {
this.$emit('change', value);
},
formatValue(value?: Date | null) {
if (value == null) {
return '';
}
return this.fyo.format(
value,
this.df ?? (this.selectTime ? 'Datetime' : 'Date')
);
return '';
},
},
});

View File

@ -0,0 +1,106 @@
<template>
<Popover>
<!-- Datetime Selected Display -->
<template #target="{ togglePopover }">
<div :class="labelClasses" v-if="showLabel">
{{ df?.label }}
</div>
<div
:class="[containerClasses, sizeClasses]"
class="flex"
@click="() => !isReadOnly && togglePopover()"
>
<p
:class="[baseInputClasses]"
class="overflow-auto no-scrollbar whitespace-nowrap"
v-if="!isEmpty"
>
{{ formattedValue }}
</p>
<p v-else-if="inputPlaceholder" class="text-base text-gray-500 w-full">
{{ inputPlaceholder }}
</p>
<button v-if="!isReadOnly" class="p-0.5 rounded -me-1 ms-1">
<FeatherIcon
name="calendar"
class="w-4 h-4"
:class="showMandatory ? 'text-red-600' : 'text-gray-600'"
/>
</button>
</div>
</template>
<!-- Datetime Input Popover -->
<template #content>
<DatetimePicker
:show-clear="!isRequired"
:select-time="selectTime"
:model-value="internalValue"
:format-value="formatValue"
@update:model-value="(value) => triggerChange(value)"
/>
</template>
</Popover>
</template>
<script lang="ts">
/**
* This is a Datetime/Date component that builds
* uses a custom DatetimePicker. It is not being used
* for now because users are more familiar with their
* system's date and datetime picker.
*
* That provides better UX.
*
* This component can be used once the underlying
* DatetimePicker's UX issues are solved.
*/
import { Field } from 'schemas/types';
import { defineComponent, PropType } from 'vue';
import DatetimePicker from './DatetimePicker.vue';
import FeatherIcon from '../FeatherIcon.vue';
import Popover from '../Popover.vue';
import Base from './Base.vue';
export default defineComponent({
extends: Base,
props: { value: [Date, String], df: Object as PropType<Field> },
components: { Popover, FeatherIcon, DatetimePicker },
data() {
return { selectTime: true };
},
computed: {
internalValue() {
if (this.value == null) {
return undefined;
}
if (typeof this.value === 'string') {
return new Date(this.value);
}
return this.value;
},
formattedValue() {
return this.formatValue(this.internalValue);
},
},
methods: {
triggerChange(value: Date | null) {
this.$emit('change', value);
},
formatValue(value?: Date | null) {
if (value == null) {
return '';
}
return this.fyo.format(
value,
this.df ?? (this.selectTime ? 'Datetime' : 'Date')
);
},
},
});
</script>