loading...
+ ) : error ? (
+ loading...
+ ) : error ? (
+ ({
- execution_count: [],
- memory_usage: [],
- read_bytes: [],
- cpu: [],
- })
-
- const loadData = async () => {
+ const loadData = async (url: string) => {
try {
- const res = await fetch('/api/analyze/query_graphs')
+ const res = await fetch(url)
const resJson = await res.json()
const execution_count = resJson.execution_count
const memory_usage = resJson.memory_usage
const read_bytes = resJson.read_bytes
const cpu = resJson.cpu
- setQueryGraphs({ execution_count, memory_usage, read_bytes, cpu })
+ return { execution_count, memory_usage, read_bytes, cpu }
} catch (err) {
notification.error({ message: 'Failed to load data' })
}
}
- useEffect(() => {
- loadData()
- }, [])
+ const { data, error, isLoading } = useSWR('/api/analyze/query_graphs', loadData)
const now = new Date()
const dayOfTheYear = Math.floor(
(now.getTime() - new Date(now.getFullYear(), 0, 0).getTime()) / (1000 * 60 * 60 * 24)
)
- return (
+ console.log(data, error, isLoading)
+
+ return isLoading ? (
+ loading
+ ) : error ? (
+ error
+ ) : (
Overview
{clickhouseTips[dayOfTheYear % clickhouseTips.length]}
@@ -56,7 +54,7 @@ export default function Overview() {
({
+ data={data!.execution_count.map((dataPoint: any) => ({
...dataPoint,
day_start: dataPoint.day_start.split('T')[0],
}))}
@@ -65,14 +63,14 @@ export default function Overview() {
xAxis={{ tickCount: 5 }}
style={{ padding: 20, height: 300 }}
color="#ffb200"
- loading={queryGraphs.execution_count.length < 1}
+ loading={isLoading}
/>
({
+ data={data!.read_bytes.map((dataPoint: any) => ({
day_start: dataPoint.day_start.split('T')[0],
total: dataPoint.total / 1000000000,
}))}
@@ -81,7 +79,7 @@ export default function Overview() {
xAxis={{ tickCount: 5 }}
style={{ padding: 20, height: 300 }}
color="#ffb200"
- loading={queryGraphs.read_bytes.length < 1}
+ loading={isLoading}
/>
@@ -90,7 +88,7 @@ export default function Overview() {
({
+ data={data!.memory_usage.map((dataPoint: any) => ({
day_start: dataPoint.day_start.split('T')[0],
total: dataPoint.total / 1000000000,
}))}
@@ -98,7 +96,7 @@ export default function Overview() {
yField={'total'}
style={{ padding: 20, height: 300 }}
color="#ffb200"
- loading={queryGraphs.memory_usage.length < 1}
+ loading={isLoading}
/>
@@ -111,13 +109,13 @@ export default function Overview() {
-
+
>
}
>
({
+ data={data!.cpu.map((dataPoint: any) => ({
day_start: dataPoint.day_start.split('T')[0],
total: dataPoint.total,
}))}
@@ -125,7 +123,7 @@ export default function Overview() {
yField={'total'}
style={{ padding: 20, height: 300 }}
color="#ffb200"
- loading={queryGraphs.cpu.length < 1}
+ loading={isLoading}
/>
diff --git a/frontend/src/pages/QueryEditor/Benchmark.tsx b/frontend/src/pages/QueryEditor/Benchmark.tsx
index 26a076a..9c6263c 100644
--- a/frontend/src/pages/QueryEditor/Benchmark.tsx
+++ b/frontend/src/pages/QueryEditor/Benchmark.tsx
@@ -6,6 +6,7 @@ import 'prismjs/components/prism-sql'
import 'prismjs/themes/prism.css'
import Editor from 'react-simple-code-editor'
import { Column } from '@ant-design/charts'
+import useSWR from 'swr'
export interface BenchmarkingData {
benchmarking_result: {
@@ -82,8 +83,8 @@ export default function QueryBenchmarking() {
setQuery1(code)}
- highlight={(code) => highlight(code, languages.sql)}
+ onValueChange={code => setQuery1(code)}
+ highlight={code => highlight(code, languages.sql)}
padding={10}
style={{
fontFamily: '"Fira code", "Fira Mono", monospace',
@@ -102,8 +103,8 @@ export default function QueryBenchmarking() {
setQuery2(code)}
- highlight={(code) => highlight(code, languages.sql)}
+ onValueChange={code => setQuery2(code)}
+ highlight={code => highlight(code, languages.sql)}
padding={10}
style={{
fontFamily: '"Fira code", "Fira Mono", monospace',
diff --git a/frontend/src/pages/QueryEditor/QueryEditor.tsx b/frontend/src/pages/QueryEditor/QueryEditor.tsx
index d457991..5d0b5d7 100644
--- a/frontend/src/pages/QueryEditor/QueryEditor.tsx
+++ b/frontend/src/pages/QueryEditor/QueryEditor.tsx
@@ -6,7 +6,7 @@ import 'prismjs/components/prism-sql'
import 'prismjs/themes/prism.css'
import Editor from 'react-simple-code-editor'
import { v4 as uuidv4 } from 'uuid'
-import { SaveOutlined } from '@ant-design/icons'
+import SaveOutlined from '@ant-design/icons'
function CreateSavedQueryModal({
modalOpen = false,
@@ -27,7 +27,7 @@ function CreateSavedQueryModal({
onOk={() => saveQuery(queryName)}
onCancel={() => setModalOpen(false)}
>
- setQueryName(e.target.value)} />
+ setQueryName(e.target.value)} />
>
)
@@ -42,7 +42,7 @@ export default function QueryEditor() {
const [runningQueryId, setRunningQueryId] = useState(null)
const [modalOpen, setModalOpen] = useState(false)
- const columns = data.length > 0 ? Object.keys(data[0]).map((column) => ({ title: column, dataIndex: column })) : []
+ const columns = data.length > 0 ? Object.keys(data[0]).map(column => ({ title: column, dataIndex: column })) : []
const saveQuery = async (queryName: string) => {
try {
@@ -116,7 +116,7 @@ export default function QueryEditor() {
{data && Object.keys(data[0] || {}).length > 0 ? (
) : null}
@@ -125,8 +125,8 @@ export default function QueryEditor() {
setSql(code)}
- highlight={(code) => highlight(code, languages.sql)}
+ onValueChange={code => setSql(code)}
+ highlight={code => highlight(code, languages.sql)}
padding={10}
style={{
fontFamily: '"Fira code", "Fira Mono", monospace',
diff --git a/frontend/src/pages/QueryEditor/SavedQueries.tsx b/frontend/src/pages/QueryEditor/SavedQueries.tsx
index bf3f84a..30a9320 100644
--- a/frontend/src/pages/QueryEditor/SavedQueries.tsx
+++ b/frontend/src/pages/QueryEditor/SavedQueries.tsx
@@ -2,7 +2,7 @@ import { Table, Button, Row, Col, Tooltip } from 'antd'
import React, { useEffect, useState } from 'react'
import { ColumnType } from 'antd/es/table'
import SavedQuery from './SavedQuery'
-import { ReloadOutlined } from '@ant-design/icons'
+import ReloadOutlined from '@ant-design/icons'
import { useHistory } from 'react-router-dom'
import { isoTimestampToHumanReadable } from '../../utils/dateUtils'
@@ -30,7 +30,7 @@ export default function SavedQueries({ match }: { match: { params: { id: string
loadData()
}, [])
- const columns: ColumnType<{ name: string; id: number; query: string, created_at: string }>[] = [
+ const columns: ColumnType<{ name: string; id: number; query: string; created_at: string }>[] = [
{
title: 'Name',
dataIndex: 'name',
@@ -48,7 +48,7 @@ export default function SavedQueries({ match }: { match: { params: { id: string
},
{
title: 'Created at',
- render: (_, item) => item.created_at ? isoTimestampToHumanReadable(item.created_at) : '',
+ render: (_, item) => (item.created_at ? isoTimestampToHumanReadable(item.created_at) : ''),
},
]
@@ -74,7 +74,7 @@ export default function SavedQueries({ match }: { match: { params: { id: string
diff --git a/frontend/src/pages/SlowQueries/MetricsTab.tsx b/frontend/src/pages/SlowQueries/MetricsTab.tsx
index dc3d83d..f744bab 100644
--- a/frontend/src/pages/SlowQueries/MetricsTab.tsx
+++ b/frontend/src/pages/SlowQueries/MetricsTab.tsx
@@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'
import { Line } from '@ant-design/plots'
// @ts-ignore
import { Card, Col, Row, Tooltip, notification } from 'antd'
-import { InfoCircleOutlined } from '@ant-design/icons'
+import InfoCircleOutlined from '@ant-design/icons'
import { NoDataSpinner, QueryDetailData } from './QueryDetail'
export default function MetricsTab({ query_hash }: { query_hash: string }) {
@@ -31,7 +31,7 @@ export default function MetricsTab({ query_hash }: { query_hash: string }) {
({
+ data={data.execution_count.map(dataPoint => ({
...dataPoint,
day_start: dataPoint.day_start.split('T')[0],
}))}
@@ -46,7 +46,7 @@ export default function MetricsTab({ query_hash }: { query_hash: string }) {
({
+ data={data.read_bytes.map(dataPoint => ({
day_start: dataPoint.day_start.split('T')[0],
total: dataPoint.total / 1000000000,
}))}
@@ -63,7 +63,7 @@ export default function MetricsTab({ query_hash }: { query_hash: string }) {
({
+ data={data.memory_usage.map(dataPoint => ({
day_start: dataPoint.day_start.split('T')[0],
total: dataPoint.total / 1000000000,
}))}
@@ -84,14 +84,14 @@ export default function MetricsTab({ query_hash }: { query_hash: string }) {
title={`Calculated from OSCPUVirtualTimeMicroseconds metric from ClickHouse query log's ProfileEvents.`}
>
-
+
>
}
>
({
+ data={data.cpu.map(dataPoint => ({
day_start: dataPoint.day_start.split('T')[0],
total: dataPoint.total,
}))}
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts
new file mode 100644
index 0000000..201371a
--- /dev/null
+++ b/frontend/vite.config.ts
@@ -0,0 +1,30 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [react()],
+ server: {
+ proxy: {
+ "/api": {
+ target: "http://127.0.0.1:8000",
+ secure: false,
+ ws: true,
+ },
+ "/admin/": {
+ target: "http://127.0.0.1:8000",
+ secure: false,
+ ws: true,
+ },
+ "/logout": {
+ target: "http://127.0.0.1:8000",
+ secure: false,
+ ws: true,
+ },
+ },
+ },
+ base: process.env.NODE_ENV === "production" ? "/webapp/" : "/",
+ build: {
+ outDir: "./build"
+ }
+})