Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Alerting] Improve creation and editing of "Elasticsearch query" rule in Management #134763

Merged
merged 67 commits into from
Jul 7, 2022
Merged
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
6d7f00d
[Alerting][Discover] Add query form type selection for ES query
jughosta Jun 20, 2022
b27a92c
[Alerting] Add labels
jughosta Jun 20, 2022
10c4ed0
[Alerting] Unify common rule expressiosn
jughosta Jun 21, 2022
6f2d4b6
[Alerting] Fix code style
jughosta Jun 21, 2022
1873c56
[Alerting] More refactoring
jughosta Jun 21, 2022
baa0b29
[Alerting] Show different UI based on user choice
jughosta Jun 22, 2022
bb7e0f1
[Alerting] Improve validation and reset rule params when view changes
jughosta Jun 22, 2022
f03a99a
Resolve conflicts
jughosta Jun 22, 2022
38c5bfb
Merge branch 'main' into 134183-alert-management
kibanamachine Jun 22, 2022
d64ceca
[Alerting] Fix button color
jughosta Jun 22, 2022
c3638ea
[Alerting] Revert tmp changes
jughosta Jun 22, 2022
1f6df47
[Alerting] Fix query input
jughosta Jun 22, 2022
01fed98
[Alerting] Fix thresholdComparator and timeWindowUnit changes
jughosta Jun 22, 2022
9906708
[Alerting] Unify UI for different query form types
jughosta Jun 22, 2022
a92802b
[Alerting] Clean up translations
jughosta Jun 22, 2022
c81e760
[Alerting] Fix for tests
jughosta Jun 23, 2022
f5d4f13
[Alerting] Update help tooltips
jughosta Jun 23, 2022
a95db6d
[Alerting] Preselect a default data view
jughosta Jun 23, 2022
71c801e
[Alerting] Add validation tests
jughosta Jun 23, 2022
2ede803
[Alerting] Add more tests
jughosta Jun 23, 2022
ba7dbd3
Merge branch 'main' into 134183-alert-management
kibanamachine Jun 24, 2022
f890da1
[Alerting] Add the smaller title
jughosta Jun 24, 2022
1f57bb5
[Alerting] Fix localization bug
jughosta Jun 24, 2022
e5286ae
[Alerting] Fix rules editing view
jughosta Jun 24, 2022
176bfdc
[Alerting] Fix layout for mobile
jughosta Jun 24, 2022
7f0a248
Merge branch 'main' into 134183-alert-management
kibanamachine Jun 24, 2022
19a0deb
Merge branch 'main' into 134183-alert-management
kibanamachine Jun 24, 2022
4686e08
Merge branch 'main' into 134183-alert-management
kibanamachine Jun 24, 2022
73f512a
Merge branch 'main' into 134183-alert-management
kibanamachine Jun 27, 2022
ef4eb77
[Alerting] Address PR comments
jughosta Jun 27, 2022
d238453
[Discover] unify searchType and formType
dimaanj Jun 27, 2022
1bfbe98
[Alerting] Allow to create new data views from Data View Expression
jughosta Jun 28, 2022
3965032
[Alerting] Fix lint issue
jughosta Jun 28, 2022
b6972ab
Merge branch '134183-alert-management' of https://github.com/jughosta…
dimaanj Jun 28, 2022
5f66599
[Discover] fix management and discover views
dimaanj Jun 28, 2022
7571577
[Discover] remove redundant prop
dimaanj Jun 28, 2022
660cb6f
[Alerting] Add validation message when query type is not selected yet
jughosta Jun 28, 2022
07c185f
Merge remote-tracking branch 'dima/134183-alert-management' into 1341…
jughosta Jun 28, 2022
5a2c154
[Alerting] Update validations
jughosta Jun 28, 2022
d5fd714
[Alerting] Update tests
jughosta Jun 28, 2022
763da99
[Alerting] Update tests
jughosta Jun 28, 2022
6bff722
[Alerting] Update tests
jughosta Jun 28, 2022
8d9daec
[Alerting] Prioritize index errors
jughosta Jun 28, 2022
ae53bb0
Merge branch 'main' into 134183-alert-management
kibanamachine Jun 28, 2022
79fefd0
[Alerting] Fix size validation
jughosta Jun 28, 2022
b6dd854
[Alerting] Fix timeWindowSize validation
jughosta Jun 28, 2022
b174aaa
[Alerting] Address CI issues
jughosta Jun 28, 2022
24c2f04
Merge branch 'main' into 134183-alert-management
kibanamachine Jun 28, 2022
1646703
Merge branch 'main' into 134183-alert-management
kibanamachine Jun 28, 2022
de47a00
Merge remote-tracking branch 'upstream/main' into 134183-alert-manage…
jughosta Jun 28, 2022
36ac022
Address plugins concurrency effect on sample data server API
jughosta Jun 29, 2022
6191091
Merge remote-tracking branch 'upstream/main' into 134183-alert-manage…
jughosta Jun 30, 2022
7b3e255
[Alerting] Remove deprecated strings
jughosta Jun 30, 2022
6c4aaee
[Alerting] Update copy and spacing
jughosta Jun 30, 2022
79d7ee9
[Alerting] Cleanup translations
jughosta Jun 30, 2022
9452d3d
[Alerting] Unify labels key
jughosta Jun 30, 2022
e202725
[Alerting] Update copy
jughosta Jun 30, 2022
f5a8a31
[Alerting] Update copy key
jughosta Jun 30, 2022
0aae012
[Alerting] Bring back the original label
jughosta Jun 30, 2022
012e558
Merge remote-tracking branch 'upstream/main' into 134183-alert-manage…
jughosta Jul 4, 2022
4adac03
[Alerting] Update after the merge
jughosta Jul 4, 2022
20a2ad3
[Alerting] Update validation message
jughosta Jul 4, 2022
12ec63e
[Alerting] Update styles for Create a data view button
jughosta Jul 4, 2022
27451c2
[Alerting] Add message about missing privilieges
jughosta Jul 4, 2022
2c10e79
Merge branch 'main' into 134183-alert-management
kibanamachine Jul 6, 2022
fd61f43
[Alerting] Reduce padding in data view selector
jughosta Jul 6, 2022
5c27116
[Alerting] Update copy
jughosta Jul 7, 2022
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
Expand Up @@ -6,6 +6,7 @@
* Side Public License, v 1.
*/

