instantjob-recruiter-client
Version:
a set of tools for creating an instantjob recruiter react client
277 lines (247 loc) • 8.28 kB
JSX
import React from 'react'
import Fuse from 'fuse.js'
import store from 'common/store'
import request from 'common/request'
import {
array_from_set, property_getter, property_toggler, download_file, empty_set,
} from 'common/utilities'
import {
add_users_value, remove_users_value, store_fields, store_values, update_user_comments,
update_field, update_value, remove_field, remove_value, add_entity_value, remove_entity_value,
update_entity_comment, update_exclusive_entity_value, clear_exclusive_entity_value,
} from 'actions/fields'
import {get_missions_recyclable_fields} from 'selectors/fields'
import {alert_failure, show_popover, dismiss_popover} from 'actions/display'
import NewFieldForm from 'components/popovers/new_field_form'
import DeleteField from 'components/popovers/delete_field'
import DeleteValue from 'components/popovers/delete_value'
import {add_modal} from 'components/architecture/modals'
import AssociatedValuesSettings from 'components/associated_values_settings'
export function action_remove_field(field_id) {
const field = store.getState().fields.fields[field_id] || {}
const remove = () => {
store.dispatch(remove_field(field_id))
request.delete(`fields/${field_id}`)
}
if (field.name) {
store.dispatch(show_popover(
DeleteField,
{
field,
on_delete() {
remove()
store.dispatch(dismiss_popover())
},
},
`Supprimer le champ ${field.name}`,
))
} else {
remove()
}
}
export function action_remove_value(value_id) {
function remove() {
store.dispatch(remove_value(value_id))
return request.delete(`values/${value_id}`)
}
const {values, fields} = store.getState().fields
const {mission_ids, entity_ids, name, field_id} = values[value_id]
const {name: field_name} = fields[field_id]
if (empty_set(mission_ids) && empty_set(entity_ids)) {
return remove()
} else {
store.dispatch(show_popover(
DeleteValue,
{
field_name: field_name,
value_name: name,
confirm() {
remove()
store.dispatch(dismiss_popover())
},
},
`Suppression de la valeur « ${name} »`
))
}
}
function is_exclusive_update(value_id, for_missions) {
const {fields, values} = store.getState().fields
const {field_id} = values[value_id] || {}
const {for_entity, category} = fields[field_id] || {}
return category == 'exclusive' && !(for_entity == 'User' && for_missions)
}
export function action_select_entity_value(entity_id, value_id, for_missions) {
let action = add_entity_value
if (is_exclusive_update(value_id, for_missions)) {
action = update_exclusive_entity_value
}
store.dispatch(action(entity_id, value_id, for_missions))
return request.put(`values/${value_id}/add`, {entity_id, for_missions})
}
export function action_remove_entity_value(entity_id, value_id, for_missions) {
if (is_exclusive_update(value_id, for_missions)) {
store.dispatch(clear_exclusive_entity_value(entity_id, value_id))
} else {
store.dispatch(remove_entity_value(entity_id, value_id, for_missions))
}
return request.delete(`values/${value_id}/remove`, {entity_id, for_missions})
}
export function action_update_entity_comment(entity_id, field_id, comment) {
store.dispatch(update_entity_comment(entity_id, field_id, comment))
return request.put(`fields/${field_id}/comments`, {entity_id, comment})
}
export function action_view_entity_template(entity_id, {name, id: field_id}) {
return request.asynchronous(`fields/${field_id}/create_from_template`, {entity_id})
.then(({url}) => download_file(url, name))
}
export function action_upload_entity_file(entity_id, field_id, file) {
return request.upload(`fields/${field_id}/files`, file, {entity_id})
}
export function action_fetch_entity_computed_value(entity_id, field_id) {
return request.get(`fields/${field_id}/compute`, {entity_id})
.then(property_getter('result'))
}
export function action_create_user_field() {
return action_new_field(
"Création d'un nouveau champ candidat",
"user",
{for_entity: 'User'},
)
}
export function action_create_mission_field() {
return action_new_field(
"Création d'un nouveau champ mission",
"mission",
{for_entity: 'Mission'},
get_missions_recyclable_fields(store.getState())
)
}
export function action_create_proposal_field() {
return action_new_field(
"Création d'un nouveau champ poste",
"mission_proposal",
{for_entity: 'MissionProposal'},
)
}
export function action_create_shift_field() {
return action_new_field(
"Création d'un nouveau champ créneau",
"shift",
{for_entity: 'Shift'},
)
}
export function action_create_value_field(field_id) {
return action_new_field(
"Création d'une nouvelle valeur associée",
"value",
{for_entity: 'Value', field_id}
)
}
export function action_create_workplace_field() {
return action_new_field(
"Création d'un nouveau champ Lieu de travail",
"workplace",
{for_entity: 'Workplace'}
)
}
export function action_create_deal_field() {
return action_new_field(
"Création d'un champ d'export mission",
"deal",
{for_entity: 'Deal'}
)
}
export function action_new_field(title, type, template, existing_fields = []) {
store.dispatch(show_popover(
NewFieldForm,
{
type,
create_field(field) {
action_create_field({
...field,
...template,
})
store.dispatch(dismiss_popover())
},
recycle_field(field) {
action_update_field({...field, recycled: true})
store.dispatch(dismiss_popover())
},
existing_fields,
},
title
))
}
export function action_create_field(field) {
return request.post(`agencies/${store.getState().profile.agency_id}/fields`, {field})
.then((field) => {
store.dispatch(store_fields([field]))
return field.id
})
}
export function action_create_value(field_id, name = "") {
return new Promise((resolve, reject) => {
let characters = name.split("")
if (',' in characters || ';' in characters) {
store.dispatch(alert_failure(`Les caractères ',' et ';' sont interdits dans le nom d'une valeur.`))
reject()
} else {
request.post(`fields/${field_id}/values`, {value: {name}})
.then((value) => {
store.dispatch(store_values([value]))
action_show_associated_values(value.id)
return value.id
})
.then(resolve)
}
})
}
export function action_show_associated_values(value_id) {
add_modal(() => <AssociatedValuesSettings value_id={value_id} />)
}
export const new_values_fuse = () => new Fuse([], {
keys: ["name"],
id: "id",
threshold: 0.2,
})
export const new_comments_fuse = () => new Fuse([], {
keys: ["comment"],
id: "id",
threshold: 0.2,
})
export function allow_creating_value(item_type, field) {
return !((item_type == 'mission' || item_type == 'new_mission') && field.recycled)
}
export function action_update_field(field) {
store.dispatch(update_field(field))
return request.put(`fields/${field.id}`, {field})
}
export function action_update_value(value) {
store.dispatch(update_value(value))
return request.put(`values/${value.id}`, {value})
}
export function action_update_field_template(field_id, template) {
return request.upload(`fields/${field_id}/template`, template, {field_id})
.then(() => {})
.catch(() => store.dispatch(alert_failure("Une erreur s'est produite. Avez-vous bien téléchargé un fichier au format .docx ?")))
}
export function action_export_field(field_id, deal_ids) {
const {name} = store.getState().fields.fields[field_id]
const {agency_id} = store.getState().profile
return request.asynchronous(`agencies/${agency_id}/export_missions`, {field_id, deal_ids})
.then(({url}) => download_file(url, name))
}
export const users_fields_options = [
{
name: "Renseigné par le candidat",
get: property_getter('shared_by_user'),
toggle: property_toggler('shared_by_user'),
},
]
export const missions_fields_options = [
{
name: "Partagé avec le candidat",
get: property_getter('shared_with_user'),
toggle: property_toggler('shared_with_user'),
},
]