vmui: switching to Preact (#2053)

* feat: replace @codemirror to text field

* feat: switch to Preact from React

* fix: optimize mui imports

* fix: remove unused vars

* update package-lock.json

* app/vmselect/vmui: `make vmui-update`

Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>
This commit is contained in:
Yury Molodov 2022-01-11 11:32:17 +03:00 committed by Aliaksandr Valialkin
parent ad0c21ff26
commit 7ee09286ef
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
48 changed files with 11814 additions and 5282 deletions

View file

@ -1,12 +1,12 @@
{ {
"files": { "files": {
"main.css": "./static/css/main.79ff1ad2.css", "main.css": "./static/css/main.79ff1ad2.css",
"main.js": "./static/js/main.22df0342.js", "main.js": "./static/js/main.31aed9a0.js",
"static/js/27.85f0e2b0.chunk.js": "./static/js/27.85f0e2b0.chunk.js", "static/js/27.cc1b69f7.chunk.js": "./static/js/27.cc1b69f7.chunk.js",
"index.html": "./index.html" "index.html": "./index.html"
}, },
"entrypoints": [ "entrypoints": [
"static/css/main.79ff1ad2.css", "static/css/main.79ff1ad2.css",
"static/js/main.22df0342.js" "static/js/main.31aed9a0.js"
] ]
} }

View file

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="VM-UI is a metric explorer for Victoria Metrics"/><link rel="apple-touch-icon" href="./apple-touch-icon.png"/><link rel="icon" type="image/png" sizes="32x32" href="./favicon-32x32.png"><link rel="manifest" href="./manifest.json"/><title>VM UI</title><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"/><script defer="defer" src="./static/js/main.22df0342.js"></script><link href="./static/css/main.79ff1ad2.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html> <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="VM-UI is a metric explorer for Victoria Metrics"/><link rel="apple-touch-icon" href="./apple-touch-icon.png"/><link rel="icon" type="image/png" sizes="32x32" href="./favicon-32x32.png"><link rel="manifest" href="./manifest.json"/><title>VM UI</title><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"/><script defer="defer" src="./static/js/main.31aed9a0.js"></script><link href="./static/css/main.79ff1ad2.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

View file

@ -1 +1 @@
"use strict";(self.webpackChunkvmui=self.webpackChunkvmui||[]).push([[27],{4027:function(e,n,t){t.r(n),t.d(n,{getCLS:function(){return y},getFCP:function(){return g},getFID:function(){return C},getLCP:function(){return P},getTTFB:function(){return D}});var i,r,a,o,u=function(e,n){return{name:e,value:void 0===n?-1:n,delta:0,entries:[],id:"v2-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)}},c=function(e,n){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){if("first-input"===e&&!("PerformanceEventTiming"in self))return;var t=new PerformanceObserver((function(e){return e.getEntries().map(n)}));return t.observe({type:e,buffered:!0}),t}}catch(e){}},f=function(e,n){var t=function t(i){"pagehide"!==i.type&&"hidden"!==document.visibilityState||(e(i),n&&(removeEventListener("visibilitychange",t,!0),removeEventListener("pagehide",t,!0)))};addEventListener("visibilitychange",t,!0),addEventListener("pagehide",t,!0)},s=function(e){addEventListener("pageshow",(function(n){n.persisted&&e(n)}),!0)},m=function(e,n,t){var i;return function(r){n.value>=0&&(r||t)&&(n.delta=n.value-(i||0),(n.delta||void 0===i)&&(i=n.value,e(n)))}},v=-1,p=function(){return"hidden"===document.visibilityState?0:1/0},d=function(){f((function(e){var n=e.timeStamp;v=n}),!0)},l=function(){return v<0&&(v=p(),d(),s((function(){setTimeout((function(){v=p(),d()}),0)}))),{get firstHiddenTime(){return v}}},g=function(e,n){var t,i=l(),r=u("FCP"),a=function(e){"first-contentful-paint"===e.name&&(f&&f.disconnect(),e.startTime<i.firstHiddenTime&&(r.value=e.startTime,r.entries.push(e),t(!0)))},o=window.performance&&performance.getEntriesByName&&performance.getEntriesByName("first-contentful-paint")[0],f=o?null:c("paint",a);(o||f)&&(t=m(e,r,n),o&&a(o),s((function(i){r=u("FCP"),t=m(e,r,n),requestAnimationFrame((function(){requestAnimationFrame((function(){r.value=performance.now()-i.timeStamp,t(!0)}))}))})))},h=!1,T=-1,y=function(e,n){h||(g((function(e){T=e.value})),h=!0);var t,i=function(n){T>-1&&e(n)},r=u("CLS",0),a=0,o=[],v=function(e){if(!e.hadRecentInput){var n=o[0],i=o[o.length-1];a&&e.startTime-i.startTime<1e3&&e.startTime-n.startTime<5e3?(a+=e.value,o.push(e)):(a=e.value,o=[e]),a>r.value&&(r.value=a,r.entries=o,t())}},p=c("layout-shift",v);p&&(t=m(i,r,n),f((function(){p.takeRecords().map(v),t(!0)})),s((function(){a=0,T=-1,r=u("CLS",0),t=m(i,r,n)})))},E={passive:!0,capture:!0},w=new Date,L=function(e,n){i||(i=n,r=e,a=new Date,F(removeEventListener),S())},S=function(){if(r>=0&&r<a-w){var e={entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+r};o.forEach((function(n){n(e)})),o=[]}},b=function(e){if(e.cancelable){var n=(e.timeStamp>1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,n){var t=function(){L(e,n),r()},i=function(){r()},r=function(){removeEventListener("pointerup",t,E),removeEventListener("pointercancel",i,E)};addEventListener("pointerup",t,E),addEventListener("pointercancel",i,E)}(n,e):L(n,e)}},F=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return e(n,b,E)}))},C=function(e,n){var t,a=l(),v=u("FID"),p=function(e){e.startTime<a.firstHiddenTime&&(v.value=e.processingStart-e.startTime,v.entries.push(e),t(!0))},d=c("first-input",p);t=m(e,v,n),d&&f((function(){d.takeRecords().map(p),d.disconnect()}),!0),d&&s((function(){var a;v=u("FID"),t=m(e,v,n),o=[],r=-1,i=null,F(addEventListener),a=p,o.push(a),S()}))},k={},P=function(e,n){var t,i=l(),r=u("LCP"),a=function(e){var n=e.startTime;n<i.firstHiddenTime&&(r.value=n,r.entries.push(e)),t()},o=c("largest-contentful-paint",a);if(o){t=m(e,r,n);var v=function(){k[r.id]||(o.takeRecords().map(a),o.disconnect(),k[r.id]=!0,t(!0))};["keydown","click"].forEach((function(e){addEventListener(e,v,{once:!0,capture:!0})})),f(v,!0),s((function(i){r=u("LCP"),t=m(e,r,n),requestAnimationFrame((function(){requestAnimationFrame((function(){r.value=performance.now()-i.timeStamp,k[r.id]=!0,t(!0)}))}))}))}},D=function(e){var n,t=u("TTFB");n=function(){try{var n=performance.getEntriesByType("navigation")[0]||function(){var e=performance.timing,n={entryType:"navigation",startTime:0};for(var t in e)"navigationStart"!==t&&"toJSON"!==t&&(n[t]=Math.max(e[t]-e.navigationStart,0));return n}();if(t.value=t.delta=n.responseStart,t.value<0||t.value>performance.now())return;t.entries=[n],e(t)}catch(e){}},"complete"===document.readyState?setTimeout(n,0):addEventListener("pageshow",n)}}}]); "use strict";(self.webpackChunkvmui=self.webpackChunkvmui||[]).push([[27],{4027:function(e,n,t){t.r(n),t.d(n,{getCLS:function(){return y},getFCP:function(){return g},getFID:function(){return C},getLCP:function(){return P},getTTFB:function(){return D}});var i,r,a,o,u=function(e,n){return{name:e,value:void 0===n?-1:n,delta:0,entries:[],id:"v2-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)}},c=function(e,n){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){if("first-input"===e&&!("PerformanceEventTiming"in self))return;var t=new PerformanceObserver((function(e){return e.getEntries().map(n)}));return t.observe({type:e,buffered:!0}),t}}catch(e){}},f=function(e,n){var t=function t(i){"pagehide"!==i.type&&"hidden"!==document.visibilityState||(e(i),n&&(removeEventListener("visibilitychange",t,!0),removeEventListener("pagehide",t,!0)))};addEventListener("visibilitychange",t,!0),addEventListener("pagehide",t,!0)},s=function(e){addEventListener("pageshow",(function(n){n.persisted&&e(n)}),!0)},m=function(e,n,t){var i;return function(r){n.value>=0&&(r||t)&&(n.delta=n.value-(i||0),(n.delta||void 0===i)&&(i=n.value,e(n)))}},v=-1,p=function(){return"hidden"===document.visibilityState?0:1/0},d=function(){f((function(e){var n=e.timeStamp;v=n}),!0)},l=function(){return v<0&&(v=p(),d(),s((function(){setTimeout((function(){v=p(),d()}),0)}))),{get firstHiddenTime(){return v}}},g=function(e,n){var t,i=l(),r=u("FCP"),a=function(e){"first-contentful-paint"===e.name&&(f&&f.disconnect(),e.startTime<i.firstHiddenTime&&(r.value=e.startTime,r.entries.push(e),t(!0)))},o=window.performance&&performance.getEntriesByName&&performance.getEntriesByName("first-contentful-paint")[0],f=o?null:c("paint",a);(o||f)&&(t=m(e,r,n),o&&a(o),s((function(i){r=u("FCP"),t=m(e,r,n),requestAnimationFrame((function(){requestAnimationFrame((function(){r.value=performance.now()-i.timeStamp,t(!0)}))}))})))},h=!1,T=-1,y=function(e,n){h||(g((function(e){T=e.value})),h=!0);var t,i=function(n){T>-1&&e(n)},r=u("CLS",0),a=0,o=[],v=function(e){if(!e.hadRecentInput){var n=o[0],i=o[o.length-1];a&&e.startTime-i.startTime<1e3&&e.startTime-n.startTime<5e3?(a+=e.value,o.push(e)):(a=e.value,o=[e]),a>r.value&&(r.value=a,r.entries=o,t())}},p=c("layout-shift",v);p&&(t=m(i,r,n),f((function(){p.takeRecords().map(v),t(!0)})),s((function(){a=0,T=-1,r=u("CLS",0),t=m(i,r,n)})))},E={passive:!0,capture:!0},w=new Date,L=function(e,n){i||(i=n,r=e,a=new Date,F(removeEventListener),S())},S=function(){if(r>=0&&r<a-w){var e={entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+r};o.forEach((function(n){n(e)})),o=[]}},b=function(e){if(e.cancelable){var n=(e.timeStamp>1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,n){var t=function(){L(e,n),r()},i=function(){r()},r=function(){removeEventListener("pointerup",t,E),removeEventListener("pointercancel",i,E)};addEventListener("pointerup",t,E),addEventListener("pointercancel",i,E)}(n,e):L(n,e)}},F=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return e(n,b,E)}))},C=function(e,n){var t,a=l(),v=u("FID"),p=function(e){e.startTime<a.firstHiddenTime&&(v.value=e.processingStart-e.startTime,v.entries.push(e),t(!0))},d=c("first-input",p);t=m(e,v,n),d&&f((function(){d.takeRecords().map(p),d.disconnect()}),!0),d&&s((function(){var a;v=u("FID"),t=m(e,v,n),o=[],r=-1,i=null,F(addEventListener),a=p,o.push(a),S()}))},k={},P=function(e,n){var t,i=l(),r=u("LCP"),a=function(e){var n=e.startTime;n<i.firstHiddenTime&&(r.value=n,r.entries.push(e),t())},o=c("largest-contentful-paint",a);if(o){t=m(e,r,n);var v=function(){k[r.id]||(o.takeRecords().map(a),o.disconnect(),k[r.id]=!0,t(!0))};["keydown","click"].forEach((function(e){addEventListener(e,v,{once:!0,capture:!0})})),f(v,!0),s((function(i){r=u("LCP"),t=m(e,r,n),requestAnimationFrame((function(){requestAnimationFrame((function(){r.value=performance.now()-i.timeStamp,k[r.id]=!0,t(!0)}))}))}))}},D=function(e){var n,t=u("TTFB");n=function(){try{var n=performance.getEntriesByType("navigation")[0]||function(){var e=performance.timing,n={entryType:"navigation",startTime:0};for(var t in e)"navigationStart"!==t&&"toJSON"!==t&&(n[t]=Math.max(e[t]-e.navigationStart,0));return n}();if(t.value=t.delta=n.responseStart,t.value<0||t.value>performance.now())return;t.entries=[n],e(t)}catch(e){}},"complete"===document.readyState?setTimeout(n,0):addEventListener("pageshow",n)}}}]);

