ydb-embedded-ui 4.4.2 → 4.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
  }