diff --git a/ui/src/layout/ActivityPanel.jsx b/ui/src/layout/ActivityPanel.jsx
index 6b50cee0c..18af8dc93 100644
--- a/ui/src/layout/ActivityPanel.jsx
+++ b/ui/src/layout/ActivityPanel.jsx
@@ -75,14 +75,25 @@ const ActivityPanel = () => {
scanStatus.scanning,
scanStatus.elapsedTime,
)
- const classes = useStyles({ up: up && !scanStatus.error })
+ const [acknowledgedError, setAcknowledgedError] = useState(null)
+ const isErrorVisible =
+ scanStatus.error && scanStatus.error !== acknowledgedError
+ const classes = useStyles({
+ up: up && (!scanStatus.error || !isErrorVisible),
+ })
const translate = useTranslate()
const notify = useNotify()
const [anchorEl, setAnchorEl] = useState(null)
const open = Boolean(anchorEl)
useInitialScanStatus()
- const handleMenuOpen = (event) => setAnchorEl(event.currentTarget)
+ const handleMenuOpen = (event) => {
+ if (scanStatus.error) {
+ setAcknowledgedError(scanStatus.error)
+ }
+ setAnchorEl(event.currentTarget)
+ }
+
const handleMenuClose = () => setAnchorEl(null)
const triggerScan = (full) => () => subsonic.startScan({ fullScan: full })
@@ -111,10 +122,10 @@ const ActivityPanel = () => {
- {!up || scanStatus.error ? (
-
+ {!up || isErrorVisible ? (
+
) : (
-
+
)}
diff --git a/ui/src/layout/ActivityPanel.test.jsx b/ui/src/layout/ActivityPanel.test.jsx
new file mode 100644
index 000000000..c506fd08b
--- /dev/null
+++ b/ui/src/layout/ActivityPanel.test.jsx
@@ -0,0 +1,61 @@
+import React from 'react'
+import { render, screen, fireEvent } from '@testing-library/react'
+import { Provider } from 'react-redux'
+import { createStore, combineReducers } from 'redux'
+import { describe, it, beforeEach } from 'vitest'
+
+import ActivityPanel from './ActivityPanel'
+import { activityReducer } from '../reducers'
+import config from '../config'
+import subsonic from '../subsonic'
+
+vi.mock('../subsonic', () => ({
+ default: {
+ getScanStatus: vi.fn(() =>
+ Promise.resolve({
+ json: {
+ 'subsonic-response': {
+ status: 'ok',
+ scanStatus: { error: 'Scan failed' },
+ },
+ },
+ }),
+ ),
+ startScan: vi.fn(),
+ },
+}))
+
+describe('
', () => {
+ let store
+
+ beforeEach(() => {
+ store = createStore(combineReducers({ activity: activityReducer }), {
+ activity: {
+ scanStatus: {
+ scanning: false,
+ folderCount: 0,
+ count: 0,
+ error: 'Scan failed',
+ elapsedTime: 0,
+ },
+ serverStart: { version: config.version, startTime: Date.now() },
+ },
+ })
+ })
+
+ it('clears the error icon after opening the panel', () => {
+ render(
+
+
+ ,
+ )
+
+ const button = screen.getByRole('button')
+ expect(screen.getByTestId('activity-error-icon')).toBeInTheDocument()
+
+ fireEvent.click(button)
+
+ expect(screen.getByTestId('activity-ok-icon')).toBeInTheDocument()
+ expect(screen.getByText('Scan failed')).toBeInTheDocument()
+ })
+})