feat: use qb-v2 in explorers and alerts

This commit is contained in:
Yunus M 2025-06-05 04:05:33 +05:30 committed by ahrefabhi
parent a66c8e671f
commit c9cbc75217
29 changed files with 500 additions and 475 deletions

View File

@ -5,10 +5,12 @@
width: 100%;
border-bottom: 1px solid var(--bg-slate-400);
border-top: 1px solid var(--bg-slate-400);
font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
'Helvetica Neue', sans-serif;
border: 1px solid var(--bg-slate-400);
border-right: none;
border-left: none;
@ -90,6 +92,27 @@
}
}
.where-clause-view {
.qb-content-section {
.qb-elements-container {
margin-left: 0px;
.code-mirror-where-clause,
.query-aggregation-container,
.query-add-ons,
.metrics-aggregation-section-content {
&::before {
display: none;
}
&::after {
display: none;
}
}
}
}
}
.query-names-section {
display: flex;
flex-direction: column;

View File

@ -18,6 +18,7 @@ export const QueryBuilderV2 = memo(function QueryBuilderV2({
queryComponents,
isListViewPanel = false,
showFunctions = false,
showOnlyWhereClause = false,
version,
}: QueryBuilderProps): JSX.Element {
const {
@ -67,12 +68,13 @@ export const QueryBuilderV2 = memo(function QueryBuilderV2({
queryComponents={queryComponents}
version={version}
isAvailableToDisable={false}
showSpanScopeSelector
showSpanScopeSelector={initialDataSource === DataSource.TRACES}
queryVariant={config?.queryVariant || 'dropdown'}
showOnlyWhereClause={showOnlyWhereClause}
/>
))}
{currentQuery.builder.queryFormulas.length > 0 && (
{!showOnlyWhereClause && currentQuery.builder.queryFormulas.length > 0 && (
<div className="qb-formulas-container">
{currentQuery.builder.queryFormulas.map((formula, index) => {
const query =
@ -94,25 +96,29 @@ export const QueryBuilderV2 = memo(function QueryBuilderV2({
</div>
)}
<QueryFooter
addNewBuilderQuery={addNewBuilderQuery}
addNewFormula={addNewFormula}
/>
{!showOnlyWhereClause && (
<QueryFooter
addNewBuilderQuery={addNewBuilderQuery}
addNewFormula={addNewFormula}
/>
)}
</div>
<div className="query-names-section">
{currentQuery.builder.queryData.map((query) => (
<div key={query.queryName} className="query-name">
{query.queryName}
</div>
))}
{!showOnlyWhereClause && (
<div className="query-names-section">
{currentQuery.builder.queryData.map((query) => (
<div key={query.queryName} className="query-name">
{query.queryName}
</div>
))}
{currentQuery.builder.queryFormulas.map((formula) => (
<div key={formula.queryName} className="formula-name">
{formula.queryName}
</div>
))}
</div>
{currentQuery.builder.queryFormulas.map((formula) => (
<div key={formula.queryName} className="formula-name">
{formula.queryName}
</div>
))}
</div>
)}
</div>
</QueryBuilderV2Provider>
);

View File

@ -4,6 +4,7 @@ import { Button, Radio, RadioChangeEvent } from 'antd';
import InputWithLabel from 'components/InputWithLabel/InputWithLabel';
import { GroupByFilter } from 'container/QueryBuilder/filters/GroupByFilter/GroupByFilter';
import { OrderByFilter } from 'container/QueryBuilder/filters/OrderByFilter/OrderByFilter';
import { ReduceToFilter } from 'container/QueryBuilder/filters/ReduceToFilter/ReduceToFilter';
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
import { BarChart2, ScrollText, X } from 'lucide-react';
import { useCallback, useState } from 'react';
@ -44,16 +45,23 @@ const ADD_ONS: Record<string, AddOn> = {
label: 'Legend format',
key: 'legend_format',
},
REDUCE_TO: {
icon: <ScrollText size={14} />,
label: 'Reduce to',
key: 'reduce_to',
},
};
function QueryAddOns({
query,
version,
isListViewPanel,
showReduceTo,
}: {
query: IBuilderQuery;
version: string;
isListViewPanel: boolean;
showReduceTo: boolean;
}): JSX.Element {
const [selectedViews, setSelectedViews] = useState<AddOn[]>([]);
@ -87,6 +95,13 @@ function QueryAddOns({
[handleChangeQueryData],
);
const handleChangeReduceTo = useCallback(
(value: IBuilderQuery['reduceTo']) => {
handleChangeQueryData('reduceTo', value);
},
[handleChangeQueryData],
);
const handleRemoveView = useCallback(
(key: string): void => {
setSelectedViews(selectedViews.filter((view) => view.key !== key));
@ -139,7 +154,7 @@ function QueryAddOns({
{selectedViews.find((view) => view.key === 'limit') && (
<div className="add-on-content">
<InputWithLabel
label="LIMIT"
label="Limit"
placeholder="Enter limit"
onClose={(): void => {
setSelectedViews(selectedViews.filter((view) => view.key !== 'limit'));
@ -167,10 +182,28 @@ function QueryAddOns({
</div>
</div>
)}
{selectedViews.find((view) => view.key === 'reduce_to') && showReduceTo && (
<div className="add-on-content">
<div className="periscope-input-with-label">
<div className="label">Reduce to</div>
<div className="input">
<ReduceToFilter query={query} onChange={handleChangeReduceTo} />
</div>
<Button
className="close-btn periscope-btn ghost"
icon={<X size={16} />}
onClick={(): void => handleRemoveView('reduce_to')}
/>
</div>
</div>
)}
{selectedViews.find((view) => view.key === 'legend_format') && (
<div className="add-on-content">
<InputWithLabel
label="LEGEND FORMAT"
label="Legend format"
placeholder="Write legend format"
onClose={(): void => {
setSelectedViews(
@ -189,22 +222,24 @@ function QueryAddOns({
onChange={handleOptionClick}
value={selectedViews}
>
{Object.values(ADD_ONS).map((addOn) => (
<Radio.Button
key={addOn.label}
className={
selectedViews.find((view) => view.key === addOn.key)
? 'selected-view tab'
: 'tab'
}
value={addOn}
>
<div className="add-on-tab-title">
{addOn.icon}
{addOn.label}
</div>
</Radio.Button>
))}
{Object.values(ADD_ONS)
.filter((addOn) => addOn.key !== 'reduce_to' || showReduceTo)
.map((addOn) => (
<Radio.Button
key={addOn.label}
className={
selectedViews.find((view) => view.key === addOn.key)
? 'selected-view tab'
: 'tab'
}
value={addOn}
>
<div className="add-on-tab-title">
{addOn.icon}
{addOn.label}
</div>
</Radio.Button>
))}
</Radio.Group>
</div>
</div>
@ -212,60 +247,3 @@ function QueryAddOns({
}
export default QueryAddOns;
/*
<Radio.Button
className={
// eslint-disable-next-line sonarjs/no-duplicate-string
selectedView === ADD_ONS.GROUP_BY ? 'selected_view tab' : 'tab'
}
value={ADD_ONS.GROUP_BY}
>
<div className="add-on-tab-title">
<BarChart2 size={14} />
{selectedView.label}
</div>
</Radio.Button>
<Radio.Button
className={selectedView === ADD_ONS.HAVING ? 'selected_view tab' : 'tab'}
value={ADD_ONS.HAVING}
>
<div className="add-on-tab-title">
<ScrollText size={14} />
{selectedView.label}
</div>
</Radio.Button>
<Radio.Button
className={
selectedView === ADD_ONS.ORDER_BY ? 'selected_view tab' : 'tab'
}
value={ADD_ONS.ORDER_BY}
>
<div className="add-on-tab-title">
<DraftingCompass size={14} />
{selectedView.label}
</div>
</Radio.Button>
<Radio.Button
className={selectedView === ADD_ONS.LIMIT ? 'selected_view tab' : 'tab'}
value={ADD_ONS.LIMIT}
>
<div className="add-on-tab-title">
<Package2 size={14} />
{selectedView.label}
</div>
</Radio.Button>
<Radio.Button
className={
selectedView === ADD_ONS.LEGEND_FORMAT ? 'selected_view tab' : 'tab'
}
value={ADD_ONS.LEGEND_FORMAT}
>
<div className="add-on-tab-title">
<ChevronsLeftRight size={14} />
{selectedView.label}
</div>
</Radio.Button>
*/

View File

@ -1,17 +1,10 @@
import './QueryAggregation.styles.scss';
import InputWithLabel from 'components/InputWithLabel/InputWithLabel';
import { DataSource } from 'types/common/queryBuilder';
import QueryAggregationSelect from './QueryAggregationSelect';
function QueryAggregationOptions({
source,
}: {
source: DataSource;
}): JSX.Element {
console.log('source', source);
function QueryAggregationOptions(): JSX.Element {
return (
<div className="query-aggregation-container">
<QueryAggregationSelect />

View File

@ -1,12 +1,14 @@
import { Dropdown } from 'antd';
import cx from 'classnames';
import { ENTITY_VERSION_V4 } from 'constants/app';
import { PANEL_TYPES } from 'constants/queryBuilder';
import QBEntityOptions from 'container/QueryBuilder/components/QBEntityOptions/QBEntityOptions';
import { QueryProps } from 'container/QueryBuilder/components/Query/Query.interfaces';
import SpanScopeSelector from 'container/QueryBuilder/filters/QueryBuilderSearchV2/SpanScopeSelector';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
import { Copy, Ellipsis, Trash } from 'lucide-react';
import { memo, useCallback, useState } from 'react';
import { memo, useCallback, useMemo, useState } from 'react';
import { DataSource } from 'types/common/queryBuilder';
import MetricsAggregateSection from './MerticsAggregateSection/MetricsAggregateSection';
@ -20,18 +22,16 @@ export const QueryV2 = memo(function QueryV2({
queryVariant,
query,
filterConfigs,
queryComponents,
isListViewPanel = false,
version,
showSpanScopeSelector = false,
showOnlyWhereClause = false,
}: QueryProps): JSX.Element {
const { cloneQuery } = useQueryBuilder();
const { cloneQuery, panelType } = useQueryBuilder();
const showFunctions = query?.functions?.length > 0;
const { dataSource } = query;
console.log('queryComponents', queryComponents);
const [isCollapsed, setIsCollapsed] = useState(false);
const {
@ -59,62 +59,73 @@ export const QueryV2 = memo(function QueryV2({
cloneQuery('query', query);
};
return (
<div className="query-v2">
<div className="qb-content-section">
<div className="qb-header-container">
<div className="query-actions-container">
<div className="query-actions-left-container">
<QBEntityOptions
isMetricsDataSource={dataSource === DataSource.METRICS}
showFunctions={
(version && version === ENTITY_VERSION_V4) ||
query.dataSource === DataSource.LOGS ||
showFunctions ||
false
}
isCollapsed={isCollapsed}
entityType="query"
entityData={query}
onToggleVisibility={handleToggleDisableQuery}
onDelete={handleDeleteQuery}
onCloneQuery={cloneQuery}
onCollapseEntity={handleToggleCollapsQuery}
query={query}
onQueryFunctionsUpdates={handleQueryFunctionsUpdates}
showDeleteButton={false}
showCloneOption={false}
isListViewPanel={isListViewPanel}
index={index}
queryVariant={queryVariant}
onChangeDataSource={handleChangeDataSource}
/>
</div>
const showReduceTo = useMemo(
() =>
dataSource === DataSource.METRICS &&
(panelType === PANEL_TYPES.TABLE ||
panelType === PANEL_TYPES.PIE ||
panelType === PANEL_TYPES.VALUE),
[dataSource, panelType],
);
<Dropdown
className="query-actions-dropdown"
menu={{
items: [
{
label: 'Clone',
key: 'clone-query',
icon: <Copy size={14} />,
onClick: handleCloneEntity,
},
{
label: 'Delete',
key: 'delete-query',
icon: <Trash size={14} />,
onClick: handleDeleteQuery,
},
],
}}
placement="bottomRight"
>
<Ellipsis size={16} />
</Dropdown>
return (
<div className={cx('query-v2', { 'where-clause-view': showOnlyWhereClause })}>
<div className="qb-content-section">
{!showOnlyWhereClause && (
<div className="qb-header-container">
<div className="query-actions-container">
<div className="query-actions-left-container">
<QBEntityOptions
isMetricsDataSource={dataSource === DataSource.METRICS}
showFunctions={
(version && version === ENTITY_VERSION_V4) ||
query.dataSource === DataSource.LOGS ||
showFunctions ||
false
}
isCollapsed={isCollapsed}
entityType="query"
entityData={query}
onToggleVisibility={handleToggleDisableQuery}
onDelete={handleDeleteQuery}
onCloneQuery={cloneQuery}
onCollapseEntity={handleToggleCollapsQuery}
query={query}
onQueryFunctionsUpdates={handleQueryFunctionsUpdates}
showDeleteButton={false}
showCloneOption={false}
isListViewPanel={isListViewPanel}
index={index}
queryVariant={queryVariant}
onChangeDataSource={handleChangeDataSource}
/>
</div>
<Dropdown
className="query-actions-dropdown"
menu={{
items: [
{
label: 'Clone',
key: 'clone-query',
icon: <Copy size={14} />,
onClick: handleCloneEntity,
},
{
label: 'Delete',
key: 'delete-query',
icon: <Trash size={14} />,
onClick: handleDeleteQuery,
},
],
}}
placement="bottomRight"
>
<Ellipsis size={16} />
</Dropdown>
</div>
</div>
</div>
)}
<div className="qb-elements-container">
<div className="qb-search-container">
@ -136,13 +147,20 @@ export const QueryV2 = memo(function QueryV2({
</div>
</div>
<QueryAggregation source={dataSource} />
{!showOnlyWhereClause && <QueryAggregation />}
{dataSource === DataSource.METRICS && (
{!showOnlyWhereClause && dataSource === DataSource.METRICS && (
<MetricsAggregateSection query={query} index={0} version="v4" />
)}
<QueryAddOns query={query} version="v3" isListViewPanel={false} />
{!showOnlyWhereClause && (
<QueryAddOns
query={query}
version="v3"
isListViewPanel={false}
showReduceTo={showReduceTo}
/>
)}
</div>
</div>
</div>

View File

@ -69,7 +69,7 @@ function Download({ data, isLoading, fileName }: DownloadProps): JSX.Element {
}
>
<Button
className="periscope-btn"
className="periscope-btn ghost"
loading={isLoading}
icon={<FileDown size={14} />}
/>

View File

@ -1,12 +1,15 @@
.explorer-options-container {
position: fixed;
bottom: 24px;
bottom: 8px;
left: calc(50% + 240px);
transform: translate(calc(-50% - 120px), 0);
transition: left 0.2s linear;
border-radius: 6px;
border: 1px solid var(--Slate-500, #161922);
background: var(--Ink-300, #16181d);
display: flex;
gap: 16px;
background-color: transparent;
.multi-alert-button,
@ -32,19 +35,15 @@
.explorer-update {
display: inline-flex;
align-items: center;
gap: 12px;
padding: 10px 10px;
border-radius: 50px;
border: 1px solid var(--bg-slate-400);
background: rgba(22, 24, 29, 0.6);
backdrop-filter: blur(20px);
gap: 4px;
padding: 8px;
background: var(--Ink-300, #16181d);
.action-icon {
display: flex;
justify-content: center;
align-items: center;
padding: 8px;
border-radius: 50px;
padding: 6px;
border: 1px solid var(--bg-slate-400);
background: var(--bg-slate-500);
cursor: pointer;
@ -64,10 +63,7 @@
.explorer-options {
padding: 10px 12px;
border: 1px solid var(--bg-slate-400);
border-radius: 50px;
background: rgba(22, 24, 29, 0.6);
backdrop-filter: blur(20px);
background: var(--Ink-300, #16181d);
cursor: default;
display: flex;
@ -96,27 +92,6 @@
align-items: center;
gap: 8px;
button {
display: flex;
justify-content: center;
align-items: center;
border: none;
border: 1px solid #1d2023;
box-shadow: none !important;
&.ant-btn-round {
padding: 8px 12px 8px 10px;
font-weight: 500;
}
&.ant-btn-round:disabled {
background-color: rgba(209, 209, 209, 0.074);
color: #5f5f5f;
}
}
.ant-select-focused {
border-color: transparent !important;

View File

@ -1,12 +1,10 @@
/* eslint-disable react/jsx-props-no-spreading */
import './ExplorerOptions.styles.scss';
import { InfoCircleOutlined } from '@ant-design/icons';
import { Color } from '@signozhq/design-tokens';
import {
Button,
ColorPicker,
Divider,
Input,
Modal,
RefSelectProps,
@ -45,14 +43,7 @@ import { useHandleExplorerTabChange } from 'hooks/useHandleExplorerTabChange';
import { useNotifications } from 'hooks/useNotifications';
import { mapCompositeQueryFromQuery } from 'lib/newQueryBuilder/queryBuilderMappers/mapCompositeQueryFromQuery';
import { cloneDeep, isEqual, omit } from 'lodash-es';
import {
Check,
ConciergeBell,
Disc3,
PanelBottomClose,
Plus,
X,
} from 'lucide-react';
import { Check, ConciergeBell, Disc3, Plus, X } from 'lucide-react';
import { useAppContext } from 'providers/App/App';
import { FormattingOptions } from 'providers/preferences/types';
import {
@ -78,10 +69,8 @@ import ExplorerOptionsHideArea from './ExplorerOptionsHideArea';
import { PreservedViewsInLocalStorage } from './types';
import {
DATASOURCE_VS_ROUTES,
generateRGBAFromHex,
getRandomColor,
saveNewViewHandler,
setExplorerToolBarVisibility,
} from './utils';
const allowedRoles = [USER_ROLES.ADMIN, USER_ROLES.AUTHOR, USER_ROLES.EDITOR];
@ -253,12 +242,6 @@ function ExplorerOptions({
const extraData = viewsData?.data?.data?.find((view) => view.id === viewKey)
?.extraData;
const extraDataColor = extraData ? JSON.parse(extraData).color : '';
const rgbaColor = generateRGBAFromHex(
extraDataColor || Color.BG_SIENNA_500,
0.08,
);
const { options, handleOptionsChange } = useOptionsMenu({
storageKey:
sourcepage === DataSource.TRACES
@ -589,13 +572,6 @@ function ExplorerOptions({
[isDarkMode],
);
const hideToolbar = (): void => {
setExplorerToolBarVisibility(false, sourcepage);
if (setIsExplorerOptionHidden) {
setIsExplorerOptionHidden(true);
}
};
const isEditDeleteSupported = allowedRoles.includes(user.role as string);
const [
@ -647,27 +623,6 @@ function ExplorerOptions({
viewsData?.data?.data,
]);
const infoIconText = useMemo(() => {
if (isLogsExplorer) {
return 'Learn more about Logs explorer';
}
if (isMetricsExplorer) {
return 'Learn more about Metrics explorer';
}
return 'Learn more about Traces explorer';
}, [isLogsExplorer, isMetricsExplorer]);
const infoIconLink = useMemo(() => {
if (isLogsExplorer) {
return 'https://signoz.io/docs/product-features/logs-explorer/?utm_source=product&utm_medium=logs-explorer-toolbar';
}
// TODO: Add metrics explorer info icon link
if (isMetricsExplorer) {
return '';
}
return 'https://signoz.io/docs/product-features/trace-explorer/?utm_source=product&utm_medium=trace-explorer-toolbar';
}, [isLogsExplorer, isMetricsExplorer]);
const getQueryName = (query: Query): string => {
if (query.builder.queryFormulas.length > 0) {
return `Formula ${query.builder.queryFormulas[0].queryName}`;
@ -680,11 +635,10 @@ function ExplorerOptions({
const selectLabel = (
<Button
disabled={disabled}
shape="round"
className="periscope-btn ghost"
shape="default"
icon={<ConciergeBell size={16} />}
>
Create an Alert
</Button>
/>
);
return (
<Select
@ -713,12 +667,11 @@ function ExplorerOptions({
return (
<Button
disabled={disabled}
shape="round"
shape="default"
className="periscope-btn ghost"
onClick={(): void => onCreateAlertsHandler(query)}
icon={<ConciergeBell size={16} />}
>
Create an Alert
</Button>
/>
);
}, [
disabled,
@ -732,14 +685,11 @@ function ExplorerOptions({
if (isOneChartPerQuery) {
const selectLabel = (
<Button
type="primary"
className="periscope-btn ghost"
disabled={disabled}
shape="round"
onClick={onAddToDashboard}
icon={<Plus size={16} />}
>
Add to Dashboard
</Button>
icon={<Plus size={12} />}
/>
);
return (
<Select
@ -771,14 +721,11 @@ function ExplorerOptions({
}
return (
<Button
type="primary"
className="periscope-btn ghost"
disabled={disabled}
shape="round"
onClick={onAddToDashboard}
icon={<Plus size={16} />}
>
Add to Dashboard
</Button>
/>
);
}, [disabled, isOneChartPerQuery, onAddToDashboard, splitedQueries]);
@ -797,41 +744,31 @@ function ExplorerOptions({
>
<Tooltip title="Clear this view" placement="top">
<Button
className="action-icon"
className="periscope-btn ghost"
onClick={handleClearSelect}
icon={<X size={14} />}
icon={<X size={16} />}
/>
</Tooltip>
{
// only show the update view option when the query is updated
}
{isQueryUpdated && (
<>
<Divider
type="vertical"
className={isEditDeleteSupported ? '' : 'hidden'}
<Tooltip title="Update this view" placement="top">
<Button
className={cx(
'periscope-btn ghost',
isEditDeleteSupported ? '' : 'hidden',
)}
disabled={isViewUpdating}
onClick={onUpdateQueryHandler}
icon={<Disc3 size={16} />}
/>
<Tooltip title="Update this view" placement="top">
<Button
className={cx('action-icon', isEditDeleteSupported ? ' ' : 'hidden')}
disabled={isViewUpdating}
onClick={onUpdateQueryHandler}
icon={<Disc3 size={14} />}
/>
</Tooltip>
</>
</Tooltip>
)}
</div>
)}
{!isExplorerOptionHidden && (
<div
className="explorer-options"
style={{
background: extraData
? `linear-gradient(90deg, rgba(0,0,0,0) -5%, ${rgbaColor} 9%, rgba(0,0,0,0) 30%)`
: 'transparent',
}}
>
<div className="explorer-options">
<div className="view-options">
<Select<string, { key: string; value: string }>
showSearch
@ -872,49 +809,23 @@ function ExplorerOptions({
</Select>
<Button
shape="round"
shape="default"
className={cx(
'periscope-btn secondary',
isEditDeleteSupported ? '' : 'hidden',
)}
onClick={handleSaveViewModalToggle}
className={isEditDeleteSupported ? '' : 'hidden'}
disabled={viewsIsLoading || isRefetching}
icon={<Disc3 size={16} />}
icon={<Disc3 size={12} />}
>
Save this view
</Button>
</div>
<hr className={isEditDeleteSupported ? '' : 'hidden'} />
<div className={cx('actions', isEditDeleteSupported ? '' : 'hidden')}>
{alertButton}
{dashboardButton}
</div>
<div className="actions">
{/* Hide the info icon for metrics explorer until we get the docs link */}
{!isMetricsExplorer && (
<Tooltip
title={
<div>
{infoIconText}
<Typography.Link href={infoIconLink} target="_blank">
{' '}
here
</Typography.Link>{' '}
</div>
}
>
<InfoCircleOutlined className="info-icon" />
</Tooltip>
)}
<Tooltip title="Hide">
<Button
disabled={disabled}
shape="circle"
onClick={hideToolbar}
icon={<PanelBottomClose size={16} />}
data-testid="hide-toolbar"
/>
</Tooltip>
</div>
</div>
)}
<ExplorerOptionsHideArea

View File

@ -1,4 +1,6 @@
.alert-tabs {
padding: 0px 8px;
.ant-tabs-tab {
border: none !important;
margin-left: 0px !important;
@ -48,6 +50,30 @@
}
}
.alert-query-section-container {
.ant-card-body {
padding: 0px;
.alert-tabs {
padding: 0px;
.ant-tabs {
.ant-tabs-nav {
padding: 8px 0;
.ant-tabs-nav-wrap {
padding: 0px;
}
}
.ant-tabs-extra-content {
padding: 0px;
}
}
}
}
}
.lightMode {
.alert-tabs {
.ant-tabs-nav-list {

View File

@ -4,11 +4,11 @@ import { Color } from '@signozhq/design-tokens';
import { Button, Tabs, Tooltip } from 'antd';
import logEvent from 'api/common/logEvent';
import PromQLIcon from 'assets/Dashboard/PromQl';
import { QueryBuilderV2 } from 'components/QueryBuilderV2/QueryBuilderV2';
import { ALERTS_DATA_SOURCE_MAP } from 'constants/alerts';
import { ENTITY_VERSION_V4 } from 'constants/app';
import { PANEL_TYPES } from 'constants/queryBuilder';
import { QBShortcuts } from 'constants/shortcuts/QBShortcuts';
import { QueryBuilder } from 'container/QueryBuilder';
import { useKeyboardHotkeys } from 'hooks/hotkeys/useKeyboardHotkeys';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { isEmpty } from 'lodash-es';
@ -48,7 +48,7 @@ function QuerySection({
const isDarkMode = useIsDarkMode();
const renderMetricUI = (): JSX.Element => (
<QueryBuilder
<QueryBuilderV2
panelType={panelType}
config={{
queryVariant: 'static',
@ -144,7 +144,7 @@ function QuerySection({
<div className="alert-tabs">
<Tabs
type="card"
style={{ width: '100%' }}
style={{ width: '100%', padding: '0px 8px' }}
defaultActiveKey={currentTab}
activeKey={currentTab}
onChange={handleQueryCategoryChange}
@ -178,7 +178,7 @@ function QuerySection({
<div className="alert-tabs">
<Tabs
type="card"
style={{ width: '100%' }}
style={{ width: '100%', padding: '0px 8px' }}
defaultActiveKey={currentTab}
activeKey={currentTab}
onChange={handleQueryCategoryChange}
@ -218,7 +218,7 @@ function QuerySection({
return (
<>
<StepHeading> {t('alert_form_step2', { step: step2Label })}</StepHeading>
<FormContainer>
<FormContainer className="alert-query-section-container">
<div>{renderTabs(alertType)}</div>
{renderQuerySection(currentTab)}
</FormContainer>

View File

@ -1,7 +1,5 @@
.qb-search-view-container {
padding: 8px 16px;
border-top: 1px solid var(--bg-slate-400, #1d212d);
border-bottom: 1px solid var(--bg-slate-400, #1d212d);
.ant-select-selector {
border-radius: 2px;
@ -20,9 +18,6 @@
.lightMode {
.qb-search-view-container {
border-top: 1px solid var(--bg-vanilla-300);
border-bottom: 1px solid var(--bg-vanilla-300);
.ant-select-selector {
border-color: var(--bg-vanilla-300) !important;
background-color: var(--bg-vanilla-100) !important;

View File

@ -8,18 +8,15 @@ import {
} from 'constants/queryBuilder';
import ExplorerOrderBy from 'container/ExplorerOrderBy';
import { OrderByFilterProps } from 'container/QueryBuilder/filters/OrderByFilter/OrderByFilter.interfaces';
import QueryBuilderSearchV2 from 'container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2';
import { QueryBuilderProps } from 'container/QueryBuilder/QueryBuilder.interfaces';
import { useGetPanelTypesQueryParam } from 'hooks/queryBuilder/useGetPanelTypesQueryParam';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl';
import {
ExplorerViews,
prepareQueryWithDefaultTimestamp,
} from 'pages/LogsExplorer/utils';
import { memo, useCallback, useMemo } from 'react';
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
import { DataSource } from 'types/common/queryBuilder';
function LogExplorerQuerySection({
@ -27,9 +24,7 @@ function LogExplorerQuerySection({
}: {
selectedView: ExplorerViews;
}): JSX.Element {
const { currentQuery, updateAllQueriesOperators } = useQueryBuilder();
const query = currentQuery?.builder?.queryData[0] || null;
const { updateAllQueriesOperators } = useQueryBuilder();
const panelTypes = useGetPanelTypesQueryParam(PANEL_TYPES.LIST);
const defaultValue = useMemo(() => {
@ -58,13 +53,6 @@ function LogExplorerQuerySection({
return config;
}, [panelTypes]);
const { handleChangeQueryData } = useQueryOperations({
index: 0,
query,
filterConfigs,
entityVersion: '',
});
const renderOrderBy = useCallback(
({ query, onChange }: OrderByFilterProps): JSX.Element => (
<ExplorerOrderBy query={query} onChange={onChange} />
@ -79,38 +67,16 @@ function LogExplorerQuerySection({
[panelTypes, renderOrderBy],
);
const handleChangeTagFilters = useCallback(
(value: IBuilderQuery['filters']) => {
handleChangeQueryData('filters', value);
},
[handleChangeQueryData],
);
return (
<>
{selectedView === ExplorerViews.LIST && (
<div className="qb-search-view-container">
<QueryBuilderSearchV2
query={query}
onChange={handleChangeTagFilters}
whereClauseConfig={filterConfigs?.filters}
/>
</div>
)}
{(selectedView === ExplorerViews.TABLE ||
selectedView === ExplorerViews.TIMESERIES ||
selectedView === ExplorerViews.CLICKHOUSE) && (
<QueryBuilderV2
isListViewPanel={panelTypes === PANEL_TYPES.LIST}
config={{ initialDataSource: DataSource.LOGS, queryVariant: 'static' }}
panelType={panelTypes}
filterConfigs={filterConfigs}
queryComponents={queryComponents}
version="v3" // setting this to v3 as we this is rendered in logs explorer
/>
)}
</>
<QueryBuilderV2
isListViewPanel={panelTypes === PANEL_TYPES.LIST}
config={{ initialDataSource: DataSource.LOGS, queryVariant: 'static' }}
panelType={panelTypes}
filterConfigs={filterConfigs}
queryComponents={queryComponents}
showOnlyWhereClause={selectedView === ExplorerViews.LIST}
version="v3" // setting this to v3 as we this is rendered in logs explorer
/>
);
}

View File

@ -76,6 +76,12 @@
border: 1px solid var(--bg-slate-400);
}
.order-by-container {
display: flex;
align-items: center;
gap: 8px;
}
.format-options-container {
position: relative;
}
@ -111,7 +117,35 @@
.tab-options-right {
display: flex;
align-items: center;
gap: 8px;
gap: 4px;
.order-by-container {
display: flex;
align-items: center;
gap: 8px;
.order-by-label {
color: var(--text-vanilla-400);
font-size: 12px;
font-style: normal;
font-weight: 400;
line-height: 16px; /* 133.333% */
display: flex;
align-items: center;
gap: 4px;
}
.order-by-select {
width: 100px;
.ant-select-selector {
border: none;
box-shadow: none;
background-color: transparent;
}
}
}
}
.frequency-chart-view-controller {

View File

@ -1,7 +1,7 @@
/* eslint-disable sonarjs/cognitive-complexity */
import './LogsExplorerViews.styles.scss';
import { Button, Switch, Typography } from 'antd';
import { Button, Select, Switch, Typography } from 'antd';
import { getQueryStats, WsDataEvent } from 'api/common/getQueryStats';
import logEvent from 'api/common/logEvent';
import { getYAxisFormattedValue } from 'components/Graph/yAxisConfig';
@ -46,7 +46,7 @@ import {
omit,
set,
} from 'lodash-es';
import { Sliders } from 'lucide-react';
import { ArrowUp10, Minus, Sliders } from 'lucide-react';
import { ExplorerViews } from 'pages/LogsExplorer/utils';
import { useTimezone } from 'providers/Timezone';
import {
@ -138,6 +138,8 @@ function LogsExplorerViewsContainer({
const [queryStats, setQueryStats] = useState<WsDataEvent>();
const [listChartQuery, setListChartQuery] = useState<Query | null>(null);
const [orderDirection, setOrderDirection] = useState<string>('asc');
const listQuery = useMemo(() => {
if (!stagedQuery || stagedQuery.builder.queryData.length < 1) return null;
@ -656,6 +658,23 @@ function LogsExplorerViewsContainer({
<div className="tab-options-right">
{selectedPanelType === PANEL_TYPES.LIST && (
<>
<div className="order-by-container">
<div className="order-by-label">
Order by <Minus size={14} /> <ArrowUp10 size={14} />
</div>
<Select
placeholder="Select order by"
className="order-by-select"
style={{ width: 100 }}
value={orderDirection}
onChange={(value): void => setOrderDirection(value)}
options={[
{ label: 'Ascending', value: 'asc' },
{ label: 'Descending', value: 'desc' },
]}
/>
</div>
<Download
data={flattenLogData}
isLoading={isFetching}
@ -663,7 +682,7 @@ function LogsExplorerViewsContainer({
/>
<div className="format-options-container" ref={menuRef}>
<Button
className="periscope-btn"
className="periscope-btn ghost"
onClick={handleToggleShowFormatOptions}
icon={<Sliders size={14} />}
data-testid="periscope-btn"

View File

@ -28,5 +28,6 @@ export type QueryBuilderProps = {
queryComponents?: { renderOrderBy?: (props: OrderByFilterProps) => ReactNode };
isListViewPanel?: boolean;
showFunctions?: boolean;
showOnlyWhereClause?: boolean;
version: string;
};

View File

@ -10,4 +10,5 @@ export type QueryProps = {
showFunctions?: boolean;
version: string;
showSpanScopeSelector?: boolean;
showOnlyWhereClause?: boolean;
} & Pick<QueryBuilderProps, 'filterConfigs' | 'queryComponents'>;

View File

@ -19,6 +19,8 @@
border: 1px solid var(--bg-slate-400);
background: var(--bg-ink-300);
flex-direction: row;
border-bottom: none;
margin-bottom: -1px;
.prom-ql-icon {
height: 14px;
@ -33,17 +35,35 @@
border: none;
padding: 9px;
box-shadow: none;
border-radius: 0;
border-radius: 0px;
border-left: 1px solid var(--bg-slate-400);
border-bottom: 1px solid var(--bg-slate-400);
gap: 8px;
&.active-tab {
background-color: var(--bg-slate-400);
background-color: var(--bg-ink-500);
border-bottom: 1px solid var(--bg-ink-500);
&:hover {
background-color: var(--bg-ink-500) !important;
}
}
&:disabled {
background-color: #121317;
background-color: var(--bg-ink-300);
opacity: 0.6;
}
&:first-child {
border-left: 1px solid transparent;
}
&:hover {
background-color: transparent !important;
border-left: 1px solid transparent !important;
color: var(--bg-vanilla-100);
}
}
}

View File

@ -17,6 +17,7 @@
.query-builder-search-v2 {
display: flex;
gap: 4px;
flex: 1;
.ant-select-dropdown {
padding: 0px;

View File

@ -1,12 +1,23 @@
.toolbar {
display: grid;
grid-template-columns: 3fr auto auto;
padding: 8px 16px;
display: flex;
justify-content: space-between;
align-items: flex-end;
border-top: 1px solid var(--bg-slate-400);
border-bottom: 1px solid var(--bg-slate-400);
padding: 0px 8px;
gap: 8px;
.rightActions {
margin: 4px 0;
display: flex;
align-items: center;
gap: 4px;
}
.timeRange {
display: flex;
padding-right: 8px;
align-items: center;
gap: 16px;
}

View File

@ -32,14 +32,19 @@ export default function Toolbar({
return (
<div className="toolbar">
<div className="leftActions">{leftActions}</div>
<div className="timeRange">
{showOldCTA && <NewExplorerCTA />}
<DateTimeSelectionV2
showAutoRefresh={showAutoRefresh}
showRefreshText={!isLogsExplorerPage && !isApiMonitoringPage}
/>
<div className="rightActions">
<div className="timeRange">
{showOldCTA && <NewExplorerCTA />}
<DateTimeSelectionV2
showAutoRefresh={showAutoRefresh}
showRefreshText={!isLogsExplorerPage && !isApiMonitoringPage}
hideShareModal
/>
</div>
{rightActions}
</div>
<div className="rightActions">{rightActions}</div>
</div>
);
}

View File

@ -1,4 +1,33 @@
.trace-explorer-controls {
display: flex;
justify-content: flex-end;
gap: 8px;
.order-by-container {
display: flex;
align-items: center;
gap: 8px;
.order-by-label {
color: var(--text-vanilla-400);
font-size: 12px;
font-style: normal;
font-weight: 400;
line-height: 16px; /* 133.333% */
display: flex;
align-items: center;
gap: 4px;
}
.order-by-select {
width: 100px;
.ant-select-selector {
border: none;
box-shadow: none;
background-color: transparent;
}
}
}
}

View File

@ -1,5 +1,6 @@
import './ListView.styles.scss';
import { Select } from 'antd';
import logEvent from 'api/common/logEvent';
import { ResizeTable } from 'components/ResizeTable';
import { ENTITY_VERSION_V4 } from 'constants/app';
@ -20,8 +21,9 @@ import useDragColumns from 'hooks/useDragColumns';
import { getDraggedColumns } from 'hooks/useDragColumns/utils';
import useUrlQueryData from 'hooks/useUrlQueryData';
import { RowData } from 'lib/query/createTableColumnsFromQuery';
import { ArrowUp10, Minus } from 'lucide-react';
import { useTimezone } from 'providers/Timezone';
import { memo, useCallback, useEffect, useMemo } from 'react';
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { DataSource } from 'types/common/queryBuilder';
@ -44,6 +46,8 @@ function ListView({ isFilterApplied }: ListViewProps): JSX.Element {
const panelType = panelTypeFromQueryBuilder || PANEL_TYPES.LIST;
const [orderDirection, setOrderDirection] = useState<string>('asc');
const {
selectedTime: globalSelectedTime,
maxTime,
@ -170,6 +174,24 @@ function ListView({ isFilterApplied }: ListViewProps): JSX.Element {
<Container>
{transformedQueryTableData.length !== 0 && (
<div className="trace-explorer-controls">
<div className="order-by-container">
<div className="order-by-label">
Order by <Minus size={14} /> <ArrowUp10 size={14} />
</div>
<Select
placeholder="Select order by"
className="order-by-select"
style={{ width: 100 }}
value={orderDirection}
onChange={(value): void => setOrderDirection(value)}
options={[
{ label: 'Ascending', value: 'asc' },
{ label: 'Descending', value: 'desc' },
]}
/>
</div>
<TraceExplorerControls
isLoading={isFetching}
totalCount={totalCount}

View File

@ -1,26 +1,15 @@
import { QueryBuilderV2 } from 'components/QueryBuilderV2/QueryBuilderV2';
// import QuerySearch from 'components/QueryBuilderV2/QueryV2/QuerySearch/QuerySearch';
import { PANEL_TYPES } from 'constants/queryBuilder';
import ExplorerOrderBy from 'container/ExplorerOrderBy';
import { OrderByFilterProps } from 'container/QueryBuilder/filters/OrderByFilter/OrderByFilter.interfaces';
// import SpanScopeSelector from 'container/QueryBuilder/filters/QueryBuilderSearchV2/SpanScopeSelector';
import { QueryBuilderProps } from 'container/QueryBuilder/QueryBuilder.interfaces';
import { useGetPanelTypesQueryParam } from 'hooks/queryBuilder/useGetPanelTypesQueryParam';
// import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { memo, useCallback, useMemo } from 'react';
import { DataSource } from 'types/common/queryBuilder';
import { Container } from './styles';
function QuerySection({
selectedView,
}: {
selectedView: PANEL_TYPES;
}): JSX.Element {
// const { currentQuery } = useQueryBuilder();
// const queryName = currentQuery?.builder?.queryData[0]?.queryName || '';
function QuerySection(): JSX.Element {
const panelTypes = useGetPanelTypesQueryParam(PANEL_TYPES.LIST);
const filterConfigs: QueryBuilderProps['filterConfigs'] = useMemo(() => {
@ -50,30 +39,19 @@ function QuerySection({
};
}, [panelTypes, renderOrderBy]);
console.log('query - section - selectedView', selectedView);
return (
<Container>
{/* {(selectedView === 'list' || selectedView === 'trace') && (
<div className="qb-search-view-container">
<QuerySearch />
<div className="traces-search-filter-in">in</div>
<SpanScopeSelector queryName={queryName} />
</div>
)}
{(selectedView === 'graph' || selectedView === 'table') && ( */}
<QueryBuilderV2
isListViewPanel={panelTypes === PANEL_TYPES.LIST}
config={{ initialDataSource: DataSource.TRACES, queryVariant: 'static' }}
queryComponents={queryComponents}
panelType={panelTypes}
filterConfigs={filterConfigs}
showOnlyWhereClause={
panelTypes === PANEL_TYPES.LIST || panelTypes === PANEL_TYPES.TRACE
}
version="v3" // setting this to v3 as we this is rendered in logs explorer
/>
{/* )} */}
</Container>
);
}

View File

@ -1,4 +1,4 @@
import { Typography } from 'antd';
import { Select, Typography } from 'antd';
import logEvent from 'api/common/logEvent';
import { ResizeTable } from 'components/ResizeTable';
import { ENTITY_VERSION_V4 } from 'constants/app';
@ -11,7 +11,8 @@ import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { Pagination } from 'hooks/queryPagination';
import useUrlQueryData from 'hooks/useUrlQueryData';
import { memo, useEffect, useMemo } from 'react';
import { ArrowUp10, Minus } from 'lucide-react';
import { memo, useEffect, useMemo, useState } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { DataSource } from 'types/common/queryBuilder';
@ -29,6 +30,7 @@ interface TracesViewProps {
function TracesView({ isFilterApplied }: TracesViewProps): JSX.Element {
const { stagedQuery, panelType } = useQueryBuilder();
const [orderDirection, setOrderDirection] = useState<string>('asc');
const { selectedTime: globalSelectedTime, maxTime, minTime } = useSelector<
AppState,
@ -92,11 +94,32 @@ function TracesView({ isFilterApplied }: TracesViewProps): JSX.Element {
here
</Typography.Link>
</Typography>
<TraceExplorerControls
isLoading={isLoading}
totalCount={responseData?.length || 0}
perPageOptions={PER_PAGE_OPTIONS}
/>
<div className="trace-explorer-controls">
<div className="order-by-container">
<div className="order-by-label">
Order by <Minus size={14} /> <ArrowUp10 size={14} />
</div>
<Select
placeholder="Select order by"
className="order-by-select"
style={{ width: 100 }}
value={orderDirection}
onChange={(value): void => setOrderDirection(value)}
options={[
{ label: 'Ascending', value: 'asc' },
{ label: 'Descending', value: 'desc' },
]}
/>
</div>
<TraceExplorerControls
isLoading={isLoading}
totalCount={responseData?.length || 0}
perPageOptions={PER_PAGE_OPTIONS}
/>
</div>
</ActionsContainer>
)}

View File

@ -58,7 +58,7 @@ export const useHandleExplorerTabChange = (): {
currentQueryData?: ICurrentQueryData,
redirectToUrl?: typeof ROUTES[keyof typeof ROUTES],
) => {
console.log('type', type);
console.log('hook - type', type);
const newPanelType = type as PANEL_TYPES;

View File

@ -263,7 +263,6 @@ function LogsExplorer(): JSX.Element {
isLoadingQueries={isLoadingQueries}
/>
}
showOldCTA
/>
<div className="log-explorer-query-container">

View File

@ -31,7 +31,6 @@
.qb-search-view-container {
padding: 8px;
border: 1px solid var(--Slate-400, #1d212d) !important;
display: flex;
flex-direction: row;
@ -40,8 +39,8 @@
.ant-select-selector {
border-radius: 2px;
border: 1px solid var(--Slate-400, #1d212d) !important;
background: var(--Ink-300, #16181d) !important;
border: 1px solid var(--bg-slate-400) !important;
background: var(--bg-ink-300) !important;
height: 34px !important;
box-sizing: border-box !important;
}
@ -83,7 +82,6 @@
.trace-explorer {
width: 100%;
border-left: 1px solid var(--bg-slate-400);
background: var(--bg-ink-500);
> .ant-card-body {

View File

@ -18,20 +18,17 @@ import RightToolbarActions from 'container/QueryBuilder/components/ToolbarAction
import TimeSeriesView from 'container/TimeSeriesView';
import Toolbar from 'container/Toolbar/Toolbar';
import ListView from 'container/TracesExplorer/ListView';
// import DateTimeSelector from 'container/TopNav/DateTimeSelectionV2';
import { defaultSelectedColumns } from 'container/TracesExplorer/ListView/configs';
import QuerySection from 'container/TracesExplorer/QuerySection';
import TableView from 'container/TracesExplorer/TableView';
import TracesView from 'container/TracesExplorer/TracesView';
import { useUpdateDashboard } from 'hooks/dashboard/useUpdateDashboard';
import { addEmptyWidgetInDashboardJSONWithQuery } from 'hooks/dashboard/utils';
import { useGetPanelTypesQueryParam } from 'hooks/queryBuilder/useGetPanelTypesQueryParam';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl';
import { useHandleExplorerTabChange } from 'hooks/useHandleExplorerTabChange';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
import { cloneDeep, isEmpty, set } from 'lodash-es';
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
import { ExplorerViews } from 'pages/LogsExplorer/utils';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Dashboard } from 'types/api/dashboard/getAll';
import { Query } from 'types/api/queryBuilder/queryBuilderData';
@ -46,6 +43,7 @@ function TracesExplorer(): JSX.Element {
updateAllQueriesOperators,
handleRunQuery,
stagedQuery,
handleSetConfig,
} = useQueryBuilder();
const { options } = useOptionsMenu({
@ -57,12 +55,27 @@ function TracesExplorer(): JSX.Element {
},
});
const currentPanelType = useGetPanelTypesQueryParam();
const currentTab = panelType || PANEL_TYPES.LIST;
const [selectedView, setSelectedView] = useState<ExplorerViews>(
ExplorerViews.LIST,
);
const { handleExplorerTabChange } = useHandleExplorerTabChange();
const { safeNavigate } = useSafeNavigate();
const handleChangeSelectedView = useCallback(
(view: ExplorerViews): void => {
if (selectedView === ExplorerViews.LIST) {
handleSetConfig(PANEL_TYPES.LIST, DataSource.LOGS);
}
setSelectedView(view);
handleExplorerTabChange(
view === ExplorerViews.TIMESERIES ? PANEL_TYPES.TIME_SERIES : view,
);
},
[handleSetConfig, handleExplorerTabChange, selectedView],
);
const listQuery = useMemo(() => {
if (!stagedQuery || stagedQuery.builder.queryData.length < 1) return null;
@ -163,23 +176,6 @@ function TracesExplorer(): JSX.Element {
useShareBuilderUrl(defaultQuery);
useEffect(() => {
const shouldChangeView = isMultipleQueries || isGroupByExist;
if (
(currentTab === PANEL_TYPES.LIST || currentTab === PANEL_TYPES.TRACE) &&
shouldChangeView
) {
handleExplorerTabChange(currentPanelType || PANEL_TYPES.TIME_SERIES);
}
}, [
currentTab,
isMultipleQueries,
isGroupByExist,
handleExplorerTabChange,
currentPanelType,
]);
const [isOpen, setOpen] = useState<boolean>(true);
const logEventCalledRef = useRef(false);
@ -260,27 +256,16 @@ function TracesExplorer(): JSX.Element {
showFilter={isOpen}
handleFilterVisibilityChange={(): void => setOpen(!isOpen)}
items={toolbarViews}
selectedView={
currentTab === PANEL_TYPES.TIME_SERIES ? 'timeseries' : currentTab
}
onChangeSelectedView={(view): void => {
if (view === 'timeseries') {
handleExplorerTabChange(PANEL_TYPES.TIME_SERIES);
// setSelectedView(PANEL_TYPES.TIME_SERIES);
} else {
handleExplorerTabChange((view as unknown) as PANEL_TYPES);
// setSelectedView((view as unknown) as PANEL_TYPES);
}
}}
selectedView={selectedView}
onChangeSelectedView={handleChangeSelectedView}
/>
}
rightActions={<RightToolbarActions onStageRunQuery={handleRunQuery} />}
// showOldCTA={false}
/>
</div>
<ExplorerCard sourcepage={DataSource.TRACES}>
<div className="query-section-container">
<QuerySection selectedView={currentTab} />
<QuerySection />
</div>
</ExplorerCard>
@ -293,19 +278,19 @@ function TracesExplorer(): JSX.Element {
/>
</div>
{currentTab === PANEL_TYPES.LIST && (
{selectedView === ExplorerViews.LIST && (
<div className="trace-explorer-list-view">
<ListView isFilterApplied={isFilterApplied} />
</div>
)}
{currentTab === PANEL_TYPES.TRACE && (
{selectedView === ExplorerViews.TRACE && (
<div className="trace-explorer-traces-view">
<TracesView isFilterApplied={isFilterApplied} />
</div>
)}
{currentTab === PANEL_TYPES.TIME_SERIES && (
{selectedView === ExplorerViews.TIMESERIES && (
<div className="trace-explorer-time-series-view">
<TimeSeriesView
dataSource={DataSource.TRACES}
@ -314,7 +299,7 @@ function TracesExplorer(): JSX.Element {
</div>
)}
{currentTab === PANEL_TYPES.TABLE && (
{selectedView === ExplorerViews.TABLE && (
<div className="trace-explorer-table-view">
<TableView />
</div>

View File

@ -22,6 +22,8 @@
&.ghost {
box-shadow: none;
border: none;
background: transparent;
color: var(--bg-vanilla-400, #c0c1c3);
}
cursor: pointer;
@ -33,6 +35,12 @@
box-shadow: 0 2px 0 rgba(62, 86, 245, 0.09);
}
&.secondary {
border-radius: 3px;
border: 1px solid var(--Slate-300, #242834);
background: var(--Ink-200, #23262e);
}
&:disabled {
opacity: 0.5;
}
@ -85,12 +93,12 @@
font-size: 12px;
color: var(--bg-vanilla-400);
font-size: 11px;
font-size: 12px;
font-style: normal;
font-weight: 500;
line-height: 18px;
letter-spacing: 0.56px;
text-transform: uppercase;
max-width: 150px;
min-width: 120px;
white-space: nowrap;