Refactor Listview to solve a bug
Summary:
There was a bug in ListView where the selected items where not getting updated.
Bug
In the following video I have selected Inspector and logs plugin from export drop down. When I click on litho support form it should select the default plugins which is Inspector, Mobile Config and Logs. But it only shows Inspector and Logs selected
{F226900949}
To fix it:
I call the callback `onChange` when the listview's row get updated, which will updates the props of the ListView component and hence rerendering it with updated selected rows.
Reviewed By: mweststrate
Differential Revision: D19518762
fbshipit-source-id: 39367590cbdc1d6f88afb467b17b71e13703bde3
This commit is contained in:
committed by
Facebook Github Bot
parent
426d17b08d
commit
032b594221
@@ -41,7 +41,7 @@ type StateFromProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type DispatchFromProps = {
|
type DispatchFromProps = {
|
||||||
selectedPlugins: (payload: Array<string>) => void;
|
setSelectedPlugins: (payload: Array<string>) => void;
|
||||||
setActiveSheet: (payload: ActiveSheet) => void;
|
setActiveSheet: (payload: ActiveSheet) => void;
|
||||||
setExportDataToFileActiveSheet: (payload: {
|
setExportDataToFileActiveSheet: (payload: {
|
||||||
file: string;
|
file: string;
|
||||||
@@ -57,32 +57,43 @@ const Container = styled(FlexColumn)({
|
|||||||
maxHeight: 700,
|
maxHeight: 700,
|
||||||
});
|
});
|
||||||
|
|
||||||
class ExportDataPluginSheet extends Component<Props> {
|
type State = {
|
||||||
render() {
|
availablePluginsToExport: Array<string>;
|
||||||
const {
|
|
||||||
plugins,
|
|
||||||
pluginStates,
|
|
||||||
pluginMessageQueue,
|
|
||||||
onHide,
|
|
||||||
selectedClient,
|
|
||||||
} = this.props;
|
|
||||||
const onHideWithUnsettingShare = () => {
|
|
||||||
this.props.unsetShare();
|
|
||||||
onHide();
|
|
||||||
};
|
};
|
||||||
const pluginsToExport = getActivePersistentPlugins(
|
|
||||||
|
class ExportDataPluginSheet extends Component<Props, State> {
|
||||||
|
state: State = {availablePluginsToExport: []};
|
||||||
|
static getDerivedStateFromProps(props: Props, _state: State) {
|
||||||
|
const {plugins, pluginStates, pluginMessageQueue, selectedClient} = props;
|
||||||
|
const availablePluginsToExport = getActivePersistentPlugins(
|
||||||
pluginStates,
|
pluginStates,
|
||||||
pluginMessageQueue,
|
pluginMessageQueue,
|
||||||
plugins,
|
plugins,
|
||||||
selectedClient,
|
selectedClient,
|
||||||
);
|
);
|
||||||
|
return {
|
||||||
|
availablePluginsToExport,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
if (this.props.plugins.selectedPlugins.length <= 0) {
|
||||||
|
this.props.setSelectedPlugins(this.state.availablePluginsToExport);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {onHide} = this.props;
|
||||||
|
const onHideWithUnsettingShare = () => {
|
||||||
|
this.props.unsetShare();
|
||||||
|
onHide();
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<ListView
|
<ListView
|
||||||
type="multiple"
|
type="multiple"
|
||||||
title="Select the plugins for which you want to export the data"
|
title="Select the plugins for which you want to export the data"
|
||||||
onSelect={selectedArray => {
|
onSubmit={() => {
|
||||||
this.props.selectedPlugins(selectedArray);
|
|
||||||
const {share} = this.props;
|
const {share} = this.props;
|
||||||
if (!share) {
|
if (!share) {
|
||||||
console.error(
|
console.error(
|
||||||
@@ -107,18 +118,18 @@ class ExportDataPluginSheet extends Component<Props> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
elements={pluginsToExport}
|
onChange={selectedArray => {
|
||||||
selectedElements={pluginsToExport.reduce((acc, plugin) => {
|
if (selectedArray.length > 0) {
|
||||||
if (
|
this.props.setSelectedPlugins(selectedArray);
|
||||||
plugins.selectedPlugins.length <= 0 ||
|
} else {
|
||||||
plugins.selectedPlugins.includes(plugin)
|
this.props.setSelectedPlugins(
|
||||||
) {
|
this.state.availablePluginsToExport,
|
||||||
acc.add(plugin);
|
);
|
||||||
}
|
}
|
||||||
return acc;
|
}}
|
||||||
}, new Set([]) as Set<string>)}
|
elements={this.state.availablePluginsToExport}
|
||||||
|
selectedElements={new Set(this.props.plugins.selectedPlugins)}
|
||||||
onHide={onHideWithUnsettingShare}
|
onHide={onHideWithUnsettingShare}
|
||||||
showNavButtons={true}
|
|
||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
@@ -145,7 +156,7 @@ export default connect<StateFromProps, DispatchFromProps, OwnProps, Store>(
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
(dispatch: Dispatch<Action<any>>) => ({
|
(dispatch: Dispatch<Action<any>>) => ({
|
||||||
selectedPlugins: (plugins: Array<string>) => {
|
setSelectedPlugins: (plugins: Array<string>) => {
|
||||||
dispatch(actionForSelectedPlugins(plugins));
|
dispatch(actionForSelectedPlugins(plugins));
|
||||||
},
|
},
|
||||||
setActiveSheet: (payload: ActiveSheet) => {
|
setActiveSheet: (payload: ActiveSheet) => {
|
||||||
|
|||||||
@@ -33,11 +33,11 @@ type SubType =
|
|||||||
};
|
};
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
onSelect: (elements: Array<string>) => void;
|
onSubmit?: () => void;
|
||||||
|
onChange: (elements: Array<string>) => void;
|
||||||
onHide: () => any;
|
onHide: () => any;
|
||||||
elements: Array<string>;
|
elements: Array<string>;
|
||||||
title?: string;
|
title?: string;
|
||||||
showNavButtons: boolean;
|
|
||||||
} & SubType;
|
} & SubType;
|
||||||
|
|
||||||
const Title = styled(Text)({
|
const Title = styled(Text)({
|
||||||
@@ -113,16 +113,12 @@ class RowComponent extends Component<RowComponentProps> {
|
|||||||
|
|
||||||
export default class ListView extends Component<Props, State> {
|
export default class ListView extends Component<Props, State> {
|
||||||
state: State = {selectedElements: new Set([])};
|
state: State = {selectedElements: new Set([])};
|
||||||
static getDerivedStateFromProps(props: Props, state: State) {
|
static getDerivedStateFromProps(props: Props, _state: State) {
|
||||||
if (state.selectedElements.size > 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (props.type === 'multiple') {
|
if (props.type === 'multiple') {
|
||||||
return {selectedElements: props.selectedElements};
|
return {selectedElements: props.selectedElements};
|
||||||
} else if (props.type === 'single') {
|
} else if (props.type === 'single') {
|
||||||
return {selectedElements: new Set([props.selectedElement])};
|
return {selectedElements: new Set([props.selectedElement])};
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,21 +134,17 @@ export default class ListView extends Component<Props, State> {
|
|||||||
} else {
|
} else {
|
||||||
if (selected) {
|
if (selected) {
|
||||||
selectedElements = new Set([...this.state.selectedElements, id]);
|
selectedElements = new Set([...this.state.selectedElements, id]);
|
||||||
this.setState({
|
this.props.onChange([...selectedElements]);
|
||||||
selectedElements: selectedElements,
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
selectedElements = new Set([...this.state.selectedElements]);
|
selectedElements = new Set([...this.state.selectedElements]);
|
||||||
selectedElements.delete(id);
|
selectedElements.delete(id);
|
||||||
this.setState({selectedElements});
|
this.props.onChange([...selectedElements]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!this.props.showNavButtons) {
|
|
||||||
this.props.onSelect([...selectedElements]);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const {onSubmit} = this.props;
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<FlexColumn>
|
<FlexColumn>
|
||||||
@@ -170,20 +162,14 @@ export default class ListView extends Component<Props, State> {
|
|||||||
})}
|
})}
|
||||||
</RowComponentContainer>
|
</RowComponentContainer>
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
{this.props.showNavButtons && (
|
{onSubmit && (
|
||||||
<Padder paddingTop={8} paddingBottom={2}>
|
<Padder paddingTop={8} paddingBottom={2}>
|
||||||
<FlexRow>
|
<FlexRow>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<Button compact padded onClick={this.props.onHide}>
|
<Button compact padded onClick={this.props.onHide}>
|
||||||
Close
|
Close
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button compact padded type="primary" onClick={onSubmit}>
|
||||||
compact
|
|
||||||
padded
|
|
||||||
type="primary"
|
|
||||||
onClick={() => {
|
|
||||||
this.props.onSelect([...this.state.selectedElements]);
|
|
||||||
}}>
|
|
||||||
Submit
|
Submit
|
||||||
</Button>
|
</Button>
|
||||||
</FlexRow>
|
</FlexRow>
|
||||||
|
|||||||
Reference in New Issue
Block a user