Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
4195312
Add compose_discover flyout baseline from prototype
jasonrhodes May 11, 2026
926d48e
A2: Stepped form state & types (UI-state reducer, SandboxTabConfig)
jasonrhodes May 11, 2026
8e2f347
Add useCreateRule hook
jasonrhodes May 11, 2026
acfab42
RHF migration: split form values from UI state, wire create/edit API
jasonrhodes May 11, 2026
c75f23c
Use exported field groups in form steps (RuleDetailsFieldGroup, RuleE…
jasonrhodes May 11, 2026
beb2514
Wire edit mode and create/update mutations in rules list page
jasonrhodes May 11, 2026
4b1a1f4
Simplify to single editor: remove tracking, split, and recovery condi…
jasonrhodes May 11, 2026
118f935
Fix critical bugs: RHF bridge, stubs, console.debug, Quick Edit repla…
jasonrhodes May 11, 2026
2c7aacb
Remove HorizontalMinimalStepper from PR B — ships in PR A separately
jasonrhodes May 12, 2026
ca7ac1c
Route form steps by index, not string title
jasonrhodes May 12, 2026
0fc4e80
Fix useEsqlAutocomplete provider lifecycle — remove module-level sing…
jasonrhodes May 12, 2026
9e4b2ef
Fix misleading row count display in Discover Sandbox
jasonrhodes May 12, 2026
9e5c46a
Use 'results' label to match Discover — ES|QL has no total count
jasonrhodes May 12, 2026
a18e547
Persist Sandbox date range across open/close
jasonrhodes May 12, 2026
31f592a
Remove ComposeDiscoverTabs — dead code in this PR
jasonrhodes May 12, 2026
d7e2839
Remove dead tabConfig prop from ComposeDiscoverChild
jasonrhodes May 12, 2026
dcada55
Remove dead guessRecoveryBlock export from use_heuristic_split
jasonrhodes May 12, 2026
7df6094
Assign split-query completion refs during render, not in useEffect
jasonrhodes May 12, 2026
7dc3962
Changes from node scripts/lint_ts_projects --fix
kibanamachine May 12, 2026
ea6e3c3
Changes from node scripts/regenerate_moon_projects.js --update
kibanamachine May 12, 2026
8d102a1
Changes from node scripts/eslint_all_files --no-cache --fix
kibanamachine May 12, 2026
11c5aff
Complete RHF migration: remove all form-value fields from reducer
jasonrhodes May 12, 2026
b35db53
Changes from node scripts/eslint_all_files --no-cache --fix
kibanamachine May 12, 2026
ab2ae8a
Restore Create rule button to full path navigation
jasonrhodes May 12, 2026
72aa288
Hoist useEsqlAutocomplete to flyout to prevent provider stacking
jasonrhodes May 12, 2026
445bafb
Gate step advancement on validation
jasonrhodes May 12, 2026
739e82c
Remove sample query from create mode initial state
jasonrhodes May 12, 2026
2c524dd
Delete Quick Edit Scout tests
jasonrhodes May 12, 2026
fb1945b
Changes from node scripts/eslint_all_files --no-cache --fix
kibanamachine May 12, 2026
30726ce
Use basePath.prepend for Create rule href
jasonrhodes May 12, 2026
9265e85
Reorder Sandbox toolbar: time field → date picker → Search
jasonrhodes May 12, 2026
30c743a
Replace two-button create layout with split button
jasonrhodes May 12, 2026
f50ed35
Changes from node scripts/eslint_all_files --no-cache --fix
kibanamachine May 12, 2026
2acfdc0
Remove YAML mode — deferred to follow-up PR
jasonrhodes May 12, 2026
471ef64
Restore useMemo import after YAML removal
jasonrhodes May 12, 2026
daf6a3e
Auto-select timefield when index has no matching date field
jasonrhodes May 12, 2026
d4e4c1d
Timefield selector shows only real index fields; resets on clear
jasonrhodes May 12, 2026
5c62ca1
Update create button test for EuiSplitButton
jasonrhodes May 12, 2026
9d50ab4
Rename fullQuery → sandbox.query; seed from rule in edit mode
jasonrhodes May 12, 2026
6ea8457
Guard metadata.tags against undefined in rule mapper
jasonrhodes May 12, 2026
e0470e7
Fix injectTimeFilter for single-line queries
jasonrhodes May 12, 2026
d0e117f
Remove duplicate result count above data grid
jasonrhodes May 12, 2026
a9c701e
Inline schedule and lookback fields into Alert Condition step
jasonrhodes May 12, 2026
78825f5
Import ESQL_LANG_ID/ESQLLang/monaco from @kbn/code-editor
jasonrhodes May 12, 2026
c9b5d0c
Pull services from context in chart and child components
jasonrhodes May 12, 2026
66f17ed
Remove MAX_ROWS client-side slice
jasonrhodes May 12, 2026
c4b2d2e
Guard suggest() in split query completion provider
jasonrhodes May 12, 2026
68c6a0d
Group fields: output column options + auto-populate from STATS BY
jasonrhodes May 12, 2026
1086964
Use AST parser for injectTimeFilter instead of regex
jasonrhodes May 12, 2026
fb322be
Changes from node scripts/lint_ts_projects --fix
kibanamachine May 12, 2026
eb0ab9c
Changes from node scripts/regenerate_moon_projects.js --update
kibanamachine May 12, 2026
5bd7f2a
Changes from node scripts/eslint_all_files --no-cache --fix
kibanamachine May 12, 2026
022356d
Merge branch 'main' into rna/pr-b-rhf-form
baileycash-elastic May 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React, { useEffect, useMemo, useRef, useState } from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiLoadingChart } from '@elastic/eui';
import { getESQLAdHocDataview } from '@kbn/esql-utils';
import { esFieldTypeToKibanaFieldType } from '@kbn/field-types';
import type { TypedLensByValueInput } from '@kbn/lens-plugin/public';
import type { DatatableColumn } from '@kbn/expressions-plugin/common';
import { getLensAttributesFromSuggestion, ChartType } from '@kbn/visualization-utils';
import { useRuleFormServices } from '../../form/contexts/rule_form_context';
import type { QueryColumn } from './use_query_execution';

