diff --git a/aleksis/core/frontend/components/generic/forms/RecurrenceField.vue b/aleksis/core/frontend/components/generic/forms/RecurrenceField.vue new file mode 100644 index 0000000000000000000000000000000000000000..2643fcd962b20ae9c523b7a89381161fe79b108b --- /dev/null +++ b/aleksis/core/frontend/components/generic/forms/RecurrenceField.vue @@ -0,0 +1,125 @@ +<script setup> +import DateField from "./DateField.vue"; +</script> + +<template> + <div> + <v-row> + <v-col class="py-0"> + <div>{{ $attrs.label }}</div> + </v-col> + </v-row> + <v-row> + <v-col v-if="!startDate" cols="4"> + <date-field + v-model="start" + v-bind="{ ...$attrs }" + :label="$t('forms.recurrence.start')" + :disabled="!frequency" + /> + </v-col> + <v-col :cols="startDate ? 8 : 4"> + <v-select + v-model="frequency" + v-bind="{ ...$attrs }" + :label="$t('forms.recurrence.frequency')" + :items="rruleFrequencies" + item-value="freq" + :placeholder="$t('forms.recurrence.no_repeat')" + clearable + /> + </v-col> + <v-col cols="4"> + <date-field + v-model="until" + v-bind="{ ...$attrs }" + :label="$t('forms.recurrence.until')" + :disabled="!frequency" + /> + </v-col> + </v-row> + </div> +</template> + +<script> +import { DateTime } from "luxon"; +import { RRule } from "rrule"; + +export default { + name: "RecurrenceField", + data() { + return { + innerRecurrenceOptions: {}, + rruleFrequencies: [ + { freq: RRule.DAILY, text: this.$t("forms.recurrence.frequencies.daily") }, + { freq: RRule.WEEKLY, text: this.$t("forms.recurrence.frequencies.weekly") }, + { freq: RRule.MONTHLY, text: this.$t("forms.recurrence.frequencies.monthly") }, + { freq: RRule.YEARLY, text: this.$t("forms.recurrence.frequencies.yearly") }, + ], + test: 123, + }; + }, + props: { + value: { + type: String, + required: false, + default: undefined, + }, + startDate: { + type: DateTime, + required: false, + default: undefined, + }, + }, + computed: { + frequency: { + get() { + return this.innerRecurrenceOptions?.freq; + }, + set(value) { + this.innerRecurrenceOptions.freq = value; + this.$emit("input", RRule.optionsToString(this.innerRecurrenceOptions)); + }, + }, + start: { + get() { + return this.innerRecurrenceOptions?.dtstart ? DateTime.fromJSDate(this.innerRecurrenceOptions.dtstart).toISODate() : null; + }, + set(value) { + const date = DateTime.fromISO(value).toUTC().toJSDate(); + + this.innerRecurrenceOptions.dtstart = date; + this.$emit("input", RRule.optionsToString(this.innerRecurrenceOptions)); + }, + }, + until: { + get() { + return this.innerRecurrenceOptions?.until ? DateTime.fromJSDate(this.innerRecurrenceOptions.until).toISODate() : null; + }, + set(value) { + const date = DateTime.fromISO(value).toUTC().toJSDate(); + + this.innerRecurrenceOptions.until = date; + this.$emit("input", RRule.optionsToString(this.innerRecurrenceOptions)); + }, + }, + }, + watch: { + value: { + immediate: true, + handler(newValue) { + this.innerRecurrenceOptions = newValue ? RRule.parseString(newValue) : {}; + }, + }, + startDate: { + deep: true, + immediate: true, + handler(newValue) { + Object.assign(this.innerRecurrenceOptions, { dtstart: newValue.toUTC().startOf("day").toJSDate() }); + }, + }, + }, +}; +</script> + +<style scoped></style>