Skip to content

Commit 6ec3d33

Browse files
authored
feat(AutoRefresh): use auto refresh control on other pages (#976)
1 parent 5794dcd commit 6ec3d33

File tree

22 files changed

+135
-100
lines changed

22 files changed

+135
-100
lines changed

src/containers/Tenant/Diagnostics/Autorefresh/AutorefreshControl.scss renamed to src/components/AutoRefreshControl/AutoRefreshControl.scss

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.autorefresh-control {
1+
.auto-refresh-control {
22
display: flex;
33
align-items: center;
44
gap: var(--g-spacing-1);

src/containers/Tenant/Diagnostics/Autorefresh/AutorefreshControl.tsx renamed to src/components/AutoRefreshControl/AutoRefreshControl.tsx

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
import {ArrowsRotateLeft} from '@gravity-ui/icons';
22
import {Button, Select} from '@gravity-ui/uikit';
33

4-
import {api} from '../../../../store/reducers/api';
5-
import {cn} from '../../../../utils/cn';
6-
import {useAutoRefreshInterval, useTypedDispatch} from '../../../../utils/hooks';
4+
import {api} from '../../store/reducers/api';
5+
import {cn} from '../../utils/cn';
6+
import {useAutoRefreshInterval, useTypedDispatch} from '../../utils/hooks';
77

88
import i18n from './i18n';
99

10-
import './AutorefreshControl.scss';
10+
import './AutoRefreshControl.scss';
1111

12-
const b = cn('autorefresh-control');
12+
const b = cn('auto-refresh-control');
1313

14-
interface AutorefreshControlProps {
14+
interface AutoRefreshControlProps {
1515
className?: string;
1616
}
1717

18-
export function AutorefreshControl({className}: AutorefreshControlProps) {
18+
export function AutoRefreshControl({className}: AutoRefreshControlProps) {
1919
const dispatch = useTypedDispatch();
2020
const [autoRefreshInterval, setAutoRefreshInterval] = useAutoRefreshInterval();
2121
return (

src/containers/Tenant/Diagnostics/Autorefresh/i18n/index.ts renamed to src/components/AutoRefreshControl/i18n/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {registerKeysets} from '../../../../../utils/i18n';
1+
import {registerKeysets} from '../../../utils/i18n';
22

33
import en from './en.json';
44

src/containers/Cluster/Cluster.scss

+8
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,15 @@
2828
}
2929

3030
&__tabs {
31+
--g-tabs-border-width: 0;
32+
3133
position: sticky;
3234
left: 0;
35+
36+
display: flex;
37+
justify-content: space-between;
38+
align-items: center;
39+
40+
box-shadow: inset 0 -1px 0 0 var(--g-color-line-generic);
3341
}
3442
}

src/containers/Cluster/Cluster.tsx

+13-10
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import React from 'react';
22

33
import {Skeleton, Tabs} from '@gravity-ui/uikit';
4-
import qs from 'qs';
54
import {Helmet} from 'react-helmet-async';
6-
import {Redirect, Route, Switch, useLocation, useRouteMatch} from 'react-router';
5+
import {Redirect, Route, Switch, useRouteMatch} from 'react-router-dom';
6+
import {StringParam, useQueryParams} from 'use-query-params';
77

8+
import {AutoRefreshControl} from '../../components/AutoRefreshControl/AutoRefreshControl';
89
import {EntityStatus} from '../../components/EntityStatus/EntityStatus';
910
import {InternalLink} from '../../components/InternalLink';
1011
import routes, {getLocationObjectFromHref} from '../../routes';
@@ -18,8 +19,8 @@ import type {
1819
AdditionalVersionsProps,
1920
} from '../../types/additionalProps';
2021
import {cn} from '../../utils/cn';
21-
import {CLUSTER_DEFAULT_TITLE, DEFAULT_POLLING_INTERVAL} from '../../utils/constants';
22-
import {useTypedDispatch, useTypedSelector} from '../../utils/hooks';
22+
import {CLUSTER_DEFAULT_TITLE} from '../../utils/constants';
23+
import {useAutoRefreshInterval, useTypedDispatch, useTypedSelector} from '../../utils/hooks';
2324
import {parseNodesToVersionsValues, parseVersionsToVersionToColorMap} from '../../utils/versions';
2425
import {NodesWrapper} from '../Nodes/NodesWrapper';
2526
import {StorageWrapper} from '../Storage/StorageWrapper';
@@ -53,18 +54,19 @@ export function Cluster({
5354

5455
const activeTabId = useClusterTab();
5556

56-
const location = useLocation();
57-
const queryParams = qs.parse(location.search, {
58-
ignoreQueryPrefix: true,
57+
const [{clusterName, backend}] = useQueryParams({
58+
clusterName: StringParam,
59+
backend: StringParam,
5960
});
60-
const {clusterName, backend} = queryParams;
61+
62+
const [autoRefreshInterval] = useAutoRefreshInterval();
6163

6264
const {
6365
data: {clusterData: cluster = {}, groupsStats} = {},
6466
isLoading: isClusterLoading,
6567
error,
66-
} = clusterApi.useGetClusterInfoQuery(clusterName ? String(clusterName) : undefined, {
67-
pollingInterval: DEFAULT_POLLING_INTERVAL,
68+
} = clusterApi.useGetClusterInfoQuery(clusterName ?? undefined, {
69+
pollingInterval: autoRefreshInterval,
6870
});
6971

7072
const clusterError = error && typeof error === 'object' ? error : undefined;
@@ -142,6 +144,7 @@ export function Cluster({
142144
);
143145
}}
144146
/>
147+
<AutoRefreshControl />
145148
</div>
146149

147150
<div>

src/containers/Clusters/Clusters.tsx

+23-21
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import DataTable from '@gravity-ui/react-data-table';
44
import {Select, TableColumnSetup} from '@gravity-ui/uikit';
55
import {Helmet} from 'react-helmet-async';
66

7+
import {AutoRefreshControl} from '../../components/AutoRefreshControl/AutoRefreshControl';
78
import {ResponseError} from '../../components/Errors/ResponseError';
89
import {Loader} from '../../components/Loader';
910
import {ResizeableDataTable} from '../../components/ResizeableDataTable/ResizeableDataTable';
@@ -17,8 +18,8 @@ import {
1718
selectStatusFilter,
1819
selectVersionFilter,
1920
} from '../../store/reducers/clusters/selectors';
20-
import {DEFAULT_POLLING_INTERVAL, DEFAULT_TABLE_SETTINGS} from '../../utils/constants';
21-
import {useTypedDispatch, useTypedSelector} from '../../utils/hooks';
21+
import {DEFAULT_TABLE_SETTINGS} from '../../utils/constants';
22+
import {useAutoRefreshInterval, useTypedDispatch, useTypedSelector} from '../../utils/hooks';
2223
import {getMinorVersion} from '../../utils/versions';
2324

2425
import {ClustersStatistics} from './ClustersStatistics';
@@ -31,8 +32,9 @@ import {useSelectedColumns} from './useSelectedColumns';
3132
import './Clusters.scss';
3233

3334
export function Clusters() {
35+
const [autoRefreshInterval] = useAutoRefreshInterval();
3436
const query = clustersApi.useGetClustersListQuery(undefined, {
35-
pollingInterval: DEFAULT_POLLING_INTERVAL,
37+
pollingInterval: autoRefreshInterval,
3638
});
3739

3840
const dispatch = useTypedDispatch();
@@ -107,10 +109,6 @@ export function Clusters() {
107109
.map((el) => ({value: el, content: el}));
108110
}, [clusters]);
109111

110-
if (query.isLoading) {
111-
return <Loader size="l" />;
112-
}
113-
114112
return (
115113
<div className={b()}>
116114
<Helmet>
@@ -175,23 +173,27 @@ export function Clusters() {
175173
sortable={false}
176174
/>
177175
</div>
176+
<AutoRefreshControl />
178177
</div>
179178
{query.isError ? <ResponseError error={query.error} className={b('error')} /> : null}
180-
<div className={b('table-wrapper')}>
181-
<div className={b('table-content')}>
182-
<ResizeableDataTable
183-
columnsWidthLSKey={CLUSTERS_COLUMNS_WIDTH_LS_KEY}
184-
wrapperClassName={b('table')}
185-
data={filteredClusters}
186-
columns={columnsToShow}
187-
settings={{...DEFAULT_TABLE_SETTINGS, dynamicRender: false}}
188-
initialSortOrder={{
189-
columnId: COLUMNS_NAMES.TITLE,
190-
order: DataTable.ASCENDING,
191-
}}
192-
/>
179+
{query.isLoading ? <Loader size="l" /> : null}
180+
{query.fulfilledTimeStamp ? (
181+
<div className={b('table-wrapper')}>
182+
<div className={b('table-content')}>
183+
<ResizeableDataTable
184+
columnsWidthLSKey={CLUSTERS_COLUMNS_WIDTH_LS_KEY}
185+
wrapperClassName={b('table')}
186+
data={filteredClusters}
187+
columns={columnsToShow}
188+
settings={{...DEFAULT_TABLE_SETTINGS, dynamicRender: false}}
189+
initialSortOrder={{
190+
columnId: COLUMNS_NAMES.TITLE,
191+
order: DataTable.ASCENDING,
192+
}}
193+
/>
194+
</div>
193195
</div>
194-
</div>
196+
) : null}
195197
</div>
196198
);
197199
}

src/containers/Header/Header.tsx

+5-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22

33
import {Breadcrumbs} from '@gravity-ui/uikit';
44
import {get} from 'lodash';
5-
import {useHistory, useLocation} from 'react-router';
5+
import {useLocation} from 'react-router-dom';
66

77
import {InternalLink} from '../../components/InternalLink';
88
import {LinkWithIcon} from '../../components/LinkWithIcon/LinkWithIcon';
@@ -33,14 +33,15 @@ interface HeaderProps {
3333
}
3434

3535
function Header({mainPage}: HeaderProps) {
36-
const history = useHistory();
3736
const location = useLocation();
3837
const queryParams = parseQuery(location);
3938

4039
const singleClusterMode = useTypedSelector((state) => state.singleClusterMode);
4140
const {page, pageBreadcrumbsOptions} = useTypedSelector((state) => state.header);
4241

43-
const clusterInfo = clusterApi.useGetClusterInfoQuery(queryParams.clusterName);
42+
const clusterInfo = clusterApi.useGetClusterInfoQuery(
43+
queryParams.clusterName ? String(queryParams.clusterName) : undefined,
44+
);
4445

4546
const clusterName = get(
4647
clusterInfo,
@@ -65,7 +66,7 @@ function Header({mainPage}: HeaderProps) {
6566
return breadcrumbs.map((item) => {
6667
return {...item, action: () => {}};
6768
});
68-
}, [clusterName, mainPage, history, queryParams, page, pageBreadcrumbsOptions]);
69+
}, [clusterName, mainPage, queryParams, page, pageBreadcrumbsOptions]);
6970

7071
const renderHeader = () => {
7172
return (

src/containers/Node/Node.scss

+8
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,15 @@
2323
}
2424

2525
&__tabs {
26+
--g-tabs-border-width: 0;
27+
28+
display: flex;
29+
justify-content: space-between;
30+
align-items: center;
31+
2632
padding: 0 20px;
33+
34+
box-shadow: inset 0 -1px 0 0 var(--g-color-line-generic);
2735
}
2836

2937
&__tab {

src/containers/Node/Node.tsx

+6-5
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import React from 'react';
22

33
import {Tabs} from '@gravity-ui/uikit';
44
import {Helmet} from 'react-helmet-async';
5-
import {useLocation, useRouteMatch} from 'react-router';
6-
import {Link} from 'react-router-dom';
5+
import {Link, useLocation, useRouteMatch} from 'react-router-dom';
76

7+
import {AutoRefreshControl} from '../../components/AutoRefreshControl/AutoRefreshControl';
88
import {BasicNodeViewer} from '../../components/BasicNodeViewer';
99
import {ResponseError} from '../../components/Errors/ResponseError';
1010
import {FullNodeViewer} from '../../components/FullNodeViewer/FullNodeViewer';
@@ -14,8 +14,7 @@ import {setHeaderBreadcrumbs} from '../../store/reducers/header/header';
1414
import {nodeApi} from '../../store/reducers/node/node';
1515
import type {AdditionalNodesProps} from '../../types/additionalProps';
1616
import {cn} from '../../utils/cn';
17-
import {DEFAULT_POLLING_INTERVAL} from '../../utils/constants';
18-
import {useTypedDispatch} from '../../utils/hooks';
17+
import {useAutoRefreshInterval, useTypedDispatch} from '../../utils/hooks';
1918
import {StorageWrapper} from '../Storage/StorageWrapper';
2019
import {Tablets} from '../Tablets';
2120

@@ -45,9 +44,10 @@ export function Node(props: NodeProps) {
4544
const {id: nodeId, activeTab} = match.params;
4645
const {tenantName: tenantNameFromQuery} = parseQuery(location);
4746

47+
const [autoRefreshInterval] = useAutoRefreshInterval();
4848
const {currentData, isFetching, error} = nodeApi.useGetNodeInfoQuery(
4949
{nodeId},
50-
{pollingInterval: DEFAULT_POLLING_INTERVAL},
50+
{pollingInterval: autoRefreshInterval},
5151
);
5252
const loading = isFetching && currentData === undefined;
5353
const node = currentData;
@@ -101,6 +101,7 @@ export function Node(props: NodeProps) {
101101
)}
102102
allowNotSelected={true}
103103
/>
104+
<AutoRefreshControl />
104105
</div>
105106
);
106107
};

src/containers/Node/NodeStructure/NodeStructure.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ import {ResponseError} from '../../../components/Errors/ResponseError';
99
import {nodeApi} from '../../../store/reducers/node/node';
1010
import {selectNodeStructure} from '../../../store/reducers/node/selectors';
1111
import {cn} from '../../../utils/cn';
12-
import {DEFAULT_POLLING_INTERVAL} from '../../../utils/constants';
13-
import {useTypedSelector} from '../../../utils/hooks';
12+
import {useAutoRefreshInterval, useTypedSelector} from '../../../utils/hooks';
1413

1514
import {PDisk} from './Pdisk';
1615

@@ -30,9 +29,10 @@ interface NodeStructureProps {
3029
function NodeStructure({nodeId, className}: NodeStructureProps) {
3130
const nodeStructure = useTypedSelector((state) => selectNodeStructure(state, nodeId));
3231

32+
const [autoRefreshInterval] = useAutoRefreshInterval();
3333
const {currentData, isFetching, error} = nodeApi.useGetNodeStructureQuery(
3434
{nodeId},
35-
{pollingInterval: DEFAULT_POLLING_INTERVAL},
35+
{pollingInterval: autoRefreshInterval},
3636
);
3737

3838
const loadingStructure = isFetching && currentData === undefined;

src/containers/Nodes/Nodes.tsx

+2-9
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,7 @@ import {
2424
import type {ProblemFilterValue} from '../../store/reducers/settings/types';
2525
import type {AdditionalNodesProps} from '../../types/additionalProps';
2626
import {cn} from '../../utils/cn';
27-
import {
28-
DEFAULT_POLLING_INTERVAL,
29-
DEFAULT_TABLE_SETTINGS,
30-
USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
31-
} from '../../utils/constants';
27+
import {DEFAULT_TABLE_SETTINGS, USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY} from '../../utils/constants';
3228
import {
3329
useAutoRefreshInterval,
3430
useSetting,
@@ -65,14 +61,11 @@ export const Nodes = ({path, additionalNodesProps = {}}: NodesProps) => {
6561

6662
const dispatch = useTypedDispatch();
6763

68-
const isClusterNodes = !path;
69-
7064
const problemFilter = useTypedSelector(selectProblemFilter);
71-
const [autorefresh] = useAutoRefreshInterval();
65+
const [autoRefreshInterval] = useAutoRefreshInterval();
7266

7367
const [useNodesEndpoint] = useSetting(USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY);
7468

75-
const autoRefreshInterval = isClusterNodes ? DEFAULT_POLLING_INTERVAL : autorefresh;
7669
// If there is no path, it's cluster Nodes tab
7770
const useGetComputeNodes = path && !useNodesEndpoint;
7871
const nodesQuery = nodesApi.useGetNodesQuery(useGetComputeNodes ? skipToken : {path}, {

src/containers/PDiskPage/PDiskPage.scss

+11-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
gap: 20px;
1010

1111
height: 100%;
12-
padding-top: 20px;
13-
padding-left: 20px;
12+
padding: 20px;
1413

1514
&__meta,
1615
&__title,
@@ -24,4 +23,14 @@
2423
&__groups-title {
2524
@include header-1-typography();
2625
}
26+
27+
&__controls {
28+
display: flex;
29+
align-items: center;
30+
gap: var(--g-spacing-2);
31+
}
32+
33+
&__auto-refresh-control {
34+
margin-inline-start: auto;
35+
}
2736
}

0 commit comments

Comments
 (0)