Skip to content

Commit

Permalink
refactor: logs explorer default pagination handling changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmadshaheer committed Feb 3, 2025
1 parent e33a0fd commit 6d2baca
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 68 deletions.
12 changes: 12 additions & 0 deletions frontend/src/constants/queryBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
IBuilderQuery,
IClickHouseQuery,
IPromQLQuery,
OrderByPayload,
Query,
QueryState,
TagFilter,
Expand Down Expand Up @@ -161,6 +162,17 @@ export const initialFilters: TagFilter = {
op: 'AND',
};

export const initialOrderBy: OrderByPayload[] = [
{
columnName: 'timestamp',
order: 'desc',
},
{
columnName: 'id',
order: 'desc',
},
];

export const initialQueryBuilderFormValues: IBuilderQuery = {
dataSource: DataSource.METRICS,
queryName: createNewBuilderItemName({ existNames: [], sourceNames: alphabet }),
Expand Down
103 changes: 36 additions & 67 deletions frontend/src/container/LogsExplorerViews/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { LOCALSTORAGE } from 'constants/localStorage';
import { AVAILABLE_EXPORT_PANEL_TYPES } from 'constants/panelTypes';
import { QueryParams } from 'constants/query';
import {
initialFilters,
initialOrderBy,
initialQueriesMap,
initialQueryBuilderFormValues,
PANEL_TYPES,
Expand Down Expand Up @@ -40,7 +40,7 @@ import { useHandleExplorerTabChange } from 'hooks/useHandleExplorerTabChange';
import { useNotifications } from 'hooks/useNotifications';
import useUrlQueryData from 'hooks/useUrlQueryData';
import { FlatLogData } from 'lib/logs/flatLogData';
import { getPaginationQueryData } from 'lib/newQueryBuilder/getPaginationQueryData';
import { getPaginationQueryDataV2 } from 'lib/newQueryBuilder/getPaginationQueryData';
import {
cloneDeep,
defaultTo,
Expand Down Expand Up @@ -71,7 +71,6 @@ import {
IBuilderQuery,
OrderByPayload,
Query,
TagFilter,
} from 'types/api/queryBuilder/queryBuilderData';
import {
DataSource,
Expand Down Expand Up @@ -157,14 +156,6 @@ function LogsExplorerViews({
aggregateOperator: listQuery?.aggregateOperator || StringOperators.NOOP,
});

const orderByTimestamp: OrderByPayload | null = useMemo(() => {
const timestampOrderBy = listQuery?.orderBy.find(
(item) => item.columnName === 'timestamp',
);

return timestampOrderBy || null;
}, [listQuery]);

const isMultipleQueries = useMemo(
() =>
currentQuery.builder.queryData.length > 1 ||
Expand Down Expand Up @@ -296,21 +287,16 @@ function LogsExplorerViews({
const getRequestData = useCallback(
(
query: Query | null,
params: {
page: number;
log: ILog | null;
pageSize: number;
filters: TagFilter;
},
): Query | null => {
params: { orderBy: OrderByPayload[]; page: number; pageSize: number },
) => {
if (!query) return null;

const paginateData = getPaginationQueryData({
filters: params.filters,
listItemId: params.log ? params.log.id : null,
orderByTimestamp,
page: params.page,
pageSize: params.pageSize,
const { orderBy, page, pageSize } = params;

const paginateDataV2 = getPaginationQueryDataV2({
orderBy,
page,
pageSize,
});

const queryData: IBuilderQuery[] =
Expand All @@ -319,7 +305,7 @@ function LogsExplorerViews({
: [
{
...(listQuery || initialQueryBuilderFormValues),
...paginateData,
...paginateDataV2,
},
];

Expand All @@ -333,53 +319,37 @@ function LogsExplorerViews({

return data;
},
[orderByTimestamp, listQuery],
[listQuery],
);

const handleEndReached = useCallback(
(index: number) => {
if (!listQuery) return;

if (isLimit) return;
if (logs.length < pageSize) return;
const handleEndReached = useCallback(() => {
if (!listQuery) return;

const { limit, filters } = listQuery;
if (isLimit) return;
if (logs.length < pageSize) return;

const lastLog = logs[index];
const { orderBy } = listQuery;

const nextLogsLength = logs.length + pageSize;
if (!stagedQuery) return;

const nextPageSize =
limit && nextLogsLength >= limit ? limit - logs.length : pageSize;

if (!stagedQuery) return;

const newRequestData = getRequestData(stagedQuery, {
filters,
page: page + 1,
log: orderByTimestamp ? lastLog : null,
pageSize: nextPageSize,
});

// initialise the last log timestamp to null as we don't have the logs.
// as soon as we scroll to the end of the logs we set the lastLogLineTimestamp to the last log timestamp.
setLastLogLineTimestamp(lastLog.timestamp);
const newRequestDataV2 = getRequestData(stagedQuery, {
orderBy,
page: page + 1,
pageSize,
});

setPage((prevPage) => prevPage + 1);
setPage((prevPage) => prevPage + 1);

setRequestData(newRequestData);
},
[
isLimit,
logs,
listQuery,
pageSize,
stagedQuery,
getRequestData,
page,
orderByTimestamp,
],
);
setRequestData(newRequestDataV2);
}, [
listQuery,
isLimit,
logs.length,
pageSize,
stagedQuery,
getRequestData,
page,
]);

useEffect(() => {
setQueryId(v4());
Expand Down Expand Up @@ -568,9 +538,8 @@ function LogsExplorerViews({
currentMinTimeRef.current !== minTime
) {
const newRequestData = getRequestData(stagedQuery, {
filters: listQuery?.filters || initialFilters,
orderBy: listQuery?.orderBy || initialOrderBy,
page: 1,
log: null,
pageSize,
});

Expand All @@ -582,14 +551,14 @@ function LogsExplorerViews({
}, [
stagedQuery,
requestData,
getRequestData,
listQuery,
pageSize,
minTime,
activeLogId,
onTimeRangeChange,
panelType,
selectedView,
getRequestData,
]);

const chartData = useMemo(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { parse } from 'papaparse';
import { useCallback, useMemo, useState } from 'react';
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
import { OrderByPayload } from 'types/api/queryBuilder/queryBuilderData';
import { DataSource } from 'types/common/queryBuilder';

import { getRemoveOrderFromValue } from '../QueryBuilderSearch/utils';
import { getUniqueOrderByValues, getValidOrderByResult } from '../utils';
Expand Down Expand Up @@ -87,6 +88,45 @@ export const useOrderByFilter = ({
[customValue, debouncedSearchText, selectedValue],
);

const handleLogsOrderByTimestampCases = (
orderByValues: OrderByPayload[],
): void => {
if (query.dataSource !== DataSource.LOGS) {
return;
}

const hasTimestampInPreviousState = selectedValue.some(
(item) => getRemoveOrderFromValue(item.value) === 'timestamp',
);
const hasTimestampInNewState = orderByValues.some(
(item) => item.columnName === 'timestamp',
);
const hasIdInNewState = orderByValues.some(
(item) => item.columnName === 'id',
);

// Remove ID if timestamp was removed
if (
hasTimestampInPreviousState &&
!hasTimestampInNewState &&
hasIdInNewState
) {
const idIndex = orderByValues.findIndex((item) => item.columnName === 'id');
orderByValues.splice(idIndex, 1);
}
// Add ID when timestamp exists
else if (!hasIdInNewState && hasTimestampInNewState) {
const timestampOrder =
orderByValues.find((item) => item.columnName === 'timestamp')?.order ??
'asc';

orderByValues.push({
columnName: 'id',
order: timestampOrder,
});
}
};

const handleChange = (values: IOption[]): void => {
const validResult = getValidOrderByResult(values);
const result = getUniqueOrderByValues(validResult);
Expand Down Expand Up @@ -114,6 +154,8 @@ export const useOrderByFilter = ({
};
});

handleLogsOrderByTimestampCases(orderByValues);

setSearchText('');
onChange(orderByValues);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,46 @@
import { IOption } from 'hooks/useResourceAttribute/types';
import { cloneDeep } from 'lodash-es';
import { parse } from 'papaparse';
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
import {
IBuilderQuery,
OrderByPayload,
} from 'types/api/queryBuilder/queryBuilderData';
import { DataSource } from 'types/common/queryBuilder';

import { ORDERBY_FILTERS } from './config';
import { SIGNOZ_VALUE } from './constants';

export const orderByValueDelimiter = '|';

const getOrderBy = (query: IBuilderQuery): OrderByPayload[] => {
let orderBy = cloneDeep(query.orderBy);

if (query.dataSource !== DataSource.LOGS) {
return orderBy;
}

const isIdPresent = orderBy.some((item) => item.columnName === 'id');
const timestampOrder = orderBy.find((item) => item.columnName === 'timestamp')
?.order;
const isTimestampPresent =
orderBy.some((item) => item.columnName === 'timestamp') && timestampOrder;

// Add ID if timestamp is present
if (isTimestampPresent && !isIdPresent) {
orderBy = [...orderBy, { columnName: 'id', order: timestampOrder }];
}

return orderBy;
};

export const transformToOrderByStringValues = (
query: IBuilderQuery,
entityVersion?: string,
): IOption[] => {
const prepareSelectedValue: IOption[] = query.orderBy.map((item) => {
const orderBy = getOrderBy(query);

const prepareSelectedValue: IOption[] = orderBy.map((item) => {
if (item.columnName === SIGNOZ_VALUE) {
return {
label: `${
Expand Down
38 changes: 38 additions & 0 deletions frontend/src/lib/newQueryBuilder/getPaginationQueryData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,44 @@ type SetupPaginationQueryData = (
params: SetupPaginationQueryDataParams,
) => Partial<IBuilderQuery>;

export const getPaginationQueryDataV2 = ({
orderBy,
page,
pageSize,
}: {
orderBy: OrderByPayload[];
page: number;
pageSize: number;
}): any => {
const hasOrderById = orderBy.some((item) => item.columnName === 'id');
const hasOrderByTimestamp = orderBy.some(
(item) => item.columnName === 'timestamp',
);

const offset = (page - 1) * pageSize;

const queryProps = {
offset,
pageSize,
};

const updatedOrderBy =
!hasOrderById && hasOrderByTimestamp
? [
...orderBy,
{
columnName: 'id',
order: 'ASC',
},
]
: orderBy;

return {
orderBy: updatedOrderBy,
...queryProps,
};
};

export const getPaginationQueryData: SetupPaginationQueryData = ({
filters,
listItemId,
Expand Down

0 comments on commit 6d2baca

Please sign in to comment.