forked from p15670423/monkey
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:
parent
62541d2027
commit
84b422a120
|
@ -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,76 +37,97 @@ 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) {
|
||||||
const {
|
super(props)
|
||||||
schema,
|
this.state = {masterCheckbox: true, infoPaneParams: getDefaultPaneParams(props.schema.items.$ref, props.registry)};
|
||||||
id,
|
this.onMasterCheckboxClick = this.onMasterCheckboxClick.bind(this);
|
||||||
options,
|
}
|
||||||
value,
|
|
||||||
required,
|
onMasterCheckboxClick() {
|
||||||
disabled,
|
if (this.state.masterCheckbox) {
|
||||||
readonly,
|
this.props.onChange([]);
|
||||||
multiple,
|
} else {
|
||||||
autofocus,
|
this.props.onChange(this.props.schema.default);
|
||||||
onChange,
|
}
|
||||||
registry
|
|
||||||
} = props;
|
this.toggleMasterCheckbox();
|
||||||
const {enumOptions} = options;
|
}
|
||||||
const [infoPaneParams, setInfoPaneParams] = useState(getDefaultPaneParams(schema.items.$ref, registry));
|
|
||||||
getDefaultPaneParams(schema.items.$ref, registry);
|
toggleMasterCheckbox() {
|
||||||
const selectValue = cloneDeep(value);
|
this.setState((state) => ({
|
||||||
return (
|
masterCheckbox: !state.masterCheckbox
|
||||||
<div className={'advanced-multi-select'}>
|
}));
|
||||||
<Card.Header>
|
}
|
||||||
<Button key={`${props.schema.title}-button`} value={value}
|
|
||||||
variant={'link'} disabled={disabled}
|
setPaneInfo(refString, registry, itemKey) {
|
||||||
onClick={() => {
|
let definitionObj = getFullDefinitionByKey(refString, registry, itemKey);
|
||||||
onMasterCheckboxClick(masterCheckbox, schema.default, onChange);
|
this.setState({infoPaneParams: {title: definitionObj.title, content: definitionObj.info, link: definitionObj.link}});
|
||||||
setMasterCheckbox(!masterCheckbox);
|
}
|
||||||
}}
|
render() {
|
||||||
>
|
const {
|
||||||
<FontAwesomeIcon icon={masterCheckbox ? faCheckSquare : faSquare}/>
|
schema,
|
||||||
</Button>
|
id,
|
||||||
<span className={'header-title'}>{props.schema.title}</span>
|
options,
|
||||||
</Card.Header>
|
value,
|
||||||
<Form.Group
|
required,
|
||||||
style={{height: `${getComponentHeight(enumOptions.length)}px`}}
|
disabled,
|
||||||
id={id}
|
readonly,
|
||||||
multiple={multiple}
|
multiple,
|
||||||
className='choice-block form-control'
|
autofocus,
|
||||||
required={required}
|
onChange,
|
||||||
disabled={disabled || readonly}
|
registry
|
||||||
autoFocus={autofocus}>
|
} = this.props;
|
||||||
{enumOptions.map(({value, label}, i) => {
|
const {enumOptions} = options;
|
||||||
return (
|
getDefaultPaneParams(schema.items.$ref, registry);
|
||||||
<Form.Group
|
const selectValue = cloneDeep(value);
|
||||||
key={i}
|
return (
|
||||||
onClick={() => setPaneInfo(schema.items.$ref, registry, value, setInfoPaneParams)}>
|
<div className={'advanced-multi-select'}>
|
||||||
<Button value={value} variant={'link'} disabled={disabled}
|
<Card.Header>
|
||||||
onClick={() => onChange(getSelectValuesAfterClick(selectValue, value))}>
|
<Button key={`${schema.title}-button`} value={value}
|
||||||
<FontAwesomeIcon icon={selectValue.includes(value) ? faCheckSquare : faSquare}/>
|
variant={'link'} disabled={disabled}
|
||||||
</Button>
|
onClick={this.onMasterCheckboxClick}>
|
||||||
<span className={'option-text'}>
|
<FontAwesomeIcon icon={this.state.masterCheckbox ? faCheckSquare : faSquare}/>
|
||||||
{label}
|
</Button>
|
||||||
</span>
|
<span className={'header-title'}>{schema.title}</span>
|
||||||
</Form.Group>
|
</Card.Header>
|
||||||
);
|
<Form.Group
|
||||||
})}
|
style={{height: `${getComponentHeight(enumOptions.length)}px`}}
|
||||||
</Form.Group>
|
id={id}
|
||||||
<InfoPane title={infoPaneParams.title} body={infoPaneParams.content} link={infoPaneParams.link}/>
|
multiple={multiple}
|
||||||
</div>
|
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}
|
||||||
|
onClick={() => onChange(getSelectValuesAfterClick(selectValue, value))}>
|
||||||
|
|
||||||
|
<FontAwesomeIcon icon={selectValue.includes(value) ? faCheckSquare : faSquare}/>
|
||||||
|
</Button>
|
||||||
|
<span className={'option-text'}>
|
||||||
|
{label}
|
||||||
|
</span>
|
||||||
|
</Form.Group>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
</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;
|
||||||
|
|
Loading…
Reference in New Issue