mirror of https://github.com/lidarr/Lidarr
New: Ability to test all Indexers, Lists, Clients
Co-Authored-By: Mark McDowall <markus101@users.noreply.github.com>
This commit is contained in:
parent
6103afcc09
commit
029a0e4e20
|
@ -268,7 +268,7 @@
|
|||
"react/jsx-no-bind": [2, { "allowArrowFunctions": true }],
|
||||
"react/jsx-no-duplicate-props": [2, { "ignoreCase": true }],
|
||||
"react/jsx-max-props-per-line": [2, { "maximum": 2 }],
|
||||
"react/jsx-handler-names": [2, { "eventHandlerPrefix": "on", "eventHandlerPropPrefix": "on" }],
|
||||
"react/jsx-handler-names": [2, { "eventHandlerPrefix": "(on|dispatch)", "eventHandlerPropPrefix": "on" }],
|
||||
"react/jsx-no-undef": 2,
|
||||
"react/jsx-pascal-case": 2,
|
||||
"react/jsx-uses-react": 2,
|
||||
|
|
|
@ -21,9 +21,9 @@ import Settings from 'Settings/Settings';
|
|||
import MediaManagementConnector from 'Settings/MediaManagement/MediaManagementConnector';
|
||||
import Profiles from 'Settings/Profiles/Profiles';
|
||||
import Quality from 'Settings/Quality/Quality';
|
||||
import IndexerSettings from 'Settings/Indexers/IndexerSettings';
|
||||
import ImportListSettings from 'Settings/ImportLists/ImportListSettings';
|
||||
import DownloadClientSettings from 'Settings/DownloadClients/DownloadClientSettings';
|
||||
import IndexerSettingsConnector from 'Settings/Indexers/IndexerSettingsConnector';
|
||||
import ImportListSettingsConnector from 'Settings/ImportLists/ImportListSettingsConnector';
|
||||
import DownloadClientSettingsConnector from 'Settings/DownloadClients/DownloadClientSettingsConnector';
|
||||
import NotificationSettings from 'Settings/Notifications/NotificationSettings';
|
||||
import MetadataSettings from 'Settings/Metadata/MetadataSettings';
|
||||
import TagSettings from 'Settings/Tags/TagSettings';
|
||||
|
@ -169,17 +169,17 @@ function AppRoutes(props) {
|
|||
|
||||
<Route
|
||||
path="/settings/indexers"
|
||||
component={IndexerSettings}
|
||||
component={IndexerSettingsConnector}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/settings/downloadclients"
|
||||
component={DownloadClientSettings}
|
||||
component={DownloadClientSettingsConnector}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/settings/importlists"
|
||||
component={ImportListSettings}
|
||||
component={ImportListSettingsConnector}
|
||||
/>
|
||||
|
||||
<Route
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
.button {
|
||||
composes: link from 'Components/Link/Link.css';
|
||||
|
||||
display: inline-block;
|
||||
margin: 0 2px;
|
||||
width: 22px;
|
||||
border-radius: 4px;
|
||||
|
|
|
@ -29,6 +29,7 @@ import {
|
|||
faBars as fasBars,
|
||||
faBolt as fasBolt,
|
||||
faBookmark as fasBookmark,
|
||||
faBookReader as fasBookReader,
|
||||
faBug as fasBug,
|
||||
faCalendarAlt as fasCalendarAlt,
|
||||
faCaretDown as fasCaretDown,
|
||||
|
@ -92,6 +93,7 @@ import {
|
|||
faTimes as fasTimes,
|
||||
faTimesCircle as fasTimesCircle,
|
||||
faUser as fasUser,
|
||||
faVial as fasVial,
|
||||
faWrench as fasWrench
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
|
@ -188,6 +190,7 @@ export const SUBTRACT = fasMinus;
|
|||
export const SYSTEM = fasLaptop;
|
||||
export const TAGS = fasTags;
|
||||
export const TBA = fasQuestionCircle;
|
||||
export const TEST = fasVial;
|
||||
export const UNGROUP = farObjectUngroup;
|
||||
export const UNKNOWN = fasQuestion;
|
||||
export const UNMONITORED = farBookmark;
|
||||
|
@ -195,3 +198,4 @@ export const UPDATE = fasRetweet;
|
|||
export const UNSAVED_SETTING = farDotCircle;
|
||||
export const VIEW = fasEye;
|
||||
export const WARNING = fasExclamationTriangle;
|
||||
export const WIKI = fasBookReader;
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import PageContent from 'Components/Page/PageContent';
|
||||
import PageContentBodyConnector from 'Components/Page/PageContentBodyConnector';
|
||||
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
||||
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
||||
import DownloadClientsConnector from './DownloadClients/DownloadClientsConnector';
|
||||
import DownloadClientOptionsConnector from './Options/DownloadClientOptionsConnector';
|
||||
|
@ -43,6 +47,11 @@ class DownloadClientSettings extends Component {
|
|||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
isTestingAll,
|
||||
dispatchTestAllDownloadClients
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
isSaving,
|
||||
hasPendingChanges
|
||||
|
@ -53,6 +62,18 @@ class DownloadClientSettings extends Component {
|
|||
<SettingsToolbarConnector
|
||||
isSaving={isSaving}
|
||||
hasPendingChanges={hasPendingChanges}
|
||||
additionalButtons={
|
||||
<Fragment>
|
||||
<PageToolbarSeparator />
|
||||
|
||||
<PageToolbarButton
|
||||
label="Test All Clients"
|
||||
iconName={icons.TEST}
|
||||
isSpinning={isTestingAll}
|
||||
onPress={dispatchTestAllDownloadClients}
|
||||
/>
|
||||
</Fragment>
|
||||
}
|
||||
onSavePress={this.onSavePress}
|
||||
/>
|
||||
|
||||
|
@ -71,4 +92,9 @@ class DownloadClientSettings extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
DownloadClientSettings.propTypes = {
|
||||
isTestingAll: PropTypes.bool.isRequired,
|
||||
dispatchTestAllDownloadClients: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default DownloadClientSettings;
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { testAllDownloadClients } from 'Store/Actions/settingsActions';
|
||||
import DownloadClientSettings from './DownloadClientSettings';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.settings.downloadClients.isTestingAll,
|
||||
(isTestingAll) => {
|
||||
return {
|
||||
isTestingAll
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
dispatchTestAllDownloadClients: testAllDownloadClients
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, mapDispatchToProps)(DownloadClientSettings);
|
|
@ -1,6 +1,10 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import PageContent from 'Components/Page/PageContent';
|
||||
import PageContentBodyConnector from 'Components/Page/PageContentBodyConnector';
|
||||
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
||||
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
||||
import ImportListsConnector from './ImportLists/ImportListsConnector';
|
||||
|
||||
|
@ -38,10 +42,33 @@ class ImportListSettings extends Component {
|
|||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
isTestingAll,
|
||||
dispatchTestAllImportLists
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
isSaving,
|
||||
hasPendingChanges
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
<PageContent title="Import List Settings">
|
||||
<SettingsToolbarConnector
|
||||
hasPendingChanges={this.state.hasPendingChanges}
|
||||
isSaving={isSaving}
|
||||
hasPendingChanges={hasPendingChanges}
|
||||
additionalButtons={
|
||||
<Fragment>
|
||||
<PageToolbarSeparator />
|
||||
|
||||
<PageToolbarButton
|
||||
label="Test All Lists"
|
||||
iconName={icons.TEST}
|
||||
isSpinning={isTestingAll}
|
||||
onPress={dispatchTestAllImportLists}
|
||||
/>
|
||||
</Fragment>
|
||||
}
|
||||
onSavePress={this.onSavePress}
|
||||
/>
|
||||
|
||||
|
@ -53,4 +80,9 @@ class ImportListSettings extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
ImportListSettings.propTypes = {
|
||||
isTestingAll: PropTypes.bool.isRequired,
|
||||
dispatchTestAllImportLists: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default ImportListSettings;
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { testAllImportLists } from 'Store/Actions/settingsActions';
|
||||
import ImportListSettings from './ImportListSettings';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.settings.importLists.isTestingAll,
|
||||
(isTestingAll) => {
|
||||
return {
|
||||
isTestingAll
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
dispatchTestAllImportLists: testAllImportLists
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, mapDispatchToProps)(ImportListSettings);
|
|
@ -1,6 +1,10 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import PageContent from 'Components/Page/PageContent';
|
||||
import PageContentBodyConnector from 'Components/Page/PageContentBodyConnector';
|
||||
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
||||
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
||||
import IndexersConnector from './Indexers/IndexersConnector';
|
||||
import IndexerOptionsConnector from './Options/IndexerOptionsConnector';
|
||||
|
@ -43,6 +47,11 @@ class IndexerSettings extends Component {
|
|||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
isTestingAll,
|
||||
dispatchTestAllIndexers
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
isSaving,
|
||||
hasPendingChanges
|
||||
|
@ -53,6 +62,18 @@ class IndexerSettings extends Component {
|
|||
<SettingsToolbarConnector
|
||||
isSaving={isSaving}
|
||||
hasPendingChanges={hasPendingChanges}
|
||||
additionalButtons={
|
||||
<Fragment>
|
||||
<PageToolbarSeparator />
|
||||
|
||||
<PageToolbarButton
|
||||
label="Test All Indexers"
|
||||
iconName={icons.TEST}
|
||||
isSpinning={isTestingAll}
|
||||
onPress={dispatchTestAllIndexers}
|
||||
/>
|
||||
</Fragment>
|
||||
}
|
||||
onSavePress={this.onSavePress}
|
||||
/>
|
||||
|
||||
|
@ -71,4 +92,9 @@ class IndexerSettings extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
IndexerSettings.propTypes = {
|
||||
isTestingAll: PropTypes.bool.isRequired,
|
||||
dispatchTestAllIndexers: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default IndexerSettings;
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { testAllIndexers } from 'Store/Actions/settingsActions';
|
||||
import IndexerSettings from './IndexerSettings';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.settings.indexers.isTestingAll,
|
||||
(isTestingAll) => {
|
||||
return {
|
||||
isTestingAll
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
dispatchTestAllIndexers: testAllIndexers
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, mapDispatchToProps)(IndexerSettings);
|
|
@ -42,6 +42,7 @@ class SettingsToolbar extends Component {
|
|||
showSave,
|
||||
isSaving,
|
||||
hasPendingChanges,
|
||||
additionalButtons,
|
||||
hasPendingLocation,
|
||||
onSavePress,
|
||||
onConfirmNavigation,
|
||||
|
@ -67,7 +68,12 @@ class SettingsToolbar extends Component {
|
|||
onPress={onSavePress}
|
||||
/>
|
||||
}
|
||||
|
||||
{
|
||||
additionalButtons
|
||||
}
|
||||
</PageToolbarSection>
|
||||
|
||||
<PendingChangesModal
|
||||
isOpen={hasPendingLocation}
|
||||
onConfirm={onConfirmNavigation}
|
||||
|
@ -84,6 +90,7 @@ SettingsToolbar.propTypes = {
|
|||
isSaving: PropTypes.bool,
|
||||
hasPendingLocation: PropTypes.bool.isRequired,
|
||||
hasPendingChanges: PropTypes.bool,
|
||||
additionalButtons: PropTypes.node,
|
||||
onSavePress: PropTypes.func,
|
||||
onAdvancedSettingsPress: PropTypes.func.isRequired,
|
||||
onConfirmNavigation: PropTypes.func.isRequired,
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import createAjaxRequest from 'Utilities/createAjaxRequest';
|
||||
import { set } from '../baseActions';
|
||||
|
||||
function createTestAllProvidersHandler(section, url) {
|
||||
return function(getState, payload, dispatch) {
|
||||
dispatch(set({ section, isTestingAll: true }));
|
||||
|
||||
const ajaxOptions = {
|
||||
url: `${url}/testall`,
|
||||
method: 'POST',
|
||||
contentType: 'application/json',
|
||||
dataType: 'json'
|
||||
};
|
||||
|
||||
const { request } = createAjaxRequest(ajaxOptions);
|
||||
|
||||
request.done((data) => {
|
||||
dispatch(set({
|
||||
section,
|
||||
isTestingAll: false,
|
||||
saveError: null
|
||||
}));
|
||||
});
|
||||
|
||||
request.fail((xhr) => {
|
||||
dispatch(set({
|
||||
section,
|
||||
isTestingAll: false
|
||||
}));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export default createTestAllProvidersHandler;
|
|
@ -7,6 +7,7 @@ import createFetchHandler from 'Store/Actions/Creators/createFetchHandler';
|
|||
import createFetchSchemaHandler from 'Store/Actions/Creators/createFetchSchemaHandler';
|
||||
import createSaveProviderHandler, { createCancelSaveProviderHandler } from 'Store/Actions/Creators/createSaveProviderHandler';
|
||||
import createTestProviderHandler, { createCancelTestProviderHandler } from 'Store/Actions/Creators/createTestProviderHandler';
|
||||
import createTestAllProvidersHandler from 'Store/Actions/Creators/createTestAllProvidersHandler';
|
||||
import createRemoveItemHandler from 'Store/Actions/Creators/createRemoveItemHandler';
|
||||
|
||||
//
|
||||
|
@ -27,6 +28,7 @@ export const CANCEL_SAVE_DOWNLOAD_CLIENT = 'settings/downloadClients/cancelSaveD
|
|||
export const DELETE_DOWNLOAD_CLIENT = 'settings/downloadClients/deleteDownloadClient';
|
||||
export const TEST_DOWNLOAD_CLIENT = 'settings/downloadClients/testDownloadClient';
|
||||
export const CANCEL_TEST_DOWNLOAD_CLIENT = 'settings/downloadClients/cancelTestDownloadClient';
|
||||
export const TEST_ALL_DOWNLOAD_CLIENTS = 'settings/downloadClients/testAllDownloadClients';
|
||||
|
||||
//
|
||||
// Action Creators
|
||||
|
@ -40,6 +42,7 @@ export const cancelSaveDownloadClient = createThunk(CANCEL_SAVE_DOWNLOAD_CLIENT)
|
|||
export const deleteDownloadClient = createThunk(DELETE_DOWNLOAD_CLIENT);
|
||||
export const testDownloadClient = createThunk(TEST_DOWNLOAD_CLIENT);
|
||||
export const cancelTestDownloadClient = createThunk(CANCEL_TEST_DOWNLOAD_CLIENT);
|
||||
export const testAllDownloadClients = createThunk(TEST_ALL_DOWNLOAD_CLIENTS);
|
||||
|
||||
export const setDownloadClientValue = createAction(SET_DOWNLOAD_CLIENT_VALUE, (payload) => {
|
||||
return {
|
||||
|
@ -75,6 +78,7 @@ export default {
|
|||
isSaving: false,
|
||||
saveError: null,
|
||||
isTesting: false,
|
||||
isTestingAll: false,
|
||||
items: [],
|
||||
pendingChanges: {}
|
||||
},
|
||||
|
@ -90,7 +94,8 @@ export default {
|
|||
[CANCEL_SAVE_DOWNLOAD_CLIENT]: createCancelSaveProviderHandler(section),
|
||||
[DELETE_DOWNLOAD_CLIENT]: createRemoveItemHandler(section, '/downloadclient'),
|
||||
[TEST_DOWNLOAD_CLIENT]: createTestProviderHandler(section, '/downloadclient'),
|
||||
[CANCEL_TEST_DOWNLOAD_CLIENT]: createCancelTestProviderHandler(section)
|
||||
[CANCEL_TEST_DOWNLOAD_CLIENT]: createCancelTestProviderHandler(section),
|
||||
[TEST_ALL_DOWNLOAD_CLIENTS]: createTestAllProvidersHandler(section, '/downloadclient')
|
||||
},
|
||||
|
||||
//
|
||||
|
|
|
@ -7,6 +7,7 @@ import createFetchHandler from 'Store/Actions/Creators/createFetchHandler';
|
|||
import createFetchSchemaHandler from 'Store/Actions/Creators/createFetchSchemaHandler';
|
||||
import createSaveProviderHandler, { createCancelSaveProviderHandler } from 'Store/Actions/Creators/createSaveProviderHandler';
|
||||
import createTestProviderHandler, { createCancelTestProviderHandler } from 'Store/Actions/Creators/createTestProviderHandler';
|
||||
import createTestAllProvidersHandler from 'Store/Actions/Creators/createTestAllProvidersHandler';
|
||||
import createRemoveItemHandler from 'Store/Actions/Creators/createRemoveItemHandler';
|
||||
|
||||
//
|
||||
|
@ -27,6 +28,7 @@ export const CANCEL_SAVE_IMPORT_LIST = 'settings/importlists/cancelSaveImportLis
|
|||
export const DELETE_IMPORT_LIST = 'settings/importlists/deleteImportList';
|
||||
export const TEST_IMPORT_LIST = 'settings/importlists/testImportList';
|
||||
export const CANCEL_TEST_IMPORT_LIST = 'settings/importlists/cancelTestImportList';
|
||||
export const TEST_ALL_IMPORT_LISTS = 'settings/importlists/testAllImportLists';
|
||||
|
||||
//
|
||||
// Action Creators
|
||||
|
@ -40,6 +42,7 @@ export const cancelSaveImportList = createThunk(CANCEL_SAVE_IMPORT_LIST);
|
|||
export const deleteImportList = createThunk(DELETE_IMPORT_LIST);
|
||||
export const testImportList = createThunk(TEST_IMPORT_LIST);
|
||||
export const cancelTestImportList = createThunk(CANCEL_TEST_IMPORT_LIST);
|
||||
export const testAllImportLists = createThunk(TEST_ALL_IMPORT_LISTS);
|
||||
|
||||
export const setImportListValue = createAction(SET_IMPORT_LIST_VALUE, (payload) => {
|
||||
return {
|
||||
|
@ -75,6 +78,7 @@ export default {
|
|||
isSaving: false,
|
||||
saveError: null,
|
||||
isTesting: false,
|
||||
isTestingAll: false,
|
||||
items: [],
|
||||
pendingChanges: {}
|
||||
},
|
||||
|
@ -90,7 +94,8 @@ export default {
|
|||
[CANCEL_SAVE_IMPORT_LIST]: createCancelSaveProviderHandler(section),
|
||||
[DELETE_IMPORT_LIST]: createRemoveItemHandler(section, '/importlist'),
|
||||
[TEST_IMPORT_LIST]: createTestProviderHandler(section, '/importlist'),
|
||||
[CANCEL_TEST_IMPORT_LIST]: createCancelTestProviderHandler(section)
|
||||
[CANCEL_TEST_IMPORT_LIST]: createCancelTestProviderHandler(section),
|
||||
[TEST_ALL_IMPORT_LISTS]: createTestAllProvidersHandler(section, '/importlist')
|
||||
},
|
||||
|
||||
//
|
||||
|
|
|
@ -7,6 +7,7 @@ import createFetchHandler from 'Store/Actions/Creators/createFetchHandler';
|
|||
import createFetchSchemaHandler from 'Store/Actions/Creators/createFetchSchemaHandler';
|
||||
import createSaveProviderHandler, { createCancelSaveProviderHandler } from 'Store/Actions/Creators/createSaveProviderHandler';
|
||||
import createTestProviderHandler, { createCancelTestProviderHandler } from 'Store/Actions/Creators/createTestProviderHandler';
|
||||
import createTestAllProvidersHandler from 'Store/Actions/Creators/createTestAllProvidersHandler';
|
||||
import createRemoveItemHandler from 'Store/Actions/Creators/createRemoveItemHandler';
|
||||
|
||||
//
|
||||
|
@ -27,6 +28,7 @@ export const CANCEL_SAVE_INDEXER = 'settings/indexers/cancelSaveIndexer';
|
|||
export const DELETE_INDEXER = 'settings/indexers/deleteIndexer';
|
||||
export const TEST_INDEXER = 'settings/indexers/testIndexer';
|
||||
export const CANCEL_TEST_INDEXER = 'settings/indexers/cancelTestIndexer';
|
||||
export const TEST_ALL_INDEXERS = 'settings/indexers/testAllIndexers';
|
||||
|
||||
//
|
||||
// Action Creators
|
||||
|
@ -40,6 +42,7 @@ export const cancelSaveIndexer = createThunk(CANCEL_SAVE_INDEXER);
|
|||
export const deleteIndexer = createThunk(DELETE_INDEXER);
|
||||
export const testIndexer = createThunk(TEST_INDEXER);
|
||||
export const cancelTestIndexer = createThunk(CANCEL_TEST_INDEXER);
|
||||
export const testAllIndexers = createThunk(TEST_ALL_INDEXERS);
|
||||
|
||||
export const setIndexerValue = createAction(SET_INDEXER_VALUE, (payload) => {
|
||||
return {
|
||||
|
@ -75,6 +78,7 @@ export default {
|
|||
isSaving: false,
|
||||
saveError: null,
|
||||
isTesting: false,
|
||||
isTestingAll: false,
|
||||
items: [],
|
||||
pendingChanges: {}
|
||||
},
|
||||
|
@ -90,7 +94,8 @@ export default {
|
|||
[CANCEL_SAVE_INDEXER]: createCancelSaveProviderHandler(section),
|
||||
[DELETE_INDEXER]: createRemoveItemHandler(section, '/indexer'),
|
||||
[TEST_INDEXER]: createTestProviderHandler(section, '/indexer'),
|
||||
[CANCEL_TEST_INDEXER]: createCancelTestProviderHandler(section)
|
||||
[CANCEL_TEST_INDEXER]: createCancelTestProviderHandler(section),
|
||||
[TEST_ALL_INDEXERS]: createTestAllProvidersHandler(section, '/indexer')
|
||||
},
|
||||
|
||||
//
|
||||
|
|
|
@ -3,7 +3,8 @@ import React, { Component } from 'react';
|
|||
import titleCase from 'Utilities/String/titleCase';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import Icon from 'Components/Icon';
|
||||
import Link from 'Components/Link/Link';
|
||||
import IconButton from 'Components/Link/IconButton';
|
||||
import SpinnerIconButton from 'Components/Link/SpinnerIconButton';
|
||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
import FieldSet from 'Components/FieldSet';
|
||||
import Table from 'Components/Table/Table';
|
||||
|
@ -18,36 +19,68 @@ function getInternalLink(source) {
|
|||
case 'IndexerSearchCheck':
|
||||
case 'IndexerStatusCheck':
|
||||
return (
|
||||
<Link to="/settings/indexers">
|
||||
Settings
|
||||
</Link>
|
||||
<IconButton
|
||||
name={icons.SETTINGS}
|
||||
title="Settings"
|
||||
to="/settings/indexers"
|
||||
/>
|
||||
);
|
||||
case 'DownloadClientCheck':
|
||||
case 'ImportMechanismCheck':
|
||||
return (
|
||||
<Link to="/settings/downloadclients">
|
||||
Settings
|
||||
</Link>
|
||||
<IconButton
|
||||
name={icons.SETTINGS}
|
||||
title="Settings"
|
||||
to="/settings/downloadclients"
|
||||
/>
|
||||
);
|
||||
case 'RootFolderCheck':
|
||||
return (
|
||||
<div>
|
||||
<Link to="/artisteditor">
|
||||
Artist Editor
|
||||
</Link>
|
||||
</div>
|
||||
<IconButton
|
||||
name={icons.ARTIST}
|
||||
title="Artist Editor"
|
||||
to="/artisteditor"
|
||||
/>
|
||||
);
|
||||
case 'UpdateCheck':
|
||||
return (
|
||||
<Link to="/system/updates">
|
||||
Updates
|
||||
</Link>
|
||||
<IconButton
|
||||
name={icons.UPDATE}
|
||||
title="Updates"
|
||||
to="/system/updates"
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function getTestLink(source, props) {
|
||||
switch (source) {
|
||||
case 'IndexerStatusCheck':
|
||||
return (
|
||||
<SpinnerIconButton
|
||||
name={icons.TEST}
|
||||
title="Test All"
|
||||
isSpinning={props.isTestingAllIndexers}
|
||||
onPress={props.dispatchTestAllIndexers}
|
||||
/>
|
||||
);
|
||||
case 'DownloadClientCheck':
|
||||
return (
|
||||
<SpinnerIconButton
|
||||
name={icons.TEST}
|
||||
title="Test All"
|
||||
isSpinning={props.isTestingAllDownloadClients}
|
||||
onPress={props.dispatchTestAllDownloadClients}
|
||||
/>
|
||||
);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const columns = [
|
||||
{
|
||||
className: styles.status,
|
||||
|
@ -60,12 +93,8 @@ const columns = [
|
|||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'wikiLink',
|
||||
label: 'Wiki',
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'internalLink',
|
||||
name: 'actions',
|
||||
label: 'Actions',
|
||||
isVisible: true
|
||||
}
|
||||
];
|
||||
|
@ -121,6 +150,7 @@ class Health extends Component {
|
|||
{
|
||||
items.map((item) => {
|
||||
const internalLink = getInternalLink(item.source);
|
||||
const testLink = getTestLink(item.source, this.props);
|
||||
|
||||
return (
|
||||
<TableRow key={`health${item.message}`}>
|
||||
|
@ -135,18 +165,20 @@ class Health extends Component {
|
|||
<TableRowCell>{item.message}</TableRowCell>
|
||||
|
||||
<TableRowCell>
|
||||
<Link
|
||||
<IconButton
|
||||
name={icons.WIKI}
|
||||
to={item.wikiUrl}
|
||||
title="Read the Wiki for more information"
|
||||
>
|
||||
Wiki
|
||||
</Link>
|
||||
</TableRowCell>
|
||||
/>
|
||||
|
||||
<TableRowCell>
|
||||
{
|
||||
internalLink
|
||||
}
|
||||
|
||||
{
|
||||
!!testLink &&
|
||||
testLink
|
||||
}
|
||||
</TableRowCell>
|
||||
</TableRow>
|
||||
);
|
||||
|
@ -164,7 +196,11 @@ class Health extends Component {
|
|||
Health.propTypes = {
|
||||
isFetching: PropTypes.bool.isRequired,
|
||||
isPopulated: PropTypes.bool.isRequired,
|
||||
items: PropTypes.array.isRequired
|
||||
items: PropTypes.array.isRequired,
|
||||
isTestingAllDownloadClients: PropTypes.bool.isRequired,
|
||||
isTestingAllIndexers: PropTypes.bool.isRequired,
|
||||
dispatchTestAllDownloadClients: PropTypes.func.isRequired,
|
||||
dispatchTestAllIndexers: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default Health;
|
||||
|
|
|
@ -3,12 +3,15 @@ import React, { Component } from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { fetchHealth } from 'Store/Actions/systemActions';
|
||||
import { testAllDownloadClients, testAllIndexers } from 'Store/Actions/settingsActions';
|
||||
import Health from './Health';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.system.health,
|
||||
(health) => {
|
||||
(state) => state.settings.downloadClients.isTestingAll,
|
||||
(state) => state.settings.indexers.isTestingAll,
|
||||
(health, isTestingAllDownloadClients, isTestingAllIndexers) => {
|
||||
const {
|
||||
isFetching,
|
||||
isPopulated,
|
||||
|
@ -18,14 +21,18 @@ function createMapStateToProps() {
|
|||
return {
|
||||
isFetching,
|
||||
isPopulated,
|
||||
items
|
||||
items,
|
||||
isTestingAllDownloadClients,
|
||||
isTestingAllIndexers
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
fetchHealth
|
||||
dispatchFetchHealth: fetchHealth,
|
||||
dispatchTestAllDownloadClients: testAllDownloadClients,
|
||||
dispatchTestAllIndexers: testAllIndexers
|
||||
};
|
||||
|
||||
class HealthConnector extends Component {
|
||||
|
@ -34,23 +41,28 @@ class HealthConnector extends Component {
|
|||
// Lifecycle
|
||||
|
||||
componentDidMount() {
|
||||
this.props.fetchHealth();
|
||||
this.props.dispatchFetchHealth();
|
||||
}
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
dispatchFetchHealth,
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Health
|
||||
{...this.props}
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
HealthConnector.propTypes = {
|
||||
fetchHealth: PropTypes.func.isRequired
|
||||
dispatchFetchHealth: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, mapDispatchToProps)(HealthConnector);
|
||||
|
|
Loading…
Reference in New Issue