Yunus M ab4f6adb19
Logs explorer design update (#4352)
* feat: logs explorer - new design

* feat: update styles

* feat: added new toolbar for logs explorer (#4336)

* feat: logs list view changes (#4348)

* feat: logs list view changes

* fix: list view and toolbar styles

* feat: side btns

* feat: added auto refresh handler

* feat: handle popover close for btn click date time

* feat: extract the common log actions btn component

* feat: update the button for log line actions

* fix: event propagation from context button

* feat: use styles from ui-library

* Query builder design update (#4359)

* feat: QB design update

* fix: add functionality and light mode styles

* fix: ts issues

* fix: update all css color variables to correct names

* fix: lint errors

* feat: new table view for logs explorer list section  (#4353)

* feat: table view changes for logs list

* feat: code refactor to support log line actions

* feat: code refactor to support log line actions

* fix: the positioning of the btns

* feat: fix the table onclick

* fix: header issue

* fix: on hover

* fix: type issue

* fix: eslint error

* fix: type errors (#4360)

* feat: handle light theme for logs explorer design changes (#4363)

* feat: handle light theme for list tables and dateTime selection

* feat: handle light theme for popover

* fix: address review comments

* feat: date time custom time modal to render inside the new popover (#4366)

* feat: single calender for range picker

* fix: edgecases

* feat: integrate date time selector across app

* fix: remove dangling border after element removal

* feat: handle qb design changes across the application

* feat: handle light theme

* feat: handle light theme

* fix: virtuoso scroll refresh issue

* feat: handle new typing changes for date time picker v2 (#4386)

Co-authored-by: Yunus M <myounis.ar@live.com>

* chore: styles improvement across new design (#4389)

* fix: improve date time styles

* feat: table view changes according to new design

* fix: button visibility in clickhouse and promQL headers (#4390)

* feat: change the tabs to new design buttons for query builder

* Settings theme change (#4368)

* feat: settings theme change

* [Refactor]: New design for Log details page (#4362)

New design for Log details page 

Co-authored-by: Vikrant Gupta <vikrant.thomso@gmail.com>
Co-authored-by: Yunus M <myounis.ar@live.com>

* feat: save view for new design (#4392)

* feat: save view for new design

* refactor: done with save view

* feat: update styles for logs detail view (#4407)

* feat: update styles for logs detail view

* feat: update styles for logs detail view

* feat: add raw view attributes in the logs list view (#4422)

* feat: add raw view attributes in the logs list view

* feat: add raw view attributes in the logs list view

* fix: raw attributes

* fix: logs UI improvements (#4426)

* fix: remove fixed times from the date time picker v2

* fix: added old logs explorer CTA in new designs

* feat: handle active logs indicator update

* fix: address review comments

* fix: old logs explorer page

* fix: remove info text and add relative time buttons

* fix: update logs explorer tab designs

* fix: update logs explorer tab designs

* fix: update logs explorer tab designs

* refactor: New design for Save views. (#4435)

* feat: [GH-4436]: date range enhancements (#4448)

* feat: [GH-4436]: when selecting custom time range it should be from start of day to end of date

* fix: custom time width and refresh text visibility issues (#4428)

---------

Co-authored-by: Yunus M <myounis.ar@live.com>

* feat: update ui (#4449)

* feat: added loading and error states for logs design (#4452)

* feat: added loading and error states for logs design

* feat: added error states for table view and time series view

* feat: handle error and loading states

* feat: loading states

* [Refactor]: Tab Switch deplay issue and UI improvement for Clickhouse (#4409)

* fix: switching between logs display tabs (#4457)

* [Feat]: View in Traces (#4450)

* refactor: datetime selector beside run query removed add to dashboard

* refactor: added tab for traces view details page

* refactor: done with the save view in traces

* fix: the gittery effect when navigatigating from views

* refactor: view tab view title light mode support

* refactor: removed console

* fix: gittery effect when switch view from views tabs

* refactor: separate traces routes

* refactor: remove query params

* chore: fix tsc issues

* fix: jest config issues

* fix: update TODO and remove extra braces

* feat: handle loading states and incorporate ui feedback (#4479)

* UI feedback updates (#4482)

* feat: handle loading and fix ui issues

* feat: ui updates

* fix: logs explorer issues (#4483)

* fix: logs explorer issues

* fix: jest test cases

* feat: support custom times unique to pages new design changes (#4485)

* fix: loading states for list log view (#4486)

* fix: logs search view query fix, logs details view - attribute tags alignment fix (#4489)

* fix: delete empty file

* fix: chart loading when scrolling logs (#4495)

* fix: chart should not load when scrolling the logs as it is already fetched

* fix: make the search bar as default rather than advanced options

* fix: rename show context to show in context

* fix: query range api not triggering on default select first load (#4498)

* Refactor: Log Explorer UI changes.  (#4502)

* refactor: used selected view enum

* refactor: updated hight of switch old button and tab border

* refactor: import fixes

* refactor: query builder border and button groups

* refactor: removed hypen from refreshed

* refactor: show delete button only when there is more than one query

* refactor: sqaure up the query build button groups

* refactor: updated css

* fix: additional filter color button shadow

* refactor: removed commented code and used selected panel enum

* refactor: updated typecheck script

* refactor: used enum selected view (#4504)

* fix: retain the current query on date time change (#4510)

* feat: added new icon for promQL and added tooltips for dashboards and alerts (#4512)

* feat: added new icon for promQL and added tooltips for dashboards and alerts

* fix: styles at 1440 px zoom

* fix: rename clickhouse to clickHouse

---------

Co-authored-by: Vikrant Gupta <54737045+Vikrant2520@users.noreply.github.com>
Co-authored-by: Vikrant Gupta <vikrant.thomso@gmail.com>
Co-authored-by: Rajat Dabade <rajat@signoz.io>
2024-02-12 00:23:19 +05:30

416 lines
11 KiB
TypeScript

import './Query.styles.scss';
import { Col, Input, Row } from 'antd';
// ** Constants
import { PANEL_TYPES } from 'constants/queryBuilder';
import ROUTES from 'constants/routes';
// ** Components
import {
AdditionalFiltersToggler,
DataSourceDropdown,
FilterLabel,
} from 'container/QueryBuilder/components';
import {
AggregatorFilter,
GroupByFilter,
HavingFilter,
OperatorsSelect,
OrderByFilter,
ReduceToFilter,
} from 'container/QueryBuilder/filters';
import AggregateEveryFilter from 'container/QueryBuilder/filters/AggregateEveryFilter';
import LimitFilter from 'container/QueryBuilder/filters/LimitFilter/LimitFilter';
import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
// ** Hooks
import {
ChangeEvent,
memo,
ReactNode,
useCallback,
useMemo,
useState,
} from 'react';
import { useLocation } from 'react-use';
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
import { transformToUpperCase } from 'utils/transformToUpperCase';
import QBEntityOptions from '../QBEntityOptions/QBEntityOptions';
// ** Types
import { QueryProps } from './Query.interfaces';
export const Query = memo(function Query({
index,
queryVariant,
query,
filterConfigs,
queryComponents,
}: QueryProps): JSX.Element {
const { panelType } = useQueryBuilder();
const { pathname } = useLocation();
const [isCollapse, setIsCollapsed] = useState(false);
const {
operators,
isMetricsDataSource,
isTracePanelType,
listOfAdditionalFilters,
handleChangeAggregatorAttribute,
handleChangeQueryData,
handleChangeDataSource,
handleChangeOperator,
handleDeleteQuery,
} = useQueryOperations({ index, query, filterConfigs });
const handleChangeAggregateEvery = useCallback(
(value: IBuilderQuery['stepInterval']) => {
handleChangeQueryData('stepInterval', value);
},
[handleChangeQueryData],
);
const handleChangeLimit = useCallback(
(value: IBuilderQuery['limit']) => {
handleChangeQueryData('limit', value);
},
[handleChangeQueryData],
);
const handleChangeHavingFilter = useCallback(
(value: IBuilderQuery['having']) => {
handleChangeQueryData('having', value);
},
[handleChangeQueryData],
);
const handleChangeOrderByKeys = useCallback(
(value: IBuilderQuery['orderBy']) => {
handleChangeQueryData('orderBy', value);
},
[handleChangeQueryData],
);
const handleToggleDisableQuery = useCallback(() => {
handleChangeQueryData('disabled', !query.disabled);
}, [handleChangeQueryData, query]);
const handleChangeTagFilters = useCallback(
(value: IBuilderQuery['filters']) => {
handleChangeQueryData('filters', value);
},
[handleChangeQueryData],
);
const handleChangeReduceTo = useCallback(
(value: IBuilderQuery['reduceTo']) => {
handleChangeQueryData('reduceTo', value);
},
[handleChangeQueryData],
);
const handleChangeGroupByKeys = useCallback(
(value: IBuilderQuery['groupBy']) => {
handleChangeQueryData('groupBy', value);
},
[handleChangeQueryData],
);
const handleChangeQueryLegend = useCallback(
(event: ChangeEvent<HTMLInputElement>) => {
handleChangeQueryData('legend', event.target.value);
},
[handleChangeQueryData],
);
const handleToggleCollapsQuery = (): void => {
setIsCollapsed(!isCollapse);
};
const renderOrderByFilter = useCallback((): ReactNode => {
if (queryComponents?.renderOrderBy) {
return queryComponents.renderOrderBy({
query,
onChange: handleChangeOrderByKeys,
});
}
return <OrderByFilter query={query} onChange={handleChangeOrderByKeys} />;
}, [queryComponents, query, handleChangeOrderByKeys]);
const renderAggregateEveryFilter = useCallback(
(): JSX.Element | null =>
!filterConfigs?.stepInterval?.isHidden ? (
<Row gutter={[11, 5]}>
<Col flex="5.93rem">
<FilterLabel label="Aggregate Every" />
</Col>
<Col flex="1 1 6rem">
<AggregateEveryFilter
query={query}
disabled={filterConfigs?.stepInterval?.isDisabled || false}
onChange={handleChangeAggregateEvery}
/>
</Col>
</Row>
) : null,
[
filterConfigs?.stepInterval?.isHidden,
filterConfigs?.stepInterval?.isDisabled,
query,
handleChangeAggregateEvery,
],
);
const isExplorerPage = useMemo(
() =>
pathname === ROUTES.LOGS_EXPLORER || pathname === ROUTES.TRACES_EXPLORER,
[pathname],
);
const renderAdditionalFilters = useCallback((): ReactNode => {
switch (panelType) {
case PANEL_TYPES.TIME_SERIES: {
return (
<>
<Col span={11}>
<Row gutter={[11, 5]}>
<Col flex="5.93rem">
<FilterLabel label="Limit" />
</Col>
<Col flex="1 1 12.5rem">
<LimitFilter query={query} onChange={handleChangeLimit} />
</Col>
</Row>
</Col>
<Col span={11}>
<Row gutter={[11, 5]}>
<Col flex="5.93rem">
<FilterLabel label="HAVING" />
</Col>
<Col flex="1 1 12.5rem">
<HavingFilter onChange={handleChangeHavingFilter} query={query} />
</Col>
</Row>
</Col>
<Col span={11}>
<Row gutter={[11, 5]}>
<Col flex="5.93rem">
<FilterLabel label="Order by" />
</Col>
<Col flex="1 1 12.5rem">{renderOrderByFilter()}</Col>
</Row>
</Col>
<Col span={11}>{renderAggregateEveryFilter()}</Col>
</>
);
}
case PANEL_TYPES.VALUE: {
return (
<>
<Col span={11}>
<Row gutter={[11, 5]}>
<Col flex="5.93rem">
<FilterLabel label="HAVING" />
</Col>
<Col flex="1 1 12.5rem">
<HavingFilter onChange={handleChangeHavingFilter} query={query} />
</Col>
</Row>
</Col>
<Col span={11}>{renderAggregateEveryFilter()}</Col>
</>
);
}
default: {
return (
<>
{!filterConfigs?.limit?.isHidden && (
<Col span={11}>
<Row gutter={[11, 5]}>
<Col flex="5.93rem">
<FilterLabel label="Limit" />
</Col>
<Col flex="1 1 12.5rem">
<LimitFilter query={query} onChange={handleChangeLimit} />
</Col>
</Row>
</Col>
)}
{!filterConfigs?.having?.isHidden && (
<Col span={11}>
<Row gutter={[11, 5]}>
<Col flex="5.93rem">
<FilterLabel label="HAVING" />
</Col>
<Col flex="1 1 12.5rem">
<HavingFilter onChange={handleChangeHavingFilter} query={query} />
</Col>
</Row>
</Col>
)}
<Col span={11}>
<Row gutter={[11, 5]}>
<Col flex="5.93rem">
<FilterLabel label="Order by" />
</Col>
<Col flex="1 1 12.5rem">{renderOrderByFilter()}</Col>
</Row>
</Col>
<Col span={11}>{renderAggregateEveryFilter()}</Col>
</>
);
}
}
}, [
panelType,
query,
filterConfigs?.limit?.isHidden,
filterConfigs?.having?.isHidden,
handleChangeLimit,
handleChangeHavingFilter,
renderOrderByFilter,
renderAggregateEveryFilter,
]);
return (
<Row gutter={[0, 12]}>
<QBEntityOptions
isCollapsed={isCollapse}
entityType="query"
entityData={query}
onToggleVisibility={handleToggleDisableQuery}
onDelete={handleDeleteQuery}
onCollapseEntity={handleToggleCollapsQuery}
/>
{!isCollapse && (
<Row gutter={[0, 12]} className="qb-container">
<Col span={24}>
<Row align="middle" gutter={[5, 11]}>
{!isExplorerPage && (
<Col>
{queryVariant === 'dropdown' ? (
<DataSourceDropdown
onChange={handleChangeDataSource}
value={query.dataSource}
style={{ minWidth: '5.625rem' }}
/>
) : (
<FilterLabel label={transformToUpperCase(query.dataSource)} />
)}
</Col>
)}
{isMetricsDataSource && (
<Col span={12}>
<Row gutter={[11, 5]}>
<Col flex="5.93rem">
<OperatorsSelect
value={query.aggregateOperator}
onChange={handleChangeOperator}
operators={operators}
/>
</Col>
<Col flex="auto">
<AggregatorFilter
onChange={handleChangeAggregatorAttribute}
query={query}
/>
</Col>
</Row>
</Col>
)}
<Col flex="1 1 20rem">
<Row gutter={[11, 5]}>
{isMetricsDataSource && (
<Col>
<FilterLabel label="WHERE" />
</Col>
)}
<Col flex="1" className="qb-search-container">
<QueryBuilderSearch
query={query}
onChange={handleChangeTagFilters}
whereClauseConfig={filterConfigs?.filters}
/>
</Col>
</Row>
</Col>
</Row>
</Col>
{!isMetricsDataSource && (
<Col span={11}>
<Row gutter={[11, 5]}>
<Col flex="5.93rem">
<OperatorsSelect
value={query.aggregateOperator}
onChange={handleChangeOperator}
operators={operators}
/>
</Col>
<Col flex="1 1 12.5rem">
<AggregatorFilter
query={query}
onChange={handleChangeAggregatorAttribute}
disabled={
panelType === PANEL_TYPES.LIST || panelType === PANEL_TYPES.TRACE
}
/>
</Col>
</Row>
</Col>
)}
<Col span={11} offset={isMetricsDataSource ? 0 : 2}>
<Row gutter={[11, 5]}>
<Col flex="5.93rem">
<FilterLabel
label={panelType === PANEL_TYPES.VALUE ? 'Reduce to' : 'Group by'}
/>
</Col>
<Col flex="1 1 12.5rem">
{panelType === PANEL_TYPES.VALUE ? (
<ReduceToFilter query={query} onChange={handleChangeReduceTo} />
) : (
<GroupByFilter
disabled={isMetricsDataSource && !query.aggregateAttribute.key}
query={query}
onChange={handleChangeGroupByKeys}
/>
)}
</Col>
</Row>
</Col>
{!isTracePanelType && (
<Col span={24}>
<AdditionalFiltersToggler
listOfAdditionalFilter={listOfAdditionalFilters}
>
<Row gutter={[0, 11]} justify="space-between">
{renderAdditionalFilters()}
</Row>
</AdditionalFiltersToggler>
</Col>
)}
{panelType !== PANEL_TYPES.LIST && panelType !== PANEL_TYPES.TRACE && (
<Row style={{ width: '100%' }}>
<Input
onChange={handleChangeQueryLegend}
size="middle"
value={query.legend}
addonBefore="Legend Format"
/>
</Row>
)}
</Row>
)}
</Row>
);
});