Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {ResponseError} from '../../../../components/Errors/ResponseError';
import {ResizeableDataTable} from '../../../../components/ResizeableDataTable/ResizeableDataTable';
import {TableWithControlsLayout} from '../../../../components/TableWithControlsLayout/TableWithControlsLayout';
import {topQueriesApi} from '../../../../store/reducers/executeTopQueries/executeTopQueries';
import type {KeyValueRow} from '../../../../types/api/query';
import {useAutoRefreshInterval, useTypedSelector} from '../../../../utils/hooks';
import {parseQueryErrorToString} from '../../../../utils/query';
import {QUERY_TABLE_SETTINGS} from '../../utils/constants';
Expand All @@ -16,12 +17,14 @@ import i18n from './i18n';

interface Props {
database: string;
onRowClick: (query: string) => void;
rowClassName: string;
}

export const RunningQueriesData = ({database}: Props) => {
export const RunningQueriesData = ({database, onRowClick, rowClassName}: Props) => {
const [autoRefreshInterval] = useAutoRefreshInterval();
const filters = useTypedSelector((state) => state.executeTopQueries);
const {currentData, isFetching, error} = topQueriesApi.useGetRunningQueriesQuery(
const {currentData, isLoading, error} = topQueriesApi.useGetRunningQueriesQuery(
{
database,
filters,
Expand All @@ -31,16 +34,22 @@ export const RunningQueriesData = ({database}: Props) => {

const data = currentData?.resultSets?.[0].result || [];

const handleRowClick = (row: KeyValueRow) => {
return onRowClick(row.QueryText as string);
};

return (
<React.Fragment>
{error ? <ResponseError error={parseQueryErrorToString(error)} /> : null}
<TableWithControlsLayout.Table loading={isFetching && data === undefined}>
<TableWithControlsLayout.Table loading={isLoading}>
<ResizeableDataTable
emptyDataMessage={i18n('no-data')}
columnsWidthLSKey={RUNNING_QUERIES_COLUMNS_WIDTH_LS_KEY}
columns={RUNNING_QUERIES_COLUMNS}
data={data}
settings={QUERY_TABLE_SETTINGS}
onRowClick={handleRowClick}
rowClassName={() => rowClassName}
/>
</TableWithControlsLayout.Table>
</React.Fragment>
Expand Down
8 changes: 3 additions & 5 deletions src/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ export const TopQueries = ({tenantName}: TopQueriesProps) => {
dispatch(setTopQueriesFilters(value));
};

const DataComponent = isTopQueries ? TopQueriesData : RunningQueriesData;

return (
<TableWithControlsLayout>
<TableWithControlsLayout.Controls>
Expand All @@ -115,11 +117,7 @@ export const TopQueries = ({tenantName}: TopQueriesProps) => {
/>
) : null}
</TableWithControlsLayout.Controls>
{isTopQueries ? (
<TopQueriesData database={tenantName} onRowClick={onRowClick} />
) : (
<RunningQueriesData database={tenantName} />
)}
<DataComponent database={tenantName} onRowClick={onRowClick} rowClassName={b('row')} />
</TableWithControlsLayout>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {ResizeableDataTable} from '../../../../components/ResizeableDataTable/Re
import {TableWithControlsLayout} from '../../../../components/TableWithControlsLayout/TableWithControlsLayout';
import {topQueriesApi} from '../../../../store/reducers/executeTopQueries/executeTopQueries';
import type {KeyValueRow} from '../../../../types/api/query';
import {cn} from '../../../../utils/cn';
import {isSortableTopQueriesProperty} from '../../../../utils/diagnostics';
import {useAutoRefreshInterval, useTypedSelector} from '../../../../utils/hooks';
import {parseQueryErrorToString} from '../../../../utils/query';
Expand All @@ -14,17 +13,16 @@ import {QUERY_TABLE_SETTINGS} from '../../utils/constants';
import {TOP_QUERIES_COLUMNS, TOP_QUERIES_COLUMNS_WIDTH_LS_KEY} from './getTopQueriesColumns';
import i18n from './i18n';

const b = cn('kv-top-queries');

interface Props {
database: string;
onRowClick: (query: string) => void;
rowClassName: string;
}

export const TopQueriesData = ({database, onRowClick}: Props) => {
export const TopQueriesData = ({database, onRowClick, rowClassName}: Props) => {
const [autoRefreshInterval] = useAutoRefreshInterval();
const filters = useTypedSelector((state) => state.executeTopQueries);
const {currentData, isFetching, error} = topQueriesApi.useGetTopQueriesQuery(
const {currentData, isLoading, error} = topQueriesApi.useGetTopQueriesQuery(
{
database,
filters,
Expand All @@ -46,15 +44,15 @@ export const TopQueriesData = ({database, onRowClick}: Props) => {
return (
<React.Fragment>
{error ? <ResponseError error={parseQueryErrorToString(error)} /> : null}
<TableWithControlsLayout.Table loading={isFetching && currentData === undefined}>
<TableWithControlsLayout.Table loading={isLoading}>
<ResizeableDataTable
emptyDataMessage={i18n('no-data')}
columnsWidthLSKey={TOP_QUERIES_COLUMNS_WIDTH_LS_KEY}
columns={columns}
data={data || []}
settings={QUERY_TABLE_SETTINGS}
onRowClick={handleRowClick}
rowClassName={() => b('row')}
rowClassName={() => rowClassName}
/>
</TableWithControlsLayout.Table>
</React.Fragment>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"no-data": "No data",
"filter.text.placeholder": "Search by query text...",
"filter.text.placeholder": "Search by query text or userSID...",
"mode_top": "Top",
"mode_running": "Running",
"col_user": "User",
Expand Down
14 changes: 11 additions & 3 deletions src/store/reducers/executeTopQueries/executeTopQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,11 @@ export const topQueriesApi = api.injectEndpoints({
{signal},
) => {
try {
const filterConditions = filters?.text ? `Query ILIKE '%${filters.text}%'` : '';
const commonQueryPart = `SELECT UserSID, QueryStartAt, Query as QueryText, ApplicationName from \`.sys/query_sessions\` WHERE ${filterConditions || 'true'}`;
const filterConditions = filters?.text
? `Query ILIKE '%${filters.text}%' OR UserSID ILIKE '%${filters.text}%'`
: '';

const queryText = `${commonQueryPart} AND Query NOT LIKE '${commonQueryPart}%' ORDER BY SessionStartAt limit 100`;
const queryText = `SELECT UserSID, QueryStartAt, Query as QueryText, ApplicationName from \`.sys/query_sessions\` WHERE ${filterConditions || 'true'} ORDER BY SessionStartAt limit 100`;

const response = await window.api.sendQuery(
{
Expand All @@ -114,6 +115,13 @@ export const topQueriesApi = api.injectEndpoints({

const data = parseQueryAPIExecuteResponse(response);

/* filter running queries query itself */
if (data?.resultSets?.[0]?.result) {
data.resultSets[0].result = data.resultSets[0].result.filter(
(item) => item.QueryText !== queryText,
);
}

return {data};
} catch (error) {
return {error};
Expand Down
4 changes: 3 additions & 1 deletion src/store/reducers/executeTopQueries/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ export function getFiltersConditions(path: string, filters?: TopQueriesFilters)
}

if (filters?.text) {
conditions.push(`QueryText ILIKE '%${filters.text}%'`);
conditions.push(
`(QueryText ILIKE '%${filters.text}%' OR UserSID ILIKE '%${filters.text}%')`,
);
}

return conditions.join(' AND ');
Expand Down
Loading