import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey' ; import { difference } from 'lodash' ; import { EventManager } from './event_manager' ; import type { MlClient } from '../../lib/ml_client' ; type ScheduledEvent = estypes . MlCalendarEvent ; interface BasicCalendar { job_ids : string [ ] ; description ? : string ; events : ScheduledEvent [ ] ; } export interface Calendar extends BasicCalendar { calendar_id : string ; } export interface FormCalendar extends BasicCalendar { calendarId : string ; } export class CalendarManager { private _mlClient : MlClient ; private _eventManager : EventManager ; constructor ( mlClient ) { this . _mlClient = mlClient ; this . _eventManager = new EventManager ( mlClient ) ; } async getCalendar ( calendarId ) { const { body } = await this . _mlClient . getCalendars ( { calendar_id : calendarId , } ) ; const calendars = body . calendars as Calendar [ ] ; const calendar = calendars [ 0 ] ; calendar . events = await this . _eventManager . getCalendarEvents ( calendarId ) ; return calendar ; } async getAllCalendars ( ) { const { body } = await this . _mlClient . getCalendars ( { body : { page : { from : 0 , size : 1000 } } } ) ; const events = await this . _eventManager . getAllEvents ( ) ; const calendars = body . calendars as Calendar [ ] ; calendars . forEach ( ( cal ) => ( cal . events = [ ] ) ) ; events . forEach ( ( event ) => { const calendar = calendars . find ( ( cal ) => cal . calendar_id === event . calendar_id ) ; if ( calendar && calendar . events ) { calendar . events . push ( event ) ; } } ) ; return calendars ; } param calendarIds returns { Promise < * > } async getCalendarsByIds ( calendarIds ) { const calendars = await this . getAllCalendars ( ) ; return calendars . filter ( ( calendar ) => calendarIds . includes ( calendar . calendar_id ) ) ; } async newCalendar ( calendar ) { const { calendarId , events , ... newCalendar } = calendar ; await this . _mlClient . putCalendar ( { calendar_id : calendarId , body : newCalendar , } ) ; if ( events . length ) { await this . _eventManager . addEvents ( calendarId , events ) ; } return await this . getCalendar ( calendarId ) ; } async updateCalendar ( calendarId , calendar ) { const origCalendar = await this . getCalendar ( calendarId ) ; const jobsToAdd = difference ( calendar . job_ids , origCalendar . job_ids ) ; const jobsToRemove = difference ( origCalendar . job_ids , calendar . job_ids ) ; const eventsToAdd = calendar . events . filter ( ( event ) => origCalendar . events . find ( ( e ) => this . _eventManager . isEqual ( e , event ) ) === undefined ) ; const eventsToRemove = origCalendar . events . filter ( ( event ) => calendar . events . find ( ( e ) => this . _eventManager . isEqual ( e , event ) ) === undefined ) ; if ( jobsToAdd . length ) { await this . _mlClient . putCalendarJob ( { calendar_id : calendarId , job_id : jobsToAdd . join ( ',' ) , } ) ; } if ( jobsToRemove . length ) { await this . _mlClient . deleteCalendarJob ( { calendar_id : calendarId , job_id : jobsToRemove . join ( ',' ) , } ) ; } if ( eventsToAdd . length !== 0 ) { await this . _eventManager . addEvents ( calendarId , eventsToAdd ) ; } await Promise . all ( eventsToRemove . map ( async ( event ) => { await this . _eventManager . deleteEvent ( calendarId , event . event_id ! ) ; } ) ) ; return await this . getCalendar ( calendarId ) ; } async deleteCalendar ( calendarId ) { const { body } = await this . _mlClient . deleteCalendar ( { calendar_id : calendarId } ) ; return body ; } }