grafana/public/app/features/trails/DataTrailCard.tsx
Torkel Ödegaard 1f1d348e17
DataTrails: Auto query, explore and breakdown/drilldown prototype (#77019)
* First try

* Update

* app with drilldowns

* Progres

* Progress

* update

* Update

* update

* Update

* Update

* Progress

* Update

* Progress

* Update

* Progress

* logs url sync

* related metrics

* Progress

* progress

* Progress

* Update

* Update

* Update

* Update

* Update

* fix

* Update

* update

* Update

* update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* update

* Update

* Update

* Settings

* Update

* Tweaks

* update

* Improve auto queries

* Update

* Update

* Fixes

* Update

* Update

* Update

* fix

* Update

* Removing logs view, cleanup

* Update

* Update

* disabled not implemented buttons

* Update

* Feature toggle on dashboard menu

* remove unused prometheus change

* removed bit

* Fix failing test

* chore: added `/public/app/features/trails/` to CODEOWNERS

* go mod tidy

* go mod tidy

* fix: added missing arg

* Moved panel action

* Moved panel action

---------

Co-authored-by: André Pereira <adrapereira@gmail.com>
Co-authored-by: Darren Janeczek <darren.janeczek@grafana.com>
2023-11-15 11:28:29 +00:00

99 lines
2.7 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 } from '@grafana/ui';
import { DataTrail } from './DataTrail';
import { LOGS_METRIC, VAR_DATASOURCE_EXPR, VAR_FILTERS } from './shared';
export interface Props {
trail: DataTrail;
onSelect: (trail: DataTrail) => void;
}
export function DataTrailCard({ trail, onSelect }: 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.heading}>{getMetricName(trail.state.metric)}</div>
<Stack gap={1.5}>
{dsValue && (
<Stack direction="column" gap={0.5}>
<div className={styles.label}>Datasource</div>
<div className={styles.value}>{getDataSource(trail)}</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 getDataSource(trail: DataTrail) {
return sceneGraph.interpolate(trail, VAR_DATASOURCE_EXPR);
}
function getStyles(theme: GrafanaTheme2) {
return {
container: css({
padding: theme.spacing(1),
flexGrow: 1,
display: 'flex',
flexDirection: 'column',
gap: theme.spacing(2),
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,
}),
body: css({
padding: theme.spacing(0),
}),
};
}