ydb-embedded-ui 2.4.4 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/components/InfoViewer/formatters/schema.ts +2 -1
  3. package/dist/components/InfoViewer/schemaInfo/CDCStreamInfo.tsx +3 -16
  4. package/dist/components/InfoViewer/schemaInfo/PersQueueGroupInfo.tsx +8 -13
  5. package/dist/components/InfoViewer/schemaInfo/TableIndexInfo.tsx +2 -12
  6. package/dist/components/InfoViewer/schemaOverview/CDCStreamOverview.tsx +3 -16
  7. package/dist/components/InfoViewer/schemaOverview/PersQueueGroupOverview.tsx +8 -13
  8. package/dist/components/InfoViewer/utils.ts +6 -6
  9. package/dist/components/Loader/Loader.scss +6 -3
  10. package/dist/components/Loader/Loader.tsx +7 -5
  11. package/dist/components/Loader/index.ts +1 -0
  12. package/dist/components/UptimeFIlter/UptimeFilter.tsx +21 -0
  13. package/dist/components/UptimeFIlter/index.ts +1 -0
  14. package/dist/containers/Node/Node.scss +1 -0
  15. package/dist/containers/Node/Node.tsx +3 -8
  16. package/dist/containers/Node/NodeStructure/NodeStructure.scss +0 -6
  17. package/dist/containers/Node/NodeStructure/NodeStructure.tsx +1 -1
  18. package/dist/containers/Nodes/Nodes.js +22 -10
  19. package/dist/{components → containers}/NodesViewer/NodesViewer.js +49 -62
  20. package/dist/{components → containers}/NodesViewer/NodesViewer.scss +0 -0
  21. package/dist/containers/Storage/Pdisk/Pdisk.scss +1 -1
  22. package/dist/containers/Storage/Storage.js +35 -10
  23. package/dist/containers/Storage/StorageNodes/StorageNodes.scss +2 -2
  24. package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +35 -17
  25. package/dist/containers/Storage/StorageNodes/i18n/en.json +6 -4
  26. package/dist/containers/Storage/StorageNodes/i18n/ru.json +6 -4
  27. package/dist/containers/Storage/UsageFilter/UsageFilter.scss +10 -5
  28. package/dist/containers/Tenant/Acl/Acl.js +1 -7
  29. package/dist/containers/Tenant/Diagnostics/Compute/Compute.js +1 -1
  30. package/dist/containers/Tenant/Diagnostics/Consumers/Consumers.tsx +34 -8
  31. package/dist/containers/Tenant/Diagnostics/Describe/Describe.scss +0 -8
  32. package/dist/containers/Tenant/Diagnostics/Describe/Describe.tsx +2 -6
  33. package/dist/containers/Tenant/Diagnostics/Diagnostics.scss +0 -7
  34. package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +5 -7
  35. package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.js +21 -13
  36. package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx +1 -5
  37. package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.js +4 -4
  38. package/dist/containers/Tenant/QueryEditor/SaveQuery/SaveQuery.js +1 -4
  39. package/dist/containers/Tenant/Schema/SchemaInfoViewer/SchemaInfoViewer.js +23 -28
  40. package/dist/containers/Tenant/TenantPages.tsx +1 -1
  41. package/dist/containers/Tenant/utils/schemaActions.ts +9 -20
  42. package/dist/store/reducers/clusterNodes.js +29 -10
  43. package/dist/store/reducers/nodes.js +24 -3
  44. package/dist/store/reducers/{schema.js → schema.ts} +22 -14
  45. package/dist/store/reducers/storage.js +46 -5
  46. package/dist/types/store/schema.ts +46 -0
  47. package/dist/utils/index.js +6 -2
  48. package/dist/utils/nodes.ts +9 -0
  49. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.5.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v2.4.4...v2.5.0) (2022-11-25)
