Skip to content

Commit

Permalink
chore(Queries): query result chart refactoring [YTFRONT-4423]
Browse files Browse the repository at this point in the history
  • Loading branch information
SimbiozizV committed Oct 25, 2024
1 parent 2d1932d commit 32e1f94
Show file tree
Hide file tree
Showing 54 changed files with 833 additions and 1,281 deletions.
4 changes: 2 additions & 2 deletions packages/ui/src/ui/UIFactory/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export type ExtraTab = {
position: {before: TabName} | {after: TabName};
};

export type CustomQueryResultTab = {
export type QueryResultChartTab = {
title: string;
renderContent: (params: {query: QueryItem}) => React.ReactNode;
};
Expand Down Expand Up @@ -388,7 +388,7 @@ export interface UIFactory {

renderRolesLink(params: {cluster: string; login: string; className?: string}): React.ReactNode;

getQueryResultChartTab(): CustomQueryResultTab | undefined;
getQueryResultChartTab(): QueryResultChartTab | undefined;

getExternalSettings(params: {
cluster: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React, {useMemo} from 'react';
import ChartKit from '../../../../components/YagrChartKit/YagrChartKit';
import {settings} from '@gravity-ui/chartkit';
import type {ChartKitRef} from '@gravity-ui/chartkit';
import {prepareWidgetData} from '../preparers/prepareWidgetData';
import {useSelector} from 'react-redux';
import {
selectIsPlaceholdersFieldsFilled,
selectQueryResultVisualization,
} from '../../module/queryChart/selectors';
import type {QueryResult} from '../preparers/types';
import {EmptyPlaceholdersMessage} from './EmptyPlaceholdersMessage';
import {D3Plugin} from '@gravity-ui/chartkit/d3';

settings.set({plugins: [...settings.get('plugins'), D3Plugin]});

type LineBasicProps = {
result: QueryResult;
};

export const BaseChart = React.forwardRef<ChartKitRef | undefined, LineBasicProps>(
function BaseChartComponent({result}, ref) {
const visualization = useSelector(selectQueryResultVisualization);
const fieldsIsFilled = useSelector(selectIsPlaceholdersFieldsFilled);

const widgetData = useMemo(() => {
return prepareWidgetData({result, visualization});
}, [result, visualization]);

if (!fieldsIsFilled) {
return <EmptyPlaceholdersMessage />;
}

return <ChartKit type="d3" data={widgetData} ref={ref} />;
},
);

export const Chart = React.memo(BaseChart);

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.yt-chart-field {
width: 200px;
padding: 12px 0;
border-top: 1px solid var(--g-color-line-generic);

&__header {
display: flex;
justify-content: space-between;
align-items: center;
}

&__name {
font-weight: bold;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React, {useCallback} from 'react';
import block from 'bem-cn-lite';
import './ChartField.scss';
import {Placeholder} from '../../types';
import {Button, Icon, Select} from '@gravity-ui/uikit';
import {Plus as PlusIcon} from '@gravity-ui/icons';
import {useDispatch} from 'react-redux';
import {removeField, setField} from '../../../module/queryChart/queryChartSlice';
import {ChartFieldName} from './ChartFieldName';

const b = block('yt-chart-field');

type PlaceholderComponentProps = {
placeholder: Placeholder;
availableFields: string[];
};

export const ChartField = ({placeholder, availableFields}: PlaceholderComponentProps) => {
const {id, field} = placeholder;
const dispatch = useDispatch();

const handleRemoveField = useCallback(
(fieldName: string, placeholderId: string) => {
dispatch(
removeField({
fieldName,
placeholderId,
}),
);
},
[dispatch],
);

const onSelectUpdate = React.useCallback(
(value: string[]) => {
dispatch(
setField({
placeholderId: placeholder.id,
fieldName: value[0],
}),
);
},
[dispatch, placeholder.id],
);

return (
<div className={b()}>
<div className={b('header')}>
<div className={b('name')}>{id}</div>
<Select
value={[]}
filterable={true}
options={availableFields.map((item) => ({
content: item,
value: item,
data: item,
}))}
onUpdate={onSelectUpdate}
renderControl={({onClick, ref}) => {
return (
<Button onClick={onClick} ref={ref}>
<Icon data={PlusIcon} size={16} />
</Button>
);
}}
/>
</div>

<ChartFieldName
fieldName={field}
placeholderId={placeholder.id}
onRemove={handleRemoveField}
/>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.yt-chart-field-name {
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
height: 32px;
margin-top: 4px;

$self: &;

background-color: var(--g-color-base-misc-light);

&:hover {
background-color: var(--g-color-base-simple-hover);

#{$self}__actions {
visibility: visible;
}
}

&__spacer {
display: flex;
margin-left: 12px;
}

&__title {
overflow: hidden;
text-overflow: ellipsis;
margin-left: 8px;
}

&__actions {
visibility: hidden;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, {FC} from 'react';
import {Button, Icon} from '@gravity-ui/uikit';
import {Xmark as XmarkIcon} from '@gravity-ui/icons';
import cn from 'bem-cn-lite';
import './ChartFieldName.scss';

const b = cn('yt-chart-field-name');

type Props = {
fieldName: string;
placeholderId: string;
onRemove: (fieldName: string, placeholderId: string) => void;
};

export const ChartFieldName: FC<Props> = ({fieldName, placeholderId, onRemove}) => {
if (!fieldName) return null;

const handleRemoveField = () => {
onRemove(fieldName, placeholderId);
};

return (
<div key={fieldName} className={b()}>
<div className={b('spacer')}></div>
<div className={b('title')} title={fieldName}>
{fieldName}
</div>
<div className={b('actions')}>
<Button onClick={handleRemoveField}>
<Icon data={XmarkIcon} size={16} />
</Button>
</div>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.yt-query-chart-fields {
padding-top: 12px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, {FC} from 'react';
import {ChartField} from './ChartField';
import block from 'bem-cn-lite';
import './ChartFields.scss';
import {useSelector} from 'react-redux';
import {selectQueryResultVisualizationPlaceholders} from '../../../module/queryChart/selectors';

const b = block('yt-query-chart-fields');

type PlaceholdersContainerProps = {
availableFields: string[];
};

export const ChartFields: FC<PlaceholdersContainerProps> = ({availableFields}) => {
const placeholders = useSelector(selectQueryResultVisualizationPlaceholders);

return (
<div className={b()}>
{placeholders.map((placeholder) => (
<ChartField
key={placeholder.id}
placeholder={placeholder}
availableFields={availableFields}
/>
))}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {ChartFields} from './ChartFields';
Loading

0 comments on commit 32e1f94

Please sign in to comment.