ydb-embedded-ui 4.4.1 → 4.4.2
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.
- package/CHANGELOG.md +7 -0
- package/dist/components/ProblemFilter/ProblemFilter.tsx +9 -4
- package/dist/containers/App/Content.js +1 -1
- package/dist/containers/AsideNavigation/AsideNavigation.tsx +2 -2
- package/dist/containers/Nodes/Nodes.tsx +8 -8
- package/dist/containers/Tenant/Diagnostics/Network/Network.js +8 -7
- package/dist/containers/Tenant/ObjectGeneralTabs/ObjectGeneralTabs.tsx +1 -1
- package/dist/containers/Tenant/QueryEditor/QueryEditor.js +1 -1
- package/dist/containers/Tenants/Tenants.js +8 -4
- package/dist/containers/UserSettings/Setting.tsx +4 -4
- package/dist/containers/UserSettings/UserSettings.tsx +23 -82
- package/dist/containers/UserSettings/settings.ts +91 -0
- package/dist/store/reducers/index.ts +1 -1
- package/dist/store/reducers/nodes.ts +5 -3
- package/dist/store/reducers/partitions/utils.ts +1 -1
- package/dist/store/reducers/{settings.js → settings/settings.ts} +33 -14
- package/dist/store/reducers/settings/types.ts +19 -0
- package/dist/store/state-url-mapping.js +1 -1
- package/dist/utils/constants.ts +0 -5
- package/dist/utils/hooks/useSetting.ts +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [4.4.2](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.4.1...v4.4.2) (2023-05-29)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **Partitions:** fix offsets calculation ([#402](https://github.com/ydb-platform/ydb-embedded-ui/issues/402)) ([fd4741f](https://github.com/ydb-platform/ydb-embedded-ui/commit/fd4741f8761aa6aa9ec31681522c4d261a83273f))
|
|
9
|
+
|
|
3
10
|
## [4.4.1](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.4.0...v4.4.1) (2023-05-25)
|
|
4
11
|
|
|
5
12
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {RadioButton} from '@gravity-ui/uikit';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import type {ValueOf} from '../../types/common';
|
|
4
|
+
import {ProblemFilterValues} from '../../store/reducers/settings/settings';
|
|
4
5
|
|
|
5
6
|
interface ProblemFilterProps {
|
|
6
|
-
value:
|
|
7
|
+
value: ValueOf<typeof ProblemFilterValues>;
|
|
7
8
|
onChange: (value: string) => void;
|
|
8
9
|
className?: string;
|
|
9
10
|
}
|
|
@@ -11,8 +12,12 @@ interface ProblemFilterProps {
|
|
|
11
12
|
export const ProblemFilter = ({value, onChange, className}: ProblemFilterProps) => {
|
|
12
13
|
return (
|
|
13
14
|
<RadioButton value={value} onUpdate={onChange} className={className}>
|
|
14
|
-
<RadioButton.Option value={ALL}>
|
|
15
|
-
|
|
15
|
+
<RadioButton.Option value={ProblemFilterValues.ALL}>
|
|
16
|
+
{ProblemFilterValues.ALL}
|
|
17
|
+
</RadioButton.Option>
|
|
18
|
+
<RadioButton.Option value={ProblemFilterValues.PROBLEMS}>
|
|
19
|
+
{ProblemFilterValues.PROBLEMS}
|
|
20
|
+
</RadioButton.Option>
|
|
16
21
|
</RadioButton>
|
|
17
22
|
);
|
|
18
23
|
};
|
|
@@ -16,7 +16,7 @@ import ReduxTooltip from '../ReduxTooltip/ReduxTooltip';
|
|
|
16
16
|
import Header from '../Header/Header';
|
|
17
17
|
import AppIcons from '../AppIcons/AppIcons';
|
|
18
18
|
|
|
19
|
-
import {getParsedSettingValue} from '../../store/reducers/settings';
|
|
19
|
+
import {getParsedSettingValue} from '../../store/reducers/settings/settings';
|
|
20
20
|
import {THEME_KEY} from '../../utils/constants';
|
|
21
21
|
|
|
22
22
|
import './App.scss';
|
|
@@ -24,7 +24,7 @@ import {UserSettings} from '../UserSettings/UserSettings';
|
|
|
24
24
|
import routes, {createHref, CLUSTER_PAGES} from '../../routes';
|
|
25
25
|
|
|
26
26
|
import {logout} from '../../store/reducers/authentication';
|
|
27
|
-
import {
|
|
27
|
+
import {getParsedSettingValue, setSettingValue} from '../../store/reducers/settings/settings';
|
|
28
28
|
|
|
29
29
|
import {ASIDE_HEADER_COMPACT_KEY} from '../../utils/constants';
|
|
30
30
|
|
|
@@ -273,7 +273,7 @@ const mapStateToProps = (state: any) => {
|
|
|
273
273
|
|
|
274
274
|
return {
|
|
275
275
|
ydbUser,
|
|
276
|
-
compact:
|
|
276
|
+
compact: getParsedSettingValue(state, ASIDE_HEADER_COMPACT_KEY),
|
|
277
277
|
};
|
|
278
278
|
};
|
|
279
279
|
|
|
@@ -5,6 +5,7 @@ import {useDispatch} from 'react-redux';
|
|
|
5
5
|
import DataTable from '@gravity-ui/react-data-table';
|
|
6
6
|
|
|
7
7
|
import type {EPathType} from '../../types/api/schema';
|
|
8
|
+
import type {ValueOf} from '../../types/common';
|
|
8
9
|
|
|
9
10
|
import {AccessDenied} from '../../components/Errors/403';
|
|
10
11
|
import {Illustration} from '../../components/Illustration';
|
|
@@ -16,11 +17,7 @@ import {EntitiesCount} from '../../components/EntitiesCount';
|
|
|
16
17
|
|
|
17
18
|
import routes, {CLUSTER_PAGES, createHref} from '../../routes';
|
|
18
19
|
|
|
19
|
-
import {
|
|
20
|
-
ALL,
|
|
21
|
-
DEFAULT_TABLE_SETTINGS,
|
|
22
|
-
USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
|
|
23
|
-
} from '../../utils/constants';
|
|
20
|
+
import {DEFAULT_TABLE_SETTINGS, USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY} from '../../utils/constants';
|
|
24
21
|
import {useAutofetcher, useSetting, useTypedSelector} from '../../utils/hooks';
|
|
25
22
|
import {AdditionalNodesInfo, isUnavailableNode, NodesUptimeFilterValues} from '../../utils/nodes';
|
|
26
23
|
|
|
@@ -33,7 +30,7 @@ import {
|
|
|
33
30
|
resetNodesState,
|
|
34
31
|
getComputeNodes,
|
|
35
32
|
} from '../../store/reducers/nodes';
|
|
36
|
-
import {changeFilter} from '../../store/reducers/settings';
|
|
33
|
+
import {changeFilter, ProblemFilterValues} from '../../store/reducers/settings/settings';
|
|
37
34
|
import {hideTooltip, showTooltip} from '../../store/reducers/tooltip';
|
|
38
35
|
|
|
39
36
|
import {isDatabaseEntityType} from '../Tenant/utils/schema';
|
|
@@ -104,7 +101,7 @@ export const Nodes = ({path, type, className, additionalNodesInfo = {}}: NodesPr
|
|
|
104
101
|
};
|
|
105
102
|
|
|
106
103
|
const handleProblemFilterChange = (value: string) => {
|
|
107
|
-
dispatch(changeFilter(value));
|
|
104
|
+
dispatch(changeFilter(value as ValueOf<typeof ProblemFilterValues>));
|
|
108
105
|
};
|
|
109
106
|
|
|
110
107
|
const handleUptimeFilterChange = (value: string) => {
|
|
@@ -148,7 +145,10 @@ export const Nodes = ({path, type, className, additionalNodesInfo = {}}: NodesPr
|
|
|
148
145
|
});
|
|
149
146
|
|
|
150
147
|
if (nodes && nodes.length === 0) {
|
|
151
|
-
if (
|
|
148
|
+
if (
|
|
149
|
+
problemFilter !== ProblemFilterValues.ALL ||
|
|
150
|
+
nodesUptimeFilter !== NodesUptimeFilterValues.All
|
|
151
|
+
) {
|
|
152
152
|
return <Illustration name="thumbsUp" width="200" />;
|
|
153
153
|
}
|
|
154
154
|
}
|
|
@@ -14,8 +14,7 @@ import {Illustration} from '../../../../components/Illustration';
|
|
|
14
14
|
|
|
15
15
|
import {getNetworkInfo, setDataWasNotLoaded} from '../../../../store/reducers/network';
|
|
16
16
|
import {hideTooltip, showTooltip} from '../../../../store/reducers/tooltip';
|
|
17
|
-
import {
|
|
18
|
-
import {changeFilter} from '../../../../store/reducers/settings';
|
|
17
|
+
import {changeFilter, ProblemFilterValues} from '../../../../store/reducers/settings/settings';
|
|
19
18
|
import {AutoFetcher} from '../../../../utils/autofetcher';
|
|
20
19
|
import {getDefaultNodePath} from '../../../Node/NodePages';
|
|
21
20
|
|
|
@@ -178,8 +177,9 @@ class Network extends React.Component {
|
|
|
178
177
|
}
|
|
179
178
|
|
|
180
179
|
if (
|
|
181
|
-
(filter === PROBLEMS &&
|
|
182
|
-
|
|
180
|
+
(filter === ProblemFilterValues.PROBLEMS &&
|
|
181
|
+
capacity !== connected) ||
|
|
182
|
+
filter === ProblemFilterValues.ALL ||
|
|
183
183
|
isRight
|
|
184
184
|
) {
|
|
185
185
|
problemNodesCount++;
|
|
@@ -218,8 +218,9 @@ class Network extends React.Component {
|
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
if (
|
|
221
|
-
(filter === PROBLEMS &&
|
|
222
|
-
|
|
221
|
+
(filter === ProblemFilterValues.PROBLEMS &&
|
|
222
|
+
capacity !== connected) ||
|
|
223
|
+
filter === ProblemFilterValues.ALL ||
|
|
223
224
|
isRight
|
|
224
225
|
) {
|
|
225
226
|
problemNodesCount++;
|
|
@@ -254,7 +255,7 @@ class Network extends React.Component {
|
|
|
254
255
|
);
|
|
255
256
|
});
|
|
256
257
|
|
|
257
|
-
if (filter === PROBLEMS && problemNodesCount === 0) {
|
|
258
|
+
if (filter === ProblemFilterValues.PROBLEMS && problemNodesCount === 0) {
|
|
258
259
|
return <Illustration name="thumbsUp" width="200" />;
|
|
259
260
|
} else {
|
|
260
261
|
return result;
|
|
@@ -8,7 +8,7 @@ import {Tabs} from '@gravity-ui/uikit';
|
|
|
8
8
|
|
|
9
9
|
import routes, {createHref} from '../../../routes';
|
|
10
10
|
import {TENANT_INITIAL_TAB_KEY} from '../../../utils/constants';
|
|
11
|
-
import {setSettingValue} from '../../../store/reducers/settings';
|
|
11
|
+
import {setSettingValue} from '../../../store/reducers/settings/settings';
|
|
12
12
|
|
|
13
13
|
import {TenantTabsGroups, TENANT_GENERAL_TABS} from '../TenantPages';
|
|
14
14
|
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
setMonacoHotKey,
|
|
25
25
|
} from '../../../store/reducers/executeQuery';
|
|
26
26
|
import {getExplainQuery, getExplainQueryAst} from '../../../store/reducers/explainQuery';
|
|
27
|
-
import {getParsedSettingValue, setSettingValue} from '../../../store/reducers/settings';
|
|
27
|
+
import {getParsedSettingValue, setSettingValue} from '../../../store/reducers/settings/settings';
|
|
28
28
|
import {
|
|
29
29
|
DEFAULT_IS_QUERY_RESULT_COLLAPSED,
|
|
30
30
|
DEFAULT_SIZE_RESULT_PANE_KEY,
|
|
@@ -19,9 +19,13 @@ import routes, {CLUSTER_PAGES, createHref} from '../../routes';
|
|
|
19
19
|
import {formatCPU, formatBytesToGigabyte, formatNumber} from '../../utils';
|
|
20
20
|
import {hideTooltip, showTooltip} from '../../store/reducers/tooltip';
|
|
21
21
|
import {withSearch} from '../../HOCS';
|
|
22
|
-
import {
|
|
22
|
+
import {DEFAULT_TABLE_SETTINGS, TENANT_INITIAL_TAB_KEY} from '../../utils/constants';
|
|
23
23
|
import {getTenantsInfo} from '../../store/reducers/tenants/tenants';
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
changeFilter,
|
|
26
|
+
getSettingValue,
|
|
27
|
+
ProblemFilterValues,
|
|
28
|
+
} from '../../store/reducers/settings/settings';
|
|
25
29
|
import {setHeader} from '../../store/reducers/header';
|
|
26
30
|
|
|
27
31
|
import {clusterName} from '../../store';
|
|
@@ -63,7 +67,7 @@ class Tenants extends React.Component {
|
|
|
63
67
|
};
|
|
64
68
|
|
|
65
69
|
static filterTenants(tenants, filter) {
|
|
66
|
-
if (filter === ALL) {
|
|
70
|
+
if (filter === ProblemFilterValues.ALL) {
|
|
67
71
|
return tenants;
|
|
68
72
|
}
|
|
69
73
|
|
|
@@ -311,7 +315,7 @@ class Tenants extends React.Component {
|
|
|
311
315
|
},
|
|
312
316
|
];
|
|
313
317
|
|
|
314
|
-
if (filteredTenants.length === 0 && filter !== ALL) {
|
|
318
|
+
if (filteredTenants.length === 0 && filter !== ProblemFilterValues.ALL) {
|
|
315
319
|
return <Illustration name="thumbsUp" width="200" />;
|
|
316
320
|
}
|
|
317
321
|
|
|
@@ -16,7 +16,7 @@ export interface SettingProps {
|
|
|
16
16
|
title: string;
|
|
17
17
|
settingKey: string;
|
|
18
18
|
helpPopoverContent?: ReactNode;
|
|
19
|
-
|
|
19
|
+
options?: {value: string; content: string}[];
|
|
20
20
|
defaultValue?: unknown;
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -25,7 +25,7 @@ export const Setting = ({
|
|
|
25
25
|
settingKey,
|
|
26
26
|
title,
|
|
27
27
|
helpPopoverContent,
|
|
28
|
-
|
|
28
|
+
options,
|
|
29
29
|
defaultValue,
|
|
30
30
|
}: SettingProps) => {
|
|
31
31
|
const [settingValue, setValue] = useSetting(settingKey, defaultValue);
|
|
@@ -52,13 +52,13 @@ export const Setting = ({
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
case 'radio': {
|
|
55
|
-
if (!
|
|
55
|
+
if (!options) {
|
|
56
56
|
return null;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
return (
|
|
60
60
|
<RadioButton value={String(settingValue)} onUpdate={setValue}>
|
|
61
|
-
{
|
|
61
|
+
{options.map(({value, content}) => {
|
|
62
62
|
return (
|
|
63
63
|
<RadioButton.Option value={value} key={value}>
|
|
64
64
|
{content}
|
|
@@ -2,98 +2,39 @@ import cn from 'bem-cn-lite';
|
|
|
2
2
|
|
|
3
3
|
import {Settings} from '@gravity-ui/navigation';
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
ENABLE_QUERY_MODES_FOR_EXPLAIN,
|
|
10
|
-
INVERTED_DISKS_KEY,
|
|
11
|
-
THEME_KEY,
|
|
12
|
-
USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
|
|
13
|
-
} from '../../utils/constants';
|
|
14
|
-
|
|
15
|
-
import {Setting, SettingProps} from './Setting';
|
|
16
|
-
import i18n from './i18n';
|
|
5
|
+
import {YDBEmbeddedUISettings, settings} from './settings';
|
|
6
|
+
import {Setting} from './Setting';
|
|
17
7
|
|
|
18
8
|
import './UserSettings.scss';
|
|
19
9
|
|
|
20
10
|
export const b = cn('ydb-user-settings');
|
|
21
11
|
|
|
22
|
-
enum Theme {
|
|
23
|
-
light = 'light',
|
|
24
|
-
dark = 'dark',
|
|
25
|
-
system = 'system',
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const themeValues = [
|
|
29
|
-
{
|
|
30
|
-
value: Theme.system,
|
|
31
|
-
content: i18n('settings.theme.option-system'),
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
value: Theme.light,
|
|
35
|
-
content: i18n('settings.theme.option-light'),
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
value: Theme.dark,
|
|
39
|
-
content: i18n('settings.theme.option-dark'),
|
|
40
|
-
},
|
|
41
|
-
];
|
|
42
|
-
|
|
43
|
-
export enum SettingsSection {
|
|
44
|
-
general = 'general',
|
|
45
|
-
experiments = 'experiments',
|
|
46
|
-
}
|
|
47
|
-
|
|
48
12
|
interface UserSettingsProps {
|
|
49
|
-
settings?:
|
|
13
|
+
settings?: YDBEmbeddedUISettings;
|
|
50
14
|
}
|
|
51
15
|
|
|
52
|
-
export const UserSettings = ({settings}: UserSettingsProps) => {
|
|
16
|
+
export const UserSettings = ({settings: userSettings = settings}: UserSettingsProps) => {
|
|
53
17
|
return (
|
|
54
18
|
<Settings>
|
|
55
|
-
|
|
56
|
-
id=
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
title={i18n('page.experiments')}
|
|
75
|
-
icon={{data: flaskIcon}}
|
|
76
|
-
>
|
|
77
|
-
<Settings.Section title={i18n('section.experiments')}>
|
|
78
|
-
<Setting
|
|
79
|
-
settingKey={INVERTED_DISKS_KEY}
|
|
80
|
-
title={i18n('settings.invertedDisks.title')}
|
|
81
|
-
/>
|
|
82
|
-
<Setting
|
|
83
|
-
settingKey={USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY}
|
|
84
|
-
title={i18n('settings.useNodesEndpoint.title')}
|
|
85
|
-
helpPopoverContent={i18n('settings.useNodesEndpoint.popover')}
|
|
86
|
-
/>
|
|
87
|
-
<Setting
|
|
88
|
-
settingKey={ENABLE_QUERY_MODES_FOR_EXPLAIN}
|
|
89
|
-
title={i18n('settings.enableQueryModesForExplain.title')}
|
|
90
|
-
helpPopoverContent={i18n('settings.enableQueryModesForExplain.popover')}
|
|
91
|
-
/>
|
|
92
|
-
{settings?.[SettingsSection.experiments]?.map((setting) => (
|
|
93
|
-
<Setting key={setting.settingKey} {...setting} />
|
|
94
|
-
))}
|
|
95
|
-
</Settings.Section>
|
|
96
|
-
</Settings.Page>
|
|
19
|
+
{userSettings.map((page) => {
|
|
20
|
+
const {id, title, icon, sections = []} = page;
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<Settings.Page key={id} id={id} title={title} icon={icon}>
|
|
24
|
+
{sections.map((section) => {
|
|
25
|
+
const {title: sectionTitle, settings: sectionSettings = []} = section;
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<Settings.Section key={id} title={sectionTitle}>
|
|
29
|
+
{sectionSettings.map((setting) => {
|
|
30
|
+
return <Setting key={setting.settingKey} {...setting} />;
|
|
31
|
+
})}
|
|
32
|
+
</Settings.Section>
|
|
33
|
+
);
|
|
34
|
+
})}
|
|
35
|
+
</Settings.Page>
|
|
36
|
+
);
|
|
37
|
+
})}
|
|
97
38
|
</Settings>
|
|
98
39
|
);
|
|
99
40
|
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type {IconProps} from '@gravity-ui/uikit';
|
|
2
|
+
|
|
3
|
+
import favoriteFilledIcon from '../../assets/icons/star.svg';
|
|
4
|
+
import flaskIcon from '../../assets/icons/flask.svg';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
ENABLE_QUERY_MODES_FOR_EXPLAIN,
|
|
8
|
+
INVERTED_DISKS_KEY,
|
|
9
|
+
THEME_KEY,
|
|
10
|
+
USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
|
|
11
|
+
} from '../../utils/constants';
|
|
12
|
+
|
|
13
|
+
import type {SettingProps} from './Setting';
|
|
14
|
+
import i18n from './i18n';
|
|
15
|
+
|
|
16
|
+
export interface SettingsSection {
|
|
17
|
+
id: string;
|
|
18
|
+
title: string;
|
|
19
|
+
settings: SettingProps[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface SettingsPage {
|
|
23
|
+
id: string;
|
|
24
|
+
title: string;
|
|
25
|
+
icon: IconProps;
|
|
26
|
+
sections: SettingsSection[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type YDBEmbeddedUISettings = SettingsPage[];
|
|
30
|
+
|
|
31
|
+
const themeOptions = [
|
|
32
|
+
{
|
|
33
|
+
value: 'system',
|
|
34
|
+
content: i18n('settings.theme.option-system'),
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
value: 'light',
|
|
38
|
+
content: i18n('settings.theme.option-light'),
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
value: 'dark',
|
|
42
|
+
content: i18n('settings.theme.option-dark'),
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
export const themeSetting: SettingProps = {
|
|
47
|
+
settingKey: THEME_KEY,
|
|
48
|
+
title: i18n('settings.theme.title'),
|
|
49
|
+
type: 'radio',
|
|
50
|
+
options: themeOptions,
|
|
51
|
+
};
|
|
52
|
+
export const invertedDisksSetting: SettingProps = {
|
|
53
|
+
settingKey: INVERTED_DISKS_KEY,
|
|
54
|
+
title: i18n('settings.invertedDisks.title'),
|
|
55
|
+
};
|
|
56
|
+
export const useNodesEndpointSetting: SettingProps = {
|
|
57
|
+
settingKey: USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
|
|
58
|
+
title: i18n('settings.useNodesEndpoint.title'),
|
|
59
|
+
helpPopoverContent: i18n('settings.useNodesEndpoint.popover'),
|
|
60
|
+
};
|
|
61
|
+
export const enableQueryModesForExplainSetting: SettingProps = {
|
|
62
|
+
settingKey: ENABLE_QUERY_MODES_FOR_EXPLAIN,
|
|
63
|
+
title: i18n('settings.enableQueryModesForExplain.title'),
|
|
64
|
+
helpPopoverContent: i18n('settings.enableQueryModesForExplain.popover'),
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const generalSection: SettingsSection = {
|
|
68
|
+
id: 'generalSection',
|
|
69
|
+
title: i18n('section.general'),
|
|
70
|
+
settings: [themeSetting],
|
|
71
|
+
};
|
|
72
|
+
export const experimentsSection: SettingsSection = {
|
|
73
|
+
id: 'experimentsSection',
|
|
74
|
+
title: i18n('section.experiments'),
|
|
75
|
+
settings: [invertedDisksSetting, useNodesEndpointSetting, enableQueryModesForExplainSetting],
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const generalPage: SettingsPage = {
|
|
79
|
+
id: 'generalPage',
|
|
80
|
+
title: i18n('page.general'),
|
|
81
|
+
icon: {data: favoriteFilledIcon, height: 14, width: 14},
|
|
82
|
+
sections: [generalSection],
|
|
83
|
+
};
|
|
84
|
+
export const experimentsPage: SettingsPage = {
|
|
85
|
+
id: 'experimentsPage',
|
|
86
|
+
title: i18n('page.experiments'),
|
|
87
|
+
icon: {data: flaskIcon},
|
|
88
|
+
sections: [experimentsSection],
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export const settings: YDBEmbeddedUISettings = [generalPage, experimentsPage];
|
|
@@ -19,7 +19,7 @@ import partitions from './partitions/partitions';
|
|
|
19
19
|
import executeQuery from './executeQuery';
|
|
20
20
|
import explainQuery from './explainQuery';
|
|
21
21
|
import tabletsFilters from './tabletsFilters';
|
|
22
|
-
import settings from './settings';
|
|
22
|
+
import settings from './settings/settings';
|
|
23
23
|
import preview from './preview';
|
|
24
24
|
import nodesList from './nodesList';
|
|
25
25
|
import describe from './describe';
|
|
@@ -3,7 +3,7 @@ import {createSelector, Selector} from 'reselect';
|
|
|
3
3
|
import {escapeRegExp} from 'lodash/fp';
|
|
4
4
|
|
|
5
5
|
import '../../services/api';
|
|
6
|
-
import {
|
|
6
|
+
import {HOUR_IN_SECONDS} from '../../utils/constants';
|
|
7
7
|
import {calcUptime, calcUptimeInSeconds} from '../../utils';
|
|
8
8
|
import {NodesUptimeFilterValues} from '../../utils/nodes';
|
|
9
9
|
import type {
|
|
@@ -14,9 +14,11 @@ import type {
|
|
|
14
14
|
INodesRootStateSlice,
|
|
15
15
|
INodesState,
|
|
16
16
|
} from '../../types/store/nodes';
|
|
17
|
+
import type {ValueOf} from '../../types/common';
|
|
17
18
|
import {EFlag} from '../../types/api/enums';
|
|
18
19
|
|
|
19
20
|
import {createRequestActionTypes, createApiRequest} from '../utils';
|
|
21
|
+
import {ProblemFilterValues} from './settings/settings';
|
|
20
22
|
|
|
21
23
|
export const FETCH_NODES = createRequestActionTypes('nodes', 'FETCH_NODES');
|
|
22
24
|
|
|
@@ -178,9 +180,9 @@ const getNodesList = (state: INodesRootStateSlice) => state.nodes.data;
|
|
|
178
180
|
|
|
179
181
|
const filterNodesByProblemsStatus = (
|
|
180
182
|
nodesList: INodesPreparedEntity[] = [],
|
|
181
|
-
problemFilter:
|
|
183
|
+
problemFilter: ValueOf<typeof ProblemFilterValues>,
|
|
182
184
|
) => {
|
|
183
|
-
if (problemFilter === ALL) {
|
|
185
|
+
if (problemFilter === ProblemFilterValues.ALL) {
|
|
184
186
|
return nodesList;
|
|
185
187
|
}
|
|
186
188
|
|
|
@@ -57,7 +57,7 @@ export const prepareConsumerPartitions = (
|
|
|
57
57
|
const {partition_id = '0', partition_stats, partition_consumer_stats} = partition;
|
|
58
58
|
|
|
59
59
|
const preparedPartitionStats = prepareGeneralPartitionStats(partition_stats);
|
|
60
|
-
const endOffset = preparedPartitionStats;
|
|
60
|
+
const {endOffset} = preparedPartitionStats;
|
|
61
61
|
|
|
62
62
|
const {
|
|
63
63
|
last_read_offset = '0',
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import type {Reducer} from 'redux';
|
|
2
|
+
import type {ThunkAction} from 'redux-thunk';
|
|
3
|
+
|
|
4
|
+
import type {ValueOf} from '../../../types/common';
|
|
1
5
|
import {
|
|
2
|
-
ALL,
|
|
3
6
|
SAVED_QUERIES_KEY,
|
|
4
7
|
THEME_KEY,
|
|
5
8
|
TENANT_INITIAL_TAB_KEY,
|
|
@@ -9,25 +12,38 @@ import {
|
|
|
9
12
|
PARTITIONS_HIDDEN_COLUMNS_KEY,
|
|
10
13
|
QUERY_INITIAL_MODE_KEY,
|
|
11
14
|
ENABLE_QUERY_MODES_FOR_EXPLAIN,
|
|
12
|
-
} from '
|
|
13
|
-
import '
|
|
14
|
-
import {getValueFromLS, parseJson} from '
|
|
15
|
-
import {QueryModes} from '
|
|
15
|
+
} from '../../../utils/constants';
|
|
16
|
+
import '../../../services/api';
|
|
17
|
+
import {getValueFromLS, parseJson} from '../../../utils/utils';
|
|
18
|
+
import {QueryModes} from '../../../types/store/query';
|
|
19
|
+
|
|
20
|
+
import type {RootState} from '..';
|
|
21
|
+
import type {
|
|
22
|
+
SetSettingValueAction,
|
|
23
|
+
SettingsAction,
|
|
24
|
+
SettingsRootStateSlice,
|
|
25
|
+
SettingsState,
|
|
26
|
+
} from './types';
|
|
16
27
|
|
|
17
28
|
const CHANGE_PROBLEM_FILTER = 'settings/CHANGE_PROBLEM_FILTER';
|
|
18
|
-
const SET_SETTING_VALUE = 'settings/SET_VALUE';
|
|
29
|
+
export const SET_SETTING_VALUE = 'settings/SET_VALUE';
|
|
30
|
+
|
|
31
|
+
export const ProblemFilterValues = {
|
|
32
|
+
ALL: 'All',
|
|
33
|
+
PROBLEMS: 'With problems',
|
|
34
|
+
} as const;
|
|
19
35
|
|
|
20
36
|
const userSettings = window.userSettings || {};
|
|
21
37
|
const systemSettings = window.systemSettings || {};
|
|
22
38
|
|
|
23
|
-
export function readSavedSettingsValue(key, defaultValue) {
|
|
39
|
+
export function readSavedSettingsValue(key: string, defaultValue?: string) {
|
|
24
40
|
const savedValue = window.web_version ? userSettings[key] : getValueFromLS(key);
|
|
25
41
|
|
|
26
42
|
return savedValue ?? defaultValue;
|
|
27
43
|
}
|
|
28
44
|
|
|
29
45
|
export const initialState = {
|
|
30
|
-
problemFilter: ALL,
|
|
46
|
+
problemFilter: ProblemFilterValues.ALL,
|
|
31
47
|
userSettings: {
|
|
32
48
|
...userSettings,
|
|
33
49
|
[THEME_KEY]: readSavedSettingsValue(THEME_KEY, 'system'),
|
|
@@ -49,7 +65,7 @@ export const initialState = {
|
|
|
49
65
|
systemSettings,
|
|
50
66
|
};
|
|
51
67
|
|
|
52
|
-
const settings = (state = initialState, action) => {
|
|
68
|
+
const settings: Reducer<SettingsState, SettingsAction> = (state = initialState, action) => {
|
|
53
69
|
switch (action.type) {
|
|
54
70
|
case CHANGE_PROBLEM_FILTER:
|
|
55
71
|
return {
|
|
@@ -74,7 +90,10 @@ const settings = (state = initialState, action) => {
|
|
|
74
90
|
}
|
|
75
91
|
};
|
|
76
92
|
|
|
77
|
-
export const setSettingValue = (
|
|
93
|
+
export const setSettingValue = (
|
|
94
|
+
name: string,
|
|
95
|
+
value: string,
|
|
96
|
+
): ThunkAction<void, RootState, unknown, SetSettingValueAction> => {
|
|
78
97
|
return (dispatch, getState) => {
|
|
79
98
|
dispatch({type: SET_SETTING_VALUE, data: {name, value}});
|
|
80
99
|
const {singleClusterMode} = getState();
|
|
@@ -86,7 +105,7 @@ export const setSettingValue = (name, value) => {
|
|
|
86
105
|
};
|
|
87
106
|
};
|
|
88
107
|
|
|
89
|
-
export const getSettingValue = (state, name) => {
|
|
108
|
+
export const getSettingValue = (state: SettingsRootStateSlice, name: string) => {
|
|
90
109
|
return state.settings.userSettings[name];
|
|
91
110
|
};
|
|
92
111
|
|
|
@@ -94,16 +113,16 @@ export const getSettingValue = (state, name) => {
|
|
|
94
113
|
* Returns parsed settings value.
|
|
95
114
|
* If value cannot be parsed, returns initially stored string
|
|
96
115
|
*/
|
|
97
|
-
export const getParsedSettingValue = (state, name) => {
|
|
116
|
+
export const getParsedSettingValue = (state: SettingsRootStateSlice, name: string) => {
|
|
98
117
|
const value = state.settings.userSettings[name];
|
|
99
118
|
return parseJson(value);
|
|
100
119
|
};
|
|
101
120
|
|
|
102
|
-
export const changeFilter = (filter) => {
|
|
121
|
+
export const changeFilter = (filter: ValueOf<typeof ProblemFilterValues>) => {
|
|
103
122
|
return {
|
|
104
123
|
type: CHANGE_PROBLEM_FILTER,
|
|
105
124
|
data: filter,
|
|
106
|
-
};
|
|
125
|
+
} as const;
|
|
107
126
|
};
|
|
108
127
|
|
|
109
128
|
export default settings;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type {ValueOf} from '../../../types/common';
|
|
2
|
+
import {changeFilter, ProblemFilterValues, SET_SETTING_VALUE} from './settings';
|
|
3
|
+
|
|
4
|
+
export interface SettingsState {
|
|
5
|
+
problemFilter: ValueOf<typeof ProblemFilterValues>;
|
|
6
|
+
userSettings: Record<string, string | undefined>;
|
|
7
|
+
systemSettings: Record<string, string | undefined>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type SetSettingValueAction = {
|
|
11
|
+
type: typeof SET_SETTING_VALUE;
|
|
12
|
+
data: {name: string; value: string};
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type SettingsAction = ReturnType<typeof changeFilter> | SetSettingValueAction;
|
|
16
|
+
|
|
17
|
+
export interface SettingsRootStateSlice {
|
|
18
|
+
settings: SettingsState;
|
|
19
|
+
}
|
|
@@ -6,7 +6,7 @@ import {parseQuery} from 'redux-location-state/lib/parseQuery';
|
|
|
6
6
|
import {LOCATION_PUSH, LOCATION_POP} from 'redux-location-state/lib/constants';
|
|
7
7
|
import {getMatchingDeclaredPath} from 'redux-location-state/lib/helpers';
|
|
8
8
|
|
|
9
|
-
import {initialState as initialSettingsState} from './reducers/settings';
|
|
9
|
+
import {initialState as initialSettingsState} from './reducers/settings/settings';
|
|
10
10
|
import {initialState as initialHeatmapState} from './reducers/heatmap';
|
|
11
11
|
|
|
12
12
|
const paramSetup = {
|
package/dist/utils/constants.ts
CHANGED
|
@@ -75,11 +75,6 @@ export const COLORS_PRIORITY = {
|
|
|
75
75
|
grey: 1,
|
|
76
76
|
};
|
|
77
77
|
|
|
78
|
-
export const ALL = 'All';
|
|
79
|
-
export const PROBLEMS = 'With problems';
|
|
80
|
-
|
|
81
|
-
export type IProblemFilterValues = typeof ALL | typeof PROBLEMS;
|
|
82
|
-
|
|
83
78
|
export const THEME_KEY = 'theme';
|
|
84
79
|
export const INVERTED_DISKS_KEY = 'invertedDisks';
|
|
85
80
|
export const USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY = 'useNodesEndpointInDiagnostics';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {useCallback} from 'react';
|
|
2
2
|
import {useDispatch} from 'react-redux';
|
|
3
3
|
|
|
4
|
-
import {getParsedSettingValue, setSettingValue} from '../../store/reducers/settings';
|
|
4
|
+
import {getParsedSettingValue, setSettingValue} from '../../store/reducers/settings/settings';
|
|
5
5
|
|
|
6
6
|
import {useTypedSelector} from './useTypedSelector';
|
|
7
7
|
|