grafana/public/app/features/trails/DataTrailCard.tsx
Andre Pereira 2c7e95a680
Data Trails: Cleanup and explore+share buttons (#81062)
* Share button works now. Removed add to dashboard button for now

* WIP explore link

* Remove settings dropdown for now

* Use getExploreUrl to generate explore link

* Fix conflicts

* Update betterer

* Navigate to a new trail when the recent trails list is empty

* Address PR comments
2024-01-25 20:06:22 +00:00

114 lines
3.1 KiB
TypeScript

import { css } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { AdHocFiltersVariable, sceneGraph } from '@grafana/scenes';
import { useStyles2, Stack, Tooltip, Button } from '@grafana/ui';
import { DataTrail } from './DataTrail';
import { LOGS_METRIC, VAR_FILTERS } from './shared';
import { getDataSource, getDataSourceName } from './utils';
export interface Props {
trail: DataTrail;
onSelect: (trail: DataTrail) => void;
onDelete?: () => void;
}
export function DataTrailCard({ trail, onSelect, onDelete }: Props) {
const styles = useStyles2(getStyles);
const filtersVariable = sceneGraph.lookupVariable(VAR_FILTERS, trail)!;
if (!(filtersVariable instanceof AdHocFiltersVariable)) {
return null;
}
const filters = filtersVariable.state.set.state.filters;
const dsValue = getDataSource(trail);
return (
<button className={styles.container} onClick={() => onSelect(trail)}>
<div className={styles.wrapper}>
<div className={styles.heading}>{getMetricName(trail.state.metric)}</div>
{onDelete && (
<Tooltip content={'Remove bookmark'}>
<Button size="sm" icon="trash-alt" variant="destructive" fill="text" onClick={onDelete} />
</Tooltip>
)}
</div>
<Stack gap={1.5}>
{dsValue && (
<Stack direction="column" gap={0.5}>
<div className={styles.label}>Datasource</div>
<div className={styles.value}>{getDataSourceName(dsValue)}</div>
</Stack>
)}
{filters.map((filter, index) => (
<Stack key={index} direction="column" gap={0.5}>
<div className={styles.label}>{filter.key}</div>
<div className={styles.value}>{filter.value}</div>
</Stack>
))}
</Stack>
</button>
);
}
function getMetricName(metric?: string) {
if (!metric) {
return 'Select metric';
}
if (metric === LOGS_METRIC) {
return 'Logs';
}
return metric;
}
function getStyles(theme: GrafanaTheme2) {
return {
container: css({
padding: theme.spacing(1),
flexGrow: 1,
display: 'flex',
flexDirection: 'column',
gap: theme.spacing(2),
width: '100%',
border: `1px solid ${theme.colors.border.weak}`,
borderRadius: theme.shape.radius.default,
cursor: 'pointer',
boxShadow: 'none',
background: 'transparent',
textAlign: 'left',
'&:hover': {
background: theme.colors.emphasize(theme.colors.background.primary, 0.03),
},
}),
label: css({
fontWeight: theme.typography.fontWeightMedium,
fontSize: theme.typography.bodySmall.fontSize,
}),
value: css({
fontSize: theme.typography.bodySmall.fontSize,
}),
heading: css({
padding: theme.spacing(0),
display: 'flex',
fontWeight: theme.typography.fontWeightMedium,
overflowX: 'hidden',
}),
body: css({
padding: theme.spacing(0),
}),
wrapper: css({
position: 'relative',
display: 'flex',
gap: theme.spacing.x1,
justifyContent: 'space-between',
width: '100%',
}),
};
}