mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Controls] Use EUI Selectable for Field search (#151231)
## Summary Replaces Control field selection list with EUISelectable.
This commit is contained in:
parent
2baf551deb
commit
eb9cc11a7c
11 changed files with 227 additions and 280 deletions
|
@ -109,7 +109,7 @@ export const ControlEditor = ({
|
|||
});
|
||||
|
||||
const [defaultTitle, setDefaultTitle] = useState<string>();
|
||||
const [currentTitle, setCurrentTitle] = useState(title);
|
||||
const [currentTitle, setCurrentTitle] = useState(title ?? '');
|
||||
const [currentWidth, setCurrentWidth] = useState(width);
|
||||
const [currentGrow, setCurrentGrow] = useState(grow);
|
||||
const [controlEditorValid, setControlEditorValid] = useState(false);
|
||||
|
@ -198,27 +198,27 @@ export const ControlEditor = ({
|
|||
/>
|
||||
</EuiFormRow>
|
||||
)}
|
||||
<EuiFormRow label={ControlGroupStrings.manageControl.getFieldTitle()}>
|
||||
<FieldPicker
|
||||
filterPredicate={(field: DataViewField) => {
|
||||
return Boolean(fieldRegistry?.[field.name]);
|
||||
}}
|
||||
selectedFieldName={selectedField}
|
||||
dataView={dataView}
|
||||
onSelectField={(field) => {
|
||||
onTypeEditorChange({
|
||||
fieldName: field.name,
|
||||
});
|
||||
const newDefaultTitle = field.displayName ?? field.name;
|
||||
setDefaultTitle(newDefaultTitle);
|
||||
setSelectedField(field.name);
|
||||
if (!currentTitle || currentTitle === defaultTitle) {
|
||||
setCurrentTitle(newDefaultTitle);
|
||||
updateTitle(newDefaultTitle);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
{fieldRegistry && (
|
||||
<EuiFormRow label={ControlGroupStrings.manageControl.getFieldTitle()}>
|
||||
<FieldPicker
|
||||
filterPredicate={(field: DataViewField) => Boolean(fieldRegistry[field.name])}
|
||||
selectedFieldName={selectedField}
|
||||
dataView={dataView}
|
||||
onSelectField={(field) => {
|
||||
onTypeEditorChange({
|
||||
fieldName: field.name,
|
||||
});
|
||||
const newDefaultTitle = field.displayName ?? field.name;
|
||||
setDefaultTitle(newDefaultTitle);
|
||||
setSelectedField(field.name);
|
||||
if (!currentTitle || currentTitle === defaultTitle) {
|
||||
setCurrentTitle(newDefaultTitle);
|
||||
updateTitle(newDefaultTitle);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
)}
|
||||
<EuiFormRow label={ControlGroupStrings.manageControl.getControlTypeTitle()}>
|
||||
{factory ? (
|
||||
<EuiFlexGroup alignItems="center" gutterSize="xs">
|
||||
|
|
|
@ -1,17 +1,4 @@
|
|||
.presFieldPicker__fieldButton {
|
||||
background: $euiColorEmptyShade;
|
||||
}
|
||||
|
||||
.presFieldPickerFieldButtonActive {
|
||||
box-shadow: 0 0 0 2px $euiColorPrimary;
|
||||
}
|
||||
|
||||
.presFieldPicker__fieldPanel {
|
||||
height: 300px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.presFieldPicker__container--disabled {
|
||||
opacity: .7;
|
||||
pointer-events: none;
|
||||
background-color: transparentize($euiColorPrimary, .9);
|
||||
}
|
|
@ -8,13 +8,14 @@
|
|||
|
||||
import classNames from 'classnames';
|
||||
import { sortBy, uniq } from 'lodash';
|
||||
import React, { useState } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiText } from '@elastic/eui';
|
||||
import { FieldButton, FieldIcon } from '@kbn/react-field';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FieldIcon } from '@kbn/react-field';
|
||||
import { EuiSelectable, EuiSelectableOption, EuiSpacer } from '@elastic/eui';
|
||||
import { DataView, DataViewField } from '@kbn/data-views-plugin/common';
|
||||
import { FieldSearch } from './field_search';
|
||||
|
||||
import { FieldTypeFilter } from './field_type_filter';
|
||||
|
||||
import './field_picker.scss';
|
||||
|
||||
|
@ -31,115 +32,102 @@ export const FieldPicker = ({
|
|||
filterPredicate,
|
||||
selectedFieldName,
|
||||
}: FieldPickerProps) => {
|
||||
const [nameFilter, setNameFilter] = useState<string>('');
|
||||
const [typesFilter, setTypesFilter] = useState<string[]>([]);
|
||||
const [fieldSelectableOptions, setFieldSelectableOptions] = useState<EuiSelectableOption[]>([]);
|
||||
|
||||
// Retrieve, filter, and sort fields from data view
|
||||
const fields = dataView
|
||||
? sortBy(
|
||||
dataView.fields
|
||||
.filter(
|
||||
(f) =>
|
||||
f.name.toLowerCase().includes(nameFilter.toLowerCase()) &&
|
||||
(typesFilter.length === 0 || typesFilter.includes(f.type as string))
|
||||
)
|
||||
const availableFields = useMemo(
|
||||
() =>
|
||||
sortBy(
|
||||
(dataView?.fields ?? [])
|
||||
.filter((f) => typesFilter.length === 0 || typesFilter.includes(f.type as string))
|
||||
.filter((f) => (filterPredicate ? filterPredicate(f) : true)),
|
||||
['name']
|
||||
)
|
||||
: [];
|
||||
),
|
||||
[dataView, filterPredicate, typesFilter]
|
||||
);
|
||||
|
||||
const uniqueTypes = dataView
|
||||
? uniq(
|
||||
dataView.fields
|
||||
.filter((f) => (filterPredicate ? filterPredicate(f) : true))
|
||||
.map((f) => f.type as string)
|
||||
)
|
||||
: [];
|
||||
useEffect(() => {
|
||||
if (!dataView) return;
|
||||
const options: EuiSelectableOption[] = (availableFields ?? []).map((field) => {
|
||||
return {
|
||||
key: field.name,
|
||||
label: field.displayName ?? field.name,
|
||||
className: classNames('presFieldPicker__fieldButton', {
|
||||
presFieldPickerFieldButtonActive: field.name === selectedFieldName,
|
||||
}),
|
||||
'data-test-subj': `field-picker-select-${field.name}`,
|
||||
prepend: (
|
||||
<FieldIcon
|
||||
type={field.type}
|
||||
label={field.name}
|
||||
scripted={field.scripted}
|
||||
className="eui-alignMiddle"
|
||||
/>
|
||||
),
|
||||
};
|
||||
});
|
||||
setFieldSelectableOptions(options);
|
||||
}, [availableFields, dataView, filterPredicate, selectedFieldName, typesFilter]);
|
||||
|
||||
const uniqueTypes = useMemo(
|
||||
() =>
|
||||
dataView
|
||||
? uniq(
|
||||
dataView.fields
|
||||
.filter((f) => (filterPredicate ? filterPredicate(f) : true))
|
||||
.map((f) => f.type as string)
|
||||
)
|
||||
: [],
|
||||
[dataView, filterPredicate]
|
||||
);
|
||||
|
||||
const fieldTypeFilter = (
|
||||
<FieldTypeFilter
|
||||
onFieldTypesChange={(types) => setTypesFilter(types)}
|
||||
fieldTypesValue={typesFilter}
|
||||
availableFieldTypes={uniqueTypes}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<EuiFlexGroup
|
||||
direction="column"
|
||||
alignItems="stretch"
|
||||
gutterSize="s"
|
||||
className={`presFieldPicker__container ${
|
||||
!dataView && 'presFieldPicker__container--disabled'
|
||||
}`}
|
||||
<EuiSelectable
|
||||
emptyMessage={i18n.translate('presentationUtil.fieldPicker.noFieldsLabel', {
|
||||
defaultMessage: 'No matching fields',
|
||||
})}
|
||||
aria-label={i18n.translate('presentationUtil.fieldPicker.selectableAriaLabel', {
|
||||
defaultMessage: 'Select a field',
|
||||
})}
|
||||
searchable
|
||||
options={fieldSelectableOptions}
|
||||
onChange={(options, _, changedOption) => {
|
||||
setFieldSelectableOptions(options);
|
||||
if (!dataView || !changedOption.key) return;
|
||||
const field = dataView.getFieldByName(changedOption.key);
|
||||
if (field) onSelectField?.(field);
|
||||
}}
|
||||
searchProps={{
|
||||
'data-test-subj': 'field-search-input',
|
||||
placeholder: i18n.translate('presentationUtil.fieldSearch.searchPlaceHolder', {
|
||||
defaultMessage: 'Search field names',
|
||||
}),
|
||||
}}
|
||||
listProps={{
|
||||
isVirtualized: true,
|
||||
showIcons: false,
|
||||
bordered: true,
|
||||
}}
|
||||
height={300}
|
||||
>
|
||||
<EuiFlexItem grow={false}>
|
||||
<FieldSearch
|
||||
onSearchChange={(val) => setNameFilter(val)}
|
||||
searchValue={nameFilter}
|
||||
onFieldTypesChange={(types) => setTypesFilter(types)}
|
||||
fieldTypesValue={typesFilter}
|
||||
availableFieldTypes={uniqueTypes}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiPanel
|
||||
paddingSize="s"
|
||||
hasShadow={false}
|
||||
hasBorder={true}
|
||||
className="presFieldPicker__fieldPanel"
|
||||
>
|
||||
{fields.length > 0 && (
|
||||
<EuiFlexGroup direction="column" gutterSize="none">
|
||||
{fields.map((f, i) => {
|
||||
return (
|
||||
<EuiFlexItem key={f.name}>
|
||||
<FieldButton
|
||||
data-test-subj={`field-picker-select-${f.name}`}
|
||||
className={classNames('presFieldPicker__fieldButton', {
|
||||
presFieldPickerFieldButtonActive: f.name === selectedFieldName,
|
||||
})}
|
||||
onClick={() => {
|
||||
onSelectField?.(f);
|
||||
}}
|
||||
isActive={f.name === selectedFieldName}
|
||||
fieldName={f.name}
|
||||
fieldIcon={<FieldIcon type={f.type} label={f.name} scripted={f.scripted} />}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
);
|
||||
})}
|
||||
</EuiFlexGroup>
|
||||
)}
|
||||
{!dataView && (
|
||||
<EuiFlexGroup
|
||||
direction="column"
|
||||
gutterSize="none"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<EuiText color="subdued">
|
||||
<FormattedMessage
|
||||
id="presentationUtil.fieldPicker.noDataViewLabel"
|
||||
defaultMessage="No data view selected"
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
)}
|
||||
{dataView && fields.length === 0 && (
|
||||
<EuiFlexGroup
|
||||
direction="column"
|
||||
gutterSize="none"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<EuiText color="subdued">
|
||||
<FormattedMessage
|
||||
id="presentationUtil.fieldPicker.noFieldsLabel"
|
||||
defaultMessage="No matching fields"
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
)}
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
{(list, search) => (
|
||||
<>
|
||||
{search}
|
||||
<EuiSpacer size={'s'} />
|
||||
{fieldTypeFilter}
|
||||
<EuiSpacer size={'s'} />
|
||||
{list}
|
||||
</>
|
||||
)}
|
||||
</EuiSelectable>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,133 +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 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 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
EuiFieldSearch,
|
||||
EuiFilterGroup,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiPopover,
|
||||
EuiContextMenuPanel,
|
||||
EuiContextMenuItem,
|
||||
EuiOutsideClickDetector,
|
||||
EuiFilterButton,
|
||||
EuiSpacer,
|
||||
EuiPopoverTitle,
|
||||
} from '@elastic/eui';
|
||||
import { FieldIcon } from '@kbn/react-field';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
|
||||
import './field_search.scss';
|
||||
|
||||
export interface Props {
|
||||
onSearchChange: (value: string) => void;
|
||||
searchValue?: string;
|
||||
|
||||
onFieldTypesChange: (value: string[]) => void;
|
||||
fieldTypesValue: string[];
|
||||
|
||||
availableFieldTypes: string[];
|
||||
}
|
||||
|
||||
export function FieldSearch({
|
||||
onSearchChange,
|
||||
searchValue,
|
||||
onFieldTypesChange,
|
||||
fieldTypesValue,
|
||||
availableFieldTypes,
|
||||
}: Props) {
|
||||
const searchPlaceholder = i18n.translate('presentationUtil.fieldSearch.searchPlaceHolder', {
|
||||
defaultMessage: 'Search field names',
|
||||
});
|
||||
|
||||
const [isPopoverOpen, setPopoverOpen] = useState(false);
|
||||
|
||||
const handleFilterButtonClicked = () => {
|
||||
setPopoverOpen(!isPopoverOpen);
|
||||
};
|
||||
|
||||
const buttonContent = (
|
||||
<EuiFilterButton
|
||||
data-test-subj="toggleFieldFilterButton"
|
||||
iconType="arrowDown"
|
||||
isSelected={fieldTypesValue.length > 0}
|
||||
numFilters={0}
|
||||
hasActiveFilters={fieldTypesValue.length > 0}
|
||||
numActiveFilters={fieldTypesValue.length}
|
||||
onClick={handleFilterButtonClicked}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="presentationUtil.fieldSearch.fieldFilterButtonLabel"
|
||||
defaultMessage="Filter by type"
|
||||
/>
|
||||
</EuiFilterButton>
|
||||
);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<EuiFlexGroup responsive={false} gutterSize={'s'}>
|
||||
<EuiFlexItem>
|
||||
<EuiFieldSearch
|
||||
aria-label={searchPlaceholder}
|
||||
data-test-subj="field-search-input"
|
||||
fullWidth
|
||||
onChange={(event) => onSearchChange(event.currentTarget.value)}
|
||||
placeholder={searchPlaceholder}
|
||||
value={searchValue}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer size="xs" />
|
||||
<EuiOutsideClickDetector onOutsideClick={() => {}} isDisabled={!isPopoverOpen}>
|
||||
<EuiFilterGroup>
|
||||
<EuiPopover
|
||||
panelClassName="euiFilterGroup__popoverPanel presFilterByType__panel"
|
||||
panelPaddingSize="none"
|
||||
display="block"
|
||||
isOpen={isPopoverOpen}
|
||||
closePopover={() => {
|
||||
setPopoverOpen(false);
|
||||
}}
|
||||
button={buttonContent}
|
||||
>
|
||||
<EuiPopoverTitle paddingSize="s">
|
||||
{i18n.translate('presentationUtil.fieldSearch.filterByTypeLabel', {
|
||||
defaultMessage: 'Filter by type',
|
||||
})}
|
||||
</EuiPopoverTitle>
|
||||
<EuiContextMenuPanel
|
||||
items={(availableFieldTypes as string[]).map((type) => (
|
||||
<EuiContextMenuItem
|
||||
key={type}
|
||||
icon={fieldTypesValue.includes(type) ? 'check' : 'empty'}
|
||||
data-test-subj={`typeFilter-${type}`}
|
||||
onClick={() => {
|
||||
if (fieldTypesValue.includes(type)) {
|
||||
onFieldTypesChange(fieldTypesValue.filter((f) => f !== type));
|
||||
} else {
|
||||
onFieldTypesChange([...fieldTypesValue, type]);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<EuiFlexGroup gutterSize="xs" responsive={false}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<FieldIcon type={type} label={type} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>{type}</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiContextMenuItem>
|
||||
))}
|
||||
/>
|
||||
</EuiPopover>
|
||||
</EuiFilterGroup>
|
||||
</EuiOutsideClickDetector>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* 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 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 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
EuiFilterGroup,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiPopover,
|
||||
EuiContextMenuPanel,
|
||||
EuiContextMenuItem,
|
||||
EuiOutsideClickDetector,
|
||||
EuiFilterButton,
|
||||
EuiPopoverTitle,
|
||||
} from '@elastic/eui';
|
||||
import { FieldIcon } from '@kbn/react-field';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
|
||||
import './field_type_filter.scss';
|
||||
|
||||
export interface Props {
|
||||
onFieldTypesChange: (value: string[]) => void;
|
||||
fieldTypesValue: string[];
|
||||
|
||||
availableFieldTypes: string[];
|
||||
}
|
||||
|
||||
export function FieldTypeFilter({
|
||||
onFieldTypesChange,
|
||||
fieldTypesValue,
|
||||
availableFieldTypes,
|
||||
}: Props) {
|
||||
const [isPopoverOpen, setPopoverOpen] = useState(false);
|
||||
|
||||
const handleFilterButtonClicked = () => {
|
||||
setPopoverOpen(!isPopoverOpen);
|
||||
};
|
||||
|
||||
const buttonContent = (
|
||||
<EuiFilterButton
|
||||
data-test-subj="toggleFieldFilterButton"
|
||||
iconType="arrowDown"
|
||||
isSelected={fieldTypesValue.length > 0}
|
||||
numFilters={0}
|
||||
hasActiveFilters={fieldTypesValue.length > 0}
|
||||
numActiveFilters={fieldTypesValue.length}
|
||||
onClick={handleFilterButtonClicked}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="presentationUtil.fieldSearch.fieldFilterButtonLabel"
|
||||
defaultMessage="Filter by type"
|
||||
/>
|
||||
</EuiFilterButton>
|
||||
);
|
||||
|
||||
return (
|
||||
<EuiOutsideClickDetector onOutsideClick={() => {}} isDisabled={!isPopoverOpen}>
|
||||
<EuiFilterGroup>
|
||||
<EuiPopover
|
||||
panelClassName="euiFilterGroup__popoverPanel presFilterByType__panel"
|
||||
panelPaddingSize="none"
|
||||
display="block"
|
||||
isOpen={isPopoverOpen}
|
||||
closePopover={() => {
|
||||
setPopoverOpen(false);
|
||||
}}
|
||||
button={buttonContent}
|
||||
>
|
||||
<EuiPopoverTitle paddingSize="s">
|
||||
{i18n.translate('presentationUtil.fieldSearch.filterByTypeLabel', {
|
||||
defaultMessage: 'Filter by type',
|
||||
})}
|
||||
</EuiPopoverTitle>
|
||||
<EuiContextMenuPanel
|
||||
items={(availableFieldTypes as string[]).map((type) => (
|
||||
<EuiContextMenuItem
|
||||
key={type}
|
||||
icon={fieldTypesValue.includes(type) ? 'check' : 'empty'}
|
||||
data-test-subj={`typeFilter-${type}`}
|
||||
onClick={() => {
|
||||
if (fieldTypesValue.includes(type)) {
|
||||
onFieldTypesChange(fieldTypesValue.filter((f) => f !== type));
|
||||
} else {
|
||||
onFieldTypesChange([...fieldTypesValue, type]);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<EuiFlexGroup gutterSize="xs" responsive={false}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<FieldIcon type={type} label={type} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>{type}</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiContextMenuItem>
|
||||
))}
|
||||
/>
|
||||
</EuiPopover>
|
||||
</EuiFilterGroup>
|
||||
</EuiOutsideClickDetector>
|
||||
);
|
||||
}
|
|
@ -576,7 +576,7 @@ export class DashboardPageControls extends FtrService {
|
|||
public async controlsEditorSetfield(
|
||||
fieldName: string,
|
||||
expectedType?: string,
|
||||
shouldSearch: boolean = false
|
||||
shouldSearch: boolean = true
|
||||
) {
|
||||
this.log.debug(`Setting control field to ${fieldName}`);
|
||||
if (shouldSearch) {
|
||||
|
|
|
@ -4483,7 +4483,6 @@
|
|||
"presentationUtil.solutionToolbar.quickButton.ariaButtonLabel": "Créer {createType}",
|
||||
"presentationUtil.dashboardPicker.searchDashboardPlaceholder": "Recherche dans les tableaux de bord…",
|
||||
"presentationUtil.dataViewPicker.changeDataViewTitle": "Vue de données",
|
||||
"presentationUtil.fieldPicker.noDataViewLabel": "Aucune vue de données sélectionnée",
|
||||
"presentationUtil.fieldPicker.noFieldsLabel": "Aucun champ correspondant",
|
||||
"presentationUtil.fieldSearch.fieldFilterButtonLabel": "Filtrer par type",
|
||||
"presentationUtil.fieldSearch.filterByTypeLabel": "Filtrer par type",
|
||||
|
|
|
@ -4481,7 +4481,6 @@
|
|||
"presentationUtil.solutionToolbar.quickButton.ariaButtonLabel": "新しい{createType}を作成",
|
||||
"presentationUtil.dashboardPicker.searchDashboardPlaceholder": "ダッシュボードを検索...",
|
||||
"presentationUtil.dataViewPicker.changeDataViewTitle": "データビュー",
|
||||
"presentationUtil.fieldPicker.noDataViewLabel": "データビューが選択されていません",
|
||||
"presentationUtil.fieldPicker.noFieldsLabel": "一致するがフィールドがありません",
|
||||
"presentationUtil.fieldSearch.fieldFilterButtonLabel": "タイプでフィルタリング",
|
||||
"presentationUtil.fieldSearch.filterByTypeLabel": "タイプでフィルタリング",
|
||||
|
|
|
@ -4486,7 +4486,6 @@
|
|||
"presentationUtil.solutionToolbar.quickButton.ariaButtonLabel": "创建新的 {createType}",
|
||||
"presentationUtil.dashboardPicker.searchDashboardPlaceholder": "搜索仪表板......",
|
||||
"presentationUtil.dataViewPicker.changeDataViewTitle": "数据视图",
|
||||
"presentationUtil.fieldPicker.noDataViewLabel": "未选择数据视图",
|
||||
"presentationUtil.fieldPicker.noFieldsLabel": "无匹配字段",
|
||||
"presentationUtil.fieldSearch.fieldFilterButtonLabel": "按类型筛选",
|
||||
"presentationUtil.fieldSearch.filterByTypeLabel": "按类型筛选",
|
||||
|
|
|
@ -11,6 +11,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
const a11y = getService('a11y');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
|
||||
const PageObjects = getPageObjects(['common', 'dashboard', 'home', 'dashboardControls']);
|
||||
const browser = getService('browser');
|
||||
|
||||
|
@ -56,7 +57,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('Options control panel & dashboard with options control', async () => {
|
||||
await testSubjects.click('field-picker-select-OriginCityName');
|
||||
await PageObjects.dashboardControls.controlsEditorSetfield('OriginCityName');
|
||||
await a11y.testAppSnapshot();
|
||||
await testSubjects.click('control-editor-save');
|
||||
await a11y.testAppSnapshot();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue