Skip to content

Commit e465ec6

Browse files
authored
feat(editor): promql format; store selected query type (#559)
* feat(editor): promql format; store selected query type * refactor: remove return
1 parent 52a2d73 commit e465ec6

File tree

3 files changed

+80
-7
lines changed

3 files changed

+80
-7
lines changed

src/api/formatter.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import axios from 'axios'
2+
3+
export interface PromqlFormatRequest {
4+
query: string
5+
}
6+
7+
export interface PromqlFormatResponse {
8+
status: string
9+
data: string
10+
}
11+
12+
/**
13+
* Format PromQL query using the Prometheus API
14+
* @param query - The PromQL query string to format
15+
* @returns Promise<PromqlFormatResponse> - The formatted query response
16+
*/
17+
18+
const prometheusBaseURL = 'v1/prometheus/api/v1'
19+
export const formatPromqlQuery = async (query: string): Promise<PromqlFormatResponse> => {
20+
return axios.post(`${prometheusBaseURL}/format_query`, `query=${encodeURIComponent(query)}`, {
21+
headers: {
22+
'Content-Type': 'application/x-www-form-urlencoded',
23+
},
24+
})
25+
}

src/utils/sql.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { format as sqlFormat } from 'sql-formatter'
2+
import { formatPromqlQuery, type PromqlFormatResponse } from '@/api/formatter'
3+
import { Message } from '@arco-design/web-vue'
24

35
export const parseSqlStatements = (sql: string): { text: string; start: number; end: number }[] => {
46
if (!sql) return []
@@ -127,16 +129,34 @@ export const sqlFormatter = (code: string) => {
127129
formatted = formatted.endsWith(';') ? formatted : `${formatted};`
128130
} catch (formattingError) {
129131
console.warn(`Failed to format SQL statement: ${formattingError}`)
132+
Message.warning('Failed to format. Please check console for details.')
130133
formatted = trimmed.endsWith(';') ? trimmed : `${trimmed};`
131134
}
132-
133135
return formatted
134136
} catch (error) {
135137
console.error('SQL formatting error:', error)
136138
return code
137139
}
138140
}
139141

142+
export const promqlFormatter = async (code: string): Promise<string> => {
143+
try {
144+
const trimmed = code.trim()
145+
if (!trimmed) {
146+
return code
147+
}
148+
const response = await formatPromqlQuery(trimmed)
149+
if (response.status === 'success') {
150+
return response.data
151+
}
152+
console.warn('Unexpected response format from PromQL formatter:', response)
153+
return trimmed
154+
} catch (error) {
155+
console.error('PromQL formatting error:', error)
156+
return code
157+
}
158+
}
159+
140160
export function debounce<T extends (...args: any[]) => any>(fn: T, delay: number): (...args: Parameters<T>) => void {
141161
let timer: number | null = null
142162
return (...args: Parameters<T>) => {

src/views/dashboard/query/editor.vue

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ a-card.editor-card(:bordered="false")
6868
TimeAssistance(ref="tsRef" :cm="currentView")
6969
.query-select
7070
a-space(size="medium")
71-
a-tooltip(v-if="queryType === 'sql'" mini :content="$t('dashboard.format')")
72-
a-button(type="outline" :disabled="isButtonDisabled" @click="formatSql")
71+
a-tooltip(mini :content="$t('dashboard.format')")
72+
a-button(type="outline" :disabled="isButtonDisabled" @click="formatSql()")
7373
template(#icon)
7474
icon-code-block.icon-18
7575
a-tooltip(mini :content="$t('dashboard.clearCode')")
@@ -162,7 +162,7 @@ a-card.editor-card(:bordered="false")
162162
import { acceptCompletion } from '@codemirror/autocomplete'
163163
import type { PromForm } from '@/store/modules/code-run/types'
164164
import { useStorage } from '@vueuse/core'
165-
import { sqlFormatter, parseSqlStatements, findStatementAtPosition } from '@/utils/sql'
165+
import { sqlFormatter, parseSqlStatements, findStatementAtPosition, promqlFormatter } from '@/utils/sql'
166166
import { Message } from '@arco-design/web-vue'
167167
import fileDownload from 'js-file-download'
168168
@@ -357,9 +357,15 @@ a-card.editor-card(:bordered="false")
357357
secondaryCodeRunning.value = false
358358
}
359359
360-
const formatSql = () => {
360+
const formatSql = async () => {
361361
if (queryType.value === 'sql' && codes.value.sql.trim().length > 0) {
362362
codes.value.sql = sqlFormatter(codes.value.sql)
363+
} else if (queryType.value === 'promql' && codes.value.promql.trim().length > 0) {
364+
try {
365+
codes.value.promql = await promqlFormatter(codes.value.promql)
366+
} catch (error) {
367+
//
368+
}
363369
}
364370
}
365371
@@ -422,11 +428,33 @@ a-card.editor-card(:bordered="false")
422428
}
423429
424430
window.addEventListener('beforeunload', () => {
425-
localStorage.setItem('queryCode', JSON.stringify(codes.value))
431+
localStorage.setItem(
432+
'queryCode',
433+
JSON.stringify({
434+
sql: codes.value.sql,
435+
promql: codes.value.promql,
436+
type: queryType.value,
437+
})
438+
)
426439
})
427440
428441
onMounted(() => {
429-
codes.value = useStorage('queryCode', { sql: '', promql: '' }).value
442+
const stored = useStorage('queryCode', { sql: '', promql: '', type: 'sql' }).value
443+
codes.value.sql = stored.sql || ''
444+
codes.value.promql = stored.promql || ''
445+
queryType.value = stored.type || 'sql'
446+
})
447+
448+
// Watch queryType changes and save to localStorage immediately
449+
watch(queryType, () => {
450+
localStorage.setItem(
451+
'queryCode',
452+
JSON.stringify({
453+
sql: codes.value.sql,
454+
promql: codes.value.promql,
455+
type: queryType.value,
456+
})
457+
)
430458
})
431459
432460
// TODO: i18n config

0 commit comments

Comments
 (0)