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

View File

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