import { sortBy } from 'lodash';
import type { IRouter, Logger, RequestHandlerContext } from '@kbn/core/server';
import type { AppLinkData, SampleDatasetSchema } from '../lib/sample_dataset_registry_types';
import { createIndexName } from '../lib/create_index_name';
Expand Down Expand Up @@ -55,7 +56,7 @@ export const createListRoute = (
previewImagePath: sampleDataset.previewImagePath,
darkPreviewImagePath: sampleDataset.darkPreviewImagePath,
overviewDashboard: findObjectId('dashboard', sampleDataset.overviewDashboard),
appLinks,
appLinks: sortBy(appLinks, 'order'),
defaultIndex: findObjectId('index-pattern', sampleDataset.defaultIndex),
dataIndices: sampleDataset.dataIndices.map(({ id }) => ({ id })),
...sampleDataStatus,
Expand Down
20 changes: 16 additions & 4 deletions test/api_integration/apis/home/sample_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export default function ({ getService }: FtrProviderContext) {
const FLIGHTS_CANVAS_APPLINK_PATH =
'/app/canvas#/workpad/workpad-a474e74b-aedc-47c3-894a-db77e62c41e0'; // includes default ID of the flights canvas applink path

const includesPathInAppLinks = (appLinks: Array<{ path: string }>, path: string): boolean => {
return appLinks.some((item) => item.path === path);
};

describe('sample data apis', () => {
before(async () => {
await esArchiver.emptyKibanaIndex();
Expand All @@ -41,7 +45,9 @@ export default function ({ getService }: FtrProviderContext) {
// Check and make sure the sample dataset reflects the default object IDs, because no sample data objects exist.
// Instead of checking each object ID, we check the dashboard and canvas app link as representatives.
expect(flightsData.overviewDashboard).to.be(FLIGHTS_OVERVIEW_DASHBOARD_ID);
expect(flightsData.appLinks[0].path).to.be(FLIGHTS_CANVAS_APPLINK_PATH);
expect(includesPathInAppLinks(flightsData.appLinks, FLIGHTS_CANVAS_APPLINK_PATH)).to.be(
true
);
});
});

Expand Down Expand Up @@ -109,11 +115,15 @@ export default function ({ getService }: FtrProviderContext) {
// Instead of checking each object ID, we check the dashboard and canvas app link as representatives.
if (space === 'default') {
expect(flightsData.overviewDashboard).to.be(FLIGHTS_OVERVIEW_DASHBOARD_ID);
expect(flightsData.appLinks[0].path).to.be(FLIGHTS_CANVAS_APPLINK_PATH);
expect(includesPathInAppLinks(flightsData.appLinks, FLIGHTS_CANVAS_APPLINK_PATH)).to.be(
true
);
} else {
// the sample data objects installed in the 'other' space had their IDs regenerated upon import
expect(flightsData.overviewDashboard).not.to.be(FLIGHTS_OVERVIEW_DASHBOARD_ID);
expect(flightsData.appLinks[0].path).not.to.be(FLIGHTS_CANVAS_APPLINK_PATH);
expect(includesPathInAppLinks(flightsData.appLinks, FLIGHTS_CANVAS_APPLINK_PATH)).to.be(
false
);
}
});
});
Expand Down Expand Up @@ -145,7 +155,9 @@ export default function ({ getService }: FtrProviderContext) {
// Check and make sure the sample dataset reflects the default object IDs, because no sample data objects exist.
// Instead of checking each object ID, we check the dashboard and canvas app link as representatives.
expect(flightsData.overviewDashboard).to.be(FLIGHTS_OVERVIEW_DASHBOARD_ID);
expect(flightsData.appLinks[0].path).to.be(FLIGHTS_CANVAS_APPLINK_PATH);
expect(includesPathInAppLinks(flightsData.appLinks, FLIGHTS_CANVAS_APPLINK_PATH)).to.be(
true
);
});
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@

