mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[ES|QL] Add line breaks redesign (#173596)
## Summary
Part of https://github.com/elastic/kibana/issues/171831
Replaces the single boolean button with two ever-present buttons that
allow the user to "Add line breaks on pipes" and "Remove line breaks on
pipes"
<img width="435" alt="image"
src="a7042e15
-f5b4-4a24-aa68-a7b7ca980895">
### Note
I had to use the TooltipWrapper and realized we are using this in many
places and every time we are duplicating the code. I moved it to
visualization-utils and changed the occurences.
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
1f3d3eaaa7
commit
b40b566e99
27 changed files with 96 additions and 149 deletions
|
@ -8,11 +8,11 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { TooltipWrapper } from '@kbn/visualization-utils';
|
||||
import React, { useCallback, Dispatch, useContext } from 'react';
|
||||
import { EuiFlexGroup, EuiButtonEmpty, EuiFlexItem } from '@elastic/eui';
|
||||
|
||||
import { DistributeEquallyIcon } from '../assets/distribute_equally';
|
||||
import { TooltipWrapper } from '../tooltip_wrapper';
|
||||
|
||||
import type { ColorRangesActions } from './types';
|
||||
import { ColorRangesContext } from './color_ranges_context';
|
||||
|
|
|
@ -10,11 +10,11 @@ import React, { Dispatch, useCallback, useContext } from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { EuiButtonIcon, EuiIconProps } from '@elastic/eui';
|
||||
import { TooltipWrapper } from '@kbn/visualization-utils';
|
||||
|
||||
import type { PaletteContinuity, CustomPaletteParams } from '../../../palettes';
|
||||
|
||||
import { isLastItem } from './utils';
|
||||
import { TooltipWrapper } from '../tooltip_wrapper';
|
||||
|
||||
import type { ColorRangesActions, ColorRange, ColorRangeAccessor } from './types';
|
||||
import { ColorRangesContext } from './color_ranges_context';
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
"@kbn/test-jest-helpers",
|
||||
"@kbn/data-plugin",
|
||||
"@kbn/ui-theme",
|
||||
"@kbn/visualization-utils",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -22,6 +22,7 @@ import { getAggregateQueryMode, getLanguageDisplayName } from '@kbn/es-query';
|
|||
import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
|
||||
import type { ExpressionsStart } from '@kbn/expressions-plugin/public';
|
||||
import type { IndexManagementPluginSetup } from '@kbn/index-management-plugin/public';
|
||||
import { TooltipWrapper } from '@kbn/visualization-utils';
|
||||
import {
|
||||
type LanguageDocumentationSections,
|
||||
LanguageDocumentationPopover,
|
||||
|
@ -172,7 +173,6 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({
|
|||
const [showLineNumbers, setShowLineNumbers] = useState(isCodeEditorExpanded);
|
||||
const [isCompactFocused, setIsCompactFocused] = useState(isCodeEditorExpanded);
|
||||
const [isCodeEditorExpandedFocused, setIsCodeEditorExpandedFocused] = useState(false);
|
||||
const [isWordWrapped, setIsWordWrapped] = useState(false);
|
||||
|
||||
const [editorMessages, setEditorMessages] = useState<{
|
||||
errors: MonacoMessage[];
|
||||
|
@ -478,15 +478,14 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({
|
|||
}
|
||||
}, [calculateVisibleCode, code, isCompactFocused, queryString]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isCodeEditorExpanded && !isWordWrapped) {
|
||||
const pipes = code?.split('|');
|
||||
const pipesWithNewLine = code?.split('\n|');
|
||||
if (pipes?.length === pipesWithNewLine?.length) {
|
||||
setIsWordWrapped(true);
|
||||
}
|
||||
}
|
||||
}, [code, isCodeEditorExpanded, isWordWrapped]);
|
||||
const linesBreaksButtonsStatus = useMemo(() => {
|
||||
const pipes = code?.split('|');
|
||||
const pipesWithNewLine = code?.split('\n|');
|
||||
return {
|
||||
addLineBreaksDisabled: pipes?.length === pipesWithNewLine?.length,
|
||||
removeLineBreaksDisabled: pipesWithNewLine?.length === 1,
|
||||
};
|
||||
}, [code]);
|
||||
|
||||
const onResize = ({ width }: { width: number }) => {
|
||||
setIsSpaceReduced(Boolean(editorIsInline && width < BREAKPOINT_WIDTH));
|
||||
|
@ -499,7 +498,6 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({
|
|||
const onQueryUpdate = useCallback(
|
||||
(value: string) => {
|
||||
setCode(value);
|
||||
setIsWordWrapped(false);
|
||||
onTextLangQueryChange({ [language]: value } as AggregateQuery);
|
||||
},
|
||||
[language, onTextLangQueryChange]
|
||||
|
@ -561,58 +559,72 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({
|
|||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiToolTip
|
||||
position="top"
|
||||
content={
|
||||
isWordWrapped
|
||||
? i18n.translate(
|
||||
'textBasedEditor.query.textBasedLanguagesEditor.disableWordWrapLabel',
|
||||
{
|
||||
defaultMessage: 'Disable wrap with pipes',
|
||||
}
|
||||
)
|
||||
: i18n.translate(
|
||||
<EuiFlexGroup responsive={false} gutterSize="none" alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<TooltipWrapper
|
||||
tooltipContent={i18n.translate(
|
||||
'textBasedEditor.query.textBasedLanguagesEditor.EnableWordWrapLabel',
|
||||
{
|
||||
defaultMessage: 'Add line breaks on pipes',
|
||||
}
|
||||
)}
|
||||
condition={!linesBreaksButtonsStatus.addLineBreaksDisabled}
|
||||
>
|
||||
<EuiButtonIcon
|
||||
iconType="pipeBreaks"
|
||||
color="text"
|
||||
size="s"
|
||||
data-test-subj="TextBasedLangEditor-toggleWordWrap"
|
||||
aria-label={i18n.translate(
|
||||
'textBasedEditor.query.textBasedLanguagesEditor.EnableWordWrapLabel',
|
||||
{
|
||||
defaultMessage: 'Wrap with pipes',
|
||||
defaultMessage: 'Add line breaks on pipes',
|
||||
}
|
||||
)
|
||||
}
|
||||
>
|
||||
<EuiButtonIcon
|
||||
iconType={isWordWrapped ? 'wordWrap' : 'wordWrapDisabled'}
|
||||
color="text"
|
||||
size="s"
|
||||
data-test-subj="TextBasedLangEditor-toggleWordWrap"
|
||||
aria-label={
|
||||
isWordWrapped
|
||||
? i18n.translate(
|
||||
'textBasedEditor.query.textBasedLanguagesEditor.disableWordWrapLabel',
|
||||
{
|
||||
defaultMessage: 'Disable wrap with pipes',
|
||||
}
|
||||
)
|
||||
: i18n.translate(
|
||||
'textBasedEditor.query.textBasedLanguagesEditor.EnableWordWrapLabel',
|
||||
{
|
||||
defaultMessage: 'Wrap with pipes',
|
||||
}
|
||||
)
|
||||
}
|
||||
isSelected={!isWordWrapped}
|
||||
onClick={() => {
|
||||
editor1.current?.updateOptions({
|
||||
wordWrap: isWordWrapped ? 'off' : 'on',
|
||||
});
|
||||
setIsWordWrapped(!isWordWrapped);
|
||||
const updatedCode = getWrappedInPipesCode(code, isWordWrapped);
|
||||
if (code !== updatedCode) {
|
||||
setCode(updatedCode);
|
||||
onTextLangQueryChange({ [language]: updatedCode } as AggregateQuery);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</EuiToolTip>
|
||||
)}
|
||||
isDisabled={linesBreaksButtonsStatus.addLineBreaksDisabled}
|
||||
onClick={() => {
|
||||
const updatedCode = getWrappedInPipesCode(code, false);
|
||||
if (code !== updatedCode) {
|
||||
setCode(updatedCode);
|
||||
onTextLangQueryChange({ [language]: updatedCode } as AggregateQuery);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</TooltipWrapper>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<TooltipWrapper
|
||||
tooltipContent={i18n.translate(
|
||||
'textBasedEditor.query.textBasedLanguagesEditor.disableWordWrapLabel',
|
||||
{
|
||||
defaultMessage: 'Remove line breaks on pipes',
|
||||
}
|
||||
)}
|
||||
condition={!linesBreaksButtonsStatus.removeLineBreaksDisabled}
|
||||
>
|
||||
<EuiButtonIcon
|
||||
iconType="pipeNoBreaks"
|
||||
color="text"
|
||||
size="s"
|
||||
data-test-subj="TextBasedLangEditor-toggleWordWrap"
|
||||
aria-label={i18n.translate(
|
||||
'textBasedEditor.query.textBasedLanguagesEditor.disableWordWrapLabel',
|
||||
{
|
||||
defaultMessage: 'Remove line breaks on pipes',
|
||||
}
|
||||
)}
|
||||
isDisabled={linesBreaksButtonsStatus.removeLineBreaksDisabled}
|
||||
onClick={() => {
|
||||
const updatedCode = getWrappedInPipesCode(code, true);
|
||||
if (code !== updatedCode) {
|
||||
setCode(updatedCode);
|
||||
onTextLangQueryChange({ [language]: updatedCode } as AggregateQuery);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</TooltipWrapper>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup responsive={false} gutterSize="none" alignItems="center">
|
||||
|
|
|
@ -23,7 +23,8 @@
|
|||
"@kbn/data-plugin",
|
||||
"@kbn/expressions-plugin",
|
||||
"@kbn/data-views-plugin",
|
||||
"@kbn/index-management-plugin"
|
||||
"@kbn/index-management-plugin",
|
||||
"@kbn/visualization-utils"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { TooltipWrapper } from '@kbn/visualization-utils';
|
||||
import {
|
||||
EuiFormRow,
|
||||
EuiColorPicker,
|
||||
|
@ -17,7 +18,6 @@ import {
|
|||
euiPaletteColorBlind,
|
||||
} from '@elastic/eui';
|
||||
import { getColorAlpha, makeColorWithAlpha } from '@kbn/coloring';
|
||||
import { TooltipWrapper } from './tooltip_wrapper';
|
||||
|
||||
const tooltipContent = {
|
||||
auto: i18n.translate('visualizationUiComponents.colorPicker.tooltip.auto', {
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
EuiPanel,
|
||||
useEuiTheme,
|
||||
} from '@elastic/eui';
|
||||
import { TooltipWrapper } from '../tooltip_wrapper';
|
||||
import { TooltipWrapper } from '@kbn/visualization-utils';
|
||||
import type { BucketContainerProps } from './types';
|
||||
|
||||
export const DefaultBucketContainer = ({
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
EuiPanel,
|
||||
useEuiTheme,
|
||||
} from '@elastic/eui';
|
||||
import { TooltipWrapper } from '../tooltip_wrapper';
|
||||
import { TooltipWrapper } from '@kbn/visualization-utils';
|
||||
import type { BucketContainerProps } from './types';
|
||||
|
||||
export const FieldsBucketContainer = ({
|
||||
|
|
|
@ -14,8 +14,6 @@ export * from './debounced_input';
|
|||
|
||||
export * from './debounced_value';
|
||||
|
||||
export * from './tooltip_wrapper';
|
||||
|
||||
export * from './color_picker';
|
||||
|
||||
export * from './icon_select';
|
||||
|
|
|
@ -11,7 +11,6 @@ export {
|
|||
NameInput,
|
||||
DebouncedInput,
|
||||
useDebouncedValue,
|
||||
TooltipWrapper,
|
||||
ColorPicker,
|
||||
IconSelect,
|
||||
IconSelectSetting,
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
"@kbn/coloring",
|
||||
"@kbn/field-formats-plugin",
|
||||
"@kbn/field-utils",
|
||||
"@kbn/calculate-width-from-char-count"
|
||||
"@kbn/calculate-width-from-char-count",
|
||||
"@kbn/visualization-utils"
|
||||
],
|
||||
}
|
||||
|
|
|
@ -7,3 +7,4 @@
|
|||
*/
|
||||
|
||||
export { getTimeZone } from './src/get_timezone';
|
||||
export { TooltipWrapper } from './src/tooltip_wrapper';
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import { EuiFlexGroup, EuiFlexItem, EuiRange, EuiText, useEuiTheme } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { TooltipWrapper } from './tooltip_wrapper';
|
||||
import { TooltipWrapper } from '@kbn/visualization-utils';
|
||||
|
||||
export interface ControlSliderProps {
|
||||
/** Allowed values to show on the Control Slider */
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiToolTip, EuiToolTipProps } from '@elastic/eui';
|
||||
|
||||
export type TooltipWrapperProps = Partial<Omit<EuiToolTipProps, 'content'>> & {
|
||||
tooltipContent: string;
|
||||
/** When the condition is truthy, the tooltip will be shown */
|
||||
condition: boolean;
|
||||
};
|
||||
|
||||
export const TooltipWrapper: React.FunctionComponent<TooltipWrapperProps> = ({
|
||||
children,
|
||||
condition,
|
||||
tooltipContent,
|
||||
...tooltipProps
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
{condition ? (
|
||||
<EuiToolTip content={tooltipContent} delay="long" {...tooltipProps}>
|
||||
<>{children}</>
|
||||
</EuiToolTip>
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -13,6 +13,7 @@
|
|||
],
|
||||
"kbn_references": [
|
||||
"@kbn/i18n-react",
|
||||
"@kbn/visualization-utils",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -12,6 +12,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { connect } from 'react-redux';
|
||||
import { toElasticsearchQuery, fromKueryExpression, Query } from '@kbn/es-query';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { TooltipWrapper } from '@kbn/visualization-utils';
|
||||
import { QueryStringInput } from '@kbn/unified-search-plugin/public';
|
||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
import { IUnifiedSearchPluginServices } from '@kbn/unified-search-plugin/public/types';
|
||||
|
@ -27,8 +28,6 @@ import {
|
|||
selectedFieldsSelector,
|
||||
} from '../state_management';
|
||||
|
||||
import { TooltipWrapper } from './tooltip_wrapper';
|
||||
|
||||
export interface SearchBarProps {
|
||||
isLoading: boolean;
|
||||
urlQuery: string | null;
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiToolTip, EuiToolTipProps } from '@elastic/eui';
|
||||
|
||||
export type TooltipWrapperProps = Partial<Omit<EuiToolTipProps, 'content'>> & {
|
||||
tooltipContent: string;
|
||||
/** When the condition is truthy, the tooltip will be shown */
|
||||
condition: boolean;
|
||||
};
|
||||
|
||||
export const TooltipWrapper: React.FunctionComponent<TooltipWrapperProps> = ({
|
||||
children,
|
||||
condition,
|
||||
tooltipContent,
|
||||
...tooltipProps
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
{condition ? (
|
||||
<EuiToolTip content={tooltipContent} delay="long" {...tooltipProps}>
|
||||
<>{children}</>
|
||||
</EuiToolTip>
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -49,6 +49,7 @@
|
|||
"@kbn/content-management-utils",
|
||||
"@kbn/logging",
|
||||
"@kbn/content-management-table-list-view-common",
|
||||
"@kbn/visualization-utils",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -29,7 +29,7 @@ import {
|
|||
} from '@kbn/data-plugin/public';
|
||||
import { extendedBoundsToAst, intervalOptions } from '@kbn/data-plugin/common';
|
||||
import { buildExpressionFunction } from '@kbn/expressions-plugin/public';
|
||||
import { TooltipWrapper } from '@kbn/visualization-ui-components';
|
||||
import { TooltipWrapper } from '@kbn/visualization-utils';
|
||||
import { updateColumnParam } from '../layer_helpers';
|
||||
import { OperationDefinition, ParamEditorProps } from '.';
|
||||
import { FieldBasedIndexPatternColumn } from './column_types';
|
||||
|
|
|
@ -25,7 +25,7 @@ import {
|
|||
} from '@kbn/coloring';
|
||||
import { GaugeTicksPositions, GaugeColorModes } from '@kbn/expression-gauge-plugin/common';
|
||||
import { getMaxValue, getMinValue } from '@kbn/expression-gauge-plugin/public';
|
||||
import { TooltipWrapper } from '@kbn/visualization-ui-components';
|
||||
import { TooltipWrapper } from '@kbn/visualization-utils';
|
||||
import { isNumericFieldForDatatable } from '../../../common/expressions/datatable/utils';
|
||||
import { applyPaletteParams, PalettePanelContainer } from '../../shared_components';
|
||||
import type { VisualizationDimensionEditorProps } from '../../types';
|
||||
|
|
|
@ -11,7 +11,7 @@ import { Position } from '@elastic/charts';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { LegendSize } from '@kbn/visualizations-plugin/public';
|
||||
import { EuiIconAxisLeft, EuiIconAxisBottom } from '@kbn/chart-icons';
|
||||
import { TooltipWrapper } from '@kbn/visualization-ui-components';
|
||||
import { TooltipWrapper } from '@kbn/visualization-utils';
|
||||
import type { VisualizationToolbarProps } from '../../types';
|
||||
import {
|
||||
LegendSettingsPopover,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { TooltipWrapper } from '@kbn/visualization-ui-components';
|
||||
import { TooltipWrapper } from '@kbn/visualization-utils';
|
||||
import { ToolbarPopover } from '../../../shared_components';
|
||||
import { TitlePositionOptions } from './title_position_option';
|
||||
import { FramePublicAPI } from '../../../types';
|
||||
|
|
|
@ -11,7 +11,7 @@ import { Position, ScaleType } from '@elastic/charts';
|
|||
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { AxisExtentConfig } from '@kbn/expression-xy-plugin/common';
|
||||
import { LegendSize } from '@kbn/visualizations-plugin/public';
|
||||
import { TooltipWrapper } from '@kbn/visualization-ui-components';
|
||||
import { TooltipWrapper } from '@kbn/visualization-utils';
|
||||
import type { LegendSettingsPopoverProps } from '../../../shared_components/legend/legend_settings_popover';
|
||||
import type { VisualizationToolbarProps, FramePublicAPI } from '../../../types';
|
||||
import { State, XYState, AxesSettingsConfig } from '../types';
|
||||
|
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiButtonGroup, EuiFormRow } from '@elastic/eui';
|
||||
import { IconPosition } from '@kbn/expression-xy-plugin/common';
|
||||
import { TooltipWrapper } from '@kbn/visualization-ui-components';
|
||||
import { TooltipWrapper } from '@kbn/visualization-utils';
|
||||
import { YAxisMode } from '../../types';
|
||||
|
||||
import { idPrefix } from '../dimension_editor';
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { TooltipWrapper } from '@kbn/visualization-ui-components';
|
||||
import { TooltipWrapper } from '@kbn/visualization-utils';
|
||||
import { ToolbarPopover, ValueLabelsSettings } from '../../../../shared_components';
|
||||
import { MissingValuesOptions } from './missing_values_option';
|
||||
import { LineCurveOption } from './line_curve_option';
|
||||
|
|
|
@ -97,7 +97,8 @@
|
|||
"@kbn/shared-ux-button-toolbar",
|
||||
"@kbn/cell-actions",
|
||||
"@kbn/calculate-width-from-char-count",
|
||||
"@kbn/discover-utils"
|
||||
"@kbn/discover-utils",
|
||||
"@kbn/visualization-utils"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue