Proyectos de Subversion LeadersLinked - Backend

Rev

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