ui: Factor ChildCheckbox out of AdvancedMultiSelect

This commit is contained in:
Mike Salvatore 2021-01-11 19:11:27 -05:00
parent af329d56d8
commit 878f959a8f
1 changed files with 107 additions and 84 deletions

View File

@ -10,17 +10,6 @@ import {resolveObjectPath} from './utils/ObjectPathResolver';
import InfoPane from './InfoPane'; import InfoPane from './InfoPane';
function getSelectValuesAfterClick(valueArray, clickedValue) {
if (valueArray.includes(clickedValue)) {
return valueArray.filter((e) => {
return e !== clickedValue;
});
} else {
valueArray.push(clickedValue);
return valueArray;
}
}
// Definitions passed to components only contains value and label, // Definitions passed to components only contains value and label,
// custom fields like "info" or "links" must be pulled from registry object using this function // custom fields like "info" or "links" must be pulled from registry object using this function
function getFullDefinitionsFromRegistry(refString, registry) { function getFullDefinitionsFromRegistry(refString, registry) {
@ -56,95 +45,129 @@ function MasterCheckbox(props) {
<Button key={`${title}-button`} value={value} <Button key={`${title}-button`} value={value}
variant={'link'} disabled={disabled} variant={'link'} disabled={disabled}
onClick={onClick}> onClick={onClick}>
<FontAwesomeIcon icon={checkboxState ? faCheckSquare : faSquare} /> <FontAwesomeIcon icon={checkboxState ? faCheckSquare : faSquare}/>
</Button> </Button>
<span className={'header-title'}>{title}</span> <span className={'header-title'}>{title}</span>
</Card.Header> </Card.Header>
); );
} }
function ChildCheckbox(props) {
const {
onPaneClick,
onClick,
value,
disabled,
label,
checkboxState
} = props;
return (
<Form.Group onClick={() => onPaneClick(value)}>
<Button value={value} variant={'link'} disabled={disabled} onClick={() => onClick(value)}>
<FontAwesomeIcon icon={checkboxState ? faCheckSquare : faSquare}/>
</Button>
<span className={'option-text'}>
{label}
</span>
</Form.Group>
);
}
class AdvancedMultiSelect extends React.Component { class AdvancedMultiSelect extends React.Component {
constructor(props) { constructor(props) {
super(props) super(props)
this.state = {masterCheckbox: true, infoPaneParams: getDefaultPaneParams(props.schema.items.$ref, props.registry)}; this.state = {masterCheckbox: true, infoPaneParams: getDefaultPaneParams(props.schema.items.$ref, props.registry)};
this.onMasterCheckboxClick = this.onMasterCheckboxClick.bind(this); this.onMasterCheckboxClick = this.onMasterCheckboxClick.bind(this);
this.onChildCheckboxClick = this.onChildCheckboxClick.bind(this);
this.setPaneInfo = this.setPaneInfo.bind(this, props.schema.items.$ref, props.registry);
}
onMasterCheckboxClick() {
if (this.state.masterCheckbox) {
this.props.onChange([]);
} else {
this.props.onChange(this.props.schema.default);
} }
onMasterCheckboxClick() { this.toggleMasterCheckbox();
if (this.state.masterCheckbox) { }
this.props.onChange([]);
} else {
this.props.onChange(this.props.schema.default);
}
this.toggleMasterCheckbox(); onChildCheckboxClick(value) {
this.props.onChange(this.getSelectValuesAfterClick(value));
}
getSelectValuesAfterClick(clickedValue) {
const valueArray = cloneDeep(this.props.value);
if (valueArray.includes(clickedValue)) {
return valueArray.filter((e) => {
return e !== clickedValue;
});
} else {
valueArray.push(clickedValue);
return valueArray;
} }
}
toggleMasterCheckbox() { toggleMasterCheckbox() {
this.setState((state) => ({ this.setState((state) => ({
masterCheckbox: !state.masterCheckbox masterCheckbox: !state.masterCheckbox
})); }));
} }
setPaneInfo(refString, registry, itemKey) { setPaneInfo(refString, registry, itemKey) {
let definitionObj = getFullDefinitionByKey(refString, registry, itemKey); let definitionObj = getFullDefinitionByKey(refString, registry, itemKey);
this.setState({infoPaneParams: {title: definitionObj.title, content: definitionObj.info, link: definitionObj.link}}); this.setState({infoPaneParams: {title: definitionObj.title, content: definitionObj.info, link: definitionObj.link}});
} }
render() { render() {
const { const {
schema, schema,
id, id,
options, options,
value, value,
required, required,
disabled, disabled,
readonly, readonly,
multiple, multiple,
autofocus, autofocus,
onChange, onChange,
registry registry
} = this.props; } = this.props;
const {enumOptions} = options;
getDefaultPaneParams(schema.items.$ref, registry);
const selectValue = cloneDeep(value);
return (
<div className={'advanced-multi-select'}>
<MasterCheckbox title={schema.title} value={value}
disabled={disabled} onClick={this.onMasterCheckboxClick}
checkboxState={this.state.masterCheckbox} />
<Form.Group
style={{height: `${getComponentHeight(enumOptions.length)}px`}}
id={id}
multiple={multiple}
className='choice-block form-control'
required={required}
disabled={disabled || readonly}
autoFocus={autofocus}>
{
enumOptions.map(({value, label}, i) => {
return (
<Form.Group
key={i}
onClick={() => this.setPaneInfo(schema.items.$ref, registry, value)}>
<Button value={value} variant={'link'} disabled={disabled} const {enumOptions} = options;
onClick={() => onChange(getSelectValuesAfterClick(selectValue, value))}> getDefaultPaneParams(schema.items.$ref, registry);
<FontAwesomeIcon icon={selectValue.includes(value) ? faCheckSquare : faSquare}/> return (
</Button> <div className={'advanced-multi-select'}>
<span className={'option-text'}> <MasterCheckbox title={schema.title} value={value}
{label} disabled={disabled} onClick={this.onMasterCheckboxClick}
</span> checkboxState={this.state.masterCheckbox}/>
</Form.Group> <Form.Group
); style={{height: `${getComponentHeight(enumOptions.length)}px`}}
} id={id}
)} multiple={multiple}
</Form.Group> className='choice-block form-control'
<InfoPane title={this.state.infoPaneParams.title} body={this.state.infoPaneParams.content} link={this.state.infoPaneParams.link}/> required={required}
</div> disabled={disabled || readonly}
); autoFocus={autofocus}>
} {
enumOptions.map(({value, label}, i) => {
return (
<ChildCheckbox key={i} onPaneClick={this.setPaneInfo}
onClick={this.onChildCheckboxClick} value={value}
disabled={disabled} label={label} checkboxState={this.props.value.includes(value)}/>
);
}
)}
</Form.Group>
<InfoPane title={this.state.infoPaneParams.title}
body={this.state.infoPaneParams.content}
link={this.state.infoPaneParams.link}/>
</div>
);
}
} }
export default AdvancedMultiSelect; export default AdvancedMultiSelect;