From 55ccb903d1bbbbce14517c5f9aa3a4054cdb62ee Mon Sep 17 00:00:00 2001 From: Maurice Date: Fri, 9 Oct 2026 17:39:19 +0200 Subject: [PATCH] fix(admin): the phone addon list shows the Collab and AI Parsing icons On the phone admin addon list, the Collab and AI Parsing tiles showed the generic puzzle piece, while the desktop shows the people and sparkles icons for them. Cause: the addons table stores 'Users' for collab and 'Sparkles' for llm_parsing, and the phone's ICON_MAP had no entry for either, so both fell back to Puzzle. The desktop map gained them earlier; the phone map was never updated. Fix: the phone ICON_MAP now carries Users and Sparkles, like the desktop one. Red test: FE-MOB-AADD-036 (new, MAdminAddonManager.test.tsx) failed with "expect(received).toBeInTheDocument(): received value must be an HTMLElement or an SVGElement" for svg.lucide-users. No existing assertion changed. --- .../mobile/screens/admin/MAdminAddonManager.tsx | 6 ++++-- .../mobile/admin/MAdminAddonManager.test.tsx | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/client/src/mobile/screens/admin/MAdminAddonManager.tsx b/client/src/mobile/screens/admin/MAdminAddonManager.tsx index 95d52d905..93517a651 100644 --- a/client/src/mobile/screens/admin/MAdminAddonManager.tsx +++ b/client/src/mobile/screens/admin/MAdminAddonManager.tsx @@ -3,7 +3,7 @@ import { useTranslation } from '../../../i18n' import { useSettingsStore } from '../../../store/settingsStore' import { Puzzle, ListChecks, Wallet, FileText, CalendarDays, Globe, Briefcase, Image, Terminal, Link2, Compass, BookOpen, - Sparkles, Luggage, Plane, Server, Cloud, Bookmark, Check, Loader2, + Sparkles, Luggage, Plane, Server, Cloud, Bookmark, Users, Check, Loader2, } from 'lucide-react' import DawarichIcon from '../../../components/shared/DawarichIcon' import AirTrailIcon from '../../../components/shared/AirTrailIcon' @@ -24,8 +24,10 @@ import { useLlmParsingConfig } from '../../../components/Admin/addons/useLlmPars import { ImmichIcon, SynologyIcon } from '../../../components/Admin/addons/PhotoProviderIcons' import { MAdminButton, MAdminCard, MAdminField, MAdminInput, MAdminSecretInput } from './MAdminUi' +// Keys are the `icon` column from the addons table; anything unknown falls back to +// Puzzle. Users/Sparkles cover collab and llm_parsing, as on the desktop. const ICON_MAP = { - ListChecks, Wallet, FileText, CalendarDays, Puzzle, Globe, Briefcase, Image, Terminal, Link2, Compass, BookOpen, Plane, Bookmark, + ListChecks, Wallet, FileText, CalendarDays, Puzzle, Globe, Briefcase, Image, Terminal, Link2, Compass, BookOpen, Plane, Bookmark, Users, Sparkles, Dawarich: DawarichIcon, } diff --git a/client/tests/unit/mobile/admin/MAdminAddonManager.test.tsx b/client/tests/unit/mobile/admin/MAdminAddonManager.test.tsx index 44e161298..8ee9c1c0b 100644 --- a/client/tests/unit/mobile/admin/MAdminAddonManager.test.tsx +++ b/client/tests/unit/mobile/admin/MAdminAddonManager.test.tsx @@ -1,4 +1,4 @@ -// FE-MOB-AADD-001 to FE-MOB-AADD-035 +// FE-MOB-AADD-001 to FE-MOB-AADD-036 import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import userEvent from '@testing-library/user-event'; import { delay, http, HttpResponse } from 'msw'; @@ -742,4 +742,19 @@ describe('MAdminAddonManager', () => { await user.type(screen.getByDisplayValue('sk-secret'), '-rotated'); expect(screen.getByDisplayValue('sk-secret-rotated')).toBeInTheDocument(); }); + + it('FE-MOB-AADD-036: collab and AI parsing show their own icons, not the puzzle fallback', async () => { + server.use( + addonsRoute([ + buildAddon({ id: 'collab', name: 'Collab', icon: 'Users', enabled: true }), + buildAddon({ id: 'llm_parsing', name: 'AI Parsing', icon: 'Sparkles', type: 'integration', enabled: false }), + ]), + ); + render(); + + await screen.findByRole('switch', { name: 'Collab' }); + expect(document.querySelector('svg.lucide-users')).toBeInTheDocument(); + expect(document.querySelector('svg.lucide-sparkles')).toBeInTheDocument(); + expect(document.querySelector('svg.lucide-puzzle')).not.toBeInTheDocument(); + }); });