UNPKG

instantjob-recruiter-client

Version:

a set of tools for creating an instantjob recruiter react client

92 lines (82 loc) 3.72 kB
import moment from 'common/moment' import { array_from_hash, for_all, find_optimum_in_sorted_array, flatten_array, split_array, } from 'common/utilities' import {mission_period} from 'common/missions' import store from 'common/store' import {show_popover} from 'actions/display' import AgencyEditUserCalendar from 'components/input_calendar/agency_edit_user_calendar' export function event_intersects(event, date, duration, unit) { return moment(event.start).isBefore(moment(date).add(duration, unit)) && moment(event.end).isAfter(date) } export function event_intersects_or_consecutive(event1, event2, unit) { return !(moment(event1.end).add(1, unit).isSameOrBefore(event2.start, unit) || moment(event2.end).add(1, unit).isSameOrBefore(event1.start, unit)) } const make_period_from_event = (e) => ({is_period: true, start: moment(e.start), end: moment(e.end), events: [e], full_days: e.full_days}) export function intersecting_periods_interval(periods, start, end) { let lower = find_optimum_in_sorted_array(periods, (period) => period.end.isAfter(start)) + 1 let upper = periods.length - 1 - find_optimum_in_sorted_array(periods.reverse(), (period) => period.start.isBefore(end)) periods.reverse() return {lower, upper} } export const make_periods = (events) => { let events_array = array_from_hash(events) if (events_array.length == 0) { return [] } else { return events_array.slice(1).reduce((periods, e) => { let extended_start = moment(e.start).subtract(1, "minute") let extended_end = moment(e.end).add(1, "minute") let {lower, upper} = intersecting_periods_interval(periods, extended_start, extended_end) let merging_periods = periods.slice(lower, upper) return [ ...periods.slice(0, lower), { is_period: true, start: merging_periods.length == 0 || merging_periods[0].start.isAfter(e.start) ? moment(e.start) : merging_periods[0].start, end: merging_periods.length == 0 || merging_periods.slice(-1)[0].end.isBefore(e.end) ? moment(e.end) : merging_periods.slice(-1)[0].end, full_days: e.full_days && for_all(merging_periods, (period) => period.full_days), events: [...flatten_array(merging_periods.map((period) => period.events)), e], }, ...periods.slice(upper) ] }, [make_period_from_event(events_array[0])]) } } export const make_slots = (periods) => flatten_array( periods.map(({start, end, ...period}) => { let current = moment(start).add(1, 'day').startOf('day'), previous = start const periods = [] while (current.isBefore(end)) { periods.push({start: previous, end: current, ...period}) previous = current current = moment(current).add(1, 'day') } periods.push({start: previous, end, ...period}) return periods }) ) function event_is_included_in_periods(event, periods) { let {lower, upper} = intersecting_periods_interval(periods, event.start, event.end) return lower == upper - 1 && periods[lower] && periods[lower].start.isSameOrBefore(event.start) && periods[lower].end.isSameOrAfter(event.end) } export function events_difference(old_events, new_events) { let new_periods = make_periods(new_events) let {remove, keep} = split_array(old_events, (event) => { if (event_is_included_in_periods(event, new_periods)) { return "keep" } else { return "remove" } }) let old_periods = make_periods(keep) return {remove, add: new_events.filter((event) => { return !event_is_included_in_periods(event, old_periods) })} } export function action_agency_edit_user_events({id: user_id}) { store.dispatch(show_popover( AgencyEditUserCalendar, {user_id} )) }