2020-08-28 16:00:36 +02:00
|
|
|
|
import React, { FunctionComponent, useState, useEffect, ChangeEvent, MouseEvent } from 'react';
|
|
|
|
|
import { DecisionSupportFileUpdaterProps } from './DecisionSupportFileUpdaterProps';
|
|
|
|
|
import { base58UUID } from "../../util/uuid";
|
2020-07-31 18:04:31 +02:00
|
|
|
|
|
2020-08-28 16:00:36 +02:00
|
|
|
|
export interface OptionsSectionProps extends DecisionSupportFileUpdaterProps {};
|
|
|
|
|
|
|
|
|
|
const OptionsSectionName = 'options';
|
|
|
|
|
|
2020-09-10 11:12:58 +02:00
|
|
|
|
export const OptionsSection: FunctionComponent<OptionsSectionProps> = ({ dsf, updateDSF, readOnly }) => {
|
2020-08-28 16:00:36 +02:00
|
|
|
|
interface OptionsSectionState {
|
|
|
|
|
changed: boolean
|
|
|
|
|
section: OptionsSection
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface OptionsSection {
|
|
|
|
|
options: Option[]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface Option {
|
|
|
|
|
id: string
|
|
|
|
|
label: string
|
|
|
|
|
pros: string
|
|
|
|
|
cons: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const [ state, setState ] = useState<OptionsSectionState>({
|
|
|
|
|
changed: false,
|
|
|
|
|
section: {
|
|
|
|
|
options: [],
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!state.changed) return;
|
|
|
|
|
updateDSF({ ...dsf, sections: { ...dsf.sections, [OptionsSectionName]: { ...state.section }} })
|
|
|
|
|
setState(state => ({ ...state, changed: false }));
|
|
|
|
|
}, [state.changed]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!dsf.sections[OptionsSectionName]) return;
|
|
|
|
|
setState(state => ({ ...state, changed: false, section: {...state.section, ...dsf.sections[OptionsSectionName] }}));
|
|
|
|
|
}, [dsf.sections[OptionsSectionName]]);
|
|
|
|
|
|
|
|
|
|
function newOption(label: string, pros: string, cons: string): Option {
|
|
|
|
|
return {
|
|
|
|
|
id: base58UUID(),
|
|
|
|
|
label,
|
|
|
|
|
pros,
|
|
|
|
|
cons
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const onAddOptionClick = (evt: MouseEvent) => {
|
2020-08-31 15:29:38 +02:00
|
|
|
|
const options = JSON.parse(JSON.stringify(state.section.options))
|
|
|
|
|
const option = newOption("Décision", "", "");
|
2020-08-31 12:55:33 +02:00
|
|
|
|
options.push(option);
|
|
|
|
|
setState(state => ({ ...state, changed: true, section: { ...state.section, options }}));
|
2020-08-28 16:00:36 +02:00
|
|
|
|
};
|
|
|
|
|
|
2020-08-31 15:29:38 +02:00
|
|
|
|
const onOptionChange = (id: number, attrName: string, evt: ChangeEvent<HTMLInputElement>) => {
|
2020-08-28 16:00:36 +02:00
|
|
|
|
const target = evt.currentTarget;
|
|
|
|
|
const value = target.hasOwnProperty('checked') ? target.checked : target.value;
|
2020-08-31 15:29:38 +02:00
|
|
|
|
const options = JSON.parse(JSON.stringify(state.section.options))
|
2020-08-28 16:00:36 +02:00
|
|
|
|
options[id][attrName] = value;
|
2020-08-31 12:55:33 +02:00
|
|
|
|
setState(state => ({ ...state, changed: true, section: { ...state.section, options }}));
|
2020-08-28 16:00:36 +02:00
|
|
|
|
};
|
2020-07-31 18:04:31 +02:00
|
|
|
|
|
2020-08-31 15:29:38 +02:00
|
|
|
|
const onRemoveOptionClick = (id: number, evt: MouseEvent) => {
|
2020-08-31 13:18:39 +02:00
|
|
|
|
if(confirm('Voulez-vous supprimer cette option ?')){
|
2020-08-31 15:29:38 +02:00
|
|
|
|
const options = JSON.parse(JSON.stringify(state.section.options))
|
2020-08-31 13:18:39 +02:00
|
|
|
|
options.splice(id, 1);
|
|
|
|
|
setState(state => ({ ...state, changed: true, section: { ...state.section, options }}));
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-07-31 18:04:31 +02:00
|
|
|
|
return (
|
|
|
|
|
<section>
|
|
|
|
|
<h4 id="options-section" className="is-size-4 title is-spaced"><a href="#options-section">Explorer les options</a></h4>
|
|
|
|
|
<div className="box">
|
2020-08-28 16:00:36 +02:00
|
|
|
|
<div className="table-container">
|
|
|
|
|
<table className={`table is-bordered is-striped is-hoverable is-fullwidth`}>
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th></th>
|
|
|
|
|
<th>Décision</th>
|
|
|
|
|
<th>Pours</th>
|
|
|
|
|
<th>Contres</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
{
|
|
|
|
|
state.section.options.map((o, index) => {
|
|
|
|
|
return (
|
|
|
|
|
<tr key={`option-${o.id}`}>
|
|
|
|
|
<td>
|
|
|
|
|
<button
|
2020-09-10 11:12:58 +02:00
|
|
|
|
disabled={readOnly}
|
2020-08-31 13:18:39 +02:00
|
|
|
|
onClick={onRemoveOptionClick.bind(null, index)}
|
2020-08-28 16:00:36 +02:00
|
|
|
|
className="button is-danger is-small is-outlined">
|
|
|
|
|
🗑️
|
|
|
|
|
</button>
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<textarea className="textarea"
|
2020-09-10 11:12:58 +02:00
|
|
|
|
readOnly={readOnly}
|
2020-08-28 16:00:36 +02:00
|
|
|
|
value={o.label}
|
|
|
|
|
onChange={onOptionChange.bind(null, index, 'label')}
|
|
|
|
|
placeholder="Décrire cette décision."
|
|
|
|
|
rows={10}>
|
|
|
|
|
</textarea>
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
2020-08-31 13:18:39 +02:00
|
|
|
|
<textarea className="textarea is-success"
|
2020-08-28 16:00:36 +02:00
|
|
|
|
value={o.pros}
|
2020-09-10 11:12:58 +02:00
|
|
|
|
readOnly={readOnly}
|
2020-08-28 16:00:36 +02:00
|
|
|
|
onChange={onOptionChange.bind(null, index, 'pros')}
|
|
|
|
|
placeholder="Décrire les avantages de cette décision."
|
|
|
|
|
rows={10}>
|
|
|
|
|
</textarea>
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
2020-08-31 13:18:39 +02:00
|
|
|
|
<textarea className="textarea is-danger"
|
2020-08-28 16:00:36 +02:00
|
|
|
|
value={o.cons}
|
2020-09-10 11:12:58 +02:00
|
|
|
|
readOnly={readOnly}
|
2020-08-28 16:00:36 +02:00
|
|
|
|
onChange={onOptionChange.bind(null, index, 'cons')}
|
|
|
|
|
placeholder="Décrire les désavantages de cette décision."
|
|
|
|
|
rows={10}>
|
|
|
|
|
</textarea>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
state.section.options.length === 0 ?
|
|
|
|
|
<tr>
|
2020-08-31 13:18:39 +02:00
|
|
|
|
<td></td>
|
2020-08-28 16:00:36 +02:00
|
|
|
|
<td colSpan={4}>Aucune option pour l'instant.</td>
|
|
|
|
|
</tr> :
|
|
|
|
|
null
|
|
|
|
|
}
|
|
|
|
|
</tbody>
|
|
|
|
|
<tfoot>
|
|
|
|
|
<tr>
|
2020-08-31 13:18:39 +02:00
|
|
|
|
<td colSpan={5}>
|
2020-09-10 11:12:58 +02:00
|
|
|
|
<button
|
|
|
|
|
disabled={readOnly}
|
|
|
|
|
className="button is-primary is-pulled-right"
|
|
|
|
|
onClick={onAddOptionClick}>
|
2020-08-31 13:18:39 +02:00
|
|
|
|
Ajouter
|
2020-09-10 11:12:58 +02:00
|
|
|
|
</button>
|
2020-08-28 16:00:36 +02:00
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</tfoot>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
2020-07-31 18:04:31 +02:00
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
);
|
|
|
|
|
};
|