import { css } from '@emotion/css'; import { useMemo } from 'react'; import Skeleton from 'react-loading-skeleton'; import { DataSourceInstanceSettings } from '@grafana/data'; import { config } from '@grafana/runtime'; import { CellProps, Stack, Text, Icon, useStyles2 } from '@grafana/ui'; import { getSvgSize } from '@grafana/ui/src/components/Icon/utils'; import { Trans } from 'app/core/internationalization'; import { useGetFolderQuery } from 'app/features/browse-dashboards/api/browseDashboardsAPI'; import { LocalPlugin } from '../../plugins/admin/types'; import { useGetDashboardByUidQuery, useGetLibraryElementByUidQuery } from '../api'; import { ResourceTableItem } from './types'; export function NameCell(props: CellProps) { const data = props.row.original; return ( ); } function ResourceInfo({ data }: { data: ResourceTableItem }) { switch (data.type) { case 'DASHBOARD': return ; case 'DATASOURCE': return ; case 'FOLDER': return ; case 'LIBRARY_ELEMENT': return ; // Starting from 11.4.x, new resources have both `name` and optionally a `parentName`, so we can use this catch-all component. default: return ; } } function DatasourceInfo({ data }: { data: ResourceTableItem }) { const datasourceUID = data.refId; const datasource = useDatasource(datasourceUID); if (!datasource) { return ( <> Data source {{ datasourceUID }} Unknown data source ); } return ( <> {datasource.name} {datasource.type} ); } function getTitleFromDashboardJSON(dashboardData: object | undefined): string | null { if (dashboardData && 'title' in dashboardData && typeof dashboardData.title === 'string') { return dashboardData.title; } return null; } function DashboardInfo({ data }: { data: ResourceTableItem }) { const dashboardUID = data.refId; const skipApiCall = !!data.name && !!data.parentName; const { data: dashboardData, isLoading, isError, } = useGetDashboardByUidQuery({ uid: dashboardUID }, { skip: skipApiCall }); const dashboardName = data.name || getTitleFromDashboardJSON(dashboardData?.dashboard) || dashboardUID; const dashboardParentName = data.parentName || dashboardData?.meta?.folderTitle || 'Dashboards'; if (isError) { return ( <> Unable to load dashboard Dashboard {dashboardUID} ); } if (isLoading) { return ; } return ( <> {dashboardName} {dashboardParentName} ); } function FolderInfo({ data }: { data: ResourceTableItem }) { const folderUID = data.refId; const skipApiCall = !!data.name && !!data.parentName; const { data: folderData, isLoading, isError } = useGetFolderQuery(folderUID, { skip: skipApiCall }); const folderName = data.name || folderData?.title; const folderParentName = data.parentName || folderData?.parents?.[folderData.parents.length - 1]?.title; if (isError) { return ( <> Unable to load folder Folder {data.refId} ); } if (isLoading) { return ; } return ( <> {folderName} {folderParentName ?? 'Dashboards'} ); } function LibraryElementInfo({ data }: { data: ResourceTableItem }) { const uid = data.refId; const skipApiCall = !!data.name && !!data.parentName; const { data: libraryElementData, isError, isLoading, } = useGetLibraryElementByUidQuery({ libraryElementUid: uid }, { skip: skipApiCall }); const name = data.name || libraryElementData?.result?.name || uid; const parentName = data.parentName || libraryElementData?.result?.meta?.folderName || 'General'; if (isError) { return ( <> Unable to load library element Library Element {uid} ); } if (isLoading) { return ; } return ( <> {name} {parentName} ); } function InfoSkeleton() { return ( <> ); } function BasicResourceInfo({ data }: { data: ResourceTableItem }) { return ( <> {data.name} {data.parentName && {data.parentName}} ); } function ResourceIcon({ resource }: { resource: ResourceTableItem }) { const styles = useStyles2(getIconStyles); 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; } } function getIconStyles() { return { icon: css({ display: 'block', width: getSvgSize('xl'), height: getSvgSize('xl'), }), }; } function useDatasource(datasourceUID: string | undefined): DataSourceInstanceSettings | undefined { const datasource = useMemo(() => { if (!datasourceUID) { return undefined; } return ( config.datasources[datasourceUID] || Object.values(config.datasources).find((ds) => ds.uid === datasourceUID) ); }, [datasourceUID]); return datasource; } function usePluginLogo(plugin: LocalPlugin | undefined): string | undefined { const logos = useMemo(() => { if (!plugin) { return undefined; } return plugin?.info?.logos; }, [plugin]); return logos?.small; }