Skip to content

Commit

Permalink
Merge branch 'main' into 47477-shorten-ml-job-ids
Browse files Browse the repository at this point in the history
  • Loading branch information
miltonhultgren authored Nov 15, 2023
2 parents cb25844 + 12a09b8 commit dc5ebb6
Show file tree
Hide file tree
Showing 56 changed files with 567 additions and 1,068 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@
*/

import './field_picker.scss';
import React, { useRef } from 'react';
import React from 'react';
import { i18n } from '@kbn/i18n';
import useEffectOnce from 'react-use/lib/useEffectOnce';
import { EuiComboBox, EuiComboBoxProps, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { EuiComboBox, EuiComboBoxProps } from '@elastic/eui';
import { FieldIcon } from '@kbn/field-utils/src/components/field_icon';
import classNames from 'classnames';
import type { DataType } from './types';
import { TruncatedLabel } from './truncated_label';
import type { FieldOptionValue, FieldOption } from './types';

export interface FieldPickerProps<T extends FieldOptionValue>
Expand All @@ -27,9 +24,8 @@ export interface FieldPickerProps<T extends FieldOptionValue>
'data-test-subj'?: string;
}

const DEFAULT_COMBOBOX_WIDTH = 305;
const COMBOBOX_PADDINGS = 90;
const DEFAULT_FONT = '14px Inter';
const MIDDLE_TRUNCATION_PROPS = { truncation: 'middle' as const };
const SINGLE_SELECTION_AS_TEXT_PROPS = { asPlainText: true };

