diff --git a/frontend/src/App/State/SystemAppState.ts b/frontend/src/App/State/SystemAppState.ts index a8101134c..ac640e08a 100644 --- a/frontend/src/App/State/SystemAppState.ts +++ b/frontend/src/App/State/SystemAppState.ts @@ -1,19 +1,16 @@ import DiskSpace from 'typings/DiskSpace'; -import Health from 'typings/Health'; import LogFile from 'typings/LogFile'; import Task from 'typings/Task'; import AppSectionState from './AppSectionState'; import BackupAppState from './BackupAppState'; export type DiskSpaceAppState = AppSectionState; -export type HealthAppState = AppSectionState; export type TaskAppState = AppSectionState; export type LogFilesAppState = AppSectionState; interface SystemAppState { backups: BackupAppState; diskSpace: DiskSpaceAppState; - health: HealthAppState; logFiles: LogFilesAppState; tasks: TaskAppState; updateLogFiles: LogFilesAppState; diff --git a/frontend/src/Components/SignalRListener.tsx b/frontend/src/Components/SignalRListener.tsx index 0d6e4117f..9dccbbe56 100644 --- a/frontend/src/Components/SignalRListener.tsx +++ b/frontend/src/Components/SignalRListener.tsx @@ -18,7 +18,6 @@ import { import { fetchRootFolders } from 'Store/Actions/rootFolderActions'; import { fetchSeries } from 'Store/Actions/seriesActions'; import { fetchQualityDefinitions } from 'Store/Actions/settingsActions'; -import { fetchHealth } from 'Store/Actions/systemActions'; import { fetchTagDetails, fetchTags } from 'Store/Actions/tagActions'; import { repopulatePage } from 'Utilities/pagePopulator'; import SignalRLogger from 'Utilities/SignalRLogger'; @@ -181,7 +180,11 @@ function SignalRListener() { } if (name === 'health') { - dispatch(fetchHealth()); + if (version < 5) { + return; + } + + queryClient.invalidateQueries({ queryKey: ['/health'] }); return; } diff --git a/frontend/src/Store/Actions/systemActions.js b/frontend/src/Store/Actions/systemActions.js index 64b34ad57..c9af92a86 100644 --- a/frontend/src/Store/Actions/systemActions.js +++ b/frontend/src/Store/Actions/systemActions.js @@ -18,13 +18,6 @@ const backupsSection = 'system.backups'; // State export const defaultState = { - health: { - isFetching: false, - isPopulated: false, - error: null, - items: [] - }, - diskSpace: { isFetching: false, isPopulated: false, @@ -61,7 +54,6 @@ export const defaultState = { // // Actions Types -export const FETCH_HEALTH = 'system/health/fetchHealth'; export const FETCH_DISK_SPACE = 'system/diskSpace/fetchDiskSPace'; export const FETCH_TASK = 'system/tasks/fetchTask'; @@ -78,7 +70,6 @@ export const SHUTDOWN = 'system/shutdown'; // // Action Creators -export const fetchHealth = createThunk(FETCH_HEALTH); export const fetchDiskSpace = createThunk(FETCH_DISK_SPACE); export const fetchTask = createThunk(FETCH_TASK); @@ -96,7 +87,6 @@ export const shutdown = createThunk(SHUTDOWN); // Action Handlers export const actionHandlers = handleThunks({ - [FETCH_HEALTH]: createFetchHandler('system.health', '/health'), [FETCH_DISK_SPACE]: createFetchHandler('system.diskSpace', '/diskspace'), [FETCH_TASK]: createFetchHandler('system.tasks', '/system/task'), [FETCH_TASKS]: createFetchHandler('system.tasks', '/system/task'), diff --git a/frontend/src/System/Status/Health/Health.tsx b/frontend/src/System/Status/Health/Health.tsx index b921c4d96..f6743e664 100644 --- a/frontend/src/System/Status/Health/Health.tsx +++ b/frontend/src/System/Status/Health/Health.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect } from 'react'; +import React, { useCallback } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import AppState from 'App/State/AppState'; import Alert from 'Components/Alert'; @@ -18,11 +18,10 @@ import { testAllDownloadClients, testAllIndexers, } from 'Store/Actions/settingsActions'; -import { fetchHealth } from 'Store/Actions/systemActions'; import titleCase from 'Utilities/String/titleCase'; import translate from 'Utilities/String/translate'; -import createHealthSelector from './createHealthSelector'; import HealthItemLink from './HealthItemLink'; +import useHealth from './useHealth'; import styles from './Health.css'; const columns: Column[] = [ @@ -46,9 +45,7 @@ const columns: Column[] = [ function Health() { const dispatch = useDispatch(); - const { isFetching, isPopulated, items } = useSelector( - createHealthSelector() - ); + const { data, isFetched, isFetching, isLoading } = useHealth(); const isTestingAllDownloadClients = useSelector( (state: AppState) => state.settings.downloadClients.isTestingAll ); @@ -56,7 +53,7 @@ function Health() { (state: AppState) => state.settings.indexers.isTestingAll ); - const healthIssues = !!items.length; + const healthIssues = !!data.length; const handleTestAllDownloadClientsPress = useCallback(() => { dispatch(testAllDownloadClients()); @@ -66,25 +63,21 @@ function Health() { dispatch(testAllIndexers()); }, [dispatch]); - useEffect(() => { - dispatch(fetchHealth()); - }, [dispatch]); - return (
{translate('Health')} - {isFetching && isPopulated ? ( + {isFetching && !isFetched ? ( ) : null} } > - {isFetching && !isPopulated ? : null} + {isLoading ? : null} - {isPopulated && !healthIssues ? ( + {isFetched && !healthIssues ? (
{translate('NoIssuesWithYourConfiguration')}
@@ -94,7 +87,7 @@ function Health() { <> - {items.map((item) => { + {data.map((item) => { const source = item.source; let kind: IconKind = kinds.WARNING; diff --git a/frontend/src/System/Status/Health/HealthStatus.tsx b/frontend/src/System/Status/Health/HealthStatus.tsx index b12fd3ebb..34f2cc56e 100644 --- a/frontend/src/System/Status/Health/HealthStatus.tsx +++ b/frontend/src/System/Status/Health/HealthStatus.tsx @@ -1,17 +1,15 @@ import React, { useEffect, useMemo } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { useSelector } from 'react-redux'; import AppState from 'App/State/AppState'; import PageSidebarStatus from 'Components/Page/Sidebar/PageSidebarStatus'; import usePrevious from 'Helpers/Hooks/usePrevious'; -import { fetchHealth } from 'Store/Actions/systemActions'; -import createHealthSelector from './createHealthSelector'; +import useHealth from './useHealth'; function HealthStatus() { - const dispatch = useDispatch(); const { isConnected, isReconnecting } = useSelector( (state: AppState) => state.app ); - const { isPopulated, items } = useSelector(createHealthSelector()); + const { data, refetch } = useHealth(); const wasReconnecting = usePrevious(isReconnecting); @@ -19,7 +17,7 @@ function HealthStatus() { let errors = false; let warnings = false; - items.forEach((item) => { + data.forEach((item) => { if (item.type === 'error') { errors = true; } @@ -30,23 +28,17 @@ function HealthStatus() { }); return { - count: items.length, + count: data.length, errors, warnings, }; - }, [items]); - - useEffect(() => { - if (!isPopulated) { - dispatch(fetchHealth()); - } - }, [isPopulated, dispatch]); + }, [data]); useEffect(() => { if (isConnected && wasReconnecting) { - dispatch(fetchHealth()); + refetch(); } - }, [isConnected, wasReconnecting, dispatch]); + }, [isConnected, wasReconnecting, refetch]); return ( diff --git a/frontend/src/System/Status/Health/createHealthSelector.ts b/frontend/src/System/Status/Health/createHealthSelector.ts deleted file mode 100644 index f38e3fe88..000000000 --- a/frontend/src/System/Status/Health/createHealthSelector.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { createSelector } from 'reselect'; -import AppState from 'App/State/AppState'; - -function createHealthSelector() { - return createSelector( - (state: AppState) => state.system.health, - (health) => { - return health; - } - ); -} - -export default createHealthSelector; diff --git a/frontend/src/System/Status/Health/useHealth.ts b/frontend/src/System/Status/Health/useHealth.ts new file mode 100644 index 000000000..84637288e --- /dev/null +++ b/frontend/src/System/Status/Health/useHealth.ts @@ -0,0 +1,15 @@ +import useApiQuery from 'Helpers/Hooks/useApiQuery'; +import Health from 'typings/Health'; + +const useHealth = () => { + const result = useApiQuery({ + path: '/health', + }); + + return { + ...result, + data: result.data ?? [], + }; +}; + +export default useHealth;