Use direct datetime picker from Buefy

Closes #494
Closes #459
Closes #207

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2020-12-10 12:16:35 +01:00
parent 118aabf544
commit 736020392b
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773
2 changed files with 38 additions and 162 deletions

View File

@ -1,147 +0,0 @@
<docs>
### Datetime Picker
> We're wrapping the Buefy datepicker & an input
### Defaults
- step: 10
### Example
```vue
<DateTimePicker :value="new Date()" />
```
</docs>
<template>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">{{ label }}</label>
</div>
<div class="field-body">
<div class="field is-narrow is-grouped calendar-picker">
<b-datepicker
:day-names="localeShortWeekDayNamesProxy"
:month-names="localeMonthNamesProxy"
:first-day-of-week="parseInt($t('firstDayOfWeek'), 10)"
:min-date="minDatetime"
:max-date="maxDatetime"
v-model="dateWithTime"
:placeholder="$t('Click to select')"
:years-range="[-2, 10]"
icon="calendar"
class="is-narrow"
/>
<b-timepicker
placeholder="Type or select a time..."
icon="clock"
v-model="dateWithTime"
:min-time="minTime"
:max-time="maxTime"
size="is-small"
inline
>
</b-timepicker>
</div>
</div>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue, Watch } from "vue-property-decorator";
import { localeMonthNames, localeShortWeekDayNames } from "@/utils/datetime";
@Component
export default class DateTimePicker extends Vue {
/**
* @model
* The DateTime value
*/
@Prop({ required: true, type: Date, default: () => new Date() }) value!: Date;
/**
* What's shown besides the picker
*/
@Prop({ required: false, type: String, default: "Datetime" }) label!: string;
/**
* The step for the time input
*/
@Prop({ required: false, type: Number, default: 1 }) step!: number;
/**
* Earliest date available for selection
*/
@Prop({ required: false, type: Date, default: null }) minDatetime!: Date;
/**
* Latest date available for selection
*/
@Prop({ required: false, type: Date, default: null }) maxDatetime!: Date;
dateWithTime: Date = this.value;
localeShortWeekDayNamesProxy = localeShortWeekDayNames();
localeMonthNamesProxy = localeMonthNames();
@Watch("value")
updateValue(): void {
this.dateWithTime = this.value;
}
@Watch("dateWithTime")
updateDateWithTimeWatcher(): void {
this.updateDateTime();
}
updateDateTime(): void {
/**
* Returns the updated date
*
* @type {Date}
*/
this.$emit("input", this.dateWithTime);
}
get minTime(): Date | null {
if (
this.minDatetime &&
this.datesAreOnSameDay(this.dateWithTime, this.minDatetime)
) {
return this.minDatetime;
}
return null;
}
get maxTime(): Date | null {
if (
this.maxDatetime &&
this.datesAreOnSameDay(this.dateWithTime, this.maxDatetime)
) {
return this.maxDatetime;
}
return null;
}
// eslint-disable-next-line class-methods-use-this
private datesAreOnSameDay(first: Date, second: Date): boolean {
return (
first.getFullYear() === second.getFullYear() &&
first.getMonth() === second.getMonth() &&
first.getDate() === second.getDate()
);
}
}
</script>
<style lang="scss" scoped>
.timepicker {
::v-deep .dropdown-content {
padding: 0;
}
}
.calendar-picker {
::v-deep .dropdown-menu {
z-index: 200;
}
}
</style>

View File

