Add selection option for plugin selection component

Summary: This diff refactors the Select plugin sheet to have multi select and single select options. Also renamed the class names and variables, as its business logic is quite generic.

Reviewed By: jknoxville

Differential Revision: D18118359

fbshipit-source-id: 2f1a6840032b81c5fdd9af9f6e69ea2ff611bf13
This commit is contained in:
Pritesh Nandgaonkar
2019-10-29 13:41:44 -07:00
committed by Facebook Github Bot
parent 7017ed3458
commit 63ac7e7e93
2 changed files with 75 additions and 50 deletions

View File

@@ -21,7 +21,7 @@ import {
setActiveSheet as getActiveSheetAction, setActiveSheet as getActiveSheetAction,
setExportDataToFileActiveSheet as getExportDataToFileActiveSheetAction, setExportDataToFileActiveSheet as getExportDataToFileActiveSheetAction,
} from '../reducers/application'; } from '../reducers/application';
import SelectPluginSheet from './SelectPluginSheet'; import ListView from './ListView';
import {Dispatch, Action} from 'redux'; import {Dispatch, Action} from 'redux';
type OwnProps = { type OwnProps = {
@@ -48,7 +48,9 @@ class ExportDataPluginSheet extends Component<Props> {
render() { render() {
const {plugins, pluginStates, onHide} = this.props; const {plugins, pluginStates, onHide} = this.props;
return ( return (
<SelectPluginSheet <ListView
type="multiple"
title="Select the plugins for which you want to export the data"
onSelect={selectedArray => { onSelect={selectedArray => {
this.props.selectedPlugins(selectedArray); this.props.selectedPlugins(selectedArray);
const {share} = this.props; const {share} = this.props;
@@ -75,17 +77,21 @@ class ExportDataPluginSheet extends Component<Props> {
} }
} }
}} }}
plugins={getActivePersistentPlugins(pluginStates, plugins).reduce( elements={getActivePersistentPlugins(pluginStates, plugins)}
selectedElements={getActivePersistentPlugins(
pluginStates,
plugins,
).reduce(
(acc, plugin) => { (acc, plugin) => {
acc.set( if (
plugin, plugins.selectedPlugins.length <= 0 ||
plugins.selectedPlugins.length <= 0 plugins.selectedPlugins.includes(plugin)
? true ) {
: plugins.selectedPlugins.includes(plugin), acc.add(plugin);
); }
return acc; return acc;
}, },
new Map(), new Set([]) as Set<string>,
)} )}
onHide={onHide} onHide={onHide}
/> />

View File

@@ -22,20 +22,31 @@ import {unsetShare} from '../reducers/application';
import React, {Component} from 'react'; import React, {Component} from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
export type PluginSelection = Map<string, boolean>; export type SelectionType = 'multiple' | 'single';
type SubType =
| {
selectedElements: Set<string>;
type: 'multiple';
}
| {
selectedElement: string;
type: 'single';
};
type Props = { type Props = {
onSelect: (plugins: Array<string>) => void; onSelect: (elements: Array<string>) => void;
onHide: () => any; onHide: () => any;
plugins: PluginSelection; elements: Array<string>;
}; title: string;
} & SubType;
const Title = styled(Text)({ const Title = styled(Text)({
margin: 6, margin: 6,
}); });
type State = { type State = {
plugins: PluginSelection; selectedElements: Set<string>;
}; };
const Container = styled(FlexColumn)({ const Container = styled(FlexColumn)({
@@ -51,7 +62,7 @@ const Line = styled(View)({
flexShrink: 0, flexShrink: 0,
}); });
const PluginRowComponentContainer = styled(FlexColumn)({ const RowComponentContainer = styled(FlexColumn)({
overflow: 'scroll', overflow: 'scroll',
height: 'auto', height: 'auto',
backgroundColor: colors.white, backgroundColor: colors.white,
@@ -77,13 +88,13 @@ const Padder = styled('div')(
}), }),
); );
type PluginRowComponentProps = { type RowComponentProps = {
name: string; name: string;
selected: boolean; selected: boolean;
onChange: (name: string, selected: boolean) => void; onChange: (name: string, selected: boolean) => void;
}; };
class PluginRowComponent extends Component<PluginRowComponentProps> { class RowComponent extends Component<RowComponentProps> {
render() { render() {
const {name, selected, onChange} = this.props; const {name, selected, onChange} = this.props;
return ( return (
@@ -110,59 +121,67 @@ class PluginRowComponent extends Component<PluginRowComponentProps> {
} }
} }
export default class SelectPluginSheet extends Component<Props, State> { export default class ListView extends Component<Props, State> {
static contextTypes = { static contextTypes = {
store: PropTypes.object.isRequired, store: PropTypes.object.isRequired,
}; };
state = {plugins: new Map<string, boolean>()}; state: State = {selectedElements: new Set([])};
static getDerivedStateFromProps(props: Props, state: State) { static getDerivedStateFromProps(props: Props, state: State) {
if (state.plugins.size > 0) { if (state.selectedElements.size > 0) {
return null; return null;
} }
return {plugins: props.plugins}; if (props.type === 'multiple') {
return {selectedElements: props.selectedElements};
} else if (props.type === 'single') {
return {selectedElements: new Set([props.selectedElement])};
}
return null;
} }
onSubmit(plugins: PluginSelection) { handleChange = (id: string, selected: boolean) => {
const selectedArray = Array.from(plugins.entries()).reduce<string[]>( if (this.props.type === 'single') {
(acc, [plugin, selected]) => { if (!selected) {
if (selected) { this.setState({selectedElements: new Set([])});
acc.push(plugin); } else {
} this.setState({selectedElements: new Set([id])});
return acc; }
}, } else {
[], if (selected) {
); this.setState({
this.props.onSelect(selectedArray); selectedElements: new Set([...this.state.selectedElements, id]),
} });
} else {
const selectedElements = new Set([...this.state.selectedElements]);
selectedElements.delete(id);
this.setState({selectedElements});
}
}
};
render() { render() {
const onHide = () => { const onHide = () => {
this.context.store.dispatch(unsetShare()); this.context.store.dispatch(unsetShare());
this.props.onHide(); this.props.onHide();
}; };
const {plugins} = this.state;
return ( return (
<Container> <Container>
<FlexColumn> <FlexColumn>
<Title> <Title>{this.props.title}</Title>
Select the plugins for which you want to export the data <RowComponentContainer>
</Title> {this.props.elements.map(id => {
<PluginRowComponentContainer>
{Array.from(plugins.entries()).map(([pluginID, selected]) => {
return ( return (
<PluginRowComponent <RowComponent
name={pluginID} name={id}
key={pluginID} key={id}
selected={selected} selected={this.state.selectedElements.has(id)}
onChange={(id: string, selected: boolean) => { onChange={this.handleChange}
plugins.set(id, selected);
this.setState({plugins});
}}
/> />
); );
})} })}
</PluginRowComponentContainer> </RowComponentContainer>
</FlexColumn> </FlexColumn>
<Padder paddingTop={8} paddingBottom={2}> <Padder paddingTop={8} paddingBottom={2}>
<FlexRow> <FlexRow>
@@ -175,7 +194,7 @@ export default class SelectPluginSheet extends Component<Props, State> {
padded padded
type="primary" type="primary"
onClick={() => { onClick={() => {
this.onSubmit(this.state.plugins); this.props.onSelect([...this.state.selectedElements]);
}}> }}>
Submit Submit
</Button> </Button>