ydb-embedded-ui 4.4.2 → 4.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/components/ContentWithPopup/ContentWithPopup.tsx +51 -0
  3. package/dist/components/CriticalActionDialog/CriticalActionDialog.tsx +3 -0
  4. package/dist/components/ExternalLinkWithIcon/ExternalLinkWithIcon.scss +7 -0
  5. package/dist/components/ExternalLinkWithIcon/ExternalLinkWithIcon.tsx +24 -0
  6. package/dist/components/NodeHostWrapper/NodeHostWrapper.tsx +2 -2
  7. package/dist/components/PoolBar/PoolBar.scss +6 -1
  8. package/dist/components/PoolBar/PoolBar.tsx +39 -0
  9. package/dist/components/PoolsGraph/PoolsGraph.scss +1 -1
  10. package/dist/components/PoolsGraph/PoolsGraph.tsx +23 -0
  11. package/dist/components/Tablet/Tablet.scss +4 -1
  12. package/dist/components/Tablet/Tablet.tsx +11 -35
  13. package/dist/components/{Tooltips/NodeEndpointsTooltip/NodeEndpointsTooltip.scss → TooltipsContent/NodeEndpointsTooltipContent/NodeEndpointsTooltipContent.scss} +1 -1
  14. package/dist/components/{Tooltips/NodeEndpointsTooltip/NodeEndpointsTooltip.tsx → TooltipsContent/NodeEndpointsTooltipContent/NodeEndpointsTooltipContent.tsx} +3 -3
  15. package/dist/components/TooltipsContent/PoolTooltipContent/PoolTooltipContent.tsx +24 -0
  16. package/dist/components/TooltipsContent/TabletTooltipContent/TabletTooltipContent.tsx +34 -0
  17. package/dist/components/TooltipsContent/index.ts +3 -0
  18. package/dist/containers/Cluster/Cluster.tsx +14 -10
  19. package/dist/containers/{ClusterInfo → Cluster/ClusterInfo}/ClusterInfo.scss +8 -40
  20. package/dist/containers/Cluster/ClusterInfo/ClusterInfo.tsx +223 -0
  21. package/dist/containers/{ClusterInfo → Cluster/ClusterInfo}/utils.ts +1 -1
  22. package/dist/containers/Cluster/VersionsBar/VersionsBar.scss +27 -0
  23. package/dist/containers/Cluster/VersionsBar/VersionsBar.tsx +33 -0
  24. package/dist/containers/Header/Header.tsx +3 -6
  25. package/dist/containers/Nodes/Nodes.tsx +0 -11
  26. package/dist/containers/Nodes/getNodesColumns.tsx +3 -20
  27. package/dist/containers/Tablet/Tablet.scss +4 -0
  28. package/dist/containers/Tablet/Tablet.tsx +2 -1
  29. package/dist/containers/Tablet/TabletControls/TabletControls.tsx +19 -27
  30. package/dist/containers/Tablets/Tablets.tsx +1 -17
  31. package/dist/containers/TabletsFilters/TabletsFilters.js +2 -14
  32. package/dist/containers/Tenant/Diagnostics/Consumers/columns/columns.tsx +2 -2
  33. package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +37 -38
  34. package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +15 -28
  35. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +4 -14
  36. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +5 -3
  37. package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx +2 -3
  38. package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +3 -3
  39. package/dist/containers/Tenant/Tenant.tsx +14 -15
  40. package/dist/containers/Tenant/TenantPages.tsx +3 -6
  41. package/dist/containers/Tenant/utils/schemaActions.ts +4 -4
  42. package/dist/containers/Tenants/Tenants.js +3 -17
  43. package/dist/containers/Versions/NodesTable/NodesTable.tsx +4 -34
  44. package/dist/routes.ts +1 -1
  45. package/dist/store/reducers/index.ts +1 -1
  46. package/dist/store/reducers/tenant/constants.ts +19 -0
  47. package/dist/store/reducers/{tenant.js → tenant/tenant.ts} +27 -36
  48. package/dist/store/reducers/tenant/types.ts +25 -0
  49. package/dist/types/additionalProps.ts +11 -0
  50. package/dist/utils/index.js +2 -1
  51. package/dist/utils/tooltip.js +8 -80
  52. package/package.json +2 -1
  53. package/dist/components/Breadcrumbs/Breadcrumbs.js +0 -25
  54. package/dist/components/Breadcrumbs/Breadcrumbs.scss +0 -5
  55. package/dist/components/Collapse/Collapse.js +0 -84
  56. package/dist/components/Collapse/Collapse.scss +0 -70
  57. package/dist/components/PoolBar/PoolBar.js +0 -52
  58. package/dist/components/PoolsGraph/PoolsGraph.js +0 -33
  59. package/dist/containers/ClusterInfo/ClusterInfo.tsx +0 -207
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.5.1](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.5.0...v4.5.1) (2023-06-02)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **Tablet:** fetch data on action finish ([#405](https://github.com/ydb-platform/ydb-embedded-ui/issues/405)) ([f1d71c5](https://github.com/ydb-platform/ydb-embedded-ui/commit/f1d71c5af330a0a13246f8d87433e6bba1d3509a))
9
+
10
+ ## [4.5.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.4.2...v4.5.0) (2023-06-01)
11
+
12
+
13
+ ### Features
14
+
15
+ * **ClusterInfo:** update versions bar, rework DC and Tablets fields ([#407](https://github.com/ydb-platform/ydb-embedded-ui/issues/407)) ([4824f0d](https://github.com/ydb-platform/ydb-embedded-ui/commit/4824f0d2be9d7bec3641302c88b39a3a87f37c18))
16
+
3
17
  ## [4.4.2](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.4.1...v4.4.2) (2023-05-29)
4
18
 
5
19
 
@@ -0,0 +1,51 @@
1
+ import {ReactNode, useRef, useState} from 'react';
2
+
3
+ import {Popup, PopupProps} from '@gravity-ui/uikit';
4
+
5
+ interface ContentWithPopupProps extends PopupProps {
6
+ content: ReactNode;
7
+ className?: string;
8
+ children?: ReactNode;
9
+ }
10
+
11
+ export const ContentWithPopup = ({
12
+ children,
13
+ content,
14
+ className,
15
+ hasArrow = true,
16
+ placement = ['top', 'bottom'],
17
+ ...props
18
+ }: ContentWithPopupProps) => {
19
+ const [isPopupVisible, setIsPopupVisible] = useState(false);
20
+ const anchor = useRef(null);
21
+
22
+ const showPopup = () => {
23
+ setIsPopupVisible(true);
24
+ };
25
+
26
+ const hidePopup = () => {
27
+ setIsPopupVisible(false);
28
+ };
29
+
30
+ return (
31
+ <>
32
+ <Popup
33
+ anchorRef={anchor}
34
+ open={isPopupVisible}
35
+ placement={placement}
36
+ hasArrow={hasArrow}
37
+ {...props}
38
+ >
39
+ {content}
40
+ </Popup>
41
+ <span
42
+ className={className}
43
+ ref={anchor}
44
+ onMouseEnter={showPopup}
45
+ onMouseLeave={hidePopup}
46
+ >
47
+ {children}
48
+ </span>
49
+ </>
50
+ );
51
+ };
@@ -13,6 +13,7 @@ interface CriticalActionDialogProps {
13
13
  text: string;
14
14
  onClose: VoidFunction;
15
15
  onConfirm: () => Promise<unknown>;
16
+ onConfirmActionFinish: VoidFunction;
16
17
  }
17
18
 
18
19
  export const CriticalActionDialog = ({
@@ -20,6 +21,7 @@ export const CriticalActionDialog = ({
20
21
  text,
21
22
  onClose,
22
23
  onConfirm,
24
+ onConfirmActionFinish,
23
25
  }: CriticalActionDialogProps) => {
24
26
  const [isLoading, setIsLoading] = useState(false);
25
27
 
@@ -28,6 +30,7 @@ export const CriticalActionDialog = ({
28
30
  setIsLoading(true);
29
31
 
30
32
  return onConfirm().then(() => {
33
+ onConfirmActionFinish();
31
34
  setIsLoading(false);
32
35
  onClose();
33
36
  });
@@ -0,0 +1,7 @@
1
+ .ydb-external-link-with-icon {
2
+ display: flex;
3
+ flex-wrap: nowrap;
4
+ align-items: center;
5
+
6
+ white-space: nowrap;
7
+ }
@@ -0,0 +1,24 @@
1
+ import block from 'bem-cn-lite';
2
+
3
+ import {Link} from '@gravity-ui/uikit';
4
+
5
+ import {IconWrapper} from '../Icon/Icon';
6
+
7
+ import './ExternalLinkWithIcon.scss';
8
+
9
+ const b = block('ydb-external-link-with-icon');
10
+
11
+ interface ExternalLinkWithIconProps {
12
+ title: string;
13
+ url: string;
14
+ }
15
+
16
+ export const ExternalLinkWithIcon = ({title, url}: ExternalLinkWithIconProps) => {
17
+ return (
18
+ <Link href={url} target="_blank" className={b()}>
19
+ {title}
20
+ {'\u00a0'}
21
+ <IconWrapper name="external" viewBox={'0 0 16 16'} width={16} height={16} />
22
+ </Link>
23
+ );
24
+ };
@@ -7,7 +7,7 @@ import {getDefaultNodePath} from '../../containers/Node/NodePages';
7
7
  import {isUnavailableNode, NodeAddress} from '../../utils/nodes';
8
8
 
9
9
  import EntityStatus from '../EntityStatus/EntityStatus';
10
- import {NodeEndpointsTooltip} from '../Tooltips/NodeEndpointsTooltip/NodeEndpointsTooltip';
10
+ import {NodeEndpointsTooltipContent} from '../TooltipsContent';
11
11
  import {IconWrapper} from '../Icon';
12
12
 
13
13
  import './NodeHostWrapper.scss';
@@ -31,7 +31,7 @@ export const NodeHostWrapper = ({node, getNodeRef}: NodeHostWrapperProps) => {
31
31
  <div className={b()}>
32
32
  <Popover
33
33
  disabled={!isNodeAvailable}
34
- content={<NodeEndpointsTooltip data={node} />}
34
+ content={<NodeEndpointsTooltipContent data={node} />}
35
35
  placement={['top', 'bottom']}
36
36
  behavior={PopoverBehavior.Immediate}
37
37
  >
@@ -1,4 +1,4 @@
1
- .pool-bar {
1
+ .ydb-pool-bar {
2
2
  position: relative;
3
3
 
4
4
  width: 6px;
@@ -10,6 +10,11 @@
10
10
  border: 1px solid;
11
11
  border-radius: 1px;
12
12
 
13
+ &__popup-content {
14
+ width: 170px;
15
+ padding: 10px;
16
+ }
17
+
13
18
  &:last-child {
14
19
  margin-right: 0;
15
20
  }
@@ -0,0 +1,39 @@
1
+ import block from 'bem-cn-lite';
2
+
3
+ import type {TPoolStats} from '../../types/api/nodes';
4
+
5
+ import {ContentWithPopup} from '../ContentWithPopup/ContentWithPopup';
6
+ import {PoolTooltipContent} from '../TooltipsContent';
7
+
8
+ import './PoolBar.scss';
9
+
10
+ const b = block('ydb-pool-bar');
11
+
12
+ const getBarType = (usage: number) => {
13
+ if (usage >= 75) {
14
+ return 'danger';
15
+ } else if (usage >= 50 && usage < 75) {
16
+ return 'warning';
17
+ } else {
18
+ return 'normal';
19
+ }
20
+ };
21
+
22
+ interface PoolBarProps {
23
+ data?: TPoolStats;
24
+ }
25
+
26
+ export const PoolBar = ({data = {}}: PoolBarProps) => {
27
+ const {Usage: usage = 0} = data;
28
+ const usagePercents = Math.min(usage * 100, 100);
29
+ const type = getBarType(usagePercents);
30
+
31
+ return (
32
+ <ContentWithPopup
33
+ className={b({type})}
34
+ content={<PoolTooltipContent data={data} className={b('popup-content')} />}
35
+ >
36
+ <div style={{height: `${usagePercents}%`}} className={b('value', {type})} />
37
+ </ContentWithPopup>
38
+ );
39
+ };
@@ -1,3 +1,3 @@
1
- .pools-graph {
1
+ .ydb-pools-graph {
2
2
  display: flex;
3
3
  }
@@ -0,0 +1,23 @@
1
+ import block from 'bem-cn-lite';
2
+
3
+ import type {TPoolStats} from '../../types/api/nodes';
4
+
5
+ import {PoolBar} from '../PoolBar/PoolBar';
6
+
7
+ import './PoolsGraph.scss';
8
+
9
+ const b = block('ydb-pools-graph');
10
+
11
+ interface PoolsGraphProps {
12
+ pools?: TPoolStats[];
13
+ }
14
+
15
+ export const PoolsGraph = ({pools = []}: PoolsGraphProps) => {
16
+ return (
17
+ <div className={b()}>
18
+ {pools.map((item, index) => (
19
+ <PoolBar key={index} data={item} />
20
+ ))}
21
+ </div>
22
+ );
23
+ };
@@ -1,7 +1,6 @@
1
1
  .tablet {
2
2
  display: flex;
3
3
  justify-content: center;
4
- align-items: center;
5
4
 
6
5
  width: 18px;
7
6
  height: 18px;
@@ -22,6 +21,10 @@
22
21
  }
23
22
  }
24
23
 
24
+ &__popup-content {
25
+ padding: 10px;
26
+ }
27
+
25
28
  &__type {
26
29
  line-height: 17px;
27
30
 
@@ -1,12 +1,12 @@
1
- import {useRef} from 'react';
2
1
  import cn from 'bem-cn-lite';
3
2
 
4
3
  import type {TTabletStateInfo} from '../../types/api/tablet';
5
- import type {ShowTooltipFunction} from '../../types/store/tooltip';
6
4
  import {getTabletLabel} from '../../utils/constants';
7
5
  import routes, {createHref} from '../../routes';
8
6
 
7
+ import {ContentWithPopup} from '../ContentWithPopup/ContentWithPopup';
9
8
  import {InternalLink} from '../InternalLink';
9
+ import {TabletTooltipContent} from '../TooltipsContent';
10
10
 
11
11
  import './Tablet.scss';
12
12
 
@@ -14,46 +14,22 @@ const b = cn('tablet');
14
14
 
15
15
  interface TabletProps {
16
16
  tablet?: TTabletStateInfo;
17
- onMouseEnter?: (...args: Parameters<ShowTooltipFunction>) => void;
18
- onMouseLeave?: VoidFunction;
19
17
  }
20
18
 
21
- export const Tablet = ({
22
- tablet = {},
23
- onMouseEnter = () => {},
24
- onMouseLeave = () => {},
25
- }: TabletProps) => {
26
- const ref = useRef(null);
27
-
28
- const _onTabletMouseEnter = () => {
29
- onMouseEnter(ref.current, tablet, 'tablet');
30
- };
31
-
32
- const _onTabletClick = () => {
33
- const {TabletId: id} = tablet;
34
-
35
- if (id) {
36
- onMouseLeave();
37
- }
38
- };
39
-
19
+ export const Tablet = ({tablet = {}}: TabletProps) => {
40
20
  const {TabletId: id} = tablet;
41
21
  const status = tablet.Overall?.toLowerCase();
42
22
 
43
23
  return (
44
- <InternalLink
45
- onClick={_onTabletClick}
46
- to={id && createHref(routes.tablet, {id})}
24
+ <ContentWithPopup
47
25
  className={b('wrapper')}
26
+ content={<TabletTooltipContent data={tablet} className={b('popup-content')} />}
48
27
  >
49
- <div
50
- ref={ref}
51
- className={b({status})}
52
- onMouseEnter={_onTabletMouseEnter}
53
- onMouseLeave={onMouseLeave}
54
- >
55
- <div className={b('type')}>{[getTabletLabel(tablet.Type)]}</div>
56
- </div>
57
- </InternalLink>
28
+ <InternalLink to={id && createHref(routes.tablet, {id})}>
29
+ <div className={b({status})}>
30
+ <div className={b('type')}>{[getTabletLabel(tablet.Type)]}</div>
31
+ </div>
32
+ </InternalLink>
33
+ </ContentWithPopup>
58
34
  );
59
35
  };
@@ -1,4 +1,4 @@
1
- .ydb-node-endpoints-tooltip {
1
+ .ydb-node-endpoints-tooltip-content {
2
2
  .info-viewer__value {
3
3
  min-width: 70px;
4
4
  }
@@ -4,15 +4,15 @@ import type {TSystemStateInfo} from '../../../types/api/nodes';
4
4
 
5
5
  import {InfoViewer, InfoViewerItem} from '../../InfoViewer';
6
6
 
7
- import './NodeEndpointsTooltip.scss';
7
+ import './NodeEndpointsTooltipContent.scss';
8
8
 
9
- const b = block('ydb-node-endpoints-tooltip');
9
+ const b = block('ydb-node-endpoints-tooltip-content');
10
10
 
11
11
  interface NodeEdpointsTooltipProps {
12
12
  data?: TSystemStateInfo;
13
13
  }
14
14
 
15
- export const NodeEndpointsTooltip = ({data}: NodeEdpointsTooltipProps) => {
15
+ export const NodeEndpointsTooltipContent = ({data}: NodeEdpointsTooltipProps) => {
16
16
  const info: InfoViewerItem[] = [];
17
17
 
18
18
  if (data?.Rack) {
@@ -0,0 +1,24 @@
1
+ import type {TPoolStats} from '../../../types/api/nodes';
2
+
3
+ import {InfoViewer, createInfoFormatter, formatObject} from '../../InfoViewer';
4
+
5
+ const formatPool = createInfoFormatter<TPoolStats>({
6
+ values: {
7
+ Usage: (value) => value && `${(Number(value) * 100).toFixed(2)} %`,
8
+ },
9
+ labels: {
10
+ Name: 'Pool',
11
+ },
12
+ defaultValueFormatter: (value) => value && String(value),
13
+ });
14
+
15
+ interface PoolTooltipContentProps {
16
+ data?: TPoolStats;
17
+ className?: string;
18
+ }
19
+
20
+ export const PoolTooltipContent = ({data = {}, className}: PoolTooltipContentProps) => {
21
+ const info = formatObject(formatPool, data);
22
+
23
+ return <InfoViewer className={className} info={info} dots={false} size={'s'} />;
24
+ };
@@ -0,0 +1,34 @@
1
+ import type {TTabletStateInfo} from '../../../types/api/tablet';
2
+
3
+ import {calcUptime} from '../../../utils';
4
+ import {InfoViewer, createInfoFormatter, formatObject} from '../../InfoViewer';
5
+
6
+ const formatTablet = createInfoFormatter<TTabletStateInfo>({
7
+ values: {
8
+ ChangeTime: (value) => calcUptime(value),
9
+ },
10
+ labels: {
11
+ TabletId: 'Tablet',
12
+ },
13
+ defaultValueFormatter: (value) => value && String(value),
14
+ });
15
+
16
+ interface TabletTooltipContentProps {
17
+ data?: TTabletStateInfo;
18
+ className?: string;
19
+ }
20
+
21
+ export const TabletTooltipContent = ({data = {}, className}: TabletTooltipContentProps) => {
22
+ const {TabletId, NodeId, State, Type, ChangeTime, Generation} = data;
23
+
24
+ const info = formatObject(formatTablet, {
25
+ TabletId,
26
+ NodeId,
27
+ State,
28
+ Type,
29
+ ChangeTime,
30
+ Generation,
31
+ });
32
+
33
+ return <InfoViewer className={className} info={info} dots={false} size={'s'} />;
34
+ };
@@ -0,0 +1,3 @@
1
+ export * from './NodeEndpointsTooltipContent/NodeEndpointsTooltipContent';
2
+ export * from './TabletTooltipContent/TabletTooltipContent';
3
+ export * from './PoolTooltipContent/PoolTooltipContent';
@@ -1,10 +1,10 @@
1
1
  import {useRouteMatch} from 'react-router';
2
2
  import cn from 'bem-cn-lite';
3
3
 
4
- import type {AdditionalVersionsProps} from '../../types/additionalProps';
4
+ import type {AdditionalClusterProps, AdditionalVersionsProps} from '../../types/additionalProps';
5
5
  import routes, {CLUSTER_PAGES} from '../../routes';
6
6
 
7
- import {ClusterInfo} from '../ClusterInfo/ClusterInfo';
7
+ import {ClusterInfo} from './ClusterInfo/ClusterInfo';
8
8
  import Tenants from '../Tenants/Tenants';
9
9
  import {Nodes} from '../Nodes/Nodes';
10
10
  import Storage from '../Storage/Storage';
@@ -14,32 +14,36 @@ import './Cluster.scss';
14
14
  const b = cn('cluster');
15
15
 
16
16
  interface ClusterProps {
17
- additionalClusterInfo?: any;
18
17
  additionalTenantsInfo?: any;
19
18
  additionalNodesInfo?: any;
19
+ additionalClusterProps?: AdditionalClusterProps;
20
20
  additionalVersionsProps?: AdditionalVersionsProps;
21
21
  }
22
22
 
23
- function Cluster(props: ClusterProps) {
23
+ function Cluster({
24
+ additionalTenantsInfo,
25
+ additionalNodesInfo,
26
+ additionalClusterProps,
27
+ additionalVersionsProps,
28
+ }: ClusterProps) {
24
29
  const match = useRouteMatch<{activeTab?: string}>(routes.cluster);
25
30
  const activeTab = match?.params?.activeTab ?? CLUSTER_PAGES.tenants.id;
26
31
  const renderRoutes = () => {
27
32
  switch (activeTab) {
28
33
  case CLUSTER_PAGES.tenants.id: {
29
- return <Tenants {...props} />;
34
+ return <Tenants additionalTenantsInfo={additionalTenantsInfo} />;
30
35
  }
31
36
  case CLUSTER_PAGES.nodes.id: {
32
- return <Nodes additionalNodesInfo={props.additionalNodesInfo} />;
37
+ return <Nodes additionalNodesInfo={additionalNodesInfo} />;
33
38
  }
34
39
  case CLUSTER_PAGES.storage.id: {
35
- //@ts-ignore
36
- return <Storage {...props} />;
40
+ return <Storage additionalNodesInfo={additionalNodesInfo} />;
37
41
  }
38
42
  case CLUSTER_PAGES.cluster.id: {
39
43
  return (
40
44
  <ClusterInfo
41
- additionalClusterInfo={props.additionalClusterInfo}
42
- additionalVersionsProps={props.additionalVersionsProps}
45
+ additionalClusterProps={additionalClusterProps}
46
+ additionalVersionsProps={additionalVersionsProps}
43
47
  />
44
48
  );
45
49
  }
@@ -1,4 +1,4 @@
1
- @import '../../styles/mixins';
1
+ @import '../../../styles/mixins';
2
2
 
3
3
  .cluster-info {
4
4
  $_: &;
@@ -20,14 +20,7 @@
20
20
  background: var(--yc-color-base-background);
21
21
  }
22
22
 
23
- &__loader {
24
- display: flex;
25
- justify-content: center;
26
-
27
- margin-top: 16px;
28
- }
29
-
30
- &__common {
23
+ &__title {
31
24
  display: flex;
32
25
  align-items: center;
33
26
 
@@ -35,16 +28,6 @@
35
28
  margin-bottom: 20px;
36
29
  }
37
30
 
38
- &__title {
39
- margin-bottom: 15px;
40
-
41
- font-weight: 600;
42
- }
43
-
44
- &__url {
45
- margin-right: 14px;
46
- }
47
-
48
31
  &__metric-field {
49
32
  margin-top: -8px;
50
33
  }
@@ -54,8 +37,6 @@
54
37
  flex-wrap: wrap;
55
38
  align-items: center;
56
39
 
57
- margin-left: 15px;
58
-
59
40
  & .tablet {
60
41
  margin-bottom: 2px;
61
42
  }
@@ -81,31 +62,18 @@
81
62
  margin-left: 15px;
82
63
  padding: 0 !important;
83
64
  }
84
- &__clipboard-button {
85
- display: flex;
86
- align-items: center;
87
65
 
88
- margin-left: 5px;
89
- }
90
- &__progress-label {
91
- margin: 0 10px 0 0;
66
+ &__links {
67
+ display: flex;
68
+ flex-flow: row wrap;
92
69
 
93
- font-weight: 200;
70
+ gap: 12px;
94
71
  }
95
72
 
96
- &__version-progress {
73
+ &__clipboard-button {
97
74
  display: flex;
98
75
  align-items: center;
99
76
 
100
- width: $progress_width;
101
- margin-top: 20px;
102
-
103
- & .yc-progress {
104
- width: $progress_width;
105
- }
106
- }
107
-
108
- & .yc-progress__stack {
109
- cursor: pointer;
77
+ margin-left: 5px;
110
78
  }
111
79
  }