From 828bb40084963436aeb2c39fa2f5c75a8b17e983 Mon Sep 17 00:00:00 2001 From: Ildar Kamalov Date: Fri, 14 Sep 2018 15:37:35 +0300 Subject: [PATCH] Show toast on failed request --- client/package-lock.json | 26 ++++++++-- client/package.json | 3 +- client/src/actions/index.js | 33 ++++++++++--- client/src/api/Api.js | 16 ++++--- client/src/components/App/index.js | 5 +- client/src/components/Dashboard/index.js | 2 - client/src/components/Toasts/Toast.css | 60 ++++++++++++++++++++++++ client/src/components/Toasts/Toast.js | 36 ++++++++++++++ client/src/components/Toasts/index.js | 42 +++++++++++++++++ client/src/components/ui/Alertify.css | 9 ---- client/src/reducers/index.js | 30 ++++++++++++ 11 files changed, 230 insertions(+), 32 deletions(-) create mode 100644 client/src/components/Toasts/Toast.css create mode 100644 client/src/components/Toasts/Toast.js create mode 100644 client/src/components/Toasts/index.js delete mode 100644 client/src/components/ui/Alertify.css diff --git a/client/package-lock.json b/client/package-lock.json index 26ca1857..a40c8624 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -324,11 +324,6 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=" }, - "alertifyjs": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/alertifyjs/-/alertifyjs-1.11.1.tgz", - "integrity": "sha512-8rw5zvMlg0Idltq15OOU9tGabYVA/I8JTNIM5ICUXqvrdPb7cfl+sSkTv9pDc6bbB8p9L85GtmOG7SUSv+bugQ==" - }, "align-text": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", @@ -3854,6 +3849,11 @@ } } }, + "dom-helpers": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.3.1.tgz", + "integrity": "sha512-2Sm+JaYn74OiTM2wHvxJOo3roiq/h25Yi69Fqk269cNUwIXsCvATB6CRSFC9Am/20G2b28hGv/+7NiWydIrPvg==" + }, "dom-serializer": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", @@ -9053,6 +9053,11 @@ "dev": true, "optional": true }, + "nanoid": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-1.2.3.tgz", + "integrity": "sha512-BAnxAdaihzMoszwhqRy8FPOX+dijs7esUEUYTIQ1KsOSKmCVNYnitAMmBDFxYzA6VQYvuUKw7o2K1AcMBTGzIg==" + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -12953,6 +12958,17 @@ "prop-types": "^15.5.6" } }, + "react-transition-group": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.4.0.tgz", + "integrity": "sha512-Xv5d55NkJUxUzLCImGSanK8Cl/30sgpOEMGc5m86t8+kZwrPxPCPcFqyx83kkr+5Lz5gs6djuvE5By+gce+VjA==", + "requires": { + "dom-helpers": "^3.3.1", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + } + }, "read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", diff --git a/client/package.json b/client/package.json index 4b43075b..ce8e436d 100644 --- a/client/package.json +++ b/client/package.json @@ -10,12 +10,12 @@ }, "dependencies": { "@nivo/line": "^0.42.1", - "alertifyjs": "^1.11.1", "axios": "^0.18.0", "classnames": "^2.2.6", "date-fns": "^1.29.0", "file-saver": "^1.3.8", "lodash": "^4.17.10", + "nanoid": "^1.2.3", "prop-types": "^15.6.1", "react": "^16.4.0", "react-click-outside": "^3.0.1", @@ -24,6 +24,7 @@ "react-redux": "^5.0.7", "react-router-dom": "^4.2.2", "react-table": "^6.8.6", + "react-transition-group": "^2.4.0", "redux": "^4.0.0", "redux-actions": "^2.4.0", "redux-thunk": "^2.3.0", diff --git a/client/src/actions/index.js b/client/src/actions/index.js index 7905ffb1..de5b2c3b 100644 --- a/client/src/actions/index.js +++ b/client/src/actions/index.js @@ -1,12 +1,15 @@ import { createAction } from 'redux-actions'; import round from 'lodash/round'; -import alertify from 'alertifyjs'; import { normalizeHistory, normalizeFilteringStatus, normalizeLogs } from '../helpers/helpers'; import Api from '../api/Api'; const apiClient = new Api(); +export const addErrorToast = createAction('ADD_ERROR_TOAST'); +export const addSuccessToast = createAction('ADD_SUCCESS_TOAST'); +export const removeToast = createAction('REMOVE_TOAST'); + export const toggleSettingStatus = createAction('SETTING_STATUS_TOGGLE'); export const showSettingsFailure = createAction('SETTINGS_FAILURE_SHOW'); @@ -75,6 +78,7 @@ export const initSettings = settingsList => async (dispatch) => { dispatch(initSettingsSuccess({ settingsList: newSettingsList })); } catch (error) { console.error(error); + dispatch(addErrorToast({ error })); dispatch(initSettingsFailure()); } }; @@ -90,6 +94,7 @@ export const getDnsStatus = () => async (dispatch) => { dispatch(dnsStatusSuccess(dnsStatus)); } catch (error) { console.error(error); + dispatch(addErrorToast({ error })); dispatch(initSettingsFailure()); } }; @@ -105,6 +110,7 @@ export const enableDns = () => async (dispatch) => { dispatch(enableDnsSuccess()); } catch (error) { console.error(error); + dispatch(addErrorToast({ error })); dispatch(enableDnsFailure()); } }; @@ -120,8 +126,8 @@ export const disableDns = () => async (dispatch) => { dispatch(disableDnsSuccess()); } catch (error) { console.error(error); - alertify.error(`Failed to disable DNS with status code ${error.response.status}`); - dispatch(disableDnsFailure()); + dispatch(disableDnsFailure(error)); + dispatch(addErrorToast({ error })); } }; @@ -142,6 +148,7 @@ export const getStats = () => async (dispatch) => { dispatch(getStatsSuccess(processedStats)); } catch (error) { console.error(error); + dispatch(addErrorToast({ error })); dispatch(getStatsFailure()); } }; @@ -160,8 +167,9 @@ export const getTopStats = () => async (dispatch, getState) => { const stats = await apiClient.getGlobalStatsTop(); dispatch(getTopStatsSuccess(stats)); } catch (error) { - alertify.error(`Failed to load statistics with status code ${error.response.status}`); - dispatch(getTopStatsFailure()); + console.error(error); + dispatch(addErrorToast({ error })); + dispatch(getTopStatsFailure(error)); } } }, 100); @@ -181,8 +189,9 @@ export const getLogs = () => async (dispatch, getState) => { const logs = normalizeLogs(await apiClient.getQueryLog()); dispatch(getLogsSuccess(logs)); } catch (error) { - alertify.error(`Failed to load query log with status code ${error.response.status}`); - dispatch(getLogsFailure()); + console.error(error); + dispatch(addErrorToast({ error })); + dispatch(getLogsFailure(error)); } } }, 100); @@ -205,6 +214,7 @@ export const toggleLogStatus = queryLogEnabled => async (dispatch) => { dispatch(toggleLogStatusSuccess()); } catch (error) { console.error(error); + dispatch(addErrorToast({ error })); dispatch(toggleLogStatusFailure()); } }; @@ -220,6 +230,7 @@ export const setRules = rules => async (dispatch) => { dispatch(setRulesSuccess()); } catch (error) { console.error(error); + dispatch(addErrorToast({ error })); dispatch(setRulesFailure()); } }; @@ -235,6 +246,7 @@ export const getFilteringStatus = () => async (dispatch) => { dispatch(getFilteringStatusSuccess({ status: normalizeFilteringStatus(status) })); } catch (error) { console.error(error); + dispatch(addErrorToast({ error })); dispatch(getFilteringStatusFailure()); } }; @@ -261,6 +273,7 @@ export const toggleFilterStatus = url => async (dispatch, getState) => { dispatch(getFilteringStatus()); } catch (error) { console.error(error); + dispatch(addErrorToast({ error })); dispatch(toggleFilterFailure()); } }; @@ -277,6 +290,7 @@ export const refreshFilters = () => async (dispatch) => { dispatch(getFilteringStatus()); } catch (error) { console.error(error); + dispatch(addErrorToast({ error })); dispatch(refreshFiltersFailure()); } }; @@ -295,6 +309,7 @@ export const getStatsHistory = () => async (dispatch) => { dispatch(getStatsHistorySuccess(normalizedHistory)); } catch (error) { console.error(error); + dispatch(addErrorToast({ error })); dispatch(getStatsHistoryFailure()); } }; @@ -311,6 +326,7 @@ export const addFilter = url => async (dispatch) => { dispatch(getFilteringStatus()); } catch (error) { console.error(error); + dispatch(addErrorToast({ error })); dispatch(addFilterFailure()); } }; @@ -328,6 +344,7 @@ export const removeFilter = url => async (dispatch) => { dispatch(getFilteringStatus()); } catch (error) { console.error(error); + dispatch(addErrorToast({ error })); dispatch(removeFilterFailure()); } }; @@ -347,6 +364,7 @@ export const downloadQueryLog = () => async (dispatch) => { dispatch(downloadQueryLogSuccess()); } catch (error) { console.error(error); + dispatch(addErrorToast({ error })); dispatch(downloadQueryLogFailure()); } return data; @@ -364,6 +382,7 @@ export const setUpstream = url => async (dispatch) => { dispatch(setUpstreamSuccess()); } catch (error) { console.error(error); + dispatch(addErrorToast({ error })); dispatch(setUpstreamFailure()); } }; diff --git a/client/src/api/Api.js b/client/src/api/Api.js index 1ba54271..e09ed797 100644 --- a/client/src/api/Api.js +++ b/client/src/api/Api.js @@ -6,12 +6,16 @@ export default class Api { baseUrl = 'control'; async makeRequest(path, method = 'POST', config) { - const response = await axios({ - url: `${this.baseUrl}/${path}`, - method, - ...config, - }); - return response.data; + try { + const response = await axios({ + url: `${this.baseUrl}/${path}`, + method, + ...config, + }); + return response.data; + } catch (error) { + throw new Error(`${this.baseUrl}/${path} | ${error.response.data} | ${error.response.status}`); + } } // Global methods diff --git a/client/src/components/App/index.js b/client/src/components/App/index.js index fcb31887..1b48620c 100644 --- a/client/src/components/App/index.js +++ b/client/src/components/App/index.js @@ -3,10 +3,8 @@ import { HashRouter, Route } from 'react-router-dom'; import PropTypes from 'prop-types'; import 'react-table/react-table.css'; -import 'alertifyjs/build/css/alertify.min.css'; import '../ui/Tabler.css'; import '../ui/ReactTable.css'; -import '../ui/Alertify.css'; import './index.css'; import Header from '../../containers/Header'; @@ -15,6 +13,7 @@ import Settings from '../../containers/Settings'; import Filters from '../../containers/Filters'; import Logs from '../../containers/Logs'; import Footer from '../ui/Footer'; +import Toasts from '../Toasts'; import Status from '../ui/Status'; @@ -51,6 +50,7 @@ class App extends Component { }