feature: copy ranges

This commit is contained in:
Julien Fastré 2022-06-27 21:27:37 +02:00
parent b5d5338002
commit 13dae00a2c
4 changed files with 69 additions and 4 deletions

View File

@ -38,7 +38,13 @@ export type EventInputCalendarRange = EventInput & {
id: string, id: string,
userId: number, userId: number,
calendarRangeId: number, calendarRangeId: number,
start: string,
end: string,
is: "range" is: "range"
}; };
export function isEventInputCalendarRange(toBeDetermined: EventInputCalendarRange | EventInput): toBeDetermined is EventInputCalendarRange {
return typeof toBeDetermined.is === "string" && toBeDetermined.is === "range";
}
export {}; export {};

View File

@ -35,6 +35,22 @@
</span> </span>
</template> </template>
</FullCalendar> </FullCalendar>
<div id="copy-widget">
<h4 class="chill-red" style="margin-top: 2rem;">{{ 'copy_range_from_to' }}</h4>
<div style="display: flex; margin-top: 1rem;">
<div class="col-sm-3" style="margin-right: 1rem">
<input class="form-control" type="date" v-model="copyFrom" />
</div>
<i class="fa fa-angle-double-right" style="font-size: 2rem; margin-right: 1rem"></i>
<div class="col-sm-3" style="margin-right: 1rem">
<input class="form-control" type="date" v-model="copyTo" />
</div>
<button class="btn btn-action" @click="copyDay">
{{ 'copy_range' }}
</button>
</div>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -54,11 +70,14 @@ 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} from "@fullcalendar/core"; import {EventApi, DateSelectArg, EventDropArg} from "@fullcalendar/core";
import {ISOToDate, ISOToDatetime} from "../../../../../ChillMainBundle/Resources/public/chill/js/date";
const store = useStore(key); const store = useStore(key);
const showWeekends = ref(true); const showWeekends = ref(true);
const slotDuration = ref('00:15:00'); const slotDuration = ref('00:15:00');
const copyFrom = ref<string | null>(null);
const copyTo = ref<string | null>(null);
const baseOptions = ref<CalendarOptions>({ const baseOptions = ref<CalendarOptions>({
locale: frLocale, locale: frLocale,
@ -162,6 +181,14 @@ function onEventDropOrResize(payload: EventDropArg | EventResizeDoneArg) {
}); });
}; };
function copyDay() {
if (null === copyFrom.value || null === copyTo.value) {
return;
}
store.dispatch('calendarRanges/copyFromDayToAnotherDay', {from: ISOToDate(copyFrom.value), to: ISOToDate(copyTo.value)})
}
</script> </script>
<style scoped> <style scoped>

View File

@ -1,11 +1,15 @@
import {State} from './../index'; import {State} from './../index';
import {ActionContext, Module} from 'vuex'; import {ActionContext, Module} from 'vuex';
import {CalendarRange, CalendarRangeCreate, CalendarRangeEdit} from "../../../../types"; import {CalendarRange, CalendarRangeCreate, CalendarRangeEdit, isEventInputCalendarRange} from "../../../../types";
import {fetchCalendarRangeForUser} from '../../../Calendar/api'; import {fetchCalendarRangeForUser} from '../../../Calendar/api';
import {calendarRangeToFullCalendarEvent} from '../../../Calendar/store/utils'; import {calendarRangeToFullCalendarEvent} from '../../../Calendar/store/utils';
import {EventInput} from '@fullcalendar/vue3'; import {EventInput} from '@fullcalendar/vue3';
import {makeFetch} from "../../../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods"; import {makeFetch} from "../../../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
import {datetimeToISO} from "../../../../../../../ChillMainBundle/Resources/public/chill/js/date"; import {
datetimeToISO,
dateToISO,
ISOToDatetime
} from "../../../../../../../ChillMainBundle/Resources/public/chill/js/date";
import type {EventInputCalendarRange} from "../../../../types"; import type {EventInputCalendarRange} from "../../../../types";
export interface CalendarRangesState { export interface CalendarRangesState {
@ -35,6 +39,20 @@ export default <Module<CalendarRangesState, State>>{
return false; return false;
}, },
getRangesOnDate: (state: CalendarRangesState) => (date: Date): EventInputCalendarRange[] => {
const founds = [];
const dateStr = <string>dateToISO(date);
for (let range of state.ranges) {
if (isEventInputCalendarRange(range)
&& range.start.startsWith(dateStr)
) {
founds.push(range);
}
}
return founds;
}
}, },
mutations: { mutations: {
addRanges(state: CalendarRangesState, ranges: CalendarRange[]) { addRanges(state: CalendarRangesState, ranges: CalendarRange[]) {
@ -192,7 +210,21 @@ export default <Module<CalendarRangesState, State>>{
.catch((error) => { .catch((error) => {
console.log(error); console.log(error);
}) })
} },
copyFromDayToAnotherDay(ctx, {from, to}: {from: Date, to: Date}): Promise<null> {
const rangesToCopy: EventInputCalendarRange[] = ctx.getters['getRangesOnDate'](from);
const promises = [];
for (let r of rangesToCopy) {
let start = new Date(<Date>ISOToDatetime(r.start));
start.setFullYear(to.getFullYear(), to.getMonth(), to.getDate())
let end = new Date(<Date>ISOToDatetime(r.end));
end.setFullYear(to.getFullYear(), to.getMonth(), to.getDate());
promises.push(ctx.dispatch('createRange', {start, end}));
}
return Promise.all(promises).then(_ => Promise.resolve(null));
}
} }
}; };

View File

@ -40,7 +40,7 @@ export const ISOToDate = (str: string|null): Date|null => {
let let
[year, month, day] = str.split('-').map(p => parseInt(p)); [year, month, day] = str.split('-').map(p => parseInt(p));
return new Date(year, month-1, day); return new Date(year, month-1, day, 0, 0, 0, 0);
} }
/** /**