ydb-embedded-ui 4.7.0 → 4.8.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.
- package/CHANGELOG.md +14 -0
- package/dist/containers/AsideNavigation/AsideNavigation.tsx +63 -23
- package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +3 -13
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +2 -7
- package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx +9 -9
- package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +3 -3
- package/dist/containers/Tenant/Query/QueryEditor/QueryEditor.js +13 -1
- package/dist/containers/Tenant/Tenant.scss +0 -8
- package/dist/containers/Tenant/Tenant.tsx +22 -28
- package/dist/containers/Tenant/TenantPages.tsx +0 -15
- package/dist/containers/Tenant/utils/schemaActions.ts +4 -4
- package/dist/containers/Tenants/Tenants.js +3 -11
- package/dist/routes.ts +11 -6
- package/dist/store/reducers/executeQuery.ts +17 -3
- package/dist/store/reducers/settings/settings.ts +7 -2
- package/dist/store/reducers/tenant/constants.ts +3 -1
- package/dist/store/reducers/tenant/tenant.ts +4 -4
- package/dist/store/reducers/tenant/types.ts +6 -9
- package/dist/store/state-url-mapping.js +2 -2
- package/dist/types/store/executeQuery.ts +4 -1
- package/dist/utils/constants.ts +3 -1
- package/package.json +1 -1
- package/dist/containers/Tenant/ObjectGeneralTabs/ObjectGeneralTabs.scss +0 -9
- package/dist/containers/Tenant/ObjectGeneralTabs/ObjectGeneralTabs.tsx +0 -68
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [4.8.1](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.8.0...v4.8.1) (2023-06-26)
|
4
|
+
|
5
|
+
|
6
|
+
### Bug Fixes
|
7
|
+
|
8
|
+
* **Tenants:** fix tenant link ([#439](https://github.com/ydb-platform/ydb-embedded-ui/issues/439)) ([432c621](https://github.com/ydb-platform/ydb-embedded-ui/commit/432c621eb2fb2ffd5a747299af930236d5cc06f7))
|
9
|
+
|
10
|
+
## [4.8.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.7.0...v4.8.0) (2023-06-26)
|
11
|
+
|
12
|
+
|
13
|
+
### Features
|
14
|
+
|
15
|
+
* **Tenant:** transform general tabs into left navigation items ([#431](https://github.com/ydb-platform/ydb-embedded-ui/issues/431)) ([7117b96](https://github.com/ydb-platform/ydb-embedded-ui/commit/7117b9622d5f6469dcc2bcc1c0d5cb71d4f94c0b))
|
16
|
+
|
3
17
|
## [4.7.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.6.0...v4.7.0) (2023-06-23)
|
4
18
|
|
5
19
|
|
@@ -7,6 +7,9 @@ import cn from 'bem-cn-lite';
|
|
7
7
|
import {Icon, Button} from '@gravity-ui/uikit';
|
8
8
|
import {AsideHeader, MenuItem as AsideHeaderMenuItem, FooterItem} from '@gravity-ui/navigation';
|
9
9
|
|
10
|
+
import squareChartBarIcon from '@gravity-ui/icons/svgs/square-chart-bar.svg';
|
11
|
+
import pulseIcon from '@gravity-ui/icons/svgs/pulse.svg';
|
12
|
+
|
10
13
|
import signOutIcon from '../../assets/icons/signOut.svg';
|
11
14
|
import signInIcon from '../../assets/icons/signIn.svg';
|
12
15
|
import ydbLogoIcon from '../../assets/icons/ydb.svg';
|
@@ -15,18 +18,20 @@ import userChecked from '../../assets/icons/user-check.svg';
|
|
15
18
|
import settingsIcon from '../../assets/icons/settings.svg';
|
16
19
|
import supportIcon from '../../assets/icons/support.svg';
|
17
20
|
|
18
|
-
import {UserSettings} from '../UserSettings/UserSettings';
|
19
|
-
|
20
|
-
import routes, {createHref} from '../../routes';
|
21
|
-
|
22
21
|
import {logout} from '../../store/reducers/authentication';
|
23
22
|
import {getParsedSettingValue, setSettingValue} from '../../store/reducers/settings/settings';
|
23
|
+
import {TENANT_PAGE, TENANT_PAGES_IDS} from '../../store/reducers/tenant/constants';
|
24
|
+
import routes, {TENANT, createHref, parseQuery} from '../../routes';
|
25
|
+
import {useSetting, useTypedSelector} from '../../utils/hooks';
|
26
|
+
import {ASIDE_HEADER_COMPACT_KEY, TENANT_INITIAL_PAGE_KEY} from '../../utils/constants';
|
24
27
|
|
25
|
-
import {
|
28
|
+
import {getTenantPath} from '../Tenant/TenantPages';
|
29
|
+
import {UserSettings} from '../UserSettings/UserSettings';
|
26
30
|
|
27
31
|
import './AsideNavigation.scss';
|
28
32
|
|
29
33
|
const b = cn('kv-navigation');
|
34
|
+
|
30
35
|
interface MenuItem {
|
31
36
|
id: string;
|
32
37
|
title: string;
|
@@ -111,32 +116,53 @@ interface AsideNavigationProps {
|
|
111
116
|
setSettingValue: (name: string, value: string) => void;
|
112
117
|
}
|
113
118
|
|
114
|
-
// FIXME: add items or delete
|
115
|
-
const items: MenuItem[] = [];
|
116
|
-
|
117
119
|
enum Panel {
|
118
120
|
UserSettings = 'UserSettings',
|
119
121
|
}
|
120
122
|
|
121
|
-
|
123
|
+
export const useGetLeftNavigationItems = () => {
|
122
124
|
const location = useLocation();
|
123
125
|
const history = useHistory();
|
124
126
|
|
125
|
-
const [
|
127
|
+
const [initialTenantPage, setInitialTenantPage] = useSetting<string>(TENANT_INITIAL_PAGE_KEY);
|
128
|
+
const {tenantPage = initialTenantPage} = useTypedSelector((state) => state.tenant);
|
126
129
|
|
127
|
-
const
|
128
|
-
|
129
|
-
|
130
|
+
const {pathname} = location;
|
131
|
+
const queryParams = parseQuery(location);
|
132
|
+
|
133
|
+
const isTenantPage = pathname === `/${TENANT}`;
|
130
134
|
|
131
135
|
const menuItems: AsideHeaderMenuItem[] = React.useMemo(() => {
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
136
|
+
if (!isTenantPage) {
|
137
|
+
return [];
|
138
|
+
}
|
139
|
+
|
140
|
+
const items: MenuItem[] = [
|
141
|
+
{
|
142
|
+
id: TENANT_PAGES_IDS.diagnostics,
|
143
|
+
title: 'Diagnostics',
|
144
|
+
icon: squareChartBarIcon,
|
145
|
+
iconSize: 20,
|
146
|
+
location: getTenantPath({
|
147
|
+
...queryParams,
|
148
|
+
[TENANT_PAGE]: TENANT_PAGES_IDS.diagnostics,
|
149
|
+
}),
|
150
|
+
},
|
151
|
+
{
|
152
|
+
id: TENANT_PAGES_IDS.query,
|
153
|
+
title: 'Query',
|
154
|
+
icon: pulseIcon,
|
155
|
+
iconSize: 20,
|
156
|
+
location: getTenantPath({
|
157
|
+
...queryParams,
|
158
|
+
[TENANT_PAGE]: TENANT_PAGES_IDS.query,
|
159
|
+
}),
|
160
|
+
},
|
161
|
+
];
|
162
|
+
|
163
|
+
return items.map((item) => {
|
164
|
+
const current = item.id === tenantPage;
|
165
|
+
|
140
166
|
return {
|
141
167
|
id: item.id,
|
142
168
|
title: item.title,
|
@@ -144,12 +170,26 @@ function AsideNavigation(props: AsideNavigationProps) {
|
|
144
170
|
iconSize: item.iconSize,
|
145
171
|
current,
|
146
172
|
onItemClick: () => {
|
173
|
+
setInitialTenantPage(item.id);
|
147
174
|
history.push(item.location);
|
148
175
|
},
|
149
176
|
};
|
150
177
|
});
|
151
|
-
|
152
|
-
|
178
|
+
}, [tenantPage, isTenantPage, setInitialTenantPage, history, queryParams]);
|
179
|
+
|
180
|
+
return menuItems;
|
181
|
+
};
|
182
|
+
|
183
|
+
function AsideNavigation(props: AsideNavigationProps) {
|
184
|
+
const history = useHistory();
|
185
|
+
|
186
|
+
const [visiblePanel, setVisiblePanel] = useState<Panel>();
|
187
|
+
|
188
|
+
const setIsCompact = (compact: boolean) => {
|
189
|
+
props.setSettingValue(ASIDE_HEADER_COMPACT_KEY, JSON.stringify(compact));
|
190
|
+
};
|
191
|
+
|
192
|
+
const menuItems = useGetLeftNavigationItems();
|
153
193
|
|
154
194
|
return (
|
155
195
|
<React.Fragment>
|
@@ -11,9 +11,9 @@ import type {EPathType} from '../../../types/api/schema';
|
|
11
11
|
|
12
12
|
import {useTypedSelector} from '../../../utils/hooks';
|
13
13
|
import routes, {createHref} from '../../../routes';
|
14
|
-
import type {TenantDiagnosticsTab
|
14
|
+
import type {TenantDiagnosticsTab} from '../../../store/reducers/tenant/types';
|
15
15
|
import {enableAutorefresh, disableAutorefresh} from '../../../store/reducers/schema/schema';
|
16
|
-
import {
|
16
|
+
import { setDiagnosticsTab} from '../../../store/reducers/tenant/tenant';
|
17
17
|
import {TENANT_DIAGNOSTICS_TABS_IDS} from '../../../store/reducers/tenant/constants';
|
18
18
|
|
19
19
|
import {Loader} from '../../../components/Loader';
|
@@ -96,10 +96,6 @@ function Diagnostics(props: DiagnosticsProps) {
|
|
96
96
|
}
|
97
97
|
};
|
98
98
|
|
99
|
-
const forwardToGeneralTab = (tab: TenantGeneralTab) => {
|
100
|
-
dispatch(setTopLevelTab(tab));
|
101
|
-
};
|
102
|
-
|
103
99
|
const renderTabContent = () => {
|
104
100
|
const {type} = props;
|
105
101
|
|
@@ -116,13 +112,7 @@ function Diagnostics(props: DiagnosticsProps) {
|
|
116
112
|
);
|
117
113
|
}
|
118
114
|
case TENANT_DIAGNOSTICS_TABS_IDS.topQueries: {
|
119
|
-
return
|
120
|
-
<TopQueries
|
121
|
-
path={tenantNameString}
|
122
|
-
changeSchemaTab={forwardToGeneralTab}
|
123
|
-
type={type}
|
124
|
-
/>
|
125
|
-
);
|
115
|
+
return <TopQueries path={tenantNameString} type={type} />;
|
126
116
|
}
|
127
117
|
case TENANT_DIAGNOSTICS_TABS_IDS.topShards: {
|
128
118
|
return <TopShards tenantPath={tenantNameString} type={type} />;
|
@@ -22,12 +22,8 @@ import type {KeyValueRow} from '../../../../types/api/query';
|
|
22
22
|
import type {EPathType} from '../../../../types/api/schema';
|
23
23
|
import type {ITopQueriesFilters} from '../../../../types/store/executeTopQueries';
|
24
24
|
import type {IQueryResult} from '../../../../types/store/query';
|
25
|
-
import type {TenantGeneralTab} from '../../../../store/reducers/tenant/types';
|
26
25
|
|
27
|
-
import {
|
28
|
-
TENANT_GENERAL_TABS_IDS,
|
29
|
-
TENANT_QUERY_TABS_ID,
|
30
|
-
} from '../../../../store/reducers/tenant/constants';
|
26
|
+
import {TENANT_PAGE, TENANT_PAGES_IDS, TENANT_QUERY_TABS_ID} from '../../../../store/reducers/tenant/constants';
|
31
27
|
import {formatDateTime, formatNumber} from '../../../../utils';
|
32
28
|
import {HOUR_IN_SECONDS} from '../../../../utils/constants';
|
33
29
|
import {useAutofetcher, useTypedSelector} from '../../../../utils/hooks';
|
@@ -85,7 +81,6 @@ const COLUMNS: Column<KeyValueRow>[] = [
|
|
85
81
|
|
86
82
|
interface TopQueriesProps {
|
87
83
|
path: string;
|
88
|
-
changeSchemaTab: (tab: TenantGeneralTab) => void;
|
89
84
|
type?: EPathType;
|
90
85
|
}
|
91
86
|
|
@@ -177,7 +172,7 @@ export const TopQueries = ({path, type}: TopQueriesProps) => {
|
|
177
172
|
|
178
173
|
const queryPath = getTenantPath({
|
179
174
|
...queryParams,
|
180
|
-
[
|
175
|
+
[TENANT_PAGE]: TENANT_PAGES_IDS.query,
|
181
176
|
[TenantTabsGroups.queryTab]: TENANT_QUERY_TABS_ID.newQuery,
|
182
177
|
});
|
183
178
|
|
@@ -1,11 +1,13 @@
|
|
1
|
-
import qs from 'qs';
|
2
1
|
import {useLocation} from 'react-router';
|
3
2
|
import cn from 'bem-cn-lite';
|
4
3
|
|
5
4
|
import {useThemeValue} from '@gravity-ui/uikit';
|
6
5
|
|
7
6
|
import type {EPathType} from '../../../types/api/schema';
|
8
|
-
import {
|
7
|
+
import {TENANT_PAGES_IDS} from '../../../store/reducers/tenant/constants';
|
8
|
+
import {useSetting} from '../../../utils/hooks';
|
9
|
+
import {TENANT_INITIAL_PAGE_KEY} from '../../../utils/constants';
|
10
|
+
import {parseQuery} from '../../../routes';
|
9
11
|
|
10
12
|
import {Query} from '../Query/Query';
|
11
13
|
import Diagnostics from '../Diagnostics/Diagnostics';
|
@@ -22,19 +24,17 @@ interface ObjectGeneralProps {
|
|
22
24
|
|
23
25
|
function ObjectGeneral(props: ObjectGeneralProps) {
|
24
26
|
const location = useLocation();
|
25
|
-
|
26
27
|
const theme = useThemeValue();
|
27
28
|
|
28
|
-
const
|
29
|
-
ignoreQueryPrefix: true,
|
30
|
-
});
|
29
|
+
const [initialPage] = useSetting<string>(TENANT_INITIAL_PAGE_KEY);
|
31
30
|
|
32
|
-
const
|
31
|
+
const queryParams = parseQuery(location);
|
32
|
+
const {name: tenantName, tenantPage = initialPage} = queryParams;
|
33
33
|
|
34
34
|
const renderTabContent = () => {
|
35
35
|
const {type, additionalTenantInfo, additionalNodesInfo} = props;
|
36
|
-
switch (
|
37
|
-
case
|
36
|
+
switch (tenantPage) {
|
37
|
+
case TENANT_PAGES_IDS.query: {
|
38
38
|
return <Query path={tenantName as string} theme={theme} type={type} />;
|
39
39
|
}
|
40
40
|
default: {
|
@@ -47,9 +47,9 @@ import {
|
|
47
47
|
PaneVisibilityToggleButtons,
|
48
48
|
} from '../utils/paneVisibilityToggleHelpers';
|
49
49
|
import {setShowPreview} from '../../../store/reducers/schema/schema';
|
50
|
-
import {setQueryTab,
|
50
|
+
import {setQueryTab, setTenantPage} from '../../../store/reducers/tenant/tenant';
|
51
51
|
import {
|
52
|
-
|
52
|
+
TENANT_PAGES_IDS,
|
53
53
|
TENANT_QUERY_TABS_ID,
|
54
54
|
} from '../../../store/reducers/tenant/constants';
|
55
55
|
|
@@ -278,7 +278,7 @@ function ObjectSummary(props: ObjectSummaryProps) {
|
|
278
278
|
|
279
279
|
const onOpenPreview = () => {
|
280
280
|
dispatch(setShowPreview(true));
|
281
|
-
dispatch(
|
281
|
+
dispatch(setTenantPage(TENANT_PAGES_IDS.query));
|
282
282
|
dispatch(setQueryTab(TENANT_QUERY_TABS_ID.newQuery));
|
283
283
|
};
|
284
284
|
|
@@ -15,6 +15,7 @@ import {
|
|
15
15
|
goToNextQuery,
|
16
16
|
MONACO_HOT_KEY_ACTIONS,
|
17
17
|
setMonacoHotKey,
|
18
|
+
setTenantPath,
|
18
19
|
} from '../../../../store/reducers/executeQuery';
|
19
20
|
import {getExplainQuery, getExplainQueryAst} from '../../../../store/reducers/explainQuery';
|
20
21
|
import {getParsedSettingValue, setSettingValue} from '../../../../store/reducers/settings/settings';
|
@@ -75,6 +76,7 @@ const propTypes = {
|
|
75
76
|
theme: PropTypes.string,
|
76
77
|
type: PropTypes.string,
|
77
78
|
initialQueryMode: PropTypes.string,
|
79
|
+
setTenantPath: PropTypes.func,
|
78
80
|
};
|
79
81
|
|
80
82
|
const initialTenantCommonInfoState = {
|
@@ -83,6 +85,9 @@ const initialTenantCommonInfoState = {
|
|
83
85
|
collapsed: true,
|
84
86
|
};
|
85
87
|
function QueryEditor(props) {
|
88
|
+
const {path, executeQuery, theme, setTenantPath, changeUserInput} = props;
|
89
|
+
const {tenantPath: savedPath} = executeQuery;
|
90
|
+
|
86
91
|
const [resultType, setResultType] = useState(RESULT_TYPES.EXECUTE);
|
87
92
|
|
88
93
|
const [isResultLoaded, setIsResultLoaded] = useState(false);
|
@@ -96,6 +101,13 @@ function QueryEditor(props) {
|
|
96
101
|
}
|
97
102
|
}, [enableAdditionalQueryModes, queryMode, setQueryMode]);
|
98
103
|
|
104
|
+
useEffect(() => {
|
105
|
+
if (savedPath !== path) {
|
106
|
+
setTenantPath(path);
|
107
|
+
changeUserInput({input: ''});
|
108
|
+
}
|
109
|
+
}, [changeUserInput, setTenantPath, path, savedPath]);
|
110
|
+
|
99
111
|
const [resultVisibilityState, dispatchResultVisibilityState] = useReducer(
|
100
112
|
paneVisibilityToggleReducerCreator(DEFAULT_IS_QUERY_RESULT_COLLAPSED),
|
101
113
|
initialTenantCommonInfoState,
|
@@ -507,7 +519,6 @@ function QueryEditor(props) {
|
|
507
519
|
);
|
508
520
|
};
|
509
521
|
|
510
|
-
const {executeQuery, theme} = props;
|
511
522
|
const result = renderResult();
|
512
523
|
|
513
524
|
return (
|
@@ -569,6 +580,7 @@ const mapDispatchToProps = {
|
|
569
580
|
setSettingValue,
|
570
581
|
setShowPreview,
|
571
582
|
setMonacoHotKey,
|
583
|
+
setTenantPath,
|
572
584
|
};
|
573
585
|
|
574
586
|
QueryEditor.propTypes = propTypes;
|
@@ -15,7 +15,6 @@ import {getSchemaAcl} from '../../store/reducers/schemaAcl/schemaAcl';
|
|
15
15
|
import SplitPane from '../../components/SplitPane';
|
16
16
|
import {AccessDenied} from '../../components/Errors/403';
|
17
17
|
|
18
|
-
import ObjectGeneralTabs from './ObjectGeneralTabs/ObjectGeneralTabs';
|
19
18
|
import ObjectSummary from './ObjectSummary/ObjectSummary';
|
20
19
|
import ObjectGeneral from './ObjectGeneral/ObjectGeneral';
|
21
20
|
|
@@ -111,33 +110,28 @@ function Tenant(props: TenantProps) {
|
|
111
110
|
{showBlockingError ? (
|
112
111
|
<AccessDenied />
|
113
112
|
) : (
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
additionalNodesInfo={props.additionalNodesInfo}
|
137
|
-
/>
|
138
|
-
</SplitPane>
|
139
|
-
</div>
|
140
|
-
</>
|
113
|
+
<SplitPane
|
114
|
+
defaultSizePaneKey={DEFAULT_SIZE_TENANT_KEY}
|
115
|
+
defaultSizes={[25, 75]}
|
116
|
+
triggerCollapse={summaryVisibilityState.triggerCollapse}
|
117
|
+
triggerExpand={summaryVisibilityState.triggerExpand}
|
118
|
+
minSize={[36, 200]}
|
119
|
+
onSplitStartDragAdditional={onSplitStartDragAdditional}
|
120
|
+
>
|
121
|
+
<ObjectSummary
|
122
|
+
type={preloadedPathType || currentPathType}
|
123
|
+
subType={preloadedPathSubType || currentPathSubType}
|
124
|
+
onCollapseSummary={onCollapseSummaryHandler}
|
125
|
+
onExpandSummary={onExpandSummaryHandler}
|
126
|
+
isCollapsed={summaryVisibilityState.collapsed}
|
127
|
+
additionalTenantInfo={props.additionalTenantInfo}
|
128
|
+
/>
|
129
|
+
<ObjectGeneral
|
130
|
+
type={preloadedPathType || currentPathType}
|
131
|
+
additionalTenantInfo={props.additionalTenantInfo}
|
132
|
+
additionalNodesInfo={props.additionalNodesInfo}
|
133
|
+
/>
|
134
|
+
</SplitPane>
|
141
135
|
)}
|
142
136
|
</div>
|
143
137
|
);
|
@@ -1,6 +1,4 @@
|
|
1
|
-
import {TENANT_GENERAL_TABS_IDS} from '../../store/reducers/tenant/constants';
|
2
1
|
import routes, {createHref} from '../../routes';
|
3
|
-
import {Icon} from '../../components/Icon';
|
4
2
|
|
5
3
|
export enum TenantInfoTabsIds {
|
6
4
|
overview = 'overview',
|
@@ -10,23 +8,10 @@ export enum TenantInfoTabsIds {
|
|
10
8
|
|
11
9
|
export enum TenantTabsGroups {
|
12
10
|
info = 'info',
|
13
|
-
general = 'general',
|
14
11
|
queryTab = 'queryTab',
|
15
12
|
diagnosticsTab = 'diagnosticsTab',
|
16
13
|
}
|
17
14
|
|
18
|
-
export const TENANT_GENERAL_TABS = [
|
19
|
-
{
|
20
|
-
id: TENANT_GENERAL_TABS_IDS.query,
|
21
|
-
title: 'Query',
|
22
|
-
icon: <Icon name="query" viewBox="0 0 16 16" />,
|
23
|
-
},
|
24
|
-
{
|
25
|
-
id: TENANT_GENERAL_TABS_IDS.diagnostics,
|
26
|
-
title: 'Diagnostics',
|
27
|
-
icon: <Icon name="diagnostics" viewBox="0 0 17 16" />,
|
28
|
-
},
|
29
|
-
];
|
30
15
|
export const TENANT_INFO_TABS = [
|
31
16
|
{
|
32
17
|
id: TenantInfoTabsIds.overview,
|
@@ -3,10 +3,10 @@ import type {NavigationTreeNodeType, NavigationTreeProps} from 'ydb-ui-component
|
|
3
3
|
|
4
4
|
import {changeUserInput} from '../../../store/reducers/executeQuery';
|
5
5
|
import {setShowPreview} from '../../../store/reducers/schema/schema';
|
6
|
-
import {setQueryTab,
|
6
|
+
import {setQueryTab, setTenantPage} from '../../../store/reducers/tenant/tenant';
|
7
7
|
import {
|
8
8
|
TENANT_QUERY_TABS_ID,
|
9
|
-
|
9
|
+
TENANT_PAGES_IDS,
|
10
10
|
} from '../../../store/reducers/tenant/constants';
|
11
11
|
import createToast from '../../../utils/createToast';
|
12
12
|
|
@@ -40,7 +40,7 @@ const bindActions = (
|
|
40
40
|
) => {
|
41
41
|
const inputQuery = (tmpl: (path: string) => string) => () => {
|
42
42
|
dispatch(changeUserInput({input: tmpl(path)}));
|
43
|
-
dispatch(
|
43
|
+
dispatch(setTenantPage(TENANT_PAGES_IDS.query));
|
44
44
|
dispatch(setQueryTab(TENANT_QUERY_TABS_ID.newQuery));
|
45
45
|
setActivePath(path);
|
46
46
|
};
|
@@ -70,7 +70,7 @@ const bindActions = (
|
|
70
70
|
},
|
71
71
|
openPreview: () => {
|
72
72
|
dispatch(setShowPreview(true));
|
73
|
-
dispatch(
|
73
|
+
dispatch(setTenantPage(TENANT_PAGES_IDS.query));
|
74
74
|
dispatch(setQueryTab(TENANT_QUERY_TABS_ID.newQuery));
|
75
75
|
setActivePath(path);
|
76
76
|
},
|
@@ -18,16 +18,12 @@ import {AutoFetcher} from '../../utils/autofetcher';
|
|
18
18
|
import routes, {createHref} from '../../routes';
|
19
19
|
import {formatCPU, formatBytesToGigabyte, formatNumber} from '../../utils';
|
20
20
|
import {withSearch} from '../../HOCS';
|
21
|
-
import {DEFAULT_TABLE_SETTINGS
|
21
|
+
import {DEFAULT_TABLE_SETTINGS} from '../../utils/constants';
|
22
22
|
import {getTenantsInfo} from '../../store/reducers/tenants/tenants';
|
23
|
-
import {
|
24
|
-
changeFilter,
|
25
|
-
getSettingValue,
|
26
|
-
ProblemFilterValues,
|
27
|
-
} from '../../store/reducers/settings/settings';
|
23
|
+
import {changeFilter, ProblemFilterValues} from '../../store/reducers/settings/settings';
|
28
24
|
|
29
25
|
import {clusterName} from '../../store';
|
30
|
-
import {TenantTabsGroups,
|
26
|
+
import {TenantTabsGroups, TENANT_INFO_TABS} from '../Tenant/TenantPages';
|
31
27
|
|
32
28
|
import './Tenants.scss';
|
33
29
|
|
@@ -114,7 +110,6 @@ class Tenants extends React.Component {
|
|
114
110
|
filter,
|
115
111
|
handleSearchQuery,
|
116
112
|
additionalTenantsInfo = {},
|
117
|
-
savedTenantInitialTab,
|
118
113
|
} = this.props;
|
119
114
|
|
120
115
|
const filteredTenantsBySearch = tenants.filter((item) => {
|
@@ -123,7 +118,6 @@ class Tenants extends React.Component {
|
|
123
118
|
});
|
124
119
|
const filteredTenants = Tenants.filterTenants(filteredTenantsBySearch, filter);
|
125
120
|
|
126
|
-
const initialTenantGeneralTab = savedTenantInitialTab || TENANT_GENERAL_TABS[0].id;
|
127
121
|
const initialTenantInfoTab = TENANT_INFO_TABS[0].id;
|
128
122
|
|
129
123
|
const getTenantBackend = (tenant) => {
|
@@ -153,7 +147,6 @@ class Tenants extends React.Component {
|
|
153
147
|
name: value,
|
154
148
|
backend,
|
155
149
|
[TenantTabsGroups.info]: initialTenantInfoTab,
|
156
|
-
[TenantTabsGroups.general]: initialTenantGeneralTab,
|
157
150
|
})}
|
158
151
|
/>
|
159
152
|
{additionalTenantsInfo.name && additionalTenantsInfo.name(value, row)}
|
@@ -359,7 +352,6 @@ const mapStateToProps = (state) => {
|
|
359
352
|
loading,
|
360
353
|
error,
|
361
354
|
filter: state.settings.problemFilter,
|
362
|
-
savedTenantInitialTab: getSettingValue(state, TENANT_INITIAL_TAB_KEY),
|
363
355
|
};
|
364
356
|
};
|
365
357
|
|
package/dist/routes.ts
CHANGED
@@ -5,13 +5,18 @@ import isEmpty from 'lodash/isEmpty';
|
|
5
5
|
|
6
6
|
import {backend, clusterName, webVersion} from './store';
|
7
7
|
|
8
|
+
export const CLUSTER = 'cluster';
|
9
|
+
export const TENANT = 'tenant';
|
10
|
+
export const NODE = 'node';
|
11
|
+
export const TABLET = 'tablet';
|
12
|
+
|
8
13
|
const routes = {
|
9
|
-
cluster:
|
10
|
-
tenant:
|
11
|
-
node:
|
12
|
-
tablet:
|
13
|
-
tabletsFilters:
|
14
|
-
auth:
|
14
|
+
cluster: `/${CLUSTER}/:activeTab?`,
|
15
|
+
tenant: `/${TENANT}`,
|
16
|
+
node: `/${NODE}/:id/:activeTab?`,
|
17
|
+
tablet: `/${TABLET}/:id`,
|
18
|
+
tabletsFilters: `/tabletsFilters`,
|
19
|
+
auth: `/auth`,
|
15
20
|
};
|
16
21
|
|
17
22
|
export const parseQuery = (location: Location) => {
|
@@ -23,7 +23,8 @@ const CHANGE_USER_INPUT = 'query/CHANGE_USER_INPUT';
|
|
23
23
|
const SAVE_QUERY_TO_HISTORY = 'query/SAVE_QUERY_TO_HISTORY';
|
24
24
|
const GO_TO_PREVIOUS_QUERY = 'query/GO_TO_PREVIOUS_QUERY';
|
25
25
|
const GO_TO_NEXT_QUERY = 'query/GO_TO_NEXT_QUERY';
|
26
|
-
const
|
26
|
+
const SET_MONACO_HOT_KEY = 'query/SET_MONACO_HOT_KEY';
|
27
|
+
const SET_TENANT_PATH = 'query/SET_TENANT_PATH';
|
27
28
|
|
28
29
|
const queriesHistoryInitial: string[] = parseJson(getValueFromLS(QUERIES_HISTORY_KEY, '[]'));
|
29
30
|
|
@@ -128,12 +129,18 @@ const executeQuery: Reducer<ExecuteQueryState, ExecuteQueryAction> = (
|
|
128
129
|
};
|
129
130
|
}
|
130
131
|
|
131
|
-
case
|
132
|
+
case SET_MONACO_HOT_KEY: {
|
132
133
|
return {
|
133
134
|
...state,
|
134
135
|
monacoHotKey: action.data,
|
135
136
|
};
|
136
137
|
}
|
138
|
+
case SET_TENANT_PATH: {
|
139
|
+
return {
|
140
|
+
...state,
|
141
|
+
tenantPath: action.data,
|
142
|
+
};
|
143
|
+
}
|
137
144
|
|
138
145
|
default:
|
139
146
|
return state;
|
@@ -188,7 +195,14 @@ export const changeUserInput = ({input}: {input: string}) => {
|
|
188
195
|
|
189
196
|
export const setMonacoHotKey = (value: MonacoHotKeyAction | null) => {
|
190
197
|
return {
|
191
|
-
type:
|
198
|
+
type: SET_MONACO_HOT_KEY,
|
199
|
+
data: value,
|
200
|
+
} as const;
|
201
|
+
};
|
202
|
+
|
203
|
+
export const setTenantPath = (value: string) => {
|
204
|
+
return {
|
205
|
+
type: SET_TENANT_PATH,
|
192
206
|
data: value,
|
193
207
|
} as const;
|
194
208
|
};
|
@@ -5,7 +5,7 @@ import type {ValueOf} from '../../../types/common';
|
|
5
5
|
import {
|
6
6
|
SAVED_QUERIES_KEY,
|
7
7
|
THEME_KEY,
|
8
|
-
|
8
|
+
TENANT_INITIAL_PAGE_KEY,
|
9
9
|
INVERTED_DISKS_KEY,
|
10
10
|
ASIDE_HEADER_COMPACT_KEY,
|
11
11
|
USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
|
@@ -18,6 +18,8 @@ import '../../../services/api';
|
|
18
18
|
import {getValueFromLS, parseJson} from '../../../utils/utils';
|
19
19
|
import {QueryModes} from '../../../types/store/query';
|
20
20
|
|
21
|
+
import {TENANT_PAGES_IDS} from '../tenant/constants';
|
22
|
+
|
21
23
|
import type {RootState} from '..';
|
22
24
|
import type {
|
23
25
|
SetSettingValueAction,
|
@@ -58,7 +60,10 @@ export const initialState = {
|
|
58
60
|
'false',
|
59
61
|
),
|
60
62
|
[SAVED_QUERIES_KEY]: readSavedSettingsValue(SAVED_QUERIES_KEY, '[]'),
|
61
|
-
[
|
63
|
+
[TENANT_INITIAL_PAGE_KEY]: readSavedSettingsValue(
|
64
|
+
TENANT_INITIAL_PAGE_KEY,
|
65
|
+
TENANT_PAGES_IDS.query,
|
66
|
+
),
|
62
67
|
[QUERY_INITIAL_MODE_KEY]: readSavedSettingsValue(QUERY_INITIAL_MODE_KEY, QueryModes.script),
|
63
68
|
[ASIDE_HEADER_COMPACT_KEY]: readSavedSettingsValue(ASIDE_HEADER_COMPACT_KEY, 'true'),
|
64
69
|
[PARTITIONS_HIDDEN_COLUMNS_KEY]: readSavedSettingsValue(PARTITIONS_HIDDEN_COLUMNS_KEY),
|
@@ -4,7 +4,7 @@ import type {TTenant} from '../../../types/api/tenant';
|
|
4
4
|
import type {
|
5
5
|
TenantAction,
|
6
6
|
TenantDiagnosticsTab,
|
7
|
-
|
7
|
+
TenantPage,
|
8
8
|
TenantQueryTab,
|
9
9
|
TenantState,
|
10
10
|
} from './types';
|
@@ -60,7 +60,7 @@ const tenantReducer: Reducer<TenantState, TenantAction> = (state = initialState,
|
|
60
60
|
case SET_TOP_LEVEL_TAB: {
|
61
61
|
return {
|
62
62
|
...state,
|
63
|
-
|
63
|
+
tenantPage: action.data,
|
64
64
|
};
|
65
65
|
}
|
66
66
|
case SET_QUERY_TAB: {
|
@@ -95,10 +95,10 @@ export const clearTenant = () => {
|
|
95
95
|
return {type: CLEAR_TENANT} as const;
|
96
96
|
};
|
97
97
|
|
98
|
-
export function
|
98
|
+
export function setTenantPage(page: TenantPage) {
|
99
99
|
return {
|
100
100
|
type: SET_TOP_LEVEL_TAB,
|
101
|
-
data:
|
101
|
+
data: page,
|
102
102
|
} as const;
|
103
103
|
}
|
104
104
|
|
@@ -3,21 +3,18 @@ import type {TTenant} from '../../../types/api/tenant';
|
|
3
3
|
import type {ValueOf} from '../../../types/common';
|
4
4
|
import type {ApiRequestAction} from '../../utils';
|
5
5
|
|
6
|
-
import {
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
} from './constants';
|
11
|
-
import {FETCH_TENANT, clearTenant, setDiagnosticsTab, setQueryTab, setTopLevelTab} from './tenant';
|
6
|
+
import {TENANT_QUERY_TABS_ID, TENANT_DIAGNOSTICS_TABS_IDS, TENANT_PAGES_IDS} from './constants';
|
7
|
+
import {FETCH_TENANT, clearTenant, setDiagnosticsTab, setQueryTab, setTenantPage} from './tenant';
|
8
|
+
|
9
|
+
export type TenantPage = ValueOf<typeof TENANT_PAGES_IDS>;
|
12
10
|
|
13
|
-
export type TenantGeneralTab = ValueOf<typeof TENANT_GENERAL_TABS_IDS>;
|
14
11
|
export type TenantQueryTab = ValueOf<typeof TENANT_QUERY_TABS_ID>;
|
15
12
|
export type TenantDiagnosticsTab = ValueOf<typeof TENANT_DIAGNOSTICS_TABS_IDS>;
|
16
13
|
|
17
14
|
export interface TenantState {
|
18
15
|
loading: boolean;
|
19
16
|
wasLoaded: boolean;
|
20
|
-
|
17
|
+
tenantPage?: TenantPage;
|
21
18
|
queryTab?: TenantQueryTab;
|
22
19
|
diagnosticsTab?: TenantDiagnosticsTab;
|
23
20
|
tenant?: TTenant;
|
@@ -27,6 +24,6 @@ export interface TenantState {
|
|
27
24
|
export type TenantAction =
|
28
25
|
| ApiRequestAction<typeof FETCH_TENANT, TTenant | undefined, IResponseError>
|
29
26
|
| ReturnType<typeof clearTenant>
|
30
|
-
| ReturnType<typeof
|
27
|
+
| ReturnType<typeof setTenantPage>
|
31
28
|
| ReturnType<typeof setQueryTab>
|
32
29
|
| ReturnType<typeof setDiagnosticsTab>;
|
@@ -5,6 +5,7 @@ import {
|
|
5
5
|
goToPreviousQuery,
|
6
6
|
setMonacoHotKey,
|
7
7
|
goToNextQuery,
|
8
|
+
setTenantPath,
|
8
9
|
MONACO_HOT_KEY_ACTIONS,
|
9
10
|
} from '../../store/reducers/executeQuery';
|
10
11
|
import type {ApiRequestAction} from '../../store/utils';
|
@@ -22,6 +23,7 @@ export interface ExecuteQueryState {
|
|
22
23
|
currentIndex: number;
|
23
24
|
};
|
24
25
|
monacoHotKey: null | MonacoHotKeyAction;
|
26
|
+
tenantPath?: string;
|
25
27
|
data?: IQueryResult;
|
26
28
|
stats?: IQueryResult['stats'];
|
27
29
|
error?: string | ErrorResponse;
|
@@ -35,4 +37,5 @@ export type ExecuteQueryAction =
|
|
35
37
|
| ReturnType<typeof goToPreviousQuery>
|
36
38
|
| ReturnType<typeof changeUserInput>
|
37
39
|
| ReturnType<typeof saveQueryToHistory>
|
38
|
-
| ReturnType<typeof setMonacoHotKey
|
40
|
+
| ReturnType<typeof setMonacoHotKey>
|
41
|
+
| ReturnType<typeof setTenantPath>;
|
package/dist/utils/constants.ts
CHANGED
@@ -104,9 +104,11 @@ export const DEFAULT_TABLE_SETTINGS = {
|
|
104
104
|
highlightRows: true,
|
105
105
|
} as const;
|
106
106
|
|
107
|
-
export const TENANT_INITIAL_TAB_KEY = 'saved_tenant_initial_tab';
|
108
107
|
export const QUERY_INITIAL_MODE_KEY = 'query_initial_mode';
|
109
108
|
|
110
109
|
export const PARTITIONS_HIDDEN_COLUMNS_KEY = 'partitionsHiddenColumns';
|
111
110
|
|
112
111
|
export const CLUSTER_INFO_HIDDEN_KEY = 'clusterInfoHidden';
|
112
|
+
|
113
|
+
// Remain "tab" in key name for backward compatibility
|
114
|
+
export const TENANT_INITIAL_PAGE_KEY = 'saved_tenant_initial_tab';
|
package/package.json
CHANGED
@@ -1,68 +0,0 @@
|
|
1
|
-
import qs from 'qs';
|
2
|
-
import {connect} from 'react-redux';
|
3
|
-
import {useLocation} from 'react-router';
|
4
|
-
import {Link} from 'react-router-dom';
|
5
|
-
import cn from 'bem-cn-lite';
|
6
|
-
|
7
|
-
import {Tabs} from '@gravity-ui/uikit';
|
8
|
-
|
9
|
-
import routes, {createHref} from '../../../routes';
|
10
|
-
import {TENANT_INITIAL_TAB_KEY} from '../../../utils/constants';
|
11
|
-
import {setSettingValue} from '../../../store/reducers/settings/settings';
|
12
|
-
|
13
|
-
import {TenantTabsGroups, TENANT_GENERAL_TABS} from '../TenantPages';
|
14
|
-
|
15
|
-
import './ObjectGeneralTabs.scss';
|
16
|
-
|
17
|
-
const b = cn('object-general-tabs');
|
18
|
-
|
19
|
-
interface ObjectGeneralTabsProps {
|
20
|
-
setSettingValue: (name: string, value: string) => void;
|
21
|
-
}
|
22
|
-
|
23
|
-
function ObjectGeneralTabs(props: ObjectGeneralTabsProps) {
|
24
|
-
const location = useLocation();
|
25
|
-
|
26
|
-
const queryParams = qs.parse(location.search, {
|
27
|
-
ignoreQueryPrefix: true,
|
28
|
-
});
|
29
|
-
|
30
|
-
const {name: tenantName, general: generalTab} = queryParams;
|
31
|
-
|
32
|
-
const renderContent = () => {
|
33
|
-
if (!tenantName) {
|
34
|
-
return null;
|
35
|
-
}
|
36
|
-
return (
|
37
|
-
<div className={b()}>
|
38
|
-
<Tabs
|
39
|
-
size="xl"
|
40
|
-
items={TENANT_GENERAL_TABS}
|
41
|
-
activeTab={generalTab as string}
|
42
|
-
wrapTo={({id}, node) => {
|
43
|
-
const path = createHref(routes.tenant, undefined, {
|
44
|
-
...queryParams,
|
45
|
-
name: tenantName as string,
|
46
|
-
[TenantTabsGroups.general]: id,
|
47
|
-
});
|
48
|
-
return (
|
49
|
-
<Link to={path} key={id} className={b('tab')}>
|
50
|
-
{node}
|
51
|
-
</Link>
|
52
|
-
);
|
53
|
-
}}
|
54
|
-
allowNotSelected
|
55
|
-
onSelectTab={(id) => props.setSettingValue(TENANT_INITIAL_TAB_KEY, id)}
|
56
|
-
/>
|
57
|
-
</div>
|
58
|
-
);
|
59
|
-
};
|
60
|
-
|
61
|
-
return renderContent();
|
62
|
-
}
|
63
|
-
|
64
|
-
const mapDispatchToProps = {
|
65
|
-
setSettingValue,
|
66
|
-
};
|
67
|
-
|
68
|
-
export default connect(null, mapDispatchToProps)(ObjectGeneralTabs);
|