Skip to content

Commit

Permalink
Allow to clear car selection
Browse files Browse the repository at this point in the history
  • Loading branch information
AlixH committed Nov 17, 2021
1 parent 74c9b79 commit 3a594a0
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 16 deletions.
50 changes: 36 additions & 14 deletions src/components/modal/ModalSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,20 @@ export interface Props<T> extends BaseProps {
disabled?: boolean;
label?: string;
renderItem?: (item?: T) => React.ReactElement;
// Render a generic item when the items list is empty (only if renderItemPlaceholder is null)
renderNoItem?: () => React.ReactElement;
// Render a generic item when nothing is selected
renderItemPlaceholder?: () => React.ReactElement;
// Whether or not to display the button to cleat the input
canClearInput?: boolean;
selectionMode: ItemSelectionMode;
onItemsSelected: (selectedItems: T[]) => void;
defaultItemLoading?: boolean;
openable?: boolean;
}
interface State<T> {
isVisible: boolean;
noneSelected: boolean;
selectedItems: T[];
selectedItemsCount: number;
}
Expand All @@ -42,12 +47,29 @@ export default class ModalSelect<T extends ListItem> extends React.Component<Pro
this.state = {
isVisible: false,
selectedItems: [],
selectedItemsCount: 0
selectedItemsCount: 0,
noneSelected: false
};
}

public clearInput() {
this.setState({ selectedItems: [] });
public componentDidMount() {
this.setState({ selectedItems: [this.props.defaultItem] });
}

public componentDidUpdate(prevProps: Readonly<Props<T>>, prevState: Readonly<State<T>>, snapshot?: any) {
if(this.state.selectedItems[0]?.id !== this.props.defaultItem?.id && this.state.noneSelected === false) {
this.setState({ selectedItems: [this.props.defaultItem, ...this.state.selectedItems.slice(1)] });
}
}

public resetInput(noneSelected: boolean = false): void {
this.itemsListRef?.current?.clearSelectedItems();
this.setState({noneSelected, selectedItems: [], selectedItemsCount: 0, isVisible: false});
}

private clearInput(): void {
this.resetInput(true);

}

public render() {
Expand Down Expand Up @@ -88,7 +110,7 @@ export default class ModalSelect<T extends ListItem> extends React.Component<Pro
</View>
{selectionMode === ItemSelectionMode.MULTI && (
<View style={style.bottomButtonContainer}>
<Button style={style.modalButton} block light onPress={() => this.clearSelection()}>
<Button style={style.modalButton} block light onPress={() => this.resetInput()}>
<Text style={style.buttonText}>{I18n.t('general.reset')}</Text>
</Button>
<Button
Expand All @@ -107,11 +129,6 @@ export default class ModalSelect<T extends ListItem> extends React.Component<Pro
);
}

private clearSelection(): void {
this.itemsListRef?.current?.clearSelectedItems();
this.setState(this.state);
}

private validateSelection(): void {
const { onItemsSelected } = this.props;
const selectedItems = this.itemsListRef?.current?.state.selectedItems;
Expand All @@ -130,8 +147,8 @@ export default class ModalSelect<T extends ListItem> extends React.Component<Pro
}

private renderButton(style: any) {
const { defaultItemLoading, defaultItem, renderNoItem, renderItem, renderItemPlaceholder, openable, disabled } = this.props;
const { selectedItems } = this.state;
const { defaultItemLoading, renderNoItem, renderItem, renderItemPlaceholder, openable, disabled, canClearInput } = this.props;
const { selectedItems, noneSelected } = this.state;
const listItemCommonStyle = computeListItemCommonStyle();
const commonColors = Utils.getCurrentCommonColor();
if (defaultItemLoading) {
Expand All @@ -141,16 +158,21 @@ export default class ModalSelect<T extends ListItem> extends React.Component<Pro
</View>
);
}
if (defaultItem || selectedItems[0]) {
if (selectedItems[0]) {
return (
<TouchableOpacity
disabled={disabled || !openable}
onPress={() => this.setState({ isVisible: true })}
style={[style.itemContainer, disabled && style.buttonDisabled]}>
{renderItem?.(selectedItems.length > 0 ? selectedItems[0] : defaultItem)}
{canClearInput && (
<TouchableOpacity style={style.clearContainer} onPress={() => this.clearInput()}>
<Text style={{textAlign: 'right', color: commonColors.primary}}>Clear field</Text>
</TouchableOpacity>
)}
{renderItem?.(selectedItems[0])}
</TouchableOpacity>
);
} else if (renderItemPlaceholder) {
} else if (renderItemPlaceholder && noneSelected !== false) {
return (
<TouchableOpacity onPress={() => this.setState({ isVisible: true })} style={style.itemContainer}>
{renderItemPlaceholder?.()}
Expand Down
4 changes: 4 additions & 0 deletions src/components/modal/ModalStyles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ export default function computeStyleSheet(): StyleSheet.NamedStyles<any> {
marginLeft: '5%',
marginBottom: '6@s',
textAlign: 'left'
},
clearContainer: {
width: '100%',
paddingBottom: '3@s'
}
});
const portraitStyles = {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1071,9 +1071,11 @@ export default class ChargingStationConnectorDetails extends BaseAutoRefreshScre
disabled={disabled}
openable={true}
renderNoItem={this.renderNoCar.bind(this)}
canClearInput={true}
renderItem={() => <CarComponent car={selectedCar} navigation={navigation} />}
ref={this.carModalRef}
defaultItem={selectedCar}
renderItemPlaceholder={this.renderCarPlaceholder.bind(this)}
defaultItemLoading={tagCarLoading}
onItemsSelected={(selectedCars: Car[]) => this.setState({ selectedCar: selectedCars?.[0] })}
navigation={navigation}
Expand All @@ -1084,6 +1086,19 @@ export default class ChargingStationConnectorDetails extends BaseAutoRefreshScre
);
}

private renderCarPlaceholder() {
const listItemCommonStyle = computeListItemCommonStyle();
const style = computeStyleSheet();
return (
<View style={[listItemCommonStyle.container, style.noItemContainer, style.noCarContainer]}>
<Icon style={style.noCarIcon} type={'MaterialCommunityIcons'} name={'car'} />
<View style={style.column}>
<Text style={style.messageText}>{I18n.t('cars.noCarMessageTitle')}</Text>
</View>
</View>
);
}

private renderNoCar() {
const listItemCommonStyle = computeListItemCommonStyle();
const style = computeStyleSheet();
Expand Down Expand Up @@ -1168,8 +1183,8 @@ export default class ChargingStationConnectorDetails extends BaseAutoRefreshScre
this.setState({ tagCarLoading: true });
try {
const userDefaultTagCar = await this.getUserDefaultTagAndCar(selectedUser);
this.carModalRef.current?.clearInput();
this.tagModalRef.current?.clearInput();
this.carModalRef.current?.resetInput();
this.tagModalRef.current?.resetInput();
// Temporary workaround to ensure that the default property is set (server-side changes are to be done)
if (userDefaultTagCar?.tag) {
userDefaultTagCar.tag.default = true;
Expand Down

0 comments on commit 3a594a0

Please sign in to comment.