@ -31,12 +31,31 @@
<tag-input v-model="event.tags" :data="tags" path="title" /> <tag-input v-model="event.tags" :data="tags" path="title" />
<date-time-picker v-model="event.beginsOn" :label="$t('Starts on…')" /> <b-field horizontal :label="$t('Starts on…')" class="begins-on-field">
<date-time-picker <b-datetimepicker
:min-datetime="event.beginsOn" :placeholder="$t('Type or select a date…')"
icon="calendar-today"
:locale="$i18n.locale"
v-model="event.beginsOn"
horizontal-time-picker
editable
>
</b-datetimepicker>
</b-field>
<b-field horizontal :label="$t('Ends on…')">
<b-datetimepicker
:placeholder="$t('Type or select a date…')"
icon="calendar-today"
:locale="$i18n.locale"
v-model="event.endsOn" v-model="event.endsOn"
:label="$t('Ends on…')" horizontal-time-picker
/> :min-datetime="event.beginsOn"
editable
>
</b-datetimepicker>
</b-field>
<!-- <b-switch v-model="endsOnNull">{{ $t('No end date') }}</b-switch>--> <!-- <b-switch v-model="endsOnNull">{{ $t('No end date') }}</b-switch>-->
<b-button type="is-text" @click="dateSettingsIsOpen = true"> <b-button type="is-text" @click="dateSettingsIsOpen = true">
{{ $t("Date parameters") }} {{ $t("Date parameters") }}
@ -367,6 +386,10 @@ section {
padding: 2rem 1.5rem; padding: 2rem 1.5rem;
} }
.begins-on-field {
margin-top: 22px;
}
nav.navbar { nav.navbar {
min-height: 2rem !important; min-height: 2rem !important;
background: lighten($secondary, 10%); background: lighten($secondary, 10%);
@ -394,7 +417,6 @@ import { Component, Prop, Vue, Watch } from "vue-property-decorator";
import { RefetchQueryDescription } from "apollo-client/core/watchQueryOptions"; import { RefetchQueryDescription } from "apollo-client/core/watchQueryOptions";
import PictureUpload from "@/components/PictureUpload.vue"; import PictureUpload from "@/components/PictureUpload.vue";
import EditorComponent from "@/components/Editor.vue"; import EditorComponent from "@/components/Editor.vue";
import DateTimePicker from "@/components/Event/DateTimePicker.vue";
import TagInput from "@/components/Event/TagInput.vue"; import TagInput from "@/components/Event/TagInput.vue";
import FullAddressAutoComplete from "@/components/Event/FullAddressAutoComplete.vue"; import FullAddressAutoComplete from "@/components/Event/FullAddressAutoComplete.vue";
import IdentityPickerWrapper from "@/views/Account/IdentityPickerWrapper.vue"; import IdentityPickerWrapper from "@/views/Account/IdentityPickerWrapper.vue";
@ -443,7 +465,6 @@ const DEFAULT_LIMIT_NUMBER_OF_PLACES = 10;
IdentityPickerWrapper, IdentityPickerWrapper,
FullAddressAutoComplete, FullAddressAutoComplete,
TagInput, TagInput,
DateTimePicker,
PictureUpload, PictureUpload,
Editor: EditorComponent, Editor: EditorComponent,
}, },
@ -532,14 +553,16 @@ export default class EditEvent extends Vue {
} }
private initializeEvent() { private initializeEvent() {
// TODO : Check me const roundUpTo15Minutes = (time: Date) => {
// const roundUpTo = (roundTo) => (x: number) => new Date(Math.ceil(x / roundTo) * roundTo); time.setMilliseconds(Math.round(time.getMilliseconds() / 1000) * 1000);
// const roundUpTo15Minutes = roundUpTo(1000 * 60 * 15); time.setSeconds(Math.round(time.getSeconds() / 60) * 60);
time.setMinutes(Math.round(time.getMinutes() / 15) * 15);
return time;
};
const now = roundUpTo15Minutes(new Date());
const end = new Date(now.valueOf());
// const now = roundUpTo15Minutes(new Date());
// const end = roundUpTo15Minutes(new Date());
const now = new Date();
const end = new Date();
end.setUTCHours(now.getUTCHours() + 3); end.setUTCHours(now.getUTCHours() + 3);
this.event.beginsOn = now; this.event.beginsOn = now;