Skip to content

Commit

Permalink
Allow formatting PromQL expressions in the UI
Browse files Browse the repository at this point in the history
Signed-off-by: Julius Volz <julius.volz@gmail.com>
  • Loading branch information
juliusv committed Jul 20, 2022
1 parent 911dfa8 commit be64c47
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 5 deletions.
49 changes: 46 additions & 3 deletions web/ui/react-app/src/pages/graph/ExpressionInput.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { FC, useState, useEffect, useRef } from 'react';
import { Button, InputGroup, InputGroupAddon, InputGroupText } from 'reactstrap';
import { Alert, Button, InputGroup, InputGroupAddon, InputGroupText } from 'reactstrap';

import { EditorView, highlightSpecialChars, keymap, ViewUpdate, placeholder } from '@codemirror/view';
import { EditorState, Prec, Compartment } from '@codemirror/state';
Expand All @@ -18,12 +18,13 @@ import {
import { baseTheme, lightTheme, darkTheme, promqlHighlighter } from './CMTheme';

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faSearch, faSpinner, faGlobeEurope } from '@fortawesome/free-solid-svg-icons';
import { faSearch, faSpinner, faGlobeEurope, faIndent } from '@fortawesome/free-solid-svg-icons';
import MetricsExplorer from './MetricsExplorer';
import { usePathPrefix } from '../../contexts/PathPrefixContext';
import { useTheme } from '../../contexts/ThemeContext';
import { CompleteStrategy, PromQLExtension } from '@prometheus-io/codemirror-promql';
import { newCompleteStrategy } from '@prometheus-io/codemirror-promql/dist/esm/complete';
import { API_PATH } from '../../constants/constants';

const promqlExtension = new PromQLExtension();

Expand Down Expand Up @@ -98,6 +99,9 @@ const ExpressionInput: FC<CMExpressionInputProps> = ({
const pathPrefix = usePathPrefix();
const { theme } = useTheme();

const [formatError, setFormatError] = useState<string | null>(null);
const [isFormatting, setIsFormatting] = useState<boolean>(false);

// (Re)initialize editor based on settings / setting changes.
useEffect(() => {
// Build the dynamic part of the config.
Expand Down Expand Up @@ -209,6 +213,35 @@ const ExpressionInput: FC<CMExpressionInputProps> = ({
);
};

const formatExpression = async () => {
setFormatError(null);
setIsFormatting(true);

const query = await fetch(
`${pathPrefix}/${API_PATH}/format_query?${new URLSearchParams({
query: value,
})}`,
{
cache: 'no-store',
credentials: 'same-origin',
}
).then((resp) => resp.json());

setIsFormatting(false);

if (query.status !== 'success') {
setFormatError(query.error || 'invalid response JSON');
return;
}

const view = viewRef.current;
if (view === null) {
return;
}

view.dispatch(view.state.update({ changes: { from: 0, to: view.state.doc.length, insert: query.data } }));
};

return (
<>
<InputGroup className="expression-input">
Expand All @@ -220,7 +253,15 @@ const ExpressionInput: FC<CMExpressionInputProps> = ({
<div ref={containerRef} className="cm-expression-input" />
<InputGroupAddon addonType="append">
<Button
className="metrics-explorer-btn"
className="expression-input-action-btn"
title="Format expression"
onClick={formatExpression}
disabled={isFormatting}
>
{isFormatting ? <FontAwesomeIcon icon={faSpinner} spin /> : <FontAwesomeIcon icon={faIndent} />}
</Button>
<Button
className="expression-input-action-btn"
title="Open metrics explorer"
onClick={() => setShowMetricsExplorer(true)}
>
Expand All @@ -232,6 +273,8 @@ const ExpressionInput: FC<CMExpressionInputProps> = ({
</InputGroupAddon>
</InputGroup>

{formatError && <Alert color="danger">Error formatting expression: {formatError}</Alert>}

<MetricsExplorer
show={showMetricsExplorer}
updateShow={setShowMetricsExplorer}
Expand Down
4 changes: 2 additions & 2 deletions web/ui/react-app/src/themes/_shared.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
Example:
$foo = '#000';
2. Add a style rule in _shared.scss (this file) that uses new variable.
Example:
Expand Down Expand Up @@ -58,7 +58,7 @@
.metrics-explorer .metric:hover {
background: $metrics-explorer-bg;
}
button.metrics-explorer-btn {
button.expression-input-action-btn {
color: $input-group-addon-color;
background-color: $input-group-addon-bg;
border: $input-border-width solid $input-group-addon-border-color;
Expand Down

0 comments on commit be64c47

Please sign in to comment.