ydb-embedded-ui 1.8.7 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/dist/components/BasicNodeViewer/BasicNodeViewer.scss +43 -0
  3. package/dist/components/BasicNodeViewer/BasicNodeViewer.tsx +53 -0
  4. package/dist/components/BasicNodeViewer/index.ts +1 -0
  5. package/dist/components/EntityStatus/EntityStatus.js +15 -3
  6. package/dist/components/FullNodeViewer/FullNodeViewer.js +29 -48
  7. package/dist/components/FullNodeViewer/FullNodeViewer.scss +0 -45
  8. package/dist/components/IndexInfoViewer/IndexInfoViewer.tsx +52 -0
  9. package/dist/components/InfoViewer/index.ts +4 -0
  10. package/dist/components/InfoViewer/utils.ts +32 -0
  11. package/dist/components/ProgressViewer/ProgressViewer.js +1 -1
  12. package/dist/components/TabletsOverall/TabletsOverall.tsx +1 -1
  13. package/dist/containers/Node/Node.scss +5 -1
  14. package/dist/containers/Node/Node.tsx +7 -1
  15. package/dist/containers/Node/NodeOverview/NodeOverview.tsx +1 -3
  16. package/dist/containers/Node/NodeStructure/NodeStructure.scss +30 -1
  17. package/dist/containers/Node/NodeStructure/PDiskTitleBadge.tsx +25 -0
  18. package/dist/containers/Node/NodeStructure/Pdisk.tsx +24 -2
  19. package/dist/containers/Nodes/Nodes.js +1 -0
  20. package/dist/containers/ReduxTooltip/ReduxTooltip.js +1 -1
  21. package/dist/containers/Storage/Pdisk/Pdisk.tsx +25 -33
  22. package/dist/containers/Storage/Vdisk/Vdisk.js +2 -0
  23. package/dist/containers/Tablet/Tablet.js +2 -2
  24. package/dist/containers/Tablets/Tablets.js +1 -1
  25. package/dist/containers/Tablets/Tablets.scss +0 -6
  26. package/dist/containers/TabletsFilters/TabletsFilters.scss +0 -7
  27. package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.scss +6 -2
  28. package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +24 -14
  29. package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.js +6 -2
  30. package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.scss +6 -2
  31. package/dist/containers/Tenant/Diagnostics/HotKeys/HotKeys.js +3 -3
  32. package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +24 -3
  33. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +15 -13
  34. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.scss +22 -6
  35. package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.js +80 -10
  36. package/dist/containers/Tenant/Schema/SchemaInfoViewer/SchemaInfoViewer.js +20 -16
  37. package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +1 -0
  38. package/dist/containers/Tenant/utils/schema.ts +73 -28
  39. package/dist/containers/Tenant/utils/schemaActions.ts +42 -32
  40. package/dist/services/api.js +13 -8
  41. package/dist/store/reducers/executeQuery.js +1 -1
  42. package/dist/store/reducers/executeTopQueries.js +1 -1
  43. package/dist/store/reducers/olapStats.js +5 -1
  44. package/dist/store/reducers/preview.js +1 -1
  45. package/dist/store/reducers/shardsWorkload.js +32 -4
  46. package/dist/types/api/schema.ts +43 -1
  47. package/dist/types/api/storage.ts +54 -0
  48. package/dist/utils/getNodesColumns.js +2 -0
  49. package/dist/utils/pdisk.ts +74 -0
  50. package/dist/utils/tooltip.js +27 -0
  51. package/package.json +2 -2
@@ -14,9 +14,11 @@ import {Vdisk} from './Vdisk';
14
14
 
15
15
  import {bytesToGB, pad9} from '../../../utils/utils';
16
16
  import {formatStorageValuesToGb} from '../../../utils';
17
+ import {getPDiskType} from '../../../utils/pdisk';
17
18
 
18
19
  import {DEFAULT_TABLE_SETTINGS} from '../../../utils/constants';
19
20
  import {valueIsDefined} from './NodeStructure';
21
+ import {PDiskTitleBadge} from './PDiskTitleBadge';
20
22
 
21
23
  const b = cn('kv-node-structure');
22
24
 
@@ -230,6 +232,7 @@ export function PDisk(props: PDiskProps) {
230
232
  }
231
233
  if (valueIsDefined(Category)) {
232
234
  pdiskInfo.push({label: 'Category', value: Category});
235
+ pdiskInfo.push({label: 'Type', value: getPDiskType(data)});
233
236
  }
