diff --git a/docs/management/manage-data-views.asciidoc b/docs/management/manage-data-views.asciidoc index 4c6a0d77b7a9e..60e425f77460c 100644 --- a/docs/management/manage-data-views.asciidoc +++ b/docs/management/manage-data-views.asciidoc @@ -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 <>, 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 @@ -192,6 +192,110 @@ doc['field_name'].value 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] +[[migrate-off-scripted-fields]] +==== Migrate to runtime fields or ES|QL queries + +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. + +[float] +[[scripted-field-example]] +===== Scripted field + +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. + +[source,text] +---- +def hour_of_day = $('@timestamp', ZonedDateTime.parse('1970-01-01T00:00:00Z')).getHour(); +def time_of_day = ''; + +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'; + +def response_int = Integer.parseInt($('response.keyword', '200')); +def response_category = ''; + +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] [[create-scripted-field]] ==== Create scripted fields @@ -214,6 +318,8 @@ For more information about scripted fields in {es}, refer to {ref}/modules-scrip [[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 <>. . Select the data view that contains the scripted field you want to manage. diff --git a/src/core/packages/deprecations/common/index.ts b/src/core/packages/deprecations/common/index.ts index de8122a18c551..828653289981b 100644 --- a/src/core/packages/deprecations/common/index.ts +++ b/src/core/packages/deprecations/common/index.ts @@ -8,6 +8,7 @@ */ export type { + DeprecationDetailsMessage, BaseDeprecationDetails, ConfigDeprecationDetails, FeatureDeprecationDetails, diff --git a/src/core/packages/deprecations/common/src/types.ts b/src/core/packages/deprecations/common/src/types.ts index 9a08be7808452..45f93aa5ba921 100644 --- a/src/core/packages/deprecations/common/src/types.ts +++ b/src/core/packages/deprecations/common/src/types.ts @@ -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; /** * levels: * - warning: will not break deployment upon upgrade diff --git a/src/platform/packages/shared/kbn-doc-links/src/get_doc_links.ts b/src/platform/packages/shared/kbn-doc-links/src/get_doc_links.ts index e11e9a564b935..45fa0a1757358 100644 --- a/src/platform/packages/shared/kbn-doc-links/src/get_doc_links.ts +++ b/src/platform/packages/shared/kbn-doc-links/src/get_doc_links.ts @@ -349,6 +349,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: { diff --git a/src/platform/packages/shared/kbn-doc-links/src/types.ts b/src/platform/packages/shared/kbn-doc-links/src/types.ts index 02cb037036d93..83f21ee36dc1a 100644 --- a/src/platform/packages/shared/kbn-doc-links/src/types.ts +++ b/src/platform/packages/shared/kbn-doc-links/src/types.ts @@ -307,6 +307,7 @@ export interface DocLinks { readonly fieldFormattersNumber: string; readonly fieldFormattersString: string; readonly runtimeFields: string; + readonly migrateOffScriptedFields: string; }; readonly addData: string; readonly kibana: { diff --git a/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/components/call_outs/__snapshots__/call_outs.test.tsx.snap b/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/components/call_outs/__snapshots__/call_outs.test.tsx.snap index 62e9cfb6e1278..432a526ffcafc 100644 --- a/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/components/call_outs/__snapshots__/call_outs.test.tsx.snap +++ b/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/components/call_outs/__snapshots__/call_outs.test.tsx.snap @@ -2,19 +2,22 @@ exports[`CallOuts should render normally 1`] = ` + } >

-
`; diff --git a/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.tsx b/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.tsx index 6f519bf20eb00..e4b5253c9de75 100644 --- a/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.tsx +++ b/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/components/call_outs/call_outs.tsx @@ -24,11 +24,12 @@ export const CallOuts = ({ deprecatedLangsInUse, painlessDocLink }: CallOutsProp return ( <> + } color="danger" @@ -38,7 +39,7 @@ export const CallOuts = ({ deprecatedLangsInUse, painlessDocLink }: CallOutsProp

- ); }; diff --git a/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/components/header/__snapshots__/header.test.tsx.snap b/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/components/header/__snapshots__/header.test.tsx.snap index 40cd0974b163b..59cfe17aa14a4 100644 --- a/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/components/header/__snapshots__/header.test.tsx.snap +++ b/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/components/header/__snapshots__/header.test.tsx.snap @@ -2,33 +2,59 @@ exports[`Header should render normally 1`] = `
-

- - Scripted fields can be used in visualizations and displayed in documents. However, they cannot be searched. - -
+

