instantjob-recruiter-client
Version:
a set of tools for creating an instantjob recruiter react client
104 lines (97 loc) • 3.23 kB
JSX
import {tolerant_selector} from 'selectors/base'
import {get_mission_proposals} from 'selectors/missions'
import {get_fields_by_shift, get_shifts_fields} from 'selectors/fields'
import moment from 'common/moment'
import {
make_memoized, split_array, array_from_hash, property_getter, map_hash, compare,
} from 'common/utilities'
import {action_update_shift_events, action_create_shift} from 'common/shifts'
const get_raw_shifts = (state) => state.shifts.shifts
const get_raw_shift_events = (state) => state.shifts.events
const add_start_end = ({events, ...shift}) => {
let min, max
events.forEach(({start, end}) => {
if (!min || min.isAfter(start)) {
min = moment(start)
}
if (!max || max.isBefore(end)) {
max = moment(end)
}
})
return {
...shift,
events,
start: min,
end: max,
update_events(events) {
action_update_shift_events(shift, events)
},
}
}
const get_events_by_shift = tolerant_selector(
[get_raw_shift_events],
(events) => split_array(
array_from_hash(events).filter(({deleted_at}) => !deleted_at),
property_getter('calenderable_id'),
)
)
const get_shifts = tolerant_selector(
[get_raw_shifts, get_events_by_shift, get_fields_by_shift],
(shifts, events_by_shift, fields_by_shift) => map_hash(
shifts,
(shift) => add_start_end({
...shift,
events: events_by_shift[shift.id] || [],
fields: array_from_hash(fields_by_shift[shift.id]) || [],
})
)
)
const get_splitted_shifts = tolerant_selector(
[get_shifts],
(shifts) => map_hash(
split_array(array_from_hash(shifts), property_getter('proposal_id')),
(shifts) => split_array(shifts, property_getter('event_id'))
)
)
export const get_proposal_shifts = make_memoized((proposal_id, mission_id) => tolerant_selector(
[get_mission_proposals, get_splitted_shifts, get_shifts_fields],
(missions, splitted_shifts, shifts_fields) => {
const {events, create_shift} = missions[mission_id] || {}
return (events || []).sort(compare(({start}) => moment(start).valueOf())).map(({start, end, id}) => {
const [shift] = (splitted_shifts[proposal_id] || {})[id] || []
const get_shift = () => new Promise((resolve, reject) => {
if (shift) {
resolve(shift)
} else {
action_create_shift(proposal_id, id).then(resolve, reject)
}
})
let fields
if (shift) {
fields = shift.fields
} else {
fields = shifts_fields.map(({select_value, update_comment, fetch_value, ...field}) => ({
...field,
on_select_value(value_id) {
return get_shift().then((shift) => select_value(shift.id, value_id))
},
on_submit_comment(comment) {
return get_shift().then((shift) => update_comment(shift.id, comment))
},
fetch_value() {
return get_shift().then((shift) => fetch_value(shift.id))
},
}))
}
return {
...(shift || {}),
theoretic: {start, end},
real: shift,
fields,
update_events(events) {
get_shift().then((shift) => action_update_shift_events(shift, events))
},
}
})
}
))