import React from 'react';
import { mountWithIntl, nextTick } from '@kbn/test-jest-helpers';
import { DataViewSelectPopover } from './data_view_select_popover';
import { DataViewSelectPopover, DataViewSelectPopoverProps } from './data_view_select_popover';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks';
import { act } from 'react-dom/test-utils';

const props = {
const props: DataViewSelectPopoverProps = {
onSelectDataView: () => {},
initialDataViewTitle: 'kibana_sample_data_logs',
initialDataViewId: 'mock-data-logs-id',
dataViewName: 'kibana_sample_data_logs',
dataViewId: 'mock-data-logs-id',
};

const dataViewOptions = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,76 @@
* 2.0.
*/

import React, { useCallback, useEffect, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { i18n } from '@kbn/i18n';
import {
EuiButtonEmpty,
EuiButtonIcon,
EuiExpression,
EuiFlexGroup,
EuiFlexItem,
EuiFormRow,
EuiPopover,
EuiPopoverFooter,
EuiPopoverTitle,
} from '@elastic/eui';
import { DataViewsList } from '@kbn/unified-search-plugin/public';
import { DataViewListItem } from '@kbn/data-views-plugin/public';
import { useTriggersAndActionsUiDeps } from '../es_query/util';

interface DataViewSelectPopoverProps {
export interface DataViewSelectPopoverProps {
onSelectDataView: (newDataViewId: string) => void;
initialDataViewTitle: string;
initialDataViewId?: string;
dataViewName?: string;
dataViewId?: string;
}

export const DataViewSelectPopover: React.FunctionComponent<DataViewSelectPopoverProps> = ({
onSelectDataView,
initialDataViewTitle,
initialDataViewId,
dataViewName,
dataViewId,
}) => {
const { data } = useTriggersAndActionsUiDeps();
const { data, dataViewEditor } = useTriggersAndActionsUiDeps();
const [dataViewItems, setDataViewsItems] = useState<DataViewListItem[]>();
const [dataViewPopoverOpen, setDataViewPopoverOpen] = useState(false);

const [selectedDataViewId, setSelectedDataViewId] = useState(initialDataViewId);
const [selectedTitle, setSelectedTitle] = useState<string>(initialDataViewTitle);
const closeDataViewEditor = useRef<() => void | undefined>();

const loadDataViews = useCallback(async () => {
const fetchedDataViewItems = await data.dataViews.getIdsWithTitle();
setDataViewsItems(fetchedDataViewItems);
}, [setDataViewsItems, data.dataViews]);

const closeDataViewPopover = useCallback(() => setDataViewPopoverOpen(false), []);

const createDataView = useMemo(
() =>
dataViewEditor?.userPermissions.editDataView()
Copy link
Contributor

Choose a reason for hiding this comment

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

When I create a user who can create stack rules but has no access to create data views and I have no data views available, I see this:
Screen Shot 2022-06-30 at 1 12 03 PM

Wondering if there should be any helper text about needing the right privileges to create data views?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added the following message to the popover. Wdyt @ymao1 @gchaps ?
cc @andreadelrio

Screenshot 2022-07-04 at 15 25 45

Copy link
Contributor

Choose a reason for hiding this comment

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

Here is my suggestion:

You need additional privileges to create data views. Contact your administrator.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@gchaps Thanks Gail! Updated the copy.

? () => {
closeDataViewEditor.current = dataViewEditor.openEditor({
onSave: async (createdDataView) => {
if (createdDataView.id) {
await onSelectDataView(createdDataView.id);
await loadDataViews();
}
},
});
}
: undefined,
[dataViewEditor, onSelectDataView, loadDataViews]
);

useEffect(() => {
const initDataViews = async () => {
const fetchedDataViewItems = await data.dataViews.getIdsWithTitle();
setDataViewsItems(fetchedDataViewItems);
return () => {
// Make sure to close the editor when unmounting
if (closeDataViewEditor.current) {
closeDataViewEditor.current();
}
};
initDataViews();
}, [data.dataViews]);
}, []);

const closeDataViewPopover = useCallback(() => setDataViewPopoverOpen(false), []);
useEffect(() => {
loadDataViews();
}, [loadDataViews]);

if (!dataViewItems) {
return null;
Expand All @@ -62,12 +90,17 @@ export const DataViewSelectPopover: React.FunctionComponent<DataViewSelectPopove
description={i18n.translate('xpack.stackAlerts.components.ui.alertParams.dataViewLabel', {
defaultMessage: 'data view',
})}
value={selectedTitle}
value={
dataViewName ??
i18n.translate('xpack.stackAlerts.components.ui.alertParams.dataViewPlaceholder', {
defaultMessage: 'Select a data view',
})
}
isActive={dataViewPopoverOpen}
onClick={() => {
setDataViewPopoverOpen(true);
}}
isInvalid={!selectedTitle}
isInvalid={!dataViewId}
/>
}
isOpen={dataViewPopoverOpen}
Expand Down Expand Up @@ -102,18 +135,31 @@ export const DataViewSelectPopover: React.FunctionComponent<DataViewSelectPopove
<DataViewsList
dataViewsList={dataViewItems}
onChangeDataView={(newId) => {
setSelectedDataViewId(newId);
const newTitle = dataViewItems?.find(({ id }) => id === newId)?.title;
if (newTitle) {
setSelectedTitle(newTitle);
}

onSelectDataView(newId);
closeDataViewPopover();
}}
currentDataViewId={selectedDataViewId}
currentDataViewId={dataViewId}
/>
</EuiFormRow>
{createDataView && (
<EuiPopoverFooter>
<EuiButtonEmpty
iconType="plusInCircleFilled"
data-test-subj="chooseDataViewPopover.createDataViewButton"
onClick={() => {
closeDataViewPopover();
createDataView();
}}
>
{i18n.translate(
'xpack.stackAlerts.components.ui.alertParams.dataViewPopover.createDataViewButton',
{
defaultMessage: 'Create a data view',
}
)}
</EuiButtonEmpty>
</EuiPopoverFooter>
)}
</div>
</EuiPopover>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,13 @@ export const IndexSelectPopover: React.FunctionComponent<Props> = ({
description={i18n.translate('xpack.stackAlerts.components.ui.alertParams.indexLabel', {
defaultMessage: 'index',
})}
value={index && index.length > 0 ? renderIndices(index) : firstFieldOption.text}
value={
index && index.length > 0
? renderIndices(index)
: i18n.translate('xpack.stackAlerts.components.ui.alertParams.indexPlaceholder', {
defaultMessage: 'Select an index',
})
}
isActive={indexPopoverOpen}
onClick={() => {
setIndexPopoverOpen(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const EXPRESSION_ERRORS = {
thresholdComparator: new Array<string>(),
timeWindowSize: new Array<string>(),
searchConfiguration: new Array<string>(),
searchType: new Array<string>(),
};

export const EXPRESSION_ERROR_KEYS = Object.keys(EXPRESSION_ERRORS) as ErrorKey[];
Loading