From e5aada55613673b2af4391cbaa44a91c15f310d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Sat, 2 Jul 2022 15:13:02 +0200 Subject: [PATCH] add locals on MyCalendar app --- .../Resources/public/types.ts | 10 ++ .../Resources/public/vuejs/Calendar/api.ts | 10 +- .../public/vuejs/Calendar/store/utils.ts | 13 ++- .../public/vuejs/MyCalendarRange/App2.vue | 1 + .../vuejs/MyCalendarRange/store/index.ts | 3 + .../store/modules/calendarLocals.ts | 95 +++++++++++++++++++ .../store/modules/fullcalendar.ts | 3 +- .../ChillMainBundle/Resources/public/types.ts | 5 + .../Resources/public/types.ts | 22 +++++ 9 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/store/modules/calendarLocals.ts create mode 100644 src/Bundle/ChillPersonBundle/Resources/public/types.ts diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/types.ts b/src/Bundle/ChillCalendarBundle/Resources/public/types.ts index 12cd6abbe..ebc7ab7be 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/types.ts +++ b/src/Bundle/ChillCalendarBundle/Resources/public/types.ts @@ -1,5 +1,6 @@ import {EventInput} from '@fullcalendar/vue3'; import {DateTime, Location, User, UserAssociatedInterface} from '../../../ChillMainBundle/Resources/public/types' ; +import {Person} from "../../../ChillPersonBundle/Resources/public/types"; export interface CalendarRange { id: number; @@ -30,6 +31,15 @@ export interface Calendar { id: number; } +export interface CalendarLight { + id: number; + endDate: DateTime; + startDate: DateTime; + mainUser: User; + persons: Person[]; + status: "valid" | "moved" | "canceled"; +} + export interface CalendarRemote { id: number; endDate: DateTime; diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/api.ts b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/api.ts index f209a632a..17ef256ad 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/api.ts +++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/api.ts @@ -1,7 +1,7 @@ import {fetchResults} from '../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods'; import {datetimeToISO} from '../../../../../ChillMainBundle/Resources/public/chill/js/date'; import {User} from '../../../../../ChillMainBundle/Resources/public/types'; -import {CalendarRange, CalendarRemote} from '../../types'; +import {CalendarLight, CalendarRange, CalendarRemote} from '../../types'; // re-export whoami export {whoami} from "../../../../../ChillMainBundle/Resources/public/lib/api/user"; @@ -28,3 +28,11 @@ export const fetchCalendarRemoteForUser = (user: User, start: Date, end: Date): return fetchResults(uri, {dateFrom, dateTo}); } + +export const fetchCalendarLocalForUser = (user: User, start: Date, end: Date): Promise => { + const uri = `/api/1.0/calendar/calendar/by-user/${user.id}.json`; + const dateFrom = datetimeToISO(start); + const dateTo = datetimeToISO(end); + + return fetchResults(uri, {dateFrom, dateTo}); +} diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/utils.ts b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/utils.ts index 678d70926..a446a7ebd 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/utils.ts +++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/utils.ts @@ -1,7 +1,7 @@ import {COLORS} from '../const'; import {ISOToDatetime} from '../../../../../../ChillMainBundle/Resources/public/chill/js/date'; import {DateTime, User} from '../../../../../../ChillMainBundle/Resources/public/types'; -import {CalendarRange, CalendarRemote} from '../../../types'; +import {CalendarLight, CalendarRange, CalendarRemote} from '../../../types'; import type {EventInputCalendarRange} from '../../../types'; import {EventInput} from '@fullcalendar/vue3'; @@ -90,3 +90,14 @@ export const remoteToFullCalendarEvent = (entity: CalendarRemote): EventInput & is: 'remote', }; } + +export const localsToFullCalendarEvent = (entity: CalendarLight): EventInput & {id: string} => { + return { + id: `local_${entity.id}`, + title: entity.persons.map(p => p.text).join(', '), + start: entity.startDate.datetime8601, + end: entity.endDate.datetime8601, + allDay: false, + is: 'local', + }; +} diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue index 2e6769a2a..5cbd17a76 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue +++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue @@ -74,6 +74,7 @@ {{ arg.event.title}} {{ arg.timeText }} - {{ arg.event.extendedProps.locationName }} + {{ arg.event.title}} no 'is' diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/store/index.ts b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/store/index.ts index 1f0798f55..f87832cb5 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/store/index.ts +++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/store/index.ts @@ -8,12 +8,14 @@ import calendarRemotes, {CalendarRemotesState} from './modules/calendarRemotes'; import {whoami} from "../../../../../../ChillMainBundle/Resources/public/lib/api/user"; import {User} from '../../../../../../ChillMainBundle/Resources/public/types'; import locations, {LocationState} from "./modules/location"; +import calendarLocals, {CalendarLocalsState} from "./modules/calendarLocals"; const debug = process.env.NODE_ENV !== 'production'; export interface State { calendarRanges: CalendarRangesState, calendarRemotes: CalendarRemotesState, + calendarLocals: CalendarLocalsState, fullCalendar: FullCalendarState, me: MeState, locations: LocationState @@ -30,6 +32,7 @@ const futureStore = function(): Promise> { fullCalendar, calendarRanges, calendarRemotes, + calendarLocals, locations, }, mutations: {} diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/store/modules/calendarLocals.ts b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/store/modules/calendarLocals.ts new file mode 100644 index 000000000..12df9663d --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/store/modules/calendarLocals.ts @@ -0,0 +1,95 @@ +import {State} from './../index'; +import {ActionContext, Module} from 'vuex'; +import {CalendarLight} from '../../../../types'; +import {fetchCalendarLocalForUser} from '../../../Calendar/api'; +import {EventInput} from '@fullcalendar/vue3'; +import {localsToFullCalendarEvent} from "../../../Calendar/store/utils"; +import {TransportExceptionInterface} from "../../../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods"; +import {COLORS} from "../../../Calendar/const"; + +export interface CalendarLocalsState { + locals: EventInput[], + localsLoaded: {start: number, end: number}[], + localsIndex: Set, + key: number +} + +type Context = ActionContext; + +export default > { + namespaced: true, + state: (): CalendarLocalsState => ({ + locals: [], + localsLoaded: [], + localsIndex: new Set(), + key: 0 + }), + getters: { + isLocalsLoaded: (state: CalendarLocalsState) => ({start, end}: {start: Date, end: Date}): boolean => { + for (let range of state.localsLoaded) { + if (start.getTime() === range.start && end.getTime() === range.end) { + return true; + } + } + + return false; + }, + }, + mutations: { + addLocals(state: CalendarLocalsState, ranges: CalendarLight[]) { + console.log('addLocals', ranges); + + const toAdd = ranges + .map(cr => localsToFullCalendarEvent(cr)) + .filter(r => !state.localsIndex.has(r.id)); + + toAdd.forEach((r) => { + state.localsIndex.add(r.id); + state.locals.push(r); + }); + state.key = state.key + toAdd.length; + }, + addLoaded(state: CalendarLocalsState, payload: {start: Date, end: Date}) { + state.localsLoaded.push({start: payload.start.getTime(), end: payload.end.getTime()}); + }, + }, + actions: { + fetchLocals(ctx: Context, payload: {start: Date, end: Date}): Promise { + const start = payload.start; + const end = payload.end; + + if (ctx.rootGetters['me/getMe'] === null) { + return Promise.resolve(null); + } + + if (ctx.getters.isLocalsLoaded({start, end})) { + return Promise.resolve(ctx.getters.getRangeSource); + } + + ctx.commit('addLoaded', { + start: start, + end: end, + }); + + return fetchCalendarLocalForUser( + ctx.rootGetters['me/getMe'], + start, + end + ) + .then((remotes: CalendarLight[]) => { + // to be add when reactivity problem will be solve ? + //ctx.commit('addRemotes', remotes); + const inputs = remotes + .map(cr => localsToFullCalendarEvent(cr)) + .map(cr => ({...cr, backgroundColor: COLORS[0], textColor: 'black', editable: false})) + ctx.commit('calendarRanges/addExternals', inputs, {root: true}); + return Promise.resolve(null); + }) + .catch((e: TransportExceptionInterface) => { + console.error(e); + + return Promise.resolve(null); + }); + } + } +}; diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/store/modules/fullcalendar.ts b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/store/modules/fullcalendar.ts index 786dffec9..de379753f 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/store/modules/fullcalendar.ts +++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/store/modules/fullcalendar.ts @@ -41,7 +41,8 @@ export default { return Promise.all([ ctx.dispatch('calendarRanges/fetchRanges', {start, end}, {root: true}).then(_ => Promise.resolve(null)), - ctx.dispatch('calendarRemotes/fetchRemotes', {start, end}, {root: true}).then(_ => Promise.resolve(null)) + ctx.dispatch('calendarRemotes/fetchRemotes', {start, end}, {root: true}).then(_ => Promise.resolve(null)), + ctx.dispatch('calendarLocals/fetchLocals', {start, end}, {root: true}).then(_ => Promise.resolve(null)) ] ).then(_ => Promise.resolve(null)); diff --git a/src/Bundle/ChillMainBundle/Resources/public/types.ts b/src/Bundle/ChillMainBundle/Resources/public/types.ts index 859edf2cc..142864393 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/types.ts +++ b/src/Bundle/ChillMainBundle/Resources/public/types.ts @@ -3,6 +3,11 @@ export interface DateTime { datetime8601: string } +export interface Civility { + id: number; + // TODO +} + export interface Job { id: number; type: "user_job"; diff --git a/src/Bundle/ChillPersonBundle/Resources/public/types.ts b/src/Bundle/ChillPersonBundle/Resources/public/types.ts new file mode 100644 index 000000000..755c23e2d --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/public/types.ts @@ -0,0 +1,22 @@ +import {Address, Center, Civility, DateTime} from "../../../ChillMainBundle/Resources/public/types"; + +export interface Person { + id: number; + type: "person"; + text: string; + textAge: string; + firstName: string; + lastName: string; + current_household_address: Address | null; + birthdate: DateTime | null; + deathdate: DateTime | null; + age: number; + phonenumber: string; + mobilenumber: string; + email: string; + gender: "woman" | "man" | "other"; + centers: Center[]; + civility: Civility | null; + current_household_id: number; + current_residential_addresses: Address[]; +}