234
237
  pdiskInfo.push({
235
238
  label: 'Allocated Size',
@@ -286,8 +289,27 @@ export function PDisk(props: PDiskProps) {
286
289
  <div className={b('pdisk')} id={props.id}>
287
290
  <div className={b('pdisk-header')}>
288
291
  <div className={b('pdisk-title-wrapper')}>
289
- <span>{data.Path}</span>
290
- <EntityStatus status={data.Device} name={`${data.NodeId}-${data.PDiskId}`} />
292
+ <EntityStatus status={data.Device} />
293
+ <PDiskTitleBadge
294
+ label="PDiskID"
295
+ value={data.PDiskId}
296
+ className={b('pdisk-title-id')}
297
+ />
298
+ <PDiskTitleBadge
299
+ value={getPDiskType(data)}
300
+ className={b('pdisk-title-type')}
301
+ />
302
+ <ProgressViewer
303
+ value={data.TotalSize - data.AvailableSize}
304
+ capacity={data.TotalSize}
305
+ formatValues={formatStorageValuesToGb}
306
+ colorizeProgress={true}
307
+ className={b('pdisk-title-size')}
308
+ />
309
+ <PDiskTitleBadge
310
+ label="VDisks"
311
+ value={data.vDisks.length}
312
+ />
291
313
  </div>
292
314
  <Button onClick={unfolded ? onClosePDiskDetails : onOpenPDiskDetails} view="flat-secondary">
293
315
  <ArrowToggle direction={unfolded ? 'top' : 'bottom'} />
@@ -63,6 +63,7 @@ class Nodes extends React.Component {
63
63
  }
64
64
 
65
65
  componentWillUnmount() {
66
+ this.props.hideTooltip();
66
67
  clearInterval(this.reloadDescriptor);
67
68
  }
68
69
 
@@ -11,7 +11,7 @@ const propTypes = {
11
11
  className: PropTypes.string,
12
12
  toolTipVisible: PropTypes.bool,
13
13
  currentHoveredRef: PropTypes.object,
14
- data: PropTypes.object,
14
+ data: PropTypes.any,
15
15
  template: PropTypes.func,
16
16
  hideTooltip: PropTypes.func,
17
17
  };
@@ -8,6 +8,8 @@ import {bytesToGB} from '../../../utils/utils';
8
8
  import routes, {createHref} from '../../../routes';
9
9
  //@ts-ignore
10
10
  import {getPDiskId} from '../../../utils';
11
+ import {getPDiskType} from '../../../utils/pdisk';
12
+ import {TPDiskStateInfo, TPDiskState} from '../../../types/api/storage';
11
13
  import DiskStateProgressBar, {
12
14
  diskProgressColors,
13
15
  } from '../DiskStateProgressBar/DiskStateProgressBar';
@@ -20,38 +22,29 @@ import './Pdisk.scss';
20
22
  const b = cn('pdisk-storage');
21
23
 
22
24
  const stateSeverity = {
23
- Initial: 0,
24
- Normal: 1,
25
- InitialFormatRead: 3,
26
- InitialSysLogRead: 3,
27
- InitialCommonLogRead: 3,
28
- InitialFormatReadError: 5,
29
- InitialSysLogReadError: 5,
30
- InitialSysLogParseError: 5,
31
- InitialCommonLogReadError: 5,
32
- InitialCommonLogParseError: 5,
33
- CommonLoggerInitError: 5,
34
- OpenFileError: 5,
35
- ChunkQuotaError: 5,
36
- DeviceIoError: 5,
25
+ [TPDiskState.Initial]: 0,
26
+ [TPDiskState.Normal]: 1,
27
+ [TPDiskState.InitialFormatRead]: 3,
28
+ [TPDiskState.InitialSysLogRead]: 3,
29
+ [TPDiskState.InitialCommonLogRead]: 3,
30
+ [TPDiskState.InitialFormatReadError]: 5,
31
+ [TPDiskState.InitialSysLogReadError]: 5,
32
+ [TPDiskState.InitialSysLogParseError]: 5,
33
+ [TPDiskState.InitialCommonLogReadError]: 5,
34
+ [TPDiskState.InitialCommonLogParseError]: 5,
35
+ [TPDiskState.CommonLoggerInitError]: 5,
36
+ [TPDiskState.OpenFileError]: 5,
37
+ [TPDiskState.ChunkQuotaError]: 5,
38
+ [TPDiskState.DeviceIoError]: 5,
37
39
  };
38
40
 
39
- type PDiskState = keyof typeof stateSeverity;
40
-
41
- interface PDiskProps {
42
- NodeId: number;
43
- Host?: string;
44
- Path?: string;
45
- Realtime?: string;
46
- Device?: string;
47
- AvailableSize?: string;
48
- TotalSize?: string;
49
- State?: PDiskState;
50
- PDiskId: number;
51
- }
41
+ type PDiskProps = TPDiskStateInfo;
42
+
43
+ const isSeverityKey = (key?: TPDiskState): key is keyof typeof stateSeverity =>
44
+ key !== undefined && key in stateSeverity;
52
45
 
53
- const getStateSeverity = (pDiskState?: PDiskState) => {
54
- return pDiskState ? stateSeverity[pDiskState] : NOT_AVAILABLE_SEVERITY;
46
+ const getStateSeverity = (pDiskState?: TPDiskState) => {
47
+ return isSeverityKey(pDiskState) ? stateSeverity[pDiskState] : NOT_AVAILABLE_SEVERITY;
55
48
  };
56
49
 
57
50
  function Pdisk(props: PDiskProps) {
@@ -76,8 +69,7 @@ function Pdisk(props: PDiskProps) {
76
69
  };
77
70
  /* eslint-disable */
78
71
  const preparePdiskData = () => {
79
- const {AvailableSize, TotalSize, State, PDiskId, NodeId, Host, Path, Realtime, Device} =
80
- props;
72
+ const {AvailableSize, TotalSize, State, PDiskId, NodeId, Path, Realtime, Device} = props;
81
73
  const errorColors = [
82
74
  diskProgressColors[colorSeverity.Orange as keyof typeof diskProgressColors],
83
75
  diskProgressColors[colorSeverity.Red as keyof typeof diskProgressColors],
@@ -89,9 +81,9 @@ function Pdisk(props: PDiskProps) {
89
81
  ];
90
82
 
91
83
  pdiskData.push({property: 'State', value: State || 'not available'});
84
+ pdiskData.push({property: 'Type', value: getPDiskType(props) || 'unknown'});
92
85
  NodeId && pdiskData.push({property: 'Node Id', value: NodeId});
93
86
 
94
- Host && pdiskData.push({property: 'Host', value: Host});
95
87
  Path && pdiskData.push({property: 'Path', value: Path});
96
88
  pdiskData.push({
97
89
  property: 'Available',
@@ -151,7 +143,7 @@ function Pdisk(props: PDiskProps) {
151
143
  href={createHref(
152
144
  routes.node,
153
145
  {id: props.NodeId, activeTab: STRUCTURE},
154
- {pdiskId: props.PDiskId},
146
+ {pdiskId: props.PDiskId || ''},
155
147
  )}
156
148
  />
157
149
  </div>
@@ -7,6 +7,7 @@ import {Popup} from '@yandex-cloud/uikit';
7
7
  import {bytesToGB, bytesToSpeed} from '../../../utils/utils';
8
8
  import routes, {createHref} from '../../../routes';
9
9
  import {stringifyVdiskId, getPDiskId} from '../../../utils';
10
+ import {getPDiskType} from '../../../utils/pdisk';
10
11
  import DiskStateProgressBar, {
11
12
  diskProgressColors,
12
13
  } from '../DiskStateProgressBar/DiskStateProgressBar';
@@ -169,6 +170,7 @@ function Vdisk(props) {
169
170
  property: 'State',
170
171
  value: PDisk.State || 'not available',
171
172
  });
173
+ pdiskData.push({property: 'Type', value: getPDiskType(PDisk) || 'unknown'});
172
174
  PDisk.NodeId && pdiskData.push({property: 'Node Id', value: PDisk.NodeId});
173
175
  PDisk.NodeId &&
174
176
  nodes[PDisk.NodeId] &&
@@ -199,7 +199,7 @@ class Tablet extends React.Component {
199
199
  return (
200
200
  <CriticalActionDialog
201
201
  visible={dialogVisible}
202
- text="The tablet will be killed. Do you want to proceed?"
202
+ text="The tablet will be restarted. Do you want to proceed?"
203
203
  onClose={this.hideDialog}
204
204
  onConfirm={this._onKillClick}
205
205
  />
@@ -363,7 +363,7 @@ class Tablet extends React.Component {
363
363
  disabled={this.isDisabledKill()}
364
364
  className={b('control')}
365
365
  >
366
- Kill
366
+ Restart
367
367
  </Button>
368
368
  {this.hasHiveId() ? (
369
369
  <React.Fragment>
@@ -150,7 +150,7 @@ class Tablets extends React.Component {
150
150
  const {stateFilter, typeFilter, className} = this.props;
151
151
 
152
152
  return (
153
- <div className={(b(), className)}>
153
+ <div className={b(null, className)}>
154
154
  <div className={b('header')}>
155
155
  <Select
156
156
  className={b('filter-control')}
@@ -13,13 +13,7 @@
13
13
  }
14
14
 
15
15
  &__items {
16
- display: flex;
17
16
  flex: 1 1 auto;
18
- flex-wrap: wrap;
19
- }
20
-
21
- &__items-wrapper {
22
- overflow: auto;
23
17
  }
24
18
 
25
19
  &__filters {
@@ -3,7 +3,6 @@
3
3
  .tablets-filters {
4
4
  overflow: auto;
5
5
 
6
- max-height: 400px;
7
6
  @include flex-container();
8
7
 
9
8
  &__node {
@@ -19,18 +18,12 @@
19
18
  }
20
19
 
21
20
  &__items {
22
- display: flex;
23
21
  overflow: auto;
24
22
  flex: 1 1 auto;
25
- flex-wrap: wrap;
26
23
 
27
24
  padding: 5px 20px;
28
25
  }
29
26
 
30
- &__items-wrapper {
31
- overflow: auto;
32
- }
33
-
34
27
  &__filters {
35
28
  display: flex;
36
29
  align-items: center;
@@ -1,9 +1,13 @@
1
+ $section-title-margin: 20px;
2
+ $section-title-line-height: 24px;
3
+
1
4
  .kv-detailed-overview {
2
5
  display: flex;
3
- gap: 10px;
6
+ gap: 20px;
4
7
  &__section {
5
8
  display: flex;
6
- flex: 0 0 50%;
9
+ overflow-x: hidden;
10
+ flex: 0 0 calc(50% - 10px);
7
11
  flex-direction: column;
8
12
  }
9
13
 
@@ -13,6 +13,11 @@ export enum GeneralPagesIds {
13
13
  'graph' = 'graph',
14
14
  }
15
15
 
16
+ type Page = {
17
+ id: GeneralPagesIds,
18
+ title: string,
19
+ };
20
+
16
21
  const overview = {
17
22
  id: GeneralPagesIds.overview,
18
23
  title: 'Overview',
@@ -76,17 +81,22 @@ export const TABLE_PAGES = [overview, topShards, graph, tablets, hotKeys, descri
76
81
 
77
82
  export const DIR_PAGES = [overview, topShards, describe];
78
83
 
79
- export const getPagesByType = (type?: EPathType) => {
80
- switch (type) {
81
- case EPathType.EPathTypeColumnStore:
82
- case EPathType.EPathTypeSubDomain:
83
- return DATABASE_PAGES;
84
- case EPathType.EPathTypeColumnTable:
85
- case EPathType.EPathTypeTable:
86
- return TABLE_PAGES;
87
- case EPathType.EPathTypeDir:
88
- case EPathType.EPathTypeTableIndex:
89
- default:
90
- return DIR_PAGES;
91
- }
92
- }
84
+ // verbose mapping to guarantee correct tabs for new path types
85
+ // TS will error when a new type is added but not mapped here
86
+ const pathTypeToPages: Record<EPathType, Page[] | undefined> = {
87
+ [EPathType.EPathTypeInvalid]: undefined,
88
+
89
+ [EPathType.EPathTypeSubDomain]: DATABASE_PAGES,
90
+ [EPathType.EPathTypeExtSubDomain]: DATABASE_PAGES,
91
+ [EPathType.EPathTypeColumnStore]: DATABASE_PAGES,
92
+
93
+ [EPathType.EPathTypeTable]: TABLE_PAGES,
94
+ [EPathType.EPathTypeColumnTable]: TABLE_PAGES,
95
+
96
+ [EPathType.EPathTypeDir]: DIR_PAGES,
97
+ [EPathType.EPathTypeTableIndex]: DIR_PAGES,
98
+ [EPathType.EPathTypeCdcStream]: DIR_PAGES,
99
+ };
100
+
101
+ export const getPagesByType = (type?: EPathType) =>
102
+ (type && pathTypeToPages[type]) || DIR_PAGES;
@@ -97,10 +97,14 @@ class Healthcheck extends React.Component {
97
97
  </div>
98
98
  {this.renderUpdateButton()}
99
99
  </div>
100
- <div>
100
+ <div className={b('preview-content')}>
101
101
  {text}
102
102
  {!statusOk && (
103
- <Button view="flat-info" onClick={showMoreHandler}>
103
+ <Button
104
+ view="flat-info"
105
+ onClick={showMoreHandler}
106
+ size="s"
107
+ >
104
108
  Show details
105
109
  </Button>
106
110
  )}
@@ -1,3 +1,4 @@
1
+ @use '../DetailedOverview/DetailedOverview.scss' as detailedOverview;
1
2
  @import '../../../../styles/mixins.scss';
2
3
 
3
4
  .healthcheck {
@@ -37,14 +38,17 @@
37
38
 
38
39
  &__status-wrapper {
39
40
  display: flex;
40
- align-items: baseline;
41
41
 
42
- margin-bottom: 15px;
42
+ margin-bottom: detailedOverview.$section-title-margin;
43
43
  gap: 8px;
44
44
  }
45
45
 
46
46
  &__preview-title {
47
47
  font-weight: 600;
48
+ line-height: detailedOverview.$section-title-line-height;
49
+ }
50
+
51
+ &__preview-content {
48
52
  line-height: 24px;
49
53
  }
50
54
 
@@ -8,9 +8,10 @@ import Icon from '../../../../components/Icon/Icon';
8
8
 
9
9
  import {AutoFetcher} from '../../../../utils/autofetcher';
10
10
  import {getHotKeys, setHotKeysOptions} from '../../../../store/reducers/hotKeys';
11
- import {EPathType} from '../../../../types/api/schema';
12
11
  import {prepareQueryError} from '../../../../utils';
13
12
 
13
+ import {isColumnEntityType, isTableType} from '../../utils/schema';
14
+
14
15
  import './HotKeys.scss';
15
16
 
16
17
  const b = cn('hot-keys');
@@ -42,8 +43,7 @@ function HotKeys({
42
43
  type,
43
44
  }) {
44
45
  const fetchData = () => {
45
- // ColumnTables excluded intentionally
46
- if (type === EPathType.EPathTypeTable) {
46
+ if (isTableType(type) && !isColumnEntityType(type)) {
47
47
  getHotKeys(currentSchemaPath);
48
48
  }
49
49
  };
@@ -1,4 +1,4 @@
1
- import {useEffect, useMemo} from 'react';
1
+ import {ReactNode, useEffect, useMemo} from 'react';
2
2
  import {useDispatch, useSelector} from 'react-redux';
3
3
  import cn from 'bem-cn-lite';
4
4
 
@@ -6,8 +6,9 @@ import {Loader} from '@yandex-cloud/uikit';
6
6
 
7
7
  //@ts-ignore
8
8
  import SchemaInfoViewer from '../../Schema/SchemaInfoViewer/SchemaInfoViewer';
9
+ import {IndexInfoViewer} from '../../../../components/IndexInfoViewer/IndexInfoViewer';
9
10
 
10
- import type {EPathType} from '../../../../types/api/schema';
11
+ import {EPathType} from '../../../../types/api/schema';
11
12
  import {isColumnEntityType, isTableType} from '../../utils/schema';
12
13
  import {AutoFetcher} from '../../../../utils/autofetcher';
13
14
  //@ts-ignore
@@ -112,11 +113,31 @@ function Overview(props: OverviewProps) {
112
113
  );
113
114
  };
114
115
 
116
+ const renderContent = () => {
117
+ // verbose mapping to guarantee a correct render for new path types
118
+ // TS will error when a new type is added but not mapped here
119
+ const pathTypeToComponent: Record<EPathType, (() => ReactNode) | undefined> = {
120
+ [EPathType.EPathTypeInvalid]: undefined,
121
+ [EPathType.EPathTypeDir]: undefined,
122
+ [EPathType.EPathTypeTable]: undefined,
123
+ [EPathType.EPathTypeSubDomain]: undefined,
124
+ [EPathType.EPathTypeTableIndex]: () => <IndexInfoViewer data={schemaData} />,
125
+ [EPathType.EPathTypeExtSubDomain]: undefined,
126
+ [EPathType.EPathTypeColumnStore]: undefined,
127
+ [EPathType.EPathTypeColumnTable]: undefined,
128
+ [EPathType.EPathTypeCdcStream]: undefined,
129
+ };
130
+
131
+ return (props.type && pathTypeToComponent[props.type]?.()) || (
132
+ <SchemaInfoViewer fullPath={currentItem.Path} data={schemaData} />
133
+ );
134
+ }
135
+
115
136
  return loading && !wasLoaded ? (
116
137
  renderLoader()
117
138
  ) : (
118
139
  <div className={props.className}>
119
- <SchemaInfoViewer fullPath={currentItem.Path} data={schemaData} />
140
+ {renderContent()}
120
141
  </div>
121
142
  );
122
143
  }
@@ -25,9 +25,11 @@ const renderName = (tenant) => {
25
25
  if (tenant) {
26
26
  const {Name} = tenant;
27
27
  return (
28
- <div className={b('tenant-name')}>
28
+ <div className={b('tenant-name-wrapper')}>
29
29
  <EntityStatus status={tenant.State} />
30
- <span>{Name}</span>
30
+ <span className={b('tenant-name-trim')}>
31
+ <span className={b('tenant-name')}>{Name}</span>
32
+ </span>
31
33
  </div>
32
34
  );
33
35
  }
@@ -139,17 +141,17 @@ class TenantOverview extends React.Component {
139
141
  this.props.tenant.Name,
140
142
  this.props.tenant.Type,
141
143
  )}
142
- <div className={b('system-tablets')}>
143
- {SystemTablets &&
144
- SystemTablets.map((tablet, tabletIndex) => (
145
- <Tablet
146
- onMouseEnter={showTooltip}
147
- onMouseLeave={hideTooltip}
148
- key={tabletIndex}
149
- tablet={tablet}
150
- />
151
- ))}
152
- </div>
144
+ </div>
145
+ <div className={b('system-tablets')}>
146
+ {SystemTablets &&
147
+ SystemTablets.map((tablet, tabletIndex) => (
148
+ <Tablet
149
+ onMouseEnter={showTooltip}
150
+ onMouseLeave={hideTooltip}
151
+ key={tabletIndex}
152
+ tablet={tablet}
153
+ />
154
+ ))}
153
155
  </div>
154
156
  <div className={b('common-info')}>
155
157
  {PoolStats ? (
@@ -1,30 +1,46 @@
1
+ @use '../DetailedOverview/DetailedOverview.scss' as detailedOverview;
2
+
1
3
  .tenant-overview {
2
4
  padding-bottom: 20px;
3
5
  &__loader {
4
6
  display: flex;
5
7
  justify-content: center;
6
8
  }
7
- &__tenant-name {
9
+ &__tenant-name-wrapper {
8
10
  display: flex;
11
+ overflow: hidden;
9
12
  align-items: center;
10
13
 
11
14
  & .yc-link {
12
15
  display: flex;
13
16
  }
14
17
  }
18
+ &__tenant-name-trim {
19
+ overflow: hidden;
20
+
21
+ white-space: nowrap;
22
+ text-overflow: ellipsis;
23
+ direction: rtl;
24
+ }
25
+
26
+ &__tenant-name {
27
+ unicode-bidi: plaintext;
28
+ }
15
29
 
16
30
  &__top {
17
31
  display: flex;
18
32
  align-items: center;
19
33
 
20
- margin-bottom: 20px;
34
+ margin-bottom: 10px;
35
+
36
+ line-height: 24px;
21
37
  }
22
38
 
23
39
  &__top-label {
24
- margin-bottom: 20px;
40
+ margin-bottom: detailedOverview.$section-title-margin;
25
41
 
26
42
  font-weight: 600;
27
- line-height: 24px;
43
+ line-height: detailedOverview.$section-title-line-height;
28
44
  gap: 10px;
29
45
  }
30
46
 
@@ -42,7 +58,7 @@
42
58
  flex-wrap: wrap;
43
59
  align-items: center;
44
60
 
45
- margin-left: 15px;
61
+ margin-bottom: 35px;
46
62
  }
47
63
 
48
64
  &__collapse-title {
@@ -76,7 +92,7 @@
76
92
  margin-bottom: 20px;
77
93
 
78
94
  font-size: var(--yc-text-body-2-font-size);
79
- font-weight: 500;
95
+ font-weight: 600;
80
96
  line-height: var(--yc-text-body-2-line-height);
81
97
  }
82
98
  }