export function FieldPicker<T extends FieldOptionValue = FieldOptionValue>({
selectedOptions,
Expand All @@ -40,95 +36,86 @@ export function FieldPicker<T extends FieldOptionValue = FieldOptionValue>({
['data-test-subj']: dataTestSub,
...rest
}: FieldPickerProps<T>) {
let theLongestLabel = '';
const styledOptions = options?.map(({ compatible, exists, ...otherAttr }) => {
if (otherAttr.options) {
return {
...otherAttr,
options: otherAttr.options.map(({ exists: fieldOptionExists, ...fieldOption }) => ({
...fieldOption,
className: classNames({
'lnFieldPicker__option--incompatible': !fieldOption.compatible,
'lnFieldPicker__option--nonExistant': !fieldOptionExists,
}),
})),
options: otherAttr.options.map(({ exists: fieldOptionExists, ...fieldOption }) => {
if (fieldOption.label.length > theLongestLabel.length) {
theLongestLabel = fieldOption.label;
}
return {
...fieldOption,
prepend: fieldOption.value.dataType ? (
<FieldIcon
type={fieldOption.value.dataType}
fill="none"
className="eui-alignMiddle"
/>
) : null,
className: classNames({
'lnFieldPicker__option--incompatible': !fieldOption.compatible,
'lnFieldPicker__option--nonExistant': !fieldOptionExists,
}),
};
}),
};
}
return {
...otherAttr,
compatible,
prepend: otherAttr.value.dataType ? (
<FieldIcon type={otherAttr.value.dataType} fill="none" className="eui-alignMiddle" />
) : null,
className: classNames({
'lnFieldPicker__option--incompatible': !compatible,
'lnFieldPicker__option--nonExistant': !exists,
}),
};
});
const comboBoxRef = useRef<HTMLInputElement>(null);
const [labelProps, setLabelProps] = React.useState<{
width: number;
font: string;
}>({
width: DEFAULT_COMBOBOX_WIDTH - COMBOBOX_PADDINGS,
font: DEFAULT_FONT,
});

const computeStyles = (_e: UIEvent | undefined, shouldRecomputeAll = false) => {
if (comboBoxRef.current) {
const current = {
...labelProps,
width: comboBoxRef.current?.clientWidth - COMBOBOX_PADDINGS,
};
if (shouldRecomputeAll) {
current.font = window.getComputedStyle(comboBoxRef.current).font;
}
setLabelProps(current);
}
};

useEffectOnce(() => {
if (comboBoxRef.current) {
computeStyles(undefined, true);
}
window.addEventListener('resize', computeStyles);
});

const panelMinWidth = getPanelMinWidth(theLongestLabel.length);
return (
<div ref={comboBoxRef}>
<EuiComboBox
fullWidth
compressed
isClearable={false}
data-test-subj={dataTestSub ?? 'indexPattern-dimension-field'}
placeholder={i18n.translate('visualizationUiComponents.fieldPicker.fieldPlaceholder', {
defaultMessage: 'Select a field',
})}
options={styledOptions}
isInvalid={fieldIsInvalid}
selectedOptions={selectedOptions}
singleSelection={{ asPlainText: true }}
onChange={(choices) => {
if (choices.length === 0) {
onDelete?.();
return;
}
onChoose(choices[0].value);
}}
renderOption={(option, searchValue) => {
return (
<EuiFlexGroup gutterSize="s" alignItems="center" responsive={false}>
<EuiFlexItem grow={null}>
<FieldIcon
type={(option.value as unknown as { dataType: DataType }).dataType}
fill="none"
/>
</EuiFlexItem>
<EuiFlexItem>
<TruncatedLabel {...labelProps} label={option.label} search={searchValue} />
</EuiFlexItem>
</EuiFlexGroup>
);
}}
{...rest}
/>
</div>
<EuiComboBox
fullWidth
compressed
isClearable={false}
data-test-subj={dataTestSub ?? 'indexPattern-dimension-field'}
placeholder={i18n.translate('visualizationUiComponents.fieldPicker.fieldPlaceholder', {
defaultMessage: 'Select a field',
})}
options={styledOptions}
isInvalid={fieldIsInvalid}
selectedOptions={selectedOptions}
singleSelection={SINGLE_SELECTION_AS_TEXT_PROPS}
truncationProps={MIDDLE_TRUNCATION_PROPS}
inputPopoverProps={{ panelMinWidth }}
onChange={(choices) => {
if (choices.length === 0) {
onDelete?.();
return;
}
onChoose(choices[0].value);
}}
{...rest}
/>
);
}

const MINIMUM_POPOVER_WIDTH = 300;
const MINIMUM_POPOVER_WIDTH_CHAR_COUNT = 28;
const AVERAGE_CHAR_WIDTH = 7;
const MAXIMUM_POPOVER_WIDTH_CHAR_COUNT = 60;
const MAXIMUM_POPOVER_WIDTH = 550; // fitting 60 characters

function getPanelMinWidth(labelLength: number) {
if (labelLength > MAXIMUM_POPOVER_WIDTH_CHAR_COUNT) {
return MAXIMUM_POPOVER_WIDTH;
}
if (labelLength > MINIMUM_POPOVER_WIDTH_CHAR_COUNT) {
const overflownChars = labelLength - MINIMUM_POPOVER_WIDTH_CHAR_COUNT;
return MINIMUM_POPOVER_WIDTH + overflownChars * AVERAGE_CHAR_WIDTH;
}
return MINIMUM_POPOVER_WIDTH;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@
*/

export { FieldPicker } from './field_picker';
export { TruncatedLabel } from './truncated_label';
export type { FieldOptionValue, FieldOption, DataType } from './types';

This file was deleted.

This file was deleted.

1 change: 0 additions & 1 deletion packages/kbn-visualization-ui-components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

export {
FieldPicker,
TruncatedLabel,
NameInput,
DebouncedInput,
useDebouncedValue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n';
import React from 'react';
import { ToolbarButton, ToolbarButtonProps } from '../toolbar_button';

export type Props = Omit<ToolbarButtonProps, 'iconType' | 'label' | 'type'>;
export type Props = Omit<ToolbarButtonProps<'standard'>, 'iconType' | 'label' | 'type'>;

const label = {
getLibraryButtonLabel: () =>
Expand Down
Loading

0 comments on commit dc5ebb6

Please sign in to comment.