Commit 3ec16569 authored by Cyrille Bollu's avatar Cyrille Bollu
Browse files

Shows errors on the user interface with toast notifications


Signed-off-by: default avatarCyrille Bollu <cyrille@bollu.be>
parent e1800a8d
Pipeline #460188 failed with stage
in 18 seconds
......@@ -4,6 +4,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage';
import { KeyboardAvoidingView, Appearance } from 'react-native';
import { NavigationContainer, DefaultTheme, DarkTheme } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import Toast from 'react-native-toast-message'
import * as Font from 'expo-font';
import AppLoading from 'expo-app-loading';
import Login from './components/Login';
......@@ -141,6 +142,7 @@ class App extends React.Component {
<Stack.Screen name="NewCard" component={Card} />
</Stack.Navigator>
</NavigationContainer>
<Toast />
</KeyboardAvoidingView>
)
}
......
......@@ -7,6 +7,7 @@ import { setToken } from '../store/tokenSlice';
import { Pressable, RefreshControl, ScrollView, View, Text, TextInput } from 'react-native';
import { DraxProvider } from 'react-native-drax';
import { initialWindowMetrics } from 'react-native-safe-area-context';
import Toast from 'react-native-toast-message';
import {i18n} from '../i18n/i18n.js';
import axios from 'axios';
import AppMenu from './AppMenu';
......@@ -122,13 +123,23 @@ class AllBoards extends React.Component {
})
.then((resp) => {
if (resp.status !== 200) {
console.log('Error', resp)
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: resp,
})
console.log('Error', resp)
} else {
console.log('Board created')
this.props.addBoard(resp.data)
}
})
.catch((error) => {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: error.message,
})
this.setState({ newBoardName: '' })
console.log(error)
})
......@@ -149,6 +160,11 @@ class AllBoards extends React.Component {
})
.then((resp) => {
if (resp.status !== 200) {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: resp,
})
console.log('Error', resp)
} else {
console.log('boards retrieved from server')
......@@ -165,6 +181,11 @@ class AllBoards extends React.Component {
}
})
.catch((error) => {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: error.message,
})
this.setState({
refreshing: false
})
......
......@@ -4,6 +4,7 @@ import { ActionSheetIOS, Pressable, View, Text, TextInput } from 'react-native';
import { initialWindowMetrics } from 'react-native-safe-area-context';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'
import Toast from 'react-native-toast-message';
import { addBoard, deleteBoard, renameBoard } from '../store/boardSlice';
import Icon from './Icon';
import axios from 'axios';
......@@ -108,6 +109,11 @@ class Board extends React.Component {
})
.then((resp) => {
if (resp.status !== 200) {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: resp,
})
this.props.addBoard(this.props.board)
console.log('Error', resp)
} else {
......@@ -115,6 +121,11 @@ class Board extends React.Component {
}
})
.catch((error) => {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: error.message,
})
this.props.addBoard(this.props.board)
console.log(error)
})
......@@ -131,6 +142,11 @@ class Board extends React.Component {
})
.then((resp) => {
if (resp.status !== 200) {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: resp,
})
this.props.addBoard(this.props.board)
console.log('Error', resp)
} else {
......@@ -138,6 +154,11 @@ class Board extends React.Component {
}
})
.catch((error) => {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: error.message,
})
this.props.addBoard(this.props.board)
console.log(error)
})
......@@ -163,6 +184,11 @@ class Board extends React.Component {
})
.then((resp) => {
if (resp.status !== 200) {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: resp,
})
this.props.renameBoard({
boardId: this.props.board.id,
boardTitle: boardNameBackup
......@@ -173,6 +199,11 @@ class Board extends React.Component {
}
})
.catch((error) => {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: error.message,
})
this.props.renameBoard({
boardId: this.props.board.id,
boardTitle: boardNameBackup
......
......@@ -11,6 +11,7 @@ import { DraxProvider, DraxScrollView, DraxView } from 'react-native-drax';
import axios from 'axios';
import { initialWindowMetrics } from 'react-native-safe-area-context';
import { HeaderBackButton } from '@react-navigation/elements';
import Toast from 'react-native-toast-message';
import { i18n } from '../i18n/i18n.js';
// Component that display a board's cards, grouped by stack
......@@ -327,6 +328,11 @@ class BoardDetails extends React.Component {
})
.then((resp) => {
if (resp.status !== 200) {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: resp,
})
console.log('Error', resp)
} else {
console.log('Card created')
......@@ -343,6 +349,11 @@ class BoardDetails extends React.Component {
}
})
.catch((error) => {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: error.message,
})
console.log(error)
})
}
......@@ -362,7 +373,12 @@ class BoardDetails extends React.Component {
})
.then((resp) => {
if (resp.status !== 200) {
console.log('Error', resp)
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: resp,
})
console.log('Error', resp)
} else {
console.log('Stack created')
// Add stack to board in store
......@@ -382,7 +398,12 @@ class BoardDetails extends React.Component {
}
})
.catch((error) => {
console.log(error)
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: error.message,
})
console.log(error)
})
}
......@@ -399,29 +420,42 @@ class BoardDetails extends React.Component {
'Authorization': this.props.token.value
}
}).then((resp) => {
// TODO check for error
console.log('board details retrieved from server')
this.setState({
refreshing: false
})
// Update board's details in store
resp.data.forEach(stack => {
this.props.addStack({
boardId: this.props.route.params.boardId,
stack
if (resp.status !== 200) {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: resp,
})
})
// Shows last visited stack or stack with order === 0 (assumes server's answer is ordered)
// TODO: handle case where the remembered stackId has been deleted
if (resp.data.length > 0) {
console.log('Error', resp)
} else {
console.log('board details retrieved from server')
this.setState({
index: (this.props.route.params.stackId !== null && this.state.index === null) ? parseInt(this.props.route.params.stackId) : this.state.index ?? resp.data[0].id,
refreshing: false
})
// Update board's details in store
resp.data.forEach(stack => {
this.props.addStack({
boardId: this.props.route.params.boardId,
stack
})
})
}
// Shows last visited stack or stack with order === 0 (assumes server's answer is ordered)
// TODO: handle case where the remembered stackId has been deleted
if (resp.data.length > 0) {
this.setState({
index: (this.props.route.params.stackId !== null && this.state.index === null) ? parseInt(this.props.route.params.stackId) : this.state.index ?? resp.data[0].id,
})
}
}
}).catch((error) => {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: error.message,
})
console.log(error)
})
}
......@@ -443,15 +477,28 @@ class BoardDetails extends React.Component {
'Authorization': this.props.token.value
}
})
.then(() => {
// TODO check for error
console.log('card moved')
// Refresh board
return this.loadBoard()
.then((resp) => {
if (resp.status !== 200) {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: resp,
})
console.log('Error', resp)
} else {
console.log('card moved')
// Refresh board
return this.loadBoard()
}
})
.catch(() => {
.catch((error) => {
// Reverts change and inform user
// TODO inform user
console.log(error)
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: error.message,
})
this.props.moveCard({
boardId: this.props.route.params.boardId,
oldStackId: stackId,
......@@ -472,6 +519,11 @@ class BoardDetails extends React.Component {
})
.then((resp) => {
if (resp.status !== 200) {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: resp,
})
console.log('Error', resp)
} else {
console.log('Stack deleted')
......@@ -482,6 +534,11 @@ class BoardDetails extends React.Component {
}
})
.catch((error) => {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: error.message,
})
console.log(error)
})
}
......@@ -497,6 +554,11 @@ class BoardDetails extends React.Component {
})
.then((resp) => {
if (resp.status !== 200) {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: resp,
})
console.log('Error', resp)
} else {
console.log('Card deleted')
......@@ -508,7 +570,12 @@ class BoardDetails extends React.Component {
}
})
.catch((error) => {
console.log(error)
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: error.message,
})
console.log(error)
})
}
......
......@@ -11,6 +11,7 @@ import BouncyCheckbox from "react-native-bouncy-checkbox";
import DateTimePicker from '@react-native-community/datetimepicker';
import axios from 'axios';
import * as Localization from 'expo-localization';
import Toast from 'react-native-toast-message';
import {i18n} from '../i18n/i18n.js';
class Card extends React.Component {
......@@ -202,6 +203,11 @@ class Card extends React.Component {
})
.then((resp) => {
if (resp.status !== 200) {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: resp,
})
console.log('Error', resp)
} else {
console.log('Card saved')
......@@ -209,6 +215,11 @@ class Card extends React.Component {
}
})
.catch((error) => {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: error.message,
})
console.log(error)
})
}
......
import React from 'react';
import { View } from 'react-native';
import Menu, { MenuItem } from 'react-native-material-menu';
import axios from 'axios';
import {i18n} from '../i18n/i18n.js';
export default class CardMenu extends React.Component {
constructor(props) {
super(props)
this.menu = React.createRef()
this.moveCard = this.moveCard.bind(this)
}
render() {
return (
<View>
<Menu
ref={this.menu}
>
<MenuItem
onPress={() => {
this.menu.current.hide();
}}
>
{i18n.t('moveCard')}
</MenuItem>
</Menu>
</View>
)
}
moveCard() {
// Gets the board 'stacks
axios.put(this.props.server.value + `/index.php/apps/deck/api/v1.0/boards/${this.props.route.params.boardId}/stacks/${this.props.route.params.stackId}/cards/${this.props.route.params.cardId}/reorder`, {
headers: {
'Content-Type': 'application/json',
'Authorization': this.props.token.value
}
})
.then(() => {
})
}
}
\ No newline at end of file
......@@ -11,6 +11,7 @@ export const en = {
description : 'Description: ',
dueDate : 'Due date: ',
edit : 'Edit',
error: 'Error',
logout: 'Logout',
moveCard : 'Move card',
noStack : 'This board has no stack. Start working by first creating a stack.',
......@@ -39,6 +40,7 @@ export const fr = {
description : 'Description: ',
dueDate : 'Echéance: ',
edit : 'Modifier',
error: 'Erreur',
logout: 'Logout',
moveCard : 'Déplacer la carte',
noStack : 'Ce tableau n\'a pas de liste. Commencez par en créer une.',
......
......@@ -7297,6 +7297,11 @@
"resolved": "https://registry.npmjs.org/react-native-tab-view/-/react-native-tab-view-3.1.1.tgz",
"integrity": "sha512-M5pRN6utQfytKWoKlKVzg5NbkYu308qNoW1khGTtEOTs1k14p2dHJ/BWOJoJYHKbPVUyZldbG9MFT7gUl4YHnw=="
},
"react-native-toast-message": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/react-native-toast-message/-/react-native-toast-message-2.0.2.tgz",
"integrity": "sha512-jjHRgK4o388WTfikoJ2D/EWtnrXKOW8YvpSBMENRG/QwK9C6SUWZ2zas/lpP634IMUbS1VuKwtQqpNXoJIAHwg=="
},
"react-native-vector-icons": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-8.1.0.tgz",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment