Skip to content

Commit

Permalink
Add Color dialog to dataset unit
Browse files Browse the repository at this point in the history
  • Loading branch information
kuzmadom committed Apr 2, 2024
1 parent 5592b99 commit eb6dc05
Show file tree
Hide file tree
Showing 46 changed files with 1,081 additions and 154 deletions.
6 changes: 6 additions & 0 deletions src/shared/constants/qa/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,9 @@ export enum DocSectionQa {
Item = 'doc-section-item',
Title = 'doc-item-title',
}

export const enum DialogColorQa {
PaletteSelect = 'palette-select',
GradientType = 'color-dialog-gradient-type-radio',
ApplyButton = 'color-dialog-apply-button',
}
6 changes: 0 additions & 6 deletions src/shared/constants/qa/wizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,6 @@ export const enum DialogFieldSubTotalsQa {
SubTotalsSwitch = 'sub-totals-switch',
}

export const enum DialogColorQa {
PaletteSelect = 'palette-select',
GradientType = 'color-dialog-gradient-type-radio',
ApplyButton = 'color-dialog-apply-button',
}

export const enum DialogMetricSettingsQa {
Dialog = 'metric-settings-dialog',
CancelButton = 'metric-settings-dialog-cancel',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import React from 'react';

import {Button, Icon, TextInput} from '@gravity-ui/uikit';
import block from 'bem-cn-lite';
import {PaletteItem} from 'units/wizard/components/Palette/components/PaletteItem/PaletteItem';

import {PaletteItem} from '../../Palette/components/PaletteItem/PaletteItem';

import trashIcon from '@gravity-ui/icons/svgs/trash-bin.svg';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import {
import {selectColorPalettes, selectCurrentColorPalette} from 'store/selectors/colorPaletteEditor';
import {DatalensGlobalState} from 'ui';
import {DialogRow} from 'units/wizard/components/Dialogs/components/DialogRow/DialogRow';
import {GradientPalettePreview} from 'units/wizard/components/GradientPalettePreview/GradientPalettePreview';
import {isStringWithFullLengthHex} from 'utils/validation';

import {GradientPalettePreview} from '../../GradientPalettePreview/GradientPalettePreview';
import ColorPaletteChartkitPreview from '../ColorPaletteCharkitPreview/ColorPaletteChartkitPreview';
import ColorTextInput from '../ColorTextInput/ColorTextInput';

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';

import {ColorMode, ColorPalette, ColorsConfig} from 'shared';

import {GradientView} from '../GradientView/GradientView';
import {PaletteView} from '../PaletteView/PaletteView';

type Props = {
colorsConfig: ColorsConfig;
colorPalettes: ColorPalette[];
loading?: boolean;
values?: string[];
onChange: (config: Partial<ColorsConfig>) => void;
};

export const ColorSettingsContainer = (props: Props) => {
const {colorsConfig, colorPalettes, loading, values, onChange} = props;

const handleChangePaletteColors = (args: {
palette: string;
mountedColors: ColorsConfig['mountedColors'];
}) => {
const {palette, mountedColors} = args;
onChange({palette, mountedColors});
};

if (colorsConfig.colorMode === ColorMode.GRADIENT) {
return (
<GradientView
colorConfig={colorsConfig}
onChange={onChange}
usePolygonBorders={false}
validationStatus={{}}
/>
);
}

return (
<PaletteView
palette={colorsConfig.palette}
colorPalettes={colorPalettes}
mountedColors={colorsConfig.mountedColors || {}}
onChange={handleChangePaletteColors}
loading={loading}
values={values || []}
/>
);
};
41 changes: 41 additions & 0 deletions src/ui/components/DialogColor/DialogColor.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
.dialog-color {
display: flex;
flex-direction: column;
width: 680px;
height: 560px;
max-height: 80vh;
min-height: 300px;

--yc-dialog-header-padding-bottom: 15px;

&_palette-mode {
height: 560px;
}

&_palette-mode &__body {
padding: 0;
}

&_palette-mode &__row {
padding: 0 32px;
}

&_gradient-mode {
height: 374px;
}

&__title-icon {
margin-bottom: 2px;
margin-right: 4px;
height: 24px;
width: 24px;
display: flex;
align-items: center;
justify-content: center;
}

&__body {
overflow-y: auto;
border-bottom: 1px solid var(--g-color-line-generic);
}
}
166 changes: 166 additions & 0 deletions src/ui/components/DialogColor/DialogColor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import React, {ChangeEvent} from 'react';

import {BucketPaint} from '@gravity-ui/icons';
import {Button, Dialog, Icon, RadioButton} from '@gravity-ui/uikit';
import block from 'bem-cn-lite';
import {i18n} from 'i18n';
import cloneDeep from 'lodash/cloneDeep';
import isEqual from 'lodash/isEqual';
import {useDispatch, useSelector} from 'react-redux';
import {ColorMode, ColorsConfig, DEFAULT_PALETTE, Feature} from 'shared';
import {Utils} from 'ui';
import {fetchColorPalettes} from 'ui/store/actions/colorPaletteEditor';
import {selectColorPalettes} from 'ui/store/selectors/colorPaletteEditor';

import {ColorSettingsContainer} from './ColorSettingsContainer/ColorSettingsContainer';

import './DialogColor.scss';

const SHOW = 'show';
const HIDE = 'hide';

const b = block('dialog-color');

interface Props {
colorsConfig: ColorsConfig;
colorModes: ColorMode[];
values: string[];
loading?: boolean;
onApply: (colorsConfig: ColorsConfig) => void;
onClose: () => void;
usePolygonBorders?: boolean;
}

function getColorMode(colorMode: ColorMode | undefined, modes: ColorMode[]) {
if (typeof colorMode !== 'undefined' && modes.includes(colorMode)) {
return colorMode;
}
return modes[0];
}

function getInitialConfig(args: {config: ColorsConfig; modes: ColorMode[]}) {
const {config, modes} = args;
const result = cloneDeep(config);
result.colorMode = getColorMode(config.colorMode, modes);
result.palette = config.palette || DEFAULT_PALETTE.id;

return result;
}

export const DialogColor = (props: Props) => {
const {onClose, onApply, colorsConfig, colorModes, values, loading, usePolygonBorders} = props;
const [isValid, setIsValid] = React.useState<boolean>(true);

const dispatch = useDispatch();
const colorPalettes = useSelector(selectColorPalettes);
const [updatedConfig, setUpdatedConfig] = React.useState<ColorsConfig>(
getInitialConfig({config: colorsConfig, modes: colorModes}),
);

React.useEffect(() => {
if (Utils.isEnabledFeature(Feature.CustomColorPalettes)) {
dispatch(fetchColorPalettes());
}
}, [dispatch]);

const updateConfig = (updates: Partial<ColorsConfig>) => {
setUpdatedConfig({...updatedConfig, ...updates});
// TODO: validate config
setIsValid(true);
};

const handleChangeColorMode = (event: ChangeEvent<HTMLInputElement>) => {
updateConfig({colorMode: event.target.value as ColorMode});
};

const handlePolygonBorders = (event: ChangeEvent<HTMLInputElement>) => {
updateConfig({polygonBorders: event.target.value});
};

const applyChanges = () => {
onApply(updatedConfig);
onClose();
};

const resetChanges = () => {
setUpdatedConfig(cloneDeep(colorsConfig));
};

return (
<Dialog open={true} onClose={onClose} disableFocusTrap={true}>
<div className={b({[`${updatedConfig.colorMode}-mode`]: true})}>
<Dialog.Header
insertBefore={
<div className={b('title-icon')}>
<Icon data={BucketPaint} size={18} />
</div>
}
caption={i18n('wizard', 'label_colors-settings')}
/>
<Dialog.Body className={b('body')}>
{colorModes.length > 1 && (
<div className={b('row')}>
<span className={b('label')}>{i18n('wizard', 'label_color-mode')}</span>
<RadioButton
size="m"
value={updatedConfig.colorMode}
onChange={handleChangeColorMode}
>
<RadioButton.Option value={ColorMode.PALETTE}>
{i18n('wizard', 'label_palette')}
</RadioButton.Option>
<RadioButton.Option value={ColorMode.GRADIENT}>
{i18n('wizard', 'label_gradient')}
</RadioButton.Option>
</RadioButton>
</div>
)}
{usePolygonBorders && (
<div className={b('row')}>
<span className={b('label')}>{i18n('wizard', 'label_borders')}</span>
<RadioButton
size="m"
value={colorsConfig.polygonBorders ? SHOW : HIDE}
onChange={handlePolygonBorders}
>
<RadioButton.Option value={SHOW}>
{i18n('wizard', 'label_show')}
</RadioButton.Option>
<RadioButton.Option value={HIDE}>
{i18n('wizard', 'label_hide')}
</RadioButton.Option>
</RadioButton>
</div>
)}
<ColorSettingsContainer
colorsConfig={updatedConfig}
onChange={updateConfig}
colorPalettes={colorPalettes}
values={values}
loading={loading}
/>
</Dialog.Body>
<Dialog.Footer
preset="default"
onClickButtonCancel={onClose}
onClickButtonApply={applyChanges}
textButtonApply={i18n('wizard', 'button_apply')}
textButtonCancel={i18n('wizard', 'button_cancel')}
propsButtonApply={{
disabled: !isValid,
qa: 'color-dialog-apply-button',
}}
>
<Button
view="outlined"
size="l"
disabled={!isEqual(colorsConfig, updatedConfig)}
onClick={resetChanges}
>
{i18n('wizard', 'button_reset')}
</Button>
</Dialog.Footer>
</div>
</Dialog>
);
};
68 changes: 68 additions & 0 deletions src/ui/components/DialogColor/GradientView/GradientView.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
@import '../../../styles/mixins.scss';

.dialog-color {
&__row {
margin-bottom: 20px;
vertical-align: middle;
line-height: 20px;
display: flex;
align-items: center;
}

&__label {
display: inline-block;
margin-right: 20px;
}

&__palette-select {
width: 204px;
display: inline-block;
}

&__reverse-button {
margin-left: 6px;
line-height: 24px;
vertical-align: middle;
}

&__thresholds-checkbox {
margin-right: 10px;
}

&__threshold-inputs-wrapper {
display: flex;
width: 395px;
padding-right: 36px;
height: 28px;
justify-content: space-between;
}

&__threshold-input {
display: inline-block;
width: 80px;
}

&__error-label {
margin: 20px 32px;
}

&__preview {
width: 358px;
height: 28px;
background: #000000;
vertical-align: middle;
margin-left: 12px;
}

&__select {
width: 100%;
}

&__select-popup {
@include dl-select-popup;
}

&__hint-icon {
margin-left: 5px;
}
}
Loading

0 comments on commit eb6dc05

Please sign in to comment.