([log]);
+
+ const {
+ logs: previousLogs,
+ isFetching: isPreviousLogsFetching,
+ handleShowNextLines: handlePreviousLogsShowNextLine,
+ } = useContextLogData({
+ log,
+ filters,
+ isEdit,
+ query,
+ order: ORDERBY_FILTERS.ASC,
+ page: prevLogPage,
+ setPage: setPrevLogPage,
+ });
+
+ const {
+ logs: afterLogs,
+ isFetching: isAfterLogsFetching,
+ handleShowNextLines: handleAfterLogsShowNextLine,
+ } = useContextLogData({
+ log,
+ filters,
+ isEdit,
+ query,
+ order: ORDERBY_FILTERS.DESC,
+ page: afterLogPage,
+ setPage: setAfterLogPage,
+ });
+
+ useEffect(() => {
+ setLogs((prev) => [...previousLogs, ...prev]);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [previousLogs]);
+
+ useEffect(() => {
+ setLogs((prev) => [...prev, ...afterLogs]);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [afterLogs]);
+
+ useEffect(() => {
+ setLogs([log]);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [filters]);
+
+ const getItemContent = useCallback(
+ (_: number, logTorender: ILog): JSX.Element => (
+
+ ),
+ [log.id],
+ );
+
+ return (
+
+
+ {isPreviousLogsFetching && (
+
+ )}
+
+ {isAfterLogsFetching && (
+
+ )}
+
+
+ );
+}
+
+interface ContextLogRendererProps {
+ isEdit: boolean;
+ query: Query;
+ log: ILog;
+ filters: TagFilter | null;
+}
+
+export default ContextLogRenderer;
diff --git a/frontend/src/container/LogDetailedView/ContextView/ContextView.styles.scss b/frontend/src/container/LogDetailedView/ContextView/ContextView.styles.scss
index bc8ae4f719..bfb267b607 100644
--- a/frontend/src/container/LogDetailedView/ContextView/ContextView.styles.scss
+++ b/frontend/src/container/LogDetailedView/ContextView/ContextView.styles.scss
@@ -1,3 +1,23 @@
.log-context-container {
border: 1px solid var(--bg-slate-400);
-}
\ No newline at end of file
+ flex: 1;
+ position: relative;
+ overflow: scroll;
+ overflow-x: hidden;
+
+ &::-webkit-scrollbar {
+ width: 0.3rem;
+ }
+
+ &::-webkit-scrollbar-track {
+ background: transparent;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background: var(--bg-slate-300);
+ }
+
+ &::-webkit-scrollbar-thumb:hover {
+ background: var(--bg-slate-200);
+ }
+}
diff --git a/frontend/src/container/LogDetailedView/ContextView/ContextView.tsx b/frontend/src/container/LogDetailedView/ContextView/ContextView.tsx
index e3a3c2d67b..fbb3f611f3 100644
--- a/frontend/src/container/LogDetailedView/ContextView/ContextView.tsx
+++ b/frontend/src/container/LogDetailedView/ContextView/ContextView.tsx
@@ -1,11 +1,10 @@
import './ContextView.styles.scss';
-import RawLogView from 'components/Logs/RawLogView';
-import LogsContextList from 'container/LogsContextList';
-import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
import { ILog } from 'types/api/logs/log';
import { Query, TagFilter } from 'types/api/queryBuilder/queryBuilderData';
+import ContextLogRenderer from './ContextLogRenderer';
+
interface LogContextProps {
log: ILog;
contextQuery: Query | undefined;
@@ -24,28 +23,11 @@ function ContextView({
return (
-
-
-
);
diff --git a/frontend/src/container/LogDetailedView/ContextView/useContextLogData.ts b/frontend/src/container/LogDetailedView/ContextView/useContextLogData.ts
new file mode 100644
index 0000000000..5a0ef84741
--- /dev/null
+++ b/frontend/src/container/LogDetailedView/ContextView/useContextLogData.ts
@@ -0,0 +1,163 @@
+import { DEFAULT_ENTITY_VERSION } from 'constants/app';
+import { PANEL_TYPES } from 'constants/queryBuilder';
+import {
+ getOrderByTimestamp,
+ INITIAL_PAGE_SIZE,
+ LOGS_MORE_PAGE_SIZE,
+} from 'container/LogsContextList/configs';
+import { getRequestData } from 'container/LogsContextList/utils';
+import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
+import { useGetExplorerQueryRange } from 'hooks/queryBuilder/useGetExplorerQueryRange';
+import {
+ Dispatch,
+ SetStateAction,
+ useCallback,
+ useEffect,
+ useMemo,
+ useState,
+} from 'react';
+import { SuccessResponse } from 'types/api';
+import { ILog } from 'types/api/logs/log';
+import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
+import { Query, TagFilter } from 'types/api/queryBuilder/queryBuilderData';
+
+export const useContextLogData = ({
+ log,
+ query,
+ order,
+ isEdit,
+ filters,
+ page,
+ setPage,
+}: {
+ log: ILog;
+ query: Query;
+ order: string;
+ isEdit: boolean;
+ filters: TagFilter | null;
+ page: number;
+ setPage: Dispatch>;
+}): {
+ logs: ILog[];
+ handleShowNextLines: () => void;
+ isError: boolean;
+ isFetching: boolean;
+ isDisabledFetch: boolean;
+} => {
+ const [logs, setLogs] = useState([]);
+
+ const orderByTimestamp = useMemo(() => getOrderByTimestamp(order), [order]);
+
+ const logsMorePageSize = useMemo(() => (page - 1) * LOGS_MORE_PAGE_SIZE, [
+ page,
+ ]);
+ const pageSize = useMemo(
+ () => (page <= 1 ? INITIAL_PAGE_SIZE : logsMorePageSize + INITIAL_PAGE_SIZE),
+ [page, logsMorePageSize],
+ );
+ const isDisabledFetch = useMemo(() => logs.length < pageSize, [
+ logs.length,
+ pageSize,
+ ]);
+
+ const currentStagedQueryData = useMemo(() => {
+ if (!query || query.builder.queryData.length !== 1) return null;
+
+ return query.builder.queryData[0];
+ }, [query]);
+
+ const initialLogsRequest = useMemo(
+ () =>
+ getRequestData({
+ stagedQueryData: currentStagedQueryData,
+ query,
+ log,
+ orderByTimestamp,
+ page,
+ }),
+ [currentStagedQueryData, page, log, query, orderByTimestamp],
+ );
+
+ const [requestData, setRequestData] = useState(
+ initialLogsRequest,
+ );
+
+ const handleSuccess = useCallback(
+ (data: SuccessResponse) => {
+ const currentData = data?.payload.data.newResult.data.result || [];
+
+ if (currentData.length > 0 && currentData[0].list) {
+ const currentLogs: ILog[] = currentData[0].list.map((item) => ({
+ ...item.data,
+ timestamp: item.timestamp,
+ }));
+
+ if (order === ORDERBY_FILTERS.ASC) {
+ const reversedCurrentLogs = currentLogs.reverse();
+ setLogs([...reversedCurrentLogs]);
+ } else {
+ setLogs([...currentLogs]);
+ }
+ }
+ },
+ [order],
+ );
+
+ const { isError, isFetching } = useGetExplorerQueryRange(
+ requestData,
+ PANEL_TYPES.LIST,
+ DEFAULT_ENTITY_VERSION,
+ {
+ keepPreviousData: true,
+ enabled: !!requestData,
+ onSuccess: handleSuccess,
+ },
+ );
+
+ const handleShowNextLines = useCallback(() => {
+ const newRequestData = getRequestData({
+ stagedQueryData: currentStagedQueryData,
+ query,
+ log,
+ orderByTimestamp,
+ page: page + 1,
+ pageSize: LOGS_MORE_PAGE_SIZE,
+ });
+
+ setPage((prevPage) => prevPage + 1);
+ setRequestData(newRequestData);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [
+ query,
+ page,
+ order,
+ currentStagedQueryData,
+ isDisabledFetch,
+ orderByTimestamp,
+ ]);
+
+ useEffect(() => {
+ if (!isEdit) return;
+
+ const newRequestData = getRequestData({
+ stagedQueryData: currentStagedQueryData,
+ query,
+ log,
+ orderByTimestamp,
+ page: 1,
+ });
+
+ setPage(1);
+ setLogs([]);
+ setRequestData(newRequestData);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [filters]);
+
+ return {
+ logs,
+ handleShowNextLines,
+ isError,
+ isFetching,
+ isDisabledFetch,
+ };
+};