const CHART_HEIGHT = 180;

interface ComposeDiscoverChartProps {
query: string;
timeField: string;
timeRange: { from: string; to: string };
columns: QueryColumn[];
}
Comment on lines +20 to +25
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: lens and dataViews can be pulled from context instead of being passed as props.

Both are already provided by RuleFormContext (via useRuleFormServices()), so the component can grab them internally rather than having the caller thread them through.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in c9b5d0c — both chart and child now call useRuleFormServices() directly.


const toDatatableColumns = (columns: QueryColumn[]): DatatableColumn[] =>
columns.map(
(col) =>
({
id: col.id,
name: col.id,
meta: { type: esFieldTypeToKibanaFieldType(col.esType), esType: col.esType },
} as DatatableColumn)
);

export const ComposeDiscoverChart: React.FC<ComposeDiscoverChartProps> = ({
query,
timeField,
timeRange,
columns,
}) => {
const { lens, dataViews } = useRuleFormServices();
const [lensAttributes, setLensAttributes] = useState<
TypedLensByValueInput['attributes'] | undefined
>(undefined);
const [isLoading, setIsLoading] = useState(false);

const datatableColumnsRef = useRef<DatatableColumn[]>([]);
datatableColumnsRef.current = useMemo(() => toDatatableColumns(columns), [columns]);

useEffect(() => {
if (!query.trim() || !timeField.trim() || columns.length === 0) {
setLensAttributes(undefined);
return;
}

let cancelled = false;
setIsLoading(true);

const run = async () => {
try {
const { suggestions } = await lens.stateHelperApi();
if (cancelled) return;

const adHocDataView = await getESQLAdHocDataview({
dataViewsService: dataViews,
query,
});
if (cancelled) return;

adHocDataView.timeFieldName = timeField;

const context = {
dataViewSpec: adHocDataView.toSpec(),
fieldName: '',
textBasedColumns: datatableColumnsRef.current,
query: { esql: query },
};

const allSuggestions =
suggestions(context, adHocDataView, ['lnsDatatable'], ChartType.Bar) ?? [];

const chartSuggestions = allSuggestions.filter(
(s) => s.visualizationId && s.visualizationId !== 'lnsDatatable'
);

if (!cancelled) {
if (chartSuggestions[0]) {
const attrs = getLensAttributesFromSuggestion({
filters: [],
query: { esql: query },
suggestion: chartSuggestions[0],
dataView: adHocDataView,
});
setLensAttributes(attrs as TypedLensByValueInput['attributes']);
} else {
setLensAttributes(undefined);
}
setIsLoading(false);
}
} catch {
if (!cancelled) {
setLensAttributes(undefined);
setIsLoading(false);
}
}
};

run();
return () => {
cancelled = true;
};
}, [query, timeField, columns, lens, dataViews]);

if (isLoading && !lensAttributes) {
return (
<EuiFlexGroup style={{ height: CHART_HEIGHT }} justifyContent="center" alignItems="center">
<EuiFlexItem grow={false}>
<EuiLoadingChart size="l" />
</EuiFlexItem>
</EuiFlexGroup>
);
}

if (!lensAttributes) return null;

const LensComponent = lens.EmbeddableComponent;

return (
<div style={{ height: CHART_HEIGHT, width: '100%' }}>
<LensComponent
id="composeDiscoverChart"
viewMode="view"
timeRange={timeRange}
attributes={lensAttributes}
noPadding
disableTriggers
/>
</div>
);
};
Loading
Loading