From f89be4319869dfc3f400965151346c970bcd5028 Mon Sep 17 00:00:00 2001 From: Matej Minar Date: Thu, 16 May 2024 17:41:57 +0200 Subject: [PATCH] feat(metrics): Add guides (#71018) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/getsentry/sentry/assets/9060071/6a5db38c-50ab-4d8a-a40e-458dcb12261c The last step has nicer text if you have Trace Explorer—we add there that you can filter by span-specific tags. Closes https://github.com/getsentry/sentry/issues/70212 --------- Co-authored-by: getsantry[bot] <66042841+getsantry[bot]@users.noreply.github.com> --- .../components/assistant/getGuidesContent.tsx | 59 +++++++++- .../metricWidgetViewerModal/queries.tsx | 1 + static/app/stores/guideStore.tsx | 2 +- static/app/views/metrics/layout.tsx | 2 + static/app/views/metrics/queries.tsx | 18 +-- static/app/views/metrics/queryBuilder.tsx | 105 ++++++++++-------- static/app/views/metrics/widget.tsx | 23 ++-- static/app/views/metrics/widgetDetails.tsx | 7 +- 8 files changed, 150 insertions(+), 67 deletions(-) diff --git a/static/app/components/assistant/getGuidesContent.tsx b/static/app/components/assistant/getGuidesContent.tsx index 57111fe1b67a8..2138e0444d0ab 100644 --- a/static/app/components/assistant/getGuidesContent.tsx +++ b/static/app/components/assistant/getGuidesContent.tsx @@ -3,8 +3,11 @@ import ExternalLink from 'sentry/components/links/externalLink'; import Link from 'sentry/components/links/link'; import {t, tct} from 'sentry/locale'; import ConfigStore from 'sentry/stores/configStore'; +import type {Organization} from 'sentry/types'; -export default function getGuidesContent(orgSlug: string | null): GuidesContent { +export default function getGuidesContent( + organization: Organization | null +): GuidesContent { if (ConfigStore.get('demoMode')) { return getDemoModeGuides(); } @@ -90,7 +93,11 @@ export default function getGuidesContent(orgSlug: string | null): GuidesContent description: tct( `Today only admins in your organization can create alert rules but we recommend [link:allowing members to create alerts], too.`, { - link: , + link: ( + + ), } ), nextText: t('Allow'), @@ -174,6 +181,54 @@ export default function getGuidesContent(orgSlug: string | null): GuidesContent }, ], }, + { + guide: 'metrics_onboarding', + requiredTargets: ['metrics_onboarding'], + steps: [ + { + title: t('Metrics Selector'), + target: 'metrics_selector', + description: t('Your metrics are available here.'), + }, + { + title: t('Aggregate Metrics'), + target: 'metrics_aggregate', + description: t('See different facets of your metric through aggregations.'), + }, + { + title: t('Grouping & Filtering'), + target: 'metrics_groupby', + description: t('Segment or filter your data by the tags you’ve attached.'), + }, + { + title: t('Multiple Metrics'), + target: 'add_metric_query', + description: t('Plot a second metric to see correlations.'), + }, + { + title: t('Visualization'), + target: 'metrics_chart', + description: t( + 'View plotted metrics, dots on the chart represent associated sample spans.' + ), + }, + { + title: t('Span Samples'), + target: 'metrics_table', + description: tct( + 'See sample spans summarized in a table format. [openInTraces]', + { + openInTraces: + organization?.features.includes( + 'performance-trace-explorer-with-metrics' + ) && organization?.features.includes('performance-trace-explorer') + ? t('To filter by tags found only on spans, click "Open in Traces".') + : '', + } + ), + }, + ], + }, ]; } diff --git a/static/app/components/modals/metricWidgetViewerModal/queries.tsx b/static/app/components/modals/metricWidgetViewerModal/queries.tsx index 97f1f83e265ad..5c1fe0a924e92 100644 --- a/static/app/components/modals/metricWidgetViewerModal/queries.tsx +++ b/static/app/components/modals/metricWidgetViewerModal/queries.tsx @@ -124,6 +124,7 @@ export function Queries({ onQueryChange(data, index)} metricsQuery={query} projects={selection.projects} diff --git a/static/app/stores/guideStore.tsx b/static/app/stores/guideStore.tsx index 0bf76e810aeeb..3acbc08db1507 100644 --- a/static/app/stores/guideStore.tsx +++ b/static/app/stores/guideStore.tsx @@ -168,7 +168,7 @@ const storeConfig: GuideStoreDefinition = { return; } - const guidesContent: GuidesContent = getGuidesContent(this.state.orgSlug); + const guidesContent: GuidesContent = getGuidesContent(this.state.organization); // map server guide state (i.e. seen status) with guide content const guides = guidesContent.reduce((acc: Guide[], content) => { const serverGuide = data.find(guide => guide.guide === content.guide); diff --git a/static/app/views/metrics/layout.tsx b/static/app/views/metrics/layout.tsx index defbc826d81c7..c84a970093379 100644 --- a/static/app/views/metrics/layout.tsx +++ b/static/app/views/metrics/layout.tsx @@ -6,6 +6,7 @@ import * as Sentry from '@sentry/react'; import emptyStateImg from 'sentry-images/spot/custom-metrics-empty-state.svg'; import Alert from 'sentry/components/alert'; +import GuideAnchor from 'sentry/components/assistant/guideAnchor'; import FeatureBadge from 'sentry/components/badge/featureBadge'; import Banner from 'sentry/components/banner'; import {Button} from 'sentry/components/button'; @@ -148,6 +149,7 @@ export const MetricsLayout = memo(() => { ) : hasCustomMetrics || isEmptyStateDismissed ? ( + diff --git a/static/app/views/metrics/queries.tsx b/static/app/views/metrics/queries.tsx index e5fb98f449118..8353d8323d3c0 100644 --- a/static/app/views/metrics/queries.tsx +++ b/static/app/views/metrics/queries.tsx @@ -2,6 +2,7 @@ import {Fragment, useCallback, useLayoutEffect, useMemo} from 'react'; import styled from '@emotion/styled'; import * as echarts from 'echarts/core'; +import GuideAnchor from 'sentry/components/assistant/guideAnchor'; import {Button} from 'sentry/components/button'; import SwitchButton from 'sentry/components/switchButton'; import {Tooltip} from 'sentry/components/tooltip'; @@ -118,13 +119,15 @@ export function Queries() { ))} - + + +