Show loading errors as Alerts (#5736)

New: Improved page loading errors
This commit is contained in:
Bogdan 2023-06-16 20:49:08 +03:00 committed by GitHub
parent 059a156f4a
commit 1f785dd30d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 67 additions and 38 deletions

View File

@ -1,5 +1,6 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import Alert from 'Components/Alert';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import ConfirmModal from 'Components/Modal/ConfirmModal'; import ConfirmModal from 'Components/Modal/ConfirmModal';
import PageContent from 'Components/Page/PageContent'; import PageContent from 'Components/Page/PageContent';
@ -155,14 +156,14 @@ class Blocklist extends Component {
{ {
!isFetching && !!error && !isFetching && !!error &&
<div>Unable to load blocklist</div> <Alert kind={kinds.DANGER}>Unable to load blocklist</Alert>
} }
{ {
isPopulated && !error && !items.length && isPopulated && !error && !items.length &&
<div> <Alert kind={kinds.INFO}>
No history blocklist No history blocklist
</div> </Alert>
} }
{ {

View File

@ -1,5 +1,6 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import Alert from 'Components/Alert';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import FilterMenu from 'Components/Menu/FilterMenu'; import FilterMenu from 'Components/Menu/FilterMenu';
import PageContent from 'Components/Page/PageContent'; import PageContent from 'Components/Page/PageContent';
@ -11,7 +12,7 @@ import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody'; import TableBody from 'Components/Table/TableBody';
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper'; import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
import TablePager from 'Components/Table/TablePager'; import TablePager from 'Components/Table/TablePager';
import { align, icons } from 'Helpers/Props'; import { align, icons, kinds } from 'Helpers/Props';
import hasDifferentItems from 'Utilities/Object/hasDifferentItems'; import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
import HistoryRowConnector from './HistoryRowConnector'; import HistoryRowConnector from './HistoryRowConnector';
@ -104,7 +105,7 @@ class History extends Component {
{ {
!isFetchingAny && hasError && !isFetchingAny && hasError &&
<div>Unable to load history</div> <Alert kind={kinds.DANGER}>Unable to load history</Alert>
} }
{ {
@ -112,9 +113,9 @@ class History extends Component {
// wait for the episodes to populate because they are never coming. // wait for the episodes to populate because they are never coming.
isPopulated && !hasError && !items.length && isPopulated && !hasError && !items.length &&
<div> <Alert kind={kinds.INFO}>
No history found No history found
</div> </Alert>
} }
{ {

View File

@ -1,6 +1,7 @@
import _ from 'lodash'; import _ from 'lodash';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import Alert from 'Components/Alert';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import PageContent from 'Components/Page/PageContent'; import PageContent from 'Components/Page/PageContent';
import PageContentBody from 'Components/Page/PageContentBody'; import PageContentBody from 'Components/Page/PageContentBody';
@ -12,7 +13,7 @@ import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody'; import TableBody from 'Components/Table/TableBody';
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper'; import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
import TablePager from 'Components/Table/TablePager'; import TablePager from 'Components/Table/TablePager';
import { align, icons } from 'Helpers/Props'; import { align, icons, kinds } from 'Helpers/Props';
import getRemovedItems from 'Utilities/Object/getRemovedItems'; import getRemovedItems from 'Utilities/Object/getRemovedItems';
import hasDifferentItems from 'Utilities/Object/hasDifferentItems'; import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
import getSelectedIds from 'Utilities/Table/getSelectedIds'; import getSelectedIds from 'Utilities/Table/getSelectedIds';
@ -228,17 +229,17 @@ class Queue extends Component {
{ {
!isRefreshing && hasError ? !isRefreshing && hasError ?
<div> <Alert kind={kinds.DANGER}>
Failed to load Queue Failed to load Queue
</div> : </Alert> :
null null
} }
{ {
isAllPopulated && !hasError && !items.length ? isAllPopulated && !hasError && !items.length ?
<div> <Alert kind={kinds.INFO}>
Queue is empty Queue is empty
</div> : </Alert> :
null null
} }

View File

@ -1,9 +1,11 @@
import { reduce } from 'lodash'; import { reduce } from 'lodash';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import Alert from 'Components/Alert';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import PageContent from 'Components/Page/PageContent'; import PageContent from 'Components/Page/PageContent';
import PageContentBody from 'Components/Page/PageContentBody'; import PageContentBody from 'Components/Page/PageContentBody';
import { kinds } from 'Helpers/Props';
import selectAll from 'Utilities/Table/selectAll'; import selectAll from 'Utilities/Table/selectAll';
import toggleSelected from 'Utilities/Table/toggleSelected'; import toggleSelected from 'Utilities/Table/toggleSelected';
import ImportSeriesFooterConnector from './ImportSeriesFooterConnector'; import ImportSeriesFooterConnector from './ImportSeriesFooterConnector';
@ -103,7 +105,9 @@ class ImportSeries extends Component {
{ {
!rootFoldersFetching && !!rootFoldersError ? !rootFoldersFetching && !!rootFoldersError ?
<div>Unable to load root folders</div> : <Alert kind={kinds.DANGER}>
Unable to load root folders
</Alert> :
null null
} }
@ -112,9 +116,9 @@ class ImportSeries extends Component {
!rootFoldersFetching && !rootFoldersFetching &&
rootFoldersPopulated && rootFoldersPopulated &&
!unmappedFolders.length ? !unmappedFolders.length ?
<div> <Alert kind={kinds.INFO}>
All series in {path} have been imported All series in {path} have been imported
</div> : </Alert> :
null null
} }

View File

@ -67,7 +67,7 @@ class ImportSeriesSelectFolder extends Component {
{ {
!isFetching && error ? !isFetching && error ?
<div>Unable to load root folders</div> : <Alert kind={kinds.DANGER}>Unable to load root folders</Alert> :
null null
} }

View File

@ -1,6 +1,8 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import Alert from 'Components/Alert';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import { kinds } from 'Helpers/Props';
import AgendaConnector from './Agenda/AgendaConnector'; import AgendaConnector from './Agenda/AgendaConnector';
import * as calendarViews from './calendarViews'; import * as calendarViews from './calendarViews';
import CalendarDaysConnector from './Day/CalendarDaysConnector'; import CalendarDaysConnector from './Day/CalendarDaysConnector';
@ -30,7 +32,7 @@ class Calendar extends Component {
{ {
!isFetching && !!error && !isFetching && !!error &&
<div>Unable to load the calendar</div> <Alert kind={kinds.DANGER}>Unable to load the calendar</Alert>
} }
{ {

View File

@ -1,6 +1,8 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import Alert from 'Components/Alert';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import { kinds } from 'Helpers/Props';
function PageSectionContent(props) { function PageSectionContent(props) {
const { const {
@ -17,7 +19,7 @@ function PageSectionContent(props) {
); );
} else if (!isFetching && !!error) { } else if (!isFetching && !!error) {
return ( return (
<div>{errorMessage}</div> <Alert kind={kinds.DANGER}>{errorMessage}</Alert>
); );
} else if (isPopulated && !error) { } else if (isPopulated && !error) {
return ( return (

View File

@ -1,10 +1,11 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import Alert from 'Components/Alert';
import Icon from 'Components/Icon'; import Icon from 'Components/Icon';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import Table from 'Components/Table/Table'; import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody'; import TableBody from 'Components/Table/TableBody';
import { icons } from 'Helpers/Props'; import { icons, kinds } from 'Helpers/Props';
import EpisodeHistoryRow from './EpisodeHistoryRow'; import EpisodeHistoryRow from './EpisodeHistoryRow';
const columns = [ const columns = [
@ -77,13 +78,13 @@ class EpisodeHistory extends Component {
if (!isFetching && !!error) { if (!isFetching && !!error) {
return ( return (
<div>Unable to load episode history.</div> <Alert kind={kinds.DANGER}>Unable to load episode history.</Alert>
); );
} }
if (isPopulated && !hasItems && !error) { if (isPopulated && !hasItems && !error) {
return ( return (
<div>No episode history.</div> <Alert kind={kinds.INFO}>No episode history.</Alert>
); );
} }

View File

@ -2,6 +2,7 @@ import React, { useCallback, useState } from 'react';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { LanguageSettingsAppState } from 'App/State/SettingsAppState'; import { LanguageSettingsAppState } from 'App/State/SettingsAppState';
import Alert from 'Components/Alert';
import Form from 'Components/Form/Form'; import Form from 'Components/Form/Form';
import FormGroup from 'Components/Form/FormGroup'; import FormGroup from 'Components/Form/FormGroup';
import FormInputGroup from 'Components/Form/FormInputGroup'; import FormInputGroup from 'Components/Form/FormInputGroup';
@ -82,7 +83,9 @@ function SelectLanguageModalContent(props: SelectLanguageModalContentProps) {
<ModalBody> <ModalBody>
{isFetching ? <LoadingIndicator /> : null} {isFetching ? <LoadingIndicator /> : null}
{!isFetching && error ? <div>Unable To Load Languages</div> : null} {!isFetching && error ? (
<Alert kind={kinds.DANGER}>Unable to load Languages</Alert>
) : null}
{isPopulated && !error ? ( {isPopulated && !error ? (
<Form> <Form>

View File

@ -3,6 +3,7 @@ import { useDispatch, useSelector } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { Error } from 'App/State/AppSectionState'; import { Error } from 'App/State/AppSectionState';
import AppState from 'App/State/AppState'; import AppState from 'App/State/AppState';
import Alert from 'Components/Alert';
import Form from 'Components/Form/Form'; import Form from 'Components/Form/Form';
import FormGroup from 'Components/Form/FormGroup'; import FormGroup from 'Components/Form/FormGroup';
import FormInputGroup from 'Components/Form/FormInputGroup'; import FormInputGroup from 'Components/Form/FormInputGroup';
@ -126,7 +127,9 @@ function SelectQualityModalContent(props: SelectQualityModalContentProps) {
<ModalBody> <ModalBody>
{isFetching && <LoadingIndicator />} {isFetching && <LoadingIndicator />}
{!isFetching && error ? <div>Unable to load qualities</div> : null} {!isFetching && error ? (
<Alert kind={kinds.DANGER}>Unable to load qualities</Alert>
) : null}
{isPopulated && !error ? ( {isPopulated && !error ? (
<Form> <Form>

View File

@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import Alert from 'Components/Alert';
import Form from 'Components/Form/Form'; import Form from 'Components/Form/Form';
import Button from 'Components/Link/Button'; import Button from 'Components/Link/Button';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
@ -8,6 +9,7 @@ import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter'; import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader'; import ModalHeader from 'Components/Modal/ModalHeader';
import DownloadProtocol from 'DownloadClient/DownloadProtocol'; import DownloadProtocol from 'DownloadClient/DownloadProtocol';
import { kinds } from 'Helpers/Props';
import createEnabledDownloadClientsSelector from 'Store/Selectors/createEnabledDownloadClientsSelector'; import createEnabledDownloadClientsSelector from 'Store/Selectors/createEnabledDownloadClientsSelector';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
import SelectDownloadClientRow from './SelectDownloadClientRow'; import SelectDownloadClientRow from './SelectDownloadClientRow';
@ -36,7 +38,7 @@ function SelectDownloadClientModalContent(
{isFetching ? <LoadingIndicator /> : null} {isFetching ? <LoadingIndicator /> : null}
{!isFetching && error ? ( {!isFetching && error ? (
<div>Unable to load download clients</div> <Alert kind={kinds.DANGER}>Unable to load download clients</Alert>
) : null} ) : null}
{isPopulated && !error ? ( {isPopulated && !error ? (

View File

@ -43,7 +43,7 @@ function RootFolders(props) {
if (!isFetching && !!error) { if (!isFetching && !!error) {
return ( return (
<div>Unable to load root folders</div> <Alert kind={kinds.DANGER}>Unable to load root folders</Alert>
); );
} }

View File

@ -97,7 +97,7 @@ class SeriesHistoryModalContent extends Component {
{ {
!isFetching && !!error && !isFetching && !!error &&
<div>Unable to load history.</div> <Alert kind={kinds.DANGER}>Unable to load history.</Alert>
} }
{ {

View File

@ -10,6 +10,7 @@ import { SelectProvider } from 'App/SelectContext';
import ClientSideCollectionAppState from 'App/State/ClientSideCollectionAppState'; import ClientSideCollectionAppState from 'App/State/ClientSideCollectionAppState';
import SeriesAppState, { SeriesIndexAppState } from 'App/State/SeriesAppState'; import SeriesAppState, { SeriesIndexAppState } from 'App/State/SeriesAppState';
import { RSS_SYNC } from 'Commands/commandNames'; import { RSS_SYNC } from 'Commands/commandNames';
import Alert from 'Components/Alert';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import PageContent from 'Components/Page/PageContent'; import PageContent from 'Components/Page/PageContent';
import PageContentBody from 'Components/Page/PageContentBody'; import PageContentBody from 'Components/Page/PageContentBody';
@ -20,7 +21,7 @@ import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection';
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator'; import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper'; import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
import withScrollPosition from 'Components/withScrollPosition'; import withScrollPosition from 'Components/withScrollPosition';
import { align, icons } from 'Helpers/Props'; import { align, icons, kinds } from 'Helpers/Props';
import SortDirection from 'Helpers/Props/SortDirection'; import SortDirection from 'Helpers/Props/SortDirection';
import NoSeries from 'Series/NoSeries'; import NoSeries from 'Series/NoSeries';
import { executeCommand } from 'Store/Actions/commandActions'; import { executeCommand } from 'Store/Actions/commandActions';
@ -304,7 +305,9 @@ const SeriesIndex = withScrollPosition((props: SeriesIndexProps) => {
> >
{isFetching && !isPopulated ? <LoadingIndicator /> : null} {isFetching && !isPopulated ? <LoadingIndicator /> : null}
{!isFetching && !!error ? <div>Unable to load series</div> : null} {!isFetching && !!error ? (
<Alert kind={kinds.DANGER}>Unable to load series</Alert>
) : null}
{isLoaded ? ( {isLoaded ? (
<div className={styles.contentBodyContainer}> <div className={styles.contentBodyContainer}>

View File

@ -28,7 +28,7 @@ function DownloadClientOptions(props) {
{ {
!isFetching && error && !isFetching && error &&
<div>Unable to load download client options</div> <Alert kind={kinds.DANGER}>Unable to load download client options</Alert>
} }
{ {

View File

@ -123,7 +123,7 @@ class GeneralSettings extends Component {
{ {
!isFetching && error && !isFetching && error &&
<div>Unable to load General settings</div> <Alert kind={kinds.DANGER}>Unable to load General settings</Alert>
} }
{ {

View File

@ -27,7 +27,7 @@ function IndexerOptions(props) {
{ {
!isFetching && error && !isFetching && error &&
<div>Unable to load indexer options</div> <Alert kind={kinds.DANGER}>Unable to load indexer options</Alert>
} }
{ {

View File

@ -77,7 +77,7 @@ class MediaManagement extends Component {
{ {
!isFetching && error ? !isFetching && error ?
<FieldSet legend="Naming Settings"> <FieldSet legend="Naming Settings">
<div>Unable to load Media Management settings</div> <Alert kind={kinds.DANGER}>Unable to load Media Management settings</Alert>
</FieldSet> : null </FieldSet> : null
} }

View File

@ -211,7 +211,7 @@ class Naming extends Component {
{ {
!isFetching && error && !isFetching && error &&
<div>Unable to load Naming settings</div> <Alert kind={kinds.DANGER}>Unable to load Naming settings</Alert>
} }
{ {

View File

@ -1,5 +1,6 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import Alert from 'Components/Alert';
import FieldSet from 'Components/FieldSet'; import FieldSet from 'Components/FieldSet';
import Form from 'Components/Form/Form'; import Form from 'Components/Form/Form';
import FormGroup from 'Components/Form/FormGroup'; import FormGroup from 'Components/Form/FormGroup';
@ -8,7 +9,7 @@ import FormLabel from 'Components/Form/FormLabel';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import PageContent from 'Components/Page/PageContent'; import PageContent from 'Components/Page/PageContent';
import PageContentBody from 'Components/Page/PageContentBody'; import PageContentBody from 'Components/Page/PageContentBody';
import { inputTypes } from 'Helpers/Props'; import { inputTypes, kinds } from 'Helpers/Props';
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector'; import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
import themes from 'Styles/Themes'; import themes from 'Styles/Themes';
import titleCase from 'Utilities/String/titleCase'; import titleCase from 'Utilities/String/titleCase';
@ -81,7 +82,7 @@ class UISettings extends Component {
{ {
!isFetching && error ? !isFetching && error ?
<div>Unable to load UI settings</div> : <Alert kind={kinds.DANGER}>Unable to load UI settings</Alert> :
null null
} }

View File

@ -1,5 +1,6 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import Alert from 'Components/Alert';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import PageContent from 'Components/Page/PageContent'; import PageContent from 'Components/Page/PageContent';
import PageContentBody from 'Components/Page/PageContentBody'; import PageContentBody from 'Components/Page/PageContentBody';
@ -8,7 +9,7 @@ import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection'; import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection';
import Table from 'Components/Table/Table'; import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody'; import TableBody from 'Components/Table/TableBody';
import { icons } from 'Helpers/Props'; import { icons, kinds } from 'Helpers/Props';
import BackupRow from './BackupRow'; import BackupRow from './BackupRow';
import RestoreBackupModalConnector from './RestoreBackupModalConnector'; import RestoreBackupModalConnector from './RestoreBackupModalConnector';
@ -106,12 +107,16 @@ class Backups extends Component {
{ {
!isFetching && !!error && !isFetching && !!error &&
<div>Unable to load backups</div> <Alert kind={kinds.DANGER}>
Unable to load backups
</Alert>
} }
{ {
noBackups && noBackups &&
<div>No backups are available</div> <Alert kind={kinds.INFO}>
No backups are available
</Alert>
} }
{ {