diff --git a/src/app/Archives/AllArchivedRecordingsTable.tsx b/src/app/Archives/AllArchivedRecordingsTable.tsx index 5d405a627..96d021975 100644 --- a/src/app/Archives/AllArchivedRecordingsTable.tsx +++ b/src/app/Archives/AllArchivedRecordingsTable.tsx @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { ErrorView } from '@app/ErrorView/ErrorView'; +import { authFailMessage, isAuthFail } from '@app/ErrorView/types'; import { ArchivedRecordingsTable } from '@app/Recordings/ArchivedRecordingsTable'; import { LoadingView } from '@app/Shared/Components/LoadingView'; import { ArchivedRecording, RecordingDirectory, Target, NotificationCategory } from '@app/Shared/Services/api.types'; @@ -78,6 +80,7 @@ export const AllArchivedRecordingsTable: React.FC([]); const [searchText, setSearchText] = React.useState(''); const [expandedDirectories, setExpandedDirectories] = React.useState<_RecordingDirectory[]>([]); + const [errorMessage, setErrorMessage] = React.useState(''); const [isLoading, setIsLoading] = React.useState(false); const addSubscription = useSubscriptions(); const [sortBy, getSortParams] = useSort(); @@ -90,12 +93,23 @@ export const AllArchivedRecordingsTable: React.FC { + setIsLoading(false); + setErrorMessage(error.message); + }, + [setIsLoading, setErrorMessage], + ); + const refreshDirectoriesAndCounts = React.useCallback(() => { setIsLoading(true); addSubscription( - context.api.doGet('fs/recordings', 'beta').subscribe(handleDirectoriesAndCounts), + context.api.doGet('fs/recordings', 'beta').subscribe({ + next: handleDirectoriesAndCounts, + error: handleError, + }), ); - }, [addSubscription, context.api, setIsLoading, handleDirectoriesAndCounts]); + }, [addSubscription, context.api, setIsLoading, handleDirectoriesAndCounts, handleError]); const handleSearchInput = React.useCallback( (searchInput: string) => { @@ -134,6 +148,14 @@ export const AllArchivedRecordingsTable: React.FC { + addSubscription( + context.target.authFailure().subscribe(() => { + setErrorMessage(authFailMessage); + }), + ); + }, [context, context.target, setErrorMessage, addSubscription]); + React.useEffect(() => { if (!context.settings.autoRefreshEnabled()) { return; @@ -262,7 +284,24 @@ export const AllArchivedRecordingsTable: React.FC { + context.target.setAuthRetry(); + }, [context.target]); + + const isError = React.useMemo(() => errorMessage != '', [errorMessage]); + + if (isError) { + view = ( + <> + + + ); + } else if (isLoading) { view = ; } else if (!searchedDirectories.length) { view = ( diff --git a/src/app/Archives/AllTargetsArchivedRecordingsTable.tsx b/src/app/Archives/AllTargetsArchivedRecordingsTable.tsx index df4d1b8bf..32a7a16b8 100644 --- a/src/app/Archives/AllTargetsArchivedRecordingsTable.tsx +++ b/src/app/Archives/AllTargetsArchivedRecordingsTable.tsx @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { ErrorView } from '@app/ErrorView/ErrorView'; +import { authFailMessage, isAuthFail } from '@app/ErrorView/types'; import { ArchivedRecordingsTable } from '@app/Recordings/ArchivedRecordingsTable'; import { LoadingView } from '@app/Shared/Components/LoadingView'; import { Target, TargetDiscoveryEvent, NotificationCategory } from '@app/Shared/Services/api.types'; @@ -82,6 +84,7 @@ export const AllTargetsArchivedRecordingsTable: React.FC([]); const [expandedTargets, setExpandedTargets] = React.useState([] as Target[]); const [hideEmptyTargets, setHideEmptyTargets] = React.useState(true); + const [errorMessage, setErrorMessage] = React.useState(''); const [isLoading, setIsLoading] = React.useState(false); const addSubscription = useSubscriptions(); const [sortBy, getSortParams] = useSort(); @@ -105,6 +108,7 @@ export const AllTargetsArchivedRecordingsTable: React.FC { setIsLoading(false); + setErrorMessage(''); setArchivesForTargets( targetNodes.map((node) => { const target: Target = { @@ -119,7 +123,15 @@ export const AllTargetsArchivedRecordingsTable: React.FC { + setIsLoading(false); + setErrorMessage(error.message); + }, + [setIsLoading, setErrorMessage], ); /* eslint-disable @typescript-eslint/no-explicit-any */ @@ -145,9 +157,12 @@ export const AllTargetsArchivedRecordingsTable: React.FC v.data.targetNodes)) - .subscribe(handleArchivesForTargets), + .subscribe({ + next: handleArchivesForTargets, + error: handleError, + }), ); - }, [addSubscription, context.api, setIsLoading, handleArchivesForTargets]); + }, [addSubscription, context.api, setIsLoading, handleArchivesForTargets, handleError]); /* eslint-disable @typescript-eslint/no-explicit-any */ const getCountForNewTarget = React.useCallback( @@ -260,6 +275,14 @@ export const AllTargetsArchivedRecordingsTable: React.FC { + addSubscription( + context.target.authFailure().subscribe(() => { + setErrorMessage(authFailMessage); + }), + ); + }, [context, context.target, setErrorMessage, addSubscription]); + React.useEffect(() => { if (!context.settings.autoRefreshEnabled()) { return; @@ -374,7 +397,24 @@ export const AllTargetsArchivedRecordingsTable: React.FC { + context.target.setAuthRetry(); + }, [context.target]); + + const isError = React.useMemo(() => errorMessage != '', [errorMessage]); + + if (isError) { + view = ( + <> + + + ); + } else if (isLoading) { view = ; } else if (!searchedArchivesForTargets.length) { view = ( diff --git a/src/app/Shared/Services/Api.service.tsx b/src/app/Shared/Services/Api.service.tsx index 0583bb946..d689f23a8 100644 --- a/src/app/Shared/Services/Api.service.tsx +++ b/src/app/Shared/Services/Api.service.tsx @@ -36,7 +36,6 @@ import { EventProbe, EventProbesResponse, Recording, - AssetJwtResponse, EventTemplate, RuleResponse, ArchivedRecording,