From 58a475cb03bad0b6632f9e5eae1e8e8ce05177b5 Mon Sep 17 00:00:00 2001 From: Matheus Macabu Date: Wed, 2 Apr 2025 13:05:02 +0200 Subject: [PATCH] CloudMigrations: Refactor and unify resource naming/icon resolution (#103258) This is more in preparation for the snapshot configuration option, to avoid having to duplicate the functions that would: - Find an icon based on resource type - Find a label based on resource type Since we use those for other components, I figured we could just make a helper function to reuse them. --- .../migrate-to-cloud/onprem/NameCell.tsx | 46 +++++--------- .../migrate-to-cloud/onprem/resourceInfo.ts | 61 +++++++++++++++++++ .../onprem/useNotifyOnSuccess.tsx | 30 +++------ public/locales/en-US/grafana.json | 26 ++++---- 4 files changed, 96 insertions(+), 67 deletions(-) create mode 100644 public/app/features/migrate-to-cloud/onprem/resourceInfo.ts diff --git a/public/app/features/migrate-to-cloud/onprem/NameCell.tsx b/public/app/features/migrate-to-cloud/onprem/NameCell.tsx index 8858c2f611c..ba047a6bb96 100644 --- a/public/app/features/migrate-to-cloud/onprem/NameCell.tsx +++ b/public/app/features/migrate-to-cloud/onprem/NameCell.tsx @@ -12,6 +12,7 @@ import { useGetFolderQuery } from 'app/features/browse-dashboards/api/browseDash import { LocalPlugin } from '../../plugins/admin/types'; import { useGetDashboardByUidQuery, useGetLibraryElementByUidQuery } from '../api'; +import { iconNameForResource } from './resourceInfo'; import { ResourceTableItem } from './types'; export function NameCell(props: CellProps) { @@ -210,39 +211,20 @@ function ResourceIcon({ resource }: { resource: ResourceTableItem }) { const datasource = useDatasource(resource.type === 'DATASOURCE' ? resource.refId : undefined); const pluginLogo = usePluginLogo(resource.type === 'PLUGIN' ? resource.plugin : undefined); - switch (resource.type) { - case 'DASHBOARD': - return ; - case 'FOLDER': - return ; - case 'DATASOURCE': - if (datasource?.meta?.info?.logos?.small) { - return ; - } - - return ; - case 'LIBRARY_ELEMENT': - return ; - case 'MUTE_TIMING': - return ; - case 'NOTIFICATION_TEMPLATE': - return ; - case 'CONTACT_POINT': - return ; - case 'NOTIFICATION_POLICY': - return ; - case 'ALERT_RULE': - return ; - case 'ALERT_RULE_GROUP': - return ; - case 'PLUGIN': - if (pluginLogo) { - return ; - } - return ; - default: - return undefined; + // Handle special cases for icons. + if (resource.type === 'DATASOURCE' && datasource?.meta?.info?.logos?.small) { + return ; + } else if (resource.type === 'PLUGIN' && pluginLogo) { + return ; + } else { + // Generic icons for all other resource types. + const iconName = iconNameForResource(resource.type); + if (iconName) { + return ; + } } + + return undefined; } function getIconStyles() { diff --git a/public/app/features/migrate-to-cloud/onprem/resourceInfo.ts b/public/app/features/migrate-to-cloud/onprem/resourceInfo.ts new file mode 100644 index 00000000000..d28c45d0448 --- /dev/null +++ b/public/app/features/migrate-to-cloud/onprem/resourceInfo.ts @@ -0,0 +1,61 @@ +import { t } from 'app/core/internationalization'; + +import { ResourceTableItem } from './types'; + +export function iconNameForResource(resource: ResourceTableItem['type']) { + switch (resource) { + case 'DASHBOARD': + return 'dashboard'; + case 'FOLDER': + return 'folder'; + case 'DATASOURCE': + return 'database'; + case 'LIBRARY_ELEMENT': + return 'library-panel'; + case 'MUTE_TIMING': + return 'clock-nine'; + case 'NOTIFICATION_TEMPLATE': + return 'file-alt'; + case 'CONTACT_POINT': + return 'at'; + case 'NOTIFICATION_POLICY': + return 'comment-alt'; + case 'ALERT_RULE': + return 'bell'; + case 'ALERT_RULE_GROUP': + return 'bell'; + case 'PLUGIN': + return 'plug'; + default: + return undefined; + } +} + +export function pluralizeResourceName(resource: ResourceTableItem['type']) { + switch (resource) { + case 'DASHBOARD': + return t('migrate-to-cloud.resource-types.dashboard', 'Dashboards'); + case 'FOLDER': + return t('migrate-to-cloud.resource-types.folder', 'Folders'); + case 'DATASOURCE': + return t('migrate-to-cloud.resource-types.datasource', 'Data Sources'); + case 'LIBRARY_ELEMENT': + return t('migrate-to-cloud.resource-types.library_element', 'Library Elements'); + case 'MUTE_TIMING': + return t('migrate-to-cloud.resource-types.mute_timing', 'Mute Timings'); + case 'NOTIFICATION_TEMPLATE': + return t('migrate-to-cloud.resource-types.notification_template', 'Notification Templates'); + case 'CONTACT_POINT': + return t('migrate-to-cloud.resource-types.contact_point', 'Contact Points'); + case 'NOTIFICATION_POLICY': + return t('migrate-to-cloud.resource-types.notification_policy', 'Notification Policies'); + case 'ALERT_RULE': + return t('migrate-to-cloud.resource-types.alert_rule', 'Alert Rules'); + case 'ALERT_RULE_GROUP': + return t('migrate-to-cloud.resource-types.alert_rule_group', 'Alert Rule Groups'); + case 'PLUGIN': + return t('migrate-to-cloud.resource-types.plugin', 'Plugins'); + default: + return undefined; + } +} diff --git a/public/app/features/migrate-to-cloud/onprem/useNotifyOnSuccess.tsx b/public/app/features/migrate-to-cloud/onprem/useNotifyOnSuccess.tsx index e98a8221bb6..99e716fd79c 100644 --- a/public/app/features/migrate-to-cloud/onprem/useNotifyOnSuccess.tsx +++ b/public/app/features/migrate-to-cloud/onprem/useNotifyOnSuccess.tsx @@ -5,6 +5,9 @@ import { t } from 'app/core/internationalization'; import { GetSnapshotResponseDto, SnapshotDto } from '../api'; +import { pluralizeResourceName } from './resourceInfo'; +import { ResourceTableItem } from './types'; + // After the number of distinct resource types migrated exceeeds this value, we display a generic success message. const SUCCESS_MESSAGE_ITEM_TYPES_THRESHOLD = 4; @@ -44,30 +47,13 @@ function getTranslatedMessage(snapshot: GetSnapshotResponseDto) { // We don't have per-resource status counts, so there's no way to accurately pluralize these // so we just don't :) - if (type === 'DASHBOARD') { - types.push(t('migrate-to-cloud.migrated-counts.dashboards', 'dashboards')); - } else if (type === 'DATASOURCE') { - types.push(t('migrate-to-cloud.migrated-counts.datasources', 'data sources')); - } else if (type === 'FOLDER') { - types.push(t('migrate-to-cloud.migrated-counts.folders', 'folders')); - } else if (type === 'LIBRARY_ELEMENT') { - types.push(t('migrate-to-cloud.migrated-counts.library_elements', 'library elements')); - } else if (type === 'MUTE_TIMING') { - types.push(t('migrate-to-cloud.migrated-counts.mute_timings', 'mute timings')); - } else if (type === 'NOTIFICATION_TEMPLATE') { - types.push(t('migrate-to-cloud.migrated-counts.notification_templates', 'notification templates')); - } else if (type === 'CONTACT_POINT') { - types.push(t('migrate-to-cloud.migrated-counts.contact_points', 'contact points')); - } else if (type === 'NOTIFICATION_POLICY') { - types.push(t('migrate-to-cloud.migrated-counts.notification_policies', 'notification policies')); - } else if (type === 'ALERT_RULE') { - types.push(t('migrate-to-cloud.migrated-counts.alert_rules', 'alert rules')); - } else if (type === 'ALERT_RULE_GROUP') { - types.push(t('migrate-to-cloud.migrated-counts.alert_rule_groups', 'alert rule groups')); - } else if (type === 'PLUGIN') { - types.push(t('migrate-to-cloud.migrated-counts.plugins', 'plugins')); + const resourceType = pluralizeResourceName(type as ResourceTableItem['type']); + if (!resourceType) { + continue; } + types.push(resourceType); + distinctItems += 1; } diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index bf41cf88b47..b37077dc212 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -3871,19 +3871,6 @@ "link-title": "View the full migration guide", "title": "Let us help you migrate to this stack" }, - "migrated-counts": { - "alert_rule_groups": "alert rule groups", - "alert_rules": "alert rules", - "contact_points": "contact points", - "dashboards": "dashboards", - "datasources": "data sources", - "folders": "folders", - "library_elements": "library elements", - "mute_timings": "mute timings", - "notification_policies": "notification policies", - "notification_templates": "notification templates", - "plugins": "plugins" - }, "migration-token": { "delete-button": "Delete token", "delete-modal-body": "If you've already used this token with a self-managed installation, that installation will no longer be able to upload content.", @@ -3983,6 +3970,19 @@ "plugin": "Plugin", "unknown": "Unknown" }, + "resource-types": { + "alert_rule": "Alert Rules", + "alert_rule_group": "Alert Rule Groups", + "contact_point": "Contact Points", + "dashboard": "Dashboards", + "datasource": "Data Sources", + "folder": "Folders", + "library_element": "Library Elements", + "mute_timing": "Mute Timings", + "notification_policy": "Notification Policies", + "notification_template": "Notification Templates", + "plugin": "Plugins" + }, "summary": { "cancel-snapshot": "Cancel snapshot", "disconnect": "Disconnect",