Skip to content

Commit e6c9080

Browse files
authored
Merge branch 'main' into astandrik.video-tests
2 parents 377f20a + c0781f1 commit e6c9080

File tree

14 files changed

+222
-115
lines changed

14 files changed

+222
-115
lines changed

.github/workflows/quality.yml

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ jobs:
189189
rm -rf gh-pages/$REPORT_DIR
190190
mkdir -p gh-pages/$REPORT_DIR
191191
cp -r playwright-artifacts/playwright-report/* gh-pages/$REPORT_DIR/
192+
# Also copy test-results.json if it exists
193+
if [ -f "playwright-artifacts/test-results.json" ]; then
194+
cp playwright-artifacts/test-results.json gh-pages/$REPORT_DIR/
195+
fi
192196
193197
- name: Deploy report to GitHub Pages
194198
uses: peaceiris/actions-gh-pages@v3
@@ -217,34 +221,6 @@ jobs:
217221
name: playwright-artifacts
218222
path: playwright-artifacts
219223

220-
- name: Count new tests
221-
id: count_tests
222-
run: |
223-
git fetch origin main:main
224-
new_tests=0
225-
226-
# Get list of changed test files
227-
for file in $(git diff --name-only main...HEAD | grep -E '^tests/suites/.*\.(spec|test)\.(ts|tsx|js|jsx)$'); do
228-
# Count tests in current version
229-
if git show HEAD:"$file" > /dev/null 2>&1; then
230-
current_tests=$(git show HEAD:"$file" | grep -E "test\([\'\"]" | wc -l)
231-
else
232-
current_tests=0
233-
fi
234-
235-
# Count tests in main version
236-
if git show main:"$file" > /dev/null 2>&1; then
237-
base_tests=$(git show main:"$file" | grep -E "test\([\'\"]" | wc -l)
238-
else
239-
base_tests=0
240-
fi
241-
242-
# Add difference to total
243-
((new_tests += current_tests - base_tests))
244-
done
245-
246-
echo "new_tests=$new_tests" >> $GITHUB_OUTPUT
247-
248224
- name: Update PR description
249225
uses: actions/github-script@v6
250226
with:
@@ -289,17 +265,14 @@ jobs:
289265
parseFloat(percent) > 0 ? '🔺' :
290266
parseFloat(percent) < 0 ? '🔽' : '✅';
291267
292-
const newTests = parseInt('${{ steps.count_tests.outputs.new_tests }}');
293-
const testsStatus = newTests > 0 ? '✨' : '➖';
294-
295268
const ciSection = `## CI Results
296269
297270
### Test Status: <span style="color: ${statusColor};">${status}</span>
298271
📊 [Full Report](${reportUrl})
299272
300-
| Total | Passed | Failed | Flaky | Skipped | New Tests |
301-
|:-----:|:------:|:------:|:-----:|:-------:|:---------:|
302-
| ${testResults.total} | ${testResults.passed} | ${testResults.failed} | ${testResults.flaky} | ${testResults.skipped} | ${testsStatus} ${newTests} |
273+
| Total | Passed | Failed | Flaky | Skipped |
274+
|:-----:|:------:|:------:|:-----:|:-------:|
275+
| ${testResults.total} | ${testResults.passed} | ${testResults.failed} | ${testResults.flaky} | ${testResults.skipped} |
303276
304277
### Bundle Size: ${bundleStatus}
305278
Current: ${formatSize(currentSize)} | Main: ${formatSize(mainSize)}
@@ -318,7 +291,6 @@ jobs:
318291
- Bundle size is measured for the entire 'dist' directory.
319292
- 📊 indicates links to detailed reports.
320293
- 🔺 indicates increase, 🔽 decrease, and ✅ no change in bundle size.
321-
- ${testsStatus} indicates ${newTests} new test cases added in this PR.
322294
</details>`;
323295
324296
const { data: pullRequest } = await github.rest.pulls.get({

package-lock.json

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
},
1212
"dependencies": {
1313
"@bem-react/classname": "^1.6.0",
14+
"@ebay/nice-modal-react": "^1.2.13",
1415
"@gravity-ui/axios-wrapper": "^1.4.1",
1516
"@gravity-ui/chartkit": "^5.9.0",
1617
"@gravity-ui/components": "^3.7.0",
@@ -27,7 +28,6 @@
2728
"@hookform/resolvers": "^3.9.0",
2829
"@reduxjs/toolkit": "^2.2.3",
2930
"@tanstack/react-table": "^8.19.3",
30-
"@ebay/nice-modal-react": "^1.2.13",
3131
"axios": "^1.7.3",
3232
"axios-retry": "^4.4.2",
3333
"colord": "^2.9.3",
@@ -53,7 +53,7 @@
5353
"use-query-params": "^2.2.1",
5454
"uuid": "^10.0.0",
5555
"web-vitals": "^1.1.2",
56-
"ydb-ui-components": "^4.2.0",
56+
"ydb-ui-components": "^4.3.2",
5757
"zod": "^3.23.8"
5858
},
5959
"scripts": {

src/containers/Tenant/ObjectSummary/SchemaTree/SchemaTree.tsx

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,19 @@ import {useCreateDirectoryFeatureAvailable} from '../../../../store/reducers/cap
99
import {selectUserInput} from '../../../../store/reducers/query/query';
1010
import {schemaApi} from '../../../../store/reducers/schema/schema';
1111
import {tableSchemaDataApi} from '../../../../store/reducers/tableSchemaData';
12-
import type {GetTableSchemaDataParams} from '../../../../store/reducers/tableSchemaData';
1312
import type {EPathType, TEvDescribeSchemeResult} from '../../../../types/api/schema';
14-
import {wait} from '../../../../utils';
15-
import {SECOND_IN_MS} from '../../../../utils/constants';
1613
import {
1714
useQueryExecutionSettings,
1815
useTypedDispatch,
1916
useTypedSelector,
2017
} from '../../../../utils/hooks';
2118
import {getConfirmation} from '../../../../utils/hooks/withConfirmation/useChangeInputWithConfirmation';
2219
import {getSchemaControls} from '../../utils/controls';
23-
import {isChildlessPathType, mapPathTypeToNavigationTreeType} from '../../utils/schema';
20+
import {
21+
isChildlessPathType,
22+
mapPathTypeToNavigationTreeType,
23+
nodeTableTypeToPathType,
24+
} from '../../utils/schema';
2425
import {getActions} from '../../utils/schemaActions';
2526
import {CreateDirectoryDialog} from '../CreateDirectoryDialog/CreateDirectoryDialog';
2627
import {useDispatchTreeKey, useTreeKey} from '../UpdateTreeContext';
@@ -33,29 +34,15 @@ interface SchemaTreeProps {
3334
onActivePathUpdate: (path: string) => void;
3435
}
3536

36-
const TABLE_SCHEMA_TIMEOUT = SECOND_IN_MS * 2;
37-
3837
export function SchemaTree(props: SchemaTreeProps) {
3938
const createDirectoryFeatureAvailable = useCreateDirectoryFeatureAvailable();
4039
const {rootPath, rootName, rootType, currentPath, onActivePathUpdate} = props;
4140
const dispatch = useTypedDispatch();
4241
const input = useTypedSelector(selectUserInput);
43-
const [getTableSchemaDataMutation] = tableSchemaDataApi.useGetTableSchemaDataMutation();
44-
45-
const getTableSchemaDataPromise = React.useCallback(
46-
async (args: GetTableSchemaDataParams) => {
47-
try {
48-
const result = await Promise.race([
49-
getTableSchemaDataMutation(args).unwrap(),
50-
wait<undefined>(TABLE_SCHEMA_TIMEOUT),
51-
]);
52-
return result;
53-
} catch (e) {
54-
return undefined;
55-
}
56-
},
57-
[getTableSchemaDataMutation],
58-
);
42+
const [
43+
getTableSchemaDataQuery,
44+
{currentData: actionsSchemaData, isFetching: isActionsDataFetching},
45+
] = tableSchemaDataApi.useLazyGetTableSchemaDataQuery();
5946

6047
const [querySettings, setQueryExecutionSettings] = useQueryExecutionSettings();
6148
const [createDirectoryOpen, setCreateDirectoryOpen] = React.useState(false);
@@ -123,6 +110,36 @@ export function SchemaTree(props: SchemaTreeProps) {
123110
setParentPath(value);
124111
setCreateDirectoryOpen(true);
125112
};
113+
114+
const getTreeNodeActions = React.useMemo(() => {
115+
return getActions(
116+
dispatch,
117+
{
118+
setActivePath: onActivePathUpdate,
119+
updateQueryExecutionSettings: (settings) =>
120+
setQueryExecutionSettings({...querySettings, ...settings}),
121+
showCreateDirectoryDialog: createDirectoryFeatureAvailable
122+
? handleOpenCreateDirectoryDialog
123+
: undefined,
124+
getConfirmation: input ? getConfirmation : undefined,
125+
126+
schemaData: actionsSchemaData,
127+
isSchemaDataLoading: isActionsDataFetching,
128+
},
129+
rootPath,
130+
);
131+
}, [
132+
actionsSchemaData,
133+
createDirectoryFeatureAvailable,
134+
dispatch,
135+
input,
136+
isActionsDataFetching,
137+
onActivePathUpdate,
138+
querySettings,
139+
rootPath,
140+
setQueryExecutionSettings,
141+
]);
142+
126143
return (
127144
<React.Fragment>
128145
<CreateDirectoryDialog
@@ -141,20 +158,15 @@ export function SchemaTree(props: SchemaTreeProps) {
141158
collapsed: false,
142159
}}
143160
fetchPath={fetchPath}
144-
getActions={getActions(
145-
dispatch,
146-
{
147-
setActivePath: onActivePathUpdate,
148-
updateQueryExecutionSettings: (settings) =>
149-
setQueryExecutionSettings({...querySettings, ...settings}),
150-
showCreateDirectoryDialog: createDirectoryFeatureAvailable
151-
? handleOpenCreateDirectoryDialog
152-
: undefined,
153-
getTableSchemaDataPromise,
154-
getConfirmation: input ? getConfirmation : undefined,
155-
},
156-
rootPath,
157-
)}
161+
getActions={getTreeNodeActions}
162+
onActionsOpenToggle={({path, type, isOpen}) => {
163+
const pathType = nodeTableTypeToPathType[type];
164+
if (isOpen && pathType) {
165+
getTableSchemaDataQuery({path, tenantName: rootPath, type: pathType});
166+
}
167+
168+
return [];
169+
}}
158170
renderAdditionalNodeElements={getSchemaControls(dispatch, {
159171
setActivePath: onActivePathUpdate,
160172
})}

src/containers/Tenant/utils/schemaActions.ts renamed to src/containers/Tenant/utils/schemaActions.tsx

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
import {Flex, Spin} from '@gravity-ui/uikit';
12
import copy from 'copy-to-clipboard';
23
import type {NavigationTreeNodeType, NavigationTreeProps} from 'ydb-ui-components';
34

45
import type {AppDispatch} from '../../../store';
5-
import type {GetTableSchemaDataParams} from '../../../store/reducers/tableSchemaData';
66
import {TENANT_PAGES_IDS, TENANT_QUERY_TABS_ID} from '../../../store/reducers/tenant/constants';
77
import {setQueryTab, setTenantPage} from '../../../store/reducers/tenant/tenant';
88
import type {QuerySettings} from '../../../types/store/query';
@@ -12,7 +12,6 @@ import {transformPath} from '../ObjectSummary/transformPath';
1212
import type {SchemaData} from '../Schema/SchemaViewer/types';
1313
import i18n from '../i18n';
1414

15-
import {nodeTableTypeToPathType} from './schema';
1615
import type {TemplateFn} from './schemaQueryTemplates';
1716
import {
1817
addTableIndex,
@@ -36,14 +35,13 @@ import {
3635
upsertQueryTemplate,
3736
} from './schemaQueryTemplates';
3837

39-
interface ActionsAdditionalEffects {
38+
interface ActionsAdditionalParams {
4039
updateQueryExecutionSettings: (settings?: Partial<QuerySettings>) => void;
4140
setActivePath: (path: string) => void;
4241
showCreateDirectoryDialog?: (path: string) => void;
43-
getTableSchemaDataPromise?: (
44-
params: GetTableSchemaDataParams,
45-
) => Promise<SchemaData[] | undefined>;
4642
getConfirmation?: () => Promise<boolean>;
43+
schemaData?: SchemaData[];
44+
isSchemaDataLoading?: boolean;
4745
}
4846

4947
interface BindActionParams {
@@ -56,32 +54,18 @@ interface BindActionParams {
5654
const bindActions = (
5755
params: BindActionParams,
5856
dispatch: AppDispatch,
59-
additionalEffects: ActionsAdditionalEffects,
57+
additionalEffects: ActionsAdditionalParams,
6058
) => {
61-
const {setActivePath, showCreateDirectoryDialog, getTableSchemaDataPromise, getConfirmation} =
59+
const {setActivePath, showCreateDirectoryDialog, getConfirmation, schemaData} =
6260
additionalEffects;
6361

6462
const inputQuery = (tmpl: TemplateFn) => () => {
6563
const applyInsert = () => {
66-
const pathType = nodeTableTypeToPathType[params.type];
67-
const withTableData = [selectQueryTemplate, upsertQueryTemplate].includes(tmpl);
68-
69-
const userInputDataPromise =
70-
withTableData && pathType && getTableSchemaDataPromise
71-
? getTableSchemaDataPromise({
72-
path: params.path,
73-
tenantName: params.tenantName,
74-
type: pathType,
75-
})
76-
: Promise.resolve(undefined);
77-
7864
//order is important here: firstly we should open query tab and initialize editor (it will be set to window.ydbEditor), after that it is possible to insert snippet
7965
dispatch(setTenantPage(TENANT_PAGES_IDS.query));
8066
dispatch(setQueryTab(TENANT_QUERY_TABS_ID.newQuery));
8167
setActivePath(params.path);
82-
userInputDataPromise.then((tableData) => {
83-
insertSnippetToEditor(tmpl({...params, tableData}));
84-
});
68+
insertSnippetToEditor(tmpl({...params, schemaData}));
8569
};
8670
if (getConfirmation) {
8771
const confirmedPromise = getConfirmation();
@@ -142,8 +126,25 @@ const bindActions = (
142126

143127
type ActionsSet = ReturnType<Required<NavigationTreeProps>['getActions']>;
144128

129+
interface ActionConfig {
130+
text: string;
131+
action: () => void;
132+
isLoading?: boolean;
133+
}
134+
135+
const getActionWithLoader = ({text, action, isLoading}: ActionConfig) => ({
136+
text: (
137+
<Flex justifyContent="space-between" alignItems="center">
138+
{text}
139+
{isLoading && <Spin size="xs" />}
140+
</Flex>
141+
),
142+
action,
143+
disabled: isLoading,
144+
});
145+
145146
export const getActions =
146-
(dispatch: AppDispatch, additionalEffects: ActionsAdditionalEffects, rootPath = '') =>
147+
(dispatch: AppDispatch, additionalEffects: ActionsAdditionalParams, rootPath = '') =>
147148
(path: string, type: NavigationTreeNodeType) => {
148149
const relativePath = transformPath(path, rootPath);
149150
const actions = bindActions(
@@ -176,8 +177,16 @@ export const getActions =
176177
[
177178
{text: i18n('actions.alterTable'), action: actions.alterTable},
178179
{text: i18n('actions.dropTable'), action: actions.dropTable},
179-
{text: i18n('actions.selectQuery'), action: actions.selectQuery},
180-
{text: i18n('actions.upsertQuery'), action: actions.upsertQuery},
180+
getActionWithLoader({
181+
text: i18n('actions.selectQuery'),
182+
action: actions.selectQuery,
183+
isLoading: additionalEffects.isSchemaDataLoading,
184+
}),
185+
getActionWithLoader({
186+
text: i18n('actions.upsertQuery'),
187+
action: actions.upsertQuery,
188+
isLoading: additionalEffects.isSchemaDataLoading,
189+
}),
181190
{text: i18n('actions.addTableIndex'), action: actions.addTableIndex},
182191
{text: i18n('actions.createCdcStream'), action: actions.createCdcStream},
183192
],

src/containers/Tenant/utils/schemaQueryTemplates.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type {SchemaData} from '../Schema/SchemaViewer/types';
33
export interface SchemaQueryParams {
44
path: string;
55
relativePath: string;
6-
tableData?: SchemaData[];
6+
schemaData?: SchemaData[];
77
}
88

99
export type TemplateFn = (params?: SchemaQueryParams) => string;
@@ -87,7 +87,7 @@ ALTER TABLE ${path}
8787
export const selectQueryTemplate = (params?: SchemaQueryParams) => {
8888
const path = params?.relativePath ? `\`${params?.relativePath}\`` : '${2:<my_table>}';
8989
const columns =
90-
params?.tableData?.map((column) => '`' + column.name + '`').join(', ') || '${1:*}';
90+
params?.schemaData?.map((column) => '`' + column.name + '`').join(', ') || '${1:*}';
9191
const filters = params?.relativePath ? '' : 'WHERE ${3:Key1 = 1}\nORDER BY ${4:Key1}\n';
9292
return `SELECT ${columns}
9393
FROM ${path}
@@ -96,8 +96,8 @@ ${filters}LIMIT \${5:10};`;
9696
export const upsertQueryTemplate = (params?: SchemaQueryParams) => {
9797
const path = params?.relativePath ? `\`${params?.relativePath}\`` : '${1:<my_table>}';
9898
const columns =
99-
params?.tableData?.map((column) => `\`${column.name}\``).join(', ') || '${2:id, name}';
100-
const values = params?.tableData ? '${3: }' : '${3:1, "foo"}';
99+
params?.schemaData?.map((column) => `\`${column.name}\``).join(', ') || '${2:id, name}';
100+
const values = params?.schemaData ? '${3: }' : '${3:1, "foo"}';
101101
return `UPSERT INTO ${path}
102102
( ${columns} )
103103
VALUES ( ${values} );`;

0 commit comments

Comments
 (0)