import { css, cx } from '@emotion/css'; import { uniq } from 'lodash'; import React, { memo, useEffect, useState } from 'react'; import { DataSourceApi, GrafanaTheme2 } from '@grafana/data/src'; import { getDataSourceSrv } from '@grafana/runtime/src'; import { Icon, Tooltip } from '@grafana/ui'; import { Badge, IconButton, useStyles2 } from '@grafana/ui/src'; import { useAppNotification } from '../../../core/copy/appNotification'; import { getSavedQuerySrv } from '../api/SavedQueriesSrv'; import { QueryItem } from '../types'; import { implementationComingSoonAlert } from '../utils'; import { QueryEditorDrawer } from './QueryEditorDrawer'; type QueryListItemProps = { query: QueryItem; showModal: (component: React.ComponentType, props: T) => void; hideModal: () => void; updateComponent: () => void; author: string; date: string; }; const options = { type: 'edit', } as const; export const QueryListItem = memo( ({ query, showModal, hideModal, updateComponent, author, date }: QueryListItemProps) => { const notifyApp = useAppNotification(); const styles = useStyles2(getStyles); const [dsInfo, setDsInfo] = useState([]); useEffect(() => { const getQueryDsInstance = async () => { const uniqueUids = uniq(query?.ds_uid ?? []); setDsInfo((await Promise.all(uniqueUids.map((dsUid) => getDataSourceSrv().get(dsUid)))).filter(Boolean)); }; getQueryDsInstance(); }, [query.ds_uid]); const closeDrawer = () => { hideModal(); updateComponent(); }; const openDrawer = async () => { const result = await getSavedQuerySrv().getSavedQueries([{ uid: query.uid }]); const savedQuery = result[0]; showModal(QueryEditorDrawer, { onDismiss: closeDrawer, savedQuery: savedQuery, options }); }; const deleteQuery = async () => { await getSavedQuerySrv().deleteSavedQuery({ uid: query.uid }); updateComponent(); }; const getDsType = () => { const dsType = dsInfo?.length > 1 ? 'mixed' : dsInfo?.[0]?.type ?? 'datasource'; return startWithUpperCase(dsType); }; const startWithUpperCase = (dsType: string) => { return dsType.charAt(0).toUpperCase() + dsType.slice(1); }; const getTooltip = () => { return (
    {dsInfo.map((dsI, key) => { return (
  • datasource   {startWithUpperCase(dsI.type)}
  • ); })}
); }; const copyToClipboard = async () => { const models = await getSavedQuerySrv().getSavedQueries([{ uid: query.uid }]); if (!models?.length) { implementationComingSoonAlert(); return; } await navigator.clipboard.writeText( JSON.stringify( { ...models[0], uid: undefined, storageOptions: undefined, }, null, 2 ) ); notifyApp.success('Query JSON copied to clipboard!'); }; return ( {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions*/} {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions*/} {query.title} {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions*/} datasource   {getDsType()}  {getDsType() === 'Mixed' && ( )} {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions*/} {`Avatar   {author} {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions*/} {date} ); } ); QueryListItem.displayName = 'QueryListItem'; const getStyles = (theme: GrafanaTheme2) => { return { row: css` height: 70px; cursor: pointer; `, tableTr: css` display: flex; justify-content: space-between; margin-top: 22px; `, disabled: css` color: ${theme.colors.text.secondary}; `, gitIcon: css` width: 30px; height: 30px; margin-left: 10px; margin-top: 1px; opacity: 0.8; `, infoIcon: css` margin-top: -2px; `, dsTooltipIcon: css` width: 11px; height: 11px; `, dsIcon: css` width: 16px !important; height: 16px !important; `, dsTooltipList: css` list-style-type: none; `, }; };