Skip to content

Commit 4711321

Browse files
authored
feat(aci): Add custom datasets for detectors (#94800)
We were using discover datasets for metric detectors which helped us quickly demo how we can reuse their configurations to populate the dropdowns for metric aggregate options. Some differences between widgets and detectors - Their functions expect a WidgetQuery object - We don't really use the pageFiltersStore as our source of truth, all of their stuff does and hooks/contexts directly read from the store - We can avoid making contexts that only wrap react query - We might have a different set of allowed functions and tags or default queries - Transforming to a graph series for us is different and needs to be exported for chartcuterie
1 parent 99c748b commit 4711321

17 files changed

+608
-233
lines changed

static/app/views/detectors/components/forms/metric/getDatasetConfig.tsx

Lines changed: 0 additions & 28 deletions
This file was deleted.

static/app/views/detectors/components/forms/metric/metric.tsx

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,12 @@ import {
2323
import type {Detector} from 'sentry/types/workflowEngine/detectors';
2424
import {generateFieldAsString} from 'sentry/utils/discover/fields';
2525
import useOrganization from 'sentry/utils/useOrganization';
26-
import useProjects from 'sentry/utils/useProjects';
2726
import {
2827
AlertRuleSensitivity,
2928
AlertRuleThresholdType,
3029
} from 'sentry/views/alerts/rules/metric/types';
3130
import {AssigneeField} from 'sentry/views/detectors/components/forms/assigneeField';
3231
import {EditDetectorLayout} from 'sentry/views/detectors/components/forms/editDetectorLayout';
33-
import {getDatasetConfig} from 'sentry/views/detectors/components/forms/metric/getDatasetConfig';
3432
import type {MetricDetectorFormData} from 'sentry/views/detectors/components/forms/metric/metricFormData';
3533
import {
3634
DetectorDataset,
@@ -40,51 +38,19 @@ import {
4038
import {Visualize} from 'sentry/views/detectors/components/forms/metric/visualize';
4139
import {NewDetectorLayout} from 'sentry/views/detectors/components/forms/newDetectorLayout';
4240
import {SectionLabel} from 'sentry/views/detectors/components/forms/sectionLabel';
41+
import {getDatasetConfig} from 'sentry/views/detectors/datasetConfig/getDatasetConfig';
4342
import {getResolutionDescription} from 'sentry/views/detectors/utils/getDetectorResolutionDescription';
4443
import {getStaticDetectorThresholdSuffix} from 'sentry/views/detectors/utils/metricDetectorSuffix';
45-
import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext';
46-
import {TraceItemDataset} from 'sentry/views/explore/types';
47-
48-
function MetricDetectorFormContext({children}: {children: React.ReactNode}) {
49-
const projectId = useMetricDetectorFormField(METRIC_DETECTOR_FORM_FIELDS.projectId);
50-
const dataset = useMetricDetectorFormField(METRIC_DETECTOR_FORM_FIELDS.dataset);
51-
const {projects} = useProjects();
52-
53-
const traceItemProjects = useMemo(() => {
54-
const project = projects.find(p => p.id === projectId);
55-
if (!project) {
56-
return undefined;
57-
}
58-
return [project];
59-
}, [projectId, projects]);
60-
61-
let traceItemType = TraceItemDataset.SPANS;
62-
if (dataset === DetectorDataset.LOGS) {
63-
traceItemType = TraceItemDataset.LOGS;
64-
}
65-
66-
return (
67-
<TraceItemAttributeProvider
68-
traceItemType={traceItemType}
69-
projects={traceItemProjects}
70-
enabled
71-
>
72-
{children}
73-
</TraceItemAttributeProvider>
74-
);
75-
}
7644

7745
function MetricDetectorForm() {
7846
return (
79-
<MetricDetectorFormContext>
80-
<FormStack>
81-
<DetectSection />
82-
<PrioritizeSection />
83-
<ResolveSection />
84-
<AssignSection />
85-
<AutomateSection />
86-
</FormStack>
87-
</MetricDetectorFormContext>
47+
<FormStack>
48+
<DetectSection />
49+
<PrioritizeSection />
50+
<ResolveSection />
51+
<AssignSection />
52+
<AutomateSection />
53+
</FormStack>
8854
);
8955
}
9056

static/app/views/detectors/components/forms/metric/queryFilterBuilder.tsx

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,41 @@ import {Tooltip} from 'sentry/components/core/tooltip';
66
import FormContext from 'sentry/components/forms/formContext';
77
import {t} from 'sentry/locale';
88
import {space} from 'sentry/styles/space';
9-
import type {PageFilters} from 'sentry/types/core';
10-
import type {WidgetQuery} from 'sentry/views/dashboards/types';
11-
import {getDatasetConfig} from 'sentry/views/detectors/components/forms/metric/getDatasetConfig';
9+
import {DiscoverDatasets} from 'sentry/utils/discover/types';
10+
import {unreachable} from 'sentry/utils/unreachable';
1211
import {
12+
DetectorDataset,
1313
METRIC_DETECTOR_FORM_FIELDS,
1414
useMetricDetectorFormField,
1515
} from 'sentry/views/detectors/components/forms/metric/metricFormData';
1616
import {
1717
SectionLabel,
1818
SectionLabelSecondary,
1919
} from 'sentry/views/detectors/components/forms/sectionLabel';
20+
import {getDatasetConfig} from 'sentry/views/detectors/datasetConfig/getDatasetConfig';
21+
22+
function getDiscoverDataset(dataset: DetectorDataset): DiscoverDatasets {
23+
switch (dataset) {
24+
case DetectorDataset.ERRORS:
25+
return DiscoverDatasets.ERRORS;
26+
case DetectorDataset.TRANSACTIONS:
27+
return DiscoverDatasets.TRANSACTIONS;
28+
case DetectorDataset.SPANS:
29+
return DiscoverDatasets.SPANS_EAP;
30+
case DetectorDataset.LOGS:
31+
return DiscoverDatasets.OURLOGS;
32+
case DetectorDataset.RELEASES:
33+
return DiscoverDatasets.DISCOVER;
34+
default:
35+
unreachable(dataset);
36+
return DiscoverDatasets.ERRORS;
37+
}
38+
}
2039

2140
export function DetectorQueryFilterBuilder() {
2241
const currentQuery = useMetricDetectorFormField(METRIC_DETECTOR_FORM_FIELDS.query);
2342
const dataset = useMetricDetectorFormField(METRIC_DETECTOR_FORM_FIELDS.dataset);
2443
const projectId = useMetricDetectorFormField(METRIC_DETECTOR_FORM_FIELDS.projectId);
25-
const environment = useMetricDetectorFormField(METRIC_DETECTOR_FORM_FIELDS.environment);
2644
const formContext = useContext(FormContext);
2745

2846
const datasetConfig = useMemo(() => getDatasetConfig(dataset), [dataset]);
@@ -32,33 +50,12 @@ export function DetectorQueryFilterBuilder() {
3250
formContext.form?.setValue(METRIC_DETECTOR_FORM_FIELDS.query, queryString);
3351
};
3452

35-
// Create mock page filters using form data
36-
const mockPageFilters = useMemo(
37-
(): PageFilters => ({
38-
projects: projectId ? [parseInt(projectId, 10)] : [],
39-
environments: environment ? [environment] : [],
40-
datetime: {
41-
start: null,
42-
end: null,
43-
period: '24h',
44-
utc: false,
45-
},
46-
}),
47-
[projectId, environment]
48-
);
49-
50-
// Create a mock widget query for the SearchBar
51-
const widgetQuery = useMemo(
52-
(): WidgetQuery => ({
53-
conditions: currentQuery || '',
54-
aggregates: [],
55-
columns: [],
56-
fieldAliases: [],
57-
name: '',
58-
orderby: '',
59-
}),
60-
[currentQuery]
61-
);
53+
const projectIds = useMemo(() => {
54+
if (projectId) {
55+
return [Number(projectId)];
56+
}
57+
return [];
58+
}, [projectId]);
6259

6360
return (
6461
<Flex direction="column" gap={space(0.5)} flex={1}>
@@ -75,14 +72,11 @@ export function DetectorQueryFilterBuilder() {
7572
</div>
7673
<QueryFieldRowWrapper>
7774
<SearchBar
78-
pageFilters={mockPageFilters}
79-
onClose={(field: string) => {
80-
handleQueryChange(field);
81-
}}
75+
initialQuery={currentQuery}
76+
projectIds={projectIds}
77+
onClose={handleQueryChange}
8278
onSearch={handleQueryChange}
83-
widgetQuery={widgetQuery}
84-
portalTarget={document.body}
85-
getFilterWarning={() => null}
79+
dataset={getDiscoverDataset(dataset)}
8680
/>
8781
</QueryFieldRowWrapper>
8882
</Flex>

0 commit comments

Comments
 (0)