instantjob-recruiter-client
Version:
a set of tools for creating an instantjob recruiter react client
188 lines (175 loc) • 5.54 kB
JSX
import {update_item, store_items} from './base'
import {
set_from_array, array_from_set, set_difference, property_getter, flatten_array, map_hash,
create_hash, filter_hash,
} from '../common/utilities'
const initial_state = {
fields: {},
values: {},
}
const sanitize_set = (set) => !set || Array.isArray(set) ? set_from_array(set || []) : set
const sanitize_value = ({entity_ids, mission_ids, ...value}) => ({
...map_hash({entity_ids, mission_ids}, sanitize_set),
...value,
})
const sanitize_field = ({values, ...field}) => ({
values: set_from_array(values.map(property_getter('id'))),
...field,
})
const update_field = (state, {values, ...field}) => update_item(
store_items(state, "values", (values || []).map(sanitize_value)),
"fields",
field,
)
const update_value = (state, {entity_ids, mission_ids, ...value}) => update_item(
state,
'values',
{
...value,
...map_hash(filter_hash({entity_ids, mission_ids}, Boolean), set_from_array),
}
)
const add_items_value = (state, value_id, item_ids, for_missions) => {
const value = state.values[value_id]
const ids_key = for_missions ? 'mission_ids' : 'entity_ids'
return {
...state,
values: {
...state.values,
[value_id]: {
...value,
[ids_key]: {
...value[ids_key],
...set_from_array(item_ids),
},
},
},
}
}
const make_update_clear_items_exclusive_value = () => create_hash(
['clear', 'update'],
(verb) => (state, value_id, item_ids) => {
const {field_id} = state.values[value_id] || {}
const {value_id_for} = state.fields[field_id] || {}
return update_item(state, "fields", {id: field_id, value_id_for: {
...value_id_for,
...create_hash(item_ids, () => verb == 'clear' ? null : value_id)
}})
}
)
const {
update: update_items_exclusive_value,
clear: clear_items_exclusive_value,
} = make_update_clear_items_exclusive_value()
const remove_items_value = (state, value_id, item_ids, for_missions) => {
const value = state.values[value_id]
const ids_key = for_missions ? 'mission_ids' : 'entity_ids'
return {
...state,
values: {
...state.values,
[value_id]: {
...value,
[ids_key]: set_difference(array_from_set(value[ids_key]), set_from_array(item_ids)),
},
},
}
}
const update_items_comment = (state, field_id, comments) => {
return update_item(state, "fields", {
id: field_id,
comments: {
...((state.fields[field_id] || {}).comments || {}),
...comments,
},
})
}
export function fields(state = initial_state, action) {
let fields, values, value, field
switch (action.type) {
case "store_fields":
return store_items(
store_items(
state,
"values",
flatten_array(action.fields.map(property_getter('values', []))).map(sanitize_value),
),
"fields",
action.fields.map(sanitize_field),
)
case "update_field":
return update_field(state, action.field)
case "update_fields":
return action.fields.reduce(update_field, state)
case "remove_field":
fields = {...state.fields}
delete fields[action.field_id]
values = {...state.values}
array_from_set(state.fields[action.field_id].values).forEach((id) => {
delete values[id]
})
return {
...state,
fields,
values,
}
case "store_values":
return {
...state,
values: action.values.reduce((values, value) => ({
...values,
[value.id]: sanitize_value(value),
}), state.values),
fields: action.values.reduce((fields, value) => ({
...fields,
[value.field_id]: {
...state.fields[value.field_id],
values: {
...state.fields[value.field_id].values,
[value.id]: true,
}
}
}), state.fields),
}
case "update_value":
return update_value(state, action.value)
case "update_values":
return action.values.reduce(update_value, state)
case "remove_value":
values = {...state.values}
delete values[action.value_id]
field = state.fields[state.values[action.value_id].field_id]
return {
...state,
values,
fields: {
...state.fields,
[field.id]: {
...field,
values: {
...field.values,
[action.value_id]: false,
}
}
}
}
case "add_users_value":
return add_items_value(state, action.value_id, action.user_ids)
case "remove_users_value":
return remove_items_value(state, action.value_id, action.user_ids)
case "add_entity_value":
return add_items_value(state, action.value_id, [action.entity_id], action.for_missions)
case "update_exclusive_entity_value":
return update_items_exclusive_value(state, action.value_id, [action.entity_id])
case "clear_exclusive_entity_value":
return clear_items_exclusive_value(state, action.value_id, [action.entity_id])
case "remove_entity_value":
return remove_items_value(state, action.value_id, [action.entity_id], action.for_missions)
case "update_user_comments":
return update_items_comment(state, action.field_id, action.user_comments)
case "update_entity_comment":
return update_items_comment(state, action.field_id, {[action.entity_id]: action.comment})
default:
return state
}
}