diff --git a/Web App/web/src/i18n/da.json b/Web App/web/src/i18n/da.json index 83b6393..68d1f67 100644 --- a/Web App/web/src/i18n/da.json +++ b/Web App/web/src/i18n/da.json @@ -251,6 +251,7 @@ }, "integrations": { + "categories": { "vehicles": "Bilproducenter", "chargers": "EV-ladere" }, "title": "Integrationer", "subtitle": "Forbind eksterne tjenester til din konto.", "toyota": "Toyota Connected (MyToyota)", diff --git a/Web App/web/src/i18n/en.json b/Web App/web/src/i18n/en.json index 6aa24eb..b911664 100644 --- a/Web App/web/src/i18n/en.json +++ b/Web App/web/src/i18n/en.json @@ -250,6 +250,7 @@ }, "integrations": { + "categories": { "vehicles": "Car manufacturers", "chargers": "EV chargers" }, "title": "Integrations", "subtitle": "Connect external services to your account.", "toyota": "Toyota Connected (MyToyota)", diff --git a/Web App/web/src/i18n/pl.json b/Web App/web/src/i18n/pl.json index 36c36ff..ea4d6ba 100644 --- a/Web App/web/src/i18n/pl.json +++ b/Web App/web/src/i18n/pl.json @@ -255,6 +255,7 @@ }, "integrations": { + "categories": { "vehicles": "Producenci samochodów", "chargers": "Ładowarki EV" }, "title": "Integracje", "subtitle": "Połącz zewnętrzne usługi ze swoim kontem.", "toyota": "Toyota Connected (MyToyota)", diff --git a/Web App/web/src/views/Settings.vue b/Web App/web/src/views/Settings.vue index 0198511..8a52f60 100644 --- a/Web App/web/src/views/Settings.vue +++ b/Web App/web/src/views/Settings.vue @@ -424,6 +424,39 @@ async function testToyotaConnection() { } } +// --- Integrations: category tabs --- +// +// The API Server panel groups plugins into the same categories (see +// panel/src/components/PluginsCard.vue, and the Category* constants in +// internal/plugins/plugin.go that both read from), so grouping them the same way +// here means someone who has seen one list can read the other. Only a category +// that actually has an integration gets a tab — two tabs today, not six empty +// ones — and a category whose integrations are all still loading has none, which +// is why the active group falls back to the first rather than to a fixed id. +const INTEGRATION_CATEGORIES = ["vehicles", "chargers"]; + +const integrationsByCategory = computed(() => ({ + vehicles: [toyota.value && "toyota"].filter(Boolean), + chargers: [anker.value && "anker", greencell.value && "greencell"].filter(Boolean), +})); + +const integrationGroups = computed(() => + INTEGRATION_CATEGORIES.filter((c) => integrationsByCategory.value[c].length).map((c) => ({ + id: c, + label: t(`settings.integrations.categories.${c}`), + ids: integrationsByCategory.value[c], + })) +); + +const integrationTab = ref(""); +const activeIntegrationGroup = computed( + () => integrationGroups.value.find((g) => g.id === integrationTab.value) || integrationGroups.value[0] +); + +function showsIntegration(id) { + return !!activeIntegrationGroup.value?.ids.includes(id); +} + // --- Integrations: Anker Solix (V1 Smart EV Charger) --- // // Same superadmin → org admin → user cascade as Toyota above; the fields are the @@ -1211,7 +1244,23 @@ onBeforeUnmount(() => {
{{ t("settings.integrations.subtitle") }}
-