Proyectos de Subversion LeadersLinked - Backend

Rev

Rev 14738 | Rev 15126 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
10540 stevensc 1
/* eslint-disable no-mixed-spaces-and-tabs */
10513 stevensc 2
import axios from 'axios'
10518 stevensc 3
import React, { useState, useEffect } from 'react'
10513 stevensc 4
import { useForm } from 'react-hook-form'
5
import { useDispatch } from 'react-redux'
10450 stevensc 6
import { useHistory, useParams } from 'react-router-dom'
10513 stevensc 7
import { addNotification } from '../../../redux/notification/notification.actions'
10436 stevensc 8
 
10439 stevensc 9
 
10856 stevensc 10
const FormView = ({ actionLink, type_link, vacancy_link, vacancies, add_link, setActionLink }) => {
10513 stevensc 11
 
10558 stevensc 12
	// States
10845 stevensc 13
	const [vacancyOptions, setVacancyOptions] = useState(vacancies)
14
	const [vacancyUrl, setVacancyUrl] = useState(vacancy_link.replace('UUID_PLACEHOLDER', vacancies[0].uuid))
10840 stevensc 15
	const [typeOptions, setTypeOptions] = useState({
16
		url: type_link,
17
		value: ''
18
	})
10558 stevensc 19
	const [generalOptions, setGeneralOptions] = useState({
20
		uuid: '',
21
		name: '',
22
		description: '',
23
		functions: '',
24
		objectives: ''
25
	})
10852 stevensc 26
	const [candidatesOptions, setCandidatesOptions] = useState([])
10853 stevensc 27
	const [competencies, setCompetencies] = useState([{
28
		competency_uuid: '',
29
		competency_name: '',
30
		competency_type_uuid: '',
31
		competency_type_name: '',
32
		behaviors: []
33
	}])
11069 stevensc 34
	const [pointsOptions] = useState([
15090 efrain 35
		{ label: 'N/A', value: 0 },
36
		{ label: '25%', value: 1 },
37
		{ label: '50%', value: 2 },
38
		{ label: '75%', value: 3 },
39
		{ label: '100%', value: 4 }
40
	])
41
	const [pointsGlobalOptions] = useState([
10558 stevensc 42
		{ label: 'Sugerir otro cargo', value: 0 },
43
		{ label: '25%', value: 1 },
44
		{ label: '50%', value: 2 },
45
		{ label: '75%', value: 3 },
46
		{ label: '100%', value: 4 }
47
	])
11069 stevensc 48
	const [statusOptions] = useState([
10558 stevensc 49
		{ label: 'Aceptado', value: 'a' },
50
		{ label: 'Rechazado', value: 'r' }
51
	])
10516 stevensc 52
 
10558 stevensc 53
	// Hooks
10852 stevensc 54
	const { setValue, register, watch, handleSubmit } = useForm()
10558 stevensc 55
	const history = useHistory()
56
	const dispatch = useDispatch()
57
	const { action } = useParams()
10439 stevensc 58
 
11071 stevensc 59
	const onSubmit = () => {
10915 stevensc 60
 
10856 stevensc 61
		const content = []
62
		competencies.forEach(competency => competency.behaviors.forEach(behavior => {
63
			content.push({
10852 stevensc 64
				competencyUuid: behavior.competency_uuid,
65
				behaviorUuid: behavior.uuid,
11075 stevensc 66
				comment: watch(`${behavior.competency_uuid}-${behavior.uuid}-comment`),
11073 stevensc 67
				evaluation: watch(`select-${behavior.competency_uuid}-${behavior.uuid}`)
10856 stevensc 68
			})
10853 stevensc 69
		}))
10852 stevensc 70
 
71
		const submitData = new FormData()
10865 stevensc 72
		submitData.append('content', JSON.stringify(content))
10852 stevensc 73
		submitData.append('candidate_uuid', watch('candidate'))
74
		submitData.append('points', watch('points'))
75
		submitData.append('comment', watch('comment'))
76
		submitData.append('status', watch('status'))
77
 
10859 stevensc 78
		axios.post(actionLink, submitData)
79
			.then(({ data }) => {
80
				if (!data.success) {
11071 stevensc 81
					typeof data.data === 'string'
82
						?
83
						dispatch(addNotification({
84
							style: 'danger',
85
							msg: data.data
86
						}))
14738 stevensc 87
						: Object.entries(data.data).map(([key, value]) =>
88
							value.map(err =>
89
								dispatch(addNotification({
90
									style: 'danger',
91
									msg: `${key}: ${err}`
92
								}))
93
							)
94
						)
11072 stevensc 95
					return
10859 stevensc 96
				}
97
 
10870 stevensc 98
				history.goBack()
10859 stevensc 99
				dispatch(addNotification({
100
					style: 'success',
101
					msg: `Registro ${action === 'edit' ? 'actualizado' : 'añadido'}`
102
				}))
103
			})
10852 stevensc 104
	}
105
 
10558 stevensc 106
	useEffect(() => {
10840 stevensc 107
		if (action === 'edit') {
108
			axios.get(actionLink)
109
				.then(({ data }) => {
110
					const resData = data.data
111
 
112
					if (!data.success) {
11071 stevensc 113
						return dispatch(addNotification({
11051 stevensc 114
							style: 'danger',
10840 stevensc 115
							msg: 'Ha ocurrido un error'
116
						}))
117
					}
118
 
119
					setCompetencies(resData.job_description.competencies)
10844 stevensc 120
					setCandidatesOptions([resData.candidate])
121
					setVacancyOptions([{ name: resData.vacancy.name, uuid: resData.vacancy.uuid }])
10843 stevensc 122
					setTypeOptions({ ...typeOptions, value: resData.interview.type === 'r' ? 'Entrevista por Recursos Humanos' : 'Entrevista por Potencial superior' })
10840 stevensc 123
					setGeneralOptions({
124
						...generalOptions,
125
						name: resData.vacancy.name,
126
						uuid: resData.vacancy.uuid,
127
						description: resData.vacancy.description,
128
						functions: resData.job_description.functions,
129
						objectives: resData.job_description.objectives
130
					})
11237 stevensc 131
					setValue('comment', resData.interview.comment)
132
					setValue('points', resData.interview.points)
133
					setValue('status', resData.interview.status)
11073 stevensc 134
					resData.interview.content.forEach((obj) => {
135
						setValue(`select-${obj.competencyUuid}-${obj.behaviorUuid}`, obj.evaluation)
11074 stevensc 136
						setValue(`${obj.competencyUuid}-${obj.behaviorUuid}-comment`, obj.comment)
11073 stevensc 137
					})
10840 stevensc 138
				})
139
		}
140
	}, [action])
141
 
142
	useEffect(() => {
143
		axios.get(typeOptions.url)
10753 stevensc 144
			.then(({ data }) => {
10513 stevensc 145
 
10753 stevensc 146
				if (!data.success) {
11071 stevensc 147
					return dispatch(addNotification({
11051 stevensc 148
						style: 'danger',
10753 stevensc 149
						msg: 'Ha ocurrido un error'
150
					}))
151
				}
10513 stevensc 152
 
10843 stevensc 153
				setTypeOptions({ ...typeOptions, value: data.data })
10753 stevensc 154
			})
155
 
10840 stevensc 156
	}, [typeOptions.url])
10516 stevensc 157
 
10843 stevensc 158
	useEffect(() => {
10935 stevensc 159
		if (action == 'add') {
160
			axios.get(vacancyUrl)
161
				.then(({ data }) => {
162
					const resData = data.data
10843 stevensc 163
 
10935 stevensc 164
					if (!data.success) {
11071 stevensc 165
						return dispatch(addNotification({
11051 stevensc 166
							style: 'danger',
10935 stevensc 167
							msg: 'Ha ocurrido un error'
168
						}))
169
					}
10843 stevensc 170
 
10935 stevensc 171
					setCandidatesOptions(resData.candidates)
172
					setCompetencies(resData.job_description.competencies)
173
					setTypeOptions({ ...typeOptions, value: resData.interview.type === 'r' ? 'Entrevista por Recursos Humanos' : 'Entrevista por Potencial superior' })
174
					setGeneralOptions({
175
						...generalOptions,
176
						name: resData.vacancy.name,
177
						uuid: resData.vacancy.uuid,
178
						description: resData.vacancy.description,
179
						functions: resData.job_description.functions,
180
						objectives: resData.job_description.objectives
181
					})
10843 stevensc 182
				})
10935 stevensc 183
		}
10843 stevensc 184
	}, [vacancyUrl])
185
 
10558 stevensc 186
	return (
187
		<section className="content">
188
			<div className="container-fluid">
189
				<div className="row">
190
					<div className="col-12">
10852 stevensc 191
						<form onSubmit={handleSubmit(onSubmit)}>
192
							<div className='card'>
193
								<div className="card-header">
194
									<ul className="nav nav-tabs" id="myTab" role="tablist">
195
										<li className="nav-item" role="presentation">
196
											<button className="nav-link active" id="home-tab" data-toggle="tab" data-target="#home" type="button" role="tab" aria-controls="home" aria-selected="true">General</button>
197
										</li>
198
										<li className="nav-item" role="presentation">
199
											<button className="nav-link" id="profile-tab" data-toggle="tab" data-target="#profile" type="button" role="tab" aria-controls="profile" aria-selected="false">Competencias</button>
200
										</li>
201
										<li className="nav-item" role="presentation">
202
											<button className="nav-link" id="contact-tab" data-toggle="tab" data-target="#contact" type="button" role="tab" aria-controls="contact" aria-selected="false">Conclusiones</button>
203
										</li>
204
									</ul>
205
								</div>
206
								<div className="card-body">
207
									<div className="tab-content" id="myTabContent">
208
										<div className="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
209
											<div className="row p-3 justify-content-between">
210
												<div className="col-6">
211
													<div className="form-group">
212
														<label>Vacantes</label>
10856 stevensc 213
														<select
214
															className='form-control'
215
															name='vacancy' ref={register}
216
															disabled={action === 'edit'}
217
															onChange={(e) => {
218
																setVacancyUrl(vacancy_link.replace('UUID_PLACEHOLDER', e.target.value))
219
																setActionLink(add_link.replace('UUID_PLACEHOLDER', e.target.value))
220
															}}>
10852 stevensc 221
															{
222
																vacancyOptions.map(({ name, uuid }) => (
223
																	<option selected={generalOptions.name === name} key={uuid} value={uuid}>{name}</option>
224
																))
225
															}
226
														</select>
227
													</div>
10569 stevensc 228
												</div>
10852 stevensc 229
												<div className="col-6">
230
													<div className="form-group">
231
														<label>Candidatos</label>
232
														<select className='form-control' name='candidate' ref={register} disabled={action === 'edit'} onChange={(e) => setTypeOptions(prev => ({ ...prev, url: type_link.replace('UUID_PLACEHOLDER', e.target.value) }))}>
233
															{
234
																candidatesOptions.map(({ first_name, last_name, uuid }) => (
235
																	<option selected={watch('candidate') === uuid} key={uuid} value={uuid}>{`${first_name} ${last_name}`}</option>
236
																))
237
															}
238
														</select>
239
													</div>
240
												</div>
10558 stevensc 241
											</div>
10852 stevensc 242
											<h5>{typeOptions.value}</h5>
243
											<div className="card">
244
												<div className="card-body">
245
													<h5>{generalOptions.name}</h5>
246
													<p>{generalOptions.description}</p>
247
													<h6>Funciones</h6>
248
													<p>{generalOptions.functions}</p>
249
													<h6>Objetivos</h6>
250
													<p>{generalOptions.objectives}</p>
10569 stevensc 251
												</div>
10558 stevensc 252
											</div>
253
										</div>
10852 stevensc 254
										<div className="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">
255
											{
256
												competencies.map((competency) => (
257
													<div className="card" key={competency.competency_uuid}>
258
														<div className="card-header">
259
															<h5>{competency.competency_name} - {competency.competency_type_name}</h5>
260
														</div>
261
														<div className="card-body">
11268 stevensc 262
															<div className="table-responsive">
263
																{
264
																	competency.behaviors
265
																	&&
266
																	competency.behaviors.map((behavior) => (
267
																		<table key={behavior.uuid} className="table table-hover">
268
																			<thead>
269
																				<tr>
270
																					<th style={{ width: '20%' }}>Conducta Observable</th>
271
																					<th style={{ width: '60%' }}>Comentario</th>
272
																					<th style={{ width: '20%' }}>Evaluación</th>
273
																				</tr>
274
																			</thead>
275
																			<tbody>
276
																				<tr>
277
																					<td style={{ width: '20%' }}>{behavior.description}</td>
278
																					<td style={{ width: '60%' }}>
15090 efrain 279
																						<input
280
																							type="text"
11268 stevensc 281
																							name={`${behavior.competency_uuid}-${behavior.uuid}-comment`}
15090 efrain 282
																							maxlength="80"
11268 stevensc 283
																							ref={register}
284
																							className='form-control w100'
285
																						/>
286
																					</td>
287
																					<td style={{ width: '20%' }}>
288
																						<select className='form-control' name={`select-${behavior.competency_uuid}-${behavior.uuid}`} ref={register}>
289
																							{
290
																								pointsOptions.map(({ label, value }) => {
291
																									return <option selected={watch(`select-${behavior.competency_uuid}-${behavior.uuid}`) === value} key={value} value={value}>{label}</option>
292
																								})
293
																							}
294
																						</select>
295
																					</td>
296
																				</tr>
297
																			</tbody>
298
																		</table>
299
																	))
300
																}
301
															</div>
10852 stevensc 302
														</div>
303
													</div>
304
												))
305
											}
306
										</div>
307
										<div className="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">
308
											<div className="form-group">
309
												<label>Comentario</label>
15090 efrain 310
												<textarea type="text" name="comment" className="form-control" rows="5" cols="50" ref={register} />
10558 stevensc 311
											</div>
10852 stevensc 312
											<div className="form-group">
313
												<label>Evaluación</label>
11237 stevensc 314
												<select className='form-control' name='points' ref={register}>
10852 stevensc 315
													{
15090 efrain 316
														pointsGlobalOptions.map(({ label, value }) => (
10852 stevensc 317
															<option selected={watch('points') === value} key={value} value={value}>{label}</option>
318
														))
319
													}
320
												</select>
321
											</div>
322
											<div className="form-group">
323
												<label>Estatus</label>
11237 stevensc 324
												<select className='form-control' name='status' ref={register}>
10852 stevensc 325
													{
326
														statusOptions.map(({ label, value }) => (
327
															<option selected={watch('status') === value} key={value} value={value}>{label}</option>
328
														))
329
													}
330
												</select>
331
											</div>
10558 stevensc 332
										</div>
333
									</div>
10852 stevensc 334
									<div className="form-group">
335
										<button type="submit" className="btn btn-primary btn-form-save-close mr-2">
336
											Guardar
337
										</button>
338
										<button
339
											type="button"
340
											className="btn btn-secondary btn-edit-cancel"
341
											onClick={() => history.goBack()}
342
										>
343
											Cancelar
344
										</button>
10558 stevensc 345
									</div>
346
								</div>
347
							</div>
10852 stevensc 348
						</form>
10558 stevensc 349
					</div>
350
				</div>
351
			</div>
352
		</section >
353
	)
10436 stevensc 354
}
355
export default FormView