Библиотека для рендеринга сетки дашборда.
npm i @gravity-ui/dashkit @gravity-ui/uikit
Библиотека позволяет выстраивать виджеты в сетку, изменять их размеры, добавлять новые и удалять их. Виджет представляет из себя react-компонент – к примеру, текст, график, картинка и т.п.
Добавление новых виджетов осуществляется через систему плагинов.
Плагины нужны для создания собственных виджетов.
type ItemManipulationCallback = (eventData: {
layout: Layouts;
oldItem: Layout;
newItem: Layout;
placeholder: Layout;
e: MouseEvent;
element: HTMLElement;
}) => void;
interface DashKitProps {
config: Config;
editMode: boolean;
onItemEdit: ({id}: {id: string}) => void;
onChange: (data: {config: Config; itemsStateAndParams: ItemsStateAndParams}) => void;
onDrop: (dropProps: ItemDropProps) => void;
onItemMountChange: (item: ConfigItem, state: {isAsync: boolead; isMounted: boolean}) => void;
onItemRender: (item: ConfigItem) => void;
onDragStart?: ItemManipulationCallback;
onDrag?: ItemManipulationCallback;
onDragStop?: ItemManipulationCallback;
onResizeStart?: ItemManipulationCallback;
onResize?: ItemManipulationCallback;
onResizeStop?: ItemManipulationCallback;
defaultGlobalParams: GlobalParams;
globalParams: GlobalParams;
itemsStateAndParams: ItemsStateAndParams;
settings: SettingsProps;
context: ContextProps;
overlayControls?: Record<string, OverlayControlItem[]> | null;
overlayMenuItems?: MenuItems[] | null;
noOverlay?: boolean;
focusable?: boolean;
draggableHandleClassName?: string;
getPreparedCopyItemOptions?: (options: PreparedCopyItemOptions) => PreparedCopyItemOptions;
onCopyFulfill?: (error: null | Error, data?: PreparedCopyItemOptions) => void;
}
config
: кофигурация.editMode
: включает или отключает режим редактирования.onItemEdit
: вызывается по клику для редактирования виджета.onChange
: вызывается при изменении значенияconfig
илиitemsStateAndParams
.onDrop
: вызывается, когда элемент перетаскивается изActionPanel
(панели действий) с помощью(#DashKitDnDWrapper)
.onItemMountChange
: вызывается при изменении состояния монтирования элемента.onItemRender
: вызывается по завершении рендеринга элемента.defaultGlobalParams
,globalParams
: параметры, которые влияют на все виджеты. В DataLensdefaultGlobalParams
— глобальные параметры, заданные в настройках дашборда, аglobalParams
— глобальные параметры, которые можно задать в URL.itemsStateAndParams
: itemsStateAndParams.settings
: настройкиDashKit
.context
: объект, который пробросится в виде свойства во все виджеты.overlayControls
: объект, который переопределяет дефолтные контролы виджета, отображаемые в режиме редактирования. Если он не передан, будут отображаться базовые контролы. При передачеnull
будет отображаться только кнопка закрытия или пользовательское меню.overlayMenuItems
: пользовательские элементы выпадающего меню, отображаемое в режиме редактирования.noOverlay
: если установлено значениеtrue
, оверлей и контролы не отображаются при редактировании.focusable
: если установлено значениеtrue
, элементы сетки будут доступны для фокуса.draggableHandleClassName
: имя CSS-класса элемента, который позволяет перетаскивать виджет.onDragStart
: вызывается при начале перетаскивания элемента в библиотекеReactGridLayout
.onDrag
: вызывается во время перетаскивания элемента в библиотекеReactGridLayout
.onDragStop
: вызывается по завершении перетаскивания элемента в библиотекеReactGridLayout
.onResizeStart
: вызывается при начале изменения размера элемента в библиотеке ReactGridLayout.onResize
: вызывается в процессе изменения размера элемента в библиотекеReactGridLayout
.onResizeStop
: вызывается по завершении изменения размера элемента в библиотекеReactGridLayout
.getPreparedCopyItemOptions
: вызывается для преобразования скопированного элемента в сериализуемый объект перед его сохранением в локальное хранилище. Используется вместо устаревшего свойстваcontext.getPreparedCopyItemOptions
.onCopyFulfill
: вызывается при завершении копирования элемента. При успешном копировании передаетсяerror=null
и определенное значениеdata
, при неудачном копировании —error: Error
безdata
.
Перед использованием DashKit
в качестве React-компонента необходимо его настроить.
-
Установка языка:
import {configure, Lang} from '@gravity-ui/uikit'; configure({lang: Lang.En});
-
DashKit.setSettings
Используется для глобальных настроек
DashKit
(отступы между виджетами, размеры виджетов по умолчанию и меню оверлея виджета).import {DashKit} from '@gravity-ui/dashkit'; DashKit.setSettings({ gridLayout: {margin: [8, 8]}, isMobile: true, // menu: [] as Array<MenuItem>, });
-
DashKit.registerPlugins
Регистрация и конфигурация плагинов:
import {DashKit} from '@gravity-ui/dashkit'; import {pluginTitle, pluginText} from '@gravity-ui/dashkit'; DashKit.registerPlugins( pluginTitle, pluginText.setSettings({ apiHandler({text}) { return api.getMarkdown(text); }, }), ); DashKit.registerPlugins({ type: 'custom', defaultLayout: { w: 10, h: 8, }, renderer: function CustomPlugin() { return <div>Custom widget with custom controls</div>; }, });
export interface Config {
salt: string; // to form a unique id
counter: number; // to form a unique id, only increases
items: ConfigItem[]; // initial widget states
layout: ConfigLayout[]; // widget position on the grid https://github.com/react-grid-layout
aliases: ConfigAliases; // aliases for parameters see #Params
connections: ConfigConnection[]; // links between widgets see #Params
}
Пример конфигурации:
import {DashKitProps} from '@gravity-ui/dashkit';
const config: DashKitProps['config'] = {
salt: '0.46703554571365613',
counter: 4,
items: [
{
id: 'tT',
data: {
size: 'm',
text: 'Caption',
showInTOC: true,
},
type: 'title',
namespace: 'default',
orderId: 1,
},
{
id: 'Ea',
data: {
text: 'mode _editActive',
_editActive: true,
},
type: 'text',
namespace: 'default',
},
{
id: 'zR',
data: {
text: '### Text',
},
type: 'text',
namespace: 'default',
orderId: 0,
},
{
id: 'Dk',
data: {
foo: 'bar',
},
type: 'custom',
namespace: 'default',
orderId: 5,
},
],
layout: [
{
h: 2,
i: 'tT',
w: 36,
x: 0,
y: 0,
},
{
h: 6,
i: 'Ea',
w: 12,
x: 0,
y: 2,
},
{
h: 6,
i: 'zR',
w: 12,
x: 12,
y: 2,
},
{
h: 4,
i: 'Dk',
w: 8,
x: 0,
y: 8,
},
],
aliases: {},
connections: [],
};
Добавление нового объекта в кофигурацию:
const newLayout = updateLayout: [
{
h: 6,
i: 'Ea',
w: 12,
x: 0,
y: 6,
},
{
h: 4,
i: 'Dk',
w: 8,
x: 0,
y: 12,
},
];
const newConfig = DashKit.setItem({
item: {
data: {
text: `Some text`,
},
namespace: 'default',
type: 'text',
// Optional. If new item needed to be inserted in current layout with predefined dimensions
layout: { // Current item inseterted before 'Ea'
h: 6,
w: 12,
x: 0,
y: 2,
},,
},
config: config,
options: {
// Optional. New layout values for existing items when new element is dropped from ActionPanel
updateLayout: newLayout,
},
});
Изменение существующего объекта в кофигурации:
const newConfig = DashKit.setItem({
item: {
id: 'tT', // item.id
data: {
size: 'm',
text: `New caption`,
},
namespace: 'default',
type: 'title',
},
config: config,
});
Удаление объекта из кофигурации:
import {DashKitProps} from '@gravity-ui/dashkit';
const oldItemsStateAndParams: DashKitProps['itemsStateAndParams'] = {};
const {config: newConfig, itemsStateAndParams} = DashKit.removeItem({
id: 'tT', // item.id
config: config,
itemsStateAndParams: this.state.itemsStateAndParams,
});
type Params = Record<string, string | string[]>;
DashKit
формирует параметры на основе параметров по умолчанию для виджетов, ссылок и алиасов. Эти параметры необходимы для библиотеки ChartKit.
Порядок формирования:
defaultGlobalParams
.- Параметры виджета, используемые по умолчанию, —
item.default
. globalParams
.- Параметры из
itemsStateAndParams
, согласно очереди.
Объект, который хранит параметры и состояния виджетов, а также очередь изменения параметров.
У него есть поле __meta__
для хранения очереди и метаинформации.
interface StateAndParamsMeta = {
__meta__: {
queue: {id: string}[]; // queue
version: number; // current version itemsStateAndParams
};
}
В нем также хранятся состояния и параметры виджетов:
interface ItemsStateAndParamsBase {
[itemId: string]: {
state?: Record<string, any>;
params?: Params;
};
}
type ItemsStateAndParams = StateAndParamsMeta & ItemsStateAndParamsBase;
Можно задать пользовательские элементы выпадающего меню оверлея DashKit
виджета, которое отображается в режиме редактирования.
type MenuItem = {
id: string; // uniq id
title?: string; // string title
icon?: ReactNode; // node of icon
iconSize?: number | string; // icon size in px as number or as string with units
handler?: (item: ConfigItem) => void; // custom item action handler
visible?: (item: ConfigItem) => boolean; // optional visibility handler for filtering menu items
className?: string; // custom class property
};
// use array of menu items in settings
<Dashkit overlayMenuItems={[] as Array<MenuItem> | null} />
[deprecated]
// overlayMenuItems property has greater priority over setSettings menu
DashKit.setSettings({menu: [] as Array<MenuItem>});
type DraggedOverItem = {
h: number;
w: number;
type: string;
parent: string;
i?: number;
};
interface DashKitDnDWrapperProps {
dragImageSrc?: string;
onDragStart?: (dragProps: ItemDragProps) => void;
onDragEnd?: () => void;
onDropDragOver?: (draggedItem: DraggedOverItem, sharedItem: DraggedOverItem | null) => void | boolean;
}
dragImageSrc
— изображение для предпросмотра при перетаскивании элемента. По умолчанию используется прозрачный PNG-файл размером 1 пиксель в форматеbase64
.onDragStart
— обратный вызов, срабатывающий при начале перетаскивания элемента изActionPanel
.onDragEnd
— обратный вызов, срабатывающий при завершении перетаскивания элемента или его отмене.
type ItemDragProps = {
type: string; // Plugin type
layout?: { // Optional. Layout item size for preview and init
w?: number;
h?: number;
};
extra?: any; // Custom user context
};
type ItemDropProps = {
commit: () => void; // Callback should be called after all config operations are made
dragProps: ItemDragProps; // Item drag props
itemLayout: ConfigLayout; // Calculated item layout dimensions
newLayout: ConfigLayout[]; // New layout after element is dropped
};
const overlayMenuItems = [
{
id: 'chart',
icon: <Icon data={ChartColumn} />,
title: 'Chart',
qa: 'chart',
dragProps: { // ItemDragProps
type: 'custom', // Registered plugin type
},
}
]
const onDrop = (dropProps: ItemDropProps) => {
// ... add element to your config
dropProps.commit();
}
<DashKitDnDWrapper>
<DashKit editMode={true} config={config} onChange={onChange} onDrop={onDrop} />
<ActionPanel items={overlayMenuItems} />
</DashKitDnDWrapper>
Имя | Описание |
---|---|
Переменные панели действий | |
--dashkit-action-panel-color |
Цвет фона. |
--dashkit-action-panel-border-color |
Цвет границы. |
--dashkit-action-panel-border-radius |
Радиус скругления углов. |
Переменные элементов панели действий | |
--dashkit-action-panel-item-color |
Цвет фона. |
--dashkit-action-panel-item-text-color |
Цвет текста. |
--dashkit-action-panel-item-color-hover |
Цвет фона при наведении. |
--dashkit-action-panel-item-text-color-hover |
Цвет текста при наведении. |
Переменные оверлея | |
--dashkit-overlay-border-color |
Цвет границы. |
--dashkit-overlay-color |
Цвет фона. |
--dashkit-overlay-opacity |
Непрозрачность. |
Переменные элементов сетки | |
--dashkit-grid-item-edit-opacity |
Непрозрачность. |
--dashkit-grid-item-border-radius |
Радиус скругления углов. |
Переменные-заполнители | |
--dashkit-placeholder-color |
Цвет фона. |
--dashkit-placeholder-opacity |
Непрозрачность. |
.custom-theme-wrapper {
--dashkit-grid-item-edit-opacit: 1;
--dashkit-overlay-color: var(--g-color-base-float);
--dashkit-overlay-border-color: var(--g-color-base-float);
--dashkit-overlay-opacity: 0.5;
--dashkit-action-panel-border-color: var(--g-color-line-info);
--dashkit-action-panel-color: var(--g-color-base-float-accent);
--dashkit-action-panel-border-radius: var(--g-border-radius-xxl);
}
// ....
const CustomThemeWrapper = (props: {
dashkitProps: DashkitProps;
actionPanelProps: ActionPanelProps;
}) => {
return (
<div className="custom-theme-wrapper">
<Dashkit {...props.dashkitProps} />
<ActionPanel {...props.actionPanelProps} />
</div>
);
};
- Установите зависимости:
npm ci
. - Выполните сборку проекта:
npm run build
. - Запустите Storybook:
npm run start
.
По умолчанию Storybook запускается на http://localhost:7120/
.
В некоторых случаях при запущенном storybook свежие изменения из проекта могут не примениться. В таких ситуациях следует пересобрать проект вручную и перезапустить Storybook.
server {
server_name dashkit.username.ru;
include common/ssl;
access_log /home/username/logs/common.access.log;
error_log /home/username/logs/common.error.log;
root /home/username/projects/dashkit;
location / {
try_files $uri @node;
}
location @node {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:7120;
proxy_redirect off;
}
}