mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
replace React bunder based on webpack with Vite #952
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -29,6 +29,8 @@ node_modules
|
|||||||
test.sh
|
test.sh
|
||||||
scripts/__pycache__
|
scripts/__pycache__
|
||||||
.temp
|
.temp
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
|
||||||
# i18n generated files
|
# i18n generated files
|
||||||
interface/src/i18n/i18n-react.tsx
|
interface/src/i18n/i18n-react.tsx
|
||||||
@@ -47,4 +49,6 @@ dump_entities.csv
|
|||||||
dump_entities.xls*
|
dump_entities.xls*
|
||||||
scripts/run.sh
|
scripts/run.sh
|
||||||
test_results.txt
|
test_results.txt
|
||||||
interface/build-analysis-*.html
|
|
||||||
|
# bundle analyzer
|
||||||
|
stats.html
|
||||||
|
|||||||
3
.prettierignore
Normal file
3
.prettierignore
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
node_modules/
|
||||||
|
build/
|
||||||
|
.prettierrc
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"singleQuote": true,
|
|
||||||
"semi": true,
|
|
||||||
"trailingComma": "none",
|
"trailingComma": "none",
|
||||||
"printWidth": 120
|
"tabWidth": 2,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"printWidth": 120,
|
||||||
|
"bracketSpacing": true
|
||||||
}
|
}
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
# 
|
|
||||||
|
|
||||||
# Firmware Installation
|
|
||||||
|
|
||||||
Follow the instructions in the [documentation](https://emsesp.github.io/docs) on how to install the firmware binaries in the Assets below.
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
# 
|
|
||||||
|
|
||||||
This is a snapshot of the current "beta" development code and firmware binaries for the ESP32. It has all the latest features and fixes but please be aware that this is still experimental firmware used for testing and thus may contain the odd bug. Use at your own risk and remember to report an issue if you find something unusual.
|
|
||||||
|
|
||||||
# Firmware Installation
|
|
||||||
|
|
||||||
Follow the instructions in the [documentation](https://emsesp.github.io/docs) on how to install the firmware binaries in the Assets below.
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# This enables lint extensions
|
|
||||||
EXTEND_ESLINT=true
|
|
||||||
|
|
||||||
# This is the name of your project. It appears on the sign-in page and in the menu bar.
|
|
||||||
REACT_APP_PROJECT_NAME=EMS-ESP
|
|
||||||
|
|
||||||
# This is the url path your project will be exposed under.
|
|
||||||
REACT_APP_PROJECT_PATH=ems-esp
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
GENERATE_SOURCEMAP=false
|
|
||||||
|
|
||||||
REACT_APP_HOSTED=true
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
GENERATE_SOURCEMAP=false
|
|
||||||
5
interface/.eslintignore
Normal file
5
interface/.eslintignore
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
node_modules/
|
||||||
|
build/
|
||||||
|
.prettierrc
|
||||||
|
.eslintrc.js
|
||||||
|
env.d.ts
|
||||||
48
interface/.eslintrc.js
Normal file
48
interface/.eslintrc.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: ['react-refresh'],
|
||||||
|
extends: [
|
||||||
|
// By extending from a plugin config, we can get recommended rules without having to add them manually.
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:react/recommended',
|
||||||
|
'plugin:import/recommended',
|
||||||
|
'plugin:import/typescript',
|
||||||
|
'plugin:jsx-a11y/recommended',
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
// 'plugin:react-refresh/recommended',
|
||||||
|
// This disables the formatting rules in ESLint that Prettier is going to be responsible for handling.
|
||||||
|
// Make sure it's always the last config, so it gets the chance to override other configs.
|
||||||
|
'eslint-config-prettier'
|
||||||
|
],
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
// Tells eslint-plugin-react to automatically detect the version of React to use.
|
||||||
|
version: 'detect'
|
||||||
|
},
|
||||||
|
// Tells eslint how to resolve imports
|
||||||
|
'import/resolver': {
|
||||||
|
node: {
|
||||||
|
paths: ['src'],
|
||||||
|
extensions: ['.js', '.jsx', '.ts', '.tsx']
|
||||||
|
},
|
||||||
|
typescript: {
|
||||||
|
alwaysTryTypes: true // always try to resolve types under `<root>@types` directory even it doesn't contain any source code, like `@types/unist`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parserOptions: {
|
||||||
|
project: ['tsconfig.json'],
|
||||||
|
createDefaultProgram: true
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
// Add your own rules here to override ones from the extended configs.
|
||||||
|
'react/react-in-jsx-scope': 'off',
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
'jsx-a11y/no-autofocus': 'off',
|
||||||
|
'react-refresh/only-export-components': 'off',
|
||||||
|
'no-console': 'warn',
|
||||||
|
'react/prop-types': 'off',
|
||||||
|
'react/self-closing-comp': 'warn',
|
||||||
|
'@typescript-eslint/consistent-type-definitions': ['off', 'type'],
|
||||||
|
'@typescript-eslint/explicit-function-return-type': 'off'
|
||||||
|
}
|
||||||
|
};
|
||||||
31
interface/.vscode
Normal file
31
interface/.vscode
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"emmet.excludeLanguages": [],
|
||||||
|
"emmet.includeLanguages": {
|
||||||
|
"markdown": "html",
|
||||||
|
"javascript": "javascriptreact",
|
||||||
|
"typescript": "typescriptreact"
|
||||||
|
},
|
||||||
|
"emmet.showSuggestionsAsSnippets": true,
|
||||||
|
"emmet.triggerExpansionOnTab": true,
|
||||||
|
"files.exclude": {
|
||||||
|
"**/*.js.map": {
|
||||||
|
"when": "$(basename)"
|
||||||
|
},
|
||||||
|
"**/node_modules": true
|
||||||
|
},
|
||||||
|
"html.autoClosingTags": true,
|
||||||
|
"javascript.autoClosingTags": true,
|
||||||
|
"javascript.suggest.completeFunctionCalls": true,
|
||||||
|
"typescript.suggest.completeFunctionCalls": true,
|
||||||
|
"javascript.inlayHints.functionLikeReturnTypes.enabled": true,
|
||||||
|
"typescript.inlayHints.functionLikeReturnTypes.enabled": true,
|
||||||
|
"javascript.inlayHints.parameterNames.enabled": "all",
|
||||||
|
"typescript.inlayHints.parameterNames.enabled": "all",
|
||||||
|
"javascript.suggest.autoImports": true,
|
||||||
|
"search.exclude": {
|
||||||
|
"**/coverage": true,
|
||||||
|
"**/node_modules": true
|
||||||
|
},
|
||||||
|
"typescript.autoClosingTags": true,
|
||||||
|
"typescript.suggest.autoImports": true
|
||||||
|
}
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
|
|
||||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
|
||||||
const ProgmemGenerator = require('./progmem-generator.js');
|
|
||||||
const TerserPlugin = require('terser-webpack-plugin');
|
|
||||||
|
|
||||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
|
|
||||||
|
|
||||||
module.exports = function override(config, env) {
|
|
||||||
const hosted = process.env.REACT_APP_HOSTED;
|
|
||||||
|
|
||||||
if (env === 'production' && !hosted) {
|
|
||||||
// rename the output file, we need it's path to be short, for embedded FS
|
|
||||||
config.output.filename = 'js/[id].[chunkhash:4].js';
|
|
||||||
config.output.chunkFilename = 'js/[id].[chunkhash:4].js';
|
|
||||||
|
|
||||||
// take out the manifest plugin
|
|
||||||
config.plugins = config.plugins.filter((plugin) => !(plugin instanceof WebpackManifestPlugin));
|
|
||||||
|
|
||||||
// shorten css filenames
|
|
||||||
const miniCssExtractPlugin = config.plugins.find((plugin) => plugin instanceof MiniCssExtractPlugin);
|
|
||||||
miniCssExtractPlugin.options.filename = 'css/[id].[contenthash:4].css';
|
|
||||||
miniCssExtractPlugin.options.chunkFilename = 'css/[id].[contenthash:4].c.css';
|
|
||||||
|
|
||||||
// don't emit license file
|
|
||||||
const terserPlugin = config.optimization.minimizer.find((plugin) => plugin instanceof TerserPlugin);
|
|
||||||
terserPlugin.options.extractComments = false;
|
|
||||||
|
|
||||||
// create size map
|
|
||||||
// config.plugins.push(new BundleAnalyzerPlugin());
|
|
||||||
|
|
||||||
// build progmem data files
|
|
||||||
config.plugins.push(new ProgmemGenerator({ outputPath: '../lib/framework/WWWData.h', bytesPerLine: 20 }));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
return config;
|
|
||||||
};
|
|
||||||
14
interface/index.html
Normal file
14
interface/index.html
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0, maximum-scale=1, minimum-scale=1" />
|
||||||
|
<link rel="stylesheet" href="/css/roboto.css" />
|
||||||
|
<link rel="manifest" href="/app/manifest.json" />
|
||||||
|
<title>EMS-ESP</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/index.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
14278
interface/package-lock.json
generated
14278
interface/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,18 @@
|
|||||||
{
|
{
|
||||||
"name": "EMS-ESP",
|
"name": "EMS-ESP",
|
||||||
"version": "3.5.0",
|
"version": "3.6.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"proxy": "http://localhost:3080",
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "tsc && vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"preview_standalone": "npm-run-all -p preview typesafe-i18n mock-api",
|
||||||
|
"mock-api": "nodemon --watch ../mock-api ../mock-api/server.js",
|
||||||
|
"standalone": "npm-run-all -p dev typesafe-i18n mock-api",
|
||||||
|
"typesafe-i18n": "typesafe-i18n",
|
||||||
|
"format": "prettier --write '**/*.{ts,tsx,js,css,json,md}'",
|
||||||
|
"lint": "eslint . --ext .ts,.tsx"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.10.5",
|
"@emotion/react": "^11.10.5",
|
||||||
"@emotion/styled": "^11.10.5",
|
"@emotion/styled": "^11.10.5",
|
||||||
@@ -10,96 +20,47 @@
|
|||||||
"@mui/icons-material": "^5.11.0",
|
"@mui/icons-material": "^5.11.0",
|
||||||
"@mui/material": "^5.11.8",
|
"@mui/material": "^5.11.8",
|
||||||
"@table-library/react-table-library": "4.0.24",
|
"@table-library/react-table-library": "4.0.24",
|
||||||
|
"@types/lodash-es": "^4.17.6",
|
||||||
"@types/node": "^18.13.0",
|
"@types/node": "^18.13.0",
|
||||||
"@types/react": "^18.0.27",
|
"@types/react": "^18.0.27",
|
||||||
"@types/react-dom": "^18.0.10",
|
"@types/react-dom": "^18.0.10",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"@types/lodash-es": "^4.17.6",
|
|
||||||
"async-validator": "^4.2.5",
|
"async-validator": "^4.2.5",
|
||||||
"axios": "^1.3.2",
|
"axios": "^1.3.2",
|
||||||
"jwt-decode": "^3.1.2",
|
"jwt-decode": "^3.1.2",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"notistack": "^2.0.8",
|
"notistack": "^2.0.8",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-app-rewired": "^2.2.1",
|
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-dropzone": "^14.2.3",
|
"react-dropzone": "^14.2.3",
|
||||||
"react-icons": "^4.7.1",
|
"react-icons": "^4.7.1",
|
||||||
"react-router-dom": "^6.8.1",
|
"react-router-dom": "^6.8.1",
|
||||||
"react-scripts": "^5.0.1",
|
|
||||||
"sockette": "^2.0.6",
|
"sockette": "^2.0.6",
|
||||||
"typesafe-i18n": "^5.24.0",
|
"typesafe-i18n": "^5.24.0",
|
||||||
"typescript": "^4.9.5"
|
"typescript": "^4.9.5"
|
||||||
},
|
},
|
||||||
"scripts": {
|
|
||||||
"start": "react-app-rewired start",
|
|
||||||
"build": "react-app-rewired build",
|
|
||||||
"test": "react-app-rewired test",
|
|
||||||
"eject": "react-scripts eject",
|
|
||||||
"format": "prettier --write '**/*.{ts,tsx,js,css,json,md}'",
|
|
||||||
"build-hosted": "env-cmd -f .env.hosted npm run build",
|
|
||||||
"build-localhost": "PUBLIC_URL=/ react-app-rewired build",
|
|
||||||
"mock-api": "nodemon --watch ../mock-api ../mock-api/server.js",
|
|
||||||
"standalone": "npm-run-all -p start typesafe-i18n mock-api",
|
|
||||||
"lint": "eslint . --ext .ts,.tsx",
|
|
||||||
"typesafe-i18n": "typesafe-i18n"
|
|
||||||
},
|
|
||||||
"eslintConfig": {
|
|
||||||
"extends": [
|
|
||||||
"react-app",
|
|
||||||
"react-app/jest"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"eol-last": 1,
|
|
||||||
"react/jsx-closing-bracket-location": 1,
|
|
||||||
"react/jsx-closing-tag-location": 1,
|
|
||||||
"react/jsx-wrap-multilines": 1,
|
|
||||||
"react/jsx-curly-newline": 1,
|
|
||||||
"no-multiple-empty-lines": [
|
|
||||||
1,
|
|
||||||
{
|
|
||||||
"max": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"no-trailing-spaces": 1,
|
|
||||||
"semi": 1,
|
|
||||||
"no-extra-semi": 1,
|
|
||||||
"react/jsx-max-props-per-line": [
|
|
||||||
1,
|
|
||||||
{
|
|
||||||
"when": "multiline"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"react/jsx-first-prop-new-line": [
|
|
||||||
1,
|
|
||||||
"multiline"
|
|
||||||
],
|
|
||||||
"@typescript-eslint/no-shadow": 1,
|
|
||||||
"max-len": [
|
|
||||||
1,
|
|
||||||
{
|
|
||||||
"code": 220
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"arrow-parens": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"browserslist": {
|
|
||||||
"production": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not op_mini all"
|
|
||||||
],
|
|
||||||
"development": [
|
|
||||||
"last 1 chrome version",
|
|
||||||
"last 1 firefox version",
|
|
||||||
"last 1 safari version"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"http-proxy-middleware": "^2.0.6",
|
"@typescript-eslint/eslint-plugin": "^5.51.0",
|
||||||
|
"@typescript-eslint/parser": "^5.51.0",
|
||||||
|
"@vitejs/plugin-react-swc": "^3.1.0",
|
||||||
|
"babel-plugin-styled-components": "^2.0.7",
|
||||||
|
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
|
||||||
|
"eslint": "^8.33.0",
|
||||||
|
"eslint-config-prettier": "^8.6.0",
|
||||||
|
"eslint-import-resolver-typescript": "^3.5.3",
|
||||||
|
"eslint-plugin-import": "^2.27.5",
|
||||||
|
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||||
|
"eslint-plugin-react": "^7.32.2",
|
||||||
|
"eslint-plugin-react-refresh": "^0.3.3",
|
||||||
"nodemon": "^2.0.20",
|
"nodemon": "^2.0.20",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"webpack-bundle-analyzer": "^4.7.0"
|
"prettier": "^2.8.4",
|
||||||
|
"rollup-plugin-visualizer": "^5.9.0",
|
||||||
|
"vite": "^4.1.1",
|
||||||
|
"vite-plugin-svgr": "^2.4.0",
|
||||||
|
"vite-tsconfig-paths": "^4.0.5",
|
||||||
|
"@types/styled-components": "^5.1.26",
|
||||||
|
"@swc/plugin-styled-components": "^1.5.41",
|
||||||
|
"styled-components": "^5.3.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ var zlib = require('zlib');
|
|||||||
var mime = require('mime-types');
|
var mime = require('mime-types');
|
||||||
|
|
||||||
const ARDUINO_INCLUDES = '#include <Arduino.h>\n\n';
|
const ARDUINO_INCLUDES = '#include <Arduino.h>\n\n';
|
||||||
|
const INDENT = ' ';
|
||||||
|
|
||||||
function getFilesSync(dir, files = []) {
|
function getFilesSync(dir, files = []) {
|
||||||
readdirSync(dir, { withFileTypes: true }).forEach((entry) => {
|
readdirSync(dir, { withFileTypes: true }).forEach((entry) => {
|
||||||
@@ -28,17 +29,16 @@ function cleanAndOpen(path) {
|
|||||||
return createWriteStream(path, { flags: 'w+' });
|
return createWriteStream(path, { flags: 'w+' });
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProgmemGenerator {
|
export default function ProgmemGenerator({ outputPath = './WWWData.h', bytesPerLine = 20 }) {
|
||||||
constructor(options = {}) {
|
return {
|
||||||
const { outputPath, bytesPerLine = 20, indent = ' ', includes = ARDUINO_INCLUDES } = options;
|
name: 'ProgmemGenerator',
|
||||||
this.options = { outputPath, bytesPerLine, indent, includes };
|
writeBundle: () => {
|
||||||
}
|
console.log('Generating ' + outputPath);
|
||||||
|
const includes = ARDUINO_INCLUDES;
|
||||||
apply(compiler) {
|
const indent = INDENT;
|
||||||
compiler.hooks.emit.tapAsync({ name: 'ProgmemGenerator' }, (compilation, callback) => {
|
|
||||||
const { outputPath, bytesPerLine, indent, includes } = this.options;
|
|
||||||
const fileInfo = [];
|
const fileInfo = [];
|
||||||
const writeStream = cleanAndOpen(resolve(compilation.options.context, outputPath));
|
const writeStream = cleanAndOpen(resolve(outputPath));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const writeIncludes = () => {
|
const writeIncludes = () => {
|
||||||
writeStream.write(includes);
|
writeStream.write(includes);
|
||||||
@@ -73,17 +73,18 @@ class ProgmemGenerator {
|
|||||||
|
|
||||||
const writeFiles = () => {
|
const writeFiles = () => {
|
||||||
// process static files
|
// process static files
|
||||||
const buildPath = compilation.options.output.path;
|
const buildPath = resolve('build');
|
||||||
for (const filePath of getFilesSync(buildPath)) {
|
for (const filePath of getFilesSync(buildPath)) {
|
||||||
const readStream = readFileSync(filePath);
|
const readStream = readFileSync(filePath);
|
||||||
const relativeFilePath = relative(buildPath, filePath);
|
const relativeFilePath = relative(buildPath, filePath);
|
||||||
writeFile(relativeFilePath, readStream);
|
writeFile(relativeFilePath, readStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
// process assets
|
// process assets
|
||||||
const { assets } = compilation;
|
// const { assets } = compilation;
|
||||||
Object.keys(assets).forEach((relativeFilePath) => {
|
// Object.keys(assets).forEach((relativeFilePath) => {
|
||||||
writeFile(relativeFilePath, coherseToBuffer(assets[relativeFilePath].source()));
|
// writeFile(relativeFilePath, coherseToBuffer(assets[relativeFilePath].source()));
|
||||||
});
|
// });
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateWWWClass = () => {
|
const generateWWWClass = () => {
|
||||||
@@ -110,13 +111,11 @@ ${indent.repeat(2)}}
|
|||||||
writeWWWClass();
|
writeWWWClass();
|
||||||
|
|
||||||
writeStream.on('finish', () => {
|
writeStream.on('finish', () => {
|
||||||
callback();
|
// callback();
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
writeStream.end();
|
writeStream.end();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = ProgmemGenerator;
|
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta
|
|
||||||
name="viewport"
|
|
||||||
content="width=device-width, initial-scale=1, user-scalable=0, maximum-scale=1, minimum-scale=1"
|
|
||||||
/>
|
|
||||||
<link rel="stylesheet" href="%PUBLIC_URL%/css/roboto.css" />
|
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/app/manifest.json" />
|
|
||||||
<title>EMS-ESP</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<noscript> You need to enable JavaScript to run this app. </noscript>
|
|
||||||
<div id="root"></div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -4,13 +4,13 @@ import { SnackbarProvider } from 'notistack';
|
|||||||
import { IconButton } from '@mui/material';
|
import { IconButton } from '@mui/material';
|
||||||
import CloseIcon from '@mui/icons-material/Close';
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
|
|
||||||
import CustomTheme from './CustomTheme';
|
import CustomTheme from 'CustomTheme';
|
||||||
import AppRouting from './AppRouting';
|
import AppRouting from 'AppRouting';
|
||||||
|
|
||||||
import { localStorageDetector } from 'typesafe-i18n/detectors';
|
import { localStorageDetector } from 'typesafe-i18n/detectors';
|
||||||
import TypesafeI18n from './i18n/i18n-react';
|
import TypesafeI18n from 'i18n/i18n-react';
|
||||||
import { detectLocale } from './i18n/i18n-util';
|
import { detectLocale } from 'i18n/i18n-util';
|
||||||
import { loadLocaleAsync } from './i18n/i18n-util.async';
|
import { loadLocaleAsync } from 'i18n/i18n-util.async';
|
||||||
|
|
||||||
const detectedLocale = detectLocale(localStorageDetector);
|
const detectedLocale = detectLocale(localStorageDetector);
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ import { Route, Routes, Navigate, useLocation } from 'react-router-dom';
|
|||||||
|
|
||||||
import { useSnackbar, VariantType } from 'notistack';
|
import { useSnackbar, VariantType } from 'notistack';
|
||||||
|
|
||||||
import { useI18nContext } from './i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
import { Authentication, AuthenticationContext } from './contexts/authentication';
|
import { Authentication, AuthenticationContext } from 'contexts/authentication';
|
||||||
import { RequireAuthenticated, RequireUnauthenticated } from './components';
|
import { RequireAuthenticated, RequireUnauthenticated } from 'components';
|
||||||
|
|
||||||
import SignIn from './SignIn';
|
import SignIn from 'SignIn';
|
||||||
import AuthenticatedRouting from './AuthenticatedRouting';
|
import AuthenticatedRouting from 'AuthenticatedRouting';
|
||||||
|
|
||||||
interface SecurityRedirectProps {
|
interface SecurityRedirectProps {
|
||||||
message: string;
|
message: string;
|
||||||
@@ -28,7 +28,6 @@ const RootRedirect: FC<SecurityRedirectProps> = ({ message, variant, signOut })
|
|||||||
return <Navigate to="/" />;
|
return <Navigate to="/" />;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO still need this?
|
|
||||||
export const RemoveTrailingSlashes = () => {
|
export const RemoveTrailingSlashes = () => {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -2,19 +2,19 @@ import { FC, useCallback, useEffect } from 'react';
|
|||||||
import { Navigate, Routes, Route, useNavigate, useLocation } from 'react-router-dom';
|
import { Navigate, Routes, Route, useNavigate, useLocation } from 'react-router-dom';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
|
|
||||||
import * as AuthenticationApi from './api/authentication';
|
import * as AuthenticationApi from 'api/authentication';
|
||||||
import { PROJECT_PATH } from './api/env';
|
import { PROJECT_PATH } from 'api/env';
|
||||||
import { AXIOS } from './api/endpoints';
|
import { AXIOS } from 'api/endpoints';
|
||||||
import { Layout, RequireAdmin } from './components';
|
import { Layout, RequireAdmin } from 'components';
|
||||||
|
|
||||||
import ProjectRouting from './project/ProjectRouting';
|
import ProjectRouting from 'project/ProjectRouting';
|
||||||
|
|
||||||
import NetworkConnection from './framework/network/NetworkConnection';
|
import NetworkConnection from 'framework/network/NetworkConnection';
|
||||||
import AccessPoint from './framework/ap/AccessPoint';
|
import AccessPoint from 'framework/ap/AccessPoint';
|
||||||
import NetworkTime from './framework/ntp/NetworkTime';
|
import NetworkTime from 'framework/ntp/NetworkTime';
|
||||||
import Mqtt from './framework/mqtt/Mqtt';
|
import Mqtt from 'framework/mqtt/Mqtt';
|
||||||
import System from './framework/system/System';
|
import System from 'framework/system/System';
|
||||||
import Security from './framework/security/Security';
|
import Security from 'framework/security/Security';
|
||||||
|
|
||||||
const AuthenticatedRouting: FC = () => {
|
const AuthenticatedRouting: FC = () => {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { CssBaseline } from '@mui/material';
|
|||||||
import { createTheme, responsiveFontSizes, ThemeProvider } from '@mui/material/styles';
|
import { createTheme, responsiveFontSizes, ThemeProvider } from '@mui/material/styles';
|
||||||
import { blueGrey, blue } from '@mui/material/colors';
|
import { blueGrey, blue } from '@mui/material/colors';
|
||||||
|
|
||||||
import { RequiredChildrenProps } from './utils';
|
import { RequiredChildrenProps } from 'utils';
|
||||||
|
|
||||||
const theme = responsiveFontSizes(
|
const theme = responsiveFontSizes(
|
||||||
createTheme({
|
createTheme({
|
||||||
|
|||||||
@@ -5,26 +5,26 @@ import { useSnackbar } from 'notistack';
|
|||||||
import { Box, Fab, Paper, Typography, Button } from '@mui/material';
|
import { Box, Fab, Paper, Typography, Button } from '@mui/material';
|
||||||
import ForwardIcon from '@mui/icons-material/Forward';
|
import ForwardIcon from '@mui/icons-material/Forward';
|
||||||
|
|
||||||
import * as AuthenticationApi from './api/authentication';
|
import * as AuthenticationApi from 'api/authentication';
|
||||||
import { PROJECT_NAME } from './api/env';
|
import { PROJECT_NAME } from 'api/env';
|
||||||
import { AuthenticationContext } from './contexts/authentication';
|
import { AuthenticationContext } from 'contexts/authentication';
|
||||||
|
|
||||||
import { extractErrorMessage, onEnterCallback, updateValue } from './utils';
|
import { extractErrorMessage, onEnterCallback, updateValue } from 'utils';
|
||||||
import { SignInRequest } from './types';
|
import { SignInRequest } from 'types';
|
||||||
import { ValidatedTextField } from './components';
|
import { ValidatedTextField } from 'components';
|
||||||
import { SIGN_IN_REQUEST_VALIDATOR, validate } from './validators';
|
import { SIGN_IN_REQUEST_VALIDATOR, validate } from 'validators';
|
||||||
|
|
||||||
import { I18nContext } from './i18n/i18n-react';
|
import { I18nContext } from 'i18n/i18n-react';
|
||||||
import type { Locales } from './i18n/i18n-types';
|
import type { Locales } from 'i18n/i18n-types';
|
||||||
import { loadLocaleAsync } from './i18n/i18n-util.async';
|
import { loadLocaleAsync } from 'i18n/i18n-util.async';
|
||||||
|
|
||||||
import { ReactComponent as NLflag } from './i18n/NL.svg';
|
import { ReactComponent as NLflag } from 'i18n/NL.svg';
|
||||||
import { ReactComponent as DEflag } from './i18n/DE.svg';
|
import { ReactComponent as DEflag } from 'i18n/DE.svg';
|
||||||
import { ReactComponent as GBflag } from './i18n/GB.svg';
|
import { ReactComponent as GBflag } from 'i18n/GB.svg';
|
||||||
import { ReactComponent as SVflag } from './i18n/SV.svg';
|
import { ReactComponent as SVflag } from 'i18n/SV.svg';
|
||||||
import { ReactComponent as PLflag } from './i18n/PL.svg';
|
import { ReactComponent as PLflag } from 'i18n/PL.svg';
|
||||||
import { ReactComponent as NOflag } from './i18n/NO.svg';
|
import { ReactComponent as NOflag } from 'i18n/NO.svg';
|
||||||
import { ReactComponent as FRflag } from './i18n/FR.svg';
|
import { ReactComponent as FRflag } from 'i18n/FR.svg';
|
||||||
|
|
||||||
const SignIn: FC = () => {
|
const SignIn: FC = () => {
|
||||||
const authenticationContext = useContext(AuthenticationContext);
|
const authenticationContext = useContext(AuthenticationContext);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AxiosPromise } from 'axios';
|
import { AxiosPromise } from 'axios';
|
||||||
|
|
||||||
import { APSettings, APStatus } from '../types';
|
import { APSettings, APStatus } from 'types';
|
||||||
import { AXIOS } from './endpoints';
|
import { AXIOS } from './endpoints';
|
||||||
|
|
||||||
export function readAPStatus(): AxiosPromise<APStatus> {
|
export function readAPStatus(): AxiosPromise<APStatus> {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import * as H from 'history';
|
|||||||
import jwtDecode from 'jwt-decode';
|
import jwtDecode from 'jwt-decode';
|
||||||
import { Path } from 'react-router-dom';
|
import { Path } from 'react-router-dom';
|
||||||
|
|
||||||
import { Me, SignInRequest, SignInResponse } from '../types';
|
import { Me, SignInRequest, SignInResponse } from 'types';
|
||||||
|
|
||||||
import { ACCESS_TOKEN, AXIOS } from './endpoints';
|
import { ACCESS_TOKEN, AXIOS } from './endpoints';
|
||||||
import { PROJECT_PATH } from './env';
|
import { PROJECT_PATH } from './env';
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
export const PROJECT_NAME = process.env.REACT_APP_PROJECT_NAME || 'EMS-ESP';
|
export const PROJECT_NAME = 'EMS-ESP';
|
||||||
export const PROJECT_PATH = process.env.REACT_APP_PROJECT_PATH || 'project';
|
export const PROJECT_PATH = 'project';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AxiosPromise } from 'axios';
|
import { AxiosPromise } from 'axios';
|
||||||
|
|
||||||
import { Features } from '../types';
|
import { Features } from 'types';
|
||||||
|
|
||||||
import { AXIOS } from './endpoints';
|
import { AXIOS } from './endpoints';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { AxiosPromise } from 'axios';
|
import { AxiosPromise } from 'axios';
|
||||||
import { MqttSettings, MqttStatus } from '../types';
|
import { MqttSettings, MqttStatus } from 'types';
|
||||||
|
|
||||||
import { AXIOS } from './endpoints';
|
import { AXIOS } from './endpoints';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AxiosPromise } from 'axios';
|
import { AxiosPromise } from 'axios';
|
||||||
|
|
||||||
import { WiFiNetworkList, NetworkSettings, NetworkStatus } from '../types';
|
import { WiFiNetworkList, NetworkSettings, NetworkStatus } from 'types';
|
||||||
|
|
||||||
import { AXIOS } from './endpoints';
|
import { AXIOS } from './endpoints';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { AxiosPromise } from 'axios';
|
import { AxiosPromise } from 'axios';
|
||||||
import { NTPSettings, NTPStatus, Time } from '../types';
|
import { NTPSettings, NTPStatus, Time } from 'types';
|
||||||
|
|
||||||
import { AXIOS } from './endpoints';
|
import { AXIOS } from './endpoints';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AxiosPromise } from 'axios';
|
import { AxiosPromise } from 'axios';
|
||||||
|
|
||||||
import { SecuritySettings, Token } from '../types';
|
import { SecuritySettings, Token } from 'types';
|
||||||
|
|
||||||
import { AXIOS } from './endpoints';
|
import { AXIOS } from './endpoints';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AxiosPromise } from 'axios';
|
import { AxiosPromise } from 'axios';
|
||||||
|
|
||||||
import { OTASettings, SystemStatus, LogSettings, LogEntries } from '../types';
|
import { OTASettings, SystemStatus, LogSettings, LogEntries } from 'types';
|
||||||
|
|
||||||
import { AXIOS, AXIOS_BIN, FileUploadConfig, startUploadFile } from './endpoints';
|
import { AXIOS, AXIOS_BIN, FileUploadConfig, startUploadFile } from './endpoints';
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { FC } from 'react';
|
|||||||
|
|
||||||
import { Paper, Divider } from '@mui/material';
|
import { Paper, Divider } from '@mui/material';
|
||||||
|
|
||||||
import { RequiredChildrenProps } from '../utils';
|
import { RequiredChildrenProps } from 'utils';
|
||||||
|
|
||||||
interface SectionContentProps extends RequiredChildrenProps {
|
interface SectionContentProps extends RequiredChildrenProps {
|
||||||
title: string;
|
title: string;
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import { useLocation } from 'react-router-dom';
|
|||||||
|
|
||||||
import { Box, Toolbar } from '@mui/material';
|
import { Box, Toolbar } from '@mui/material';
|
||||||
|
|
||||||
import { PROJECT_NAME } from '../../api/env';
|
import { PROJECT_NAME } from 'api/env';
|
||||||
import { RequiredChildrenProps } from '../../utils';
|
import { RequiredChildrenProps } from 'utils';
|
||||||
|
|
||||||
import LayoutDrawer from './LayoutDrawer';
|
import LayoutDrawer from './LayoutDrawer';
|
||||||
import LayoutAppBar from './LayoutAppBar';
|
import LayoutAppBar from './LayoutAppBar';
|
||||||
|
|||||||
@@ -17,19 +17,19 @@ import {
|
|||||||
import PersonIcon from '@mui/icons-material/Person';
|
import PersonIcon from '@mui/icons-material/Person';
|
||||||
import AccountCircleIcon from '@mui/icons-material/AccountCircle';
|
import AccountCircleIcon from '@mui/icons-material/AccountCircle';
|
||||||
|
|
||||||
import { AuthenticatedContext } from '../../contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
|
|
||||||
import { I18nContext } from '../../i18n/i18n-react';
|
import { I18nContext } from 'i18n/i18n-react';
|
||||||
import type { Locales } from '../../i18n/i18n-types';
|
import type { Locales } from 'i18n/i18n-types';
|
||||||
import { loadLocaleAsync } from '../../i18n/i18n-util.async';
|
import { loadLocaleAsync } from 'i18n/i18n-util.async';
|
||||||
|
|
||||||
import { ReactComponent as NLflag } from '../../i18n/NL.svg';
|
import { ReactComponent as NLflag } from 'i18n/NL.svg';
|
||||||
import { ReactComponent as DEflag } from '../../i18n/DE.svg';
|
import { ReactComponent as DEflag } from 'i18n/DE.svg';
|
||||||
import { ReactComponent as GBflag } from '../../i18n/GB.svg';
|
import { ReactComponent as GBflag } from 'i18n/GB.svg';
|
||||||
import { ReactComponent as SVflag } from '../../i18n/SV.svg';
|
import { ReactComponent as SVflag } from 'i18n/SV.svg';
|
||||||
import { ReactComponent as PLflag } from '../../i18n/PL.svg';
|
import { ReactComponent as PLflag } from 'i18n/PL.svg';
|
||||||
import { ReactComponent as NOflag } from '../../i18n/NO.svg';
|
import { ReactComponent as NOflag } from 'i18n/NO.svg';
|
||||||
import { ReactComponent as FRflag } from '../../i18n/FR.svg';
|
import { ReactComponent as FRflag } from 'i18n/FR.svg';
|
||||||
|
|
||||||
const ItemTypography = styled(Typography)<TypographyProps>({
|
const ItemTypography = styled(Typography)<TypographyProps>({
|
||||||
maxWidth: '250px',
|
maxWidth: '250px',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { FC } from 'react';
|
|||||||
|
|
||||||
import { Box, Divider, Drawer, Toolbar, Typography, styled } from '@mui/material';
|
import { Box, Divider, Drawer, Toolbar, Typography, styled } from '@mui/material';
|
||||||
|
|
||||||
import { PROJECT_NAME } from '../../api/env';
|
import { PROJECT_NAME } from 'api/env';
|
||||||
|
|
||||||
import LayoutMenu from './LayoutMenu';
|
import LayoutMenu from './LayoutMenu';
|
||||||
import { DRAWER_WIDTH } from './Layout';
|
import { DRAWER_WIDTH } from './Layout';
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ import SettingsIcon from '@mui/icons-material/Settings';
|
|||||||
import LockIcon from '@mui/icons-material/Lock';
|
import LockIcon from '@mui/icons-material/Lock';
|
||||||
import SettingsEthernetIcon from '@mui/icons-material/SettingsEthernet';
|
import SettingsEthernetIcon from '@mui/icons-material/SettingsEthernet';
|
||||||
|
|
||||||
import ProjectMenu from '../../project/ProjectMenu';
|
import ProjectMenu from 'project/ProjectMenu';
|
||||||
|
|
||||||
import LayoutMenuItem from './LayoutMenuItem';
|
import LayoutMenuItem from './LayoutMenuItem';
|
||||||
import { AuthenticatedContext } from '../../contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const LayoutMenu: FC = () => {
|
const LayoutMenu: FC = () => {
|
||||||
const authenticatedContext = useContext(AuthenticatedContext);
|
const authenticatedContext = useContext(AuthenticatedContext);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { ListItem, ListItemButton, ListItemIcon, ListItemText, SvgIconProps } fr
|
|||||||
|
|
||||||
import { grey } from '@mui/material/colors';
|
import { grey } from '@mui/material/colors';
|
||||||
|
|
||||||
import { routeMatches } from '../../utils';
|
import { routeMatches } from 'utils';
|
||||||
|
|
||||||
interface LayoutMenuItemProps {
|
interface LayoutMenuItemProps {
|
||||||
icon: React.ComponentType<SvgIconProps>;
|
icon: React.ComponentType<SvgIconProps>;
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import { FC } from 'react';
|
|||||||
import { Box, Button, CircularProgress, Typography } from '@mui/material';
|
import { Box, Button, CircularProgress, Typography } from '@mui/material';
|
||||||
import RefreshIcon from '@mui/icons-material/Refresh';
|
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||||
|
|
||||||
import { MessageBox } from '..';
|
import { MessageBox } from 'components';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
interface FormLoaderProps {
|
interface FormLoaderProps {
|
||||||
message?: string;
|
message?: string;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { FC } from 'react';
|
|||||||
|
|
||||||
import { CircularProgress, Box, Typography, Theme } from '@mui/material';
|
import { CircularProgress, Box, Typography, Theme } from '@mui/material';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
interface LoadingSpinnerProps {
|
interface LoadingSpinnerProps {
|
||||||
height?: number | string;
|
height?: number | string;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { FC } from 'react';
|
|||||||
import type { Blocker } from '@remix-run/router';
|
import type { Blocker } from '@remix-run/router';
|
||||||
import { Button, Dialog, DialogActions, DialogContent, DialogTitle } from '@mui/material';
|
import { Button, Dialog, DialogActions, DialogContent, DialogTitle } from '@mui/material';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
interface BlockNavigationProps {
|
interface BlockNavigationProps {
|
||||||
blocker: Blocker;
|
blocker: Blocker;
|
||||||
@@ -19,7 +19,7 @@ const BlockNavigation: FC<BlockNavigationProps> = ({ blocker }) => {
|
|||||||
<Button variant="outlined" onClick={() => blocker.reset?.()} color="secondary">
|
<Button variant="outlined" onClick={() => blocker.reset?.()} color="secondary">
|
||||||
{LL.STAY()}
|
{LL.STAY()}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="contained" onClick={() => blocker.proceed?.()} color="primary" autoFocus>
|
<Button variant="contained" onClick={() => blocker.proceed?.()} color="primary">
|
||||||
{LL.LEAVE()}
|
{LL.LEAVE()}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { FC, useContext } from 'react';
|
import { FC, useContext } from 'react';
|
||||||
import { Navigate } from 'react-router-dom';
|
import { Navigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { AuthenticatedContext } from '../../contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
import { RequiredChildrenProps } from '../../utils';
|
import { RequiredChildrenProps } from 'utils';
|
||||||
|
|
||||||
const RequireAdmin: FC<RequiredChildrenProps> = ({ children }) => {
|
const RequireAdmin: FC<RequiredChildrenProps> = ({ children }) => {
|
||||||
const authenticatedContext = useContext(AuthenticatedContext);
|
const authenticatedContext = useContext(AuthenticatedContext);
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import {
|
|||||||
AuthenticatedContext,
|
AuthenticatedContext,
|
||||||
AuthenticatedContextValue,
|
AuthenticatedContextValue,
|
||||||
AuthenticationContext
|
AuthenticationContext
|
||||||
} from '../../contexts/authentication/context';
|
} from 'contexts/authentication/context';
|
||||||
import { storeLoginRedirect } from '../../api/authentication';
|
import { storeLoginRedirect } from 'api/authentication';
|
||||||
|
|
||||||
import { RequiredChildrenProps } from '../../utils';
|
import { RequiredChildrenProps } from 'utils';
|
||||||
|
|
||||||
const RequireAuthenticated: FC<RequiredChildrenProps> = ({ children }) => {
|
const RequireAuthenticated: FC<RequiredChildrenProps> = ({ children }) => {
|
||||||
const authenticationContext = useContext(AuthenticationContext);
|
const authenticationContext = useContext(AuthenticationContext);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { FC, useContext } from 'react';
|
import { FC, useContext } from 'react';
|
||||||
import { Navigate } from 'react-router-dom';
|
import { Navigate } from 'react-router-dom';
|
||||||
|
|
||||||
import * as AuthenticationApi from '../../api/authentication';
|
import * as AuthenticationApi from 'api/authentication';
|
||||||
import { AuthenticationContext } from '../../contexts/authentication';
|
import { AuthenticationContext } from 'contexts/authentication';
|
||||||
import { RequiredChildrenProps } from '../../utils';
|
import { RequiredChildrenProps } from 'utils';
|
||||||
|
|
||||||
const RequireUnauthenticated: FC<RequiredChildrenProps> = ({ children }) => {
|
const RequireUnauthenticated: FC<RequiredChildrenProps> = ({ children }) => {
|
||||||
const authenticationContext = useContext(AuthenticationContext);
|
const authenticationContext = useContext(AuthenticationContext);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { useNavigate } from 'react-router-dom';
|
|||||||
|
|
||||||
import { Tabs, useMediaQuery, useTheme } from '@mui/material';
|
import { Tabs, useMediaQuery, useTheme } from '@mui/material';
|
||||||
|
|
||||||
import { RequiredChildrenProps } from '../../utils';
|
import { RequiredChildrenProps } from 'utils';
|
||||||
|
|
||||||
interface RouterTabsProps extends RequiredChildrenProps {
|
interface RouterTabsProps extends RequiredChildrenProps {
|
||||||
value: string | false;
|
value: string | false;
|
||||||
@@ -15,6 +15,7 @@ const RouterTabs: FC<RouterTabsProps> = ({ value, children }) => {
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const smallDown = useMediaQuery(theme.breakpoints.down('sm'));
|
const smallDown = useMediaQuery(theme.breakpoints.down('sm'));
|
||||||
|
|
||||||
|
// TODO fix this
|
||||||
const handleTabChange = (event: React.ChangeEvent<{}>, path: string) => {
|
const handleTabChange = (event: React.ChangeEvent<{}>, path: string) => {
|
||||||
navigate(path);
|
navigate(path);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { Box, Button, LinearProgress, Theme, Typography, useTheme } from '@mui/m
|
|||||||
import CloudUploadIcon from '@mui/icons-material/CloudUpload';
|
import CloudUploadIcon from '@mui/icons-material/CloudUpload';
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const getBorderColor = (theme: Theme, props: DropzoneState) => {
|
const getBorderColor = (theme: Theme, props: DropzoneState) => {
|
||||||
if (props.isDragAccept) {
|
if (props.isDragAccept) {
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import { useCallback, useEffect, useState } from 'react';
|
|||||||
import axios, { AxiosPromise, CancelTokenSource, AxiosProgressEvent } from 'axios';
|
import axios, { AxiosPromise, CancelTokenSource, AxiosProgressEvent } from 'axios';
|
||||||
import { useSnackbar } from 'notistack';
|
import { useSnackbar } from 'notistack';
|
||||||
|
|
||||||
import { extractErrorMessage } from '../../utils';
|
import { extractErrorMessage } from 'utils';
|
||||||
import { FileUploadConfig } from '../../api/endpoints';
|
import { FileUploadConfig } from 'api/endpoints';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
interface MediaUploadOptions {
|
interface MediaUploadOptions {
|
||||||
upload: (file: File, config?: FileUploadConfig) => AxiosPromise<void>;
|
upload: (file: File, config?: FileUploadConfig) => AxiosPromise<void>;
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import { FC, useCallback, useEffect, useState } from 'react';
|
|||||||
import { useSnackbar } from 'notistack';
|
import { useSnackbar } from 'notistack';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
import * as AuthenticationApi from '../../api/authentication';
|
import * as AuthenticationApi from 'api/authentication';
|
||||||
import { ACCESS_TOKEN } from '../../api/endpoints';
|
import { ACCESS_TOKEN } from 'api/endpoints';
|
||||||
import { RequiredChildrenProps } from '../../utils';
|
import { RequiredChildrenProps } from 'utils';
|
||||||
import { LoadingSpinner } from '../../components';
|
import { LoadingSpinner } from 'components';
|
||||||
import { Me } from '../../types';
|
import { Me } from 'types';
|
||||||
import { AuthenticationContext } from './context';
|
import { AuthenticationContext } from './context';
|
||||||
|
|
||||||
const Authentication: FC<RequiredChildrenProps> = ({ children }) => {
|
const Authentication: FC<RequiredChildrenProps> = ({ children }) => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createContext } from 'react';
|
import { createContext } from 'react';
|
||||||
import { Me } from '../../types';
|
import { Me } from 'types';
|
||||||
|
|
||||||
export interface AuthenticationContextValue {
|
export interface AuthenticationContextValue {
|
||||||
refresh: () => Promise<void>;
|
refresh: () => Promise<void>;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
|
|
||||||
import * as FeaturesApi from '../../api/features';
|
import * as FeaturesApi from 'api/features';
|
||||||
|
|
||||||
import { extractErrorMessage, RequiredChildrenProps } from '../../utils';
|
import { extractErrorMessage, RequiredChildrenProps } from 'utils';
|
||||||
import { Features } from '../../types';
|
import { Features } from 'types';
|
||||||
import { ApplicationError, LoadingSpinner } from '../../components';
|
import { ApplicationError, LoadingSpinner } from 'components';
|
||||||
|
|
||||||
import { FeaturesContext } from '.';
|
import { FeaturesContext } from '.';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { createContext } from 'react';
|
import { createContext } from 'react';
|
||||||
|
|
||||||
import { Features } from '../../types';
|
import { Features } from 'types';
|
||||||
|
|
||||||
export interface FeaturesContextValue {
|
export interface FeaturesContextValue {
|
||||||
features: Features;
|
features: Features;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { Button, Checkbox, MenuItem } from '@mui/material';
|
|||||||
import WarningIcon from '@mui/icons-material/Warning';
|
import WarningIcon from '@mui/icons-material/Warning';
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
|
||||||
import { createAPSettingsValidator, validate } from '../../validators';
|
import { createAPSettingsValidator, validate } from 'validators';
|
||||||
import {
|
import {
|
||||||
BlockFormControlLabel,
|
BlockFormControlLabel,
|
||||||
ButtonRow,
|
ButtonRow,
|
||||||
@@ -15,13 +15,13 @@ import {
|
|||||||
ValidatedPasswordField,
|
ValidatedPasswordField,
|
||||||
ValidatedTextField,
|
ValidatedTextField,
|
||||||
BlockNavigation
|
BlockNavigation
|
||||||
} from '../../components';
|
} from 'components';
|
||||||
|
|
||||||
import { APProvisionMode, APSettings } from '../../types';
|
import { APProvisionMode, APSettings } from 'types';
|
||||||
import { numberValue, updateValueDirty, useRest } from '../../utils';
|
import { numberValue, updateValueDirty, useRest } from 'utils';
|
||||||
import * as APApi from '../../api/ap';
|
import * as APApi from 'api/ap';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
export const isAPEnabled = ({ provision_mode }: APSettings) => {
|
export const isAPEnabled = ({ provision_mode }: APSettings) => {
|
||||||
return provision_mode === APProvisionMode.AP_MODE_ALWAYS || provision_mode === APProvisionMode.AP_MODE_DISCONNECTED;
|
return provision_mode === APProvisionMode.AP_MODE_ALWAYS || provision_mode === APProvisionMode.AP_MODE_DISCONNECTED;
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ import DeviceHubIcon from '@mui/icons-material/DeviceHub';
|
|||||||
import ComputerIcon from '@mui/icons-material/Computer';
|
import ComputerIcon from '@mui/icons-material/Computer';
|
||||||
import RefreshIcon from '@mui/icons-material/Refresh';
|
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||||
|
|
||||||
import * as APApi from '../../api/ap';
|
import * as APApi from 'api/ap';
|
||||||
import { APNetworkStatus, APStatus } from '../../types';
|
import { APNetworkStatus, APStatus } from 'types';
|
||||||
import { ButtonRow, FormLoader, SectionContent } from '../../components';
|
import { ButtonRow, FormLoader, SectionContent } from 'components';
|
||||||
import { useRest } from '../../utils';
|
import { useRest } from 'utils';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
export const apStatusHighlight = ({ status }: APStatus, theme: Theme) => {
|
export const apStatusHighlight = ({ status }: APStatus, theme: Theme) => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import { Navigate, Routes, Route } from 'react-router-dom';
|
|||||||
|
|
||||||
import { Tab } from '@mui/material';
|
import { Tab } from '@mui/material';
|
||||||
|
|
||||||
import { AuthenticatedContext } from '../../contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
import APStatusForm from './APStatusForm';
|
import APStatusForm from './APStatusForm';
|
||||||
import APSettingsForm from './APSettingsForm';
|
import APSettingsForm from './APSettingsForm';
|
||||||
import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from '../../components';
|
import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const AccessPoint: FC = () => {
|
const AccessPoint: FC = () => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ import { Navigate, Route, Routes } from 'react-router-dom';
|
|||||||
|
|
||||||
import { Tab } from '@mui/material';
|
import { Tab } from '@mui/material';
|
||||||
|
|
||||||
import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from '../../components';
|
import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components';
|
||||||
import { AuthenticatedContext } from '../../contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
|
|
||||||
import MqttStatusForm from './MqttStatusForm';
|
import MqttStatusForm from './MqttStatusForm';
|
||||||
import MqttSettingsForm from './MqttSettingsForm';
|
import MqttSettingsForm from './MqttSettingsForm';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const Mqtt: FC = () => {
|
const Mqtt: FC = () => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { Button, Checkbox, MenuItem, Grid, Typography, InputAdornment } from '@m
|
|||||||
import WarningIcon from '@mui/icons-material/Warning';
|
import WarningIcon from '@mui/icons-material/Warning';
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
|
||||||
import { createMqttSettingsValidator, validate } from '../../validators';
|
import { createMqttSettingsValidator, validate } from 'validators';
|
||||||
import {
|
import {
|
||||||
BlockFormControlLabel,
|
BlockFormControlLabel,
|
||||||
ButtonRow,
|
ButtonRow,
|
||||||
@@ -15,12 +15,12 @@ import {
|
|||||||
ValidatedPasswordField,
|
ValidatedPasswordField,
|
||||||
ValidatedTextField,
|
ValidatedTextField,
|
||||||
BlockNavigation
|
BlockNavigation
|
||||||
} from '../../components';
|
} from 'components';
|
||||||
import { MqttSettings } from '../../types';
|
import { MqttSettings } from 'types';
|
||||||
import { numberValue, updateValueDirty, useRest } from '../../utils';
|
import { numberValue, updateValueDirty, useRest } from 'utils';
|
||||||
import * as MqttApi from '../../api/mqtt';
|
import * as MqttApi from 'api/mqtt';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const MqttSettingsForm: FC = () => {
|
const MqttSettingsForm: FC = () => {
|
||||||
const { loadData, saving, data, setData, origData, dirtyFlags, setDirtyFlags, blocker, saveData, errorMessage } =
|
const { loadData, saving, data, setData, origData, dirtyFlags, setDirtyFlags, blocker, saveData, errorMessage } =
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ import ReportIcon from '@mui/icons-material/Report';
|
|||||||
import SpeakerNotesOffIcon from '@mui/icons-material/SpeakerNotesOff';
|
import SpeakerNotesOffIcon from '@mui/icons-material/SpeakerNotesOff';
|
||||||
import AutoAwesomeMotionIcon from '@mui/icons-material/AutoAwesomeMotion';
|
import AutoAwesomeMotionIcon from '@mui/icons-material/AutoAwesomeMotion';
|
||||||
|
|
||||||
import { ButtonRow, FormLoader, SectionContent } from '../../components';
|
import { ButtonRow, FormLoader, SectionContent } from 'components';
|
||||||
import { MqttStatus, MqttDisconnectReason } from '../../types';
|
import { MqttStatus, MqttDisconnectReason } from 'types';
|
||||||
import * as MqttApi from '../../api/mqtt';
|
import * as MqttApi from 'api/mqtt';
|
||||||
import { useRest } from '../../utils';
|
import { useRest } from 'utils';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
export const mqttStatusHighlight = ({ enabled, connected }: MqttStatus, theme: Theme) => {
|
export const mqttStatusHighlight = ({ enabled, connected }: MqttStatus, theme: Theme) => {
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
|
|||||||
@@ -3,15 +3,15 @@ import { Navigate, Routes, Route, useNavigate } from 'react-router-dom';
|
|||||||
|
|
||||||
import { Tab } from '@mui/material';
|
import { Tab } from '@mui/material';
|
||||||
|
|
||||||
import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from '../../components';
|
import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components';
|
||||||
import { WiFiNetwork } from '../../types';
|
import { WiFiNetwork } from 'types';
|
||||||
import { AuthenticatedContext } from '../../contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
import { WiFiConnectionContext } from './WiFiConnectionContext';
|
import { WiFiConnectionContext } from './WiFiConnectionContext';
|
||||||
import NetworkStatusForm from './NetworkStatusForm';
|
import NetworkStatusForm from './NetworkStatusForm';
|
||||||
import WiFiNetworkScanner from './WiFiNetworkScanner';
|
import WiFiNetworkScanner from './WiFiNetworkScanner';
|
||||||
import NetworkSettingsForm from './NetworkSettingsForm';
|
import NetworkSettingsForm from './NetworkSettingsForm';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const NetworkConnection: FC = () => {
|
const NetworkConnection: FC = () => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|||||||
@@ -31,19 +31,19 @@ import {
|
|||||||
ValidatedTextField,
|
ValidatedTextField,
|
||||||
MessageBox,
|
MessageBox,
|
||||||
BlockNavigation
|
BlockNavigation
|
||||||
} from '../../components';
|
} from 'components';
|
||||||
import { NetworkSettings } from '../../types';
|
import { NetworkSettings } from 'types';
|
||||||
import * as NetworkApi from '../../api/network';
|
import * as NetworkApi from 'api/network';
|
||||||
import { numberValue, updateValueDirty, useRest } from '../../utils';
|
import { numberValue, updateValueDirty, useRest } from 'utils';
|
||||||
import * as EMSESP from '../../project/api';
|
import * as EMSESP from 'project/api';
|
||||||
|
|
||||||
import { WiFiConnectionContext } from './WiFiConnectionContext';
|
import { WiFiConnectionContext } from './WiFiConnectionContext';
|
||||||
import { isNetworkOpen, networkSecurityMode } from './WiFiNetworkSelector';
|
import { isNetworkOpen, networkSecurityMode } from './WiFiNetworkSelector';
|
||||||
import { ValidateFieldsError } from 'async-validator';
|
import { ValidateFieldsError } from 'async-validator';
|
||||||
import { validate } from '../../validators';
|
import { validate } from 'validators';
|
||||||
import { createNetworkSettingsValidator } from '../../validators/network';
|
import { createNetworkSettingsValidator } from 'validators/network';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import RestartMonitor from '../system/RestartMonitor';
|
import RestartMonitor from '../system/RestartMonitor';
|
||||||
|
|
||||||
const WiFiSettingsForm: FC = () => {
|
const WiFiSettingsForm: FC = () => {
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ import DnsIcon from '@mui/icons-material/Dns';
|
|||||||
import RefreshIcon from '@mui/icons-material/Refresh';
|
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||||
import RouterIcon from '@mui/icons-material/Router';
|
import RouterIcon from '@mui/icons-material/Router';
|
||||||
|
|
||||||
import { ButtonRow, FormLoader, SectionContent } from '../../components';
|
import { ButtonRow, FormLoader, SectionContent } from 'components';
|
||||||
import { NetworkConnectionStatus, NetworkStatus } from '../../types';
|
import { NetworkConnectionStatus, NetworkStatus } from 'types';
|
||||||
import * as NetworkApi from '../../api/network';
|
import * as NetworkApi from 'api/network';
|
||||||
import { useRest } from '../../utils';
|
import { useRest } from 'utils';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const isConnected = ({ status }: NetworkStatus) =>
|
const isConnected = ({ status }: NetworkStatus) =>
|
||||||
status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED ||
|
status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED ||
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createContext } from 'react';
|
import { createContext } from 'react';
|
||||||
import { WiFiNetwork } from '../../types';
|
import { WiFiNetwork } from 'types';
|
||||||
|
|
||||||
export interface WiFiConnectionContextValue {
|
export interface WiFiConnectionContextValue {
|
||||||
selectedNetwork?: WiFiNetwork;
|
selectedNetwork?: WiFiNetwork;
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ import { useSnackbar } from 'notistack';
|
|||||||
import { Button } from '@mui/material';
|
import { Button } from '@mui/material';
|
||||||
import PermScanWifiIcon from '@mui/icons-material/PermScanWifi';
|
import PermScanWifiIcon from '@mui/icons-material/PermScanWifi';
|
||||||
|
|
||||||
import * as NetworkApi from '../../api/network';
|
import * as NetworkApi from 'api/network';
|
||||||
import { WiFiNetwork, WiFiNetworkList } from '../../types';
|
import { WiFiNetwork, WiFiNetworkList } from 'types';
|
||||||
import { ButtonRow, FormLoader, SectionContent } from '../../components';
|
import { ButtonRow, FormLoader, SectionContent } from 'components';
|
||||||
|
|
||||||
import WiFiNetworkSelector from './WiFiNetworkSelector';
|
import WiFiNetworkSelector from './WiFiNetworkSelector';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const NUM_POLLS = 10;
|
const NUM_POLLS = 10;
|
||||||
const POLLING_FREQUENCY = 500;
|
const POLLING_FREQUENCY = 500;
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import LockOpenIcon from '@mui/icons-material/LockOpen';
|
|||||||
import LockIcon from '@mui/icons-material/Lock';
|
import LockIcon from '@mui/icons-material/Lock';
|
||||||
import WifiIcon from '@mui/icons-material/Wifi';
|
import WifiIcon from '@mui/icons-material/Wifi';
|
||||||
|
|
||||||
import { MessageBox } from '../../components';
|
import { MessageBox } from 'components';
|
||||||
|
|
||||||
import { WiFiEncryptionType, WiFiNetwork, WiFiNetworkList } from '../../types';
|
import { WiFiEncryptionType, WiFiNetwork, WiFiNetworkList } from 'types';
|
||||||
|
|
||||||
import { WiFiConnectionContext } from './WiFiConnectionContext';
|
import { WiFiConnectionContext } from './WiFiConnectionContext';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
interface WiFiNetworkSelectorProps {
|
interface WiFiNetworkSelectorProps {
|
||||||
networkList: WiFiNetworkList;
|
networkList: WiFiNetworkList;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { Button, Checkbox, MenuItem } from '@mui/material';
|
|||||||
import WarningIcon from '@mui/icons-material/Warning';
|
import WarningIcon from '@mui/icons-material/Warning';
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
|
||||||
import { validate } from '../../validators';
|
import { validate } from 'validators';
|
||||||
import {
|
import {
|
||||||
BlockFormControlLabel,
|
BlockFormControlLabel,
|
||||||
ButtonRow,
|
ButtonRow,
|
||||||
@@ -13,14 +13,14 @@ import {
|
|||||||
SectionContent,
|
SectionContent,
|
||||||
ValidatedTextField,
|
ValidatedTextField,
|
||||||
BlockNavigation
|
BlockNavigation
|
||||||
} from '../../components';
|
} from 'components';
|
||||||
import { NTPSettings } from '../../types';
|
import { NTPSettings } from 'types';
|
||||||
import { updateValueDirty, useRest } from '../../utils';
|
import { updateValueDirty, useRest } from 'utils';
|
||||||
import * as NTPApi from '../../api/ntp';
|
import * as NTPApi from 'api/ntp';
|
||||||
import { selectedTimeZone, timeZoneSelectItems, TIME_ZONES } from './TZ';
|
import { selectedTimeZone, timeZoneSelectItems, TIME_ZONES } from './TZ';
|
||||||
import { NTP_SETTINGS_VALIDATOR } from '../../validators/ntp';
|
import { NTP_SETTINGS_VALIDATOR } from 'validators/ntp';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const NTPSettingsForm: FC = () => {
|
const NTPSettingsForm: FC = () => {
|
||||||
const { loadData, saving, data, setData, origData, dirtyFlags, setDirtyFlags, blocker, saveData, errorMessage } =
|
const { loadData, saving, data, setData, origData, dirtyFlags, setDirtyFlags, blocker, saveData, errorMessage } =
|
||||||
|
|||||||
@@ -26,13 +26,13 @@ import UpdateIcon from '@mui/icons-material/Update';
|
|||||||
import DnsIcon from '@mui/icons-material/Dns';
|
import DnsIcon from '@mui/icons-material/Dns';
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
|
||||||
import * as NTPApi from '../../api/ntp';
|
import * as NTPApi from 'api/ntp';
|
||||||
import { NTPStatus, NTPSyncStatus } from '../../types';
|
import { NTPStatus, NTPSyncStatus } from 'types';
|
||||||
import { ButtonRow, FormLoader, SectionContent } from '../../components';
|
import { ButtonRow, FormLoader, SectionContent } from 'components';
|
||||||
import { extractErrorMessage, formatDateTime, formatLocalDateTime, useRest } from '../../utils';
|
import { extractErrorMessage, formatDateTime, formatLocalDateTime, useRest } from 'utils';
|
||||||
import { AuthenticatedContext } from '../../contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
export const isNtpActive = ({ status }: NTPStatus) => status === NTPSyncStatus.NTP_ACTIVE;
|
export const isNtpActive = ({ status }: NTPStatus) => status === NTPSyncStatus.NTP_ACTIVE;
|
||||||
export const isNtpEnabled = ({ status }: NTPStatus) => status !== NTPSyncStatus.NTP_DISABLED;
|
export const isNtpEnabled = ({ status }: NTPStatus) => status !== NTPSyncStatus.NTP_DISABLED;
|
||||||
@@ -127,7 +127,6 @@ const NTPStatusForm: FC = () => {
|
|||||||
onClick={configureTime}
|
onClick={configureTime}
|
||||||
disabled={processing}
|
disabled={processing}
|
||||||
color="primary"
|
color="primary"
|
||||||
autoFocus
|
|
||||||
>
|
>
|
||||||
{LL.UPDATE()}
|
{LL.UPDATE()}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ import { Navigate, Route, Routes } from 'react-router-dom';
|
|||||||
|
|
||||||
import { Tab } from '@mui/material';
|
import { Tab } from '@mui/material';
|
||||||
|
|
||||||
import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from '../../components';
|
import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components';
|
||||||
import { AuthenticatedContext } from '../../contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
|
|
||||||
import NTPStatusForm from './NTPStatusForm';
|
import NTPStatusForm from './NTPStatusForm';
|
||||||
import NTPSettingsForm from './NTPSettingsForm';
|
import NTPSettingsForm from './NTPSettingsForm';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const NetworkTime: FC = () => {
|
const NetworkTime: FC = () => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ import {
|
|||||||
|
|
||||||
import CloseIcon from '@mui/icons-material/Close';
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
|
|
||||||
import { extractErrorMessage } from '../../utils';
|
import { extractErrorMessage } from 'utils';
|
||||||
import { useSnackbar } from 'notistack';
|
import { useSnackbar } from 'notistack';
|
||||||
import { MessageBox } from '../../components';
|
import { MessageBox } from 'components';
|
||||||
import * as SecurityApi from '../../api/security';
|
import * as SecurityApi from 'api/security';
|
||||||
import { Token } from '../../types';
|
import { Token } from 'types';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
interface GenerateTokenProps {
|
interface GenerateTokenProps {
|
||||||
username?: string;
|
username?: string;
|
||||||
|
|||||||
@@ -9,18 +9,17 @@ import CheckIcon from '@mui/icons-material/Check';
|
|||||||
import CloseIcon from '@mui/icons-material/Close';
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
import VpnKeyIcon from '@mui/icons-material/VpnKey';
|
import VpnKeyIcon from '@mui/icons-material/VpnKey';
|
||||||
|
|
||||||
import { Table } from '@table-library/react-table-library/table';
|
|
||||||
import { useTheme } from '@table-library/react-table-library/theme';
|
import { useTheme } from '@table-library/react-table-library/theme';
|
||||||
import { Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
|
import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
|
||||||
|
|
||||||
import * as SecurityApi from '../../api/security';
|
import * as SecurityApi from 'api/security';
|
||||||
import { SecuritySettings, User } from '../../types';
|
import { SecuritySettings, User } from 'types';
|
||||||
import { ButtonRow, FormLoader, MessageBox, SectionContent } from '../../components';
|
import { ButtonRow, FormLoader, MessageBox, SectionContent } from 'components';
|
||||||
import { createUserValidator } from '../../validators';
|
import { createUserValidator } from 'validators';
|
||||||
import { useRest } from '../../utils';
|
import { useRest } from 'utils';
|
||||||
import { AuthenticatedContext } from '../../contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
import GenerateToken from './GenerateToken';
|
import GenerateToken from './GenerateToken';
|
||||||
import UserForm from './UserForm';
|
import UserForm from './UserForm';
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import { Navigate, Routes, Route } from 'react-router-dom';
|
|||||||
|
|
||||||
import { Tab } from '@mui/material';
|
import { Tab } from '@mui/material';
|
||||||
|
|
||||||
import { RouterTabs, useRouterTab, useLayoutTitle } from '../../components';
|
import { RouterTabs, useRouterTab, useLayoutTitle } from 'components';
|
||||||
|
|
||||||
import SecuritySettingsForm from './SecuritySettingsForm';
|
import SecuritySettingsForm from './SecuritySettingsForm';
|
||||||
import ManageUsersForm from './ManageUsersForm';
|
import ManageUsersForm from './ManageUsersForm';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const Security: FC = () => {
|
const Security: FC = () => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|||||||
@@ -5,21 +5,14 @@ import { Button } from '@mui/material';
|
|||||||
import WarningIcon from '@mui/icons-material/Warning';
|
import WarningIcon from '@mui/icons-material/Warning';
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
|
||||||
import * as SecurityApi from '../../api/security';
|
import * as SecurityApi from 'api/security';
|
||||||
import { SecuritySettings } from '../../types';
|
import { SecuritySettings } from 'types';
|
||||||
import {
|
import { ButtonRow, FormLoader, MessageBox, SectionContent, ValidatedPasswordField, BlockNavigation } from 'components';
|
||||||
ButtonRow,
|
import { SECURITY_SETTINGS_VALIDATOR, validate } from 'validators';
|
||||||
FormLoader,
|
import { updateValueDirty, useRest } from 'utils';
|
||||||
MessageBox,
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
SectionContent,
|
|
||||||
ValidatedPasswordField,
|
|
||||||
BlockNavigation
|
|
||||||
} from '../../components';
|
|
||||||
import { SECURITY_SETTINGS_VALIDATOR, validate } from '../../validators';
|
|
||||||
import { updateValueDirty, useRest } from '../../utils';
|
|
||||||
import { AuthenticatedContext } from '../../contexts/authentication';
|
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const SecuritySettingsForm: FC = () => {
|
const SecuritySettingsForm: FC = () => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ import SaveIcon from '@mui/icons-material/Save';
|
|||||||
|
|
||||||
import { Button, Checkbox, Dialog, DialogActions, DialogContent, DialogTitle } from '@mui/material';
|
import { Button, Checkbox, Dialog, DialogActions, DialogContent, DialogTitle } from '@mui/material';
|
||||||
|
|
||||||
import { BlockFormControlLabel, ValidatedPasswordField, ValidatedTextField } from '../../components';
|
import { BlockFormControlLabel, ValidatedPasswordField, ValidatedTextField } from 'components';
|
||||||
import { User } from '../../types';
|
import { User } from 'types';
|
||||||
import { updateValue } from '../../utils';
|
import { updateValue } from 'utils';
|
||||||
import { validate } from '../../validators';
|
import { validate } from 'validators';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
interface UserFormProps {
|
interface UserFormProps {
|
||||||
creating: boolean;
|
creating: boolean;
|
||||||
@@ -93,7 +93,6 @@ const UserForm: FC<UserFormProps> = ({ creating, validator, user, setUser, onDon
|
|||||||
variant="outlined"
|
variant="outlined"
|
||||||
onClick={validateAndDone}
|
onClick={validateAndDone}
|
||||||
color="primary"
|
color="primary"
|
||||||
autoFocus
|
|
||||||
>
|
>
|
||||||
{creating ? LL.ADD(0) : LL.UPDATE()}
|
{creating ? LL.ADD(0) : LL.UPDATE()}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -3,19 +3,19 @@ import { AxiosPromise } from 'axios';
|
|||||||
|
|
||||||
import { Typography, Button, Box } from '@mui/material';
|
import { Typography, Button, Box } from '@mui/material';
|
||||||
|
|
||||||
import { FileUploadConfig } from '../../api/endpoints';
|
import { FileUploadConfig } from 'api/endpoints';
|
||||||
|
|
||||||
import { SingleUpload, useFileUpload } from '../../components';
|
import { SingleUpload, useFileUpload } from 'components';
|
||||||
|
|
||||||
import DownloadIcon from '@mui/icons-material/GetApp';
|
import DownloadIcon from '@mui/icons-material/GetApp';
|
||||||
|
|
||||||
import { useSnackbar } from 'notistack';
|
import { useSnackbar } from 'notistack';
|
||||||
|
|
||||||
import { extractErrorMessage } from '../../utils';
|
import { extractErrorMessage } from 'utils';
|
||||||
|
|
||||||
import * as EMSESP from '../../project/api';
|
import * as EMSESP from 'project/api';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
interface UploadFileProps {
|
interface UploadFileProps {
|
||||||
uploadGeneralFile: (file: File, config?: FileUploadConfig) => AxiosPromise<void>;
|
uploadGeneralFile: (file: File, config?: FileUploadConfig) => AxiosPromise<void>;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { Button, Checkbox } from '@mui/material';
|
|||||||
import WarningIcon from '@mui/icons-material/Warning';
|
import WarningIcon from '@mui/icons-material/Warning';
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
|
||||||
import * as SystemApi from '../../api/system';
|
import * as SystemApi from 'api/system';
|
||||||
import {
|
import {
|
||||||
BlockFormControlLabel,
|
BlockFormControlLabel,
|
||||||
ButtonRow,
|
ButtonRow,
|
||||||
@@ -13,16 +13,16 @@ import {
|
|||||||
ValidatedPasswordField,
|
ValidatedPasswordField,
|
||||||
ValidatedTextField,
|
ValidatedTextField,
|
||||||
BlockNavigation
|
BlockNavigation
|
||||||
} from '../../components';
|
} from 'components';
|
||||||
|
|
||||||
import { OTASettings } from '../../types';
|
import { OTASettings } from 'types';
|
||||||
import { numberValue, updateValueDirty, useRest } from '../../utils';
|
import { numberValue, updateValueDirty, useRest } from 'utils';
|
||||||
|
|
||||||
import { ValidateFieldsError } from 'async-validator';
|
import { ValidateFieldsError } from 'async-validator';
|
||||||
import { validate } from '../../validators';
|
import { validate } from 'validators';
|
||||||
import { OTA_SETTINGS_VALIDATOR } from '../../validators/system';
|
import { OTA_SETTINGS_VALIDATOR } from 'validators/system';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const OTASettingsForm: FC = () => {
|
const OTASettingsForm: FC = () => {
|
||||||
const { loadData, saving, data, setData, origData, dirtyFlags, setDirtyFlags, blocker, saveData, errorMessage } =
|
const { loadData, saving, data, setData, origData, dirtyFlags, setDirtyFlags, blocker, saveData, errorMessage } =
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { useEffect } from 'react';
|
import { FC, useRef, useState, useEffect } from 'react';
|
||||||
import { FC, useRef, useState } from 'react';
|
|
||||||
|
|
||||||
import * as SystemApi from '../../api/system';
|
import * as SystemApi from 'api/system';
|
||||||
import { FormLoader } from '../../components';
|
import { FormLoader } from 'components';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const RESTART_TIMEOUT = 2 * 60 * 1000;
|
const RESTART_TIMEOUT = 2 * 60 * 1000;
|
||||||
const POLL_TIMEOUT = 2000;
|
const POLL_TIMEOUT = 2000;
|
||||||
|
|||||||
@@ -3,15 +3,15 @@ import { Navigate, Routes, Route } from 'react-router-dom';
|
|||||||
|
|
||||||
import { Tab } from '@mui/material';
|
import { Tab } from '@mui/material';
|
||||||
|
|
||||||
import { useRouterTab, RouterTabs, useLayoutTitle, RequireAdmin } from '../../components';
|
import { useRouterTab, RouterTabs, useLayoutTitle, RequireAdmin } from 'components';
|
||||||
import { AuthenticatedContext } from '../../contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
import UploadFileForm from './UploadFileForm';
|
import UploadFileForm from './UploadFileForm';
|
||||||
import SystemStatusForm from './SystemStatusForm';
|
import SystemStatusForm from './SystemStatusForm';
|
||||||
import OTASettingsForm from './OTASettingsForm';
|
import OTASettingsForm from './OTASettingsForm';
|
||||||
|
|
||||||
import SystemLog from './SystemLog';
|
import SystemLog from './SystemLog';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const System: FC = () => {
|
const System: FC = () => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|||||||
@@ -2,21 +2,21 @@ import { FC, useState, useEffect, useCallback, useLayoutEffect } from 'react';
|
|||||||
|
|
||||||
import { Box, styled, Button, Checkbox, MenuItem, Grid, Slider, FormLabel } from '@mui/material';
|
import { Box, styled, Button, Checkbox, MenuItem, Grid, Slider, FormLabel } from '@mui/material';
|
||||||
|
|
||||||
import * as SystemApi from '../../api/system';
|
import * as SystemApi from 'api/system';
|
||||||
import { addAccessTokenParameter } from '../../api/authentication';
|
import { addAccessTokenParameter } from 'api/authentication';
|
||||||
|
|
||||||
import { SectionContent, FormLoader, BlockFormControlLabel, ValidatedTextField } from '../../components';
|
import { SectionContent, FormLoader, BlockFormControlLabel, ValidatedTextField } from 'components';
|
||||||
|
|
||||||
import { LogSettings, LogEntry, LogEntries, LogLevel } from '../../types';
|
import { LogSettings, LogEntry, LogEntries, LogLevel } from 'types';
|
||||||
import { updateValue, useRest, extractErrorMessage } from '../../utils';
|
import { updateValue, useRest, extractErrorMessage } from 'utils';
|
||||||
|
|
||||||
import DownloadIcon from '@mui/icons-material/GetApp';
|
import DownloadIcon from '@mui/icons-material/GetApp';
|
||||||
|
|
||||||
import { useSnackbar } from 'notistack';
|
import { useSnackbar } from 'notistack';
|
||||||
|
|
||||||
import { EVENT_SOURCE_ROOT } from '../../api/endpoints';
|
import { EVENT_SOURCE_ROOT } from 'api/endpoints';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
export const LOG_EVENTSOURCE_URL = EVENT_SOURCE_ROOT + 'log';
|
export const LOG_EVENTSOURCE_URL = EVENT_SOURCE_ROOT + 'log';
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ const SystemLog: FC = () => {
|
|||||||
|
|
||||||
const onDownload = () => {
|
const onDownload = () => {
|
||||||
let result = '';
|
let result = '';
|
||||||
for (let i of logEntries.events) {
|
for (const i of logEntries.events) {
|
||||||
result += i.t + ' ' + levelLabel(i.l) + ' ' + i.i + ': [' + i.n + '] ' + i.m + '\n';
|
result += i.t + ' ' + levelLabel(i.l) + ' ' + i.i + ': [' + i.n + '] ' + i.m + '\n';
|
||||||
}
|
}
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
|
|||||||
@@ -31,17 +31,17 @@ import BuildIcon from '@mui/icons-material/Build';
|
|||||||
import TimerIcon from '@mui/icons-material/Timer';
|
import TimerIcon from '@mui/icons-material/Timer';
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
|
||||||
import { ButtonRow, FormLoader, SectionContent, MessageBox } from '../../components';
|
import { ButtonRow, FormLoader, SectionContent, MessageBox } from 'components';
|
||||||
import { SystemStatus, Version } from '../../types';
|
import { SystemStatus, Version } from 'types';
|
||||||
import * as SystemApi from '../../api/system';
|
import * as SystemApi from 'api/system';
|
||||||
import { extractErrorMessage, useRest } from '../../utils';
|
import { extractErrorMessage, useRest } from 'utils';
|
||||||
|
|
||||||
import { AuthenticatedContext } from '../../contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import RestartMonitor from './RestartMonitor';
|
import RestartMonitor from './RestartMonitor';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
export const VERSIONCHECK_ENDPOINT = 'https://api.github.com/repos/emsesp/EMS-ESP32/releases/latest';
|
export const VERSIONCHECK_ENDPOINT = 'https://api.github.com/repos/emsesp/EMS-ESP32/releases/latest';
|
||||||
export const VERSIONCHECK_DEV_ENDPOINT = 'https://api.github.com/repos/emsesp/EMS-ESP32/releases/tags/latest';
|
export const VERSIONCHECK_DEV_ENDPOINT = 'https://api.github.com/repos/emsesp/EMS-ESP32/releases/tags/latest';
|
||||||
@@ -131,7 +131,6 @@ const SystemStatusForm: FC = () => {
|
|||||||
onClick={restart}
|
onClick={restart}
|
||||||
disabled={processing}
|
disabled={processing}
|
||||||
color="primary"
|
color="primary"
|
||||||
autoFocus
|
|
||||||
>
|
>
|
||||||
{LL.RESTART()}
|
{LL.RESTART()}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -238,7 +237,6 @@ const SystemStatusForm: FC = () => {
|
|||||||
variant="outlined"
|
variant="outlined"
|
||||||
onClick={factoryReset}
|
onClick={factoryReset}
|
||||||
disabled={processing}
|
disabled={processing}
|
||||||
autoFocus
|
|
||||||
color="error"
|
color="error"
|
||||||
>
|
>
|
||||||
{LL.FACTORY_RESET()}
|
{LL.FACTORY_RESET()}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { FC, useRef, useState } from 'react';
|
import { FC, useRef, useState } from 'react';
|
||||||
|
|
||||||
import * as SystemApi from '../../api/system';
|
import * as SystemApi from 'api/system';
|
||||||
import { SectionContent } from '../../components';
|
import { SectionContent } from 'components';
|
||||||
import { FileUploadConfig } from '../../api/endpoints';
|
import { FileUploadConfig } from 'api/endpoints';
|
||||||
|
|
||||||
import GeneralFileUpload from './GeneralFileUpload';
|
import GeneralFileUpload from './GeneralFileUpload';
|
||||||
import RestartMonitor from './RestartMonitor';
|
import RestartMonitor from './RestartMonitor';
|
||||||
|
|
||||||
import { useI18nContext } from '../../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const UploadFileForm: FC = () => {
|
const UploadFileForm: FC = () => {
|
||||||
const [restarting, setRestarting] = useState<boolean>();
|
const [restarting, setRestarting] = useState<boolean>();
|
||||||
|
|||||||
0
interface/src/i18n/FR.svg
Executable file → Normal file
0
interface/src/i18n/FR.svg
Executable file → Normal file
|
Before Width: | Height: | Size: 243 B After Width: | Height: | Size: 243 B |
@@ -2,9 +2,9 @@ import React from 'react';
|
|||||||
import ReactDOM from 'react-dom/client';
|
import ReactDOM from 'react-dom/client';
|
||||||
import { createBrowserRouter, createRoutesFromElements, Route, RouterProvider } from 'react-router-dom';
|
import { createBrowserRouter, createRoutesFromElements, Route, RouterProvider } from 'react-router-dom';
|
||||||
|
|
||||||
import App from './App';
|
import App from 'App';
|
||||||
|
|
||||||
const router = createBrowserRouter(createRoutesFromElements(<Route path="/*" element={<App />}></Route>));
|
const router = createBrowserRouter(createRoutesFromElements(<Route path="/*" element={<App />} />));
|
||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import { Navigate, Route, Routes } from 'react-router-dom';
|
|||||||
|
|
||||||
import { Tab } from '@mui/material';
|
import { Tab } from '@mui/material';
|
||||||
|
|
||||||
import { RouterTabs, useRouterTab, useLayoutTitle } from '../components';
|
import { RouterTabs, useRouterTab, useLayoutTitle } from 'components';
|
||||||
|
|
||||||
import { useI18nContext } from '../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
import DashboardStatus from './DashboardStatus';
|
import DashboardStatus from './DashboardStatus';
|
||||||
import DashboardData from './DashboardData';
|
import DashboardData from './DashboardData';
|
||||||
|
|||||||
@@ -22,10 +22,9 @@ import {
|
|||||||
|
|
||||||
import { useSnackbar } from 'notistack';
|
import { useSnackbar } from 'notistack';
|
||||||
|
|
||||||
import { Table } from '@table-library/react-table-library/table';
|
|
||||||
import { useTheme } from '@table-library/react-table-library/theme';
|
import { useTheme } from '@table-library/react-table-library/theme';
|
||||||
import { useSort, SortToggleType } from '@table-library/react-table-library/sort';
|
import { useSort, SortToggleType } from '@table-library/react-table-library/sort';
|
||||||
import { Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
|
import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
|
||||||
import { useRowSelect } from '@table-library/react-table-library/select';
|
import { useRowSelect } from '@table-library/react-table-library/select';
|
||||||
|
|
||||||
import DownloadIcon from '@mui/icons-material/GetApp';
|
import DownloadIcon from '@mui/icons-material/GetApp';
|
||||||
@@ -49,13 +48,13 @@ import DeviceIcon from './DeviceIcon';
|
|||||||
|
|
||||||
import { IconContext } from 'react-icons';
|
import { IconContext } from 'react-icons';
|
||||||
|
|
||||||
import { AuthenticatedContext } from '../contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
|
|
||||||
import { ButtonRow, ValidatedTextField, SectionContent, MessageBox } from '../components';
|
import { ButtonRow, ValidatedTextField, SectionContent, MessageBox } from 'components';
|
||||||
|
|
||||||
import * as EMSESP from './api';
|
import * as EMSESP from './api';
|
||||||
|
|
||||||
import { numberValue, updateValue, extractErrorMessage } from '../utils';
|
import { numberValue, updateValue, extractErrorMessage } from 'utils';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
SensorData,
|
SensorData,
|
||||||
@@ -72,7 +71,7 @@ import {
|
|||||||
DeviceEntityMask
|
DeviceEntityMask
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
import { useI18nContext } from '../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
const DashboardData: FC = () => {
|
const DashboardData: FC = () => {
|
||||||
const { me } = useContext(AuthenticatedContext);
|
const { me } = useContext(AuthenticatedContext);
|
||||||
@@ -502,7 +501,9 @@ const DashboardData: FC = () => {
|
|||||||
onChange={updateValue(setDeviceValue)}
|
onChange={updateValue(setDeviceValue)}
|
||||||
>
|
>
|
||||||
{deviceValue.l.map((val) => (
|
{deviceValue.l.map((val) => (
|
||||||
<MenuItem value={val}>{val}</MenuItem>
|
<MenuItem value={val} key={val}>
|
||||||
|
{val}
|
||||||
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
</ValidatedTextField>
|
</ValidatedTextField>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -16,9 +16,8 @@ import {
|
|||||||
useTheme
|
useTheme
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
|
|
||||||
import { Table } from '@table-library/react-table-library/table';
|
|
||||||
import { useTheme as tableTheme } from '@table-library/react-table-library/theme';
|
import { useTheme as tableTheme } from '@table-library/react-table-library/theme';
|
||||||
import { Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
|
import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
|
||||||
|
|
||||||
import DeviceHubIcon from '@mui/icons-material/DeviceHub';
|
import DeviceHubIcon from '@mui/icons-material/DeviceHub';
|
||||||
import RefreshIcon from '@mui/icons-material/Refresh';
|
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||||
@@ -26,18 +25,18 @@ import PermScanWifiIcon from '@mui/icons-material/PermScanWifi';
|
|||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
import DirectionsBusIcon from '@mui/icons-material/DirectionsBus';
|
import DirectionsBusIcon from '@mui/icons-material/DirectionsBus';
|
||||||
|
|
||||||
import { AuthenticatedContext } from '../contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
|
|
||||||
import { ButtonRow, FormLoader, SectionContent } from '../components';
|
import { ButtonRow, FormLoader, SectionContent } from 'components';
|
||||||
|
|
||||||
import { Status, busConnectionStatus, Stat } from './types';
|
import { Status, busConnectionStatus, Stat } from './types';
|
||||||
|
|
||||||
import { extractErrorMessage, useRest } from '../utils';
|
import { extractErrorMessage, useRest } from 'utils';
|
||||||
|
|
||||||
import * as EMSESP from './api';
|
import * as EMSESP from './api';
|
||||||
|
|
||||||
import type { Translation } from '../i18n/i18n-types';
|
import type { Translation } from 'i18n/i18n-types';
|
||||||
import { useI18nContext } from '../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
export const isConnected = ({ status }: Status) => status !== busConnectionStatus.BUS_STATUS_OFFLINE;
|
export const isConnected = ({ status }: Status) => status !== busConnectionStatus.BUS_STATUS_OFFLINE;
|
||||||
|
|
||||||
@@ -80,7 +79,7 @@ const DashboardStatus: FC = () => {
|
|||||||
const { me } = useContext(AuthenticatedContext);
|
const { me } = useContext(AuthenticatedContext);
|
||||||
|
|
||||||
const showName = (id: any) => {
|
const showName = (id: any) => {
|
||||||
let name: keyof Translation['STATUS_NAMES'] = id;
|
const name: keyof Translation['STATUS_NAMES'] = id;
|
||||||
return LL.STATUS_NAMES[name]();
|
return LL.STATUS_NAMES[name]();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -183,7 +182,7 @@ const DashboardStatus: FC = () => {
|
|||||||
<Button startIcon={<CancelIcon />} variant="outlined" onClick={() => setConfirmScan(false)} color="secondary">
|
<Button startIcon={<CancelIcon />} variant="outlined" onClick={() => setConfirmScan(false)} color="secondary">
|
||||||
{LL.CANCEL()}
|
{LL.CANCEL()}
|
||||||
</Button>
|
</Button>
|
||||||
<Button startIcon={<PermScanWifiIcon />} variant="outlined" onClick={scan} color="primary" autoFocus>
|
<Button startIcon={<PermScanWifiIcon />} variant="outlined" onClick={scan} color="primary">
|
||||||
{LL.SCAN()}
|
{LL.SCAN()}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
@@ -226,13 +225,13 @@ const DashboardStatus: FC = () => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<Box m={3}></Box>
|
<Box m={3} />
|
||||||
<Table data={{ nodes: data.stats }} theme={stats_theme} layout={{ custom: true }}>
|
<Table data={{ nodes: data.stats }} theme={stats_theme} layout={{ custom: true }}>
|
||||||
{(tableList: any) => (
|
{(tableList: any) => (
|
||||||
<>
|
<>
|
||||||
<Header>
|
<Header>
|
||||||
<HeaderRow>
|
<HeaderRow>
|
||||||
<HeaderCell resize></HeaderCell>
|
<HeaderCell resize />
|
||||||
<HeaderCell stiff>{LL.SUCCESS()}</HeaderCell>
|
<HeaderCell stiff>{LL.SUCCESS()}</HeaderCell>
|
||||||
<HeaderCell stiff>{LL.FAIL()}</HeaderCell>
|
<HeaderCell stiff>{LL.FAIL()}</HeaderCell>
|
||||||
<HeaderCell stiff>{LL.QUALITY()}</HeaderCell>
|
<HeaderCell stiff>{LL.QUALITY()}</HeaderCell>
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
|
|
||||||
import { CgSmartHomeBoiler } from 'react-icons/cg';
|
import { CgSmartHomeBoiler } from 'react-icons/cg';
|
||||||
import { MdOutlineSensors } from 'react-icons/md';
|
|
||||||
import { FaSolarPanel } from 'react-icons/fa';
|
import { FaSolarPanel } from 'react-icons/fa';
|
||||||
import { MdThermostatAuto } from 'react-icons/md';
|
import { MdThermostatAuto, MdOutlineSensors } from 'react-icons/md';
|
||||||
import { AiOutlineControl } from 'react-icons/ai';
|
|
||||||
import { GiHeatHaze } from 'react-icons/gi';
|
import { GiHeatHaze } from 'react-icons/gi';
|
||||||
import { TiFlowSwitch } from 'react-icons/ti';
|
import { TiFlowSwitch } from 'react-icons/ti';
|
||||||
import { VscVmConnect } from 'react-icons/vsc';
|
import { VscVmConnect } from 'react-icons/vsc';
|
||||||
import { AiOutlineGateway } from 'react-icons/ai';
|
import { AiOutlineControl, AiOutlineGateway, AiOutlineAlert, AiOutlineChrome } from 'react-icons/ai';
|
||||||
import { AiOutlineAlert } from 'react-icons/ai';
|
|
||||||
import { AiOutlineChrome } from 'react-icons/ai';
|
|
||||||
|
|
||||||
interface DeviceIconProps {
|
interface DeviceIconProps {
|
||||||
type_id: number;
|
type_id: number;
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import { Navigate, Route, Routes } from 'react-router-dom';
|
|||||||
|
|
||||||
import { Tab } from '@mui/material';
|
import { Tab } from '@mui/material';
|
||||||
|
|
||||||
import { RouterTabs, useRouterTab, useLayoutTitle } from '../components';
|
import { RouterTabs, useRouterTab, useLayoutTitle } from 'components';
|
||||||
|
|
||||||
import { useI18nContext } from '../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
import HelpInformation from './HelpInformation';
|
import HelpInformation from './HelpInformation';
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { FC } from 'react';
|
|||||||
|
|
||||||
import { Typography, Button, Box, List, ListItem, ListItemText, Link, ListItemAvatar } from '@mui/material';
|
import { Typography, Button, Box, List, ListItem, ListItemText, Link, ListItemAvatar } from '@mui/material';
|
||||||
|
|
||||||
import { SectionContent } from '../components';
|
import { SectionContent } from 'components';
|
||||||
|
|
||||||
import { useSnackbar } from 'notistack';
|
import { useSnackbar } from 'notistack';
|
||||||
|
|
||||||
@@ -12,9 +12,9 @@ import GitHubIcon from '@mui/icons-material/GitHub';
|
|||||||
import DownloadIcon from '@mui/icons-material/GetApp';
|
import DownloadIcon from '@mui/icons-material/GetApp';
|
||||||
import EastIcon from '@mui/icons-material/East';
|
import EastIcon from '@mui/icons-material/East';
|
||||||
|
|
||||||
import { extractErrorMessage } from '../utils';
|
import { extractErrorMessage } from 'utils';
|
||||||
|
|
||||||
import { useI18nContext } from '../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
import * as EMSESP from './api';
|
import * as EMSESP from './api';
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,15 @@ import { FC, useContext } from 'react';
|
|||||||
|
|
||||||
import { List } from '@mui/material';
|
import { List } from '@mui/material';
|
||||||
|
|
||||||
import { AuthenticatedContext } from '../contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
|
|
||||||
import { PROJECT_PATH } from '../api/env';
|
import { PROJECT_PATH } from 'api/env';
|
||||||
|
|
||||||
import { useI18nContext } from '../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
import TuneIcon from '@mui/icons-material/Tune';
|
import TuneIcon from '@mui/icons-material/Tune';
|
||||||
import DashboardIcon from '@mui/icons-material/Dashboard';
|
import DashboardIcon from '@mui/icons-material/Dashboard';
|
||||||
import LayoutMenuItem from '../components/layout/LayoutMenuItem';
|
import LayoutMenuItem from 'components/layout/LayoutMenuItem';
|
||||||
import InfoIcon from '@mui/icons-material/Info';
|
import InfoIcon from '@mui/icons-material/Info';
|
||||||
|
|
||||||
const ProjectMenu: FC = () => {
|
const ProjectMenu: FC = () => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { Navigate, Routes, Route } from 'react-router-dom';
|
import { Navigate, Routes, Route } from 'react-router-dom';
|
||||||
|
|
||||||
import { RequireAdmin } from '../components';
|
import { RequireAdmin } from 'components';
|
||||||
|
|
||||||
import Dashboard from './Dashboard';
|
import Dashboard from './Dashboard';
|
||||||
import Settings from './Settings';
|
import Settings from './Settings';
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import { Navigate, Route, Routes } from 'react-router-dom';
|
|||||||
|
|
||||||
import { Tab } from '@mui/material';
|
import { Tab } from '@mui/material';
|
||||||
|
|
||||||
import { RouterTabs, useRouterTab, useLayoutTitle } from '../components';
|
import { RouterTabs, useRouterTab, useLayoutTitle } from 'components';
|
||||||
|
|
||||||
import { useI18nContext } from '../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
import SettingsApplication from './SettingsApplication';
|
import SettingsApplication from './SettingsApplication';
|
||||||
import SettingsCustomization from './SettingsCustomization';
|
import SettingsCustomization from './SettingsCustomization';
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import WarningIcon from '@mui/icons-material/Warning';
|
|||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew';
|
import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew';
|
||||||
|
|
||||||
import { validate } from '../validators';
|
import { validate } from 'validators';
|
||||||
import { createSettingsValidator } from './validators';
|
import { createSettingsValidator } from './validators';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -20,14 +20,14 @@ import {
|
|||||||
ButtonRow,
|
ButtonRow,
|
||||||
MessageBox,
|
MessageBox,
|
||||||
BlockNavigation
|
BlockNavigation
|
||||||
} from '../components';
|
} from 'components';
|
||||||
import { numberValue, extractErrorMessage, updateValueDirty, useRest } from '../utils';
|
import { numberValue, extractErrorMessage, updateValueDirty, useRest } from 'utils';
|
||||||
|
|
||||||
import * as EMSESP from './api';
|
import * as EMSESP from './api';
|
||||||
import { Settings, BOARD_PROFILES } from './types';
|
import { Settings, BOARD_PROFILES } from './types';
|
||||||
|
|
||||||
import { useI18nContext } from '../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import RestartMonitor from '../framework/system/RestartMonitor';
|
import RestartMonitor from 'framework/system/RestartMonitor';
|
||||||
|
|
||||||
export function boardProfileSelectItems() {
|
export function boardProfileSelectItems() {
|
||||||
return Object.keys(BOARD_PROFILES).map((code) => (
|
return Object.keys(BOARD_PROFILES).map((code) => (
|
||||||
@@ -505,9 +505,9 @@ const SettingsApplication: FC = () => {
|
|||||||
>
|
>
|
||||||
<MenuItem value={1}>{LL.ONOFF()}</MenuItem>
|
<MenuItem value={1}>{LL.ONOFF()}</MenuItem>
|
||||||
<MenuItem value={2}>{LL.ONOFF_CAP()}</MenuItem>
|
<MenuItem value={2}>{LL.ONOFF_CAP()}</MenuItem>
|
||||||
<MenuItem value={3}>"true"/"false"</MenuItem>
|
<MenuItem value={3}>"true"/"false"</MenuItem>
|
||||||
<MenuItem value={4}>true/false</MenuItem>
|
<MenuItem value={4}>true/false</MenuItem>
|
||||||
<MenuItem value={5}>"1"/"0"</MenuItem>
|
<MenuItem value={5}>"1"/"0"</MenuItem>
|
||||||
<MenuItem value={6}>1/0</MenuItem>
|
<MenuItem value={6}>1/0</MenuItem>
|
||||||
</ValidatedTextField>
|
</ValidatedTextField>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -19,9 +19,8 @@ import {
|
|||||||
Link
|
Link
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
|
|
||||||
import { Table } from '@table-library/react-table-library/table';
|
|
||||||
import { useTheme } from '@table-library/react-table-library/theme';
|
import { useTheme } from '@table-library/react-table-library/theme';
|
||||||
import { Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
|
import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
|
||||||
|
|
||||||
import { useSnackbar } from 'notistack';
|
import { useSnackbar } from 'notistack';
|
||||||
|
|
||||||
@@ -36,17 +35,17 @@ import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew';
|
|||||||
|
|
||||||
import OptionIcon from './OptionIcon';
|
import OptionIcon from './OptionIcon';
|
||||||
|
|
||||||
import { ButtonRow, FormLoader, ValidatedTextField, SectionContent, MessageBox, BlockNavigation } from '../components';
|
import { ButtonRow, FormLoader, ValidatedTextField, SectionContent, MessageBox, BlockNavigation } from 'components';
|
||||||
|
|
||||||
import * as EMSESP from './api';
|
import * as EMSESP from './api';
|
||||||
|
|
||||||
import { extractErrorMessage, updateValue } from '../utils';
|
import { extractErrorMessage, updateValue } from 'utils';
|
||||||
|
|
||||||
import { DeviceShort, Devices, DeviceEntity, DeviceEntityMask } from './types';
|
import { DeviceShort, Devices, DeviceEntity, DeviceEntityMask } from './types';
|
||||||
|
|
||||||
import { useI18nContext } from '../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
import RestartMonitor from '../framework/system/RestartMonitor';
|
import RestartMonitor from 'framework/system/RestartMonitor';
|
||||||
|
|
||||||
export const APIURL = window.location.origin + '/api/';
|
export const APIURL = window.location.origin + '/api/';
|
||||||
|
|
||||||
@@ -57,7 +56,7 @@ const SettingsCustomization: FC = () => {
|
|||||||
const emptyDeviceEntity = { id: '', v: 0, n: '', cn: '', m: 0, w: false };
|
const emptyDeviceEntity = { id: '', v: 0, n: '', cn: '', m: 0, w: false };
|
||||||
|
|
||||||
const [numChanges, setNumChanges] = useState<number>(0);
|
const [numChanges, setNumChanges] = useState<number>(0);
|
||||||
let blocker = useBlocker(numChanges !== 0);
|
const blocker = useBlocker(numChanges !== 0);
|
||||||
|
|
||||||
const [restarting, setRestarting] = useState<boolean>(false);
|
const [restarting, setRestarting] = useState<boolean>(false);
|
||||||
const [restartNeeded, setRestartNeeded] = useState<boolean>(false);
|
const [restartNeeded, setRestartNeeded] = useState<boolean>(false);
|
||||||
@@ -201,15 +200,15 @@ const SettingsCustomization: FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getMaskNumber = (newMask: string[]) => {
|
const getMaskNumber = (newMask: string[]) => {
|
||||||
var new_mask = 0;
|
let new_mask = 0;
|
||||||
for (let entry of newMask) {
|
for (const entry of newMask) {
|
||||||
new_mask |= Number(entry);
|
new_mask |= Number(entry);
|
||||||
}
|
}
|
||||||
return new_mask;
|
return new_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getMaskString = (m: number) => {
|
const getMaskString = (m: number) => {
|
||||||
var new_masks = [];
|
let new_masks: string[] = [];
|
||||||
if ((m & 1) === 1) {
|
if ((m & 1) === 1) {
|
||||||
new_masks.push('1');
|
new_masks.push('1');
|
||||||
}
|
}
|
||||||
@@ -561,7 +560,6 @@ const SettingsCustomization: FC = () => {
|
|||||||
</ToggleButtonGroup>
|
</ToggleButtonGroup>
|
||||||
)}
|
)}
|
||||||
</Cell>
|
</Cell>
|
||||||
|
|
||||||
<Cell>{!deviceEntity && formatName(de)}</Cell>
|
<Cell>{!deviceEntity && formatName(de)}</Cell>
|
||||||
<Cell>{!deviceEntity && !(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.mi)}</Cell>
|
<Cell>{!deviceEntity && !(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.mi)}</Cell>
|
||||||
<Cell>{!deviceEntity && !(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.ma)}</Cell>
|
<Cell>{!deviceEntity && !(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.ma)}</Cell>
|
||||||
@@ -584,13 +582,7 @@ const SettingsCustomization: FC = () => {
|
|||||||
<Button startIcon={<CancelIcon />} variant="outlined" onClick={() => setConfirmReset(false)} color="secondary">
|
<Button startIcon={<CancelIcon />} variant="outlined" onClick={() => setConfirmReset(false)} color="secondary">
|
||||||
{LL.CANCEL()}
|
{LL.CANCEL()}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button startIcon={<SettingsBackupRestoreIcon />} variant="outlined" onClick={resetCustomization} color="error">
|
||||||
startIcon={<SettingsBackupRestoreIcon />}
|
|
||||||
variant="outlined"
|
|
||||||
onClick={resetCustomization}
|
|
||||||
autoFocus
|
|
||||||
color="error"
|
|
||||||
>
|
|
||||||
{LL.RESET(0)}
|
{LL.RESET(0)}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { AxiosPromise } from 'axios';
|
import { AxiosPromise } from 'axios';
|
||||||
import { AXIOS, AXIOS_API, AXIOS_BIN } from '../api/endpoints';
|
import { AXIOS, AXIOS_API, AXIOS_BIN } from 'api/endpoints';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BoardProfile,
|
BoardProfile,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import Schema, { InternalRuleItem } from 'async-validator';
|
import Schema, { InternalRuleItem } from 'async-validator';
|
||||||
import { IP_OR_HOSTNAME_VALIDATOR } from '../validators/shared';
|
import { IP_OR_HOSTNAME_VALIDATOR } from 'validators/shared';
|
||||||
import { Settings } from './types';
|
import { Settings } from './types';
|
||||||
|
|
||||||
export const GPIO_VALIDATOR = {
|
export const GPIO_VALIDATOR = {
|
||||||
|
|||||||
1
interface/src/react-app-env.d.ts
vendored
1
interface/src/react-app-env.d.ts
vendored
@@ -1 +0,0 @@
|
|||||||
/// <reference types="react-scripts" />
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
const pkg = require('../package.json');
|
|
||||||
const { createProxyMiddleware } = require('http-proxy-middleware');
|
|
||||||
const target = process.env.PROXY || pkg.proxy;
|
|
||||||
|
|
||||||
module.exports = function (app) {
|
|
||||||
app.use(
|
|
||||||
createProxyMiddleware('/api', {
|
|
||||||
target
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// app.use(
|
|
||||||
// createProxyMiddleware('/ws', {
|
|
||||||
// target: target,
|
|
||||||
// // target: target.replace(/^http(s?):\/\//, 'ws$1://'),
|
|
||||||
// ws: true
|
|
||||||
// })
|
|
||||||
// );
|
|
||||||
};
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import { useBeforeUnload, unstable_useBlocker as useBlocker } from 'react-router-dom';
|
|
||||||
|
|
||||||
// You can abstract `useBlocker` to use the browser's `window.confirm` dialog to
|
|
||||||
// determine whether or not the user should navigate within the current origin.
|
|
||||||
// `useBlocker` can also be used in conjunction with `useBeforeUnload` to
|
|
||||||
// prevent navigation away from the current origin.
|
|
||||||
//
|
|
||||||
// IMPORTANT: There are edge cases with this behavior in which React Router
|
|
||||||
// cannot reliably access the correct location in the history stack. In such
|
|
||||||
// cases the user may attempt to stay on the page but the app navigates anyway,
|
|
||||||
// or the app may stay on the correct page but the browser's history stack gets
|
|
||||||
// out of whack. You should test your own implementation thoroughly to make sure
|
|
||||||
// the tradeoffs are right for your users.
|
|
||||||
export default function usePrompt(
|
|
||||||
message: string | null | undefined | false,
|
|
||||||
{ beforeUnload }: { beforeUnload?: boolean } = {}
|
|
||||||
) {
|
|
||||||
let blocker = useBlocker(
|
|
||||||
React.useCallback(() => (typeof message === 'string' ? !window.confirm(message) : false), [message])
|
|
||||||
);
|
|
||||||
let prevState = React.useRef(blocker.state);
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (blocker.state === 'blocked') {
|
|
||||||
blocker.reset();
|
|
||||||
}
|
|
||||||
prevState.current = blocker.state;
|
|
||||||
}, [blocker]);
|
|
||||||
|
|
||||||
useBeforeUnload(
|
|
||||||
React.useCallback(
|
|
||||||
(event) => {
|
|
||||||
if (beforeUnload && typeof message === 'string') {
|
|
||||||
event.preventDefault();
|
|
||||||
event.returnValue = message;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[message, beforeUnload]
|
|
||||||
),
|
|
||||||
{ capture: true }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,7 @@ import { AxiosPromise } from 'axios';
|
|||||||
|
|
||||||
import { extractErrorMessage } from '.';
|
import { extractErrorMessage } from '.';
|
||||||
|
|
||||||
import { useI18nContext } from '../i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
import { unstable_useBlocker as useBlocker } from 'react-router-dom';
|
import { unstable_useBlocker as useBlocker } from 'react-router-dom';
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ export const useRest = <D>({ read, update }: RestRequestOptions<D>) => {
|
|||||||
const [origData, setOrigData] = useState<D>();
|
const [origData, setOrigData] = useState<D>();
|
||||||
const [dirtyFlags, setDirtyFlags] = useState<string[]>();
|
const [dirtyFlags, setDirtyFlags] = useState<string[]>();
|
||||||
|
|
||||||
let blocker = useBlocker(dirtyFlags?.length !== 0);
|
const blocker = useBlocker(dirtyFlags?.length !== 0);
|
||||||
|
|
||||||
const loadData = useCallback(async () => {
|
const loadData = useCallback(async () => {
|
||||||
setData(undefined);
|
setData(undefined);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useCallback, useEffect, useRef, useState } from 'react';
|
|||||||
import Sockette from 'sockette';
|
import Sockette from 'sockette';
|
||||||
import { debounce } from 'lodash-es';
|
import { debounce } from 'lodash-es';
|
||||||
|
|
||||||
import { addAccessTokenParameter } from '../api/authentication';
|
import { addAccessTokenParameter } from 'api/authentication';
|
||||||
|
|
||||||
interface WebSocketIdMessage {
|
interface WebSocketIdMessage {
|
||||||
type: 'id';
|
type: 'id';
|
||||||
@@ -17,7 +17,7 @@ interface WebSocketPayloadMessage<D> {
|
|||||||
|
|
||||||
export type WebSocketMessage<D> = WebSocketIdMessage | WebSocketPayloadMessage<D>;
|
export type WebSocketMessage<D> = WebSocketIdMessage | WebSocketPayloadMessage<D>;
|
||||||
|
|
||||||
export const useWs = <D>(wsUrl: string, wsThrottle: number = 100) => {
|
export const useWs = <D>(wsUrl: string, wsThrottle = 100) => {
|
||||||
const ws = useRef<Sockette>();
|
const ws = useRef<Sockette>();
|
||||||
const clientId = useRef<string>();
|
const clientId = useRef<string>();
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ export const useWs = <D>(wsUrl: string, wsThrottle: number = 100) => {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const doSaveData = useCallback((newData: D, clearData: boolean = false) => {
|
const doSaveData = useCallback((newData: D, clearData = false) => {
|
||||||
if (!ws.current) {
|
if (!ws.current) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -55,11 +55,7 @@ export const useWs = <D>(wsUrl: string, wsThrottle: number = 100) => {
|
|||||||
|
|
||||||
const saveData = useRef(debounce(doSaveData, wsThrottle));
|
const saveData = useRef(debounce(doSaveData, wsThrottle));
|
||||||
|
|
||||||
const updateData = (
|
const updateData = (newData: React.SetStateAction<D | undefined>, transmitData: true, clearData: false) => {
|
||||||
newData: React.SetStateAction<D | undefined>,
|
|
||||||
transmitData: boolean = true,
|
|
||||||
clearData: boolean = false
|
|
||||||
) => {
|
|
||||||
setData(newData);
|
setData(newData);
|
||||||
setTransmit(transmitData);
|
setTransmit(transmitData);
|
||||||
setClear(clearData);
|
setClear(clearData);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Schema from 'async-validator';
|
import Schema from 'async-validator';
|
||||||
import { isAPEnabled } from '../framework/ap/APSettingsForm';
|
import { isAPEnabled } from 'framework/ap/APSettingsForm';
|
||||||
import { APSettings } from '../types';
|
import { APSettings } from 'types';
|
||||||
import { IP_ADDRESS_VALIDATOR } from './shared';
|
import { IP_ADDRESS_VALIDATOR } from './shared';
|
||||||
|
|
||||||
export const createAPSettingsValidator = (apSettings: APSettings) =>
|
export const createAPSettingsValidator = (apSettings: APSettings) =>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import Schema from 'async-validator';
|
import Schema from 'async-validator';
|
||||||
import { MqttSettings } from '../types';
|
import { MqttSettings } from 'types';
|
||||||
import { IP_OR_HOSTNAME_VALIDATOR } from './shared';
|
import { IP_OR_HOSTNAME_VALIDATOR } from './shared';
|
||||||
|
|
||||||
export const createMqttSettingsValidator = (mqttSettings: MqttSettings) =>
|
export const createMqttSettingsValidator = (mqttSettings: MqttSettings) =>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import Schema from 'async-validator';
|
import Schema from 'async-validator';
|
||||||
import { NetworkSettings } from '../types';
|
import { NetworkSettings } from 'types';
|
||||||
import { HOSTNAME_VALIDATOR, IP_ADDRESS_VALIDATOR } from './shared';
|
import { HOSTNAME_VALIDATOR, IP_ADDRESS_VALIDATOR } from './shared';
|
||||||
|
|
||||||
export const createNetworkSettingsValidator = (networkSettings: NetworkSettings) =>
|
export const createNetworkSettingsValidator = (networkSettings: NetworkSettings) =>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user