Update dialogs to use TypeScript

This commit is contained in:
Arnaud Vergnet 2020-09-22 11:49:31 +02:00
parent f95635136e
commit 98518c46b6
5 changed files with 149 additions and 166 deletions

View file

@ -17,36 +17,31 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
// @flow
import * as React from 'react';
import {Button, Dialog, Paragraph, Portal} from 'react-native-paper';
import i18n from 'i18n-js';
type PropsType = {
visible: boolean,
onDismiss: () => void,
title: string | React.Node,
message: string | React.Node,
visible: boolean;
onDismiss: () => void;
title: string | React.ReactNode;
message: string | React.ReactNode;
};
class AlertDialog extends React.PureComponent<PropsType> {
render(): React.Node {
const {props} = this;
return (
<Portal>
<Dialog visible={props.visible} onDismiss={props.onDismiss}>
<Dialog.Title>{props.title}</Dialog.Title>
<Dialog.Content>
<Paragraph>{props.message}</Paragraph>
</Dialog.Content>
<Dialog.Actions>
<Button onPress={props.onDismiss}>{i18n.t('dialog.ok')}</Button>
</Dialog.Actions>
</Dialog>
</Portal>
);
}
function AlertDialog(props: PropsType) {
return (
<Portal>
<Dialog visible={props.visible} onDismiss={props.onDismiss}>
<Dialog.Title>{props.title}</Dialog.Title>
<Dialog.Content>
<Paragraph>{props.message}</Paragraph>
</Dialog.Content>
<Dialog.Actions>
<Button onPress={props.onDismiss}>{i18n.t('dialog.ok')}</Button>
</Dialog.Actions>
</Dialog>
</Portal>
);
}
export default AlertDialog;

View file

@ -1,90 +0,0 @@
/*
* Copyright (c) 2019 - 2020 Arnaud Vergnet.
*
* This file is part of Campus INSAT.
*
* Campus INSAT is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Campus INSAT is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
// @flow
import * as React from 'react';
import i18n from 'i18n-js';
import {ERROR_TYPE} from '../../utils/WebData';
import AlertDialog from './AlertDialog';
type PropsType = {
visible: boolean,
onDismiss: () => void,
errorCode: number,
};
class ErrorDialog extends React.PureComponent<PropsType> {
title: string;
message: string;
generateMessage() {
const {props} = this;
this.title = i18n.t('errors.title');
switch (props.errorCode) {
case ERROR_TYPE.BAD_CREDENTIALS:
this.message = i18n.t('errors.badCredentials');
break;
case ERROR_TYPE.BAD_TOKEN:
this.message = i18n.t('errors.badToken');
break;
case ERROR_TYPE.NO_CONSENT:
this.message = i18n.t('errors.noConsent');
break;
case ERROR_TYPE.TOKEN_SAVE:
this.message = i18n.t('errors.tokenSave');
break;
case ERROR_TYPE.TOKEN_RETRIEVE:
this.message = i18n.t('errors.unknown');
break;
case ERROR_TYPE.BAD_INPUT:
this.message = i18n.t('errors.badInput');
break;
case ERROR_TYPE.FORBIDDEN:
this.message = i18n.t('errors.forbidden');
break;
case ERROR_TYPE.CONNECTION_ERROR:
this.message = i18n.t('errors.connectionError');
break;
case ERROR_TYPE.SERVER_ERROR:
this.message = i18n.t('errors.serverError');
break;
default:
this.message = i18n.t('errors.unknown');
break;
}
this.message += `\n\nCode ${props.errorCode}`;
}
render(): React.Node {
this.generateMessage();
const {props} = this;
return (
<AlertDialog
visible={props.visible}
onDismiss={props.onDismiss}
title={this.title}
message={this.message}
/>
);
}
}
export default ErrorDialog;

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2019 - 2020 Arnaud Vergnet.
*
* This file is part of Campus INSAT.
*
* Campus INSAT is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Campus INSAT is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
import * as React from 'react';
import i18n from 'i18n-js';
import {ERROR_TYPE} from '../../utils/WebData';
import AlertDialog from './AlertDialog';
type PropsType = {
visible: boolean;
onDismiss: () => void;
errorCode: number;
};
function ErrorDialog(props: PropsType) {
let title: string;
let message: string;
title = i18n.t('errors.title');
switch (props.errorCode) {
case ERROR_TYPE.BAD_CREDENTIALS:
message = i18n.t('errors.badCredentials');
break;
case ERROR_TYPE.BAD_TOKEN:
message = i18n.t('errors.badToken');
break;
case ERROR_TYPE.NO_CONSENT:
message = i18n.t('errors.noConsent');
break;
case ERROR_TYPE.TOKEN_SAVE:
message = i18n.t('errors.tokenSave');
break;
case ERROR_TYPE.TOKEN_RETRIEVE:
message = i18n.t('errors.unknown');
break;
case ERROR_TYPE.BAD_INPUT:
message = i18n.t('errors.badInput');
break;
case ERROR_TYPE.FORBIDDEN:
message = i18n.t('errors.forbidden');
break;
case ERROR_TYPE.CONNECTION_ERROR:
message = i18n.t('errors.connectionError');
break;
case ERROR_TYPE.SERVER_ERROR:
message = i18n.t('errors.serverError');
break;
default:
message = i18n.t('errors.unknown');
break;
}
message += `\n\nCode ${props.errorCode}`;
return (
<AlertDialog
visible={props.visible}
onDismiss={props.onDismiss}
title={title}
message={message}
/>
);
}
export default ErrorDialog;

View file

@ -17,8 +17,6 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
// @flow
import * as React from 'react';
import {
ActivityIndicator,
@ -30,20 +28,23 @@ import {
import i18n from 'i18n-js';
type PropsType = {
visible: boolean,
onDismiss?: () => void,
onAccept?: () => Promise<void>, // async function to be executed
title?: string,
titleLoading?: string,
message?: string,
startLoading?: boolean,
visible: boolean;
onDismiss?: () => void;
onAccept?: () => Promise<void>; // async function to be executed
title?: string;
titleLoading?: string;
message?: string;
startLoading?: boolean;
};
type StateType = {
loading: boolean,
loading: boolean;
};
class LoadingConfirmDialog extends React.PureComponent<PropsType, StateType> {
export default class LoadingConfirmDialog extends React.PureComponent<
PropsType,
StateType
> {
static defaultProps = {
onDismiss: () => {},
onAccept: (): Promise<void> => {
@ -71,14 +72,16 @@ class LoadingConfirmDialog extends React.PureComponent<PropsType, StateType> {
onClickAccept = () => {
const {props} = this;
this.setState({loading: true});
if (props.onAccept != null) props.onAccept().then(this.hideLoading);
if (props.onAccept != null) {
props.onAccept().then(this.hideLoading);
}
};
/**
* Waits for fade out animations to finish before hiding loading
* @returns {TimeoutID}
* @returns {NodeJS.Timeout}
*/
hideLoading = (): TimeoutID =>
hideLoading = (): NodeJS.Timeout =>
setTimeout(() => {
this.setState({loading: false});
}, 200);
@ -88,10 +91,12 @@ class LoadingConfirmDialog extends React.PureComponent<PropsType, StateType> {
*/
onDismiss = () => {
const {state, props} = this;
if (!state.loading && props.onDismiss != null) props.onDismiss();
if (!state.loading && props.onDismiss != null) {
props.onDismiss();
}
};
render(): React.Node {
render() {
const {state, props} = this;
return (
<Portal>
@ -121,5 +126,3 @@ class LoadingConfirmDialog extends React.PureComponent<PropsType, StateType> {
);
}
}
export default LoadingConfirmDialog;

View file

@ -17,28 +17,26 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
// @flow
import * as React from 'react';
import {Button, Dialog, Paragraph, Portal} from 'react-native-paper';
import {FlatList} from 'react-native';
export type OptionsDialogButtonType = {
title: string,
icon?: string,
onPress: () => void,
title: string;
icon?: string;
onPress: () => void;
};
type PropsType = {
visible: boolean,
title: string,
message: string,
buttons: Array<OptionsDialogButtonType>,
onDismiss: () => void,
visible: boolean;
title: string;
message: string;
buttons: Array<OptionsDialogButtonType>;
onDismiss: () => void;
};
class OptionsDialog extends React.PureComponent<PropsType> {
getButtonRender = ({item}: {item: OptionsDialogButtonType}): React.Node => {
function OptionsDialog(props: PropsType) {
const getButtonRender = ({item}: {item: OptionsDialogButtonType}) => {
return (
<Button onPress={item.onPress} icon={item.icon}>
{item.title}
@ -46,35 +44,32 @@ class OptionsDialog extends React.PureComponent<PropsType> {
);
};
keyExtractor = (item: OptionsDialogButtonType): string => {
const keyExtractor = (item: OptionsDialogButtonType): string => {
if (item.icon != null) {
return item.title + item.icon;
}
return item.title;
};
render(): React.Node {
const {props} = this;
return (
<Portal>
<Dialog visible={props.visible} onDismiss={props.onDismiss}>
<Dialog.Title>{props.title}</Dialog.Title>
<Dialog.Content>
<Paragraph>{props.message}</Paragraph>
</Dialog.Content>
<Dialog.Actions>
<FlatList
data={props.buttons}
renderItem={this.getButtonRender}
keyExtractor={this.keyExtractor}
horizontal
inverted
/>
</Dialog.Actions>
</Dialog>
</Portal>
);
}
return (
<Portal>
<Dialog visible={props.visible} onDismiss={props.onDismiss}>
<Dialog.Title>{props.title}</Dialog.Title>
<Dialog.Content>
<Paragraph>{props.message}</Paragraph>
</Dialog.Content>
<Dialog.Actions>
<FlatList
data={props.buttons}
renderItem={getButtonRender}
keyExtractor={keyExtractor}
horizontal
inverted
/>
</Dialog.Actions>
</Dialog>
</Portal>
);
}
export default OptionsDialog;