ydb-embedded-ui 4.6.0 → 4.8.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +27 -0
- package/dist/assets/icons/versions.svg +3 -0
- package/dist/components/NodeHostWrapper/NodeHostWrapper.tsx +6 -1
- package/dist/components/Tablet/Tablet.tsx +17 -3
- package/dist/components/TabletsStatistic/TabletsStatistic.tsx +23 -16
- package/dist/containers/App/Content.js +5 -2
- package/dist/containers/AsideNavigation/AsideNavigation.tsx +50 -18
- package/dist/containers/Cluster/Cluster.tsx +6 -13
- package/dist/containers/Cluster/ClusterInfo/ClusterInfo.tsx +3 -3
- package/dist/containers/Cluster/{utils.ts → utils.tsx} +11 -0
- package/dist/containers/Header/Header.scss +9 -0
- package/dist/containers/Header/Header.tsx +70 -14
- package/dist/containers/Header/breadcrumbs.ts +146 -0
- package/dist/containers/Node/Node.tsx +21 -27
- package/dist/containers/Node/NodePages.ts +10 -6
- package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +11 -3
- package/dist/containers/Tablet/Tablet.tsx +35 -27
- package/dist/containers/Tablet/TabletInfo/TabletInfo.tsx +2 -2
- package/dist/containers/TabletsFilters/TabletsFilters.js +13 -15
- package/dist/containers/Tenant/Diagnostics/Consumers/columns/columns.tsx +1 -1
- package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.scss +5 -1
- package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +4 -14
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.scss +5 -3
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.tsx +1 -1
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +2 -1
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +9 -16
- package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx +11 -11
- package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +7 -3
- package/dist/containers/Tenant/{QueryEditor/QueryResult/QueryResult.js → Query/ExecuteResult/ExecuteResult.js} +3 -5
- package/dist/containers/Tenant/{QueryEditor/QueryResult/QueryResult.scss → Query/ExecuteResult/ExecuteResult.scss} +1 -1
- package/dist/containers/Tenant/{QueryEditor/QueryExplain/QueryExplain.js → Query/ExplainResult/ExplainResult.js} +3 -5
- package/dist/containers/Tenant/{QueryEditor/QueryExplain/QueryExplain.scss → Query/ExplainResult/ExplainResult.scss} +1 -1
- package/dist/containers/Tenant/Query/QueriesHistory/QueriesHistory.scss +20 -0
- package/dist/containers/Tenant/Query/QueriesHistory/QueriesHistory.tsx +60 -0
- package/dist/containers/Tenant/Query/Query.scss +16 -0
- package/dist/containers/Tenant/Query/Query.tsx +73 -0
- package/dist/containers/Tenant/{QueryEditor → Query/QueryEditor}/QueryEditor.js +39 -88
- package/dist/containers/Tenant/{QueryEditor → Query/QueryEditor}/QueryEditor.scss +7 -23
- package/dist/containers/Tenant/{QueryEditor → Query}/QueryEditorControls/QueryEditorControls.scss +1 -4
- package/dist/containers/Tenant/Query/QueryTabs/QueryTabs.tsx +59 -0
- package/dist/containers/Tenant/{QueryEditor → Query}/SaveQuery/SaveQuery.js +5 -5
- package/dist/containers/Tenant/Query/SavedQueries/SavedQueries.scss +55 -0
- package/dist/containers/Tenant/Query/SavedQueries/SavedQueries.tsx +150 -0
- package/dist/containers/Tenant/Query/i18n/en.json +12 -0
- package/dist/containers/Tenant/Query/i18n/ru.json +12 -0
- package/dist/containers/Tenant/Query/utils/getPreparedResult.ts +30 -0
- package/dist/containers/Tenant/Tenant.scss +0 -8
- package/dist/containers/Tenant/Tenant.tsx +24 -46
- package/dist/containers/Tenant/TenantPages.tsx +7 -16
- package/dist/containers/Tenant/utils/constants.ts +10 -0
- package/dist/containers/Tenant/utils/schemaActions.ts +9 -4
- package/dist/containers/Tenants/Tenants.js +26 -13
- package/dist/routes.ts +21 -7
- package/dist/services/api.ts +9 -5
- package/dist/store/reducers/executeQuery.ts +18 -4
- package/dist/store/reducers/header/header.ts +31 -0
- package/dist/store/reducers/header/types.ts +54 -0
- package/dist/store/reducers/index.ts +1 -1
- package/dist/store/reducers/node/types.ts +2 -0
- package/dist/store/reducers/settings/settings.ts +8 -3
- package/dist/store/reducers/tablet.ts +18 -1
- package/dist/store/reducers/tenant/constants.ts +9 -1
- package/dist/store/reducers/tenant/tenant.ts +23 -4
- package/dist/store/reducers/tenant/types.ts +9 -5
- package/dist/store/reducers/topic.ts +1 -1
- package/dist/store/state-url-mapping.js +6 -3
- package/dist/types/store/executeQuery.ts +4 -1
- package/dist/types/store/query.ts +5 -0
- package/dist/types/store/tablet.ts +7 -4
- package/dist/utils/constants.ts +5 -1
- package/package.json +2 -1
- package/dist/containers/Tenant/ObjectGeneralTabs/ObjectGeneralTabs.scss +0 -9
- package/dist/containers/Tenant/ObjectGeneralTabs/ObjectGeneralTabs.tsx +0 -68
- package/dist/containers/Tenant/QueryEditor/QueriesHistory/QueriesHistory.scss +0 -85
- package/dist/containers/Tenant/QueryEditor/QueriesHistory/QueriesHistory.tsx +0 -95
- package/dist/containers/Tenant/QueryEditor/SavedQueries/SavedQueries.js +0 -161
- package/dist/containers/Tenant/QueryEditor/SavedQueries/SavedQueries.scss +0 -93
- package/dist/containers/Tenant/QueryEditor/i18n/en.json +0 -3
- package/dist/containers/Tenant/QueryEditor/i18n/ru.json +0 -3
- package/dist/store/reducers/header.ts +0 -26
- /package/dist/containers/Tenant/{QueryEditor → Query}/Issues/Issues.scss +0 -0
- /package/dist/containers/Tenant/{QueryEditor → Query}/Issues/Issues.tsx +0 -0
- /package/dist/containers/Tenant/{QueryEditor → Query}/Issues/models.ts +0 -0
- /package/dist/containers/Tenant/{QueryEditor → Query}/QueryDuration/QueryDuration.scss +0 -0
- /package/dist/containers/Tenant/{QueryEditor → Query}/QueryDuration/QueryDuration.tsx +0 -0
- /package/dist/containers/Tenant/{QueryEditor → Query}/QueryEditorControls/OldQueryEditorControls.tsx +0 -0
- /package/dist/containers/Tenant/{QueryEditor → Query}/QueryEditorControls/QueryEditorControls.tsx +0 -0
- /package/dist/containers/Tenant/{QueryEditor → Query}/QueryEditorControls/shared.ts +0 -0
- /package/dist/containers/Tenant/{QueryEditor → Query}/SaveQuery/SaveQuery.scss +0 -0
- /package/dist/containers/Tenant/{QueryEditor → Query}/i18n/index.ts +0 -0
@@ -4,7 +4,7 @@ import {useHistory, useLocation} from 'react-router';
|
|
4
4
|
import qs from 'qs';
|
5
5
|
import cn from 'bem-cn-lite';
|
6
6
|
|
7
|
-
import DataTable, {Column
|
7
|
+
import DataTable, {Column} from '@gravity-ui/react-data-table';
|
8
8
|
import {Loader} from '@gravity-ui/uikit';
|
9
9
|
|
10
10
|
import {DateRange, DateRangeValues} from '../../../../components/DateRange';
|
@@ -22,29 +22,22 @@ 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 {
|
26
|
+
import {TENANT_PAGE, TENANT_PAGES_IDS, TENANT_QUERY_TABS_ID} from '../../../../store/reducers/tenant/constants';
|
28
27
|
import {formatDateTime, formatNumber} from '../../../../utils';
|
29
|
-
import {
|
28
|
+
import {HOUR_IN_SECONDS} from '../../../../utils/constants';
|
30
29
|
import {useAutofetcher, useTypedSelector} from '../../../../utils/hooks';
|
31
30
|
import {prepareQueryError} from '../../../../utils/query';
|
32
|
-
import routes, {createHref} from '../../../../routes';
|
33
31
|
|
32
|
+
import {MAX_QUERY_HEIGHT, QUERY_TABLE_SETTINGS} from '../../utils/constants';
|
34
33
|
import {isColumnEntityType} from '../../utils/schema';
|
35
|
-
import {TenantTabsGroups} from '../../TenantPages';
|
34
|
+
import {TenantTabsGroups, getTenantPath} from '../../TenantPages';
|
36
35
|
|
37
36
|
import i18n from './i18n';
|
38
37
|
import './TopQueries.scss';
|
39
38
|
|
40
39
|
const b = cn('kv-top-queries');
|
41
40
|
|
42
|
-
const TABLE_SETTINGS: Settings = {
|
43
|
-
...DEFAULT_TABLE_SETTINGS,
|
44
|
-
dynamicRenderType: 'variable',
|
45
|
-
};
|
46
|
-
|
47
|
-
const MAX_QUERY_HEIGHT = 10;
|
48
41
|
const COLUMNS: Column<KeyValueRow>[] = [
|
49
42
|
{
|
50
43
|
name: 'CPUTimeUs',
|
@@ -88,7 +81,6 @@ const COLUMNS: Column<KeyValueRow>[] = [
|
|
88
81
|
|
89
82
|
interface TopQueriesProps {
|
90
83
|
path: string;
|
91
|
-
changeSchemaTab: (tab: TenantGeneralTab) => void;
|
92
84
|
type?: EPathType;
|
93
85
|
}
|
94
86
|
|
@@ -178,9 +170,10 @@ export const TopQueries = ({path, type}: TopQueriesProps) => {
|
|
178
170
|
ignoreQueryPrefix: true,
|
179
171
|
});
|
180
172
|
|
181
|
-
const queryPath =
|
173
|
+
const queryPath = getTenantPath({
|
182
174
|
...queryParams,
|
183
|
-
[
|
175
|
+
[TENANT_PAGE]: TENANT_PAGES_IDS.query,
|
176
|
+
[TenantTabsGroups.queryTab]: TENANT_QUERY_TABS_ID.newQuery,
|
184
177
|
});
|
185
178
|
|
186
179
|
history.push(queryPath);
|
@@ -222,7 +215,7 @@ export const TopQueries = ({path, type}: TopQueriesProps) => {
|
|
222
215
|
<DataTable
|
223
216
|
columns={COLUMNS}
|
224
217
|
data={data}
|
225
|
-
settings={
|
218
|
+
settings={QUERY_TABLE_SETTINGS}
|
226
219
|
onRowClick={handleRowClick}
|
227
220
|
theme="yandex-cloud"
|
228
221
|
/>
|
@@ -1,13 +1,15 @@
|
|
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
|
-
import
|
12
|
+
import {Query} from '../Query/Query';
|
11
13
|
import Diagnostics from '../Diagnostics/Diagnostics';
|
12
14
|
|
13
15
|
import './ObjectGeneral.scss';
|
@@ -22,20 +24,18 @@ 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
|
38
|
-
return <
|
36
|
+
switch (tenantPage) {
|
37
|
+
case TENANT_PAGES_IDS.query: {
|
38
|
+
return <Query path={tenantName as string} theme={theme} type={type} />;
|
39
39
|
}
|
40
40
|
default: {
|
41
41
|
return (
|
@@ -47,8 +47,11 @@ import {
|
|
47
47
|
PaneVisibilityToggleButtons,
|
48
48
|
} from '../utils/paneVisibilityToggleHelpers';
|
49
49
|
import {setShowPreview} from '../../../store/reducers/schema/schema';
|
50
|
-
import {
|
51
|
-
import {
|
50
|
+
import {setQueryTab, setTenantPage} from '../../../store/reducers/tenant/tenant';
|
51
|
+
import {
|
52
|
+
TENANT_PAGES_IDS,
|
53
|
+
TENANT_QUERY_TABS_ID,
|
54
|
+
} from '../../../store/reducers/tenant/constants';
|
52
55
|
|
53
56
|
import './ObjectSummary.scss';
|
54
57
|
|
@@ -275,7 +278,8 @@ function ObjectSummary(props: ObjectSummaryProps) {
|
|
275
278
|
|
276
279
|
const onOpenPreview = () => {
|
277
280
|
dispatch(setShowPreview(true));
|
278
|
-
dispatch(
|
281
|
+
dispatch(setTenantPage(TENANT_PAGES_IDS.query));
|
282
|
+
dispatch(setQueryTab(TENANT_QUERY_TABS_ID.newQuery));
|
279
283
|
};
|
280
284
|
|
281
285
|
const renderCommonInfoControls = () => {
|
@@ -20,9 +20,9 @@ import {PaneVisibilityToggleButtons} from '../../utils/paneVisibilityToggleHelpe
|
|
20
20
|
import ResultIssues from '../Issues/Issues';
|
21
21
|
import {QueryDuration} from '../QueryDuration/QueryDuration';
|
22
22
|
|
23
|
-
import './
|
23
|
+
import './ExecuteResult.scss';
|
24
24
|
|
25
|
-
const b = cn('
|
25
|
+
const b = cn('ydb-query-execute-result');
|
26
26
|
|
27
27
|
const resultOptionsIds = {
|
28
28
|
result: 'result',
|
@@ -34,7 +34,7 @@ const resultOptions = [
|
|
34
34
|
{value: resultOptionsIds.stats, content: 'Stats'},
|
35
35
|
];
|
36
36
|
|
37
|
-
function
|
37
|
+
export function ExecuteResult(props) {
|
38
38
|
const [activeSection, setActiveSection] = useState(resultOptionsIds.result);
|
39
39
|
const isFullscreen = useSelector((state) => state.fullscreen);
|
40
40
|
const dispatch = useDispatch();
|
@@ -162,5 +162,3 @@ function QueryResult(props) {
|
|
162
162
|
</React.Fragment>
|
163
163
|
);
|
164
164
|
}
|
165
|
-
|
166
|
-
export default QueryResult;
|
@@ -21,9 +21,9 @@ import {LANGUAGE_S_EXPRESSION_ID} from '../../../../utils/monaco';
|
|
21
21
|
|
22
22
|
import {PaneVisibilityToggleButtons} from '../../utils/paneVisibilityToggleHelpers';
|
23
23
|
|
24
|
-
import './
|
24
|
+
import './ExplainResult.scss';
|
25
25
|
|
26
|
-
const b = cn('
|
26
|
+
const b = cn('ydb-query-explain-result');
|
27
27
|
|
28
28
|
const EDITOR_OPTIONS = {
|
29
29
|
automaticLayout: true,
|
@@ -90,7 +90,7 @@ function GraphRoot(props) {
|
|
90
90
|
return <div id="graphRoot" style={{height: '100vh'}} />;
|
91
91
|
}
|
92
92
|
|
93
|
-
function
|
93
|
+
export function ExplainResult(props) {
|
94
94
|
const dispatch = useDispatch();
|
95
95
|
const [activeOption, setActiveOption] = useState(ExplainOptionIds.schema);
|
96
96
|
|
@@ -287,5 +287,3 @@ function QueryExplain(props) {
|
|
287
287
|
</React.Fragment>
|
288
288
|
);
|
289
289
|
}
|
290
|
-
|
291
|
-
export default QueryExplain;
|
@@ -0,0 +1,20 @@
|
|
1
|
+
@import '../../../../styles/mixins.scss';
|
2
|
+
|
3
|
+
.ydb-queries-history {
|
4
|
+
overflow: auto;
|
5
|
+
|
6
|
+
height: 100%;
|
7
|
+
padding: 0 16px;
|
8
|
+
|
9
|
+
@include flex-container();
|
10
|
+
@include table-styles;
|
11
|
+
|
12
|
+
&__query {
|
13
|
+
overflow: hidden;
|
14
|
+
flex-grow: 1;
|
15
|
+
|
16
|
+
cursor: pointer;
|
17
|
+
white-space: pre;
|
18
|
+
text-overflow: ellipsis;
|
19
|
+
}
|
20
|
+
}
|
@@ -0,0 +1,60 @@
|
|
1
|
+
import {useDispatch} from 'react-redux';
|
2
|
+
import block from 'bem-cn-lite';
|
3
|
+
|
4
|
+
import DataTable, {Column} from '@gravity-ui/react-data-table';
|
5
|
+
|
6
|
+
import TruncatedQuery from '../../../../components/TruncatedQuery/TruncatedQuery';
|
7
|
+
import {setQueryTab} from '../../../../store/reducers/tenant/tenant';
|
8
|
+
import {TENANT_QUERY_TABS_ID} from '../../../../store/reducers/tenant/constants';
|
9
|
+
import {useTypedSelector} from '../../../../utils/hooks';
|
10
|
+
import {MAX_QUERY_HEIGHT, QUERY_TABLE_SETTINGS} from '../../utils/constants';
|
11
|
+
|
12
|
+
import i18n from '../i18n';
|
13
|
+
|
14
|
+
import './QueriesHistory.scss';
|
15
|
+
|
16
|
+
const b = block('ydb-queries-history');
|
17
|
+
|
18
|
+
interface QueriesHistoryProps {
|
19
|
+
changeUserInput: (value: {input: string}) => void;
|
20
|
+
}
|
21
|
+
|
22
|
+
function QueriesHistory({changeUserInput}: QueriesHistoryProps) {
|
23
|
+
const dispatch = useDispatch();
|
24
|
+
|
25
|
+
const queriesHistory = useTypedSelector((state) => state.executeQuery.history.queries) ?? [];
|
26
|
+
const reversedHistory = [...queriesHistory].reverse();
|
27
|
+
|
28
|
+
const onQueryClick = (queryText: string) => {
|
29
|
+
changeUserInput({input: queryText});
|
30
|
+
dispatch(setQueryTab(TENANT_QUERY_TABS_ID.newQuery));
|
31
|
+
};
|
32
|
+
|
33
|
+
const columns: Column<string>[] = [
|
34
|
+
{
|
35
|
+
name: 'queryText',
|
36
|
+
header: 'Query Text',
|
37
|
+
render: ({row: query}) => (
|
38
|
+
<div className={b('query')}>
|
39
|
+
<TruncatedQuery value={query} maxQueryHeight={MAX_QUERY_HEIGHT} />
|
40
|
+
</div>
|
41
|
+
),
|
42
|
+
sortable: false,
|
43
|
+
},
|
44
|
+
];
|
45
|
+
|
46
|
+
return (
|
47
|
+
<div className={b()}>
|
48
|
+
<DataTable
|
49
|
+
theme="yandex-cloud"
|
50
|
+
columns={columns}
|
51
|
+
data={reversedHistory}
|
52
|
+
settings={QUERY_TABLE_SETTINGS}
|
53
|
+
emptyDataMessage={i18n('history.empty')}
|
54
|
+
onRowClick={(row) => onQueryClick(row)}
|
55
|
+
/>
|
56
|
+
</div>
|
57
|
+
);
|
58
|
+
}
|
59
|
+
|
60
|
+
export default QueriesHistory;
|
@@ -0,0 +1,73 @@
|
|
1
|
+
import {useDispatch} from 'react-redux';
|
2
|
+
import block from 'bem-cn-lite';
|
3
|
+
|
4
|
+
import type {EPathType} from '../../../types/api/schema';
|
5
|
+
import type {SavedQuery} from '../../../types/store/query';
|
6
|
+
import {changeUserInput} from '../../../store/reducers/executeQuery';
|
7
|
+
import {TENANT_QUERY_TABS_ID} from '../../../store/reducers/tenant/constants';
|
8
|
+
import {useSetting, useTypedSelector} from '../../../utils/hooks';
|
9
|
+
import {SAVED_QUERIES_KEY} from '../../../utils/constants';
|
10
|
+
|
11
|
+
import {QueryTabs} from './QueryTabs/QueryTabs';
|
12
|
+
import {SavedQueries} from './SavedQueries/SavedQueries';
|
13
|
+
import QueriesHistory from './QueriesHistory/QueriesHistory';
|
14
|
+
import QueryEditor from './QueryEditor/QueryEditor';
|
15
|
+
|
16
|
+
import './Query.scss';
|
17
|
+
|
18
|
+
const b = block('ydb-query');
|
19
|
+
|
20
|
+
interface QueryProps {
|
21
|
+
theme: string;
|
22
|
+
path?: string;
|
23
|
+
type?: EPathType;
|
24
|
+
}
|
25
|
+
|
26
|
+
export const Query = (props: QueryProps) => {
|
27
|
+
const dispatch = useDispatch();
|
28
|
+
|
29
|
+
const {queryTab = TENANT_QUERY_TABS_ID.newQuery} = useTypedSelector((state) => state.tenant);
|
30
|
+
|
31
|
+
const [savedQueries, setSavedQueries] = useSetting<SavedQuery[]>(SAVED_QUERIES_KEY, []);
|
32
|
+
|
33
|
+
const handleDeleteQuery = (queryName: string) => {
|
34
|
+
const newSavedQueries = savedQueries.filter(
|
35
|
+
(el) => el.name.toLowerCase() !== queryName.toLowerCase(),
|
36
|
+
);
|
37
|
+
setSavedQueries(newSavedQueries);
|
38
|
+
};
|
39
|
+
|
40
|
+
const handleUserInputChange = (value: {input: string}) => {
|
41
|
+
dispatch(changeUserInput(value));
|
42
|
+
};
|
43
|
+
|
44
|
+
const renderContent = () => {
|
45
|
+
switch (queryTab) {
|
46
|
+
case TENANT_QUERY_TABS_ID.newQuery: {
|
47
|
+
return <QueryEditor changeUserInput={handleUserInputChange} {...props} />;
|
48
|
+
}
|
49
|
+
case TENANT_QUERY_TABS_ID.history: {
|
50
|
+
return <QueriesHistory changeUserInput={handleUserInputChange} />;
|
51
|
+
}
|
52
|
+
case TENANT_QUERY_TABS_ID.saved: {
|
53
|
+
return (
|
54
|
+
<SavedQueries
|
55
|
+
changeUserInput={handleUserInputChange}
|
56
|
+
savedQueries={savedQueries}
|
57
|
+
onDeleteQuery={handleDeleteQuery}
|
58
|
+
/>
|
59
|
+
);
|
60
|
+
}
|
61
|
+
default: {
|
62
|
+
return null;
|
63
|
+
}
|
64
|
+
}
|
65
|
+
};
|
66
|
+
|
67
|
+
return (
|
68
|
+
<div className={b()}>
|
69
|
+
<QueryTabs className={b('tabs')} activeTab={queryTab} />
|
70
|
+
<div className={b('content')}>{renderContent()}</div>
|
71
|
+
</div>
|
72
|
+
);
|
73
|
+
};
|
@@ -5,43 +5,43 @@ import cn from 'bem-cn-lite';
|
|
5
5
|
import _ from 'lodash';
|
6
6
|
import MonacoEditor from 'react-monaco-editor';
|
7
7
|
|
8
|
-
import SplitPane from '
|
9
|
-
import {QueryResultTable} from '
|
8
|
+
import SplitPane from '../../../../components/SplitPane';
|
9
|
+
import {QueryResultTable} from '../../../../components/QueryResultTable';
|
10
10
|
|
11
11
|
import {
|
12
12
|
sendExecuteQuery,
|
13
|
-
changeUserInput,
|
14
13
|
saveQueryToHistory,
|
15
14
|
goToPreviousQuery,
|
16
15
|
goToNextQuery,
|
17
16
|
MONACO_HOT_KEY_ACTIONS,
|
18
17
|
setMonacoHotKey,
|
19
|
-
|
20
|
-
|
21
|
-
import {
|
22
|
-
import {
|
18
|
+
setTenantPath,
|
19
|
+
} from '../../../../store/reducers/executeQuery';
|
20
|
+
import {getExplainQuery, getExplainQueryAst} from '../../../../store/reducers/explainQuery';
|
21
|
+
import {getParsedSettingValue, setSettingValue} from '../../../../store/reducers/settings/settings';
|
22
|
+
import {setShowPreview} from '../../../../store/reducers/schema/schema';
|
23
23
|
import {
|
24
24
|
DEFAULT_IS_QUERY_RESULT_COLLAPSED,
|
25
25
|
DEFAULT_SIZE_RESULT_PANE_KEY,
|
26
26
|
SAVED_QUERIES_KEY,
|
27
27
|
QUERY_INITIAL_MODE_KEY,
|
28
28
|
ENABLE_ADDITIONAL_QUERY_MODES,
|
29
|
-
} from '
|
30
|
-
import {useSetting} from '
|
31
|
-
import {QueryModes} from '
|
29
|
+
} from '../../../../utils/constants';
|
30
|
+
import {useSetting} from '../../../../utils/hooks';
|
31
|
+
import {QueryModes} from '../../../../types/store/query';
|
32
32
|
|
33
33
|
import {
|
34
34
|
PaneVisibilityActionTypes,
|
35
35
|
paneVisibilityToggleReducerCreator,
|
36
|
-
} from '
|
37
|
-
import Preview from '
|
36
|
+
} from '../../utils/paneVisibilityToggleHelpers';
|
37
|
+
import Preview from '../../Preview/Preview';
|
38
38
|
|
39
|
-
import
|
40
|
-
import
|
41
|
-
import
|
42
|
-
import {
|
43
|
-
|
44
|
-
import
|
39
|
+
import {ExecuteResult} from '../ExecuteResult/ExecuteResult';
|
40
|
+
import {ExplainResult} from '../ExplainResult/ExplainResult';
|
41
|
+
import {QueryEditorControls} from '../QueryEditorControls/QueryEditorControls';
|
42
|
+
import {OldQueryEditorControls} from '../QueryEditorControls/OldQueryEditorControls';
|
43
|
+
|
44
|
+
import {getPreparedResult} from '../utils/getPreparedResult';
|
45
45
|
|
46
46
|
import './QueryEditor.scss';
|
47
47
|
|
@@ -67,6 +67,7 @@ const b = cn('query-editor');
|
|
67
67
|
|
68
68
|
const propTypes = {
|
69
69
|
sendExecuteQuery: PropTypes.func,
|
70
|
+
changeUserInput: PropTypes.func,
|
70
71
|
path: PropTypes.string,
|
71
72
|
response: PropTypes.oneOfType([PropTypes.bool, PropTypes.array]),
|
72
73
|
executeQuery: PropTypes.object,
|
@@ -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,
|
@@ -324,11 +336,11 @@ function QueryEditor(props) {
|
|
324
336
|
/>
|
325
337
|
);
|
326
338
|
}
|
327
|
-
const textResults = getPreparedResult();
|
339
|
+
const textResults = getPreparedResult(data);
|
328
340
|
const disabled = !textResults.length || resultType !== RESULT_TYPES.EXECUTE;
|
329
341
|
|
330
342
|
return data || error ? (
|
331
|
-
<
|
343
|
+
<ExecuteResult
|
332
344
|
result={content}
|
333
345
|
stats={stats}
|
334
346
|
error={error}
|
@@ -348,7 +360,7 @@ function QueryEditor(props) {
|
|
348
360
|
} = props;
|
349
361
|
|
350
362
|
return (
|
351
|
-
<
|
363
|
+
<ExplainResult
|
352
364
|
error={error}
|
353
365
|
explain={data}
|
354
366
|
astQuery={handleAstQuery}
|
@@ -436,46 +448,6 @@ function QueryEditor(props) {
|
|
436
448
|
return queries.length - 1 === currentIndex;
|
437
449
|
};
|
438
450
|
|
439
|
-
const renderHistoryNavigation = () => {
|
440
|
-
const {changeUserInput} = props;
|
441
|
-
return (
|
442
|
-
<div className={b('history-controls')}>
|
443
|
-
<QueriesHistory changeUserInput={changeUserInput} />
|
444
|
-
</div>
|
445
|
-
);
|
446
|
-
};
|
447
|
-
|
448
|
-
const getPreparedResult = () => {
|
449
|
-
const {
|
450
|
-
executeQuery: {data},
|
451
|
-
} = props;
|
452
|
-
const columnDivider = '\t';
|
453
|
-
const rowDivider = '\n';
|
454
|
-
|
455
|
-
if (!data?.result?.length) {
|
456
|
-
return '';
|
457
|
-
}
|
458
|
-
|
459
|
-
const columnHeaders = Object.keys(data.result[0]);
|
460
|
-
const rows = [columnHeaders].concat(data.result);
|
461
|
-
|
462
|
-
return rows
|
463
|
-
.map((item) => {
|
464
|
-
const row = [];
|
465
|
-
|
466
|
-
for (const field in item) {
|
467
|
-
if (typeof item[field] === 'object' || Array.isArray(item[field])) {
|
468
|
-
row.push(JSON.stringify(item[field]));
|
469
|
-
} else {
|
470
|
-
row.push(item[field]);
|
471
|
-
}
|
472
|
-
}
|
473
|
-
|
474
|
-
return row.join(columnDivider);
|
475
|
-
})
|
476
|
-
.join(rowDivider);
|
477
|
-
};
|
478
|
-
|
479
451
|
const onChangeWindow = _.throttle(() => {
|
480
452
|
updateEditor();
|
481
453
|
}, 100);
|
@@ -513,14 +485,6 @@ function QueryEditor(props) {
|
|
513
485
|
setSettingValue(SAVED_QUERIES_KEY, JSON.stringify(newSavedQueries));
|
514
486
|
};
|
515
487
|
|
516
|
-
const onDeleteQueryHandler = (queryName) => {
|
517
|
-
const {savedQueries = [], setSettingValue} = props;
|
518
|
-
const newSavedQueries = savedQueries.filter(
|
519
|
-
(el) => el.name.toLowerCase() !== queryName.toLowerCase(),
|
520
|
-
);
|
521
|
-
setSettingValue(SAVED_QUERIES_KEY, JSON.stringify(newSavedQueries));
|
522
|
-
};
|
523
|
-
|
524
488
|
const renderControls = () => {
|
525
489
|
const {executeQuery, explainQuery, savedQueries} = props;
|
526
490
|
|
@@ -555,22 +519,6 @@ function QueryEditor(props) {
|
|
555
519
|
);
|
556
520
|
};
|
557
521
|
|
558
|
-
const renderUpperControls = () => {
|
559
|
-
const {savedQueries, changeUserInput} = props;
|
560
|
-
|
561
|
-
return (
|
562
|
-
<div className={b('upper-controls')}>
|
563
|
-
{renderHistoryNavigation()}
|
564
|
-
<SavedQueries
|
565
|
-
savedQueries={savedQueries}
|
566
|
-
changeUserInput={changeUserInput}
|
567
|
-
onDeleteQuery={onDeleteQueryHandler}
|
568
|
-
/>
|
569
|
-
</div>
|
570
|
-
);
|
571
|
-
};
|
572
|
-
|
573
|
-
const {executeQuery, theme} = props;
|
574
522
|
const result = renderResult();
|
575
523
|
|
576
524
|
return (
|
@@ -584,7 +532,11 @@ function QueryEditor(props) {
|
|
584
532
|
collapsedSizes={[100, 0]}
|
585
533
|
onSplitStartDragAdditional={onSplitStartDragAdditional}
|
586
534
|
>
|
587
|
-
<div
|
535
|
+
<div
|
536
|
+
className={b('pane-wrapper', {
|
537
|
+
top: true,
|
538
|
+
})}
|
539
|
+
>
|
588
540
|
<div className={b('monaco-wrapper')}>
|
589
541
|
<div className={b('monaco')}>
|
590
542
|
<MonacoEditor
|
@@ -598,7 +550,6 @@ function QueryEditor(props) {
|
|
598
550
|
</div>
|
599
551
|
</div>
|
600
552
|
{renderControls()}
|
601
|
-
{renderUpperControls()}
|
602
553
|
</div>
|
603
554
|
<div className={b('pane-wrapper')}>
|
604
555
|
{props.showPreview ? renderPreview() : result}
|
@@ -621,7 +572,6 @@ const mapStateToProps = (state) => {
|
|
621
572
|
|
622
573
|
const mapDispatchToProps = {
|
623
574
|
sendExecuteQuery,
|
624
|
-
changeUserInput,
|
625
575
|
saveQueryToHistory,
|
626
576
|
goToPreviousQuery,
|
627
577
|
goToNextQuery,
|
@@ -630,6 +580,7 @@ const mapDispatchToProps = {
|
|
630
580
|
setSettingValue,
|
631
581
|
setShowPreview,
|
632
582
|
setMonacoHotKey,
|
583
|
+
setTenantPath,
|
633
584
|
};
|
634
585
|
|
635
586
|
QueryEditor.propTypes = propTypes;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
@import '
|
1
|
+
@import '../../../../styles/mixins.scss';
|
2
2
|
|
3
3
|
.query-editor {
|
4
4
|
position: relative;
|
@@ -24,7 +24,8 @@
|
|
24
24
|
|
25
25
|
width: 100%;
|
26
26
|
height: 100%;
|
27
|
-
|
27
|
+
|
28
|
+
border: 1px solid var(--yc-color-line-generic);
|
28
29
|
}
|
29
30
|
|
30
31
|
&__monaco-wrapper {
|
@@ -40,28 +41,11 @@
|
|
40
41
|
flex-direction: column;
|
41
42
|
|
42
43
|
background-color: var(--yc-color-base-background);
|
43
|
-
}
|
44
|
-
|
45
|
-
&__upper-controls {
|
46
|
-
position: absolute;
|
47
|
-
top: -38px;
|
48
|
-
right: 20px;
|
49
|
-
|
50
|
-
display: flex;
|
51
|
-
gap: 12px;
|
52
|
-
|
53
|
-
justify-content: flex-end;
|
54
|
-
align-items: center;
|
55
|
-
}
|
56
|
-
|
57
|
-
&__history-controls {
|
58
|
-
display: flex;
|
59
|
-
align-items: center;
|
60
|
-
}
|
61
44
|
|
62
|
-
|
63
|
-
|
45
|
+
&_top {
|
46
|
+
padding: 0 16px;
|
64
47
|
|
65
|
-
|
48
|
+
border-bottom: 1px solid var(--yc-color-line-generic);
|
49
|
+
}
|
66
50
|
}
|
67
51
|
}
|