File diff suppressed because one or more lines are too long

View file

@ -1,81 +0,0 @@
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/
/*! @preserve
* numeral.js
* version : 2.0.6
* author : Adam Draper
* license : MIT
* http://adamwdraper.github.com/Numeral-js/
*/
/**
* A better abstraction over CSS.
*
* @copyright Oleg Isonen (Slobodskoi) / Isonen 2014-present
* @website https://github.com/cssinjs/jss
* @license MIT
*/
/** @license MUI v5.2.6
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v0.20.2
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v16.13.1
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.2
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.2
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.2
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.2
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,39 @@
/*! @preserve
* numeral.js
* version : 2.0.6
* author : Adam Draper
* license : MIT
* http://adamwdraper.github.com/Numeral-js/
*/
/**
* A better abstraction over CSS.
*
* @copyright Oleg Isonen (Slobodskoi) / Isonen 2014-present
* @website https://github.com/cssinjs/jss
* @license MIT
*/
/** @license MUI v5.2.6
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v16.13.1
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.2
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

View file

@ -1,4 +1,4 @@
FROM node:alpine3.14 FROM node:alpine3.15
RUN apk update && apk add --no-cache bash bash-doc bash-completion libtool autoconf automake nasm pkgconfig libpng gcc make g++ zlib-dev gawk RUN apk update && apk add --no-cache bash bash-doc bash-completion libtool autoconf automake nasm pkgconfig libpng gcc make g++ zlib-dev gawk

View file

@ -1,7 +1,13 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires,no-undef // eslint-disable-next-line @typescript-eslint/no-var-requires,no-undef
const {override, addExternalBabelPlugin} = require("customize-cra"); const {override, addExternalBabelPlugin, addWebpackAlias} = require("customize-cra");
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
module.exports = override( module.exports = override(
addExternalBabelPlugin("@babel/plugin-proposal-nullish-coalescing-operator") addExternalBabelPlugin("@babel/plugin-proposal-nullish-coalescing-operator"),
addWebpackAlias({
"react": "preact/compat",
"react-dom/test-utils": "preact/test-utils",
"react-dom": "preact/compat", // Must be below test-utils
"react/jsx-runtime": "preact/jsx-runtime"
})
); );

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,6 @@
"homepage": "./", "homepage": "./",
"dependencies": { "dependencies": {
"@date-io/dayjs": "^2.11.0", "@date-io/dayjs": "^2.11.0",
"@emotion/react": "^11.7.1",
"@emotion/styled": "^11.6.0", "@emotion/styled": "^11.6.0",
"@mui/icons-material": "^5.2.5", "@mui/icons-material": "^5.2.5",
"@mui/lab": "^5.0.0-alpha.63", "@mui/lab": "^5.0.0-alpha.63",
@ -29,12 +28,8 @@
"lodash.get": "^4.4.2", "lodash.get": "^4.4.2",
"lodash.throttle": "^4.1.1", "lodash.throttle": "^4.1.1",
"numeral": "^2.0.6", "numeral": "^2.0.6",
"preact": "^10.6.4",
"qs": "^6.10.2", "qs": "^6.10.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-draggable": "^4.4.4",
"react-measure": "^2.5.2",
"react-scripts": "5.0.0",
"typescript": "~4.5.4", "typescript": "~4.5.4",
"uplot": "^1.6.18", "uplot": "^1.6.18",
"web-vitals": "^2.1.3" "web-vitals": "^2.1.3"

View file

@ -1,4 +1,4 @@
import React from "react"; import React from "preact/compat";
import {render, screen} from "@testing-library/react"; import {render, screen} from "@testing-library/react";
import App from "./App"; import App from "./App";

View file

@ -1,11 +1,11 @@
import React, {FC} from "react"; import React, {FC} from "preact/compat";
import {SnackbarProvider} from "./contexts/Snackbar"; import {SnackbarProvider} from "./contexts/Snackbar";
import HomeLayout from "./components/Home/HomeLayout"; import HomeLayout from "./components/Home/HomeLayout";
import {StateProvider} from "./state/common/StateContext"; import {StateProvider} from "./state/common/StateContext";
import {AuthStateProvider} from "./state/auth/AuthStateContext"; import {AuthStateProvider} from "./state/auth/AuthStateContext";
import {GraphStateProvider} from "./state/graph/GraphStateContext"; import {GraphStateProvider} from "./state/graph/GraphStateContext";
import { ThemeProvider, StyledEngineProvider } from "@mui/material/styles";
import THEME from "./theme/theme"; import THEME from "./theme/theme";
import { ThemeProvider, StyledEngineProvider } from "@mui/material/styles";
import CssBaseline from "@mui/material/CssBaseline"; import CssBaseline from "@mui/material/CssBaseline";
import LocalizationProvider from "@mui/lab/LocalizationProvider"; import LocalizationProvider from "@mui/lab/LocalizationProvider";
import DayjsUtils from "@date-io/dayjs"; import DayjsUtils from "@date-io/dayjs";

View file

@ -1,5 +1,9 @@
import React, {FC} from "react"; import React, {FC} from "preact/compat";
import {AppBar, Box, Link, Toolbar, Typography} from "@mui/material"; import AppBar from "@mui/material/AppBar";
import Box from "@mui/material/Box";
import Link from "@mui/material/Link";
import Toolbar from "@mui/material/Toolbar";
import Typography from "@mui/material/Typography";
import {ExecutionControls} from "../Home/Configurator/Time/ExecutionControls"; import {ExecutionControls} from "../Home/Configurator/Time/ExecutionControls";
import {DisplayTypeSwitch} from "../Home/Configurator/DisplayTypeSwitch"; import {DisplayTypeSwitch} from "../Home/Configurator/DisplayTypeSwitch";
import Logo from "../common/Logo"; import Logo from "../common/Logo";

View file

@ -1,26 +1,24 @@
/* eslint max-lines: ["error", {"max": 300}] */ /* eslint max-lines: ["error", {"max": 300}] */
import React, {useState} from "react"; import React, {useState} from "preact/compat";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Checkbox from "@mui/material/Checkbox";
import DialogActions from "@mui/material/DialogActions";
import DialogContent from "@mui/material/DialogContent";
import DialogContentText from "@mui/material/DialogContentText";
import FormControl from "@mui/material/FormControl";
import FormControlLabel from "@mui/material/FormControlLabel";
import FormHelperText from "@mui/material/FormHelperText";
import Input from "@mui/material/Input";
import InputAdornment from "@mui/material/InputAdornment";
import InputLabel from "@mui/material/InputLabel";
import Tab from "@mui/material/Tab";
import Tabs from "@mui/material/Tabs";
import TextField from "@mui/material/TextField";
import Typography from "@mui/material/Typography";
import DialogTitle from "@mui/material/DialogTitle"; import DialogTitle from "@mui/material/DialogTitle";
import Dialog from "@mui/material/Dialog"; import Dialog from "@mui/material/Dialog";
import {
Box,
Button,
Checkbox,
DialogActions,
DialogContent,
DialogContentText,
FormControl,
FormControlLabel,
FormHelperText,
Input,
InputAdornment,
InputLabel,
Tab,
Tabs,
TextField,
Typography,
} from "@mui/material";
import createStyles from "@mui/styles/createStyles"; import createStyles from "@mui/styles/createStyles";
import TabPanel from "./AuthTabPanel"; import TabPanel from "./AuthTabPanel";
import PersonIcon from "@mui/icons-material/Person"; import PersonIcon from "@mui/icons-material/Person";
@ -28,6 +26,7 @@ import LockIcon from "@mui/icons-material/Lock";
import makeStyles from "@mui/styles/makeStyles"; import makeStyles from "@mui/styles/makeStyles";
import {useAuthDispatch, useAuthState} from "../../../../state/auth/AuthStateContext"; import {useAuthDispatch, useAuthState} from "../../../../state/auth/AuthStateContext";
import {AUTH_METHOD, WithCheckbox} from "../../../../state/auth/reducer"; import {AUTH_METHOD, WithCheckbox} from "../../../../state/auth/reducer";
import {ChangeEvent, ClipboardEvent} from "react";
// TODO: make generic when creating second dialog // TODO: make generic when creating second dialog
export interface DialogProps { export interface DialogProps {
@ -76,7 +75,7 @@ export const AuthDialog: React.FC<DialogProps> = (props) => {
setTabIndex(newValue); setTabIndex(newValue);
}; };
const handleBearerChange = (event: React.ChangeEvent<HTMLInputElement>) => { const handleBearerChange = (event: ChangeEvent<HTMLInputElement>) => {
const newVal = event.target.value; const newVal = event.target.value;
if (newVal.startsWith(BEARER_PREFIX)) { if (newVal.startsWith(BEARER_PREFIX)) {
setBearerValue(newVal); setBearerValue(newVal);
@ -89,7 +88,7 @@ export const AuthDialog: React.FC<DialogProps> = (props) => {
onClose(); onClose();
}; };
const onBearerPaste = (e: React.ClipboardEvent) => { const onBearerPaste = (e: ClipboardEvent) => {
// if you're pasting token word Bearer will be added automagically // if you're pasting token word Bearer will be added automagically
const newVal = e.clipboardData.getData("text/plain"); const newVal = e.clipboardData.getData("text/plain");
if (newVal.startsWith(BEARER_PREFIX)) { if (newVal.startsWith(BEARER_PREFIX)) {

View file

@ -1,4 +1,4 @@
import React from "react"; import React from "preact/compat";
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
interface TabPanelProps { interface TabPanelProps {

View file

@ -1,10 +1,9 @@
import React, {FC} from "react"; import React, {FC} from "preact/compat";
import TableChartIcon from "@mui/icons-material/TableChart"; import TableChartIcon from "@mui/icons-material/TableChart";
import ShowChartIcon from "@mui/icons-material/ShowChart"; import ShowChartIcon from "@mui/icons-material/ShowChart";
import CodeIcon from "@mui/icons-material/Code"; import CodeIcon from "@mui/icons-material/Code";
import ToggleButton from "@mui/material/ToggleButton";
import { ToggleButton, ToggleButtonGroup } from "@mui/material"; import ToggleButtonGroup from "@mui/material/ToggleButtonGroup";
import {useAppDispatch, useAppState} from "../../../state/common/StateContext"; import {useAppDispatch, useAppState} from "../../../state/common/StateContext";
import withStyles from "@mui/styles/withStyles"; import withStyles from "@mui/styles/withStyles";

View file

@ -1,5 +1,8 @@
import React, {FC, useCallback, useMemo} from "react"; import React, {FC, useCallback, useMemo} from "preact/compat";
import {Box, FormControlLabel, TextField} from "@mui/material"; import {ChangeEvent} from "react";
import Box from "@mui/material/Box";
import FormControlLabel from "@mui/material/FormControlLabel";
import TextField from "@mui/material/TextField";
import {useGraphDispatch, useGraphState} from "../../../../state/graph/GraphStateContext"; import {useGraphDispatch, useGraphState} from "../../../../state/graph/GraphStateContext";
import debounce from "lodash.debounce"; import debounce from "lodash.debounce";
import BasicSwitch from "../../../../theme/switch"; import BasicSwitch from "../../../../theme/switch";
@ -12,7 +15,7 @@ const AxesLimitsConfigurator: FC = () => {
const onChangeYaxisLimits = () => { graphDispatch({type: "TOGGLE_ENABLE_YAXIS_LIMITS"}); }; const onChangeYaxisLimits = () => { graphDispatch({type: "TOGGLE_ENABLE_YAXIS_LIMITS"}); };
const onChangeLimit = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>, axis: string, index: number) => { const onChangeLimit = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>, axis: string, index: number) => {
const newLimits = yaxis.limits.range; const newLimits = yaxis.limits.range;
newLimits[axis][index] = +e.target.value; newLimits[axis][index] = +e.target.value;
if (newLimits[axis][0] === newLimits[axis][1] || newLimits[axis][0] > newLimits[axis][1]) return; if (newLimits[axis][0] === newLimits[axis][1] || newLimits[axis][0] > newLimits[axis][1]) return;

View file

@ -1,18 +1,20 @@
import SettingsIcon from "@mui/icons-material/Settings"; import SettingsIcon from "@mui/icons-material/Settings";
import React, {FC, useState, useRef} from "react"; import React, {FC, useState} from "preact/compat";
import AxesLimitsConfigurator from "./AxesLimitsConfigurator"; import AxesLimitsConfigurator from "./AxesLimitsConfigurator";
import {Box, Button, IconButton, Paper, Typography} from "@mui/material"; import Box from "@mui/material/Box";
import Draggable from "react-draggable"; import Button from "@mui/material/Button";
import IconButton from "@mui/material/IconButton";
import Paper from "@mui/material/Paper";
import Popover from "@mui/material/Popover";
import Typography from "@mui/material/Typography";
import makeStyles from "@mui/styles/makeStyles"; import makeStyles from "@mui/styles/makeStyles";
import CloseIcon from "@mui/icons-material/Close"; import CloseIcon from "@mui/icons-material/Close";
const useStyles = makeStyles({ const useStyles = makeStyles({
popover: { popover: {
position: "absolute",
display: "grid", display: "grid",
gridGap: "16px", gridGap: "16px",
padding: "0 0 25px", padding: "0 0 25px",
zIndex: 2,
}, },
popoverHeader: { popoverHeader: {
display: "flex", display: "flex",
@ -22,7 +24,6 @@ const useStyles = makeStyles({
padding: "6px 6px 6px 12px", padding: "6px 6px 6px 12px",
borderRadius: "4px 4px 0 0", borderRadius: "4px 4px 0 0",
color: "#FFF", color: "#FFF",
cursor: "move",
}, },
popoverBody: { popoverBody: {
display: "grid", display: "grid",
@ -32,32 +33,39 @@ const useStyles = makeStyles({
}); });
const GraphSettings: FC = () => { const GraphSettings: FC = () => {
const [open, setOpen] = useState(false); const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
const draggableRef = useRef<HTMLDivElement>(null); const open = Boolean(anchorEl);
const position = { x: 173, y: 0 };
const classes = useStyles(); const classes = useStyles();
return <Box display="flex" px={2}> return <Box display="flex" px={2}>
<Button onClick={() => setOpen((old) => !old)} variant="outlined"> <Button variant="outlined" aria-describedby="settings-popover"
onClick={(e) => setAnchorEl(e.currentTarget)} >
<SettingsIcon sx={{fontSize: 16, marginRight: "4px"}}/> <SettingsIcon sx={{fontSize: 16, marginRight: "4px"}}/>
<span style={{lineHeight: 1, paddingTop: "1px"}}>{open ? "Hide" : "Show"} graph settings</span> <span style={{lineHeight: 1, paddingTop: "1px"}}>{open ? "Hide" : "Show"} graph settings</span>
</Button> </Button>
{open && ( <Popover
<Draggable nodeRef={draggableRef} defaultPosition={position} handle="#handle"> id="settings-popover"
<Paper elevation={3} className={classes.popover} ref={draggableRef}> open={open}
<div id="handle" className={classes.popoverHeader}> anchorEl={anchorEl}
<Typography variant="body1"><b>Graph Settings</b></Typography> onClose={() => setAnchorEl(null)}
<IconButton size="small" onClick={() => setOpen(false)}> anchorOrigin={{
<CloseIcon style={{color: "white"}}/> vertical: "top",
</IconButton> horizontal: anchorEl ? anchorEl.offsetWidth + 15 : 200
</div> }}
<Box className={classes.popoverBody}> >
<AxesLimitsConfigurator/> <Paper elevation={3} className={classes.popover}>
</Box> <div id="handle" className={classes.popoverHeader}>
</Paper> <Typography variant="body1"><b>Graph Settings</b></Typography>
</Draggable> <IconButton size="small" onClick={() => setAnchorEl(null)}>
)} <CloseIcon style={{color: "white"}}/>
</IconButton>
</div>
<Box className={classes.popoverBody}>
<AxesLimitsConfigurator/>
</Box>
</Paper>
</Popover>
</Box>; </Box>;
}; };

View file

@ -1,5 +1,6 @@
import React, {FC} from "react"; import React, {FC} from "preact/compat";
import {Box, FormControlLabel} from "@mui/material"; import Box from "@mui/material/Box";
import FormControlLabel from "@mui/material/FormControlLabel";
import {saveToStorage} from "../../../../utils/storage"; import {saveToStorage} from "../../../../utils/storage";
import {useAppDispatch, useAppState} from "../../../../state/common/StateContext"; import {useAppDispatch, useAppState} from "../../../../state/common/StateContext";
import BasicSwitch from "../../../../theme/switch"; import BasicSwitch from "../../../../theme/switch";

View file

@ -1,7 +1,13 @@
import React, {FC, useEffect, useRef, useState} from "react"; import React, {FC, useEffect, useRef, useState} from "preact/compat";
import { import Accordion from "@mui/material/Accordion";
Accordion, AccordionDetails, AccordionSummary, Box, Grid, IconButton, Typography, Tooltip, Button import AccordionDetails from "@mui/material/AccordionDetails";
} from "@mui/material"; import AccordionSummary from "@mui/material/AccordionSummary";
import Box from "@mui/material/Box";
import IconButton from "@mui/material/IconButton";
import Typography from "@mui/material/Typography";
import Tooltip from "@mui/material/Tooltip";
import Button from "@mui/material/Button";
import Portal from "@mui/material/Portal";
import QueryEditor from "./QueryEditor"; import QueryEditor from "./QueryEditor";
import {TimeSelector} from "../Time/TimeSelector"; import {TimeSelector} from "../Time/TimeSelector";
import {useAppDispatch, useAppState} from "../../../../state/common/StateContext"; import {useAppDispatch, useAppState} from "../../../../state/common/StateContext";
@ -9,7 +15,6 @@ import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import HighlightOffIcon from "@mui/icons-material/HighlightOff"; import HighlightOffIcon from "@mui/icons-material/HighlightOff";
import AddIcon from "@mui/icons-material/Add"; import AddIcon from "@mui/icons-material/Add";
import PlayCircleOutlineIcon from "@mui/icons-material/PlayCircleOutline"; import PlayCircleOutlineIcon from "@mui/icons-material/PlayCircleOutline";
import Portal from "@mui/material/Portal";
import ServerConfigurator from "./ServerConfigurator"; import ServerConfigurator from "./ServerConfigurator";
import AdditionalSettings from "./AdditionalSettings"; import AdditionalSettings from "./AdditionalSettings";
import {ErrorTypes} from "../../../../types"; import {ErrorTypes} from "../../../../types";
@ -21,7 +26,7 @@ export interface QueryConfiguratorProps {
const QueryConfigurator: FC<QueryConfiguratorProps> = ({error, queryOptions}) => { const QueryConfigurator: FC<QueryConfiguratorProps> = ({error, queryOptions}) => {
const {serverUrl, query, queryHistory, queryControls: {autocomplete}} = useAppState(); const {query, queryHistory, queryControls: {autocomplete}} = useAppState();
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const [expanded, setExpanded] = useState(true); const [expanded, setExpanded] = useState(true);
const queryContainer = useRef<HTMLDivElement>(null); const queryContainer = useRef<HTMLDivElement>(null);
@ -109,8 +114,8 @@ const QueryConfigurator: FC<QueryConfiguratorProps> = ({error, queryOptions}) =>
</Box> </Box>
</AccordionSummary> </AccordionSummary>
<AccordionDetails> <AccordionDetails>
<Grid container columnSpacing={2}> <Box display="flex" flexWrap="wrap" gap={2}>
<Grid item xs={6} minWidth={400}> <Box flexGrow="2" minWidth="50%">
<ServerConfigurator error={error}/> <ServerConfigurator error={error}/>
{/* for portal QueryEditor */} {/* for portal QueryEditor */}
<div ref={queryContainer}/> <div ref={queryContainer}/>
@ -120,14 +125,14 @@ const QueryConfigurator: FC<QueryConfiguratorProps> = ({error, queryOptions}) =>
<span style={{lineHeight: 1, paddingTop: "1px"}}>Query</span> <span style={{lineHeight: 1, paddingTop: "1px"}}>Query</span>
</Button> </Button>
</Box>} </Box>}
</Grid> </Box>
<Grid item xs> <Box flexGrow="1">
<TimeSelector setDuration={onSetDuration}/> <TimeSelector setDuration={onSetDuration}/>
</Grid> </Box>
<Grid item xs={12} pt={1}> <Box flexBasis="100%" pt={1}>
<AdditionalSettings/> <AdditionalSettings/>
</Grid> </Box>
</Grid> </Box>
</AccordionDetails> </AccordionDetails>
</Accordion> </Accordion>
</>; </>;

View file

@ -1,6 +1,8 @@
import React, {FC, useEffect, useState} from "react"; import React, {FC, useEffect, useState} from "preact/compat";
import {KeyboardEvent} from "react";
import {ErrorTypes} from "../../../../types"; import {ErrorTypes} from "../../../../types";
import {Autocomplete, TextField} from "@mui/material"; import Autocomplete from "@mui/material/Autocomplete";
import TextField from "@mui/material/TextField";
import {queryToBreakLine} from "../../../../utils/query-string"; import {queryToBreakLine} from "../../../../utils/query-string";
export interface QueryEditorProps { export interface QueryEditorProps {
@ -33,11 +35,11 @@ const QueryEditor: FC<QueryEditorProps> = ({
setValue(queryToBreakLine(query)); setValue(queryToBreakLine(query));
}, [query]); }, [query]);
const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>): void => { const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>): void => {
if (e.ctrlKey || e.metaKey) setDownMetaKeys([...downMetaKeys, e.key]); if (e.ctrlKey || e.metaKey) setDownMetaKeys([...downMetaKeys, e.key]);
}; };
const handleKeyUp = (e: React.KeyboardEvent<HTMLDivElement>): void => { const handleKeyUp = (e: KeyboardEvent<HTMLDivElement>): void => {
const {key, ctrlKey, metaKey} = e; const {key, ctrlKey, metaKey} = e;
if (downMetaKeys.includes(key)) setDownMetaKeys(downMetaKeys.filter(k => k !== key)); if (downMetaKeys.includes(key)) setDownMetaKeys(downMetaKeys.filter(k => k !== key));
const ctrlMetaKey = ctrlKey || metaKey; const ctrlMetaKey = ctrlKey || metaKey;

View file

@ -1,5 +1,8 @@
import React, {FC, useEffect, useState} from "react"; import React, {FC, useEffect, useState} from "preact/compat";
import {Box, TextField, Tooltip, IconButton} from "@mui/material"; import Box from "@mui/material/Box";
import TextField from "@mui/material/TextField";
import Tooltip from "@mui/material/Tooltip";
import IconButton from "@mui/material/IconButton";
import SecurityIcon from "@mui/icons-material/Security"; import SecurityIcon from "@mui/icons-material/Security";
import {useAppDispatch, useAppState} from "../../../../state/common/StateContext"; import {useAppDispatch, useAppState} from "../../../../state/common/StateContext";
import {AuthDialog} from "../Auth/AuthDialog"; import {AuthDialog} from "../Auth/AuthDialog";

View file

@ -1,5 +1,8 @@
import React, {FC, useCallback, useEffect, useState} from "react"; import React, {FC, useCallback, useEffect, useState} from "preact/compat";
import {Box, FormControlLabel, TextField} from "@mui/material"; import {ChangeEvent} from "react";
import Box from "@mui/material/Box";
import FormControlLabel from "@mui/material/FormControlLabel";
import TextField from "@mui/material/TextField";
import BasicSwitch from "../../../../theme/switch"; import BasicSwitch from "../../../../theme/switch";
import {useGraphDispatch, useGraphState} from "../../../../state/graph/GraphStateContext"; import {useGraphDispatch, useGraphState} from "../../../../state/graph/GraphStateContext";
import {useAppState} from "../../../../state/common/StateContext"; import {useAppState} from "../../../../state/common/StateContext";
@ -11,7 +14,7 @@ const StepConfigurator: FC = () => {
const [error, setError] = useState(false); const [error, setError] = useState(false);
const {time: {period: {step}}} = useAppState(); const {time: {period: {step}}} = useAppState();
const onChangeStep = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => { const onChangeStep = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const value = +e.target.value; const value = +e.target.value;
if (value > 0) { if (value > 0) {
graphDispatch({type: "SET_CUSTOM_STEP", payload: value}); graphDispatch({type: "SET_CUSTOM_STEP", payload: value});

View file

@ -1,4 +1,4 @@
import {useEffect, useMemo, useState} from "react"; import {useEffect, useMemo, useState} from "preact/compat";
import {getQueryOptions, getQueryRangeUrl, getQueryUrl} from "../../../../api/query-range"; import {getQueryOptions, getQueryRangeUrl, getQueryUrl} from "../../../../api/query-range";
import {useAppState} from "../../../../state/common/StateContext"; import {useAppState} from "../../../../state/common/StateContext";
import {InstantMetricResult, MetricBase, MetricResult} from "../../../../api/types"; import {InstantMetricResult, MetricBase, MetricResult} from "../../../../api/types";

View file

@ -1,5 +1,8 @@
import React, {FC, useEffect, useState} from "react"; import React, {FC, useEffect, useState} from "preact/compat";
import {Box, FormControlLabel, IconButton, Tooltip} from "@mui/material"; import Box from "@mui/material/Box";
import FormControlLabel from "@mui/material/FormControlLabel";
import IconButton from "@mui/material/IconButton";
import Tooltip from "@mui/material/Tooltip";
import EqualizerIcon from "@mui/icons-material/Equalizer"; import EqualizerIcon from "@mui/icons-material/Equalizer";
import {useAppDispatch, useAppState} from "../../../../state/common/StateContext"; import {useAppDispatch, useAppState} from "../../../../state/common/StateContext";
import CircularProgressWithLabel from "../../../common/CircularProgressWithLabel"; import CircularProgressWithLabel from "../../../common/CircularProgressWithLabel";

View file

@ -1,5 +1,11 @@
import React, {FC} from "react"; import React, {FC} from "preact/compat";
import {Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow} from "@mui/material"; import Paper from "@mui/material/Paper";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import {supportedDurations} from "../../../../utils/time"; import {supportedDurations} from "../../../../utils/time";
export const TimeDurationPopover: FC = () => { export const TimeDurationPopover: FC = () => {

View file

@ -1,5 +1,9 @@
import React, {FC, useEffect, useState} from "react"; import React, {FC, useEffect, useState} from "preact/compat";
import {Box, Popover, TextField, Typography} from "@mui/material"; import {ChangeEvent, MouseEvent, KeyboardEvent} from "react";
import Box from "@mui/material/Box";
import Popover from "@mui/material/Popover";
import TextField from "@mui/material/TextField";
import Typography from "@mui/material/Typography";
import {checkDurationLimit} from "../../../../utils/time"; import {checkDurationLimit} from "../../../../utils/time";
import {TimeDurationPopover} from "./TimeDurationPopover"; import {TimeDurationPopover} from "./TimeDurationPopover";
import {InlineBtn} from "../../../common/InlineBtn"; import {InlineBtn} from "../../../common/InlineBtn";
@ -17,11 +21,11 @@ const TimeDurationSelector: FC<TimeDurationSelector> = ({setDuration}) => {
const [durationStringFocused, setFocused] = useState(false); const [durationStringFocused, setFocused] = useState(false);
const open = Boolean(anchorEl); const open = Boolean(anchorEl);
const handleDurationChange = (event: React.ChangeEvent<HTMLInputElement>) => { const handleDurationChange = (event: ChangeEvent<HTMLInputElement>) => {
setDurationString(event.target.value); setDurationString(event.target.value);
}; };
const handlePopoverOpen = (event: React.MouseEvent<Element, MouseEvent>) => { const handlePopoverOpen = (event: MouseEvent<HTMLSpanElement>) => {
setAnchorEl(event.currentTarget); setAnchorEl(event.currentTarget);
}; };
@ -29,7 +33,7 @@ const TimeDurationSelector: FC<TimeDurationSelector> = ({setDuration}) => {
setAnchorEl(null); setAnchorEl(null);
}; };
const onKeyUp = (event: React.KeyboardEvent<HTMLInputElement>) => { const onKeyUp = (event: KeyboardEvent<HTMLInputElement>) => {
if (event.key !== "Enter") return; if (event.key !== "Enter") return;
const target = event.target as HTMLInputElement; const target = event.target as HTMLInputElement;
target.blur(); target.blur();

View file

@ -1,5 +1,7 @@
import React, {FC, useEffect, useState} from "react"; import React, {FC, useEffect, useState} from "preact/compat";
import {Box, TextField, Typography} from "@mui/material"; import Box from "@mui/material/Box";
import TextField from "@mui/material/TextField";
import Typography from "@mui/material/Typography";
import DateTimePicker from "@mui/lab/DateTimePicker"; import DateTimePicker from "@mui/lab/DateTimePicker";
import {useAppDispatch, useAppState} from "../../../../state/common/StateContext"; import {useAppDispatch, useAppState} from "../../../../state/common/StateContext";
import {dateFromSeconds, formatDateForNativeInput} from "../../../../utils/time"; import {dateFromSeconds, formatDateForNativeInput} from "../../../../utils/time";

View file

@ -1,5 +1,8 @@
import React, {FC} from "react"; import React, {FC} from "preact/compat";
import {Alert, Box, CircularProgress, Fade} from "@mui/material"; import Alert from "@mui/material/Alert";
import Box from "@mui/material/Box";
import CircularProgress from "@mui/material/CircularProgress";
import Fade from "@mui/material/Fade";
import GraphView from "./Views/GraphView"; import GraphView from "./Views/GraphView";
import TableView from "./Views/TableView"; import TableView from "./Views/TableView";
import {useAppState} from "../../state/common/StateContext"; import {useAppState} from "../../state/common/StateContext";

View file

@ -1,5 +1,7 @@
import React, {FC} from "react"; import React, {FC} from "preact/compat";
import {Box, IconButton, Tooltip} from "@mui/material"; import Box from "@mui/material/Box";
import IconButton from "@mui/material/IconButton";
import Tooltip from "@mui/material/Tooltip";
import FileCopyIcon from "@mui/icons-material/FileCopy"; import FileCopyIcon from "@mui/icons-material/FileCopy";
import {useSnack} from "../../contexts/Snackbar"; import {useSnack} from "../../contexts/Snackbar";

View file

@ -1,5 +1,7 @@
import React, {FC} from "react"; import React, {FC} from "preact/compat";
import {Box, Button, Grid, Typography} from "@mui/material"; import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import {useSnack} from "../../contexts/Snackbar"; import {useSnack} from "../../contexts/Snackbar";
interface UrlLineProps { interface UrlLineProps {
@ -10,7 +12,7 @@ export const UrlLine: FC<UrlLineProps> = ({url}) => {
const {showInfoMessage} = useSnack(); const {showInfoMessage} = useSnack();
return <Grid item style={{backgroundColor: "#eee", width: "100%"}}> return <Box style={{backgroundColor: "#eee", width: "100%"}}>
<Box flexDirection="row" display="flex" justifyContent="space-between" alignItems="center"> <Box flexDirection="row" display="flex" justifyContent="space-between" alignItems="center">
<Box pl={2} py={1} display="flex" style={{ <Box pl={2} py={1} display="flex" style={{
flex: 1, flex: 1,
@ -38,5 +40,5 @@ export const UrlLine: FC<UrlLineProps> = ({url}) => {
}}>Copy Query Url</Button> }}>Copy Query Url</Button>
</Box> </Box>
</Box> </Box>
</Grid>; </Box>;
}; };

View file

@ -1,4 +1,4 @@
import React, {FC, useEffect, useMemo, useState} from "react"; import React, {FC, useEffect, useMemo, useState} from "preact/compat";
import {MetricResult} from "../../../api/types"; import {MetricResult} from "../../../api/types";
import LineChart from "../../LineChart/LineChart"; import LineChart from "../../LineChart/LineChart";
import {AlignedData as uPlotData, Series as uPlotSeries} from "uplot"; import {AlignedData as uPlotData, Series as uPlotSeries} from "uplot";

View file

@ -1,6 +1,7 @@
import React, {FC, useMemo} from "react"; import React, {FC, useMemo} from "preact/compat";
import {InstantMetricResult} from "../../../api/types"; import {InstantMetricResult} from "../../../api/types";
import {Box, Button} from "@mui/material"; import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import {useSnack} from "../../../contexts/Snackbar"; import {useSnack} from "../../../contexts/Snackbar";
export interface JsonViewProps { export interface JsonViewProps {

View file

@ -1,7 +1,13 @@
import React, {FC, useMemo} from "react"; import React, {FC, useMemo} from "preact/compat";
import {InstantMetricResult} from "../../../api/types"; import {InstantMetricResult} from "../../../api/types";
import {InstantDataSeries} from "../../../types"; import {InstantDataSeries} from "../../../types";
import {Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow} from "@mui/material"; import Paper from "@mui/material/Paper";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import makeStyles from "@mui/styles/makeStyles"; import makeStyles from "@mui/styles/makeStyles";
import {useSortedCategories} from "../../../hooks/useSortedCategories"; import {useSortedCategories} from "../../../hooks/useSortedCategories";

View file

@ -1,4 +1,4 @@
import React, {FC, useMemo} from "react"; import React, {FC, useMemo} from "preact/compat";
import {hexToRGB} from "../../utils/color"; import {hexToRGB} from "../../utils/color";
import {useAppState} from "../../state/common/StateContext"; import {useAppState} from "../../state/common/StateContext";
import {LegendItem} from "../../utils/uplot/types"; import {LegendItem} from "../../utils/uplot/types";

View file

@ -1,4 +1,4 @@
import React, {FC, useCallback, useEffect, useRef, useState} from "react"; import React, {FC, useCallback, useEffect, useRef, useState} from "preact/compat";
import {useAppDispatch, useAppState} from "../../state/common/StateContext"; import {useAppDispatch, useAppState} from "../../state/common/StateContext";
import uPlot, {AlignedData as uPlotData, Options as uPlotOptions, Series as uPlotSeries, Range, Scales, Scale} from "uplot"; import uPlot, {AlignedData as uPlotData, Options as uPlotOptions, Series as uPlotSeries, Range, Scales, Scale} from "uplot";
import {useGraphState} from "../../state/graph/GraphStateContext"; import {useGraphState} from "../../state/graph/GraphStateContext";

View file

@ -1,7 +1,7 @@
import Box from "@mui/material/Box";
import CircularProgress, {CircularProgressProps} from "@mui/material/CircularProgress"; import CircularProgress, {CircularProgressProps} from "@mui/material/CircularProgress";
import {Box} from "@mui/material";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import React, {FC} from "react"; import React, {FC} from "preact/compat";
const CircularProgressWithLabel: FC<CircularProgressProps & { label: number }> = (props) => { const CircularProgressWithLabel: FC<CircularProgressProps & { label: number }> = (props) => {
return ( return (

View file

@ -1,6 +1,6 @@
import makeStyles from "@mui/styles/makeStyles"; import makeStyles from "@mui/styles/makeStyles";
import React from "react"; import React from "preact/compat";
import {Link} from "@mui/material"; import Link from "@mui/material/Link";
const useStyles = makeStyles({ const useStyles = makeStyles({
inlineBtn: { inlineBtn: {

View file

@ -1,8 +1,9 @@
import React, {FC} from "react"; import React, {FC} from "preact/compat";
import {SvgIcon} from "@mui/material"; import {CSSProperties} from "@mui/styles";
import SvgIcon from "@mui/material/SvgIcon";
interface LogoProps { interface LogoProps {
style?: React.CSSProperties style?: CSSProperties
} }
const Logo: FC<LogoProps> = ({style}) => ( const Logo: FC<LogoProps> = ({style}) => (

View file

@ -1,5 +1,6 @@
import React, {createContext, FC, useContext, useEffect, useState} from "react"; import React, {createContext, FC, useContext, useEffect, useState} from "preact/compat";
import {Alert, Snackbar} from "@mui/material"; import Alert from "@mui/material/Alert";
import Snackbar from "@mui/material/Snackbar";
export interface SnackModel { export interface SnackModel {
message?: string; message?: string;

View file

@ -1,4 +1,4 @@
import { useState, useEffect } from "react"; import { useState, useEffect } from "preact/compat";
const useResize = (node: HTMLElement | null): {width: number, height: number} => { const useResize = (node: HTMLElement | null): {width: number, height: number} => {
const [windowSize, setWindowSize] = useState({ const [windowSize, setWindowSize] = useState({

View file

@ -1,4 +1,4 @@
import {useMemo} from "react"; import {useMemo} from "preact/compat";
import {MetricBase} from "../api/types"; import {MetricBase} from "../api/types";
export type MetricCategory = { export type MetricCategory = {

View file

@ -1,14 +1,11 @@
import React from "react"; import React, { render } from "preact/compat";
import ReactDOM from "react-dom";
import "./index.css"; import "./index.css";
import App from "./App"; import App from "./App";
import reportWebVitals from "./reportWebVitals"; import reportWebVitals from "./reportWebVitals";
ReactDOM.render(
<React.StrictMode> const root = document.getElementById("root");
<App /> if (root) render(<App />, root);
</React.StrictMode>,
document.getElementById("root")
);
// If you want to start measuring performance in your app, pass a function // If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log)) // to log results (for example: reportWebVitals(console.log))

View file

@ -1,5 +1,6 @@
import React, {createContext, Dispatch, FC, useContext, useMemo, useReducer} from "react"; import React, {createContext, FC, useContext, useMemo, useReducer} from "preact/compat";
import {AuthAction, AuthState, initialPrepopulatedState, reducer} from "./reducer"; import {AuthAction, AuthState, initialPrepopulatedState, reducer} from "./reducer";
import {Dispatch} from "react";
type AuthStateContextType = { state: AuthState, dispatch: Dispatch<AuthAction> }; type AuthStateContextType = { state: AuthState, dispatch: Dispatch<AuthAction> };

View file

@ -1,6 +1,7 @@
import React, {createContext, Dispatch, FC, useContext, useEffect, useMemo, useReducer} from "react"; import React, {createContext, FC, useContext, useEffect, useMemo, useReducer} from "preact/compat";
import {Action, AppState, initialState, reducer} from "./reducer"; import {Action, AppState, initialState, reducer} from "./reducer";
import {getQueryStringValue, setQueryStringValue} from "../../utils/query-string"; import {getQueryStringValue, setQueryStringValue} from "../../utils/query-string";
import {Dispatch} from "react";
type StateContextType = { state: AppState, dispatch: Dispatch<Action> }; type StateContextType = { state: AppState, dispatch: Dispatch<Action> };

View file

@ -1,5 +1,6 @@
import React, {createContext, Dispatch, FC, useContext, useMemo, useReducer} from "react"; import React, {createContext, FC, useContext, useMemo, useReducer} from "preact/compat";
import {GraphAction, GraphState, initialGraphState, reducer} from "./reducer"; import {GraphAction, GraphState, initialGraphState, reducer} from "./reducer";
import {Dispatch} from "react";
type GraphStateContextType = { state: GraphState, dispatch: Dispatch<GraphAction> }; type GraphStateContextType = { state: GraphState, dispatch: Dispatch<GraphAction> };

View file

@ -1,5 +1,5 @@
import {styled} from "@mui/material/styles";
import Switch from "@mui/material/Switch"; import Switch from "@mui/material/Switch";
import {styled} from "@mui/styles";
const BasicSwitch = styled(Switch)(() => ({ const BasicSwitch = styled(Switch)(() => ({
padding: 10, padding: 10,