mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch 'issue123_duplicate_calendar_range_by_week' into 'master'
Add a button to duplicate calendar ranges from a week to another one See merge request Chill-Projet/chill-bundles!706
This commit is contained in:
commit
fa91e9494d
5
.changes/unreleased/Feature-20240701-153223.yaml
Normal file
5
.changes/unreleased/Feature-20240701-153223.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
kind: Feature
|
||||||
|
body: Add a button to duplicate calendar ranges from a week to another one
|
||||||
|
time: 2024-07-01T15:32:23.602091234+02:00
|
||||||
|
custom:
|
||||||
|
Issue: "123"
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm">
|
<div class="col-sm">
|
||||||
<label class="form-label">{{ $t('created_availabilities') }}</label>
|
<label class="form-label">{{ $t("created_availabilities") }}</label>
|
||||||
<vue-multiselect
|
<vue-multiselect
|
||||||
v-model="pickedLocation"
|
v-model="pickedLocation"
|
||||||
:options="locations"
|
:options="locations"
|
||||||
@ -14,10 +14,15 @@
|
|||||||
></vue-multiselect>
|
></vue-multiselect>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="display-options row justify-content-between" style="margin-top: 1rem;">
|
<div
|
||||||
|
class="display-options row justify-content-between"
|
||||||
|
style="margin-top: 1rem"
|
||||||
|
>
|
||||||
<div class="col-sm-9 col-xs-12">
|
<div class="col-sm-9 col-xs-12">
|
||||||
<div class="input-group mb-3">
|
<div class="input-group mb-3">
|
||||||
<label class="input-group-text" for="slotDuration">Durée des créneaux</label>
|
<label class="input-group-text" for="slotDuration"
|
||||||
|
>Durée des créneaux</label
|
||||||
|
>
|
||||||
<select v-model="slotDuration" id="slotDuration" class="form-select">
|
<select v-model="slotDuration" id="slotDuration" class="form-select">
|
||||||
<option value="00:05:00">5 minutes</option>
|
<option value="00:05:00">5 minutes</option>
|
||||||
<option value="00:10:00">10 minutes</option>
|
<option value="00:10:00">10 minutes</option>
|
||||||
@ -58,13 +63,20 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-3 col-xs-12">
|
<div class="col-xs-12 col-sm-3">
|
||||||
<div class="float-end">
|
<div class="float-end">
|
||||||
<div class="form-check input-group">
|
<div class="form-check input-group">
|
||||||
<span class="input-group-text">
|
<span class="input-group-text">
|
||||||
<input id="showHideWE" class="mt-0" type="checkbox" v-model="showWeekends">
|
<input
|
||||||
|
id="showHideWE"
|
||||||
|
class="mt-0"
|
||||||
|
type="checkbox"
|
||||||
|
v-model="showWeekends"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
<label for="showHideWE" class="form-check-label input-group-text">Week-ends</label>
|
<label for="showHideWE" class="form-check-label input-group-text"
|
||||||
|
>Week-ends</label
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -72,39 +84,86 @@
|
|||||||
<FullCalendar :options="calendarOptions" ref="calendarRef">
|
<FullCalendar :options="calendarOptions" ref="calendarRef">
|
||||||
<template v-slot:eventContent="arg: EventApi">
|
<template v-slot:eventContent="arg: EventApi">
|
||||||
<span :class="eventClasses(arg.event)">
|
<span :class="eventClasses(arg.event)">
|
||||||
<b v-if="arg.event.extendedProps.is === 'remote'">{{ arg.event.title}}</b>
|
<b v-if="arg.event.extendedProps.is === 'remote'">{{
|
||||||
<b v-else-if="arg.event.extendedProps.is === 'range'">{{ arg.timeText }} - {{ arg.event.extendedProps.locationName }}</b>
|
arg.event.title
|
||||||
<b v-else-if="arg.event.extendedProps.is === 'local'">{{ arg.event.title}}</b>
|
}}</b>
|
||||||
<b v-else >no 'is'</b>
|
<b v-else-if="arg.event.extendedProps.is === 'range'"
|
||||||
<a v-if="arg.event.extendedProps.is === 'range'" class="fa fa-fw fa-times delete"
|
>{{ arg.timeText }} - {{ arg.event.extendedProps.locationName }}</b
|
||||||
@click.prevent="onClickDelete(arg.event)">
|
>
|
||||||
</a>
|
<b v-else-if="arg.event.extendedProps.is === 'local'">{{
|
||||||
</span>
|
arg.event.title
|
||||||
|
}}</b>
|
||||||
|
<b v-else>no 'is'</b>
|
||||||
|
<a
|
||||||
|
v-if="arg.event.extendedProps.is === 'range'"
|
||||||
|
class="fa fa-fw fa-times delete"
|
||||||
|
@click.prevent="onClickDelete(arg.event)"
|
||||||
|
>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</FullCalendar>
|
</FullCalendar>
|
||||||
|
|
||||||
<div id="copy-widget">
|
<div id="copy-widget">
|
||||||
<div class="container">
|
<div class="container mt-2 mb-2">
|
||||||
<div class="row align-items-center">
|
|
||||||
<div class="col-sm-4 col-xs-12">
|
<div class="row justify-content-between align-items-center mb-4">
|
||||||
<h6 class="chill-red">{{ $t('copy_range_from_to') }}</h6>
|
<div class="col-xs-12 col-sm-3 col-md-2">
|
||||||
</div>
|
<h6 class="chill-red">{{ $t("copy_range_from_to") }}</h6>
|
||||||
<div class="col-sm-3 col-xs-12">
|
</div>
|
||||||
<input class="form-control" type="date" v-model="copyFrom" />
|
<div class="col-xs-12 col-sm-9 col-md-2">
|
||||||
</div>
|
<select v-model="dayOrWeek" id="dayOrWeek" class="form-select">
|
||||||
<div class="col-sm-1 col-xs-12" style="text-align: center; font-size: x-large;">
|
<option value="day">{{ $t("from_day_to_day") }}</option>
|
||||||
<i class="fa fa-angle-double-right"></i>
|
<option value="week">{{ $t("from_week_to_week") }}</option>
|
||||||
</div>
|
</select>
|
||||||
<div class="col-sm-3 col-xs-12" >
|
</div>
|
||||||
<input class="form-control" type="date" v-model="copyTo" />
|
<template v-if="dayOrWeek === 'day'">
|
||||||
</div>
|
<div class="col-xs-12 col-sm-3 col-md-3">
|
||||||
<div class="col-sm-1">
|
<input class="form-control" type="date" v-model="copyFrom" />
|
||||||
<button class="btn btn-action" @click="copyDay">
|
</div>
|
||||||
{{ $t('copy_range') }}
|
<div class="col-xs-12 col-sm-1 col-md-1 copy-chevron">
|
||||||
</button>
|
<i class="fa fa-angle-double-right"></i>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-12 col-sm-3 col-md-3">
|
||||||
|
<input class="form-control" type="date" v-model="copyTo" />
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-12 col-sm-5 col-md-1">
|
||||||
|
<button class="btn btn-action float-end" @click="copyDay">
|
||||||
|
{{ $t("copy_range") }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<div class="col-xs-12 col-sm-3 col-md-3">
|
||||||
|
<select
|
||||||
|
v-model="copyFromWeek"
|
||||||
|
id="copyFromWeek"
|
||||||
|
class="form-select"
|
||||||
|
>
|
||||||
|
<option v-for="w in lastWeeks" :value="w.value" :key="w.value">
|
||||||
|
{{ w.text }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-12 col-sm-1 col-md-1 copy-chevron">
|
||||||
|
<i class="fa fa-angle-double-right"></i>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-12 col-sm-3 col-md-3">
|
||||||
|
<select v-model="copyToWeek" id="copyToWeek" class="form-select">
|
||||||
|
<option v-for="w in nextWeeks" :value="w.value" :key="w.value">
|
||||||
|
{{ w.text }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-12 col-sm-5 col-md-1">
|
||||||
|
<button class="btn btn-action float-end" @click="copyWeek">
|
||||||
|
{{ $t("copy_range") }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- not directly seen, but include in a modal -->
|
<!-- not directly seen, but include in a modal -->
|
||||||
@ -112,42 +171,95 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
CalendarOptions,
|
CalendarOptions,
|
||||||
DatesSetArg,
|
DatesSetArg,
|
||||||
EventInput
|
EventInput,
|
||||||
} from '@fullcalendar/core';
|
} from "@fullcalendar/core";
|
||||||
import {reactive, computed, ref} from "vue";
|
import { reactive, computed, ref, onMounted } from "vue";
|
||||||
import {useStore} from "vuex";
|
import { useStore } from "vuex";
|
||||||
import {key} from './store';
|
import { key } from "./store";
|
||||||
import FullCalendar from '@fullcalendar/vue3';
|
import FullCalendar from "@fullcalendar/vue3";
|
||||||
import frLocale from '@fullcalendar/core/locales/fr';
|
import frLocale from "@fullcalendar/core/locales/fr";
|
||||||
import interactionPlugin, {DropArg, EventResizeDoneArg} from "@fullcalendar/interaction";
|
import interactionPlugin, {
|
||||||
|
DropArg,
|
||||||
|
EventResizeDoneArg,
|
||||||
|
} from "@fullcalendar/interaction";
|
||||||
import timeGridPlugin from "@fullcalendar/timegrid";
|
import timeGridPlugin from "@fullcalendar/timegrid";
|
||||||
import {EventApi, DateSelectArg, EventDropArg, EventClickArg} from "@fullcalendar/core";
|
import {
|
||||||
import {ISOToDate} from "../../../../../ChillMainBundle/Resources/public/chill/js/date";
|
EventApi,
|
||||||
|
DateSelectArg,
|
||||||
|
EventDropArg,
|
||||||
|
EventClickArg,
|
||||||
|
} from "@fullcalendar/core";
|
||||||
|
import {
|
||||||
|
dateToISO,
|
||||||
|
ISOToDate,
|
||||||
|
} from "../../../../../ChillMainBundle/Resources/public/chill/js/date";
|
||||||
import VueMultiselect from "vue-multiselect";
|
import VueMultiselect from "vue-multiselect";
|
||||||
import {Location} from "../../../../../ChillMainBundle/Resources/public/types";
|
import { Location } from "../../../../../ChillMainBundle/Resources/public/types";
|
||||||
import EditLocation from "./Components/EditLocation.vue";
|
import EditLocation from "./Components/EditLocation.vue";
|
||||||
import {useI18n} from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
const store = useStore(key);
|
const store = useStore(key);
|
||||||
|
|
||||||
const {t} = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const showWeekends = ref(false);
|
const showWeekends = ref(false);
|
||||||
const slotDuration = ref('00:05:00');
|
const slotDuration = ref("00:15:00");
|
||||||
const slotMinTime = ref('09:00:00');
|
const slotMinTime = ref("09:00:00");
|
||||||
const slotMaxTime = ref('18:00:00');
|
const slotMaxTime = ref("18:00:00");
|
||||||
const copyFrom = ref<string | null>(null);
|
const copyFrom = ref<string | null>(null);
|
||||||
const copyTo = ref<string | null>(null);
|
const copyTo = ref<string | null>(null);
|
||||||
const editLocation = ref<InstanceType<typeof EditLocation> | null>(null)
|
const editLocation = ref<InstanceType<typeof EditLocation> | null>(null);
|
||||||
|
const dayOrWeek = ref("day");
|
||||||
|
const copyFromWeek = ref<string | null>(null);
|
||||||
|
const copyToWeek = ref<string | null>(null);
|
||||||
|
|
||||||
|
interface Weeks {
|
||||||
|
value: string | null;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getMonday = (week: number): Date => {
|
||||||
|
const lastMonday = new Date();
|
||||||
|
lastMonday.setDate(
|
||||||
|
lastMonday.getDate() - ((lastMonday.getDay() + 6) % 7) + week * 7
|
||||||
|
);
|
||||||
|
return lastMonday;
|
||||||
|
};
|
||||||
|
|
||||||
|
const dateOptions: Intl.DateTimeFormatOptions = {
|
||||||
|
weekday: "long",
|
||||||
|
year: "numeric",
|
||||||
|
month: "long",
|
||||||
|
day: "numeric",
|
||||||
|
};
|
||||||
|
|
||||||
|
const lastWeeks = computed((): Weeks[] =>
|
||||||
|
Array.from(Array(30).keys()).map((w) => {
|
||||||
|
const lastMonday = getMonday(15-w);
|
||||||
|
return {
|
||||||
|
value: dateToISO(lastMonday),
|
||||||
|
text: `Semaine du ${lastMonday.toLocaleDateString("fr-FR", dateOptions)}`,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const nextWeeks = computed((): Weeks[] =>
|
||||||
|
Array.from(Array(52).keys()).map((w) => {
|
||||||
|
const nextMonday = getMonday(w + 1);
|
||||||
|
return {
|
||||||
|
value: dateToISO(nextMonday),
|
||||||
|
text: `Semaine du ${nextMonday.toLocaleDateString("fr-FR", dateOptions)}`,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
const baseOptions = ref<CalendarOptions>({
|
const baseOptions = ref<CalendarOptions>({
|
||||||
locale: frLocale,
|
locale: frLocale,
|
||||||
plugins: [interactionPlugin, timeGridPlugin],
|
plugins: [interactionPlugin, timeGridPlugin],
|
||||||
initialView: 'timeGridWeek',
|
initialView: "timeGridWeek",
|
||||||
initialDate: new Date(),
|
initialDate: new Date(),
|
||||||
scrollTimeReset: false,
|
scrollTimeReset: false,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
@ -164,9 +276,9 @@ const baseOptions = ref<CalendarOptions>({
|
|||||||
selectMirror: false,
|
selectMirror: false,
|
||||||
editable: true,
|
editable: true,
|
||||||
headerToolbar: {
|
headerToolbar: {
|
||||||
left: 'prev,next today',
|
left: "prev,next today",
|
||||||
center: 'title',
|
center: "title",
|
||||||
right: 'timeGridWeek,timeGridDay'
|
right: "timeGridWeek,timeGridDay",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -180,20 +292,23 @@ const locations = computed<Location[]>(() => {
|
|||||||
|
|
||||||
const pickedLocation = computed<Location | null>({
|
const pickedLocation = computed<Location | null>({
|
||||||
get(): Location | null {
|
get(): Location | null {
|
||||||
return store.state.locations.locationPicked || store.state.locations.currentLocation;
|
return (
|
||||||
|
store.state.locations.locationPicked ||
|
||||||
|
store.state.locations.currentLocation
|
||||||
|
);
|
||||||
},
|
},
|
||||||
set(newLocation: Location | null): void {
|
set(newLocation: Location | null): void {
|
||||||
store.commit('locations/setLocationPicked', newLocation, {root: true});
|
store.commit("locations/setLocationPicked", newLocation, { root: true });
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return the show classes for the event
|
* return the show classes for the event
|
||||||
* @param arg
|
* @param arg
|
||||||
*/
|
*/
|
||||||
const eventClasses = function(arg: EventApi): object {
|
const eventClasses = function (arg: EventApi): object {
|
||||||
return {'calendarRangeItems': true};
|
return { calendarRangeItems: true };
|
||||||
}
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// currently, all events are stored into calendarRanges, due to reactivity bug
|
// currently, all events are stored into calendarRanges, due to reactivity bug
|
||||||
@ -230,51 +345,60 @@ const calendarOptions = computed((): CalendarOptions => {
|
|||||||
* launched when the calendar range date change
|
* launched when the calendar range date change
|
||||||
*/
|
*/
|
||||||
function onDatesSet(event: DatesSetArg): void {
|
function onDatesSet(event: DatesSetArg): void {
|
||||||
store.dispatch('fullCalendar/setCurrentDatesView', {start: event.start, end: event.end});
|
store.dispatch("fullCalendar/setCurrentDatesView", {
|
||||||
|
start: event.start,
|
||||||
|
end: event.end,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDateSelect(event: DateSelectArg): void {
|
function onDateSelect(event: DateSelectArg): void {
|
||||||
|
|
||||||
if (null === pickedLocation.value) {
|
if (null === pickedLocation.value) {
|
||||||
window.alert("Indiquez une localisation avant de créer une période de disponibilité.");
|
window.alert(
|
||||||
|
"Indiquez une localisation avant de créer une période de disponibilité."
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
store.dispatch('calendarRanges/createRange', {start: event.start, end: event.end, location: pickedLocation.value});
|
store.dispatch("calendarRanges/createRange", {
|
||||||
|
start: event.start,
|
||||||
|
end: event.end,
|
||||||
|
location: pickedLocation.value,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When a calendar range is deleted
|
* When a calendar range is deleted
|
||||||
*/
|
*/
|
||||||
function onClickDelete(event: EventApi): void {
|
function onClickDelete(event: EventApi): void {
|
||||||
console.log('onClickDelete', event);
|
if (event.extendedProps.is !== "range") {
|
||||||
|
|
||||||
if (event.extendedProps.is !== 'range') {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
store.dispatch('calendarRanges/deleteRange', event.extendedProps.calendarRangeId);
|
store.dispatch(
|
||||||
|
"calendarRanges/deleteRange",
|
||||||
|
event.extendedProps.calendarRangeId
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onEventDropOrResize(payload: EventDropArg | EventResizeDoneArg) {
|
function onEventDropOrResize(payload: EventDropArg | EventResizeDoneArg) {
|
||||||
if (payload.event.extendedProps.is !== 'range') {
|
if (payload.event.extendedProps.is !== "range") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const changedEvent = payload.event;
|
const changedEvent = payload.event;
|
||||||
|
|
||||||
store.dispatch('calendarRanges/patchRangeTime', {
|
store.dispatch("calendarRanges/patchRangeTime", {
|
||||||
calendarRangeId: payload.event.extendedProps.calendarRangeId,
|
calendarRangeId: payload.event.extendedProps.calendarRangeId,
|
||||||
start: payload.event.start,
|
start: payload.event.start,
|
||||||
end: payload.event.end,
|
end: payload.event.end,
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
function onEventClick(payload: EventClickArg): void {
|
function onEventClick(payload: EventClickArg): void {
|
||||||
// @ts-ignore TS does not recognize the target. But it does exists.
|
// @ts-ignore TS does not recognize the target. But it does exists.
|
||||||
if (payload.jsEvent.target.classList.contains('delete')) {
|
if (payload.jsEvent.target.classList.contains("delete")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (payload.event.extendedProps.is !== 'range') {
|
if (payload.event.extendedProps.is !== "range") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,10 +409,26 @@ function copyDay() {
|
|||||||
if (null === copyFrom.value || null === copyTo.value) {
|
if (null === copyFrom.value || null === copyTo.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
store.dispatch("calendarRanges/copyFromDayToAnotherDay", {
|
||||||
store.dispatch('calendarRanges/copyFromDayToAnotherDay', {from: ISOToDate(copyFrom.value), to: ISOToDate(copyTo.value)})
|
from: ISOToDate(copyFrom.value),
|
||||||
|
to: ISOToDate(copyTo.value),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function copyWeek() {
|
||||||
|
if (null === copyFromWeek.value || null === copyToWeek.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
store.dispatch("calendarRanges/copyFromWeekToAnotherWeek", {
|
||||||
|
fromMonday: ISOToDate(copyFromWeek.value),
|
||||||
|
toMonday: ISOToDate(copyToWeek.value),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
copyFromWeek.value = dateToISO(getMonday(0));
|
||||||
|
copyToWeek.value = dateToISO(getMonday(1));
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -299,4 +439,9 @@ function copyDay() {
|
|||||||
z-index: 9999999999;
|
z-index: 9999999999;
|
||||||
padding: 0.25rem 0 0.25rem;
|
padding: 0.25rem 0 0.25rem;
|
||||||
}
|
}
|
||||||
|
div.copy-chevron {
|
||||||
|
text-align: center;
|
||||||
|
font-size: x-large;
|
||||||
|
width: 2rem;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -5,11 +5,9 @@ const appMessages = {
|
|||||||
show_my_calendar: "Afficher mon calendrier",
|
show_my_calendar: "Afficher mon calendrier",
|
||||||
show_weekends: "Afficher les week-ends",
|
show_weekends: "Afficher les week-ends",
|
||||||
copy_range: "Copier",
|
copy_range: "Copier",
|
||||||
copy_range_from_to: "Copier les plages d'un jour à l'autre",
|
copy_range_from_to: "Copier les plages",
|
||||||
copy_range_to_next_day: "Copier les plages du jour au jour suivant",
|
from_day_to_day: "d'un jour à l'autre",
|
||||||
copy_range_from_day: "Copier les plages du ",
|
from_week_to_week: "d'une semaine à l'autre",
|
||||||
to_the_next_day: " au jour suivant",
|
|
||||||
copy_range_to_next_week: "Copier les plages de la semaine à la semaine suivante",
|
|
||||||
copy_range_how_to: "Créez les plages de disponibilités durant une journée et copiez-les facilement au jour suivant avec ce bouton. Si les week-ends sont cachés, le jour suivant un vendredi sera le lundi.",
|
copy_range_how_to: "Créez les plages de disponibilités durant une journée et copiez-les facilement au jour suivant avec ce bouton. Si les week-ends sont cachés, le jour suivant un vendredi sera le lundi.",
|
||||||
new_range_to_save: "Nouvelles plages à enregistrer",
|
new_range_to_save: "Nouvelles plages à enregistrer",
|
||||||
update_range_to_save: "Plages à modifier",
|
update_range_to_save: "Plages à modifier",
|
||||||
|
@ -52,6 +52,23 @@ export default <Module<CalendarRangesState, State>>{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return founds;
|
||||||
|
},
|
||||||
|
getRangesOnWeek: (state: CalendarRangesState) => (mondayDate: Date): EventInputCalendarRange[] => {
|
||||||
|
const founds = [];
|
||||||
|
for (let d of Array.from(Array(7).keys())) {
|
||||||
|
const dateOfWeek = new Date(mondayDate);
|
||||||
|
dateOfWeek.setDate(mondayDate.getDate() + d);
|
||||||
|
const dateStr = <string>dateToISO(dateOfWeek);
|
||||||
|
for (let range of state.ranges) {
|
||||||
|
if (isEventInputCalendarRange(range)
|
||||||
|
&& range.start.startsWith(dateStr)
|
||||||
|
) {
|
||||||
|
founds.push(range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return founds;
|
return founds;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -238,7 +255,7 @@ export default <Module<CalendarRangesState, State>>{
|
|||||||
|
|
||||||
for (let r of rangesToCopy) {
|
for (let r of rangesToCopy) {
|
||||||
let start = new Date(<Date>ISOToDatetime(r.start));
|
let start = new Date(<Date>ISOToDatetime(r.start));
|
||||||
start.setFullYear(to.getFullYear(), to.getMonth(), to.getDate())
|
start.setFullYear(to.getFullYear(), to.getMonth(), to.getDate());
|
||||||
let end = new Date(<Date>ISOToDatetime(r.end));
|
let end = new Date(<Date>ISOToDatetime(r.end));
|
||||||
end.setFullYear(to.getFullYear(), to.getMonth(), to.getDate());
|
end.setFullYear(to.getFullYear(), to.getMonth(), to.getDate());
|
||||||
let location = ctx.rootGetters['locations/getLocationById'](r.locationId);
|
let location = ctx.rootGetters['locations/getLocationById'](r.locationId);
|
||||||
@ -246,6 +263,23 @@ export default <Module<CalendarRangesState, State>>{
|
|||||||
promises.push(ctx.dispatch('createRange', {start, end, location}));
|
promises.push(ctx.dispatch('createRange', {start, end, location}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Promise.all(promises).then(_ => Promise.resolve(null));
|
||||||
|
},
|
||||||
|
copyFromWeekToAnotherWeek(ctx, {fromMonday, toMonday}: {fromMonday: Date, toMonday: Date}): Promise<null> {
|
||||||
|
|
||||||
|
const rangesToCopy: EventInputCalendarRange[] = ctx.getters['getRangesOnWeek'](fromMonday);
|
||||||
|
const promises = [];
|
||||||
|
const diffTime = toMonday.getTime() - fromMonday.getTime();
|
||||||
|
for (let r of rangesToCopy) {
|
||||||
|
let start = new Date(<Date>ISOToDatetime(r.start));
|
||||||
|
let end = new Date(<Date>ISOToDatetime(r.end));
|
||||||
|
start.setTime(start.getTime() + diffTime);
|
||||||
|
end.setTime(end.getTime() + diffTime);
|
||||||
|
let location = ctx.rootGetters['locations/getLocationById'](r.locationId);
|
||||||
|
|
||||||
|
promises.push(ctx.dispatch('createRange', {start, end, location}));
|
||||||
|
}
|
||||||
|
|
||||||
return Promise.all(promises).then(_ => Promise.resolve(null));
|
return Promise.all(promises).then(_ => Promise.resolve(null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user