Skip to content

Commit

Permalink
Standardizing IconField implementation across the app (elastic#47196)
Browse files Browse the repository at this point in the history
* Moving FieldNameIcon implementation to FieldIcon implementation in kibana_react directory

* Adding LensFieldIcon implementation around the new FieldIcon to be used in Lens components

* Applying new LensFieldIcon in the Lens components

* Applying new FieldIcon component in Graph components

* Applying new FieldIcon component in the rest of the components

* Adding missing type to lens field icon

* adding missing type

* Addressing PR comments
  • Loading branch information
Maja Grubic committed Oct 7, 2019
1 parent cb27486 commit e485a6a
Show file tree
Hide file tree
Showing 15 changed files with 158 additions and 53 deletions.

This file was deleted.

4 changes: 2 additions & 2 deletions src/legacy/ui/public/directives/field_name/field_name.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import React from 'react';
import classNames from 'classnames';
// @ts-ignore
import { shortenDottedString } from '../../../../core_plugins/kibana/common/utils/shorten_dotted_string';
import { FieldNameIcon } from './field_name_icon';
import { FieldIcon } from '../../../../../../src/plugins/kibana_react/public';
import { getFieldTypeName } from './field_type_name';

// property field is provided at discover's field chooser
Expand Down Expand Up @@ -53,7 +53,7 @@ export function FieldName({ field, fieldName, fieldType, useShortDots }: Props)

return (
<span className={className} title={typeName}>
<FieldNameIcon type={type} label={typeName} />
<FieldIcon type={type} label={typeName} />
<span className="dscFieldName">{displayName}</span>
</span>
);
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,24 @@
*/
import React from 'react';
import { shallow } from 'enzyme';
import { FieldNameIcon } from './field_name_icon';
import { FieldIcon } from './field_icon';

test('FieldNameIcon renders a blackwhite icon for a string', () => {
const component = shallow(<FieldNameIcon type="string" label="test" />);
test('FieldIcon renders a blackwhite icon for a string', () => {
const component = shallow(<FieldIcon type="string" />);
expect(component).toMatchSnapshot();
});

test('FieldNameIcon renders a colored icon for a number', () => {
const component = shallow(<FieldNameIcon type="number" label="test" useColor />);
test('FieldIcon renders a colored icon for a number', () => {
const component = shallow(<FieldIcon type="number" label="test" useColor />);
expect(component).toMatchSnapshot();
});

test('FieldNameIcon renders an icon for an unknown type', () => {
const component = shallow(<FieldNameIcon type="sdfsdf" label="test" useColor />);
test('FieldIcon renders an icon for an unknown type', () => {
const component = shallow(<FieldIcon type="sdfsdf" label="test" useColor />);
expect(component).toMatchSnapshot();
});

test('FieldIcon renders with className if provided', () => {
const component = shallow(<FieldIcon type="sdfsdf" label="test" className="myClass" useColor />);
expect(component).toMatchSnapshot();
});
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ interface IconMapEntry {
icon: string;
color: string;
}
interface FieldNameIconProps {
interface FieldIconProps {
type:
| 'boolean'
| 'conflict'
Expand All @@ -37,17 +37,18 @@ interface FieldNameIconProps {
| '_source'
| 'string'
| string;
label: string;
label?: string;
size?: IconSize;
useColor?: boolean;
className?: string;
}

const { colors } = palettes.euiPaletteColorBlind;

// defaultIcon => a unknown datatype
const defaultIcon = { icon: 'questionInCircle', color: colors[0] };

const typeToEuiIconMap: Partial<Record<string, IconMapEntry>> = {
export const typeToEuiIconMap: Partial<Record<string, IconMapEntry>> = {
boolean: { icon: 'invert', color: colors[5] },
// icon for an index pattern mapping conflict in discover
conflict: { icon: 'alert', color: colors[8] },
Expand All @@ -63,9 +64,15 @@ const typeToEuiIconMap: Partial<Record<string, IconMapEntry>> = {
};

/**
* Field icon displayed in discover doc_viewer + side bar
* Field icon used across the app
*/
export function FieldNameIcon({ type, label, size = 's', useColor = false }: FieldNameIconProps) {
export function FieldIcon({
type,
label,
size = 's',
useColor = false,
className = undefined,
}: FieldIconProps) {
const euiIcon = typeToEuiIconMap[type] || defaultIcon;

return (
Expand All @@ -74,6 +81,7 @@ export function FieldNameIcon({ type, label, size = 's', useColor = false }: Fie
aria-label={label || type}
size={size as IconSize}
color={useColor || type === 'conflict' ? euiIcon.color : undefined}
className={className}
/>
);
}
19 changes: 19 additions & 0 deletions src/plugins/kibana_react/public/field_icon/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export * from './field_icon';
1 change: 1 addition & 0 deletions src/plugins/kibana_react/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ export * from './exit_full_screen_button';
export * from './context';
export * from './overlays';
export * from './ui_settings';
export * from './field_icon';
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import classNames from 'classnames';
import { WorkspaceField } from '../../types';
import { iconChoices } from '../../helpers/style_choices';
import { LegacyIcon } from '../legacy_icon';
import { FieldIcon } from './field_icon';
import { FieldIcon } from '../../../../../../../src/plugins/kibana_react/public';
import { UpdateableFieldProperties } from './field_manager';

import { isEqual } from '../helpers';
Expand Down Expand Up @@ -216,7 +216,7 @@ export function FieldEditor({
const { type, label } = option;
return (
<span className={contentClassName}>
<FieldIcon type={type!} />{' '}
<FieldIcon type={type!} size="m" useColor />{' '}
<EuiHighlight search={searchValue}>{label}</EuiHighlight>
</span>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import { EuiPopover, EuiSelectable, EuiBadge } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import classNames from 'classnames';
import { WorkspaceField } from '../../types';

import { FieldIcon } from './field_icon';
import { FieldIcon } from '../../../../../../../src/plugins/kibana_react/public';

export interface FieldPickerProps {
fieldMap: Record<string, WorkspaceField>;
Expand Down Expand Up @@ -121,7 +120,7 @@ function toOptions(
): Array<{ label: string; checked?: 'on' | 'off'; prepend?: ReactNode }> {
return fields.map(field => ({
label: field.name,
prepend: <FieldIcon type={field.type} />,
prepend: <FieldIcon type={field.type} size="m" useColor />,
checked: field.selected ? 'on' : undefined,
}));
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { DatasourceDataPanelProps, DataType } from '../types';
import { IndexPatternPrivateState, IndexPatternField, IndexPattern } from './indexpattern';
import { ChildDragDropProvider, DragContextState } from '../drag_drop';
import { FieldItem } from './field_item';
import { FieldIcon } from './field_icon';
import { LensFieldIcon } from './lens_field_icon';
import { updateLayerIndexPattern } from './state_helpers';
import { ChangeIndexPattern } from './change_indexpattern';

Expand Down Expand Up @@ -442,7 +442,7 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({
}))
}
>
<FieldIcon type={type} /> {fieldTypeNames[type]}
<LensFieldIcon type={type} /> {fieldTypeNames[type]}
</EuiContextMenuItem>
))}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
EuiHighlight,
} from '@elastic/eui';
import { OperationType, IndexPattern, IndexPatternField } from '../indexpattern';
import { FieldIcon } from '../field_icon';
import { LensFieldIcon } from '../lens_field_icon';
import { DataType } from '../../types';
import { OperationFieldSupportMatrix } from './dimension_panel';

Expand Down Expand Up @@ -172,7 +172,9 @@ export function FieldSelect({
return (
<EuiFlexGroup gutterSize="s" alignItems="center">
<EuiFlexItem grow={null}>
<FieldIcon type={((option.value as unknown) as { dataType: DataType }).dataType} />
<LensFieldIcon
type={((option.value as unknown) as { dataType: DataType }).dataType}
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiHighlight search={searchValue}>{option.label}</EuiHighlight>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ import { Query } from 'src/plugins/data/common';
import { fieldFormats } from '../../../../../../src/legacy/ui/public/registry/field_formats';
import { IndexPattern, IndexPatternField, DraggedField } from './indexpattern';
import { DragDrop } from '../drag_drop';
import { FieldIcon, getColorForDataType } from './field_icon';
import { DatasourceDataPanelProps, DataType } from '../types';
import { BucketedAggregation, FieldStatsResponse } from '../../common';
import { LensFieldIcon, getColorForDataType } from './lens_field_icon';

export interface FieldItemProps {
core: DatasourceDataPanelProps['core'];
Expand Down Expand Up @@ -177,7 +177,7 @@ export function FieldItem(props: FieldItemProps) {
values: { fieldName: field.name },
})}
>
<FieldIcon type={field.type as DataType} />
<LensFieldIcon type={field.type as DataType} />

<span className="lnsFieldItem__name" title={field.name}>
{wrappableHighlightableFieldName}
Expand Down Expand Up @@ -362,11 +362,11 @@ function FieldItemPopoverContents(props: State & FieldItemProps) {
defaultMessage: 'Count',
})
);
const expectedColor = getColorForDataType(field.type);
const colors: DataSeriesColorsValues = {
colorValues: [],
specId,
};
const expectedColor = getColorForDataType(field.type);

const seriesColors = new Map([[colors, expectedColor]]);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React from 'react';
import { shallow } from 'enzyme';
import { LensFieldIcon, getColorForDataType } from './lens_field_icon';

test('LensFieldIcon renders properly', () => {
const component = shallow(<LensFieldIcon type={'date'} />);
expect(component).toMatchSnapshot();
});

test('LensFieldIcon getColorForDataType for a valid type', () => {
const color = getColorForDataType('date');
expect(color).toEqual('#B0916F');
});

test('LensFieldIcon getColorForDataType for an invalid type', () => {
const color = getColorForDataType('invalid');
expect(color).toEqual('#1EA593');
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React from 'react';
import { palettes } from '@elastic/eui';
import { FieldIcon, typeToEuiIconMap } from '../../../../../../src/plugins/kibana_react/public';
import { DataType } from '../types';

export function getColorForDataType(type: string) {
const iconMap = typeToEuiIconMap[type];
if (iconMap) {
return iconMap.color;
}
return palettes.euiPaletteColorBlind.colors[0];
}

export function LensFieldIcon({ type }: { type: DataType }) {
return <FieldIcon type={type} className="lnsFieldListPanel__fieldIcon" size="m" useColor />;
}

0 comments on commit e485a6a

Please sign in to comment.