import * as React from 'react'; import { copyTransforms, RefinerProps } from './utils'; import { debounce } from 'lodash'; interface ChoiceState { id: string; // unique id for the Component choices: any[]; //the selected choices } /** * Column Component to add filter/refinement functionality to a categorical table column. */ export class ColumnChoiceRefinerComponent extends React.Component< RefinerProps, ChoiceState > { protected static id_counter = 0; protected id; transformUpdateDebounced; constructor(props) { super(props); const state = { id: 'mmui_column_choice_refiner_component_' + this.getId(), choices: [], }; this.state = state; // debounce updating the transforms with input value const delay = this.props.transformsDelay === undefined ? 1000 : this.props.transformsDelay; const transformUpdateHandler = () => { this.updateTransforms(this.state.choices); }; this.transformUpdateDebounced = debounce(transformUpdateHandler, delay); } /** * Generate a unique id for this component instance */ protected getId(): string { if (this.id === undefined) { this.id = ColumnChoiceRefinerComponent.id_counter; ColumnChoiceRefinerComponent.id_counter++; } return this.id; } clearInputs = () => { // debounce updating the transforms with input value this.transformUpdateDebounced(); document .querySelectorAll(`#${this.state.id} input[type=checkbox]`) .forEach((el: any) => (el.checked = false)); this.setState( { choices: [], }, () => { this.props.setIsFiltered(false); } ); }; /** * Handles changes to the input field. * If there is a value in the input field, set a categorical transform with that value on config.columnName. * @param evt */ handleInputChange(evt) { const value = evt.target.value; const checked = evt.target.checked; // debounce updating the transforms with input value this.transformUpdateDebounced(); const selectedChoices = JSON.parse(JSON.stringify(this.state.choices)); const choiceIndex = selectedChoices.indexOf(value); if (checked) { if (choiceIndex < 0) { selectedChoices.push(value); } } else { if (choiceIndex >= 0) { selectedChoices.splice(choiceIndex, 1); } } this.setState( { choices: selectedChoices, }, () => { if (this.state.choices.length > 0) { this.props.setIsFiltered(true); } else { this.props.setIsFiltered(false); } } ); } updateTransforms(choices) { let config = this.props.config, newTransforms, refinementTransform; const filters = []; for (let i = 0; i < choices.length; i++) { const filter = { value: choices[i], column: config.columnName, type: 'equalsTextStrict', }; filters.push(filter); } // make a complete copy of the transforms newTransforms = copyTransforms(this.props.transforms); if ( Object.prototype.hasOwnProperty.call( newTransforms.filters, config.columnName ) ) { refinementTransform = newTransforms.filters[config.columnName]; } else { refinementTransform = { type: 'or', column: config.columnName, }; } refinementTransform.filters = filters; newTransforms.filters[config.columnName] = refinementTransform; this.props.setTransforms(newTransforms); } /** * Render Column Component */ render() { const componentColumnId = this.getId(); return (
{this.props?.data?.extent.map((ex, i) => { if (ex != '') { const id = `${this.props.componentHeadId}-${componentColumnId}-${i}`; return (
); } })}
); } }