mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-25 19:40:24 +00:00
feat: use new qb in logs explorer
This commit is contained in:
parent
0ffa666903
commit
2520718afb
@ -4,7 +4,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 16px;
|
||||
gap: 16px;
|
||||
gap: 8px;
|
||||
font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
||||
'Helvetica Neue', sans-serif;
|
||||
|
||||
@ -42,10 +42,12 @@
|
||||
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--bg-slate-200, #1d212d);
|
||||
font-family: 'Space Mono', monospace !important;
|
||||
|
||||
ul {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
font-family: 'Space Mono', monospace !important;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 0.3rem;
|
||||
@ -71,6 +73,8 @@
|
||||
align-items: center !important;
|
||||
gap: 8px !important;
|
||||
|
||||
font-family: 'Space Mono', monospace !important;
|
||||
|
||||
.cm-completionIcon {
|
||||
display: none !important;
|
||||
}
|
||||
@ -87,9 +91,9 @@
|
||||
}
|
||||
|
||||
.cm-line {
|
||||
line-height: 1.8 !important;
|
||||
line-height: 24px !important;
|
||||
background: var(--bg-ink-300) !important;
|
||||
|
||||
font-family: 'Space Mono', monospace !important;
|
||||
::-moz-selection {
|
||||
background: var(--bg-ink-100) !important;
|
||||
opacity: 0.5 !important;
|
||||
@ -124,6 +128,7 @@
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
margin-top: 16px;
|
||||
|
||||
.valid,
|
||||
.invalid {
|
||||
@ -196,22 +201,109 @@
|
||||
}
|
||||
}
|
||||
|
||||
.query-examples {
|
||||
padding: 12px;
|
||||
background-color: var(--bg-vanilla-100);
|
||||
border: 1px solid var(--bg-vanilla-300);
|
||||
border-radius: 4px;
|
||||
.code-mirror-card {
|
||||
.ant-card-body {
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-top: 8px;
|
||||
margin-bottom: 0;
|
||||
padding-left: 16px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 8px;
|
||||
.query-text-preview-title {
|
||||
font-size: 13px;
|
||||
color: var(--bg-vanilla-100);
|
||||
background-color: var(--bg-robin-500);
|
||||
padding: 2px 6px;
|
||||
border-radius: 2px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 4px;
|
||||
.query-text-preview {
|
||||
font-family: 'Space Mono', monospace;
|
||||
font-size: 13px;
|
||||
color: var(--bg-vanilla-200);
|
||||
padding: 2px 6px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.query-examples-card {
|
||||
background-color: var(--bg-ink-400);
|
||||
border: 1px solid var(--bg-slate-200);
|
||||
|
||||
.ant-card-body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.query-examples {
|
||||
.ant-collapse-header {
|
||||
padding: 8px 16px !important;
|
||||
color: var(--bg-vanilla-300) !important;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.ant-collapse-content {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.query-examples-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.query-example-tag {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
padding: 8px 12px;
|
||||
background-color: var(--bg-ink-400);
|
||||
border: 1px solid var(--bg-slate-200);
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
outline: none;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--bg-ink-300);
|
||||
border-color: var(--bg-robin-500);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid var(--bg-robin-500);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.query-example-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.query-example-label {
|
||||
font-weight: 500;
|
||||
color: var(--bg-vanilla-300);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.query-example-query {
|
||||
font-family: 'Space Mono', monospace;
|
||||
font-size: 12px;
|
||||
color: var(--bg-vanilla-200);
|
||||
background-color: var(--bg-ink-300);
|
||||
padding: 2px 6px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.query-example-description {
|
||||
font-size: 12px;
|
||||
color: var(--bg-vanilla-200);
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.query-example-content {
|
||||
display: inline-flex;
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -247,10 +339,36 @@
|
||||
}
|
||||
}
|
||||
|
||||
.query-examples {
|
||||
.query-examples-card {
|
||||
background-color: var(--bg-ink-400);
|
||||
border-color: var(--bg-slate-500);
|
||||
color: var(--bg-vanilla-100);
|
||||
|
||||
.ant-collapse-header {
|
||||
color: var(--bg-vanilla-100) !important;
|
||||
}
|
||||
|
||||
.query-example-tag {
|
||||
background-color: var(--bg-ink-400);
|
||||
border-color: var(--bg-slate-500);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--bg-ink-300);
|
||||
border-color: var(--bg-robin-500);
|
||||
}
|
||||
|
||||
.query-example-label {
|
||||
color: var(--bg-vanilla-100);
|
||||
}
|
||||
|
||||
.query-example-query {
|
||||
color: var(--bg-vanilla-100);
|
||||
background-color: var(--bg-ink-300);
|
||||
}
|
||||
|
||||
.query-example-description {
|
||||
color: var(--bg-vanilla-100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,8 +14,8 @@ import {
|
||||
} from '@codemirror/autocomplete';
|
||||
import { javascript } from '@codemirror/lang-javascript';
|
||||
import { copilot } from '@uiw/codemirror-theme-copilot';
|
||||
import CodeMirror, { EditorView, Extension } from '@uiw/react-codemirror';
|
||||
import { Badge, Card, Divider, Space, Typography } from 'antd';
|
||||
import CodeMirror, { EditorView } from '@uiw/react-codemirror';
|
||||
import { Card, Collapse, Space, Typography } from 'antd';
|
||||
import { getValueSuggestions } from 'api/querySuggestions/getValueSuggestion';
|
||||
import { useGetQueryKeySuggestions } from 'hooks/querySuggestions/useGetQueryKeySuggestions';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
@ -32,58 +32,100 @@ import {
|
||||
} from 'utils/antlrQueryUtils';
|
||||
|
||||
const { Text } = Typography;
|
||||
const { Panel } = Collapse;
|
||||
|
||||
function collapseSpacesOutsideStrings(): Extension {
|
||||
return EditorView.inputHandler.of((view, from, to, text) => {
|
||||
// Get the current line text
|
||||
const { state } = view;
|
||||
const line = state.doc.lineAt(from);
|
||||
|
||||
// Find the position within the line
|
||||
const before = line.text.slice(0, from - line.from);
|
||||
const after = line.text.slice(to - line.from);
|
||||
|
||||
const fullText = before + text + after;
|
||||
|
||||
let insideString = false;
|
||||
let escaped = false;
|
||||
let processed = '';
|
||||
|
||||
for (let i = 0; i < fullText.length; i++) {
|
||||
const char = fullText[i];
|
||||
|
||||
if (char === '"' && !escaped) {
|
||||
insideString = !insideString;
|
||||
}
|
||||
if (char === '\\' && !escaped) {
|
||||
escaped = true;
|
||||
} else {
|
||||
escaped = false;
|
||||
}
|
||||
|
||||
if (!insideString && char === ' ' && processed.endsWith(' ')) {
|
||||
// Collapse multiple spaces outside strings
|
||||
// Skip this space
|
||||
} else {
|
||||
processed += char;
|
||||
}
|
||||
}
|
||||
|
||||
// Only dispatch if the processed text differs
|
||||
if (processed !== fullText) {
|
||||
view.dispatch({
|
||||
changes: {
|
||||
from: line.from,
|
||||
to: line.to,
|
||||
insert: processed,
|
||||
},
|
||||
});
|
||||
return true;
|
||||
}
|
||||
const queryExamples = [
|
||||
{
|
||||
label: 'Basic Query',
|
||||
query: "status = 'error'",
|
||||
description: 'Find all errors',
|
||||
},
|
||||
{
|
||||
label: 'Multiple Conditions',
|
||||
query: "status = 'error' AND service = 'frontend'",
|
||||
description: 'Find errors from frontend service',
|
||||
},
|
||||
{
|
||||
label: 'IN Operator',
|
||||
query: "status IN ['error', 'warning']",
|
||||
description: 'Find items with specific statuses',
|
||||
},
|
||||
{
|
||||
label: 'Function Usage',
|
||||
query: "HAS(service, 'frontend')",
|
||||
description: 'Use HAS function',
|
||||
},
|
||||
{
|
||||
label: 'Numeric Comparison',
|
||||
query: 'duration > 1000',
|
||||
description: 'Find items with duration greater than 1000ms',
|
||||
},
|
||||
{
|
||||
label: 'Range Query',
|
||||
query: 'duration BETWEEN 100 AND 1000',
|
||||
description: 'Find items with duration between 100ms and 1000ms',
|
||||
},
|
||||
{
|
||||
label: 'Pattern Matching',
|
||||
query: "service LIKE 'front%'",
|
||||
description: 'Find services starting with "front"',
|
||||
},
|
||||
{
|
||||
label: 'Complex Conditions',
|
||||
query: "(status = 'error' OR status = 'warning') AND service = 'frontend'",
|
||||
description: 'Find errors or warnings from frontend service',
|
||||
},
|
||||
{
|
||||
label: 'Multiple Functions',
|
||||
query: "HAS(service, 'frontend') AND HAS(status, 'error')",
|
||||
description: 'Use multiple HAS functions',
|
||||
},
|
||||
{
|
||||
label: 'NOT Operator',
|
||||
query: "NOT status = 'success'",
|
||||
description: 'Find items that are not successful',
|
||||
},
|
||||
{
|
||||
label: 'Array Contains',
|
||||
query: "tags CONTAINS 'production'",
|
||||
description: 'Find items with production tag',
|
||||
},
|
||||
{
|
||||
label: 'Regex Pattern',
|
||||
query: "service REGEXP '^prod-.*'",
|
||||
description: 'Find services matching regex pattern',
|
||||
},
|
||||
{
|
||||
label: 'Null Check',
|
||||
query: 'error IS NULL',
|
||||
description: 'Find items without errors',
|
||||
},
|
||||
{
|
||||
label: 'Multiple Attributes',
|
||||
query:
|
||||
"service = 'frontend' AND environment = 'production' AND status = 'error'",
|
||||
description: 'Find production frontend errors',
|
||||
},
|
||||
{
|
||||
label: 'Nested Conditions',
|
||||
query:
|
||||
"(service = 'frontend' OR service = 'backend') AND (status = 'error' OR status = 'warning')",
|
||||
description: 'Find errors or warnings from frontend or backend',
|
||||
},
|
||||
];
|
||||
|
||||
// Custom extension to stop events
|
||||
const stopEventsExtension = EditorView.domEventHandlers({
|
||||
keydown: (event) => {
|
||||
event.stopPropagation();
|
||||
// Optionally: event.preventDefault();
|
||||
return false; // Important for CM to know you handled it
|
||||
},
|
||||
input: (event) => {
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
function CodeMirrorWhereClause(): JSX.Element {
|
||||
const [query, setQuery] = useState<string>('');
|
||||
@ -328,35 +370,42 @@ function CodeMirrorWhereClause(): JSX.Element {
|
||||
handleQueryChange(value);
|
||||
};
|
||||
|
||||
const renderContextBadge = (): JSX.Element | null => {
|
||||
if (!queryContext) return null;
|
||||
|
||||
let color = 'black';
|
||||
let text = 'Unknown';
|
||||
|
||||
if (queryContext.isInKey) {
|
||||
color = 'blue';
|
||||
text = 'Key';
|
||||
} else if (queryContext.isInOperator) {
|
||||
color = 'purple';
|
||||
text = 'Operator';
|
||||
} else if (queryContext.isInValue) {
|
||||
color = 'green';
|
||||
text = 'Value';
|
||||
} else if (queryContext.isInFunction) {
|
||||
color = 'orange';
|
||||
text = 'Function';
|
||||
} else if (queryContext.isInConjunction) {
|
||||
color = 'magenta';
|
||||
text = 'Conjunction';
|
||||
} else if (queryContext.isInParenthesis) {
|
||||
color = 'grey';
|
||||
text = 'Parenthesis';
|
||||
}
|
||||
|
||||
return <Badge color={color} text={text} />;
|
||||
const handleExampleClick = (exampleQuery: string): void => {
|
||||
// If there's an existing query, append the example with AND
|
||||
const newQuery = query ? `${query} AND ${exampleQuery}` : exampleQuery;
|
||||
setQuery(newQuery);
|
||||
handleQueryChange(newQuery);
|
||||
};
|
||||
|
||||
// const renderContextBadge = (): JSX.Element | null => {
|
||||
// if (!queryContext) return null;
|
||||
|
||||
// let color = 'black';
|
||||
// let text = 'Unknown';
|
||||
|
||||
// if (queryContext.isInKey) {
|
||||
// color = 'blue';
|
||||
// text = 'Key';
|
||||
// } else if (queryContext.isInOperator) {
|
||||
// color = 'purple';
|
||||
// text = 'Operator';
|
||||
// } else if (queryContext.isInValue) {
|
||||
// color = 'green';
|
||||
// text = 'Value';
|
||||
// } else if (queryContext.isInFunction) {
|
||||
// color = 'orange';
|
||||
// text = 'Function';
|
||||
// } else if (queryContext.isInConjunction) {
|
||||
// color = 'magenta';
|
||||
// text = 'Conjunction';
|
||||
// } else if (queryContext.isInParenthesis) {
|
||||
// color = 'grey';
|
||||
// text = 'Parenthesis';
|
||||
// }
|
||||
|
||||
// return <Badge color={color} text={text} />;
|
||||
// };
|
||||
|
||||
function myCompletions(context: CompletionContext): CompletionResult | null {
|
||||
const word = context.matchBefore(/\w*/);
|
||||
if (word?.from === word?.to && !context.explicit) return null;
|
||||
@ -552,7 +601,7 @@ function CodeMirrorWhereClause(): JSX.Element {
|
||||
|
||||
return (
|
||||
<div className="code-mirror-where-clause">
|
||||
<Card size="small">
|
||||
<Card className="code-mirror-card">
|
||||
<CodeMirror
|
||||
value={query}
|
||||
theme={copilot}
|
||||
@ -568,62 +617,95 @@ function CodeMirrorWhereClause(): JSX.Element {
|
||||
activateOnTyping: true,
|
||||
maxRenderedOptions: 50,
|
||||
}),
|
||||
collapseSpacesOutsideStrings(),
|
||||
javascript({ jsx: false, typescript: false }),
|
||||
EditorView.lineWrapping,
|
||||
stopEventsExtension,
|
||||
// customTheme,
|
||||
]}
|
||||
basicSetup={{
|
||||
lineNumbers: false,
|
||||
}}
|
||||
/>
|
||||
|
||||
{query && (
|
||||
<>
|
||||
<Divider style={{ margin: '8px 0' }} />
|
||||
<Space direction="vertical" size={4}>
|
||||
<Text>Query:</Text>
|
||||
<Text code>{query}</Text>
|
||||
</Space>
|
||||
</>
|
||||
)}
|
||||
|
||||
{query && (
|
||||
<>
|
||||
<Divider style={{ margin: '8px 0' }} />
|
||||
|
||||
<div className="query-validation">
|
||||
<div className="query-validation-status">
|
||||
<Text>Status:</Text>
|
||||
<div className={validation.isValid ? 'valid' : 'invalid'}>
|
||||
{validation.isValid ? (
|
||||
<Space>
|
||||
<CheckCircleFilled /> Valid
|
||||
</Space>
|
||||
) : (
|
||||
<Space>
|
||||
<CloseCircleFilled /> Invalid
|
||||
</Space>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="query-validation-errors">
|
||||
{validation.errors.map((error) => (
|
||||
<div key={error.message} className="query-validation-error">
|
||||
<div className="query-validation-error-line">
|
||||
{error.line}:{error.column}
|
||||
</div>
|
||||
|
||||
<div className="query-validation-error-message">{error.message}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</Card>
|
||||
|
||||
{queryContext && (
|
||||
{query && (
|
||||
<Card size="small">
|
||||
<Space direction="vertical" size={4}>
|
||||
<Text className="query-text-preview-title">searchExpr</Text>
|
||||
<Text className="query-text-preview">{query}</Text>
|
||||
</Space>
|
||||
|
||||
<div className="query-validation">
|
||||
<div className="query-validation-status">
|
||||
<Text>Status:</Text>
|
||||
<div className={validation.isValid ? 'valid' : 'invalid'}>
|
||||
{validation.isValid ? (
|
||||
<Space>
|
||||
<CheckCircleFilled /> Valid
|
||||
</Space>
|
||||
) : (
|
||||
<Space>
|
||||
<CloseCircleFilled /> Invalid
|
||||
</Space>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="query-validation-errors">
|
||||
{validation.errors.map((error) => (
|
||||
<div key={error.message} className="query-validation-error">
|
||||
<div className="query-validation-error-line">
|
||||
{error.line}:{error.column}
|
||||
</div>
|
||||
|
||||
<div className="query-validation-error-message">{error.message}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
<Card size="small" className="query-examples-card">
|
||||
<Collapse
|
||||
ghost
|
||||
size="small"
|
||||
className="query-examples"
|
||||
defaultActiveKey={[]}
|
||||
>
|
||||
<Panel header="Query Examples" key="1">
|
||||
<div className="query-examples-list">
|
||||
{queryExamples.map((example) => (
|
||||
<div
|
||||
className="query-example-content"
|
||||
key={example.label}
|
||||
onClick={(): void => handleExampleClick(example.query)}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onKeyDown={(e): void => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
handleExampleClick(example.query);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<CodeMirror
|
||||
value={example.query}
|
||||
theme={copilot}
|
||||
extensions={[
|
||||
javascript({ jsx: false, typescript: false }),
|
||||
EditorView.editable.of(false),
|
||||
]}
|
||||
basicSetup={{ lineNumbers: false }}
|
||||
className="query-example-code-mirror"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Panel>
|
||||
</Collapse>
|
||||
</Card>
|
||||
|
||||
{/* {queryContext && (
|
||||
<Card size="small" title="Current Context" className="query-context">
|
||||
<div className="context-details">
|
||||
<Space direction="vertical" size={4}>
|
||||
@ -640,7 +722,6 @@ function CodeMirrorWhereClause(): JSX.Element {
|
||||
{renderContextBadge()}
|
||||
</Space>
|
||||
|
||||
{/* Display the key-operator-value triplet when available */}
|
||||
{queryContext.keyToken && (
|
||||
<Space>
|
||||
<Text strong>Key:</Text>
|
||||
@ -664,7 +745,7 @@ function CodeMirrorWhereClause(): JSX.Element {
|
||||
</Space>
|
||||
</div>
|
||||
</Card>
|
||||
)}
|
||||
)} */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
import QueryBuilderV2 from 'components/QueryBuilderV2/QueryBuilderV2';
|
||||
|
||||
function Home2(): JSX.Element {
|
||||
return (
|
||||
<div>
|
||||
<QueryBuilderV2 />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Home2;
|
||||
@ -1,5 +1,6 @@
|
||||
import './LogsExplorerQuerySection.styles.scss';
|
||||
|
||||
import QueryBuilderV2 from 'components/QueryBuilderV2/QueryBuilderV2';
|
||||
import {
|
||||
initialQueriesMap,
|
||||
OPERATORS,
|
||||
@ -107,6 +108,8 @@ function LogExplorerQuerySection({
|
||||
version="v3" // setting this to v3 as we this is rendered in logs explorer
|
||||
/>
|
||||
)}
|
||||
|
||||
{selectedView === SELECTED_VIEWS.QUERY_BUILDER_V2 && <QueryBuilderV2 />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import './ToolbarActions.styles.scss';
|
||||
import { FilterOutlined } from '@ant-design/icons';
|
||||
import { Button, Switch, Tooltip, Typography } from 'antd';
|
||||
import cx from 'classnames';
|
||||
import { Atom, SquareMousePointer, Terminal } from 'lucide-react';
|
||||
import { Atom, Binoculars, SquareMousePointer, Terminal } from 'lucide-react';
|
||||
import { SELECTED_VIEWS } from 'pages/LogsExplorer/utils';
|
||||
|
||||
interface LeftToolbarActionsProps {
|
||||
@ -19,7 +19,7 @@ interface LeftToolbarActionsProps {
|
||||
const activeTab = 'active-tab';
|
||||
const actionBtn = 'action-btn';
|
||||
export const queryBuilder = 'query-builder';
|
||||
|
||||
export const queryBuilderV2 = 'query-builder-v2';
|
||||
export default function LeftToolbarActions({
|
||||
items,
|
||||
selectedView,
|
||||
@ -81,6 +81,22 @@ export default function LeftToolbarActions({
|
||||
<Terminal size={14} data-testid="clickhouse-view" />
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<Tooltip title="Query Builder V2">
|
||||
<Button
|
||||
disabled={QB.disabled}
|
||||
className={cx(
|
||||
queryBuilderV2,
|
||||
actionBtn,
|
||||
selectedView === queryBuilderV2 ? activeTab : '',
|
||||
)}
|
||||
onClick={(): void =>
|
||||
onChangeSelectedView(SELECTED_VIEWS.QUERY_BUILDER_V2)
|
||||
}
|
||||
>
|
||||
<Binoculars size={14} data-testid="query-builder-view-v2" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<div className="frequency-chart-view-controller">
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import Home2 from 'container/Home/Home2';
|
||||
import Home from 'container/Home/Home';
|
||||
|
||||
function HomePage(): JSX.Element {
|
||||
return <Home2 />;
|
||||
return <Home />;
|
||||
}
|
||||
|
||||
export default HomePage;
|
||||
|
||||
@ -21,6 +21,7 @@ export enum SELECTED_VIEWS {
|
||||
SEARCH = 'search',
|
||||
QUERY_BUILDER = 'query-builder',
|
||||
CLICKHOUSE = 'clickhouse',
|
||||
QUERY_BUILDER_V2 = 'query-builder-v2',
|
||||
}
|
||||
|
||||
export const LogsQuickFiltersConfig: IQuickFiltersConfig[] = [
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user