Skip to content

Commit 6e59d28

Browse files
Merge branch '7.x' into backport/7.x/pr-102267
2 parents cf65748 + 043f24a commit 6e59d28

17 files changed

Lines changed: 383 additions & 312 deletions

File tree

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
import { act } from 'react-dom/test-utils';
9+
import { setup, SetupResult, getProcessorValue } from './processor.helpers';
10+
11+
const CIRCLE_TYPE = 'circle';
12+
13+
describe('Processor: Circle', () => {
14+
let onUpdate: jest.Mock;
15+
let testBed: SetupResult;
16+
17+
beforeAll(() => {
18+
jest.useFakeTimers();
19+
});
20+
21+
afterAll(() => {
22+
jest.useRealTimers();
23+
});
24+
25+
beforeEach(async () => {
26+
onUpdate = jest.fn();
27+
28+
await act(async () => {
29+
testBed = await setup({
30+
value: {
31+
processors: [],
32+
},
33+
onFlyoutOpen: jest.fn(),
34+
onUpdate,
35+
});
36+
});
37+
testBed.component.update();
38+
const {
39+
actions: { addProcessor, addProcessorType },
40+
} = testBed;
41+
// Open the processor flyout
42+
addProcessor();
43+
44+
// Add type (the other fields are not visible until a type is selected)
45+
await addProcessorType(CIRCLE_TYPE);
46+
});
47+
48+
test('prevents form submission if required fields are not provided', async () => {
49+
const {
50+
actions: { saveNewProcessor },
51+
form,
52+
} = testBed;
53+
54+
// Click submit button with only the type defined
55+
await saveNewProcessor();
56+
57+
// Expect form error as "field" and "shape_type" are required parameters
58+
expect(form.getErrorsMessages()).toEqual([
59+
'A field value is required.',
60+
'A shape type value is required.',
61+
]);
62+
});
63+
64+
test('saves with required parameter values', async () => {
65+
const {
66+
actions: { saveNewProcessor },
67+
form,
68+
} = testBed;
69+
70+
// Add "field" value (required)
71+
form.setInputValue('fieldNameField.input', 'field_1');
72+
// Save the field
73+
form.setSelectValue('shapeSelectorField', 'shape');
74+
// Set the error distance
75+
form.setInputValue('errorDistanceField.input', '10');
76+
77+
await saveNewProcessor();
78+
79+
const processors = getProcessorValue(onUpdate, CIRCLE_TYPE);
80+
81+
expect(processors[0].circle).toEqual({
82+
field: 'field_1',
83+
error_distance: 10,
84+
shape_type: 'shape',
85+
});
86+
});
87+
88+
test('allows optional parameters to be set', async () => {
89+
const {
90+
actions: { saveNewProcessor },
91+
form,
92+
} = testBed;
93+
94+
// Add "field" value (required)
95+
form.setInputValue('fieldNameField.input', 'field_1');
96+
// Select the shape
97+
form.setSelectValue('shapeSelectorField', 'geo_shape');
98+
// Add "target_field" value
99+
form.setInputValue('targetField.input', 'target_field');
100+
101+
form.setInputValue('errorDistanceField.input', '10');
102+
103+
// Save the field with new changes
104+
await saveNewProcessor();
105+
106+
const processors = getProcessorValue(onUpdate, CIRCLE_TYPE);
107+
expect(processors[0].circle).toEqual({
108+
field: 'field_1',
109+
error_distance: 10,
110+
shape_type: 'geo_shape',
111+
target_field: 'target_field',
112+
});
113+
});
114+
});

x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/processor.helpers.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ type TestSubject =
151151
| 'keepOriginalField.input'
152152
| 'removeIfSuccessfulField.input'
153153
| 'targetFieldsField.input'
154+
| 'shapeSelectorField'
155+
| 'errorDistanceField.input'
154156
| 'separatorValueField.input'
155157
| 'quoteValueField.input'
156158
| 'emptyValueField.input'

