From 93463f2e04c89afd833cdab4800e70d33c2c9697 Mon Sep 17 00:00:00 2001 From: mohamadyasser118 Date: Fri, 27 Mar 2026 08:09:40 +0200 Subject: [PATCH 1/4] feat(webui): add SQL syntax highlighting to metric form editors --- internal/webui/package.json | 3 + .../components/MetricFormStepSQL.tsx | 66 +++++++++++-------- .../components/MetricFormStepSettings.tsx | 47 ++++++++++--- internal/webui/yarn.lock | 7 +- 4 files changed, 86 insertions(+), 37 deletions(-) diff --git a/internal/webui/package.json b/internal/webui/package.json index d3f4744cbb..ff7dac4acb 100644 --- a/internal/webui/package.json +++ b/internal/webui/package.json @@ -45,11 +45,13 @@ "axios": "^1.13.5", "classnames": "^2.5.1", "form-data": "^4.0.0", + "prismjs": "^1.30.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-hook-form": "^7.55.0", "react-markdown": "^10.1.0", "react-router-dom": "^6.28.1", + "react-simple-code-editor": "^0.14.1", "react-syntax-highlighter": "^16.1.1", "react-use-websocket": "^4.5.0", "tss-react": "^4.9.6", @@ -60,6 +62,7 @@ "devDependencies": { "@eslint/js": "^9.27.0", "@types/node": "^22.15.0", + "@types/prismjs": "^1.26.6", "@types/react": "^18.3.28", "@types/react-dom": "^18.3.7", "@types/react-syntax-highlighter": "^15.5.13", diff --git a/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSQL.tsx b/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSQL.tsx index cfde2d1c6e..107819aef7 100644 --- a/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSQL.tsx +++ b/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSQL.tsx @@ -2,44 +2,58 @@ import { FormControl, FormHelperText, InputLabel, OutlinedInput } from "@mui/mat import { useFormContext } from "react-hook-form"; import { useFormStyles } from "styles/form"; import { MetricFormValues } from "../MetricForm.types"; +import Editor from "react-simple-code-editor"; +import { highlight, languages } from "prismjs"; +import "prismjs/components/prism-sql"; +import "prismjs/themes/prism.css"; +import { Controller } from "react-hook-form"; + export const MetricFormStepSQL = () => { - const { register, formState: { errors } } = useFormContext(); + const { control, formState: { errors } } = useFormContext(); const { classes, cx } = useFormStyles(); - const hasError = (field: keyof MetricFormValues) => !!errors[field]; - - const getError = (field: keyof MetricFormValues) => { - const error = errors[field]; - if (error) { - return error.message; - } - return undefined; - }; + const hasError = !!errors.SQLs; + const errorMessage = errors.SQLs?.message; return (
- SQLs - + SQLs + + ( + highlight(code, languages.sql, "sql")} + padding={12} + id="SQLs" + style={{ + fontFamily: "'Fira Code', 'Consolas', monospace", + fontSize: "0.75rem", + lineHeight: 1.6, + minHeight: "240px", + border: hasError ? "1px solid #d32f2f" : "1px solid rgba(0,0,0,0.23)", + borderRadius: "4px", + backgroundColor: "#fafafa", + color: "#333", + }} + /> + )} /> - {getError("SQLs")} + {errorMessage}
); diff --git a/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSettings.tsx b/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSettings.tsx index f7bb9a6496..7b58639023 100644 --- a/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSettings.tsx +++ b/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSettings.tsx @@ -2,12 +2,17 @@ import { Checkbox, FormControl, FormControlLabel, FormHelperText, InputLabel, Ou import { useController, useFormContext } from "react-hook-form"; import { useFormStyles } from "styles/form"; import { MetricFormValues } from "../MetricForm.types"; +import Editor from "react-simple-code-editor"; +import { highlight, languages } from "prismjs"; +import "prismjs/components/prism-sql"; +import "prismjs/themes/prism-tomorrow.css"; +import { Controller } from "react-hook-form"; export const MetricFormStepSettings = () => { const { register, control } = useFormContext(); const { classes, cx } = useFormStyles(); - const { field } = useController({ name: "IsInstanceLevel", control }); + const { field: instanceLevelField } = useController({ name: "IsInstanceLevel", control }); return (
@@ -30,13 +35,35 @@ export const MetricFormStepSettings = () => { className={cx(classes.formControlInput, classes.widthFull)} variant="outlined" > - Init SQL - + Init SQL + + ( + highlight(code, languages.sql, "sql")} + padding={12} + id="InitSQL" + style={{ + fontFamily: "'Fira Code', 'Consolas', monospace", + fontSize: "0.75rem", + lineHeight: 1.6, + minHeight: "120px", + border: "1px solid rgba(0,0,0,0.23)", + borderRadius: "4px", + backgroundColor: "#2d2d2d", + color: "#ccc", + }} + /> + )} /> { labelPlacement="start" control={ } /> diff --git a/internal/webui/yarn.lock b/internal/webui/yarn.lock index 7b73fcc7a7..cc7eaf8010 100644 --- a/internal/webui/yarn.lock +++ b/internal/webui/yarn.lock @@ -1013,7 +1013,7 @@ resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== -"@types/prismjs@^1.0.0": +"@types/prismjs@^1.0.0", "@types/prismjs@^1.26.6": version "1.26.6" resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.6.tgz#6ea27c126d645319ae4f7055eda63a9e835c0187" integrity sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw== @@ -3428,6 +3428,11 @@ react-router@6.30.3: dependencies: "@remix-run/router" "1.23.2" +react-simple-code-editor@^0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/react-simple-code-editor/-/react-simple-code-editor-0.14.1.tgz#fd37eb3349f5def45900dd46acf296f796d81d2c" + integrity sha512-BR5DtNRy+AswWJECyA17qhUDvrrCZ6zXOCfkQY5zSmb96BVUbpVAv03WpcjcwtCwiLbIANx3gebHOcXYn1EHow== + react-syntax-highlighter@^16.1.1: version "16.1.1" resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-16.1.1.tgz#928459855d375f5cfc8e646071e20d541cebcb52" From 7ed1a40058e1c195e50f626a41605653c9a1de0e Mon Sep 17 00:00:00 2001 From: mohamadyasser118 Date: Fri, 27 Mar 2026 08:30:34 +0200 Subject: [PATCH 2/4] feat(webui): add SQL syntax highlighting to metric form editors --- .../MetricForm/components/MetricFormStepSettings.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSettings.tsx b/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSettings.tsx index 7b58639023..5951dfe5d9 100644 --- a/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSettings.tsx +++ b/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSettings.tsx @@ -5,7 +5,7 @@ import { MetricFormValues } from "../MetricForm.types"; import Editor from "react-simple-code-editor"; import { highlight, languages } from "prismjs"; import "prismjs/components/prism-sql"; -import "prismjs/themes/prism-tomorrow.css"; +import "prismjs/themes/prism.css"; import { Controller } from "react-hook-form"; export const MetricFormStepSettings = () => { @@ -59,8 +59,8 @@ export const MetricFormStepSettings = () => { minHeight: "120px", border: "1px solid rgba(0,0,0,0.23)", borderRadius: "4px", - backgroundColor: "#2d2d2d", - color: "#ccc", + backgroundColor: "#fafafa", + color: "#333", }} /> )} From 5c7595d458216661c8a07f8eeb54a5f2ff667313 Mon Sep 17 00:00:00 2001 From: mohamadyasser118 Date: Sat, 2 May 2026 00:03:20 +0300 Subject: [PATCH 3/4] fix: update SQL editor --- internal/webui/src/App.tsx | 3 + .../components/MetricFormStepSQL.tsx | 22 ++++--- .../components/MetricFormStepSettings.tsx | 58 ++++++++++--------- internal/webui/tsconfig.json | 1 + 4 files changed, 49 insertions(+), 35 deletions(-) diff --git a/internal/webui/src/App.tsx b/internal/webui/src/App.tsx index 07a5b7ff0b..e45655191d 100644 --- a/internal/webui/src/App.tsx +++ b/internal/webui/src/App.tsx @@ -13,6 +13,9 @@ import { privateRoutes, publicRoutes } from "layout/Routes"; import { AppBar } from "./layout/AppBar"; +import "prismjs/components/prism-sql"; +import "prismjs/themes/prism.css"; + const mdTheme = createTheme(); export default function App() { diff --git a/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSQL.tsx b/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSQL.tsx index 107819aef7..1016b71a67 100644 --- a/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSQL.tsx +++ b/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSQL.tsx @@ -1,17 +1,16 @@ -import { FormControl, FormHelperText, InputLabel, OutlinedInput } from "@mui/material"; -import { useFormContext } from "react-hook-form"; +import { FormControl, FormHelperText, InputLabel, OutlinedInput, useTheme } from "@mui/material"; +import { Controller, useFormContext } from "react-hook-form"; import { useFormStyles } from "styles/form"; import { MetricFormValues } from "../MetricForm.types"; import Editor from "react-simple-code-editor"; import { highlight, languages } from "prismjs"; -import "prismjs/components/prism-sql"; -import "prismjs/themes/prism.css"; -import { Controller } from "react-hook-form"; + export const MetricFormStepSQL = () => { const { control, formState: { errors } } = useFormContext(); const { classes, cx } = useFormStyles(); + const theme = useTheme(); const hasError = !!errors.SQLs; const errorMessage = errors.SQLs?.message; @@ -22,6 +21,7 @@ export const MetricFormStepSQL = () => { className={cx(classes.formControlInput, classes.widthFull)} error={hasError} variant="outlined" + aria-describedby="SQLs-error" > { highlight(code, languages.sql, "sql")} padding={12} - id="SQLs" + id="InitSQL" + aria-describedby="InitSQL-error" style={{ fontFamily: "'Fira Code', 'Consolas', monospace", fontSize: "0.75rem", lineHeight: 1.6, minHeight: "240px", - border: hasError ? "1px solid #d32f2f" : "1px solid rgba(0,0,0,0.23)", borderRadius: "4px", - backgroundColor: "#fafafa", - color: "#333", + backgroundColor: theme.palette.background.paper, + color: theme.palette.text.primary, + border: hasError + ? `1px solid ${theme.palette.error.main}` + : `1px solid ${theme.palette.divider}`, }} /> )} diff --git a/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSettings.tsx b/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSettings.tsx index 5951dfe5d9..201ee10e1d 100644 --- a/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSettings.tsx +++ b/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSettings.tsx @@ -1,17 +1,17 @@ -import { Checkbox, FormControl, FormControlLabel, FormHelperText, InputLabel, OutlinedInput } from "@mui/material"; -import { useController, useFormContext } from "react-hook-form"; +import { Checkbox, FormControl, FormControlLabel, FormHelperText, InputLabel, OutlinedInput, useTheme } from "@mui/material"; +import { Controller, useController, useFormContext } from "react-hook-form"; import { useFormStyles } from "styles/form"; import { MetricFormValues } from "../MetricForm.types"; import Editor from "react-simple-code-editor"; import { highlight, languages } from "prismjs"; -import "prismjs/components/prism-sql"; -import "prismjs/themes/prism.css"; -import { Controller } from "react-hook-form"; + export const MetricFormStepSettings = () => { - const { register, control } = useFormContext(); + const { register, control, formState: { errors }, } = useFormContext(); const { classes, cx } = useFormStyles(); - + const theme = useTheme(); + const hasError = !!errors.SQLs; + const errorMessage = errors.SQLs?.message; const { field: instanceLevelField } = useController({ name: "IsInstanceLevel", control }); return ( @@ -19,6 +19,8 @@ export const MetricFormStepSettings = () => { Gauges { { name="InitSQL" control={control} render={({ field }) => ( - highlight(code, languages.sql, "sql")} - padding={12} - id="InitSQL" - style={{ - fontFamily: "'Fira Code', 'Consolas', monospace", - fontSize: "0.75rem", - lineHeight: 1.6, - minHeight: "120px", - border: "1px solid rgba(0,0,0,0.23)", - borderRadius: "4px", - backgroundColor: "#fafafa", - color: "#333", - }} - /> - )} + highlight(code, languages.sql, "sql")} + padding={12} + id="InitSQL" + style={{ + fontFamily: "'Fira Code', 'Consolas', monospace", + fontSize: "0.75rem", + lineHeight: 1.6, + minHeight: "120px", + borderRadius: "4px", + backgroundColor: theme.palette.background.paper, + color: theme.palette.text.primary, + border: hasError + ? `1px solid ${theme.palette.error.main}` + : `1px solid ${theme.palette.divider}`, + }} + /> + )} /> + {errorMessage} Date: Sat, 2 May 2026 00:38:41 +0300 Subject: [PATCH 4/4] fix: clean implementation of SQL editor changes --- internal/webui/src/App.tsx | 3 + .../components/MetricFormStepSQL.tsx | 74 ++++++++++++------- .../components/MetricFormStepSettings.tsx | 63 ++++++++++++---- 3 files changed, 97 insertions(+), 43 deletions(-) diff --git a/internal/webui/src/App.tsx b/internal/webui/src/App.tsx index 07a5b7ff0b..e45655191d 100644 --- a/internal/webui/src/App.tsx +++ b/internal/webui/src/App.tsx @@ -13,6 +13,9 @@ import { privateRoutes, publicRoutes } from "layout/Routes"; import { AppBar } from "./layout/AppBar"; +import "prismjs/components/prism-sql"; +import "prismjs/themes/prism.css"; + const mdTheme = createTheme(); export default function App() { diff --git a/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSQL.tsx b/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSQL.tsx index cfde2d1c6e..1016b71a67 100644 --- a/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSQL.tsx +++ b/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSQL.tsx @@ -1,45 +1,63 @@ -import { FormControl, FormHelperText, InputLabel, OutlinedInput } from "@mui/material"; -import { useFormContext } from "react-hook-form"; +import { FormControl, FormHelperText, InputLabel, OutlinedInput, useTheme } from "@mui/material"; +import { Controller, useFormContext } from "react-hook-form"; import { useFormStyles } from "styles/form"; import { MetricFormValues } from "../MetricForm.types"; +import Editor from "react-simple-code-editor"; +import { highlight, languages } from "prismjs"; + + export const MetricFormStepSQL = () => { - const { register, formState: { errors } } = useFormContext(); + const { control, formState: { errors } } = useFormContext(); const { classes, cx } = useFormStyles(); + const theme = useTheme(); - const hasError = (field: keyof MetricFormValues) => !!errors[field]; - - const getError = (field: keyof MetricFormValues) => { - const error = errors[field]; - if (error) { - return error.message; - } - return undefined; - }; + const hasError = !!errors.SQLs; + const errorMessage = errors.SQLs?.message; return (
- SQLs - + SQLs + + ( + highlight(code, languages.sql, "sql")} + padding={12} + id="InitSQL" + aria-describedby="InitSQL-error" + style={{ + fontFamily: "'Fira Code', 'Consolas', monospace", + fontSize: "0.75rem", + lineHeight: 1.6, + minHeight: "240px", + borderRadius: "4px", + backgroundColor: theme.palette.background.paper, + color: theme.palette.text.primary, + border: hasError + ? `1px solid ${theme.palette.error.main}` + : `1px solid ${theme.palette.divider}`, + }} + /> + )} /> - {getError("SQLs")} + {errorMessage}
); diff --git a/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSettings.tsx b/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSettings.tsx index f7bb9a6496..201ee10e1d 100644 --- a/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSettings.tsx +++ b/internal/webui/src/containers/MetricFormDialog/components/MetricForm/components/MetricFormStepSettings.tsx @@ -1,19 +1,26 @@ -import { Checkbox, FormControl, FormControlLabel, FormHelperText, InputLabel, OutlinedInput } from "@mui/material"; -import { useController, useFormContext } from "react-hook-form"; +import { Checkbox, FormControl, FormControlLabel, FormHelperText, InputLabel, OutlinedInput, useTheme } from "@mui/material"; +import { Controller, useController, useFormContext } from "react-hook-form"; import { useFormStyles } from "styles/form"; import { MetricFormValues } from "../MetricForm.types"; +import Editor from "react-simple-code-editor"; +import { highlight, languages } from "prismjs"; + export const MetricFormStepSettings = () => { - const { register, control } = useFormContext(); + const { register, control, formState: { errors }, } = useFormContext(); const { classes, cx } = useFormStyles(); - - const { field } = useController({ name: "IsInstanceLevel", control }); + const theme = useTheme(); + const hasError = !!errors.SQLs; + const errorMessage = errors.SQLs?.message; + const { field: instanceLevelField } = useController({ name: "IsInstanceLevel", control }); return (
Gauges { - Init SQL - + Init SQL + + ( + highlight(code, languages.sql, "sql")} + padding={12} + id="InitSQL" + style={{ + fontFamily: "'Fira Code', 'Consolas', monospace", + fontSize: "0.75rem", + lineHeight: 1.6, + minHeight: "120px", + borderRadius: "4px", + backgroundColor: theme.palette.background.paper, + color: theme.palette.text.primary, + border: hasError + ? `1px solid ${theme.palette.error.main}` + : `1px solid ${theme.palette.divider}`, + }} + /> + )} /> + {errorMessage} { labelPlacement="start" control={ } />