diff --git a/client/src/components/Settings/PhotoProvidersSection.tsx b/client/src/components/Settings/PhotoProvidersSection.tsx index ac1794a8a..a1012c97d 100644 --- a/client/src/components/Settings/PhotoProvidersSection.tsx +++ b/client/src/components/Settings/PhotoProvidersSection.tsx @@ -7,21 +7,14 @@ import { SETTINGS_BUTTON, SETTINGS_BUTTON_PRIMARY, SettingRow, SettingRows, Stat import { EditorField, INPUT } from '../shared/dialogParts' import { fs } from '../shared/DialogShell' import { Tooltip } from '../shared/Tooltip' -import { - getProviderConfig, - getProviderFields, - usePhotoProviderConnections, - type PhotoProviderAddon, -} from './usePhotoProviderConnections' +import { usePhotoProviderConnections, type PhotoProviderAddon } from './usePhotoProviderConnections' export default function PhotoProvidersSection(): React.ReactElement { const { t } = useTranslation() const { memoriesEnabled, activePhotoProviders, - providerValues, - providerConnected, - providerTesting, + providerCard, saving, handleProviderFieldChange, isProviderSaveDisabled, @@ -30,13 +23,7 @@ export default function PhotoProvidersSection(): React.ReactElement { } = usePhotoProviderConnections() const renderPhotoProviderSection = (provider: PhotoProviderAddon): React.ReactElement => { - const fields = getProviderFields(provider) - const cfg = getProviderConfig(provider) - const values = providerValues[provider.id] || {} - const connected = !!providerConnected[provider.id] - const testing = !!providerTesting[provider.id] - const canSave = !!cfg.settings_put - const canTest = !!(cfg.test_post || cfg.test_get || cfg.status_get) + const { fields, values, connected, testing, canSave, canTest } = providerCard(provider) const saveDisabledReason = !canSave ? t('memories.saveRouteNotConfigured') diff --git a/client/src/components/Settings/usePhotoProviderConnections.test.ts b/client/src/components/Settings/usePhotoProviderConnections.test.ts index 7d88bfd36..f7d259279 100644 --- a/client/src/components/Settings/usePhotoProviderConnections.test.ts +++ b/client/src/components/Settings/usePhotoProviderConnections.test.ts @@ -1,4 +1,4 @@ -// FE-COMP-PHOTOCONN-001 to -010: the photo provider connection logic both settings shells share. +// FE-COMP-PHOTOCONN-001 to -011: the photo provider connection logic both settings shells share. import { act, renderHook, waitFor } from '@testing-library/react'; import { resetAllStores, seedStore } from '../../../tests/helpers/store'; import apiClient from '../../api/client'; @@ -227,4 +227,20 @@ describe('usePhotoProviderConnections', () => { await act(() => desktop.result.current.handleTestProvider(PROVIDER)); expect(toast.error).toHaveBeenLastCalledWith('memories.connectionError(Immich)'); }); + + it('FE-COMP-PHOTOCONN-011: providerCard hands each card its fields, values, badge and working buttons', async () => { + seedProviders([PROVIDER]); + stubGets({ + '/addons/immich/settings': { data: { url: 'https://a' } }, + '/addons/immich/status': { data: { connected: true } }, + }); + const { result } = render(); + await waitFor(() => expect(result.current.providerCard(PROVIDER).connected).toBe(true)); + const card = result.current.providerCard(PROVIDER); + expect(card.fields.map((f) => f.key)).toEqual(['url', 'api_key', 'shared']); + expect(card.values).toEqual({ url: 'https://a', shared: 'false' }); + expect(card).toMatchObject({ testing: false, canSave: true, canTest: true }); + const bare = result.current.providerCard({ ...PROVIDER, id: 'other', config: {} }); + expect(bare).toMatchObject({ values: {}, connected: false, canSave: false, canTest: false }); + }); }); diff --git a/client/src/components/Settings/usePhotoProviderConnections.ts b/client/src/components/Settings/usePhotoProviderConnections.ts index 8fa325349..a0838bd97 100644 --- a/client/src/components/Settings/usePhotoProviderConnections.ts +++ b/client/src/components/Settings/usePhotoProviderConnections.ts @@ -221,9 +221,23 @@ export function usePhotoProviderConnections() { } }; + /** What one provider card draws from: its fields, values, badge and which buttons work. */ + const providerCard = (provider: PhotoProviderAddon) => { + const cfg = getProviderConfig(provider); + return { + fields: getProviderFields(provider), + values: providerValues[provider.id] || {}, + connected: !!providerConnected[provider.id], + testing: !!providerTesting[provider.id], + canSave: !!cfg.settings_put, + canTest: !!(cfg.test_post || cfg.test_get || cfg.status_get), + }; + }; + return { memoriesEnabled, activePhotoProviders, + providerCard, providerValues, providerConnected, providerTesting, diff --git a/client/src/mobile/screens/settings/MPhotoProvidersSection.tsx b/client/src/mobile/screens/settings/MPhotoProvidersSection.tsx index 09ae85e99..84ed21188 100644 --- a/client/src/mobile/screens/settings/MPhotoProvidersSection.tsx +++ b/client/src/mobile/screens/settings/MPhotoProvidersSection.tsx @@ -3,12 +3,7 @@ import { Camera, Save, RefreshCw } from 'lucide-react' import { useTranslation } from '../../../i18n' import { MSetCard, MSetEyebrow, MSetRow, MSetInput, MSetButton, MSetHint } from './MSettingsUi' import MToggle from '../../components/MToggle' -import { - getProviderConfig, - getProviderFields, - usePhotoProviderConnections, - type PhotoProviderAddon, -} from '../../../components/Settings/usePhotoProviderConnections' +import { usePhotoProviderConnections, type PhotoProviderAddon } from '../../../components/Settings/usePhotoProviderConnections' /** * Mobile-native twin of components/Settings/PhotoProvidersSection. Same logic @@ -22,9 +17,7 @@ export default function MPhotoProvidersSection(): React.ReactElement { const { memoriesEnabled, activePhotoProviders, - providerValues, - providerConnected, - providerTesting, + providerCard, saving, handleProviderFieldChange, isProviderSaveDisabled, @@ -33,13 +26,7 @@ export default function MPhotoProvidersSection(): React.ReactElement { } = usePhotoProviderConnections() const renderPhotoProviderSection = (provider: PhotoProviderAddon): React.ReactElement => { - const fields = getProviderFields(provider) - const cfg = getProviderConfig(provider) - const values = providerValues[provider.id] || {} - const connected = !!providerConnected[provider.id] - const testing = !!providerTesting[provider.id] - const canSave = !!cfg.settings_put - const canTest = !!(cfg.test_post || cfg.test_get || cfg.status_get) + const { fields, values, connected, testing, canSave, canTest } = providerCard(provider) return (