ui: Refactor AdvancedMultiSelect as a class

AdvancedMultiSelect can be broken up and composed of smaller, more
focused components. This commit refactors AdvancedMultiSelect from a
functional component to a class component.
This commit is contained in:
Mike Salvatore 2021-01-08 11:42:04 -05:00
parent 62541d2027
commit 84b422a120
1 changed files with 87 additions and 75 deletions

View File

@ -1,5 +1,4 @@
import React, {useState} from 'react'; import React from "react";
import {Card, Button, Form} from 'react-bootstrap'; import {Card, Button, Form} from 'react-bootstrap';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {faCheckSquare} from '@fortawesome/free-solid-svg-icons'; import {faCheckSquare} from '@fortawesome/free-solid-svg-icons';
@ -22,14 +21,6 @@ function getSelectValuesAfterClick(valueArray, clickedValue) {
} }
} }
function onMasterCheckboxClick(checkboxValue, defaultArray, onChangeFnc) {
if (checkboxValue) {
onChangeFnc([]);
} else {
onChangeFnc(defaultArray);
}
}
// 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) {
@ -46,18 +37,39 @@ function getFullDefinitionByKey(refString, registry, itemKey) {
return fullArray.filter(e => (e.enum[0] === itemKey))[0]; return fullArray.filter(e => (e.enum[0] === itemKey))[0];
} }
function setPaneInfo(refString, registry, itemKey, setPaneInfoFnc) {
let definitionObj = getFullDefinitionByKey(refString, registry, itemKey);
setPaneInfoFnc({title: definitionObj.title, content: definitionObj.info, link: definitionObj.link});
}
function getDefaultPaneParams(refString, registry) { function getDefaultPaneParams(refString, registry) {
let configSection = getObjectFromRegistryByRef(refString, registry); let configSection = getObjectFromRegistryByRef(refString, registry);
return ({title: configSection.title, content: configSection.description}); return ({title: configSection.title, content: configSection.description});
} }
function AdvancedMultiSelect(props) { class AdvancedMultiSelect extends React.Component {
const [masterCheckbox, setMasterCheckbox] = useState(true); constructor(props) {
super(props)
this.state = {masterCheckbox: true, infoPaneParams: getDefaultPaneParams(props.schema.items.$ref, props.registry)};
this.onMasterCheckboxClick = this.onMasterCheckboxClick.bind(this);
}
onMasterCheckboxClick() {
if (this.state.masterCheckbox) {
this.props.onChange([]);
} else {
this.props.onChange(this.props.schema.default);
}
this.toggleMasterCheckbox();
}
toggleMasterCheckbox() {
this.setState((state) => ({
masterCheckbox: !state.masterCheckbox
}));
}
setPaneInfo(refString, registry, itemKey) {
let definitionObj = getFullDefinitionByKey(refString, registry, itemKey);
this.setState({infoPaneParams: {title: definitionObj.title, content: definitionObj.info, link: definitionObj.link}});
}
render() {
const { const {
schema, schema,
id, id,
@ -70,24 +82,19 @@ function AdvancedMultiSelect(props) {
autofocus, autofocus,
onChange, onChange,
registry registry
} = props; } = this.props;
const {enumOptions} = options; const {enumOptions} = options;
const [infoPaneParams, setInfoPaneParams] = useState(getDefaultPaneParams(schema.items.$ref, registry));
getDefaultPaneParams(schema.items.$ref, registry); getDefaultPaneParams(schema.items.$ref, registry);
const selectValue = cloneDeep(value); const selectValue = cloneDeep(value);
return ( return (
<div className={'advanced-multi-select'}> <div className={'advanced-multi-select'}>
<Card.Header> <Card.Header>
<Button key={`${props.schema.title}-button`} value={value} <Button key={`${schema.title}-button`} value={value}
variant={'link'} disabled={disabled} variant={'link'} disabled={disabled}
onClick={() => { onClick={this.onMasterCheckboxClick}>
onMasterCheckboxClick(masterCheckbox, schema.default, onChange); <FontAwesomeIcon icon={this.state.masterCheckbox ? faCheckSquare : faSquare}/>
setMasterCheckbox(!masterCheckbox);
}}
>
<FontAwesomeIcon icon={masterCheckbox ? faCheckSquare : faSquare}/>
</Button> </Button>
<span className={'header-title'}>{props.schema.title}</span> <span className={'header-title'}>{schema.title}</span>
</Card.Header> </Card.Header>
<Form.Group <Form.Group
style={{height: `${getComponentHeight(enumOptions.length)}px`}} style={{height: `${getComponentHeight(enumOptions.length)}px`}}
@ -97,13 +104,16 @@ function AdvancedMultiSelect(props) {
required={required} required={required}
disabled={disabled || readonly} disabled={disabled || readonly}
autoFocus={autofocus}> autoFocus={autofocus}>
{enumOptions.map(({value, label}, i) => { {
enumOptions.map(({value, label}, i) => {
return ( return (
<Form.Group <Form.Group
key={i} key={i}
onClick={() => setPaneInfo(schema.items.$ref, registry, value, setInfoPaneParams)}> onClick={() => this.setPaneInfo(schema.items.$ref, registry, value)}>
<Button value={value} variant={'link'} disabled={disabled} <Button value={value} variant={'link'} disabled={disabled}
onClick={() => onChange(getSelectValuesAfterClick(selectValue, value))}> onClick={() => onChange(getSelectValuesAfterClick(selectValue, value))}>
<FontAwesomeIcon icon={selectValue.includes(value) ? faCheckSquare : faSquare}/> <FontAwesomeIcon icon={selectValue.includes(value) ? faCheckSquare : faSquare}/>
</Button> </Button>
<span className={'option-text'}> <span className={'option-text'}>
@ -111,11 +121,13 @@ function AdvancedMultiSelect(props) {
</span> </span>
</Form.Group> </Form.Group>
); );
})} }
)}
</Form.Group> </Form.Group>
<InfoPane title={infoPaneParams.title} body={infoPaneParams.content} link={infoPaneParams.link}/> <InfoPane title={this.state.infoPaneParams.title} body={this.state.infoPaneParams.content} link={this.state.infoPaneParams.link}/>
</div> </div>
); );
}
} }
export default AdvancedMultiSelect; export default AdvancedMultiSelect;