Add HMS error notifications with translations and plate detection fixes

New Features:
- HMS error notifications with human-readable messages (853 error codes)
- Plate not empty notification category (separate toggle in settings)
- Module-friendly names: Print/Task, AMS/Filament, Nozzle/Extruder, etc.
- Backup/restore now includes plate calibration reference images

Fixes:
- Plate calibration images now persist after restart in Docker
- Telegram notifications no longer fail on error codes with underscores
- Plate detection combo button: main toggles detection, chevron opens modal

Tests:
- Added HMS error code tests (10 tests)
- Implemented Dashboard, FileManagerModal, UploadModal tests (previously skipped)
- Added notification service tests for HMS errors and plate detection
- Fixed AuthContext unmount memory leak in tests
This commit is contained in:
maziggy
2026-01-27 08:48:57 +01:00
parent 9d6164ab1c
commit b9495877fc
26 changed files with 2488 additions and 167 deletions
+18 -3
View File
@@ -21,10 +21,12 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
const [requiresSetup, setRequiresSetup] = useState(false);
const [loading, setLoading] = useState(true);
const hasRedirectedRef = useRef(false);
const mountedRef = useRef(true);
const checkAuthStatus = async () => {
try {
const status = await api.getAuthStatus();
if (!mountedRef.current) return;
setAuthEnabled(status.auth_enabled);
setRequiresSetup(status.requires_setup);
@@ -33,10 +35,12 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
if (token) {
try {
const currentUser = await api.getCurrentUser();
if (!mountedRef.current) return;
setUser(currentUser);
} catch {
// Token invalid, clear it
setAuthToken(null);
if (!mountedRef.current) return;
setUser(null);
}
} else {
@@ -47,16 +51,23 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
setUser(null);
}
} catch {
if (!mountedRef.current) return;
setAuthEnabled(false);
setUser(null);
} finally {
setLoading(false);
if (mountedRef.current) {
setLoading(false);
}
}
};
useEffect(() => {
mountedRef.current = true;
// Check auth status on mount
checkAuthStatus();
return () => {
mountedRef.current = false;
};
}, []);
// Separate effect to handle redirect only when setup is required
@@ -95,10 +106,14 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
if (authEnabled && getAuthToken()) {
try {
const currentUser = await api.getCurrentUser();
setUser(currentUser);
if (mountedRef.current) {
setUser(currentUser);
}
} catch {
setAuthToken(null);
setUser(null);
if (mountedRef.current) {
setUser(null);
}
}
}
};