+
+
- Scripted fields are deprecated. Use + Use - instead. + instead of scripted fields. Runtime fields support Painless scripting and provide greater flexibility. You can also use the + + to compute values directly at query time. + +
+
+
+
+

+ + Scripted fields can be used in visualizations and displayed in documents. However, they cannot be searched.

diff --git a/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/components/header/header.tsx b/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/components/header/header.tsx index 2acfee2d78648..c50caa486210c 100644 --- a/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/components/header/header.tsx +++ b/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/components/header/header.tsx @@ -9,9 +9,19 @@ import React from 'react'; import { withRouter, RouteComponentProps } from 'react-router-dom'; -import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiText, EuiLink, EuiIcon } from '@elastic/eui'; +import { + EuiCallOut, + EuiButton, + EuiFlexGroup, + EuiFlexItem, + EuiText, + EuiLink, + EuiSpacer, +} from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; + import { ScopedHistory } from '@kbn/core/public'; import { reactRouterNavigate, useKibana } from '@kbn/kibana-react-plugin/public'; @@ -27,8 +37,40 @@ export const Header = withRouter(({ indexPatternId, history }: HeaderProps) => { const links = docLinks?.links; const userEditPermission = dataViews.getCanSaveSync(); return ( - + + + + + + ), + esqlLink: ( + + + + ), + }} + /> + +

{ id="indexPatternManagement.editIndexPattern.scriptedLabel" defaultMessage="Scripted fields can be used in visualizations and displayed in documents. However, they cannot be searched." /> -
- - - - - ), - }} - />

diff --git a/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/scripted_fields_table.tsx b/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/scripted_fields_table.tsx index 1a8483db6c6aa..3820a035177bd 100644 --- a/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/scripted_fields_table.tsx +++ b/src/platform/plugins/shared/data_view_management/public/components/edit_index_pattern/scripted_fields_table/scripted_fields_table.tsx @@ -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); } } diff --git a/src/platform/plugins/shared/data_view_management/public/mocks.ts b/src/platform/plugins/shared/data_view_management/public/mocks.ts index 6abc53a64d3cf..dfc924ac5d49e 100644 --- a/src/platform/plugins/shared/data_view_management/public/mocks.ts +++ b/src/platform/plugins/shared/data_view_management/public/mocks.ts @@ -57,6 +57,7 @@ const docLinks = { indexPatterns: {}, scriptedFields: {}, runtimeFields: {}, + query: {}, } as any, }; diff --git a/src/platform/plugins/shared/data_views/server/deprecations/scripted_fields.ts b/src/platform/plugins/shared/data_views/server/deprecations/scripted_fields.ts index 5866216801ab6..a70bb29219dcd 100644 --- a/src/platform/plugins/shared/data_views/server/deprecations/scripted_fields.ts +++ b/src/platform/plugins/shared/data_views/server/deprecations/scripted_fields.ts @@ -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; +type DataViewAttributesWithFields = Pick; export const createScriptedFieldsDeprecationsConfig: ( core: CoreSetup ) => RegisterDeprecationsConfig = (core: CoreSetup) => ({ getDeprecations: async (context: GetDeprecationsContext): Promise => { - const finder = - context.savedObjectsClient.createPointInTimeFinder({ + const finder = context.savedObjectsClient.createPointInTimeFinder( + { type: 'index-pattern', perPage: 1000, - fields: ['title', 'fields'], + fields: ['name', 'title', 'fields'], namespaces: ['*'], - }); + } + ); + + const dataViewsWithScriptedFields: Array> = + []; - 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 ;" to "emit();". 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 ;" to "emit();".', + 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 +) => `- **${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>; + 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'), + }, + }), +}); diff --git a/src/platform/plugins/shared/data_views/tsconfig.json b/src/platform/plugins/shared/data_views/tsconfig.json index 88f70b9de8da9..1a029d0b17b13 100644 --- a/src/platform/plugins/shared/data_views/tsconfig.json +++ b/src/platform/plugins/shared/data_views/tsconfig.json @@ -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/**/*", diff --git a/test/api_integration/apis/data_views/deprecations/scripted_fields.ts b/test/api_integration/apis/data_views/deprecations/scripted_fields.ts index 083fabada4ec7..6f54a02f97b3a 100644 --- a/test/api_integration/apis/data_views/deprecations/scripted_fields.ts +++ b/test/api_integration/apis/data_views/deprecations/scripted_fields.ts @@ -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 + ); }); }); } diff --git a/test/tsconfig.json b/test/tsconfig.json index 1d8c301c44a2b..d7e0de39d5e5e 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -77,5 +77,6 @@ "@kbn/default-nav-devtools", "@kbn/core-saved-objects-import-export-server-internal", "@kbn/management-settings-ids", + "@kbn/core-deprecations-common", ] } diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index 31550b06fa0b0..1c9c624d27447 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -2463,9 +2463,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 ;\" par \"emit();\". 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", @@ -5018,7 +5015,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.", @@ -5070,8 +5066,6 @@ "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", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index 6b06da4e230c5..85e44f4925df0 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -2462,9 +2462,6 @@ "dataViews.contentManagementType": "データビュー", "dataViews.dataStreamLabel": "データストリーム", "dataViews.deprecations.scriptedFields.manualStepOneMessage": "[スタック管理]>[Kibana]>[データビュー]に移動します。", - "dataViews.deprecations.scriptedFields.manualStepTwoMessage": "ランタイムフィールドを使用するには、スクリプト化されたフィールドがある{numberOfIndexPatternsWithScriptedFields}データビューを更新します。ほとんどの場合、既存のスクリプトを移行するには、「return ;」から「emit();」に変更する必要があります。1つ以上のスクリプト化されたフィールドがあるデータビュー:{allTitles}", - "dataViews.deprecations.scriptedFieldsMessage": "スクリプト化されたフィールドを使用する{numberOfIndexPatternsWithScriptedFields}データビュー({titlesPreview}...)があります。スクリプト化されたフィールドは廃止予定であり、今後は削除されます。ランタイムフィールドを使用してください。", - "dataViews.deprecations.scriptedFieldsTitle": "スクリプト化されたフィールドを使用しているデータビューが見つかりました。", "dataViews.fetchFieldErrorTitle": "データビューのフィールド取得中にエラーが発生 {title}(ID:{id})", "dataViews.frozenLabel": "凍結", "dataViews.functions.dataViewLoad.help": "データビューを読み込みます", @@ -5012,7 +5009,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}フィールドの型がインデックス全体で変更され、検索、視覚化、他の分析で使用できない可能性があります。", @@ -5064,8 +5060,6 @@ "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": "このフィールドを削除します", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index bd8c593300c63..3c9af5f8adc5a 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -2491,9 +2491,6 @@ "dataViews.contentManagementType": "数据视图", "dataViews.dataStreamLabel": "数据流", "dataViews.deprecations.scriptedFields.manualStepOneMessage": "导航到“堆栈管理”>“Kibana”>“数据视图”。", - "dataViews.deprecations.scriptedFields.manualStepTwoMessage": "更新 {numberOfIndexPatternsWithScriptedFields} 个具有脚本字段的数据视图以改为使用运行时字段。多数情况下,要迁移现有脚本,您需要将“return ;”更改为“emit();”。至少有一个脚本字段的数据视图:{allTitles}", - "dataViews.deprecations.scriptedFieldsMessage": "您具有 {numberOfIndexPatternsWithScriptedFields} 个使用脚本字段的数据视图 ({titlesPreview}...)。脚本字段已过时,将在未来移除。请改为使用运行时脚本。", - "dataViews.deprecations.scriptedFieldsTitle": "找到使用脚本字段的数据视图", "dataViews.fetchFieldErrorTitle": "提取数据视图 {title}(ID:{id})的字段时出错", "dataViews.frozenLabel": "已冻结", "dataViews.functions.dataViewLoad.help": "加载数据视图", @@ -5051,7 +5048,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} 字段的类型在不同索引中会有所不同,并且可能无法用于搜索、可视化和其他分析。", @@ -5103,8 +5099,6 @@ "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": "删除此字段", diff --git a/x-pack/platform/plugins/private/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx b/x-pack/platform/plugins/private/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx index beb4c7c0c678c..7c03e5e770ade 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx +++ b/x-pack/platform/plugins/private/upgrade_assistant/public/application/components/kibana_deprecations/deprecation_details_flyout.tsx @@ -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 ( <> @@ -185,11 +196,30 @@ export const DeprecationDetailsFlyout = ({ )} - {messages.map((m, i) => ( -

- {m} -

- ))} + {messages.map((currentMessage, i) => { + if (typeof currentMessage === 'object' && currentMessage.type === 'markdown') { + return ( + + {currentMessage.content} + + ); + } + + const textContent = + typeof currentMessage === 'string' ? currentMessage : currentMessage.content; + + return ( +

+ {textContent} +

+ ); + })} {documentationUrl && (