ydb-embedded-ui 3.1.0 → 3.2.1
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +30 -0
- package/README.md +2 -0
- package/dist/components/DateRange/DateRange.scss +11 -0
- package/dist/{containers/Tenant/Diagnostics/TopShards → components}/DateRange/DateRange.tsx +7 -7
- package/dist/{containers/Tenant/Diagnostics/TopShards → components}/DateRange/index.ts +0 -0
- package/dist/components/EntitiesCount/EntitiesCount.tsx +34 -0
- package/dist/components/EntitiesCount/i18n/en.json +3 -0
- package/dist/components/{AsideNavigation/Settings → EntitiesCount}/i18n/index.ts +2 -2
- package/dist/components/EntitiesCount/i18n/ru.json +3 -0
- package/dist/components/EntitiesCount/index.ts +1 -0
- package/dist/components/Fullscreen/Fullscreen.scss +7 -5
- package/dist/components/Illustration/Illustration.tsx +4 -11
- package/dist/components/InfoViewer/InfoViewer.scss +2 -0
- package/dist/components/TabletsOverall/TabletsOverall.tsx +4 -4
- package/dist/components/TabletsStatistic/TabletsStatistic.tsx +56 -0
- package/dist/components/TabletsStatistic/index.ts +1 -0
- package/dist/containers/App/App.scss +4 -12
- package/dist/containers/AsideNavigation/AsideNavigation.scss +0 -18
- package/dist/containers/AsideNavigation/AsideNavigation.tsx +95 -33
- package/dist/containers/Heatmap/Heatmap.scss +0 -7
- package/dist/containers/Heatmap/Heatmap.tsx +203 -0
- package/dist/containers/Heatmap/HeatmapCanvas/HeatmapCanvas.js +2 -1
- package/dist/containers/Heatmap/index.ts +1 -0
- package/dist/containers/Node/Node.tsx +1 -1
- package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.tsx +1 -1
- package/dist/containers/Storage/Storage.js +12 -19
- package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +16 -0
- package/dist/containers/Tablets/Tablets.scss +0 -5
- package/dist/containers/Tablets/Tablets.tsx +172 -0
- package/dist/containers/Tablets/i18n/en.json +6 -0
- package/dist/{components/AsideNavigation → containers/Tablets}/i18n/index.ts +1 -1
- package/dist/containers/Tablets/i18n/ru.json +6 -0
- package/dist/containers/Tablets/index.ts +1 -0
- package/dist/containers/TabletsFilters/TabletsFilters.js +4 -8
- package/dist/containers/TabletsFilters/TabletsFilters.scss +6 -2
- package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +8 -13
- package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +7 -7
- package/dist/containers/Tenant/Diagnostics/{TopShards/TopShards.scss → OverloadedShards/OverloadedShards.scss} +1 -1
- package/dist/containers/Tenant/Diagnostics/{TopShards/TopShards.tsx → OverloadedShards/OverloadedShards.tsx} +10 -11
- package/dist/containers/Tenant/Diagnostics/{TopShards → OverloadedShards}/i18n/en.json +0 -0
- package/dist/containers/Tenant/Diagnostics/OverloadedShards/i18n/index.ts +11 -0
- package/dist/containers/Tenant/Diagnostics/{TopShards → OverloadedShards}/i18n/ru.json +0 -0
- package/dist/containers/Tenant/Diagnostics/OverloadedShards/index.ts +1 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +7 -7
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.scss +16 -19
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +202 -0
- package/dist/containers/Tenant/Diagnostics/TopQueries/i18n/en.json +4 -0
- package/dist/containers/Tenant/Diagnostics/{TopShards → TopQueries}/i18n/index.ts +1 -1
- package/dist/containers/Tenant/Diagnostics/TopQueries/i18n/ru.json +4 -0
- package/dist/containers/Tenant/Diagnostics/TopQueries/index.ts +1 -0
- package/dist/containers/Tenants/Tenants.js +1 -1
- package/dist/containers/UserSettings/UserSettings.tsx +5 -4
- package/dist/routes.ts +1 -1
- package/dist/services/api.d.ts +7 -0
- package/dist/store/reducers/describe.ts +4 -1
- package/dist/store/reducers/executeTopQueries.ts +170 -0
- package/dist/store/reducers/{heatmap.js → heatmap.ts} +33 -18
- package/dist/store/reducers/settings.js +13 -3
- package/dist/store/reducers/shardsWorkload.ts +9 -9
- package/dist/store/reducers/storage.js +2 -0
- package/dist/store/reducers/{tablets.js → tablets.ts} +30 -17
- package/dist/store/state-url-mapping.js +10 -2
- package/dist/types/api/compute.ts +52 -0
- package/dist/types/api/consumer.ts +257 -0
- package/dist/types/api/enums.ts +2 -2
- package/dist/types/api/nodes.ts +5 -2
- package/dist/types/api/pdisk.ts +3 -0
- package/dist/types/api/schema.ts +17 -3
- package/dist/types/api/storage.ts +31 -28
- package/dist/types/api/tablet.ts +18 -2
- package/dist/types/api/tenant.ts +4 -1
- package/dist/types/api/topic.ts +157 -0
- package/dist/types/api/vdisk.ts +3 -0
- package/dist/types/store/executeTopQueries.ts +29 -0
- package/dist/types/store/heatmap.ts +51 -0
- package/dist/types/store/schema.ts +3 -3
- package/dist/types/store/shardsWorkload.ts +3 -3
- package/dist/types/store/tablets.ts +42 -0
- package/dist/utils/constants.ts +1 -37
- package/dist/utils/getNodesColumns.js +14 -2
- package/dist/utils/tablet.ts +53 -0
- package/package.json +4 -3
- package/dist/components/AsideNavigation/AsideHeader.scss +0 -147
- package/dist/components/AsideNavigation/AsideHeader.tsx +0 -389
- package/dist/components/AsideNavigation/AsideHeaderFooterItem/AsideHeaderFooterItem.scss +0 -82
- package/dist/components/AsideNavigation/AsideHeaderFooterItem/AsideHeaderFooterItem.tsx +0 -138
- package/dist/components/AsideNavigation/AsideHeaderFooterSlot/AsideHeaderFooterSlot.tsx +0 -33
- package/dist/components/AsideNavigation/AsideHeaderFooterSlot/SlotsContext.tsx +0 -49
- package/dist/components/AsideNavigation/AsideHeaderTooltip/AsideHeaderTooltip.scss +0 -16
- package/dist/components/AsideNavigation/AsideHeaderTooltip/AsideHeaderTooltip.tsx +0 -37
- package/dist/components/AsideNavigation/CompositeBar/CompositeBar.scss +0 -108
- package/dist/components/AsideNavigation/CompositeBar/CompositeBar.tsx +0 -282
- package/dist/components/AsideNavigation/Content/Content.tsx +0 -35
- package/dist/components/AsideNavigation/Drawer/Drawer.scss +0 -76
- package/dist/components/AsideNavigation/Drawer/Drawer.tsx +0 -134
- package/dist/components/AsideNavigation/Drawer/index.ts +0 -1
- package/dist/components/AsideNavigation/Logo/Logo.scss +0 -43
- package/dist/components/AsideNavigation/Logo/Logo.tsx +0 -82
- package/dist/components/AsideNavigation/Settings/README.md +0 -92
- package/dist/components/AsideNavigation/Settings/Settings.scss +0 -128
- package/dist/components/AsideNavigation/Settings/Settings.tsx +0 -270
- package/dist/components/AsideNavigation/Settings/SettingsMenu/SettingsMenu.scss +0 -78
- package/dist/components/AsideNavigation/Settings/SettingsMenu/SettingsMenu.tsx +0 -141
- package/dist/components/AsideNavigation/Settings/SettingsSearch/SettingsSearch.tsx +0 -57
- package/dist/components/AsideNavigation/Settings/collect-settings.ts +0 -156
- package/dist/components/AsideNavigation/Settings/filter-settings.ts +0 -38
- package/dist/components/AsideNavigation/Settings/helpers.ts +0 -39
- package/dist/components/AsideNavigation/Settings/i18n/en.json +0 -5
- package/dist/components/AsideNavigation/Settings/i18n/ru.json +0 -5
- package/dist/components/AsideNavigation/Settings/index.ts +0 -1
- package/dist/components/AsideNavigation/constants.ts +0 -28
- package/dist/components/AsideNavigation/helpers.ts +0 -34
- package/dist/components/AsideNavigation/i18n/en.json +0 -4
- package/dist/components/AsideNavigation/i18n/ru.json +0 -4
- package/dist/components/AsideNavigation/icons.ts +0 -32
- package/dist/components/AsideNavigation/types.ts +0 -23
- package/dist/components/TabletsStatistic/TabletsStatistic.js +0 -58
- package/dist/containers/Heatmap/Heatmap.js +0 -244
- package/dist/containers/Tablets/Tablets.js +0 -228
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.js +0 -188
- package/dist/containers/Tenant/Diagnostics/TopShards/DateRange/DateRange.scss +0 -13
- package/dist/containers/Tenant/Diagnostics/TopShards/index.ts +0 -1
- package/dist/store/reducers/executeTopQueries.js +0 -66
- package/dist/types/api/consumers.ts +0 -3
@@ -1,16 +0,0 @@
|
|
1
|
-
.nv-aside-header-tooltip {
|
2
|
-
&.yc-popup {
|
3
|
-
border: none;
|
4
|
-
box-shadow: none;
|
5
|
-
|
6
|
-
animation-name: none;
|
7
|
-
}
|
8
|
-
|
9
|
-
&__text {
|
10
|
-
padding: 6px 12px;
|
11
|
-
|
12
|
-
color: var(--yc-color-text-light-primary);
|
13
|
-
border-radius: 4px;
|
14
|
-
background-color: var(--yc-color-base-float-heavy);
|
15
|
-
}
|
16
|
-
}
|
@@ -1,37 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import block from 'bem-cn-lite';
|
3
|
-
import {Popup, PopupPlacement} from '@gravity-ui/uikit';
|
4
|
-
import './AsideHeaderTooltip.scss';
|
5
|
-
|
6
|
-
const b = block('nv-aside-header-tooltip');
|
7
|
-
const popupPlacement: PopupPlacement = ['right'];
|
8
|
-
|
9
|
-
export interface AsideHeaderTooltipProps {
|
10
|
-
anchor: HTMLElement | null;
|
11
|
-
text: React.ReactNode;
|
12
|
-
}
|
13
|
-
|
14
|
-
export const AsideHeaderTooltip: React.FC<AsideHeaderTooltipProps> = ({anchor, text}) => {
|
15
|
-
const anchorRef = React.useRef(anchor);
|
16
|
-
|
17
|
-
React.useEffect(() => {
|
18
|
-
anchorRef.current = anchor;
|
19
|
-
}, [anchor]);
|
20
|
-
if (!anchor) {
|
21
|
-
return null;
|
22
|
-
}
|
23
|
-
|
24
|
-
return (
|
25
|
-
<Popup
|
26
|
-
className={b()}
|
27
|
-
open={true}
|
28
|
-
anchorRef={anchorRef}
|
29
|
-
placement={popupPlacement}
|
30
|
-
disableEscapeKeyDown={true}
|
31
|
-
disableOutsideClick={true}
|
32
|
-
disableLayer={true}
|
33
|
-
>
|
34
|
-
<div className={b('text')}>{text}</div>
|
35
|
-
</Popup>
|
36
|
-
);
|
37
|
-
};
|
@@ -1,108 +0,0 @@
|
|
1
|
-
.nv-composite-bar {
|
2
|
-
$class: &;
|
3
|
-
|
4
|
-
flex: 1 0 auto;
|
5
|
-
|
6
|
-
width: 100%;
|
7
|
-
min-height: 40px;
|
8
|
-
|
9
|
-
&__root-menu-item {
|
10
|
-
cursor: pointer;
|
11
|
-
}
|
12
|
-
|
13
|
-
&__root-menu-item.yc-list__item_selected:not(&__root-menu-item_compact) {
|
14
|
-
background-color: var(--yc-color-base-selection);
|
15
|
-
}
|
16
|
-
|
17
|
-
& &__root-menu-item_compact#{&}__root-menu-item {
|
18
|
-
background-color: transparent;
|
19
|
-
}
|
20
|
-
|
21
|
-
&__menu-item {
|
22
|
-
display: flex;
|
23
|
-
align-items: center;
|
24
|
-
|
25
|
-
width: 100%;
|
26
|
-
height: 100%;
|
27
|
-
}
|
28
|
-
|
29
|
-
&__menu-icon-place {
|
30
|
-
display: flex;
|
31
|
-
flex-shrink: 0;
|
32
|
-
justify-content: center;
|
33
|
-
align-items: center;
|
34
|
-
|
35
|
-
width: var(--nv-aside-header-min-width);
|
36
|
-
height: 100%;
|
37
|
-
}
|
38
|
-
|
39
|
-
#{$class} &__menu-icon {
|
40
|
-
color: var(--yc-color-text-misc);
|
41
|
-
}
|
42
|
-
|
43
|
-
&__menu-title {
|
44
|
-
overflow: hidden;
|
45
|
-
|
46
|
-
width: 100%;
|
47
|
-
|
48
|
-
white-space: nowrap;
|
49
|
-
text-overflow: ellipsis;
|
50
|
-
}
|
51
|
-
|
52
|
-
&__root-collapse-item {
|
53
|
-
cursor: pointer;
|
54
|
-
}
|
55
|
-
|
56
|
-
&__collapse-item {
|
57
|
-
display: flex;
|
58
|
-
align-items: center;
|
59
|
-
|
60
|
-
width: 100%;
|
61
|
-
height: 100%;
|
62
|
-
padding: 0 16px;
|
63
|
-
}
|
64
|
-
|
65
|
-
&__collapse-items-popup-content {
|
66
|
-
padding: 4px 0;
|
67
|
-
}
|
68
|
-
|
69
|
-
&__link {
|
70
|
-
display: flex;
|
71
|
-
align-items: center;
|
72
|
-
|
73
|
-
width: 100%;
|
74
|
-
height: 100%;
|
75
|
-
|
76
|
-
&,
|
77
|
-
&:hover,
|
78
|
-
&:active,
|
79
|
-
&:visited,
|
80
|
-
&:focus {
|
81
|
-
text-decoration: none;
|
82
|
-
|
83
|
-
color: inherit;
|
84
|
-
outline: none;
|
85
|
-
}
|
86
|
-
}
|
87
|
-
|
88
|
-
&__btn-icon {
|
89
|
-
display: flex;
|
90
|
-
justify-content: center;
|
91
|
-
align-items: center;
|
92
|
-
|
93
|
-
width: 100%;
|
94
|
-
height: 100%;
|
95
|
-
|
96
|
-
@at-root .yc-list__item_active &:not(&_current) {
|
97
|
-
background-color: var(--yc-color-base-simple-hover);
|
98
|
-
}
|
99
|
-
|
100
|
-
&::before {
|
101
|
-
border-radius: 0;
|
102
|
-
}
|
103
|
-
|
104
|
-
&_current {
|
105
|
-
background-color: var(--yc-color-base-selection);
|
106
|
-
}
|
107
|
-
}
|
108
|
-
}
|
@@ -1,282 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import block from 'bem-cn-lite';
|
3
|
-
import AutoSizer from 'react-virtualized-auto-sizer';
|
4
|
-
import {List, Icon, Popup, PopupPlacement} from '@gravity-ui/uikit';
|
5
|
-
|
6
|
-
import {AsideHeaderMenuItem} from '../types';
|
7
|
-
import i18n from '../i18n';
|
8
|
-
import {AsideHeaderTooltip} from '../AsideHeaderTooltip/AsideHeaderTooltip';
|
9
|
-
|
10
|
-
import dotsIcon from '../../../assets/icons/dots.svg';
|
11
|
-
|
12
|
-
import './CompositeBar.scss';
|
13
|
-
|
14
|
-
const b = block('nv-composite-bar');
|
15
|
-
export const ITEM_HEIGHT = 40;
|
16
|
-
const POPUP_ITEM_HEIGHT = 28;
|
17
|
-
const COLLAPSE_ITEM_ID = 'nv-collapse-item-id';
|
18
|
-
const popupPlacement: PopupPlacement = ['right-start', 'right-end', 'right'];
|
19
|
-
|
20
|
-
const getSelectedItemIndex = (items: AsideHeaderMenuItem[]) => {
|
21
|
-
const index = items.findIndex(({current}) => Boolean(current));
|
22
|
-
return index === -1 ? undefined : index;
|
23
|
-
};
|
24
|
-
|
25
|
-
interface ItemProps {
|
26
|
-
item: AsideHeaderMenuItem;
|
27
|
-
isCompact: boolean;
|
28
|
-
collapseItems: AsideHeaderMenuItem[] | null;
|
29
|
-
onMouseEnter?: () => void;
|
30
|
-
onMouseLeave?: () => void;
|
31
|
-
onClick?: () => void;
|
32
|
-
}
|
33
|
-
|
34
|
-
const Item: React.FC<ItemProps> = ({item, isCompact, collapseItems, onClick}) => {
|
35
|
-
const [tooltipAnchor, setTooltipAnchor] = React.useState<HTMLDivElement | null>(null);
|
36
|
-
const [open, toggleOpen] = React.useState<boolean>(false);
|
37
|
-
const popupAnchor = React.useRef<HTMLDivElement>(null);
|
38
|
-
|
39
|
-
const tooltipText = item.tooltipText || item.title;
|
40
|
-
const iconSize = item.iconSize || 24;
|
41
|
-
const isCollapseItem = item.id === COLLAPSE_ITEM_ID;
|
42
|
-
|
43
|
-
const node = (
|
44
|
-
<div
|
45
|
-
className={b('menu-item')}
|
46
|
-
ref={popupAnchor}
|
47
|
-
onClick={() => {
|
48
|
-
if (typeof item.onItemClick === 'function') {
|
49
|
-
item.onItemClick(item, false);
|
50
|
-
}
|
51
|
-
if (isCollapseItem) {
|
52
|
-
toggleOpen(!open);
|
53
|
-
setTooltipAnchor(null);
|
54
|
-
}
|
55
|
-
onClick?.();
|
56
|
-
}}
|
57
|
-
>
|
58
|
-
<div className={b('menu-icon-place')}>
|
59
|
-
{isCompact ? (
|
60
|
-
<React.Fragment>
|
61
|
-
<div
|
62
|
-
onMouseEnter={(event) => !open && setTooltipAnchor(event.currentTarget)}
|
63
|
-
onMouseLeave={() => setTooltipAnchor(null)}
|
64
|
-
className={b('btn-icon', {current: Boolean(item.current)})}
|
65
|
-
>
|
66
|
-
{item.icon && (
|
67
|
-
<Icon data={item.icon} size={iconSize} className={b('menu-icon')} />
|
68
|
-
)}
|
69
|
-
</div>
|
70
|
-
<AsideHeaderTooltip anchor={tooltipAnchor} text={tooltipText} />
|
71
|
-
</React.Fragment>
|
72
|
-
) : (
|
73
|
-
item.icon && (
|
74
|
-
<Icon data={item.icon} size={iconSize} className={b('menu-icon')} />
|
75
|
-
)
|
76
|
-
)}
|
77
|
-
</div>
|
78
|
-
<div className={b('menu-title')} title={item.title}>
|
79
|
-
{item.title}
|
80
|
-
</div>
|
81
|
-
{isCollapseItem && Array.isArray(collapseItems) && Boolean(popupAnchor.current) && (
|
82
|
-
<Popup
|
83
|
-
placement={popupPlacement}
|
84
|
-
open={open}
|
85
|
-
anchorRef={popupAnchor}
|
86
|
-
onClose={() => toggleOpen(false)}
|
87
|
-
>
|
88
|
-
<div className={b('collapse-items-popup-content')}>
|
89
|
-
<List
|
90
|
-
itemClassName={b('root-collapse-item')}
|
91
|
-
items={collapseItems}
|
92
|
-
selectedItemIndex={getSelectedItemIndex(collapseItems)}
|
93
|
-
itemHeight={POPUP_ITEM_HEIGHT}
|
94
|
-
itemsHeight={collapseItems.length * POPUP_ITEM_HEIGHT}
|
95
|
-
virtualized={false}
|
96
|
-
filterable={false}
|
97
|
-
sortable={false}
|
98
|
-
renderItem={(collapseItem) => {
|
99
|
-
const collapseNode = (
|
100
|
-
<div
|
101
|
-
className={b('collapse-item')}
|
102
|
-
onClick={() => {
|
103
|
-
if (typeof collapseItem.onItemClick === 'function') {
|
104
|
-
collapseItem.onItemClick(collapseItem, true);
|
105
|
-
}
|
106
|
-
}}
|
107
|
-
>
|
108
|
-
{collapseItem.title}
|
109
|
-
</div>
|
110
|
-
);
|
111
|
-
if (typeof collapseItem.itemWrapper === 'function') {
|
112
|
-
return collapseItem.itemWrapper(
|
113
|
-
collapseNode,
|
114
|
-
collapseItem,
|
115
|
-
true,
|
116
|
-
isCompact,
|
117
|
-
);
|
118
|
-
}
|
119
|
-
|
120
|
-
return collapseItem.link ? (
|
121
|
-
<a href={collapseItem.link} className={b('link')}>
|
122
|
-
{collapseNode}
|
123
|
-
</a>
|
124
|
-
) : (
|
125
|
-
collapseNode
|
126
|
-
);
|
127
|
-
}}
|
128
|
-
/>
|
129
|
-
</div>
|
130
|
-
</Popup>
|
131
|
-
)}
|
132
|
-
</div>
|
133
|
-
);
|
134
|
-
|
135
|
-
if (typeof item.itemWrapper === 'function') {
|
136
|
-
return item.itemWrapper(node, item, false, isCompact) as React.ReactElement;
|
137
|
-
}
|
138
|
-
|
139
|
-
return item.link ? (
|
140
|
-
<a href={item.link} className={b('link')}>
|
141
|
-
{node}
|
142
|
-
</a>
|
143
|
-
) : (
|
144
|
-
node
|
145
|
-
);
|
146
|
-
};
|
147
|
-
Item.displayName = 'Item';
|
148
|
-
|
149
|
-
interface CompositeBarProps {
|
150
|
-
items: AsideHeaderMenuItem[];
|
151
|
-
isCompact: boolean;
|
152
|
-
onClickItem?: (item: AsideHeaderMenuItem) => void;
|
153
|
-
}
|
154
|
-
|
155
|
-
interface CompositeBarState {
|
156
|
-
height: string | number;
|
157
|
-
activeItemIndex?: number;
|
158
|
-
}
|
159
|
-
|
160
|
-
interface OnResizeArgs {
|
161
|
-
width: number;
|
162
|
-
height: number;
|
163
|
-
}
|
164
|
-
|
165
|
-
export class CompositeBar extends React.Component<CompositeBarProps> {
|
166
|
-
render() {
|
167
|
-
return (
|
168
|
-
<React.Fragment>
|
169
|
-
<div className={b()} style={{height: this.state.height}}>
|
170
|
-
{this.props.items.length !== 0 && (
|
171
|
-
<AutoSizer onResize={this.onResize}>
|
172
|
-
{({width, height}) => {
|
173
|
-
const style = {
|
174
|
-
width,
|
175
|
-
height,
|
176
|
-
};
|
177
|
-
return <div style={style}>{this.renderMenu(height)}</div>;
|
178
|
-
}}
|
179
|
-
</AutoSizer>
|
180
|
-
)}
|
181
|
-
</div>
|
182
|
-
</React.Fragment>
|
183
|
-
);
|
184
|
-
}
|
185
|
-
|
186
|
-
state: CompositeBarState = {
|
187
|
-
height: 'auto',
|
188
|
-
activeItemIndex: undefined,
|
189
|
-
};
|
190
|
-
|
191
|
-
private currentItemsCount = 0;
|
192
|
-
private skipCheckResize = false;
|
193
|
-
|
194
|
-
private onResize = ({height}: OnResizeArgs) => {
|
195
|
-
if (this.skipCheckResize) {
|
196
|
-
this.skipCheckResize = false;
|
197
|
-
return;
|
198
|
-
}
|
199
|
-
|
200
|
-
const desiredHeight = this.currentItemsCount * ITEM_HEIGHT;
|
201
|
-
if (height < desiredHeight) {
|
202
|
-
if (this.state.height !== desiredHeight) {
|
203
|
-
this.skipCheckResize = true;
|
204
|
-
this.setState({height: desiredHeight});
|
205
|
-
}
|
206
|
-
} else if (this.state.height !== 'auto') {
|
207
|
-
this.skipCheckResize = true;
|
208
|
-
this.setState({height: 'auto'});
|
209
|
-
}
|
210
|
-
};
|
211
|
-
|
212
|
-
private renderMenu(height: number) {
|
213
|
-
const {items, isCompact, onClickItem} = this.props;
|
214
|
-
const capacity = Math.max(1, Math.floor(height / ITEM_HEIGHT));
|
215
|
-
let listItems: AsideHeaderMenuItem[] | null;
|
216
|
-
let collapseItems: AsideHeaderMenuItem[] | null = null;
|
217
|
-
if (capacity === 1) {
|
218
|
-
listItems = items.filter((item) => item.pinned);
|
219
|
-
collapseItems = [...items.filter((item) => !item.pinned)];
|
220
|
-
if (collapseItems.length > 0) {
|
221
|
-
listItems.push(this.getCollapseItem());
|
222
|
-
}
|
223
|
-
} else if (capacity < items.length) {
|
224
|
-
const extraCount = items.filter(
|
225
|
-
(item, idx) => item.pinned && idx >= capacity - 1,
|
226
|
-
).length;
|
227
|
-
const pinnedFlag = items.reduceRight(
|
228
|
-
(acc, curr, idx) => {
|
229
|
-
const useExtraCount = !curr.pinned && idx < capacity - 1 && acc.extraCount > 0;
|
230
|
-
acc.flags.unshift(curr.pinned || useExtraCount);
|
231
|
-
return {
|
232
|
-
flags: acc.flags,
|
233
|
-
extraCount: acc.extraCount - Number(useExtraCount),
|
234
|
-
};
|
235
|
-
},
|
236
|
-
{flags: [] as boolean[], extraCount},
|
237
|
-
).flags;
|
238
|
-
listItems = items.filter(
|
239
|
-
(item, idx) => item.pinned || (idx < capacity - 1 && !pinnedFlag[idx]),
|
240
|
-
);
|
241
|
-
collapseItems = items.filter(
|
242
|
-
(item, idx) => !item.pinned && (idx >= capacity - 1 || pinnedFlag[idx]),
|
243
|
-
);
|
244
|
-
if (collapseItems.length > 0) {
|
245
|
-
listItems.push(this.getCollapseItem());
|
246
|
-
}
|
247
|
-
} else {
|
248
|
-
listItems = [...items];
|
249
|
-
}
|
250
|
-
this.currentItemsCount = listItems.length;
|
251
|
-
|
252
|
-
return (
|
253
|
-
<List
|
254
|
-
items={listItems}
|
255
|
-
selectedItemIndex={isCompact ? undefined : getSelectedItemIndex(listItems)}
|
256
|
-
itemHeight={ITEM_HEIGHT}
|
257
|
-
itemClassName={b('root-menu-item', {compact: isCompact})}
|
258
|
-
itemsHeight={listItems.length * ITEM_HEIGHT}
|
259
|
-
virtualized={false}
|
260
|
-
filterable={false}
|
261
|
-
sortable={false}
|
262
|
-
renderItem={(item) => (
|
263
|
-
<Item
|
264
|
-
item={item}
|
265
|
-
isCompact={isCompact}
|
266
|
-
collapseItems={collapseItems}
|
267
|
-
onClick={() => onClickItem?.(item)}
|
268
|
-
/>
|
269
|
-
)}
|
270
|
-
/>
|
271
|
-
);
|
272
|
-
}
|
273
|
-
|
274
|
-
private getCollapseItem(): AsideHeaderMenuItem {
|
275
|
-
return {
|
276
|
-
id: COLLAPSE_ITEM_ID,
|
277
|
-
title: i18n('label_more'),
|
278
|
-
icon: dotsIcon,
|
279
|
-
iconSize: 16,
|
280
|
-
};
|
281
|
-
}
|
282
|
-
}
|
@@ -1,35 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
|
3
|
-
export type RenderContentType = (data: {size: number}) => React.ReactNode;
|
4
|
-
|
5
|
-
interface ContentProps {
|
6
|
-
renderContent?: RenderContentType;
|
7
|
-
className?: string;
|
8
|
-
size: number;
|
9
|
-
}
|
10
|
-
|
11
|
-
interface RenderContentProps {
|
12
|
-
renderContent: RenderContentType;
|
13
|
-
size: number;
|
14
|
-
}
|
15
|
-
|
16
|
-
const RenderContent: React.FC<RenderContentProps> = React.memo(({renderContent, size}) => {
|
17
|
-
return <React.Fragment>{renderContent({size})}</React.Fragment>;
|
18
|
-
});
|
19
|
-
|
20
|
-
RenderContent.displayName = 'RenderContent';
|
21
|
-
|
22
|
-
export const Content: React.FC<ContentProps> = ({size, className, renderContent}) => {
|
23
|
-
return (
|
24
|
-
<div
|
25
|
-
className={className}
|
26
|
-
style={{
|
27
|
-
...({'--nv-aside-header-size': `${size}px`} as React.CSSProperties),
|
28
|
-
}}
|
29
|
-
>
|
30
|
-
{typeof renderContent === 'function' && (
|
31
|
-
<RenderContent size={size} renderContent={renderContent} />
|
32
|
-
)}
|
33
|
-
</div>
|
34
|
-
);
|
35
|
-
};
|
@@ -1,76 +0,0 @@
|
|
1
|
-
.nv-drawer {
|
2
|
-
&__item {
|
3
|
-
position: absolute;
|
4
|
-
top: 0;
|
5
|
-
bottom: 0;
|
6
|
-
left: 0;
|
7
|
-
|
8
|
-
height: 100%;
|
9
|
-
|
10
|
-
background-color: var(--yc-color-base-background);
|
11
|
-
will-change: transform;
|
12
|
-
}
|
13
|
-
|
14
|
-
&__item-transition-enter {
|
15
|
-
transform: translate(-100%, 0);
|
16
|
-
}
|
17
|
-
|
18
|
-
&__item-transition-enter-active {
|
19
|
-
transition: transform 300ms;
|
20
|
-
transform: translate(0, 0);
|
21
|
-
}
|
22
|
-
|
23
|
-
&__item-transition-enter-done {
|
24
|
-
// it is hack to prevent text blur after animation in any browsers
|
25
|
-
filter: blur(0px);
|
26
|
-
|
27
|
-
transform: translateZ(0);
|
28
|
-
}
|
29
|
-
|
30
|
-
&__item-transition-exit {
|
31
|
-
transform: translate(0, 0);
|
32
|
-
}
|
33
|
-
|
34
|
-
&__item-transition-exit-active {
|
35
|
-
transition: transform 300ms;
|
36
|
-
transform: translate(-100%, 0);
|
37
|
-
}
|
38
|
-
|
39
|
-
&__item-transition-exit-done {
|
40
|
-
visibility: hidden;
|
41
|
-
}
|
42
|
-
|
43
|
-
&__veil {
|
44
|
-
position: absolute;
|
45
|
-
top: 0;
|
46
|
-
right: 0;
|
47
|
-
bottom: 0;
|
48
|
-
left: 0;
|
49
|
-
|
50
|
-
background-color: var(--yc-color-sfx-veil);
|
51
|
-
}
|
52
|
-
|
53
|
-
&__veil-transition-enter {
|
54
|
-
opacity: 0;
|
55
|
-
}
|
56
|
-
|
57
|
-
&__veil-transition-enter-active {
|
58
|
-
opacity: 1;
|
59
|
-
|
60
|
-
transition: opacity 300ms;
|
61
|
-
}
|
62
|
-
|
63
|
-
&__veil-transition-exit {
|
64
|
-
opacity: 1;
|
65
|
-
}
|
66
|
-
|
67
|
-
&__veil-transition-exit-active {
|
68
|
-
opacity: 0;
|
69
|
-
|
70
|
-
transition: opacity 300ms;
|
71
|
-
}
|
72
|
-
|
73
|
-
&__veil-transition-exit-done {
|
74
|
-
visibility: hidden;
|
75
|
-
}
|
76
|
-
}
|
@@ -1,134 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import block from 'bem-cn-lite';
|
3
|
-
import {CSSTransition, Transition} from 'react-transition-group';
|
4
|
-
import './Drawer.scss';
|
5
|
-
|
6
|
-
const b = block('nv-drawer');
|
7
|
-
const TIMEOUT = 300;
|
8
|
-
|
9
|
-
export interface DrawerItemProps {
|
10
|
-
visible: boolean;
|
11
|
-
className?: string;
|
12
|
-
}
|
13
|
-
|
14
|
-
export const DrawerItem: React.FC<DrawerItemProps> = ({className, visible, children}) => {
|
15
|
-
return (
|
16
|
-
<CSSTransition
|
17
|
-
in={visible}
|
18
|
-
timeout={TIMEOUT}
|
19
|
-
unmountOnExit={true}
|
20
|
-
classNames={b('item-transition')}
|
21
|
-
>
|
22
|
-
<div className={b('item', className)}>{children}</div>
|
23
|
-
</CSSTransition>
|
24
|
-
);
|
25
|
-
};
|
26
|
-
|
27
|
-
type DrawerChild = React.ReactElement<DrawerItemProps>;
|
28
|
-
|
29
|
-
export interface DrawerProps {
|
30
|
-
children: DrawerChild | DrawerChild[];
|
31
|
-
preventSrcollBody?: boolean;
|
32
|
-
className?: string;
|
33
|
-
style?: React.CSSProperties;
|
34
|
-
onVeilClick?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
35
|
-
onEscape?: () => void;
|
36
|
-
}
|
37
|
-
|
38
|
-
export const Drawer: React.FC<DrawerProps> = ({
|
39
|
-
className,
|
40
|
-
children,
|
41
|
-
style,
|
42
|
-
onVeilClick,
|
43
|
-
onEscape,
|
44
|
-
preventSrcollBody = true,
|
45
|
-
}) => {
|
46
|
-
let someItemVisible = false;
|
47
|
-
React.Children.forEach(children, (child) => {
|
48
|
-
const childElem = child as DrawerChild;
|
49
|
-
if (childElem.type === DrawerItem) {
|
50
|
-
const childVisible = Boolean(childElem.props.visible);
|
51
|
-
if (childVisible) {
|
52
|
-
someItemVisible = true;
|
53
|
-
}
|
54
|
-
}
|
55
|
-
});
|
56
|
-
|
57
|
-
React.useEffect(() => {
|
58
|
-
function onKeyDown(event: KeyboardEvent) {
|
59
|
-
if (event.key === 'Escape') {
|
60
|
-
onEscape?.();
|
61
|
-
}
|
62
|
-
}
|
63
|
-
if (someItemVisible) {
|
64
|
-
window.addEventListener('keydown', onKeyDown);
|
65
|
-
}
|
66
|
-
return () => {
|
67
|
-
window.removeEventListener('keydown', onKeyDown);
|
68
|
-
};
|
69
|
-
}, [onEscape, someItemVisible]);
|
70
|
-
|
71
|
-
React.useEffect(() => {
|
72
|
-
const prevPreventSrcollBody = preventSrcollBody;
|
73
|
-
const cleanupPreventScrollBody = () => {
|
74
|
-
document.body.style.paddingRight = '';
|
75
|
-
document.body.style.paddingBottom = '';
|
76
|
-
document.body.style.overflow = '';
|
77
|
-
};
|
78
|
-
const setPreventScrollBody = () => {
|
79
|
-
const vw = window.innerWidth - document.documentElement.clientWidth;
|
80
|
-
const hw = window.innerHeight - document.documentElement.clientHeight;
|
81
|
-
document.body.style.paddingRight = vw + 'px';
|
82
|
-
document.body.style.paddingBottom = hw + 'px';
|
83
|
-
document.body.style.overflow = 'hidden';
|
84
|
-
};
|
85
|
-
if (prevPreventSrcollBody) {
|
86
|
-
if (someItemVisible) {
|
87
|
-
setPreventScrollBody();
|
88
|
-
} else {
|
89
|
-
cleanupPreventScrollBody();
|
90
|
-
}
|
91
|
-
}
|
92
|
-
return () => {
|
93
|
-
if (prevPreventSrcollBody) {
|
94
|
-
cleanupPreventScrollBody();
|
95
|
-
}
|
96
|
-
};
|
97
|
-
}, [someItemVisible, preventSrcollBody]);
|
98
|
-
|
99
|
-
return (
|
100
|
-
<Transition
|
101
|
-
in={someItemVisible}
|
102
|
-
timeout={{enter: 0, exit: TIMEOUT}}
|
103
|
-
mountOnEnter
|
104
|
-
unmountOnExit
|
105
|
-
>
|
106
|
-
{(state) => {
|
107
|
-
const childrenVisible = someItemVisible && state === 'entered';
|
108
|
-
return (
|
109
|
-
<div className={b(null, className)} style={style}>
|
110
|
-
<CSSTransition
|
111
|
-
in={childrenVisible}
|
112
|
-
timeout={TIMEOUT}
|
113
|
-
unmountOnExit={true}
|
114
|
-
classNames={b('veil-transition')}
|
115
|
-
>
|
116
|
-
<div className={b('veil')} onClick={onVeilClick} />
|
117
|
-
</CSSTransition>
|
118
|
-
{React.Children.map(children, (child) => {
|
119
|
-
const childElem = child as DrawerChild;
|
120
|
-
if (childElem.type === DrawerItem) {
|
121
|
-
const childVisible = Boolean(childElem.props.visible);
|
122
|
-
return React.cloneElement(childElem, {
|
123
|
-
...childElem.props,
|
124
|
-
visible: childVisible && childrenVisible,
|
125
|
-
});
|
126
|
-
}
|
127
|
-
return child;
|
128
|
-
})}
|
129
|
-
</div>
|
130
|
-
);
|
131
|
-
}}
|
132
|
-
</Transition>
|
133
|
-
);
|
134
|
-
};
|
@@ -1 +0,0 @@
|
|
1
|
-
export * from './Drawer';
|