mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Data Views] Disable scripted field creation in the Data Views management page (#202250)
## Summary Scripted fields in data views have been deprecated since 7.13, and superseded by runtime fields. The ability to create new scripted fields has been removed from the Data Views management page in 9.0. Existing scripted fields can still be edited or deleted, and the creation UI can be accessed by navigating directly to `/app/management/kibana/dataViews/dataView/{dataViewId}/create-field`, but it is recommended to migrate to runtime fields or ES|QL instead to prepare for removal. Additionally, the scripted fields entry in the Upgrade Assistant has been updated to reflect these changes, improve migration instructions, and surface the full list of data views across all spaces that contain scripted fields as well as their associated spaces. New documentation has been added to the "Manage data views" page with examples and instructions to help users migrate off scripted fields to runtime fields or ES|QL, which is also linked to from the Upgrade Assistant entry. Data Views management page:  Upgrade Assistant: <img src="https://github.com/user-attachments/assets/4ff27866-4fe8-4357-82e8-cd4c503ab50b" width="500" /> Resolves #182067. ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [x] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [x] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: Matt Kime <matt@mattki.me> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
82301e7454
commit
4215a637da
28 changed files with 388 additions and 212 deletions
|
@ -170,7 +170,7 @@ Edit the settings for runtime fields, or remove runtime fields from data views.
|
|||
[[scripted-fields]]
|
||||
=== Add scripted fields to data views
|
||||
|
||||
deprecated::[7.13,Use {ref}/runtime.html[runtime fields] instead of scripted fields. Runtime fields support Painless scripts and provide greater flexibility.]
|
||||
deprecated::[7.13,Use {ref}/runtime.html[runtime fields] instead of scripted fields. Runtime fields support Painless scripting and provide greater flexibility. You can also use the {ref}/esql.html[Elasticsearch Query Language (ES|QL)] to compute values directly at query time.]
|
||||
|
||||
Scripted fields compute data on the fly from the data in your {es} indices. The data is shown on
|
||||
the Discover tab as part of the document data, and you can use scripted fields in your visualizations. You query scripted fields with the <<kuery-query, {kib} query language>>, and can filter them using the filter bar. The scripted field values are computed at query time, so they aren't indexed and cannot be searched using the {kib} default
|
||||
|
@ -193,33 +193,123 @@ For more information on scripted fields and additional examples, refer to
|
|||
https://www.elastic.co/blog/using-painless-kibana-scripted-fields[Using Painless in {kib} scripted fields]
|
||||
|
||||
[float]
|
||||
[[create-scripted-field]]
|
||||
==== Create scripted fields
|
||||
[[migrate-off-scripted-fields]]
|
||||
==== Migrate to runtime fields or ES|QL queries
|
||||
|
||||
Create and add scripted fields to your data views.
|
||||
The following code snippets demonstrate how an example scripted field called `computed_values` on the Kibana Sample Data Logs data view could be migrated to either a runtime field or an ES|QL query, highlighting the differences between each approach.
|
||||
|
||||
. Go to the *Data Views* management page using the navigation menu or the <<kibana-navigation-search,global search field>>.
|
||||
[float]
|
||||
[[scripted-field-example]]
|
||||
===== Scripted field
|
||||
|
||||
. Select the data view you want to add a scripted field to.
|
||||
In the scripted field example, variables are created to track all values the script will need to access or return. Since scripted fields can only return a single value, the created variables must be returned together as an array at the end of the script.
|
||||
|
||||
. Select the *Scripted fields* tab, then click *Add scripted field*.
|
||||
[source,text]
|
||||
----
|
||||
def hour_of_day = $('@timestamp', ZonedDateTime.parse('1970-01-01T00:00:00Z')).getHour();
|
||||
def time_of_day = '';
|
||||
|
||||
. Enter a *Name* for the scripted field, then enter the *Script* you want to use to compute a value on the fly from your index data.
|
||||
if (hour_of_day >= 22 || hour_of_day < 5)
|
||||
time_of_day = 'Night';
|
||||
else if (hour_of_day < 12)
|
||||
time_of_day = 'Morning';
|
||||
else if (hour_of_day < 18)
|
||||
time_of_day = 'Afternoon';
|
||||
else
|
||||
time_of_day = 'Evening';
|
||||
|
||||
. Click *Create field*.
|
||||
def response_int = Integer.parseInt($('response.keyword', '200'));
|
||||
def response_category = '';
|
||||
|
||||
For more information about scripted fields in {es}, refer to {ref}/modules-scripting.html[Scripting].
|
||||
if (response_int < 200)
|
||||
response_category = 'Informational';
|
||||
else if (response_int < 300)
|
||||
response_category = 'Successful';
|
||||
else if (response_int < 400)
|
||||
response_category = 'Redirection';
|
||||
else if (response_int < 500)
|
||||
response_category = 'Client Error';
|
||||
else
|
||||
response_category = 'Server Error';
|
||||
|
||||
return [time_of_day, response_category];
|
||||
----
|
||||
|
||||
[float]
|
||||
[[runtime-field-example]]
|
||||
===== Runtime field
|
||||
|
||||
Unlike scripted fields, runtime fields do not need to return a single value and can emit values at any point in the script, which will be combined and returned as a multi-value field. This allows for more flexibility in the script logic and removes the need to manually manage an array of values.
|
||||
|
||||
[source,text]
|
||||
----
|
||||
def hour_of_day = $('@timestamp', ZonedDateTime.parse('1970-01-01T00:00:00Z')).getHour();
|
||||
|
||||
if (hour_of_day >= 22 || hour_of_day < 5)
|
||||
emit('Night');
|
||||
else if (hour_of_day < 12)
|
||||
emit('Morning');
|
||||
else if (hour_of_day < 18)
|
||||
emit('Afternoon');
|
||||
else
|
||||
emit('Evening');
|
||||
|
||||
def response_int = Integer.parseInt($('response.keyword', '200'));
|
||||
|
||||
if (response_int < 200)
|
||||
emit('Informational');
|
||||
else if (response_int < 300)
|
||||
emit('Successful');
|
||||
else if (response_int < 400)
|
||||
emit('Redirection');
|
||||
else if (response_int < 500)
|
||||
emit('Client Error');
|
||||
else
|
||||
emit('Server Error');
|
||||
----
|
||||
|
||||
[float]
|
||||
[[esql-example]]
|
||||
===== ES|QL query
|
||||
|
||||
Alternatively, ES|QL can be used to skip the need for data view management entirely and simply compute the values you need at query time. ES|QL supports computing multiple field values in a single query, using computed values with its rich set of commands and functions, and even aggregations against computed values. This makes it an excellent solution for one-off queries and realtime data analysis.
|
||||
|
||||
[source,esql]
|
||||
----
|
||||
FROM kibana_sample_data_logs
|
||||
| EVAL hour_of_day = DATE_EXTRACT("HOUR_OF_DAY", @timestamp)
|
||||
| EVAL time_of_day = CASE(
|
||||
hour_of_day >= 22 OR hour_of_day < 5, "Night",
|
||||
hour_of_day < 12, "Morning",
|
||||
hour_of_day < 18, "Afternoon",
|
||||
"Evening"
|
||||
)
|
||||
| EVAL response_int = TO_INTEGER(response)
|
||||
| EVAL response_category = CASE(
|
||||
response_int < 200, "Informational",
|
||||
response_int < 300, "Successful",
|
||||
response_int < 400, "Redirection",
|
||||
response_int < 500, "Client Error",
|
||||
"Server Error"
|
||||
)
|
||||
| EVAL computed_values = MV_APPEND(time_of_day, response_category)
|
||||
| DROP hour_of_day, time_of_day, response_int, response_category
|
||||
----
|
||||
|
||||
[float]
|
||||
[[update-scripted-field]]
|
||||
==== Manage scripted fields
|
||||
|
||||
WARNING: The ability to create new scripted fields has been removed from the *Data Views* management page in 9.0. Existing scripted fields can still be edited or deleted, and the creation UI can be accessed by navigating directly to `/app/management/kibana/dataViews/dataView/{dataViewId}/create-field`, but we recommend migrating to runtime fields or ES|QL queries instead to prepare for removal.
|
||||
|
||||
. Go to the *Data Views* management page using the navigation menu or the <<kibana-navigation-search,global search field>>.
|
||||
|
||||
. Select the data view that contains the scripted field you want to manage.
|
||||
|
||||
. Select the *Scripted fields* tab, then open the scripted field edit options or delete the scripted field.
|
||||
|
||||
For more information about scripted fields in {es}, refer to {ref}/modules-scripting.html[Scripting].
|
||||
|
||||
WARNING: Built-in validation is unsupported for scripted fields. When your scripts contain errors, you receive
|
||||
exceptions when you view the dynamically generated data.
|
||||
|
||||
|
|
|
@ -164,5 +164,19 @@ resolving issues if any deprecated features are enabled.
|
|||
To access the assistant, go to **Stack Management** > **Upgrade Assistant**.
|
||||
|
||||
|
||||
[discrete]
|
||||
[[deprecation-202250]]
|
||||
.Scripted field creation has been disabled in the Data Views management page (9.0.0)
|
||||
[%collapsible]
|
||||
====
|
||||
*Details* +
|
||||
The ability to create new scripted fields has been removed from the *Data Views* management page in 9.0. Existing scripted fields can still be edited or deleted, and the creation UI can be accessed by navigating directly to `/app/management/kibana/dataViews/dataView/{dataViewId}/create-field`, but we recommend migrating to runtime fields or ES|QL queries instead to prepare for removal.
|
||||
|
||||
For more information, refer to {kibana-pull}202250[#202250].
|
||||
|
||||
*Impact* +
|
||||
It will no longer be possible to create new scripted fields directly from the *Data Views* management page.
|
||||
|
||||
*Action* +
|
||||
Migrate to runtime fields or ES|QL instead of creating new scripted fields. Existing scripted fields can still be edited or deleted.
|
||||
====
|
|
@ -8,6 +8,7 @@
|
|||
*/
|
||||
|
||||
export type {
|
||||
DeprecationDetailsMessage,
|
||||
BaseDeprecationDetails,
|
||||
ConfigDeprecationDetails,
|
||||
FeatureDeprecationDetails,
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
export interface DeprecationDetailsMessage {
|
||||
type: 'markdown' | 'text';
|
||||
content: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base properties shared by all types of deprecations
|
||||
*
|
||||
|
@ -22,7 +27,7 @@ export interface BaseDeprecationDetails {
|
|||
* The description message to be displayed for the deprecation.
|
||||
* Check the README for writing deprecations in `src/core/server/deprecations/README.mdx`
|
||||
*/
|
||||
message: string | string[];
|
||||
message: string | DeprecationDetailsMessage | Array<string | DeprecationDetailsMessage>;
|
||||
/**
|
||||
* levels:
|
||||
* - warning: will not break deployment upon upgrade
|
||||
|
|
|
@ -345,6 +345,7 @@ export const getDocLinks = ({ kibanaBranch, buildFlavor }: GetDocLinkOptions): D
|
|||
fieldFormattersNumber: `${KIBANA_DOCS}numeral.html`,
|
||||
fieldFormattersString: `${KIBANA_DOCS}managing-data-views.html#string-field-formatters`,
|
||||
runtimeFields: `${KIBANA_DOCS}managing-data-views.html#runtime-fields`,
|
||||
migrateOffScriptedFields: `${KIBANA_DOCS}managing-data-views.html#migrate-off-scripted-fields`,
|
||||
},
|
||||
addData: `${KIBANA_DOCS}connect-to-elasticsearch.html`,
|
||||
kibana: {
|
||||
|
|
|
@ -304,6 +304,7 @@ export interface DocLinks {
|
|||
readonly fieldFormattersNumber: string;
|
||||
readonly fieldFormattersString: string;
|
||||
readonly runtimeFields: string;
|
||||
readonly migrateOffScriptedFields: string;
|
||||
};
|
||||
readonly addData: string;
|
||||
readonly kibana: {
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
exports[`ScriptedFieldsTable should filter based on the lang filter 1`] = `
|
||||
<Fragment>
|
||||
<header
|
||||
indexPatternId=""
|
||||
/>
|
||||
<header />
|
||||
<call-outs
|
||||
deprecatedLangsInUse={
|
||||
Array [
|
||||
|
@ -46,9 +44,7 @@ exports[`ScriptedFieldsTable should filter based on the lang filter 1`] = `
|
|||
|
||||
exports[`ScriptedFieldsTable should filter based on the query bar 1`] = `
|
||||
<Fragment>
|
||||
<header
|
||||
indexPatternId=""
|
||||
/>
|
||||
<header />
|
||||
<call-outs
|
||||
deprecatedLangsInUse={Array []}
|
||||
painlessDocLink="painlessDoc"
|
||||
|
@ -80,9 +76,7 @@ exports[`ScriptedFieldsTable should filter based on the query bar 1`] = `
|
|||
|
||||
exports[`ScriptedFieldsTable should hide the table if there are no scripted fields 1`] = `
|
||||
<Fragment>
|
||||
<header
|
||||
indexPatternId=""
|
||||
/>
|
||||
<header />
|
||||
<call-outs
|
||||
deprecatedLangsInUse={Array []}
|
||||
painlessDocLink="painlessDoc"
|
||||
|
@ -105,9 +99,7 @@ exports[`ScriptedFieldsTable should hide the table if there are no scripted fiel
|
|||
|
||||
exports[`ScriptedFieldsTable should render normally 1`] = `
|
||||
<Fragment>
|
||||
<header
|
||||
indexPatternId=""
|
||||
/>
|
||||
<header />
|
||||
<call-outs
|
||||
deprecatedLangsInUse={Array []}
|
||||
painlessDocLink="painlessDoc"
|
||||
|
@ -145,9 +137,7 @@ exports[`ScriptedFieldsTable should render normally 1`] = `
|
|||
|
||||
exports[`ScriptedFieldsTable should show a delete modal 1`] = `
|
||||
<Fragment>
|
||||
<header
|
||||
indexPatternId=""
|
||||
/>
|
||||
<header />
|
||||
<call-outs
|
||||
deprecatedLangsInUse={Array []}
|
||||
painlessDocLink="painlessDoc"
|
||||
|
|
|
@ -2,19 +2,22 @@
|
|||
|
||||
exports[`CallOuts should render normally 1`] = `
|
||||
<Fragment>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<EuiCallOut
|
||||
color="danger"
|
||||
iconType="cross"
|
||||
title={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Deprecation languages in use"
|
||||
id="indexPatternManagement.editIndexPattern.scripted.deprecationLangHeader"
|
||||
defaultMessage="Deprecated languages in use"
|
||||
id="indexPatternManagement.editIndexPattern.scripted.deprecatedLangHeader"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="The following deprecated languages are in use: {deprecatedLangsInUse}. Support for these languages will be removed in the next major version of Kibana and Elasticsearch. Convert you scripted fields to {link} to avoid any problems."
|
||||
defaultMessage="The following deprecated languages are in use: {deprecatedLangsInUse}. Support for these languages will be removed in the next major version of Kibana and Elasticsearch. Convert your scripted fields to {link} to avoid any problems."
|
||||
id="indexPatternManagement.editIndexPattern.scripted.deprecationLangLabel.deprecationLangDetail"
|
||||
values={
|
||||
Object {
|
||||
|
@ -32,9 +35,6 @@ exports[`CallOuts should render normally 1`] = `
|
|||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
|
|
|
@ -24,11 +24,12 @@ export const CallOuts = ({ deprecatedLangsInUse, painlessDocLink }: CallOutsProp
|
|||
|
||||
return (
|
||||
<>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiCallOut
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="indexPatternManagement.editIndexPattern.scripted.deprecationLangHeader"
|
||||
defaultMessage="Deprecation languages in use"
|
||||
id="indexPatternManagement.editIndexPattern.scripted.deprecatedLangHeader"
|
||||
defaultMessage="Deprecated languages in use"
|
||||
/>
|
||||
}
|
||||
color="danger"
|
||||
|
@ -38,7 +39,7 @@ export const CallOuts = ({ deprecatedLangsInUse, painlessDocLink }: CallOutsProp
|
|||
<FormattedMessage
|
||||
id="indexPatternManagement.editIndexPattern.scripted.deprecationLangLabel.deprecationLangDetail"
|
||||
defaultMessage="The following deprecated languages are in use: {deprecatedLangsInUse}. Support for these languages will be
|
||||
removed in the next major version of Kibana and Elasticsearch. Convert you scripted fields to {link} to avoid any problems."
|
||||
removed in the next major version of Kibana and Elasticsearch. Convert your scripted fields to {link} to avoid any problems."
|
||||
values={{
|
||||
deprecatedLangsInUse: deprecatedLangsInUse.join(', '),
|
||||
link: (
|
||||
|
@ -53,7 +54,6 @@ export const CallOuts = ({ deprecatedLangsInUse, painlessDocLink }: CallOutsProp
|
|||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer size="m" />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,27 +8,53 @@ exports[`Header should render normally 1`] = `
|
|||
class="euiFlexItem emotion-euiFlexItem-grow-1"
|
||||
>
|
||||
<div
|
||||
class="euiText emotion-euiText-s"
|
||||
class="euiPanel euiPanel--warning euiPanel--paddingMedium euiCallOut euiCallOut--warning emotion-euiPanel-none-m-warning-euiCallOut"
|
||||
>
|
||||
<p>
|
||||
<span>
|
||||
Scripted fields can be used in visualizations and displayed in documents. However, they cannot be searched.
|
||||
</span>
|
||||
<br />
|
||||
<p
|
||||
class="euiTitle euiCallOutHeader__title emotion-euiTitle-xs-euiCallOutHeader-warning"
|
||||
>
|
||||
<span
|
||||
class="emotion-EuiIcon"
|
||||
color="warning"
|
||||
aria-hidden="true"
|
||||
class="emotion-euiCallOut__icon"
|
||||
color="inherit"
|
||||
data-euiicon-type="warning"
|
||||
/>
|
||||
Scripted fields are deprecated
|
||||
</p>
|
||||
<div
|
||||
class="euiSpacer euiSpacer--s emotion-euiSpacer-s"
|
||||
/>
|
||||
<div
|
||||
class="euiText emotion-euiText-s-euiTextColor-default"
|
||||
>
|
||||
<span>
|
||||
Scripted fields are deprecated. Use
|
||||
Use
|
||||
<button
|
||||
class="euiLink emotion-euiLink-primary"
|
||||
type="button"
|
||||
>
|
||||
runtime fields
|
||||
</button>
|
||||
instead.
|
||||
instead of scripted fields. Runtime fields support Painless scripting and provide greater flexibility. You can also use the
|
||||
<button
|
||||
class="euiLink emotion-euiLink-primary"
|
||||
type="button"
|
||||
>
|
||||
Elasticsearch Query Language (ES|QL)
|
||||
</button>
|
||||
to compute values directly at query time.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="euiSpacer euiSpacer--m emotion-euiSpacer-m"
|
||||
/>
|
||||
<div
|
||||
class="euiText emotion-euiText-s"
|
||||
>
|
||||
<p>
|
||||
<span>
|
||||
Scripted fields can be used in visualizations and displayed in documents. However, they cannot be searched.
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -9,9 +9,6 @@
|
|||
|
||||
import React from 'react';
|
||||
import { mountWithI18nProvider } from '@kbn/test-jest-helpers';
|
||||
import { RouteComponentProps } from 'react-router-dom';
|
||||
import { ScopedHistory } from '@kbn/core/public';
|
||||
import { scopedHistoryMock } from '@kbn/core/public/mocks';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { mockManagementPlugin } from '../../../../../mocks';
|
||||
|
||||
|
@ -20,20 +17,12 @@ import { Header } from './header';
|
|||
describe('Header', () => {
|
||||
const mockedContext = mockManagementPlugin.createIndexPatternManagmentContext();
|
||||
test('should render normally', () => {
|
||||
const component = mountWithI18nProvider(
|
||||
<Header.WrappedComponent
|
||||
indexPatternId="test"
|
||||
history={scopedHistoryMock.create() as unknown as ScopedHistory}
|
||||
location={{} as unknown as RouteComponentProps['location']}
|
||||
match={{} as unknown as RouteComponentProps['match']}
|
||||
/>,
|
||||
{
|
||||
wrappingComponent: KibanaContextProvider,
|
||||
wrappingComponentProps: {
|
||||
services: mockedContext,
|
||||
},
|
||||
}
|
||||
);
|
||||
const component = mountWithI18nProvider(<Header />, {
|
||||
wrappingComponent: KibanaContextProvider,
|
||||
wrappingComponentProps: {
|
||||
services: mockedContext,
|
||||
},
|
||||
});
|
||||
|
||||
expect(component.render()).toMatchSnapshot();
|
||||
});
|
||||
|
|
|
@ -8,27 +8,52 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
||||
import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiText, EuiLink, EuiIcon } from '@elastic/eui';
|
||||
import { EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiText, EuiLink, EuiSpacer } from '@elastic/eui';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { ScopedHistory } from '@kbn/core/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { reactRouterNavigate, useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { IndexPatternManagmentContext } from '../../../../../types';
|
||||
|
||||
interface HeaderProps extends RouteComponentProps {
|
||||
indexPatternId: string;
|
||||
history: ScopedHistory;
|
||||
}
|
||||
|
||||
export const Header = withRouter(({ indexPatternId, history }: HeaderProps) => {
|
||||
const { dataViews, docLinks } = useKibana<IndexPatternManagmentContext>().services;
|
||||
export const Header = () => {
|
||||
const { docLinks } = useKibana<IndexPatternManagmentContext>().services;
|
||||
const links = docLinks?.links;
|
||||
const userEditPermission = dataViews.getCanSaveSync();
|
||||
return (
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<EuiFlexItem>
|
||||
<EuiCallOut
|
||||
title={i18n.translate('indexPatternManagement.editIndexPattern.deprecation.title', {
|
||||
defaultMessage: 'Scripted fields are deprecated',
|
||||
})}
|
||||
color="warning"
|
||||
iconType="warning"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="indexPatternManagement.editIndexPattern.deprecation.message"
|
||||
tagName="span"
|
||||
defaultMessage="Use {runtimeFieldsLink} instead of scripted fields. Runtime fields support Painless scripting and provide greater flexibility. You can also use the {esqlLink} to compute values directly at query time."
|
||||
values={{
|
||||
runtimeFieldsLink: (
|
||||
<EuiLink target="_blank" href={links.indexPatterns.runtimeFields}>
|
||||
<FormattedMessage
|
||||
id="indexPatternManagement.header.runtimeLink"
|
||||
defaultMessage="runtime fields"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
esqlLink: (
|
||||
<EuiLink target="_blank" href={links.query.queryESQL}>
|
||||
<FormattedMessage
|
||||
id="indexPatternManagement.header.esqlLink"
|
||||
defaultMessage="Elasticsearch Query Language (ES|QL)"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiText size="s">
|
||||
<p>
|
||||
<FormattedMessage
|
||||
|
@ -36,40 +61,9 @@ export const Header = withRouter(({ indexPatternId, history }: HeaderProps) => {
|
|||
id="indexPatternManagement.editIndexPattern.scriptedLabel"
|
||||
defaultMessage="Scripted fields can be used in visualizations and displayed in documents. However, they cannot be searched."
|
||||
/>
|
||||
<br />
|
||||
<EuiIcon type="warning" color="warning" css={{ marginRight: '4px' }} />
|
||||
<FormattedMessage
|
||||
id="indexPatternManagement.editIndexPattern.deprecation"
|
||||
tagName="span"
|
||||
defaultMessage="Scripted fields are deprecated. Use {runtimeDocs} instead."
|
||||
values={{
|
||||
runtimeDocs: (
|
||||
<EuiLink target="_blank" href={links.runtimeFields.overview}>
|
||||
<FormattedMessage
|
||||
id="indexPatternManagement.header.runtimeLink"
|
||||
defaultMessage="runtime fields"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
|
||||
{userEditPermission && (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
data-test-subj="addScriptedFieldLink"
|
||||
{...reactRouterNavigate(history, `patterns/${indexPatternId}/create-field/`)}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="indexPatternManagement.editIndexPattern.scripted.addFieldButton"
|
||||
defaultMessage="Add scripted field"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -59,7 +59,7 @@ export class ScriptedFieldsTable extends Component<
|
|||
}
|
||||
|
||||
fetchFields = async () => {
|
||||
const fields = await (this.props.indexPattern.getScriptedFields() as ScriptedFieldItem[]);
|
||||
const fields = this.props.indexPattern.getScriptedFields() as ScriptedFieldItem[];
|
||||
|
||||
const deprecatedLangsInUse = [];
|
||||
const deprecatedLangs = getDeprecatedScriptingLanguages();
|
||||
|
@ -67,7 +67,7 @@ export class ScriptedFieldsTable extends Component<
|
|||
|
||||
for (const field of fields) {
|
||||
const lang = field.lang;
|
||||
if (deprecatedLangs.includes(lang) || !supportedLangs.includes(lang)) {
|
||||
if (lang && (deprecatedLangs.includes(lang) || !supportedLangs.includes(lang))) {
|
||||
deprecatedLangsInUse.push(lang);
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ export class ScriptedFieldsTable extends Component<
|
|||
|
||||
return (
|
||||
<>
|
||||
<Header indexPatternId={indexPattern.id || ''} />
|
||||
<Header />
|
||||
|
||||
<CallOuts deprecatedLangsInUse={deprecatedLangsInUse} painlessDocLink={painlessDocLink} />
|
||||
|
||||
|
|
|
@ -96,7 +96,11 @@ export function getTabs(
|
|||
'data-test-subj': 'tab-indexedFields',
|
||||
});
|
||||
|
||||
if (!isRollup(indexPattern.type) && scriptedFieldsEnabled) {
|
||||
if (
|
||||
!isRollup(indexPattern.type) &&
|
||||
scriptedFieldsEnabled &&
|
||||
indexPattern.getScriptedFields().length > 0
|
||||
) {
|
||||
tabs.push({
|
||||
name: getTitle('scripted', filteredCount, totalCount),
|
||||
id: TAB_SCRIPTED_FIELDS,
|
||||
|
|
|
@ -57,6 +57,7 @@ const docLinks = {
|
|||
indexPatterns: {},
|
||||
scriptedFields: {},
|
||||
runtimeFields: {},
|
||||
query: {},
|
||||
} as any,
|
||||
};
|
||||
|
||||
|
|
|
@ -7,85 +7,83 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import {
|
||||
import type {
|
||||
CoreSetup,
|
||||
DeprecationsDetails,
|
||||
GetDeprecationsContext,
|
||||
RegisterDeprecationsConfig,
|
||||
SavedObjectsFindResult,
|
||||
} from '@kbn/core/server';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { DataViewAttributes } from '../../common';
|
||||
import type { DocLinks } from '@kbn/doc-links';
|
||||
import type { DeprecationDetailsMessage } from '@kbn/core-deprecations-common';
|
||||
import type { DataViewAttributes } from '../../common';
|
||||
|
||||
type IndexPatternAttributesWithFields = Pick<DataViewAttributes, 'title' | 'fields'>;
|
||||
type DataViewAttributesWithFields = Pick<DataViewAttributes, 'name' | 'title' | 'fields'>;
|
||||
|
||||
export const createScriptedFieldsDeprecationsConfig: (
|
||||
core: CoreSetup
|
||||
) => RegisterDeprecationsConfig = (core: CoreSetup) => ({
|
||||
getDeprecations: async (context: GetDeprecationsContext): Promise<DeprecationsDetails[]> => {
|
||||
const finder =
|
||||
context.savedObjectsClient.createPointInTimeFinder<IndexPatternAttributesWithFields>({
|
||||
const finder = context.savedObjectsClient.createPointInTimeFinder<DataViewAttributesWithFields>(
|
||||
{
|
||||
type: 'index-pattern',
|
||||
perPage: 1000,
|
||||
fields: ['title', 'fields'],
|
||||
fields: ['name', 'title', 'fields'],
|
||||
namespaces: ['*'],
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
const dataViewsWithScriptedFields: Array<SavedObjectsFindResult<DataViewAttributesWithFields>> =
|
||||
[];
|
||||
|
||||
const indexPatternsWithScriptedFields: IndexPatternAttributesWithFields[] = [];
|
||||
for await (const response of finder.find()) {
|
||||
indexPatternsWithScriptedFields.push(
|
||||
...response.saved_objects.map((so) => so.attributes).filter(hasScriptedField)
|
||||
dataViewsWithScriptedFields.push(
|
||||
...response.saved_objects.filter((so) => hasScriptedField(so.attributes))
|
||||
);
|
||||
}
|
||||
|
||||
if (indexPatternsWithScriptedFields.length > 0) {
|
||||
const PREVIEW_LIMIT = 3;
|
||||
const indexPatternTitles = indexPatternsWithScriptedFields.map((ip) => ip.title);
|
||||
|
||||
return [
|
||||
{
|
||||
title: i18n.translate('dataViews.deprecations.scriptedFieldsTitle', {
|
||||
defaultMessage: 'Found data views using scripted fields',
|
||||
}),
|
||||
message: i18n.translate('dataViews.deprecations.scriptedFieldsMessage', {
|
||||
defaultMessage: `You have {numberOfIndexPatternsWithScriptedFields} data views ({titlesPreview}...) that use scripted fields. Scripted fields are deprecated and will be removed in future. Use runtime fields instead.`,
|
||||
values: {
|
||||
titlesPreview: indexPatternTitles.slice(0, PREVIEW_LIMIT).join('; '),
|
||||
numberOfIndexPatternsWithScriptedFields: indexPatternsWithScriptedFields.length,
|
||||
},
|
||||
}),
|
||||
documentationUrl:
|
||||
'https://www.elastic.co/guide/en/elasticsearch/reference/7.x/runtime.html', // TODO: documentation service is not available serverside https://github.com/elastic/kibana/issues/95389
|
||||
level: 'warning', // warning because it is not set in stone WHEN we remove scripted fields, hence this deprecation is not a blocker for 8.0 upgrade
|
||||
correctiveActions: {
|
||||
manualSteps: [
|
||||
i18n.translate('dataViews.deprecations.scriptedFields.manualStepOneMessage', {
|
||||
defaultMessage: 'Navigate to Stack Management > Kibana > Data Views.',
|
||||
}),
|
||||
i18n.translate('dataViews.deprecations.scriptedFields.manualStepTwoMessage', {
|
||||
defaultMessage:
|
||||
'Update {numberOfIndexPatternsWithScriptedFields} data views that have scripted fields to use runtime fields instead. In most cases, to migrate existing scripts, you will need to change "return <value>;" to "emit(<value>);". Data views with at least one scripted field: {allTitles}',
|
||||
values: {
|
||||
allTitles: indexPatternTitles.join('; '),
|
||||
numberOfIndexPatternsWithScriptedFields: indexPatternsWithScriptedFields.length,
|
||||
},
|
||||
ignoreTag: true,
|
||||
}),
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
} else {
|
||||
if (!dataViewsWithScriptedFields.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
title: i18n.translate('dataViews.deprecations.scriptedFieldsTitle', {
|
||||
defaultMessage: 'Found data views using scripted fields',
|
||||
}),
|
||||
message: buildMessage({
|
||||
dataViewsWithScriptedFields,
|
||||
docLinks: core.docLinks.links,
|
||||
}),
|
||||
documentationUrl: core.docLinks.links.indexPatterns.migrateOffScriptedFields,
|
||||
deprecationType: 'feature',
|
||||
level: 'warning', // warning because it is not set in stone WHEN we remove scripted fields, hence this deprecation is not a blocker for 9.0 upgrade
|
||||
correctiveActions: {
|
||||
manualSteps: [
|
||||
i18n.translate('dataViews.deprecations.scriptedFields.manualStepOneMessage', {
|
||||
defaultMessage: 'Navigate to Stack Management > Kibana > Data Views.',
|
||||
}),
|
||||
i18n.translate('dataViews.deprecations.scriptedFields.manualStepTwoMessage', {
|
||||
defaultMessage:
|
||||
'Update data views that have scripted fields to use runtime fields instead. In most cases, you will only need to change "return <value>;" to "emit(<value>);".',
|
||||
ignoreTag: true,
|
||||
}),
|
||||
i18n.translate('dataViews.deprecations.scriptedFields.manualStepThreeMessage', {
|
||||
defaultMessage:
|
||||
'Alternatively, you can achieve similar functionality by computing values at query time using the Elasticsearch Query Language (ES|QL).',
|
||||
}),
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
});
|
||||
|
||||
export function hasScriptedField(indexPattern: IndexPatternAttributesWithFields) {
|
||||
if (indexPattern.fields) {
|
||||
export function hasScriptedField(dataView: DataViewAttributesWithFields) {
|
||||
if (dataView.fields) {
|
||||
try {
|
||||
return JSON.parse(indexPattern.fields).some(
|
||||
(field: { scripted?: boolean }) => field?.scripted
|
||||
);
|
||||
return JSON.parse(dataView.fields).some((field: { scripted?: boolean }) => field?.scripted);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
@ -93,3 +91,55 @@ export function hasScriptedField(indexPattern: IndexPatternAttributesWithFields)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const dataViewIdLabel = i18n.translate('dataViews.deprecations.scriptedFields.dataViewIdLabel', {
|
||||
defaultMessage: 'ID',
|
||||
});
|
||||
|
||||
const dataViewNameLabel = i18n.translate(
|
||||
'dataViews.deprecations.scriptedFields.dataViewNameLabel',
|
||||
{
|
||||
defaultMessage: 'Name',
|
||||
}
|
||||
);
|
||||
|
||||
const dataViewSpacesLabel = i18n.translate(
|
||||
'dataViews.deprecations.scriptedFields.dataViewSpacesLabel',
|
||||
{
|
||||
defaultMessage: 'Spaces',
|
||||
}
|
||||
);
|
||||
|
||||
const buildDataViewsListEntry = (
|
||||
so: SavedObjectsFindResult<DataViewAttributesWithFields>
|
||||
) => `- **${dataViewIdLabel}:** ${so.id}
|
||||
- **${dataViewNameLabel}:** ${
|
||||
so.attributes.name
|
||||
? `!{tooltip[${so.attributes.name}](${so.attributes.title})}`
|
||||
: so.attributes.title
|
||||
}
|
||||
- **${dataViewSpacesLabel}:** ${so.namespaces?.join(', ')}`;
|
||||
|
||||
const buildMessage = ({
|
||||
dataViewsWithScriptedFields,
|
||||
docLinks,
|
||||
}: {
|
||||
dataViewsWithScriptedFields: Array<SavedObjectsFindResult<DataViewAttributesWithFields>>;
|
||||
docLinks: DocLinks;
|
||||
}): DeprecationDetailsMessage => ({
|
||||
type: 'markdown',
|
||||
content: i18n.translate('dataViews.deprecations.scriptedFieldsMessage', {
|
||||
defaultMessage: `You have {numberOfDataViewsWithScriptedFields} {numberOfDataViewsWithScriptedFields, plural, one {data view} other {data views}} containing scripted fields. Scripted fields are deprecated and will be removed in the future.
|
||||
|
||||
The ability to create new scripted fields in the Data Views management page has been disabled in 9.0, and it is recommended to migrate to [runtime fields]({runtimeFieldsLink}) or the [Elasticsearch Query Language (ES|QL)]({esqlLink}) instead.
|
||||
|
||||
The following is a list of all data views with scripted fields and their associated spaces:
|
||||
{dataViewsList}`,
|
||||
values: {
|
||||
numberOfDataViewsWithScriptedFields: dataViewsWithScriptedFields.length,
|
||||
runtimeFieldsLink: docLinks.indexPatterns.runtimeFields,
|
||||
esqlLink: docLinks.query.queryESQL,
|
||||
dataViewsList: dataViewsWithScriptedFields.map(buildDataViewsListEntry).join('\n'),
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
"@kbn/core-http-browser",
|
||||
"@kbn/core-http-browser-internal",
|
||||
"@kbn/logging-mocks",
|
||||
"@kbn/doc-links",
|
||||
"@kbn/core-deprecations-common",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
import expect from '@kbn/expect';
|
||||
import type { DeprecationsGetResponse } from '@kbn/core/server';
|
||||
import { X_ELASTIC_INTERNAL_ORIGIN_REQUEST } from '@kbn/core-http-common';
|
||||
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
import type { DeprecationDetailsMessage } from '@kbn/core-deprecations-common';
|
||||
import type { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
|
@ -75,7 +76,9 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
);
|
||||
|
||||
expect(dataPluginDeprecations.length).to.be(1);
|
||||
expect(dataPluginDeprecations[0].message).to.contain(title);
|
||||
expect((dataPluginDeprecations[0].message as DeprecationDetailsMessage).content).to.contain(
|
||||
title
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -45,8 +45,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.settings.navigateTo();
|
||||
await PageObjects.settings.clickKibanaIndexPatterns();
|
||||
await PageObjects.settings.clickIndexPatternLogstash();
|
||||
await PageObjects.settings.clickScriptedFieldsTab();
|
||||
await PageObjects.settings.clickAddScriptedField();
|
||||
await PageObjects.settings.goToAddScriptedField();
|
||||
await PageObjects.settings.setScriptedFieldName(scriptedFiledName);
|
||||
await PageObjects.settings.setScriptedFieldScript(`doc['bytes'].value`);
|
||||
const response = await es.update(
|
||||
|
|
|
@ -59,8 +59,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.settings.navigateTo();
|
||||
await PageObjects.settings.clickKibanaIndexPatterns();
|
||||
await PageObjects.settings.clickIndexPatternLogstash();
|
||||
await PageObjects.settings.clickScriptedFieldsTab();
|
||||
await PageObjects.settings.clickAddScriptedField();
|
||||
await PageObjects.settings.goToAddScriptedField();
|
||||
await PageObjects.settings.setScriptedFieldName('doomedScriptedField');
|
||||
await PageObjects.settings.setScriptedFieldScript(`i n v a l i d s c r i p t`);
|
||||
await PageObjects.settings.clickSaveScriptedField();
|
||||
|
@ -78,7 +77,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.settings.clickKibanaIndexPatterns();
|
||||
await PageObjects.settings.clickIndexPatternLogstash();
|
||||
const startingCount = parseInt(await PageObjects.settings.getScriptedFieldsTabCount(), 10);
|
||||
await PageObjects.settings.clickScriptedFieldsTab();
|
||||
await log.debug('add scripted field');
|
||||
const script = `1`;
|
||||
await PageObjects.settings.addScriptedField(
|
||||
|
@ -112,7 +110,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.settings.clickKibanaIndexPatterns();
|
||||
await PageObjects.settings.clickIndexPatternLogstash();
|
||||
const startingCount = parseInt(await PageObjects.settings.getScriptedFieldsTabCount(), 10);
|
||||
await PageObjects.settings.clickScriptedFieldsTab();
|
||||
await log.debug('add scripted field');
|
||||
const script = `if (doc['machine.ram'].size() == 0) return -1;
|
||||
else return doc['machine.ram'].value / (1024 * 1024 * 1024);
|
||||
|
@ -227,7 +224,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.settings.clickKibanaIndexPatterns();
|
||||
await PageObjects.settings.clickIndexPatternLogstash();
|
||||
const startingCount = parseInt(await PageObjects.settings.getScriptedFieldsTabCount(), 10);
|
||||
await PageObjects.settings.clickScriptedFieldsTab();
|
||||
await log.debug('add scripted field');
|
||||
await PageObjects.settings.addScriptedField(
|
||||
scriptedPainlessFieldName2,
|
||||
|
@ -331,7 +327,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.settings.clickKibanaIndexPatterns();
|
||||
await PageObjects.settings.clickIndexPatternLogstash();
|
||||
const startingCount = parseInt(await PageObjects.settings.getScriptedFieldsTabCount(), 10);
|
||||
await PageObjects.settings.clickScriptedFieldsTab();
|
||||
await log.debug('add scripted field');
|
||||
await PageObjects.settings.addScriptedField(
|
||||
scriptedPainlessFieldName2,
|
||||
|
@ -428,7 +423,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.settings.clickKibanaIndexPatterns();
|
||||
await PageObjects.settings.clickIndexPatternLogstash();
|
||||
const startingCount = parseInt(await PageObjects.settings.getScriptedFieldsTabCount(), 10);
|
||||
await PageObjects.settings.clickScriptedFieldsTab();
|
||||
await log.debug('add scripted field');
|
||||
await PageObjects.settings.addScriptedField(
|
||||
scriptedPainlessFieldName2,
|
||||
|
|
|
@ -33,8 +33,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.settings.navigateTo();
|
||||
await PageObjects.settings.clickKibanaIndexPatterns();
|
||||
await PageObjects.settings.clickIndexPatternLogstash();
|
||||
await PageObjects.settings.clickScriptedFieldsTab();
|
||||
await PageObjects.settings.clickAddScriptedField();
|
||||
await PageObjects.settings.goToAddScriptedField();
|
||||
await PageObjects.settings.setScriptedFieldName(SCRIPTED_FIELD_NAME);
|
||||
});
|
||||
|
||||
|
|
|
@ -263,10 +263,12 @@ export class SettingsPageObject extends FtrService {
|
|||
}
|
||||
|
||||
async getScriptedFieldsTabCount() {
|
||||
return await this.retry.try(async () => {
|
||||
try {
|
||||
const text = await this.testSubjects.getVisibleText('tab-scriptedFields');
|
||||
return text.split(' ')[2].replace(/\((.*)\)/, '$1');
|
||||
});
|
||||
return text.split(' ')[2].replace(/\((.*)\)/, '$1') || '0';
|
||||
} catch (e) {
|
||||
return '0';
|
||||
}
|
||||
}
|
||||
|
||||
async getRelationshipsTabCount() {
|
||||
|
@ -727,7 +729,7 @@ export class SettingsPageObject extends FtrService {
|
|||
popularity: string,
|
||||
script: string
|
||||
) {
|
||||
await this.clickAddScriptedField();
|
||||
await this.goToAddScriptedField();
|
||||
await this.setScriptedFieldName(name);
|
||||
if (language) await this.setScriptedFieldLanguage(language);
|
||||
if (type) await this.setScriptedFieldType(type);
|
||||
|
@ -896,9 +898,12 @@ export class SettingsPageObject extends FtrService {
|
|||
await this.monacoEditor.setCodeEditorValue(script);
|
||||
}
|
||||
|
||||
async clickAddScriptedField() {
|
||||
this.log.debug('click Add Scripted Field');
|
||||
await this.testSubjects.click('addScriptedFieldLink');
|
||||
async goToAddScriptedField() {
|
||||
this.log.debug('go to Add Scripted Field url');
|
||||
const url = await this.browser.getCurrentUrl();
|
||||
const newUrl = url.split('#')[0];
|
||||
await this.browser.get(newUrl + '/create-field/');
|
||||
await this.header.waitUntilLoadingHasFinished();
|
||||
}
|
||||
|
||||
async clickSaveScriptedField() {
|
||||
|
|
|
@ -77,5 +77,6 @@
|
|||
"@kbn/default-nav-devtools",
|
||||
"@kbn/core-saved-objects-import-export-server-internal",
|
||||
"@kbn/management-settings-ids",
|
||||
"@kbn/core-deprecations-common",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -2476,9 +2476,6 @@
|
|||
"dataViews.contentManagementType": "Vue de données",
|
||||
"dataViews.dataStreamLabel": "Flux de données",
|
||||
"dataViews.deprecations.scriptedFields.manualStepOneMessage": "Accédez à Gestion de la Suite > Kibana > Vues de données.",
|
||||
"dataViews.deprecations.scriptedFields.manualStepTwoMessage": "Mettez à jour les vues de données {numberOfIndexPatternsWithScriptedFields} qui ont des champs scriptés pour qu’elles utilisent des champs d'exécution. Dans la plupart des cas, pour migrer des scripts existants, vous devrez remplacer \"return <value>;\" par \"emit(<value>);\". Vues de données avec au moins un champ scripté : {allTitles}",
|
||||
"dataViews.deprecations.scriptedFieldsMessage": "Vous avez {numberOfIndexPatternsWithScriptedFields} vues de données ({titlesPreview}...) qui utilisent des champs scriptés. Les champs scriptés sont déclassés et seront supprimés à l'avenir. Utilisez plutôt des champs d'exécution.",
|
||||
"dataViews.deprecations.scriptedFieldsTitle": "Vues de données utilisant des champs scriptés trouvées",
|
||||
"dataViews.fetchFieldErrorTitle": "Erreur lors de l'extraction des champs pour la vue de données {title} (ID : {id})",
|
||||
"dataViews.frozenLabel": "Frozen",
|
||||
"dataViews.functions.dataViewLoad.help": "Charge une vue de données",
|
||||
|
@ -5032,7 +5029,6 @@
|
|||
"indexPatternManagement.editIndexPattern.couldNotLoadMessage": "La vue de données ayant l'ID {objectId} n'a pas pu être chargée. Essayez d'en créer une nouvelle.",
|
||||
"indexPatternManagement.editIndexPattern.couldNotLoadTitle": "Impossible de charger la vue de données",
|
||||
"indexPatternManagement.editIndexPattern.deleteButton": "Supprimer",
|
||||
"indexPatternManagement.editIndexPattern.deprecation": "Les champs scriptés sont déclassés. Utilisez {runtimeDocs} à la place.",
|
||||
"indexPatternManagement.editIndexPattern.fields.addFieldButtonLabel": "Ajouter un champ",
|
||||
"indexPatternManagement.editIndexPattern.fields.conflictModal.closeBtn": "Fermer",
|
||||
"indexPatternManagement.editIndexPattern.fields.conflictModal.description": "Le type de champ {fieldName} change entre les index et peut ne pas être disponible pour la recherche, les visualisations et d'autres analyses.",
|
||||
|
@ -5080,12 +5076,9 @@
|
|||
"indexPatternManagement.editIndexPattern.list.histogramSummary": "{aggName} (intervalle : {interval})",
|
||||
"indexPatternManagement.editIndexPattern.mappingConflictHeader": "Conflit de mapping",
|
||||
"indexPatternManagement.editIndexPattern.mappingConflictLabel": "{conflictFieldsLength, plural, one {Un champ est défini} other {# champs sont définis}} avec plusieurs types (chaîne, entier, etc.) dans les différents index qui correspondent à ce modèle. Vous pourrez peut-être utiliser ce ou ces champs en conflit dans certaines parties de Kibana, mais ils ne seront pas disponibles pour les fonctions qui nécessitent que Kibana connaisse leur type. Pour corriger ce problème, vous devrez réindexer vos données.",
|
||||
"indexPatternManagement.editIndexPattern.scripted.addFieldButton": "Ajouter un champ scripté",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deleteField.cancelButton": "Annuler",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deleteField.deleteButton": "Supprimer",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deleteFieldLabel": "Supprimer le champ scripté \"{fieldName}\" ?",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deprecationLangHeader": "Langages déclassés en cours d'utilisation",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deprecationLangLabel.deprecationLangDetail": "Les langages déclassés suivants sont en cours d'utilisation : {deprecatedLangsInUse}. La prise en charge de ces langages sera supprimée dans la prochaine version majeure de Kibana et d'Elasticsearch. Convertissez vos champs scriptés en {link} pour éviter tout problème.",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deprecationLangLabel.painlessDescription": "Painless",
|
||||
"indexPatternManagement.editIndexPattern.scripted.newFieldPlaceholder": "Nouveau champ scripté",
|
||||
"indexPatternManagement.editIndexPattern.scripted.table.deleteDescription": "Supprimer ce champ",
|
||||
|
|
|
@ -2475,9 +2475,6 @@
|
|||
"dataViews.contentManagementType": "データビュー",
|
||||
"dataViews.dataStreamLabel": "データストリーム",
|
||||
"dataViews.deprecations.scriptedFields.manualStepOneMessage": "[スタック管理]>[Kibana]>[データビュー]に移動します。",
|
||||
"dataViews.deprecations.scriptedFields.manualStepTwoMessage": "ランタイムフィールドを使用するには、スクリプト化されたフィールドがある{numberOfIndexPatternsWithScriptedFields}データビューを更新します。ほとんどの場合、既存のスクリプトを移行するには、「return <value>;」から「emit(<value>);」に変更する必要があります。1つ以上のスクリプト化されたフィールドがあるデータビュー:{allTitles}",
|
||||
"dataViews.deprecations.scriptedFieldsMessage": "スクリプト化されたフィールドを使用する{numberOfIndexPatternsWithScriptedFields}データビュー({titlesPreview}...)があります。スクリプト化されたフィールドは廃止予定であり、今後は削除されます。ランタイムフィールドを使用してください。",
|
||||
"dataViews.deprecations.scriptedFieldsTitle": "スクリプト化されたフィールドを使用しているデータビューが見つかりました。",
|
||||
"dataViews.fetchFieldErrorTitle": "データビューのフィールド取得中にエラーが発生 {title}(ID:{id})",
|
||||
"dataViews.frozenLabel": "凍結",
|
||||
"dataViews.functions.dataViewLoad.help": "データビューを読み込みます",
|
||||
|
@ -5027,7 +5024,6 @@
|
|||
"indexPatternManagement.editIndexPattern.couldNotLoadMessage": "ID {objectId}のデータビューを読み込めませんでした。新規作成してください。",
|
||||
"indexPatternManagement.editIndexPattern.couldNotLoadTitle": "データビューを読み込めません",
|
||||
"indexPatternManagement.editIndexPattern.deleteButton": "削除",
|
||||
"indexPatternManagement.editIndexPattern.deprecation": "スクリプトフィールドは廃止予定です。代わりに{runtimeDocs}を使用してください。",
|
||||
"indexPatternManagement.editIndexPattern.fields.addFieldButtonLabel": "フィールドの追加",
|
||||
"indexPatternManagement.editIndexPattern.fields.conflictModal.closeBtn": "閉じる",
|
||||
"indexPatternManagement.editIndexPattern.fields.conflictModal.description": "{fieldName}フィールドの型がインデックス全体で変更され、検索、視覚化、他の分析で使用できない可能性があります。",
|
||||
|
@ -5075,12 +5071,9 @@
|
|||
"indexPatternManagement.editIndexPattern.list.histogramSummary": "{aggName} (間隔:{interval})",
|
||||
"indexPatternManagement.editIndexPattern.mappingConflictHeader": "マッピングの矛盾",
|
||||
"indexPatternManagement.editIndexPattern.mappingConflictLabel": "{conflictFieldsLength, plural, other {# 個のフィールド}}が、このパターンと一致するインデックスの間で異なるタイプ(文字列、整数など)に定義されています。これらの矛盾したフィールドはKibanaの一部で使用できますが、Kibanaがタイプを把握しなければならない機能には使用できません。この問題を修正するにはデータのレンダリングが必要です。",
|
||||
"indexPatternManagement.editIndexPattern.scripted.addFieldButton": "スクリプトフィールドを追加",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deleteField.cancelButton": "キャンセル",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deleteField.deleteButton": "削除",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deleteFieldLabel": "スクリプトフィールド''{fieldName}''を削除しますか?",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deprecationLangHeader": "廃止された言語が使用されています",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deprecationLangLabel.deprecationLangDetail": "次の廃止された言語が使用されています。{deprecatedLangsInUse}これらの言語は、KibanaとElasticsearchの次のメジャーバージョンでサポートされなくなります。問題を避けるため、スクリプトフィールドを{link}に変換してください。",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deprecationLangLabel.painlessDescription": "Painless",
|
||||
"indexPatternManagement.editIndexPattern.scripted.newFieldPlaceholder": "新規スクリプトフィールド",
|
||||
"indexPatternManagement.editIndexPattern.scripted.table.deleteDescription": "このフィールドを削除します",
|
||||
|
|
|
@ -2466,9 +2466,6 @@
|
|||
"dataViews.contentManagementType": "数据视图",
|
||||
"dataViews.dataStreamLabel": "数据流",
|
||||
"dataViews.deprecations.scriptedFields.manualStepOneMessage": "导航到'堆栈管理'>'Kibana'>'数据视图'。",
|
||||
"dataViews.deprecations.scriptedFields.manualStepTwoMessage": "更新 {numberOfIndexPatternsWithScriptedFields} 个具有脚本字段的数据视图以改为使用运行时字段。多数情况下,要迁移现有脚本,您需要将'return <value>;'更改为'emit(<value>);'。至少有一个脚本字段的数据视图:{allTitles}",
|
||||
"dataViews.deprecations.scriptedFieldsMessage": "您具有 {numberOfIndexPatternsWithScriptedFields} 个使用脚本字段的数据视图 ({titlesPreview}...)。脚本字段已过时,将在未来移除。请改为使用运行时脚本。",
|
||||
"dataViews.deprecations.scriptedFieldsTitle": "找到使用脚本字段的数据视图",
|
||||
"dataViews.fetchFieldErrorTitle": "提取数据视图 {title}(ID:{id})的字段时出错",
|
||||
"dataViews.frozenLabel": "已冻结",
|
||||
"dataViews.functions.dataViewLoad.help": "加载数据视图",
|
||||
|
@ -4993,7 +4990,6 @@
|
|||
"indexPatternManagement.editIndexPattern.couldNotLoadMessage": "无法加载 ID 为 {objectId} 的数据视图。尝试创建新视图。",
|
||||
"indexPatternManagement.editIndexPattern.couldNotLoadTitle": "无法加载数据视图",
|
||||
"indexPatternManagement.editIndexPattern.deleteButton": "删除",
|
||||
"indexPatternManagement.editIndexPattern.deprecation": "脚本字段已弃用。改用 {runtimeDocs}。",
|
||||
"indexPatternManagement.editIndexPattern.fields.addFieldButtonLabel": "添加字段",
|
||||
"indexPatternManagement.editIndexPattern.fields.conflictModal.closeBtn": "关闭",
|
||||
"indexPatternManagement.editIndexPattern.fields.conflictModal.description": "{fieldName} 字段的类型在不同索引中会有所不同,并且可能无法用于搜索、可视化和其他分析。",
|
||||
|
@ -5041,11 +5037,8 @@
|
|||
"indexPatternManagement.editIndexPattern.list.histogramSummary": "{aggName}(时间间隔:{interval})",
|
||||
"indexPatternManagement.editIndexPattern.mappingConflictHeader": "映射冲突",
|
||||
"indexPatternManagement.editIndexPattern.mappingConflictLabel": "{conflictFieldsLength, plural, one {一个字段} other {# 个字段}}已在匹配此模式的各个索引中定义为多个类型(字符串、整数等)。您也许仍能够在 Kibana 的各个部分中使用这些冲突字段,但它们将无法用于需要 Kibana 知道其类型的函数。要解决此问题,需要重新索引您的数据。",
|
||||
"indexPatternManagement.editIndexPattern.scripted.addFieldButton": "添加脚本字段",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deleteField.cancelButton": "取消",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deleteField.deleteButton": "删除",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deprecationLangHeader": "在用的过时语言",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deprecationLangLabel.deprecationLangDetail": "以下过时的语言仍在使用:{deprecatedLangsInUse}。Kibana 和 Elasticsearch 的下一主要版本将移除对这些语言的支持。将您的脚本字段转换成 {link} 以避免问题。",
|
||||
"indexPatternManagement.editIndexPattern.scripted.deprecationLangLabel.painlessDescription": "Painless",
|
||||
"indexPatternManagement.editIndexPattern.scripted.newFieldPlaceholder": "新建脚本字段",
|
||||
"indexPatternManagement.editIndexPattern.scripted.table.deleteDescription": "删除此字段",
|
||||
|
|
|
@ -22,6 +22,9 @@ import {
|
|||
EuiText,
|
||||
EuiCallOut,
|
||||
EuiSpacer,
|
||||
EuiMarkdownFormat,
|
||||
getDefaultEuiMarkdownPlugins,
|
||||
useEuiFontSize,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { uiMetricService, UIM_KIBANA_QUICK_RESOLVE_CLICK } from '../../lib/ui_metric';
|
||||
|
@ -103,6 +106,12 @@ const i18nTexts = {
|
|||
),
|
||||
};
|
||||
|
||||
const { processingPlugins } = getDefaultEuiMarkdownPlugins({
|
||||
processingConfig: {
|
||||
linkProps: { target: '_blank' },
|
||||
},
|
||||
});
|
||||
|
||||
interface AvailableCorrectiveActions {
|
||||
api: boolean;
|
||||
manual: boolean;
|
||||
|
@ -158,6 +167,8 @@ export const DeprecationDetailsFlyout = ({
|
|||
resolveDeprecation(deprecation);
|
||||
}, [deprecation, resolveDeprecation]);
|
||||
|
||||
const { lineHeight: lineHeightMedium } = useEuiFontSize('m');
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiFlyoutHeader hasBorder>
|
||||
|
@ -185,11 +196,30 @@ export const DeprecationDetailsFlyout = ({
|
|||
)}
|
||||
|
||||
<EuiText>
|
||||
{messages.map((m, i) => (
|
||||
<p key={i} className="eui-textBreakWord">
|
||||
{m}
|
||||
</p>
|
||||
))}
|
||||
{messages.map((currentMessage, i) => {
|
||||
if (typeof currentMessage === 'object' && currentMessage.type === 'markdown') {
|
||||
return (
|
||||
<EuiMarkdownFormat
|
||||
key={i}
|
||||
className="eui-textBreakWord"
|
||||
textSize="relative"
|
||||
processingPluginList={processingPlugins}
|
||||
css={{ marginBlockEnd: lineHeightMedium }}
|
||||
>
|
||||
{currentMessage.content}
|
||||
</EuiMarkdownFormat>
|
||||
);
|
||||
}
|
||||
|
||||
const textContent =
|
||||
typeof currentMessage === 'string' ? currentMessage : currentMessage.content;
|
||||
|
||||
return (
|
||||
<p key={i} className="eui-textBreakWord">
|
||||
{textContent}
|
||||
</p>
|
||||
);
|
||||
})}
|
||||
{documentationUrl && (
|
||||
<p>
|
||||
<DeprecationFlyoutLearnMoreLink documentationUrl={documentationUrl} />
|
||||
|
|
|
@ -58,7 +58,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await settings.navigateTo();
|
||||
await settings.clickKibanaIndexPatterns();
|
||||
await settings.createIndexPattern('logsta');
|
||||
await settings.clickScriptedFieldsTab();
|
||||
await log.debug('add scripted field');
|
||||
await settings.addScriptedField(
|
||||
'sharedFail',
|
||||
|
@ -114,7 +113,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await settings.clickKibanaIndexPatterns();
|
||||
await settings.clickIndexPatternLogstash();
|
||||
const startingCount = parseInt(await settings.getScriptedFieldsTabCount(), 10);
|
||||
await settings.clickScriptedFieldsTab();
|
||||
await log.debug('add scripted field');
|
||||
await settings.addScriptedField(
|
||||
'goodScript',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue