daddy/client/src/components/DecisionSupportFilePage/OptionsSection.tsx

160 lines
6.3 KiB
TypeScript
Raw Normal View History

import React, { FunctionComponent, useState, useEffect, ChangeEvent, MouseEvent } from 'react';
import { DecisionSupportFileUpdaterProps } from './DecisionSupportFileUpdaterProps';
import { base58UUID } from "../../util/uuid";
export interface OptionsSectionProps extends DecisionSupportFileUpdaterProps {};
const OptionsSectionName = 'options';
export const OptionsSection: FunctionComponent<OptionsSectionProps> = ({ dsf, updateDSF, readOnly }) => {
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-31 15:29:38 +02:00
const onOptionChange = (id: number, attrName: string, evt: ChangeEvent<HTMLInputElement>) => {
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))
options[id][attrName] = value;
2020-08-31 12:55:33 +02:00
setState(state => ({ ...state, changed: true, section: { ...state.section, options }}));
};
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 }}));
}
};
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">
<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
disabled={readOnly}
2020-08-31 13:18:39 +02:00
onClick={onRemoveOptionClick.bind(null, index)}
className="button is-danger is-small is-outlined">
🗑
</button>
</td>
<td>
<textarea className="textarea"
readOnly={readOnly}
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"
value={o.pros}
readOnly={readOnly}
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"
value={o.cons}
readOnly={readOnly}
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>
<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}>
<button
disabled={readOnly}
className="button is-primary is-pulled-right"
onClick={onAddOptionClick}>
2020-08-31 13:18:39 +02:00
Ajouter
</button>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</section>
);
};