4
+
5
+
6
+ ### Features
7
+
8
+ * **Nodes:** add uptime filter ([9bb4f66](https://github.com/ydb-platform/ydb-embedded-ui/commit/9bb4f664df8fadec5b5e612b2adb866c28415efa))
9
+ * **NodesViewer:** add uptime filter ([a802442](https://github.com/ydb-platform/ydb-embedded-ui/commit/a8024422a09ff95e55c399d26046f5103cab3f89))
10
+ * **Storage:** add nodes uptime filter ([d8cfea1](https://github.com/ydb-platform/ydb-embedded-ui/commit/d8cfea14369e8235d1f7ef86a9a3f34c05efdf5c))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **Consumers:** add autorefresh to useAutofetcher ([e0da2a1](https://github.com/ydb-platform/ydb-embedded-ui/commit/e0da2a11fcd18cb8ba808a07873a78cbf7191cdc))
16
+ * **Consumers:** add loader ([a59f472](https://github.com/ydb-platform/ydb-embedded-ui/commit/a59f472fd7c9347bcde8cc21d4001f999fc88110))
17
+ * **QueryExplain:** fix schema rerender on path change ([eb52978](https://github.com/ydb-platform/ydb-embedded-ui/commit/eb529787bf747bb2bf49bae65676011426341a23))
18
+ * **Storage:** add message on empty nodes with small uptime ([70959ab](https://github.com/ydb-platform/ydb-embedded-ui/commit/70959ab90bd0f81ebab7712b7d34c0ca80f4dd0b))
19
+ * **Storage:** fix uneven PDisks ([0269dba](https://github.com/ydb-platform/ydb-embedded-ui/commit/0269dbab0336ae5b8cbf43e1b52458e932527a66))
20
+ * **StorageNodes:** fix message display on not empty data ([bb5fffa](https://github.com/ydb-platform/ydb-embedded-ui/commit/bb5fffa786cde3f680375f8e11e3893c52c4f6da))
21
+ * **UsageFilter:** add min-width ([56b2701](https://github.com/ydb-platform/ydb-embedded-ui/commit/56b2701a17420e0322fac0223bce26e18a2f0e47))
22
+
3
23
  ## [2.4.4](https://github.com/ydb-platform/ydb-embedded-ui/compare/v2.4.3...v2.4.4) (2022-11-22)
4
24
 
5
25
 
@@ -32,7 +32,8 @@ export const formatPQGroupItem = createInfoFormatter<TPersQueueGroupDescription>
32
32
  values: {
33
33
  Partitions: (value) => formatNumber(value?.length || 0),
34
34
  PQTabletConfig: (value) => {
35
- const hours = Math.round(value.PartitionConfig.LifetimeSeconds / HOUR_IN_SECONDS * 100) / 100;
35
+ const hours =
36
+ Math.round((value.PartitionConfig.LifetimeSeconds / HOUR_IN_SECONDS) * 100) / 100;
36
37
  return `${formatNumber(hours)} hours`;
37
38
  },
38
39
  },
@@ -3,10 +3,7 @@ import type {TEvDescribeSchemeResult, TCdcStreamDescription} from '../../../type
3
3
  import {formatCdcStreamItem, formatCommonItem} from '../formatters';
4
4
  import {InfoViewer, InfoViewerItem} from '..';
5
5
 
6
- const DISPLAYED_FIELDS: Set<keyof TCdcStreamDescription> = new Set([
7
- 'Mode',
8
- 'Format',
9
- ]);
6
+ const DISPLAYED_FIELDS: Set<keyof TCdcStreamDescription> = new Set(['Mode', 'Format']);
10
7
 
11
8
  interface CDCStreamInfoProps {
12
9
  data?: TEvDescribeSchemeResult;
@@ -14,9 +11,7 @@ interface CDCStreamInfoProps {
14
11
 
15
12
  export const CDCStreamInfo = ({data}: CDCStreamInfoProps) => {
16
13
  if (!data) {
17
- return (
18
- <div className="error">No CDC Stream data</div>
19
- );
14
+ return <div className="error">No CDC Stream data</div>;
20
15
  }
21
16
 
22
17
  const TableIndex = data.PathDescription?.CdcStreamDescription;
@@ -32,13 +27,5 @@ export const CDCStreamInfo = ({data}: CDCStreamInfoProps) => {
32
27
  }
33
28
  }
34
29
 
35
- return (
36
- <>
37
- {info.length ? (
38
- <InfoViewer info={info}></InfoViewer>
39
- ) : (
40
- <>Empty</>
41
- )}
42
- </>
43
- );
30
+ return <>{info.length ? <InfoViewer info={info}></InfoViewer> : <>Empty</>}</>;
44
31
  };
@@ -9,9 +9,7 @@ interface PersQueueGrouopInfoProps {
9
9
 
10
10
  export const PersQueueGroupInfo = ({data}: PersQueueGrouopInfoProps) => {
11
11
  if (!data) {
12
- return (
13
- <div className="error">No PersQueueGroup data</div>
14
- );
12
+ return <div className="error">No PersQueueGroup data</div>;
15
13
  }
16
14
 
17
15
  const pqGroup = data.PathDescription?.PersQueueGroup;
@@ -20,15 +18,12 @@ export const PersQueueGroupInfo = ({data}: PersQueueGrouopInfoProps) => {
20
18
  info.push(formatCommonItem('PathType', data.PathDescription?.Self?.PathType));
21
19
 
22
20
  info.push(formatPQGroupItem('Partitions', pqGroup?.Partitions || []));
23
- info.push(formatPQGroupItem('PQTabletConfig', pqGroup?.PQTabletConfig || {PartitionConfig: {LifetimeSeconds: 0}}));
24
-
25
- return (
26
- <>
27
- {info.length ? (
28
- <InfoViewer info={info}></InfoViewer>
29
- ) : (
30
- <>Empty</>
31
- )}
32
- </>
21
+ info.push(
22
+ formatPQGroupItem(
23
+ 'PQTabletConfig',
24
+ pqGroup?.PQTabletConfig || {PartitionConfig: {LifetimeSeconds: 0}},
25
+ ),
33
26
  );
27
+
28
+ return <>{info.length ? <InfoViewer info={info}></InfoViewer> : <>Empty</>}</>;
34
29
  };
@@ -17,9 +17,7 @@ interface TableIndexInfoProps {
17
17
 
18
18
  export const TableIndexInfo = ({data}: TableIndexInfoProps) => {
19
19
  if (!data) {
20
- return (
21
- <div className="error">no index data</div>
22
- );
20
+ return <div className="error">no index data</div>;
23
21
  }
24
22
 
25
23
  const TableIndex = data.PathDescription?.TableIndex;
@@ -32,13 +30,5 @@ export const TableIndexInfo = ({data}: TableIndexInfoProps) => {
32
30
  }
33
31
  }
34
32
 
35
- return (
36
- <>
37
- {info.length ? (
38
- <InfoViewer info={info}></InfoViewer>
39
- ) : (
40
- <>Empty</>
41
- )}
42
- </>
43
- );
33
+ return <>{info.length ? <InfoViewer info={info}></InfoViewer> : <>Empty</>}</>;
44
34
  };
@@ -3,10 +3,7 @@ import type {TEvDescribeSchemeResult, TCdcStreamDescription} from '../../../type
3
3
  import {InfoViewer, InfoViewerItem} from '..';
4
4
  import {formatCdcStreamItem, formatCommonItem} from '../formatters';
5
5
 
6
- const DISPLAYED_FIELDS: Set<keyof TCdcStreamDescription> = new Set([
7
- 'Mode',
8
- 'Format',
9
- ]);
6
+ const DISPLAYED_FIELDS: Set<keyof TCdcStreamDescription> = new Set(['Mode', 'Format']);
10
7
 
11
8
  interface CDCStreamOverviewProps {
12
9
  data?: TEvDescribeSchemeResult;
@@ -14,9 +11,7 @@ interface CDCStreamOverviewProps {
14
11
 
15
12
  export const CDCStreamOverview = ({data}: CDCStreamOverviewProps) => {
16
13
  if (!data) {
17
- return (
18
- <div className="error">No CDC Stream data</div>
19
- );
14
+ return <div className="error">No CDC Stream data</div>;
20
15
  }
21
16
 
22
17
  const TableIndex = data.PathDescription?.CdcStreamDescription;
@@ -32,13 +27,5 @@ export const CDCStreamOverview = ({data}: CDCStreamOverviewProps) => {
32
27
  }
33
28
  }
34
29
 
35
- return (
36
- <>
37
- {info.length ? (
38
- <InfoViewer info={info}></InfoViewer>
39
- ) : (
40
- <>Empty</>
41
- )}
42
- </>
43
- );
30
+ return <>{info.length ? <InfoViewer info={info}></InfoViewer> : <>Empty</>}</>;
44
31
  };
@@ -9,9 +9,7 @@ interface PersQueueGroupOverviewProps {
9
9
 
10
10
  export const PersQueueGroupOverview = ({data}: PersQueueGroupOverviewProps) => {
11
11
  if (!data) {
12
- return (
13
- <div className="error">No PersQueueGroup data</div>
14
- );
12
+ return <div className="error">No PersQueueGroup data</div>;
15
13
  }
16
14
 
17
15
  const pqGroup = data.PathDescription?.PersQueueGroup;
@@ -21,15 +19,12 @@ export const PersQueueGroupOverview = ({data}: PersQueueGroupOverviewProps) => {
21
19
  info.push(formatCommonItem('CreateStep', data.PathDescription?.Self?.CreateStep));
22
20
 
23
21
  info.push(formatPQGroupItem('Partitions', pqGroup?.Partitions || []));
24
- info.push(formatPQGroupItem('PQTabletConfig', pqGroup?.PQTabletConfig || {PartitionConfig: {LifetimeSeconds: 0}}));
25
-
26
- return (
27
- <>
28
- {info.length ? (
29
- <InfoViewer info={info}></InfoViewer>
30
- ) : (
31
- <>Empty</>
32
- )}
33
- </>
22
+ info.push(
23
+ formatPQGroupItem(
24
+ 'PQTabletConfig',
25
+ pqGroup?.PQTabletConfig || {PartitionConfig: {LifetimeSeconds: 0}},
26
+ ),
34
27
  );
28
+
29
+ return <>{info.length ? <InfoViewer info={info}></InfoViewer> : <>Empty</>}</>;
35
30
  };
@@ -1,12 +1,12 @@
1
- import type {ReactNode} from "react";
1
+ import type {ReactNode} from 'react';
2
2
 
3
3
  type LabelMap<T> = {
4
4
  [label in keyof T]?: string;
5
- }
5
+ };
6
6
 
7
7
  type ValueFormatters<T> = {
8
8
  [label in keyof T]?: (value: T[label]) => ReactNode;
9
- }
9
+ };
10
10
 
11
11
  function formatLabel<Shape>(label: keyof Shape, map: LabelMap<Shape>) {
12
12
  return map[label] ?? label;
@@ -25,9 +25,9 @@ function formatValue<Shape, Key extends keyof Shape>(
25
25
  }
26
26
 
27
27
  interface CreateInfoFormatterOptions<Shape> {
28
- values?: ValueFormatters<Shape>,
29
- labels?: LabelMap<Shape>,
30
- defaultValueFormatter?: (value: Shape[keyof Shape]) => ReactNode,
28
+ values?: ValueFormatters<Shape>;
29
+ labels?: LabelMap<Shape>;
30
+ defaultValueFormatter?: (value: Shape[keyof Shape]) => ReactNode;
31
31
  }
32
32
 
33
33
  export function createInfoFormatter<Shape extends Record<string, any>>({
@@ -1,5 +1,8 @@
1
- @import '../../styles/mixins.scss';
1
+ .ydb-loader {
2
+ display: flex;
3
+ flex: 1 1 auto;
4
+ justify-content: center;
5
+ align-items: center;
2
6
 
3
- .kv-loader {
4
- @include loader();
7
+ height: 100%;
5
8
  }
@@ -3,14 +3,16 @@ import {Loader as KitLoader, LoaderSize} from '@gravity-ui/uikit';
3
3
 
4
4
  import './Loader.scss';
5
5
 
6
- const b = cn('kv-loader');
6
+ const b = cn('ydb-loader');
7
7
 
8
- function Loader({size = 'l'}: {size?: LoaderSize}) {
8
+ interface LoaderProps {
9
+ size?: LoaderSize;
10
+ }
11
+
12
+ export const Loader = ({size = 'm'}: LoaderProps) => {
9
13
  return (
10
14
  <div className={b()}>
11
15
  <KitLoader size={size} />
12
16
  </div>
13
17
  );
14
- }
15
-
16
- export default Loader;
18
+ };
@@ -0,0 +1 @@
1
+ export * from './Loader';
@@ -0,0 +1,21 @@
1
+ import {RadioButton} from '@gravity-ui/uikit';
2
+
3
+ import {NodesUptimeFilterValues, NodesUptimeFilterTitles} from '../../utils/nodes';
4
+
5
+ interface UptimeFilterProps {
6
+ value: keyof typeof NodesUptimeFilterValues;
7
+ onChange: (value: string) => void;
8
+ }
9
+
10
+ export const UptimeFilter = ({value, onChange}: UptimeFilterProps) => {
11
+ return (
12
+ <RadioButton value={value} onUpdate={onChange}>
13
+ <RadioButton.Option value={NodesUptimeFilterValues.All}>
14
+ {NodesUptimeFilterTitles[NodesUptimeFilterValues.All]}
15
+ </RadioButton.Option>
16
+ <RadioButton.Option value={NodesUptimeFilterValues.SmallUptime}>
17
+ {NodesUptimeFilterTitles[NodesUptimeFilterValues.SmallUptime]}
18
+ </RadioButton.Option>
19
+ </RadioButton>
20
+ );
21
+ };
@@ -0,0 +1 @@
1
+ export * from './UptimeFilter';
@@ -45,6 +45,7 @@
45
45
  }
46
46
 
47
47
  &__node-page-wrapper {
48
+ height: 100%;
48
49
  padding: 20px;
49
50
  }
50
51
  }
@@ -12,7 +12,7 @@ import Tablets from '../Tablets/Tablets';
12
12
  import Storage from '../Storage/Storage';
13
13
  import NodeOverview from './NodeOverview/NodeOverview';
14
14
  import NodeStructure from './NodeStructure/NodeStructure';
15
- import Loader from '../../components/Loader/Loader';
15
+ import {Loader} from '../../components/Loader';
16
16
  import {BasicNodeViewer} from '../../components/BasicNodeViewer';
17
17
 
18
18
  import {getNodeInfo, resetNode} from '../../store/reducers/node';
@@ -132,12 +132,7 @@ function Node(props: NodeProps) {
132
132
  }
133
133
 
134
134
  case OVERVIEW: {
135
- return (
136
- <NodeOverview
137
- node={node}
138
- className={b('overview-wrapper')}
139
- />
140
- );
135
+ return <NodeOverview node={node} className={b('overview-wrapper')} />;
141
136
  }
142
137
 
143
138
  case STRUCTURE: {
@@ -155,7 +150,7 @@ function Node(props: NodeProps) {
155
150
  };
156
151
 
157
152
  if (loading && !wasLoaded) {
158
- return <Loader />;
153
+ return <Loader size="l" />;
159
154
  } else if (error) {
160
155
  return <div>{error.statusText}</div>;
161
156
  } else {
@@ -10,12 +10,6 @@
10
10
  @include flex-container();
11
11
  @include body2-typography();
12
12
 
13
- &__loader {
14
- display: flex;
15
- flex-grow: 1;
16
- justify-content: center;
17
- }
18
-
19
13
  &__pdisk {
20
14
  display: flex;
21
15
  flex-direction: column;
@@ -6,7 +6,7 @@ import _ from 'lodash';
6
6
  import cn from 'bem-cn-lite';
7
7
 
8
8
  import {PDisk} from './Pdisk';
9
- import Loader from '../.././../components/Loader/Loader';
9
+ import {Loader} from '../.././../components/Loader';
10
10
 
11
11
  import {getNodeStructure, selectNodeStructure} from '../../../store/reducers/node';
12
12
 
@@ -9,17 +9,19 @@ import {Loader, TextInput, Label} from '@gravity-ui/uikit';
9
9
  import ProblemFilter, {problemFilterType} from '../../components/ProblemFilter/ProblemFilter';
10
10
  import {Illustration} from '../../components/Illustration';
11
11
  import {AccessDenied} from '../../components/Errors/403';
12
+ import {UptimeFilter} from '../../components/UptimeFIlter';
12
13
 
13
14
  import {hideTooltip, showTooltip} from '../../store/reducers/tooltip';
14
15
  import {withSearch} from '../../HOCS';
15
16
  import {AUTO_RELOAD_INTERVAL, ALL, DEFAULT_TABLE_SETTINGS} from '../../utils/constants';
16
17
  import {getFilteredNodes} from '../../store/reducers/clusterNodes';
17
- import {getNodes} from '../../store/reducers/nodes';
18
+ import {getNodes, setNodesUptimeFilter} from '../../store/reducers/nodes';
18
19
  import {changeFilter} from '../../store/reducers/settings';
19
20
  import {setHeader} from '../../store/reducers/header';
20
21
  import routes, {CLUSTER_PAGES, createHref} from '../../routes';
21
22
  import {calcUptime} from '../../utils';
22
23
  import {getNodesColumns} from '../../utils/getNodesColumns';
24
+ import {NodesUptimeFilterValues} from '../../utils/nodes';
23
25
 
24
26
  import './Nodes.scss';
25
27
 
@@ -44,12 +46,14 @@ class Nodes extends React.Component {
44
46
  hideTooltip: PropTypes.func,
45
47
  searchQuery: PropTypes.string,
46
48
  handleSearchQuery: PropTypes.func,
47
- filter: problemFilterType,
49
+ problemFilter: problemFilterType,
48
50
  changeFilter: PropTypes.func,
49
51
  setHeader: PropTypes.func,
50
52
  className: PropTypes.string,
51
53
  singleClusterMode: PropTypes.bool,
52
54
  additionalNodesInfo: PropTypes.object,
55
+ nodesUptimeFilter: PropTypes.string,
56
+ setNodesUptimeFilter: PropTypes.func,
53
57
  };
54
58
 
55
59
  componentDidMount() {
@@ -73,12 +77,16 @@ class Nodes extends React.Component {
73
77
  this.props.handleSearchQuery(search);
74
78
  };
75
79
 
76
- handleFilterChange = (filter) => {
77
- this.props.changeFilter(filter);
80
+ handleProblemFilterChange = (value) => {
81
+ this.props.changeFilter(value);
82
+ };
83
+
84
+ handleUptimeFilterChange = (value) => {
85
+ this.props.setNodesUptimeFilter(value);
78
86
  };
79
87
 
80
88
  renderControls() {
81
- const {searchQuery, filter, nodes} = this.props;
89
+ const {nodes, searchQuery, problemFilter, nodesUptimeFilter} = this.props;
82
90
 
83
91
  return (
84
92
  <div className={b('controls')}>
@@ -90,7 +98,8 @@ class Nodes extends React.Component {
90
98
  hasClear
91
99
  autoFocus
92
100
  />
93
- <ProblemFilter value={filter} onChange={this.handleFilterChange} />
101
+ <ProblemFilter value={problemFilter} onChange={this.handleProblemFilterChange} />
102
+ <UptimeFilter value={nodesUptimeFilter} onChange={this.handleUptimeFilterChange} />
94
103
  <Label theme="info" size="m">{`Nodes: ${nodes?.length}`}</Label>
95
104
  </div>
96
105
  );
@@ -99,7 +108,8 @@ class Nodes extends React.Component {
99
108
  renderTable = () => {
100
109
  const {
101
110
  nodes = [],
102
- filter,
111
+ problemFilter,
112
+ nodesUptimeFilter,
103
113
  searchQuery,
104
114
  showTooltip,
105
115
  hideTooltip,
@@ -126,7 +136,7 @@ class Nodes extends React.Component {
126
136
  }));
127
137
 
128
138
  if (preparedNodes.length === 0) {
129
- if (filter !== ALL) {
139
+ if (problemFilter !== ALL || nodesUptimeFilter !== NodesUptimeFilterValues.All) {
130
140
  return <Illustration name="thumbsUp" width="200" />;
131
141
  }
132
142
  }
@@ -177,7 +187,7 @@ class Nodes extends React.Component {
177
187
  }
178
188
 
179
189
  const mapStateToProps = (state) => {
180
- const {wasLoaded, loading, error} = state.nodes;
190
+ const {wasLoaded, loading, error, nodesUptimeFilter} = state.nodes;
181
191
 
182
192
  const nodes = getFilteredNodes(state);
183
193
  return {
@@ -186,7 +196,8 @@ const mapStateToProps = (state) => {
186
196
  wasLoaded,
187
197
  loading,
188
198
  error,
189
- filter: state.settings.problemFilter,
199
+ problemFilter: state.settings.problemFilter,
200
+ nodesUptimeFilter,
190
201
  };
191
202
  };
192
203
 
@@ -196,6 +207,7 @@ const mapDispatchToProps = {
196
207
  showTooltip,
197
208
  changeFilter,
198
209
  setHeader,
210
+ setNodesUptimeFilter,
199
211
  };
200
212
 
201
213
  export default withSearch(connect(mapStateToProps, mapDispatchToProps)(Nodes));