ui: Migrate from create-react-app to vite (#459)

This commit is contained in:
Bernd Storath
2024-07-16 15:10:19 +02:00
committed by GitHub
parent 3777de706d
commit 4f0d2126d8
163 changed files with 2007 additions and 10190 deletions

View File

@ -1,4 +1,5 @@
import React, { PropsWithChildren, useState, useEffect } from "react";
import type { PropsWithChildren } from "react";
import { useState, useEffect } from "react";
import SessionStore from "../stores/SessionStore";

View File

@ -36,7 +36,7 @@ function AesKeyInput(props: IProps) {
};
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
let v = e.target.value;
const v = e.target.value;
const match = v.match(/[A-Fa-f0-9]/g);
let value = "";
@ -68,11 +68,11 @@ function AesKeyInput(props: IProps) {
};
const generateRandom = () => {
let cryptoObj = window.crypto || window.Crypto;
let b = new Uint8Array(16);
const cryptoObj = window.crypto || window.Crypto;
const b = new Uint8Array(16);
cryptoObj.getRandomValues(b);
let key = Buffer.from(b).toString("hex");
const key = Buffer.from(b).toString("hex");
setValue(key);
updateField(key);
};

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react";
import { useState, useEffect } from "react";
import { Select } from "antd";
@ -55,7 +55,7 @@ function AutoComplete({ placeholder, className, value, getOption, getOptions, on
});
};
const onSelectFn = (value: string, option: any) => {
const onSelectFn = (value: string, option: Option) => {
setOption({ label: option.label, value: option.value });
if (onSelect !== undefined) {

View File

@ -1,6 +1,7 @@
import { Form } from "antd";
import Autocomplete, { OptionCallbackFunc, OptionsCallbackFunc } from "./Autocomplete";
import type { OptionCallbackFunc, OptionsCallbackFunc } from "./Autocomplete";
import Autocomplete from "./Autocomplete";
interface IProps {
label: string;

View File

@ -1,5 +1,6 @@
import React, { useState, useEffect } from "react";
import { useState, useEffect } from "react";
import { Controlled as CodeMirror } from "react-codemirror2";
import type { Editor, EditorChange } from "codemirror";
import { Form } from "antd";
@ -23,7 +24,7 @@ function CodeEditor(props: IProps) {
setReloadKey(k => k + 1);
}, [form, props]);
const handleChange = (editor: any, data: any, newCode: string) => {
const handleChange = (editor: Editor, data: EditorChange, newCode: string) => {
setValue(newCode);
form.setFieldsValue({
[props.name]: newCode,

View File

@ -1,18 +1,19 @@
import React, { useState, useEffect, useCallback } from "react";
import { Table } from "antd";
import { ColumnsType } from "antd/es/table";
import type { ColumnsType } from "antd/es/table";
import SessionStore from "../stores/SessionStore";
export type GetPageCallbackFunc = (totalCount: number, rows: object[]) => void;
interface IProps {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
columns: ColumnsType<any>;
getPage: (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => void;
onRowsSelectChange?: (ids: string[]) => void;
rowKey: string;
refreshKey?: any;
refreshKey?: unknown;
noPagination?: boolean;
}

View File

@ -1,4 +1,5 @@
import { useState, PropsWithChildren } from "react";
import type { PropsWithChildren } from "react";
import { useState } from "react";
import { Popover, Button, Typography, Space, Input } from "antd";
interface IProps {

View File

@ -3,7 +3,8 @@ import React, { useState, useEffect } from "react";
import { notification, Input, Select, Button, Space, Form, Dropdown, Menu } from "antd";
import { ReloadOutlined, CopyOutlined } from "@ant-design/icons";
import { GetRandomDevAddrRequest, GetRandomDevAddrResponse } from "@chirpstack/chirpstack-api-grpc-web/api/device_pb";
import type { GetRandomDevAddrResponse } from "@chirpstack/chirpstack-api-grpc-web/api/device_pb";
import { GetRandomDevAddrRequest } from "@chirpstack/chirpstack-api-grpc-web/api/device_pb";
import DeviceStore from "../stores/DeviceStore";
@ -39,7 +40,7 @@ function DevAddrInput(props: IProps) {
};
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
let v = e.target.value;
const v = e.target.value;
const match = v.match(/[A-Fa-f0-9]/g);
let value = "";
@ -71,7 +72,7 @@ function DevAddrInput(props: IProps) {
};
const generateRandom = () => {
let req = new GetRandomDevAddrRequest();
const req = new GetRandomDevAddrRequest();
req.setDevEui(props.devEui);
DeviceStore.getRandomDevAddr(req, (resp: GetRandomDevAddrResponse) => {

View File

@ -36,7 +36,7 @@ function EuiInput(props: IProps) {
};
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
let v = e.target.value;
const v = e.target.value;
const match = v.match(/[A-Fa-f0-9]/g);
let value = "";
@ -68,11 +68,11 @@ function EuiInput(props: IProps) {
};
const generateRandom = () => {
let cryptoObj = window.crypto || window.Crypto;
let b = new Uint8Array(8);
const cryptoObj = window.crypto || window.Crypto;
const b = new Uint8Array(8);
cryptoObj.getRandomValues(b);
let key = Buffer.from(b).toString("hex");
const key = Buffer.from(b).toString("hex");
setValue(key);
updateField(key);
};

View File

@ -1,15 +1,12 @@
import React, { useState, useEffect } from "react";
import { useState, useEffect } from "react";
import { Link, useNavigate } from "react-router-dom";
import { Button, Menu, Dropdown, Input, AutoComplete } from "antd";
import { UserOutlined, DownOutlined, QuestionOutlined } from "@ant-design/icons";
import { User } from "@chirpstack/chirpstack-api-grpc-web/api/user_pb";
import {
SettingsResponse,
GlobalSearchRequest,
GlobalSearchResponse,
} from "@chirpstack/chirpstack-api-grpc-web/api/internal_pb";
import type { User } from "@chirpstack/chirpstack-api-grpc-web/api/user_pb";
import type { SettingsResponse, GlobalSearchResponse } from "@chirpstack/chirpstack-api-grpc-web/api/internal_pb";
import { GlobalSearchRequest } from "@chirpstack/chirpstack-api-grpc-web/api/internal_pb";
import InternalStore from "../stores/InternalStore";
import SessionStore from "../stores/SessionStore";
@ -38,7 +35,7 @@ function Header({ user }: { user: User }) {
return;
}
let req = new GlobalSearchRequest();
const req = new GlobalSearchRequest();
req.setLimit(20);
req.setSearch(search);
@ -52,8 +49,8 @@ function Header({ user }: { user: User }) {
return;
}
let oidc = settings.getOpenidConnect()!;
let oAuth2 = settings.getOauth2()!;
const oidc = settings.getOpenidConnect()!;
const oAuth2 = settings.getOauth2()!;
if (oidc.getEnabled() && oidc.getLogoutUrl() !== "") {
SessionStore.logout(false, () => {
@ -74,8 +71,8 @@ function Header({ user }: { user: User }) {
return null;
}
let oidcEnabled = settings!.getOpenidConnect()!.getEnabled();
let oAuth2Enabled = settings!.getOauth2()!.getEnabled();
const oidcEnabled = settings!.getOpenidConnect()!.getEnabled();
const oAuth2Enabled = settings!.getOauth2()!.getEnabled();
const menu = (
<Menu>
@ -88,9 +85,9 @@ function Header({ user }: { user: User }) {
</Menu>
);
let options: {
label: any;
options: any[];
const options: {
label: JSX.Element;
options: ReturnType<typeof renderItem>[];
}[] = [
{
label: renderTitle("Tenants"),

View File

@ -1,4 +1,4 @@
import React, { useState } from "react";
import { useState } from "react";
import moment from "moment";
import { JSONTree as JSONTreeOriginal } from "react-json-tree";
@ -7,7 +7,7 @@ import fileDownload from "js-file-download";
import { Tag, Drawer, Button, Table, Spin, Space } from "antd";
import { ZoomInOutlined } from "@ant-design/icons";
import { LogItem } from "@chirpstack/chirpstack-api-grpc-web/api/internal_pb";
import type { LogItem } from "@chirpstack/chirpstack-api-grpc-web/api/internal_pb";
interface IProps {
logs: LogItem[];
@ -15,17 +15,17 @@ interface IProps {
function LogTable(props: IProps) {
const [drawerOpen, setDrawerOpen] = useState<boolean>(false);
const [body, setBody] = useState<any>(null);
const [drawerTitle, setDrawerTitle] = useState<any>(null);
const [body, setBody] = useState<string | null>(null);
const [drawerTitle, setDrawerTitle] = useState<string | null>(null);
const onDrawerClose = () => {
setDrawerOpen(false);
};
const onDrawerOpen = (time: any, body: any) => {
let ts = new Date(0);
ts.setUTCSeconds(time.seconds);
let drawerTitle = moment(ts).format("YYYY-MM-DD HH:mm:ss");
const onDrawerOpen = (time: { seconds: number } | undefined, body: string) => {
const ts = new Date(0);
ts.setUTCSeconds(time!.seconds);
const drawerTitle = moment(ts).format("YYYY-MM-DD HH:mm:ss");
return () => {
setBody(body);
@ -35,16 +35,16 @@ function LogTable(props: IProps) {
};
const downloadSingleFrame = () => {
fileDownload(JSON.stringify(JSON.parse(body), null, 4), "single-log.json", "application/json");
fileDownload(JSON.stringify(JSON.parse(body!), null, 4), "single-log.json", "application/json");
};
const downloadFrames = () => {
let items = props.logs.map((l, i) => JSON.parse(l.getBody()));
const items = props.logs.map((l, i) => JSON.parse(l.getBody()));
fileDownload(JSON.stringify(items, null, 4), "log.json");
};
let items = props.logs.map((l, i) => l.toObject());
let bodyJson = JSON.parse(body);
const items = props.logs.map((l, i) => l.toObject());
const bodyJson = JSON.parse(body!);
const theme = {
scheme: "google",
@ -104,7 +104,7 @@ function LogTable(props: IProps) {
key: "time",
width: 200,
render: (text, obj) => {
let ts = new Date(0);
const ts = new Date(0);
ts.setUTCSeconds(obj.time!.seconds);
return moment(ts).format("YYYY-MM-DD HH:mm:ss");
},

View File

@ -1,8 +1,11 @@
import React, { useEffect, PropsWithChildren, useState } from "react";
import type { PropsWithChildren } from "react";
import { useEffect, useState } from "react";
import L, { LatLngTuple, FitBoundsOptions } from "leaflet";
import type { LatLngTuple, FitBoundsOptions } from "leaflet";
import L from "leaflet";
import "leaflet.awesome-markers";
import { MarkerProps as LMarkerProps, useMap } from "react-leaflet";
import type { MarkerProps as LMarkerProps } from "react-leaflet";
import { useMap } from "react-leaflet";
import { MapContainer, Marker as LMarker, TileLayer } from "react-leaflet";
import InternalStore from "../stores/InternalStore";

View File

@ -1,7 +1,8 @@
import React, { useState, useEffect, useCallback } from "react";
import { useState, useEffect, useCallback } from "react";
import { Link, useLocation, useNavigate } from "react-router-dom";
import { Menu, MenuProps, Typography } from "antd";
import type { MenuProps } from "antd";
import { Menu, Typography } from "antd";
import {
CloudOutlined,
HomeOutlined,
@ -15,15 +16,13 @@ import {
RadarChartOutlined,
} from "@ant-design/icons";
import {
GetTenantResponse,
ListTenantsRequest,
ListTenantsResponse,
} from "@chirpstack/chirpstack-api-grpc-web/api/tenant_pb";
import type { GetTenantResponse, ListTenantsResponse } from "@chirpstack/chirpstack-api-grpc-web/api/tenant_pb";
import { ListTenantsRequest } from "@chirpstack/chirpstack-api-grpc-web/api/tenant_pb";
import { GetVersionResponse } from "@chirpstack/chirpstack-api-grpc-web/api/internal_pb";
import type { GetVersionResponse } from "@chirpstack/chirpstack-api-grpc-web/api/internal_pb";
import Autocomplete, { OptionCallbackFunc, OptionsCallbackFunc } from "../components/Autocomplete";
import type { OptionCallbackFunc, OptionsCallbackFunc } from "../components/Autocomplete";
import Autocomplete from "../components/Autocomplete";
import Admin from "../components/Admin";
import TenantStore from "../stores/TenantStore";
import SessionStore from "../stores/SessionStore";
@ -42,7 +41,7 @@ function SideMenu() {
};
const getTenantOptions = (search: string, fn: OptionsCallbackFunc) => {
let req = new ListTenantsRequest();
const req = new ListTenantsRequest();
req.setSearch(search);
req.setLimit(10);
@ -162,7 +161,7 @@ function SideMenu() {
parseLocation();
}, [location, parseLocation]);
let items: MenuProps["items"] = [];
const items: MenuProps["items"] = [];
if (SessionStore.isAdmin()) {
items.push({

View File

@ -1,11 +1,12 @@
import { Card } from "antd";
import { TimeUnit } from "chart.js";
import type { TimeUnit } from "chart.js";
import { Bar } from "react-chartjs-2";
import moment from "moment";
import palette from "google-palette";
import { Metric, Aggregation } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
import type { Metric } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
import { Aggregation } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
interface IProps {
metric: Metric;
@ -20,7 +21,7 @@ function MetricBar(props: IProps) {
unit = "month";
}
const animation: false = false;
const animation = false as const;
const options = {
animation: animation,
@ -43,7 +44,7 @@ function MetricBar(props: IProps) {
},
};
let data: {
const data: {
labels: number[];
datasets: {
label: string;

View File

@ -1,11 +1,12 @@
import { Card } from "antd";
import { TimeUnit } from "chart.js";
import type { TimeUnit } from "chart.js";
import { Line } from "react-chartjs-2";
import moment from "moment";
import palette from "google-palette";
import { Metric, Aggregation, MetricKind } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
import type { Metric } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
import { Aggregation, MetricKind } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
interface IProps {
metric: Metric;
@ -27,7 +28,7 @@ function MetricChart(props: IProps) {
tooltipFormat = "LT";
}
const animation: false = false;
const animation = false as const;
const options = {
animation: animation,
@ -52,7 +53,7 @@ function MetricChart(props: IProps) {
};
let prevValue = 0;
let data = {
const data = {
labels: props.metric.getTimestampsList().map(v => moment(v.toDate()).valueOf()),
datasets: props.metric
.getDatasetsList()
@ -72,7 +73,7 @@ function MetricChart(props: IProps) {
return null;
} else {
if (props.metric.getKind() === MetricKind.COUNTER) {
let val = v - prevValue;
const val = v - prevValue;
prevValue = v;
if (val < 0) {
return 0;

View File

@ -1,11 +1,14 @@
// TODO: find a way to type `ctx`
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Card } from "antd";
import { color } from "chart.js/helpers";
import { TimeUnit } from "chart.js";
import type { TimeUnit } from "chart.js";
import { Chart } from "react-chartjs-2";
import moment from "moment";
import { Metric, Aggregation } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
import type { Metric } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
import { Aggregation } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
interface IProps {
metric: Metric;
@ -22,9 +25,9 @@ function MetricHeatmap(props: IProps) {
unit = "month";
}
const animation: false = false;
const animation = false as const;
let options = {
const options = {
animation: animation,
maintainAspectRatio: false,
scales: {
@ -63,13 +66,13 @@ function MetricHeatmap(props: IProps) {
},
};
let dataData: {
const dataData: {
x: number;
y: string;
v: number;
}[] = [];
let data = {
const data = {
labels: props.metric.getDatasetsList().map(v => v.getLabel()),
datasets: [
{
@ -93,8 +96,8 @@ function MetricHeatmap(props: IProps) {
const step = value - ctx.dataset.minValue;
const factor = (1 / steps) * step;
let result: [number, number, number] = ctx.dataset.fromColor.slice();
for (var i = 0; i < 3; i++) {
const result: [number, number, number] = ctx.dataset.fromColor.slice();
for (let i = 0; i < 3; i++) {
result[i] = Math.round(result[i] + factor * (ctx.dataset.toColor[i] - ctx.dataset.fromColor[i]));
}
@ -117,8 +120,8 @@ function MetricHeatmap(props: IProps) {
const dsList = props.metric.getDatasetsList();
for (let i = 0; i < tsList.length; i++) {
for (let ds of dsList) {
let v = ds.getDataList()[i];
for (const ds of dsList) {
const v = ds.getDataList()[i];
if (v === 0) {
continue;
}

View File

@ -1,4 +1,3 @@
import React, { useState, useEffect } from "react";
import { notification, Input, Select, Button, Space, Form, Dropdown, Menu } from "antd";
@ -37,7 +36,7 @@ function RelayIdInput(props: IProps) {
};
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
let v = e.target.value;
const v = e.target.value;
const match = v.match(/[A-Fa-f0-9]/g);
let value = "";
@ -69,11 +68,11 @@ function RelayIdInput(props: IProps) {
};
const generateRandom = () => {
let cryptoObj = window.crypto || window.Crypto;
let b = new Uint8Array(4);
const cryptoObj = window.crypto || window.Crypto;
const b = new Uint8Array(4);
cryptoObj.getRandomValues(b);
let key = Buffer.from(b).toString("hex");
const key = Buffer.from(b).toString("hex");
setValue(key);
updateField(key);
};