2020-08-27 17:21:34 +02:00
|
|
|
import React, {useState} from 'react';
|
|
|
|
|
|
|
|
type Props = {
|
|
|
|
values: string[];
|
|
|
|
setValue: (field: string, value: string[]) => Promise<void>;
|
|
|
|
field: string;
|
|
|
|
options: {[key: string]: string};
|
|
|
|
placeholder?: string;
|
2020-08-28 11:36:15 +02:00
|
|
|
invert?: boolean;
|
2020-08-27 17:21:34 +02:00
|
|
|
}
|
|
|
|
|
2020-08-28 11:36:15 +02:00
|
|
|
const EditableSelection: React.FC<Props> = ({ setValue, field, values: currentValues, options, placeholder, invert = false }) => {
|
2020-08-27 17:21:34 +02:00
|
|
|
const [active, setActive] = useState<boolean>(false);
|
|
|
|
|
|
|
|
currentValues = currentValues || [];
|
|
|
|
|
|
|
|
function onClick(ev) {
|
|
|
|
ev.stopPropagation();
|
|
|
|
|
|
|
|
setActive(!active);
|
|
|
|
}
|
|
|
|
|
|
|
|
function addOption(optionKey: string, selected: boolean) {
|
|
|
|
if (selected) {
|
|
|
|
if (currentValues.indexOf(optionKey) < 0) {
|
|
|
|
setValue(field, [...currentValues, optionKey]);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
setValue(field, currentValues.filter(value => value !== optionKey));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-28 11:36:15 +02:00
|
|
|
const selection = !invert ? currentValues : (currentValues.length ? Object.keys(options).filter(option => currentValues?.indexOf(option) < 0) : []);
|
|
|
|
|
2020-08-27 17:21:34 +02:00
|
|
|
return (<>
|
2020-08-28 11:36:15 +02:00
|
|
|
<a className="action-rename" onClick={onClick}>{selection.join(', ') || placeholder}</a>
|
2020-08-27 17:21:34 +02:00
|
|
|
{active && <ul className="bbb-selection">
|
|
|
|
{Object.keys(options).map(key => {
|
|
|
|
const label = options[key];
|
|
|
|
|
|
|
|
return (
|
|
|
|
<li key={key}>
|
2020-08-28 11:36:15 +02:00
|
|
|
<input
|
|
|
|
type="checkbox"
|
|
|
|
id={key}
|
|
|
|
className="checkbox"
|
|
|
|
checked={(currentValues.indexOf(key) > -1) !== invert}
|
|
|
|
value="1"
|
|
|
|
onChange={(ev) => addOption(key, ev.target.checked !== invert)} />
|
2020-08-27 17:21:34 +02:00
|
|
|
<label htmlFor={key}>{label}</label>
|
|
|
|
</li>
|
|
|
|
);
|
|
|
|
})}
|
|
|
|
</ul>}
|
|
|
|
</>);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default EditableSelection;
|