x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/circle.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ export const Circle: FunctionComponent = () => {
9797
/>
9898

9999
<UseField
100+
data-test-subj="errorDistanceField"
100101
config={fieldsConfig.error_distance}
101102
component={NumericField}
102103
path="fields.error_distance"
@@ -105,6 +106,7 @@ export const Circle: FunctionComponent = () => {
105106
<UseField
106107
componentProps={{
107108
euiFieldProps: {
109+
'data-test-subj': 'shapeSelectorField',
108110
options: [
109111
{
110112
value: 'shape',

x-pack/plugins/translations/translations/ja-JP.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24311,8 +24311,6 @@
2431124311
"xpack.watcher.sections.watchEdit.json.titlePanel.editWatchTitle": "{watchName}を編集",
2431224312
"xpack.watcher.sections.watchEdit.loadingWatchDescription": "ウォッチの読み込み中…",
2431324313
"xpack.watcher.sections.watchEdit.loadingWatchVisualizationDescription": "ウォッチビジュアライゼーションを読み込み中…",
24314-
"xpack.watcher.sections.watchEdit.monitoring.edit.calloutDescriptionText": "ウォッチ'{watchName}'はシステムウォッチであるため、編集できません。{watchStatusLink}",
24315-
"xpack.watcher.sections.watchEdit.monitoring.edit.calloutTitleText": "このウォッチは編集できません。",
2431624314
"xpack.watcher.sections.watchEdit.monitoring.header.watchLinkTitle": "ウォッチステータスを表示します。",
2431724315
"xpack.watcher.sections.watchEdit.simulate.form.actionModesFieldLabel": "アクションモード",
2431824316
"xpack.watcher.sections.watchEdit.simulate.form.actionOverridesDescription": "ウォッチでアクションを実行またはスキップすることができるようにします。{actionsLink}",

x-pack/plugins/translations/translations/zh-CN.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24681,8 +24681,6 @@
2468124681
"xpack.watcher.sections.watchEdit.json.titlePanel.editWatchTitle": "编辑 {watchName}",
2468224682
"xpack.watcher.sections.watchEdit.loadingWatchDescription": "正在加载监视……",
2468324683
"xpack.watcher.sections.watchEdit.loadingWatchVisualizationDescription": "正在加载监视可视化……",
24684-
"xpack.watcher.sections.watchEdit.monitoring.edit.calloutDescriptionText": "监视“{watchName}”为系统监视,无法编辑。{watchStatusLink}",
24685-
"xpack.watcher.sections.watchEdit.monitoring.edit.calloutTitleText": "此监视无法编辑。",
2468624684
"xpack.watcher.sections.watchEdit.monitoring.header.watchLinkTitle": "查看监视状态。",
2468724685
"xpack.watcher.sections.watchEdit.simulate.form.actionModesFieldLabel": "操作模式",
2468824686
"xpack.watcher.sections.watchEdit.simulate.form.actionOverridesDescription": "允许监视执行或跳过操作。{actionsLink}",

x-pack/plugins/watcher/public/application/app.tsx

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717

1818
import { Router, Switch, Route, Redirect, withRouter, RouteComponentProps } from 'react-router-dom';
1919

20-
import { EuiCallOut, EuiLink } from '@elastic/eui';
20+
import { EuiPageContent, EuiEmptyPrompt, EuiLink } from '@elastic/eui';
2121

2222
import { FormattedMessage } from '@kbn/i18n/react';
2323

@@ -62,24 +62,30 @@ export const App = (deps: AppDeps) => {
6262

6363
if (!valid) {
6464
return (
65-
<EuiCallOut
66-
title={
67-
<FormattedMessage
68-
id="xpack.watcher.app.licenseErrorTitle"
69-
defaultMessage="License error"
70-
/>
71-
}
72-
color="danger"
73-
iconType="help"
74-
>
75-
{message}{' '}
76-
<EuiLink href={deps.getUrlForApp('management', { path: 'stack/license_management/home' })}>
77-
<FormattedMessage
78-
id="xpack.watcher.app.licenseErrorLinkText"
79-
defaultMessage="Manage your license."
80-
/>
81-
</EuiLink>
82-
</EuiCallOut>
65+
<EuiPageContent verticalPosition="center" horizontalPosition="center" color="danger">
66+
<EuiEmptyPrompt
67+
iconType="alert"
68+
title={
69+
<h1>
70+
<FormattedMessage
71+
id="xpack.watcher.app.licenseErrorTitle"
72+
defaultMessage="License error"
73+
/>
74+
</h1>
75+
}
76+
body={<p>{message}</p>}
77+
actions={[
78+
<EuiLink
79+
href={deps.getUrlForApp('management', { path: 'stack/license_management/home' })}
80+
>
81+
<FormattedMessage
82+
id="xpack.watcher.app.licenseErrorLinkText"
83+
defaultMessage="Manage your license"
84+
/>
85+
</EuiLink>,
86+
]}
87+
/>
88+
</EuiPageContent>
8389
);
8490
}
8591
return (

x-pack/plugins/watcher/public/application/components/page_error/page_error.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export function getPageErrorCode(errorOrErrors: any) {
2525
}
2626
}
2727

28-
export function PageError({ errorCode, id }: { errorCode?: any; id?: any }) {
28+
export function PageError({ errorCode, id }: { errorCode?: number; id?: string }) {
2929
switch (errorCode) {
3030
case 404:
3131
return <PageErrorNotExist id={id} />;

x-pack/plugins/watcher/public/application/components/page_error/page_error_forbidden.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ import { FormattedMessage } from '@kbn/i18n/react';
1313
export function PageErrorForbidden() {
1414
return (
1515
<EuiEmptyPrompt
16-
iconType="securityApp"
17-
iconColor={undefined}
16+
iconType="alert"
1817
title={
1918
<h1>
2019
<FormattedMessage

x-pack/plugins/watcher/public/application/components/page_error/page_error_not_exist.tsx

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ import React from 'react';
1010
import { EuiEmptyPrompt } from '@elastic/eui';
1111
import { FormattedMessage } from '@kbn/i18n/react';
1212

13-
export function PageErrorNotExist({ id }: { id: any }) {
13+
export function PageErrorNotExist({ id }: { id?: string }) {
1414
return (
1515
<EuiEmptyPrompt
16-
iconType="search"
17-
iconColor="primary"
16+
iconType="alert"
1817
title={
1918
<h1>
2019
<FormattedMessage
@@ -25,11 +24,18 @@ export function PageErrorNotExist({ id }: { id: any }) {
2524
}
2625
body={
2726
<p>
28-
<FormattedMessage
29-
id="xpack.watcher.pageErrorNotExist.description"
30-
defaultMessage="A watch with ID '{id}' could not be found."
31-
values={{ id }}
32-
/>
27+
{id ? (
28+
<FormattedMessage
29+
id="xpack.watcher.pageErrorNotExist.description"
30+
defaultMessage="A watch with ID '{id}' could not be found."
31+
values={{ id }}
32+
/>
33+
) : (
34+
<FormattedMessage
35+
id="xpack.watcher.pageErrorNotExist.noWatchIdDescription"
36+
defaultMessage="A watch could not be found."
37+
/>
38+
)}
3339
</p>
3440
}
3541
/>

x-pack/plugins/watcher/public/application/sections/watch_edit/components/json_watch_edit/json_watch_edit.tsx

Lines changed: 26 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,7 @@
77

88
import React, { useContext, useState } from 'react';
99

10-
import {
11-
EuiFlexGroup,
12-
EuiFlexItem,
13-
EuiPageContent,
14-
EuiSpacer,
15-
EuiTab,
16-
EuiTabs,
17-
EuiTitle,
18-
} from '@elastic/eui';
10+
import { EuiPageHeader, EuiSpacer, EuiPageContentBody } from '@elastic/eui';
1911
import { i18n } from '@kbn/i18n';
2012
import { ExecuteDetails } from '../../../../models/execute_details';
2113
import { getActionType } from '../../../../../../common/lib/get_action_type';
@@ -96,36 +88,31 @@ export const JsonWatchEdit = ({ pageTitle }: { pageTitle: string }) => {
9688
const hasExecuteWatchErrors = !!Object.keys(executeWatchErrors).find(
9789
(errorKey) => executeWatchErrors[errorKey].length >= 1
9890
);
91+
9992
return (
100-
<EuiPageContent>
101-
<EuiFlexGroup>
102-
<EuiFlexItem grow={false}>
103-
<EuiTitle size="m">
104-
<h1 data-test-subj="pageTitle">{pageTitle}</h1>
105-
</EuiTitle>
106-
</EuiFlexItem>
107-
</EuiFlexGroup>
108-
<EuiTabs>
109-
{WATCH_TABS.map((tab, index) => (
110-
<EuiTab
111-
onClick={() => {
112-
setSelectedTab(tab.id);
113-
setExecuteDetails(
114-
new ExecuteDetails({
115-
...executeDetails,
116-
actionModes: getActionModes(watchActions),
117-
})
118-
);
119-
}}
120-
isSelected={tab.id === selectedTab}
121-
key={index}
122-
data-test-subj="tab"
123-
>
124-
{tab.name}
125-
</EuiTab>
126-
))}
127-
</EuiTabs>
93+
<EuiPageContentBody restrictWidth style={{ width: '100%' }}>
94+
<EuiPageHeader
95+
pageTitle={<span data-test-subj="pageTitle">{pageTitle}</span>}
96+
bottomBorder
97+
tabs={WATCH_TABS.map((tab, index) => ({
98+
onClick: () => {
99+
setSelectedTab(tab.id);
100+
setExecuteDetails(
101+
new ExecuteDetails({
102+
...executeDetails,
103+
actionModes: getActionModes(watchActions),
104+
})
105+
);
106+
},
107+
isSelected: tab.id === selectedTab,
108+
key: index,
109+
'data-test-subj': 'tab',
110+
label: tab.name,
111+
}))}
112+
/>
113+
128114
<EuiSpacer size="l" />
115+
129116
{selectedTab === WATCH_SIMULATE_TAB && (
130117
<JsonWatchEditSimulate
131118
executeDetails={executeDetails}
@@ -135,7 +122,8 @@ export const JsonWatchEdit = ({ pageTitle }: { pageTitle: string }) => {
135122
watchActions={watchActions}
136123
/>
137124
)}
125+
138126
{selectedTab === WATCH_EDIT_TAB && <JsonWatchEditForm />}
139-
</EuiPageContent>
127+
</EuiPageContentBody>
140128
);
141129
};

0 commit comments

Comments
 (0)