refactor: provider descriptor registry — eliminate provider-specific hardcoding
Replace all if/else chains keyed on provider type strings with a descriptor-driven architecture. Each provider type (immich, gitea, planka, scheduler, nut, google_photos) has a descriptor in frontend/src/lib/providers/ that declares config fields, event tracking fields, collection metadata, validation, and hooks. Components now use getDescriptor(type) and render dynamically. Dashboard provider card shows provider name + type when global filter is active. Grid-items derived from registry.
This commit is contained in:
@@ -1,24 +1,22 @@
|
||||
/**
|
||||
* Shared IconGridSelect item definitions used across multiple pages.
|
||||
* Keeps grid item arrays DRY and consistent.
|
||||
*
|
||||
* Provider-specific items (type selector, filter, icons) are derived
|
||||
* from the provider descriptor registry — see lib/providers/.
|
||||
*/
|
||||
|
||||
import { t } from '$lib/i18n';
|
||||
import type { GridItem } from '$lib/components/IconGridSelect.svelte';
|
||||
|
||||
/** Default icon for each provider type. Use instead of hardcoded 'mdiServer'. */
|
||||
const PROVIDER_TYPE_ICONS: Record<string, string> = {
|
||||
immich: 'mdiImageMultiple',
|
||||
gitea: 'mdiGit',
|
||||
planka: 'mdiViewDashboard',
|
||||
scheduler: 'mdiClockOutline',
|
||||
nut: 'mdiBatteryCharging80',
|
||||
};
|
||||
import { allDescriptors, getDescriptor } from '$lib/providers';
|
||||
|
||||
/** Get the default icon for a provider, falling back by type then generic. */
|
||||
export function providerDefaultIcon(provider: { icon?: string; type?: string }): string {
|
||||
if (provider.icon) return provider.icon;
|
||||
if (provider.type && PROVIDER_TYPE_ICONS[provider.type]) return PROVIDER_TYPE_ICONS[provider.type];
|
||||
if (provider.type) {
|
||||
const desc = getDescriptor(provider.type);
|
||||
if (desc) return desc.icon;
|
||||
}
|
||||
return 'mdiServer';
|
||||
}
|
||||
|
||||
@@ -111,23 +109,24 @@ export const previewTargetTypeItems = (): GridItem[] => [
|
||||
{ value: 'webhook', icon: 'mdiWebhook', label: t('targets.typeWebhook'), desc: t('gridDesc.previewWebhook') },
|
||||
];
|
||||
|
||||
// --- Provider type filter (with "All" option) ---
|
||||
// --- Provider type items (derived from descriptor registry) ---
|
||||
|
||||
/** Convert snake_case type to PascalCase i18n suffix: "google_photos" → "GooglePhotos" */
|
||||
function typeToKey(type: string): string {
|
||||
return type.replace(/(^|_)([a-z])/g, (_, __, c) => c.toUpperCase());
|
||||
}
|
||||
|
||||
function descriptorToGridItem(d: { type: string; icon: string }): GridItem {
|
||||
const key = typeToKey(d.type);
|
||||
return { value: d.type, icon: d.icon, label: t(`providers.type${key}`), desc: t(`gridDesc.provider${key}`) };
|
||||
}
|
||||
|
||||
/** Provider type filter with "All types" option. */
|
||||
export const providerTypeFilterItems = (): GridItem[] => [
|
||||
{ value: '', icon: 'mdiFilterOff', label: t('common.allTypes'), desc: t('gridDesc.allEvents') },
|
||||
{ value: 'immich', icon: 'mdiCamera', label: t('providers.typeImmich'), desc: t('gridDesc.providerImmich') },
|
||||
{ value: 'gitea', icon: 'mdiGit', label: t('providers.typeGitea'), desc: t('gridDesc.providerGitea') },
|
||||
{ value: 'planka', icon: 'mdiViewDashboard', label: t('providers.typePlanka'), desc: t('gridDesc.providerPlanka') },
|
||||
{ value: 'scheduler', icon: 'mdiClockOutline', label: t('providers.typeScheduler'), desc: t('gridDesc.providerScheduler') },
|
||||
{ value: 'nut', icon: PROVIDER_TYPE_ICONS.nut, label: t('providers.typeNut'), desc: t('gridDesc.providerNut') },
|
||||
...allDescriptors().map(descriptorToGridItem),
|
||||
];
|
||||
|
||||
// --- Provider type ---
|
||||
|
||||
export const providerTypeItems = (): GridItem[] => [
|
||||
{ value: 'immich', icon: PROVIDER_TYPE_ICONS.immich, label: t('providers.typeImmich'), desc: t('gridDesc.providerImmich') },
|
||||
{ value: 'gitea', icon: PROVIDER_TYPE_ICONS.gitea, label: t('providers.typeGitea'), desc: t('gridDesc.providerGitea') },
|
||||
{ value: 'planka', icon: PROVIDER_TYPE_ICONS.planka, label: t('providers.typePlanka'), desc: t('gridDesc.providerPlanka') },
|
||||
{ value: 'scheduler', icon: PROVIDER_TYPE_ICONS.scheduler, label: t('providers.typeScheduler'), desc: t('gridDesc.providerScheduler') },
|
||||
{ value: 'nut', icon: PROVIDER_TYPE_ICONS.nut, label: t('providers.typeNut'), desc: t('gridDesc.providerNut') },
|
||||
];
|
||||
/** Provider type selector (no "All" option). */
|
||||
export const providerTypeItems = (): GridItem[] =>
|
||||
allDescriptors().map(descriptorToGridItem);
|
||||
|
||||
Reference in New Issue
Block a user