Skip to content

Instantly share code, notes, and snippets.

@coliveravenegas
Created May 31, 2017 01:53
Show Gist options
  • Save coliveravenegas/7ed315b01a01c0c8218a6c0455f3a0ca to your computer and use it in GitHub Desktop.
Save coliveravenegas/7ed315b01a01c0c8218a6c0455f3a0ca to your computer and use it in GitHub Desktop.
visaje.js
import zipWith from 'lodash/zipWith';
import constants from 'autoevaluacion/constants';
const {
SET_ERRORS,
ALL_STORED,
ALL_FETCHING,
ALL_ERROR,
FINISHED_REQUEST,
} = constants;
import { isRequiredByValoracion } from './estandares/reducer';
import { formatEstandarShortName } from 'common/formatter';
import { getContext } from 'common/context';
import { getPayloadEstandares, getIdByEstandar }
from './estandares/reducer';
import { getPayloadCriterios, getCriterios }
from './estandares/criterios/reducer';
import { getPayloadEvidencias, getEvidencias }
from './estandares/evidencias/reducer';
import { getPayloadDocumentos, getFiles }
from './estandares/documentos/reducer';
export const setErrors = (errors) => ({
type: SET_ERRORS,
errors,
});
export const finishedRequest = () => ({
type: FINISHED_REQUEST,
});
export const allStored = () => ({
type: ALL_STORED,
});
export const allFetching = (id) => ({
type: ALL_FETCHING,
id,
});
export const allError = (msg) => dispatch => {
dispatch({
type: ALL_ERROR,
});
alert(msg);
};
const removeOverlay = () => {
const elem = document.getElementById('auto_overlay');
elem.parentElement.removeChild(elem);
};
const allSaveStored = () => dispatch => {
removeOverlay();
dispatch(allStored());
};
const allSaveFetching = () => dispatch => {
var overlay = document.createElement('div');
overlay.id = 'auto_overlay';
var inner = document.createElement('div');
inner.id = 'auto_inner_overlay';
inner.innerHTML = '<div><i class="fa fa-refresh fa-animate"></i> Guardando</div>';
overlay.appendChild(inner);
document.querySelector('body').appendChild(overlay);
dispatch(allFetching());
};
const allSaveError = (msg) => dispatch => {
removeOverlay();
dispatch(allError(msg));
};
const getErrors = (errors) =>
[
errors[0] ? 'Se debe agregar por lo menos un criterio. ': '',
errors[1] ? 'Se debe agregar por lo menos una evidencia. ': '',
errors[2] ? 'Cada evidencia debe tener por lo menos un documento. ': '',
errors[3] ? 'Cada documento debe tener un estado. ': '',
].join('');
const extractErrors = (getState) => {
const errors = getState().getIn(['auto_detalles', 'ids']).toJS()
.map(id => {
const evidenciasIds = getEvidencias(getState().get('auto_evidencias'), id)
.map(e => e.get('auev_id')).toJS();
if( !isRequiredByValoracion(getState().get('auto_detalles'), id) ){
return {
id,
errors: [ false, false, false, false ],
}
}
return {
id,
errors: [
getCriterios(getState().get('auto_criterios'), id).size === 0,
evidenciasIds.length === 0,
evidenciasIds
.map(evId => getFiles(getState().get('auto_documentos'), evId).size === 0)
.reduce((acc, f) => acc || f, false),
evidenciasIds
.map(evId => getFiles(getState().get('auto_documentos'), evId).toJS().filter(f => f.audo_estado == '').length > 0)
.reduce((acc, f) => acc || f, false),
]
};
}).reduce((acc, info) => {
acc[info.id] = info.errors;
return acc;
}, {});
const logicErrors = getContext().estandares
.map(e => getErrors(errors[getIdByEstandar(getState().get('auto_detalles'), e.id)]));
const estandarRaws = [...document.querySelectorAll('.estandar__raw')];
const inlineErrors = [...document.querySelectorAll('.estandar__row')]
.map((item, i) => ($(item).find('.bg-danger').length > 0 || $(estandarRaws[i]).find('.bg-danger').length > 0) ? 'Faltan llenar campos obligatorios': '');
return logicErrors
.map((errors, i) => ({
esta_id: getContext().estandares[i].id,
title: 'Estandar: ' + getContext().estandares[i].display,
errors: errors + inlineErrors[i]
}))
.filter(item => item.errors.length > 0);
};
const getPayload = (getState) => {
return {
auto_detalles: getPayloadEstandares(getState().get('auto_detalles')),
auto_criterios: getPayloadCriterios(getState().get('auto_criterios')),
auto_evidencias: getPayloadEvidencias(getState().get('auto_evidencias')),
auto_documentos: getPayloadDocumentos(getState().get('auto_documentos')),
};
};
const saveAllData = (dispatch, getState, api, cb) => {
const payload = getPayload(getState);
const shouldNotSave = Object.keys(payload)
.map(k => payload[k].length)
.reduce((acc, i) => acc + i, 0) === 0;
const zipErrors = extractErrors(getState);
if (cb) {
dispatch(setErrors(zipErrors));
}
if (shouldNotSave && !cb) {
return;
}
console.log('saveAll payload', payload);
dispatch(allSaveFetching());
api.saveAll({
data: payload,
onSuccess: () => {
dispatch(allSaveStored());
if (cb) {
cb(zipErrors);
}
},
onError: (err) => {
console.log('err', err);
dispatch(allSaveError());
}
});
};
export const saveAll = () => (dispatch, getState, {api}) => {
saveAllData(dispatch, getState, api);
};
const finish = () => {
var form = $(document.createElement('form'));
$(form).attr("method", "POST");
$(form).attr('action', '/autoevaluacion/finish');
form.appendTo( document.body );
$(form).submit();
};
export const closeFicha = () => (dispatch, getState, {api}) => {
saveAllData(dispatch, getState, api, (err) => {
if (err.length) {
return alert('Existen errores. No se puede finalizar la ficha');
}
finish();
});
};
import React, { Component } from 'react';
import { TextAreaField } from 'common/components/Form';
import { RemoveButton } from 'common/components/buttons';
class Criterio extends Component {
_onChange = (value) => {
const {
criterio,
onChange,
} = this.props;
onChange(criterio.get('aucr_id'), value);
}
_onRemove = () => {
const {
criterio,
onRemove,
} = this.props;
onRemove(criterio.get('aucr_id'));
}
render() {
const {
criterio,
isFetching,
canRemove,
required,
} = this.props;
return (
<div className="row row_item" style={{marginRight: 0}}>
<TextAreaField
required={required}
classWrapper="col-sm-10"
value={criterio.get('descripcion')}
onChange={this._onChange}
rows="10"
/>
<div className="col-sm-2">
{
canRemove && (
<RemoveButton
disabled={isFetching}
onClick={this._onRemove}
/>
)
}
</div>
</div>
);
}
}
export default Criterio;
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { AddButton } from 'common/components/buttons';
import { getCriterios } from '../reducer';
import { addCriterioAPI, updateCriterio, removeCriterioAPI } from '../actions';
import { isFetching } from 'autoevaluacion/tablaAuto/reducer';
import Criterio from '../components/Criterio';
class Criterios extends Component {
render() {
const {
criterios,
addCriterio,
updateCriterio,
removeCriterio,
isFetching,
required,
} = this.props;
return (
<div>
{
criterios.map(c => (
<Criterio
key={c.get('aucr_id')}
criterio={c}
canRemove={criterios.size !== 1}
onChange={updateCriterio}
onRemove={removeCriterio}
isFetching={isFetching}
required={required}
/>
))
}
<AddButton
onClick={addCriterio}
text="Nuevo criterio"
size="md"
disabled={isFetching}
/>
</div>
);
}
}
const mapStateToProps = (state, {id}) => ({
criterios: getCriterios(state.get('auto_criterios'), id),
isFetching: isFetching(state.get('system_status'))
});
const mapDispatchToProps = (dispatch, {id}) => ({
addCriterio: () => dispatch(addCriterioAPI(id)),
updateCriterio: (criterioId, value) =>
dispatch(updateCriterio(criterioId, value)),
removeCriterio: (criterioId) => dispatch(removeCriterioAPI(criterioId)),
});
export default connect(mapStateToProps, mapDispatchToProps)(Criterios);
import { fromJS } from 'immutable';
import { createReducer } from 'redux-immutablejs';
import pick from 'lodash/pick';
import { getContext } from 'common/context';
import constants from 'autoevaluacion/constants';
const {
UPDATE_JUSTIFICACION,
UPDATE_COMENTARIO,
UPDATE_DETALLE_ESTANDAR_VALORACION,
ALL_STORED,
} = constants;
const JUSTIFICACION_KEY = 'aude_justificacion';
const COMENTARIO_KEY = 'aude_comentario';
const initialState = fromJS({
ids: [],
detalles: {},
});
export default createReducer(initialState, {
[UPDATE_JUSTIFICACION]: (state, { id, value }) =>
state
.setIn(['detalles', id, JUSTIFICACION_KEY], value)
.setIn(['detalles', id, 'hasChanged'], true),
[UPDATE_COMENTARIO]: (state, { id, value }) =>
state
.setIn(['detalles', id, COMENTARIO_KEY], value)
.setIn(['detalles', id, 'hasChanged'], true),
[UPDATE_DETALLE_ESTANDAR_VALORACION]: (state, { id, value }) => {
const detalle_id = getIdByEstandar(state, id);
console.log('nuevo valor', value);
return state
.setIn(['detalles', detalle_id, 'aude_valoracion'], value)
.setIn(['detalles', detalle_id, 'hasChanged'], true);
},
[ALL_STORED]: state =>
state.withMutations(state => {
state
.get('ids')
.forEach(id => state.setIn(['detalles', id, 'hasChanged'], false));
}),
});
export const getIdByEstandar = (state, esta_id) =>
state
.get('ids')
.find(id => state.getIn(['detalles', id, 'esta_id']) == esta_id);
export const getDetalleByEstandar = (state, esta_id) =>
state.getIn(['detalles', getIdByEstandar(state, esta_id)]);
const getValoracionByEstandar = (state, esta_id) => {
return state.getIn(['detalles', esta_id, 'aude_valoracion']);
};
export const isRequiredByValoracion = (state, esta_id) =>
getValoracionByEstandar(state, esta_id) != getContext().valoraciones[0].id;
export const getJustificacion = (state, id) =>
state.getIn(['detalles', id, JUSTIFICACION_KEY]);
export const getComentario = (state, id) =>
state.getIn(['detalles', id, COMENTARIO_KEY]);
const transformValoracionId = id => {
if (!id) return 0;
return getContext().valoraciones.filter(v => v.id == id)[0].value;
};
export const getValoraciones = state => {
let valor = 0;
state.get('ids').forEach(id => {
let valoracionId = state.getIn(['detalles', id, 'aude_valoracion']);
valor += transformValoracionId(isNaN(valoracionId) ? 0 : +valoracionId);
});
return valor / state.get('ids').size;
};
export const getValoracion = (state, esta_id) =>
state.getIn(['detalles', getIdByEstandar(state, esta_id), 'aude_valoracion']);
export const getStatusEstandares = state =>
state.get('ids').map(id =>
fromJS({
hasChanged: state.getIn(['detalles', id, 'hasChanged']),
}),
);
export const getPayloadEs tandares = state =>
state
.get('ids')
.filter(id => state.getIn(['detalles', id, 'hasChanged']))
.map(id => state.getIn(['detalles', id]))
.toJS()
.map(o =>
pick(o, [
'aude_id',
'aude_valoracion',
'aude_justificacion',
'aude_comentario',
]),
);
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { getIdByEstandar } from '../reducer';
import { Table, TableHeader } from 'common/components/table';
import Criterios from '../criterios/containers';
import Evidencias from '../evidencias/containers';
import { Justificacion, Comentario } from '../containers';
import { getContext } from 'common/context';
import { isRequiredByValoracion } from '../reducer';
class EstandarRowInformation extends Component {
componentDidMount() {
$(this.justificacionTitle).tooltip({
'title': 'Justifique, como estos criterios contribuyen al cumplimiento del estándar',
});
$(this.evidenciasTitle).tooltip({
'title': 'Con que evidencias, sustenta su JUSTIFICACIÓN',
});
$(this.documentosTitle).tooltip({
'title': 'Cargue los documentos que apoyan sus evidencias',
});
}
setRefJust = el => this.justificacionTitle = el;
setRefEvid = el => this.evidenciasTitle = el;
setRefDoc = el => this.documentosTitle = el;
render() {
const {
id,
idDetalle,
isRequired,
} = this.props;
const headers = [
{display: 'Criterios', customStyle: {width: '18%'}},
{display: 'Justificacion', customStyle: {width: '20%'}, ref: this.setRefJust},
{display: 'Evidencias', customStyle: {width: '21%'}, ref: this.setRefEvid},
{display: 'Documentos', customStyle: {width: '21%'}, ref: this.setRefDoc},
{display: 'Comentario', customStyle: {width: '20%'}},
];
return (
<tr className="estandar__row">
<td/>
<td colSpan="2">
<Table bordered>
<TableHeader headers={headers} />
<tbody>
<tr>
<td><Criterios id={idDetalle} required={isRequired}/></td>
<td><Justificacion id={idDetalle} required={isRequired}/></td>
<td colSpan="2"><Evidencias id={idDetalle} required={isRequired} /></td>
<td><Comentario id={idDetalle} /></td>
</tr>
</tbody>
</Table>
</td>
</tr>
);
}
};
const mapStateToProps = (state, {id}) => {
const idDetalle = getIdByEstandar(state.get('auto_detalles'), id);
return {
id: getContext().estandares.filter(e => e.id === id)[0].id,
idDetalle,
isRequired: isRequiredByValoracion(state.get('auto_detalles'), idDetalle),
}
};
export default connect(mapStateToProps)(EstandarRowInformation);
import React from 'react';
import { connect } from 'react-redux';
import { TextAreaField } from 'common/components/Form';
import { getJustificacion } from '../reducer';
import { updateJustificacion } from '../actions';
import { getContext } from 'common/context';
const Justificacion = ({
updateJustificacion,
value,
required,
}) => (
<div>
<TextAreaField
value={value}
required={required}
onChange={updateJustificacion}
rows="10"
/>
</div>
);
const mapStateToProps = (state, {id}) => ({
value: getJustificacion(state.get('auto_detalles'), id),
});
const mapDispatchToProps = (dispatch, {id}) => ({
updateJustificacion: (value) => dispatch(updateJustificacion(id, value)),
});
export default connect(mapStateToProps, mapDispatchToProps)(Justificacion);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment