From 98a46f9a8a9b67f8c01feb94d89a4c024710eb87 Mon Sep 17 00:00:00 2001 From: Krzysztof Kowalczyk Date: Mon, 18 Nov 2024 12:37:49 +0100 Subject: [PATCH] [Papercut] Fix KQL parsing error text styling (#199985) ## Summary This PR fixes styling for `KQL parsing error` text on various elements on `Maps` and `Dashboard` to have the invalid syntax and ASCII arrow on new line. Closes: #49377 ![dashboard1](https://github.com/user-attachments/assets/c607c0e0-24d8-4bd9-8106-d5c94fe1197d) ![dashboard2](https://github.com/user-attachments/assets/cb4b58af-6d8b-4609-9a4e-b948b1ec9340) ![dashboard3](https://github.com/user-attachments/assets/5a6c883e-76dc-4f9d-8db6-94c3e0bc359a) ![maps](https://github.com/user-attachments/assets/83d897a4-6856-4c47-8b14-18a1fff1de9d) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- packages/kbn-react-hooks/README.md | 20 ++++++++++++++++-- packages/kbn-react-hooks/index.ts | 1 + .../src/use_error_text_style/index.ts | 10 +++++++++ .../use_error_text_style.ts | 21 +++++++++++++++++++ .../components/control_error.tsx | 4 +++- src/plugins/controls/tsconfig.json | 1 + .../presentation_panel_error.tsx | 5 ++++- src/plugins/presentation_panel/tsconfig.json | 3 ++- .../embeddable/visualize_embeddable.tsx | 8 ++++--- src/plugins/visualizations/tsconfig.json | 3 ++- .../layer_toc/toc_entry/legend_details.tsx | 7 +++++-- x-pack/plugins/maps/tsconfig.json | 3 ++- 12 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 packages/kbn-react-hooks/src/use_error_text_style/index.ts create mode 100644 packages/kbn-react-hooks/src/use_error_text_style/use_error_text_style.ts diff --git a/packages/kbn-react-hooks/README.md b/packages/kbn-react-hooks/README.md index 792df6534c8d8..6eba8db3641d6 100644 --- a/packages/kbn-react-hooks/README.md +++ b/packages/kbn-react-hooks/README.md @@ -4,7 +4,7 @@ A utility package, `@kbn/react-hooks`, provides custom react hooks for simple ab ## Custom Hooks -### [useBoolean](./src/useBoolean) +### [useBoolean](./src/use_boolean/use_boolean.ts) Simplify handling boolean value with predefined handlers. @@ -25,4 +25,20 @@ function App() { ); } -``` \ No newline at end of file +``` + +### [useErrorTextStyle](./src/use_error_text_style/use_error_text_style.ts) + +Returns styles used for styling error text. + +```tsx +function App() { + const errorTextStyle = useErrorTextStyle(); + + return ( +
+ Error message +
+ ); +} +``` diff --git a/packages/kbn-react-hooks/index.ts b/packages/kbn-react-hooks/index.ts index 51c15bd0f10d2..0c8550091ef5a 100644 --- a/packages/kbn-react-hooks/index.ts +++ b/packages/kbn-react-hooks/index.ts @@ -8,4 +8,5 @@ */ export { useBoolean } from './src/use_boolean'; +export { useErrorTextStyle } from './src/use_error_text_style'; export type { UseBooleanHandlers, UseBooleanResult } from './src/use_boolean'; diff --git a/packages/kbn-react-hooks/src/use_error_text_style/index.ts b/packages/kbn-react-hooks/src/use_error_text_style/index.ts new file mode 100644 index 0000000000000..3cbc69f2b988d --- /dev/null +++ b/packages/kbn-react-hooks/src/use_error_text_style/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +export * from './use_error_text_style'; diff --git a/packages/kbn-react-hooks/src/use_error_text_style/use_error_text_style.ts b/packages/kbn-react-hooks/src/use_error_text_style/use_error_text_style.ts new file mode 100644 index 0000000000000..cb21a95c6ae71 --- /dev/null +++ b/packages/kbn-react-hooks/src/use_error_text_style/use_error_text_style.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import { css } from '@emotion/react'; +import { useEuiTheme } from '@elastic/eui'; + +export const useErrorTextStyle = () => { + const { euiTheme } = useEuiTheme(); + const errorTextStyle = css` + font-family: ${euiTheme.font.familyCode}; + white-space: break-spaces; + `; + + return errorTextStyle; +}; diff --git a/src/plugins/controls/public/control_group/components/control_error.tsx b/src/plugins/controls/public/control_group/components/control_error.tsx index 2ef6b06faeedd..80d33d8225b3b 100644 --- a/src/plugins/controls/public/control_group/components/control_error.tsx +++ b/src/plugins/controls/public/control_group/components/control_error.tsx @@ -12,12 +12,14 @@ import React, { useState } from 'react'; import { EuiButtonEmpty, EuiPopover } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { Markdown } from '@kbn/shared-ux-markdown'; +import { useErrorTextStyle } from '@kbn/react-hooks'; interface ControlErrorProps { error: Error | string; } export const ControlError = ({ error }: ControlErrorProps) => { + const errorTextStyle = useErrorTextStyle(); const [isPopoverOpen, setPopoverOpen] = useState(false); const errorMessage = error instanceof Error ? error.message : error; @@ -47,7 +49,7 @@ export const ControlError = ({ error }: ControlErrorProps) => { className="controlPanel errorEmbeddableCompact__popover" closePopover={() => setPopoverOpen(false)} > - + {errorMessage} diff --git a/src/plugins/controls/tsconfig.json b/src/plugins/controls/tsconfig.json index 41ab33dc18969..7759a0fdc7935 100644 --- a/src/plugins/controls/tsconfig.json +++ b/src/plugins/controls/tsconfig.json @@ -39,6 +39,7 @@ "@kbn/presentation-panel-plugin", "@kbn/shared-ux-utility", "@kbn/std", + "@kbn/react-hooks", ], "exclude": ["target/**/*"] } diff --git a/src/plugins/presentation_panel/public/panel_component/presentation_panel_error.tsx b/src/plugins/presentation_panel/public/panel_component/presentation_panel_error.tsx index 5e6ac14d14328..4973e2599ddad 100644 --- a/src/plugins/presentation_panel/public/panel_component/presentation_panel_error.tsx +++ b/src/plugins/presentation_panel/public/panel_component/presentation_panel_error.tsx @@ -16,6 +16,7 @@ import { renderSearchError } from '@kbn/search-errors'; import { Markdown } from '@kbn/shared-ux-markdown'; import { Subscription } from 'rxjs'; import { i18n } from '@kbn/i18n'; +import { useErrorTextStyle } from '@kbn/react-hooks'; import { editPanelAction } from '../panel_actions/panel_actions'; import { getErrorCallToAction } from './presentation_panel_strings'; import { DefaultPresentationPanelApi } from './types'; @@ -27,6 +28,8 @@ export const PresentationPanelError = ({ error: ErrorLike; api?: DefaultPresentationPanelApi; }) => { + const errorTextStyle = useErrorTextStyle(); + const [isEditable, setIsEditable] = useState(false); const handleErrorClick = useMemo( () => (isEditable ? () => editPanelAction?.execute({ embeddable: api }) : undefined), @@ -82,7 +85,7 @@ export const PresentationPanelError = ({ + {error.message?.length ? error.message diff --git a/src/plugins/presentation_panel/tsconfig.json b/src/plugins/presentation_panel/tsconfig.json index 9b867c0ada43c..255e4fd4eccde 100644 --- a/src/plugins/presentation_panel/tsconfig.json +++ b/src/plugins/presentation_panel/tsconfig.json @@ -28,7 +28,8 @@ "@kbn/data-views-plugin", "@kbn/panel-loader", "@kbn/search-errors", - "@kbn/shared-ux-markdown" + "@kbn/shared-ux-markdown", + "@kbn/react-hooks" ], "exclude": ["target/**/*"] } diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx index 52c76a426dc14..7b48521265d6f 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx @@ -7,7 +7,7 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { EuiEmptyPrompt, EuiFlexGroup, EuiLoadingChart } from '@elastic/eui'; +import { EuiEmptyPrompt, EuiFlexGroup, EuiLoadingChart, EuiText } from '@elastic/eui'; import { isChartSizeEvent } from '@kbn/chart-expressions-common'; import { APPLY_FILTER_TRIGGER } from '@kbn/data-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; @@ -38,6 +38,7 @@ import { apiPublishesSearchSession } from '@kbn/presentation-publishing/interfac import { get, isEmpty, isEqual, isNil, omitBy } from 'lodash'; import React, { useEffect, useRef } from 'react'; import { BehaviorSubject, switchMap } from 'rxjs'; +import { useErrorTextStyle } from '@kbn/react-hooks'; import { VISUALIZE_APP_NAME, VISUALIZE_EMBEDDABLE_TYPE } from '../../common/constants'; import { VIS_EVENT_TO_TRIGGER } from './events'; import { getInspector, getUiActions, getUsageCollection } from '../services'; @@ -454,6 +455,7 @@ export const getVisualizeEmbeddableFactory: (deps: { const hasRendered = useStateFromPublishingSubject(hasRendered$); const domNode = useRef(null); const { error, isLoading } = useExpressionRenderer(domNode, expressionParams); + const errorTextStyle = useErrorTextStyle(); useEffect(() => { return () => { @@ -495,9 +497,9 @@ export const getVisualizeEmbeddableFactory: (deps: { } body={ -

+ {error.name}: {error.message} -

+
} /> )} diff --git a/src/plugins/visualizations/tsconfig.json b/src/plugins/visualizations/tsconfig.json index 06d3931fe8e08..51deaf4139aa2 100644 --- a/src/plugins/visualizations/tsconfig.json +++ b/src/plugins/visualizations/tsconfig.json @@ -72,7 +72,8 @@ "@kbn/presentation-containers", "@kbn/search-response-warnings", "@kbn/embeddable-enhanced-plugin", - "@kbn/content-management-utils" + "@kbn/content-management-utils", + "@kbn/react-hooks" ], "exclude": ["target/**/*"] } diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/legend_details.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/legend_details.tsx index 3f9e5c8f11627..37257746006cd 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/legend_details.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/legend_details.tsx @@ -8,6 +8,7 @@ import React from 'react'; import { Adapters } from '@kbn/inspector-plugin/common/adapters'; import { EuiCallOut, EuiSpacer } from '@elastic/eui'; +import { useErrorTextStyle } from '@kbn/react-hooks'; import type { ILayer } from '../../../../../classes/layers/layer'; interface Props { @@ -16,13 +17,15 @@ interface Props { } export function LegendDetails({ inspectorAdapters, layer }: Props) { + const errorTextStyle = useErrorTextStyle(); + const errors = layer.getErrors(inspectorAdapters); if (errors.length) { return ( <> {errors.map(({ title, body }, index) => (
- + {body} @@ -37,7 +40,7 @@ export function LegendDetails({ inspectorAdapters, layer }: Props) { <> {warnings.map(({ title, body }, index) => (
- + {body} diff --git a/x-pack/plugins/maps/tsconfig.json b/x-pack/plugins/maps/tsconfig.json index dfee193ed0a25..e82e35b5ccbfd 100644 --- a/x-pack/plugins/maps/tsconfig.json +++ b/x-pack/plugins/maps/tsconfig.json @@ -90,7 +90,8 @@ "@kbn/react-kibana-context-render", "@kbn/embeddable-enhanced-plugin", "@kbn/presentation-containers", - "@kbn/field-utils" + "@kbn/field-utils", + "@kbn/react-hooks" ], "exclude": [ "target/**/*",