Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Lens] Color mapping UX refactoring #175144

Merged
merged 31 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
656c2ed
loop color v2
markov00 Jan 22, 2024
165ba64
Remane reset
markov00 Jan 24, 2024
69d63b7
update designs
markov00 Jan 29, 2024
7d8e284
Remove focus on new assignment
markov00 Jan 29, 2024
a46785d
refactored components and tests
markov00 Jan 31, 2024
0fa804f
Merge branch 'main' into 2024_01_15-loop_colors_v2
markov00 Jan 31, 2024
324914f
fix i18n unused values
markov00 Jan 31, 2024
d960db2
cleanup storybook example
markov00 Jan 31, 2024
d1dbbc3
cleanup unnecessary comment
markov00 Jan 31, 2024
1479cd5
fix i18n labels
markov00 Feb 1, 2024
44426a0
fix tests
markov00 Feb 2, 2024
5d30104
cleanup style and fix getColorFunction
markov00 Feb 2, 2024
c7a4f99
Merge branch 'main' into 2024_01_15-loop_colors_v2
markov00 Feb 2, 2024
609fd66
remove color change on hover
markov00 Feb 2, 2024
f83bcbc
change gradient add hover style
markov00 Feb 2, 2024
f32af57
update telemetry
markov00 Feb 2, 2024
461616e
add case sensitive combobox
markov00 Feb 2, 2024
2f3c433
Merge branch 'main' into 2024_01_15-loop_colors_v2
markov00 Feb 5, 2024
5d94f2f
Remove unnecessary branch in ternary
markov00 Feb 5, 2024
66dc597
fix wrong array expansion
markov00 Feb 5, 2024
e8a1901
simplify code from review
markov00 Feb 5, 2024
8285bab
align trash icon to assignment
markov00 Feb 5, 2024
ff29d6c
don't change the rgb input when editing
markov00 Feb 5, 2024
dc66b7a
Merge branch 'main' into 2024_01_15-loop_colors_v2
markov00 Feb 6, 2024
6a8e3eb
Merge branch 'main' into 2024_01_15-loop_colors_v2
stratoula Feb 7, 2024
e45d9c7
align next color assignment logic
markov00 Feb 7, 2024
d8dd0a2
show unassigned options only with assignments
markov00 Feb 7, 2024
58c37f3
refactor findLast import
markov00 Feb 7, 2024
70cb65a
Revert "refactor findLast import"
markov00 Feb 7, 2024
a5e60e5
Merge branch 'main' into 2024_01_15-loop_colors_v2
stratoula Feb 8, 2024
275ccb2
use full width for the form rows
markov00 Feb 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,122 +6,115 @@
* Side Public License, v 1.
*/

import React, { FC } from 'react';
import { EuiFlyout, EuiForm } from '@elastic/eui';
import React, { FC, useState } from 'react';
import { EuiFlyout, EuiForm, EuiPage, isColorDark } from '@elastic/eui';
import { ComponentStory } from '@storybook/react';
import { css } from '@emotion/react';
import { CategoricalColorMapping, ColorMappingProps } from '../categorical_color_mapping';
import { AVAILABLE_PALETTES } from '../palettes';
import { AVAILABLE_PALETTES, getPalette, NeutralPalette } from '../palettes';
import { DEFAULT_COLOR_MAPPING_CONFIG } from '../config/default_color_mapping';
import { ColorMapping } from '../config';
import { getColorFactory } from '../color/color_handling';
import { ruleMatch } from '../color/rule_matching';
import { getValidColor } from '../color/color_math';

export default {
title: 'Color Mapping',
component: CategoricalColorMapping,
decorators: [
(story: Function) => (
<EuiFlyout style={{ width: 350, padding: '8px' }} onClose={() => {}} hideCloseButton>
<EuiForm>{story()}</EuiForm>
</EuiFlyout>
),
],
decorators: [(story: Function) => story()],
};

const Template: ComponentStory<FC<ColorMappingProps>> = (args) => (
<CategoricalColorMapping {...args} />
);
const Template: ComponentStory<FC<ColorMappingProps>> = (args) => {
const [updatedModel, setUpdateModel] = useState<ColorMapping.Config>(
DEFAULT_COLOR_MAPPING_CONFIG
);

const getPaletteFn = getPalette(AVAILABLE_PALETTES, NeutralPalette);

const colorFactory = getColorFactory(updatedModel, getPaletteFn, false, args.data);

return (
<EuiPage>
<ol>
{args.data.type === 'categories' &&
args.data.categories.map((c, i) => {
const match = updatedModel.assignments.some(({ rule }) => {
return ruleMatch(rule, c);
});
const color = colorFactory(c);
const isDark = isColorDark(...getValidColor(color).rgb());

return (
<li
key={i}
css={css`
width: ${100 + 200 * Math.abs(Math.cos(i))}px;
height: 30px;
margin: 2px;
padding: 5px;
background: ${color};
color: ${isDark ? 'white' : 'black'};
border: ${match ? '2px solid black' : 'none'};
font-weight: ${match ? 'bold' : 'normal'};
`}
>
{c}
</li>
);
})}
</ol>
<EuiFlyout
style={{ width: 350, minInlineSize: 366, padding: '8px', overflow: 'auto' }}
onClose={() => {}}
hideCloseButton
ownFocus={false}
>
<EuiForm>
<CategoricalColorMapping {...args} onModelUpdate={setUpdateModel} />
</EuiForm>
</EuiFlyout>
</EuiPage>
);
};
export const Default = Template.bind({});

Default.args = {
model: {
...DEFAULT_COLOR_MAPPING_CONFIG,
assignmentMode: 'manual',

colorMode: {
type: 'gradient',
steps: [
{
type: 'categorical',
colorIndex: 0,
paletteId: DEFAULT_COLOR_MAPPING_CONFIG.paletteId,
touched: false,
},
{
type: 'categorical',
colorIndex: 1,
paletteId: DEFAULT_COLOR_MAPPING_CONFIG.paletteId,
touched: false,
},
{
type: 'categorical',
colorIndex: 2,
paletteId: DEFAULT_COLOR_MAPPING_CONFIG.paletteId,
touched: false,
},
],
sort: 'asc',
type: 'categorical',
},
assignments: [
{
rule: {
type: 'matchExactly',
values: ['this is', 'a multi-line combobox that is very long and that will be truncated'],
},
color: {
type: 'gradient',
},
touched: false,
},
{
rule: {
type: 'matchExactly',
values: ['b', ['double', 'value']],
},
color: {
type: 'gradient',
},
touched: false,
},
{
rule: {
type: 'matchExactly',
values: ['c'],
},
color: {
type: 'gradient',
},
touched: false,
},
specialAssignments: [
{
rule: {
type: 'matchExactly',
values: [
'this is',
'a multi-line wrap',
'combo box',
'test combo',
'3 lines',
['double', 'value'],
],
type: 'other',
},
color: {
type: 'gradient',
type: 'loop',
},
touched: false,
},
],
assignments: [],
},
isDarkMode: false,
data: {
type: 'categories',
categories: [
'a',
'b',
'c',
'd',
'this is',
'a multi-line wrap',
'combo box',
'test combo',
'3 lines',
'US',
'Mexico',
'Brasil',
'Canada',
'Italy',
'Germany',
'France',
'Spain',
'UK',
'Portugal',
'Greece',
'Sweden',
'Finland',
],
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import { AVAILABLE_PALETTES } from './palettes';
import { DEFAULT_COLOR_MAPPING_CONFIG } from './config/default_color_mapping';
import { MULTI_FIELD_KEY_SEPARATOR } from '@kbn/data-plugin/common';

const AUTO_ASSIGN_SWITCH = '[data-test-subj="lns-colorMapping-autoAssignSwitch"]';
const ASSIGNMENTS_LIST = '[data-test-subj="lns-colorMapping-assignmentsList"]';
const ASSIGNMENTS_PROMPT = '[data-test-subj="lns-colorMapping-assignmentsPrompt"]';
const ASSIGNMENTS_PROMPT_ADD_ALL = '[data-test-subj="lns-colorMapping-assignmentsPromptAddAll"]';
const ASSIGNMENT_ITEM = (i: number) => `[data-test-subj="lns-colorMapping-assignmentsItem${i}"]`;

describe('color mapping', () => {
Expand All @@ -35,19 +36,12 @@ describe('color mapping', () => {
/>
);

expect(component.find(AUTO_ASSIGN_SWITCH).hostNodes().prop('aria-checked')).toEqual(true);
expect(component.find(ASSIGNMENTS_LIST).hostNodes().children().length).toEqual(
dataInput.categories.length
);
dataInput.categories.forEach((category, index) => {
const assignment = component.find(ASSIGNMENT_ITEM(index)).hostNodes();
expect(assignment.text()).toEqual(category);
expect(assignment.hasClass('euiComboBox-isDisabled')).toEqual(true);
});
// empty list prompt visible
expect(component.find(ASSIGNMENTS_PROMPT)).toBeTruthy();
expect(onModelUpdateFn).not.toBeCalled();
});

it('switch to manual assignments', () => {
it('Add all terms to assignments', () => {
const dataInput: ColorMappingInputData = {
type: 'categories',
categories: ['categoryA', 'categoryB'],
Expand All @@ -63,9 +57,8 @@ describe('color mapping', () => {
specialTokens={new Map()}
/>
);
component.find(AUTO_ASSIGN_SWITCH).hostNodes().simulate('click');
component.find(ASSIGNMENTS_PROMPT_ADD_ALL).hostNodes().simulate('click');
expect(onModelUpdateFn).toBeCalledTimes(1);
expect(component.find(AUTO_ASSIGN_SWITCH).hostNodes().prop('aria-checked')).toEqual(false);
expect(component.find(ASSIGNMENTS_LIST).hostNodes().children().length).toEqual(
dataInput.categories.length
);
Expand Down Expand Up @@ -97,6 +90,7 @@ describe('color mapping', () => {
}
/>
);
component.find(ASSIGNMENTS_PROMPT_ADD_ALL).hostNodes().simulate('click');
expect(component.find(ASSIGNMENTS_LIST).hostNodes().children().length).toEqual(
dataInput.categories.length
);
Expand Down
Loading