148 lines
5.8 KiB
TypeScript
148 lines
5.8 KiB
TypeScript
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 }) => {
|
||
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) => {
|
||
const option = newOption("Décision", "", "");
|
||
setState(state => ({ ...state, changed: true, section: { ...state.section, options: [ ...state.section.options, option ] }}));
|
||
};
|
||
|
||
const onOptionChange = (id: string, attrName: string, evt: ChangeEvent<HTMLInputElement>) => {
|
||
const target = evt.currentTarget;
|
||
const value = target.hasOwnProperty('checked') ? target.checked : target.value;
|
||
var options = state.section.options;
|
||
options[id][attrName] = value;
|
||
setState(state => ({ ...state, changed: true, section: { ...state.section, options: 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
|
||
|
||
className="button is-danger is-small is-outlined">
|
||
🗑️
|
||
</button>
|
||
</td>
|
||
<td>
|
||
<textarea className="textarea"
|
||
value={o.label}
|
||
onChange={onOptionChange.bind(null, index, 'label')}
|
||
placeholder="Décrire cette décision."
|
||
rows={10}>
|
||
</textarea>
|
||
</td>
|
||
<td>
|
||
<textarea className="textarea"
|
||
value={o.pros}
|
||
onChange={onOptionChange.bind(null, index, 'pros')}
|
||
placeholder="Décrire les avantages de cette décision."
|
||
rows={10}>
|
||
</textarea>
|
||
</td>
|
||
<td>
|
||
<textarea className="textarea"
|
||
value={o.cons}
|
||
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>
|
||
<td className={`noPrint`}></td>
|
||
<td colSpan={4}>Aucune option pour l'instant.</td>
|
||
</tr> :
|
||
null
|
||
}
|
||
</tbody>
|
||
<tfoot>
|
||
<tr>
|
||
<td className={`noPrint`} colSpan={3}></td>
|
||
<td colSpan={2}>
|
||
<div className="field has-addons noPrint">
|
||
<p className="control">
|
||
<a className="button is-primary" onClick={onAddOptionClick}>
|
||
Ajouter
|
||
</a>
|
||
</p>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</tfoot>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
);
|
||
}; |