Converted to Vite since create-react-app is no longer being developed

This commit is contained in:
Jamie Curnow 2023-07-20 15:11:41 +10:00
parent 824a22efad
commit 6d6021c9bb
No known key found for this signature in database
GPG Key ID: FFBB624C43388E9E
115 changed files with 2511 additions and 10015 deletions

View File

@ -34,6 +34,6 @@ server {
proxy_set_header X-Forwarded-Scheme $scheme; proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://127.0.0.1:9000; proxy_pass http://127.0.0.1:5173;
} }
} }

View File

@ -20,7 +20,7 @@ if [ "$(is_true "$DEVELOPMENT")" = '1' ]; then
log_info 'Starting frontend ...' log_info 'Starting frontend ...'
s6-setuidgid "$PUID:$PGID" yarn install s6-setuidgid "$PUID:$PGID" yarn install
exec s6-setuidgid "$PUID:$PGID" yarn start exec s6-setuidgid "$PUID:$PGID" yarn dev
else else
exit 0 exit 0
fi fi

View File

@ -1,4 +0,0 @@
PORT=9000
IMAGE_INLINE_SIZE_LIMIT=20000
REACT_APP_VERSION=development
REACT_APP_COMMIT=local

View File

@ -1,123 +0,0 @@
{
"parser": "@typescript-eslint/parser",
"plugins": [
"prettier",
],
"extends": [
"react-app",
"eslint-config-prettier",
"plugin:prettier/recommended",
"prettier"
],
"env": {
"jest": true,
"browser": true,
"commonjs": true
},
"rules": {
"prettier/prettier": [
"error"
],
"@typescript-eslint/ban-ts-comment": [
"error",
{
"ts-ignore": "allow-with-description"
}
],
"@typescript-eslint/consistent-type-definitions": [
"error",
"interface"
],
"@typescript-eslint/explicit-function-return-type": [
"off"
],
"@typescript-eslint/explicit-module-boundary-types": [
"off"
],
"@typescript-eslint/explicit-member-accessibility": [
"off"
],
"@typescript-eslint/no-empty-function": [
"off"
],
"@typescript-eslint/no-explicit-any": [
"off"
],
"@typescript-eslint/no-non-null-assertion": [
"off"
],
"@typescript-eslint/naming-convention": [
"error",
{
"selector": "default",
"format": [
"camelCase",
"PascalCase",
"UPPER_CASE"
],
"leadingUnderscore": "allow",
"trailingUnderscore": "allow"
}
],
"react-hooks/rules-of-hooks": [
"error"
],
"react-hooks/exhaustive-deps": [
"warn",
{
"additionalHooks": "useAction|useReduxAction"
}
],
"react/jsx-curly-brace-presence": [
"warn",
{
"props": "never",
"children": "never",
}
],
"no-restricted-globals": [
"off"
],
"import/extensions": 0, // We let webpack handle resolving file extensions
"import/order": [
"error",
{
"alphabetize": {
"order": "asc",
"caseInsensitive": true
},
"newlines-between": "always",
"pathGroups": [
{
"pattern": "@(react)",
"group": "external",
"position": "before"
},
{
"pattern": "@/@(fixtures|jest)/**",
"group": "internal",
"position": "before"
},
{
"pattern": "@/**",
"group": "internal"
}
],
"pathGroupsExcludedImportTypes": [
"builtin",
"internal"
],
"groups": [
"builtin",
"external",
"internal",
[
"parent",
"sibling",
"index"
]
]
}
]
}
}

113
frontend/.eslintrc.cjs Normal file
View File

@ -0,0 +1,113 @@
module.exports = {
env: {
browser: true,
es2020: true,
},
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"plugin:prettier/recommended",
"plugin:react/recommended",
"prettier",
],
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
},
plugins: ["react-refresh"],
settings: {
"import/resolver": {
// You will also need to install and configure the TypeScript resolver
// See also https://github.com/import-js/eslint-import-resolver-typescript#configuration
typescript: true,
node: true,
},
},
rules: {
"import/default": 0,
"import/no-named-as-default-member": 0,
"import/no-named-as-default": 0,
"react-refresh/only-export-components": 0,
"react/react-in-jsx-scope": 0,
"prettier/prettier": ["error"],
"@typescript-eslint/ban-ts-comment": [
"error",
{
"ts-ignore": "allow-with-description",
},
],
"@typescript-eslint/consistent-type-definitions": ["error", "interface"],
"@typescript-eslint/explicit-function-return-type": ["off"],
"@typescript-eslint/explicit-module-boundary-types": ["off"],
"@typescript-eslint/explicit-member-accessibility": ["off"],
"@typescript-eslint/no-empty-function": ["off"],
"@typescript-eslint/no-explicit-any": ["off"],
"@typescript-eslint/no-non-null-assertion": ["off"],
"@typescript-eslint/naming-convention": [
"error",
{
selector: "default",
format: ["camelCase", "PascalCase", "UPPER_CASE"],
leadingUnderscore: "allow",
trailingUnderscore: "allow",
filter: {
regex: "^(2xl)$",
match: false,
},
},
],
"react-hooks/rules-of-hooks": ["error"],
"react-hooks/exhaustive-deps": [
"warn",
{
additionalHooks: "useAction|useReduxAction",
},
],
"react/jsx-curly-brace-presence": [
"warn",
{
props: "never",
children: "never",
},
],
"no-restricted-globals": ["off"],
"import/extensions": 0, // We let webpack handle resolving file extensions
"import/order": [
"error",
{
alphabetize: {
order: "asc",
caseInsensitive: true,
},
"newlines-between": "always",
pathGroups: [
{
pattern: "@(react)",
group: "external",
position: "before",
},
{
pattern: "@/@(fixtures|jest)/**",
group: "internal",
position: "before",
},
{
pattern: "@/**",
group: "internal",
},
],
pathGroupsExcludedImportTypes: ["builtin", "internal"],
groups: [
"builtin",
"external",
"internal",
["parent", "sibling", "index"],
],
},
],
},
};

View File

@ -1,18 +1,16 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta <meta
name="viewport" name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
/>
<title>Nginx Proxy Manager</title> <title>Nginx Proxy Manager</title>
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" />
<meta http-equiv="Content-Language" content="en" /> <meta http-equiv="Content-Language" content="en" />
<meta <meta
name="apple-mobile-web-app-status-bar-style" name="apple-mobile-web-app-status-bar-style"
content="black-translucent" content="black-translucent" />
/>
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="mobile-web-app-capable" content="yes" /> <meta name="mobile-web-app-capable" content="yes" />
<meta name="HandheldFriendly" content="True" /> <meta name="HandheldFriendly" content="True" />
@ -20,36 +18,32 @@
<link <link
rel="apple-touch-icon" rel="apple-touch-icon"
sizes="180x180" sizes="180x180"
href="/images/favicon/apple-touch-icon.png" href="/images/favicon/apple-touch-icon.png" />
/>
<link <link
rel="icon" rel="icon"
type="image/png" type="image/png"
sizes="32x32" sizes="32x32"
href="/images/favicon/favicon-32x32.png" href="/images/favicon/favicon-32x32.png" />
/>
<link <link
rel="icon" rel="icon"
type="image/png" type="image/png"
sizes="16x16" sizes="16x16"
href="/images/favicon/favicon-16x16.png" href="/images/favicon/favicon-16x16.png" />
/>
<link rel="manifest" href="/images/favicon/site.webmanifest" /> <link rel="manifest" href="/images/favicon/site.webmanifest" />
<link <link
rel="mask-icon" rel="mask-icon"
href="/images/favicon/safari-pinned-tab.svg" href="/images/favicon/safari-pinned-tab.svg"
color="#5bbad5" color="#5bbad5" />
/>
<link rel="shortcut icon" href="/images/favicon/favicon.ico" /> <link rel="shortcut icon" href="/images/favicon/favicon.ico" />
<meta name="msapplication-TileColor" content="#333333" /> <meta name="msapplication-TileColor" content="#333333" />
<meta <meta
name="msapplication-config" name="msapplication-config"
content="/images/favicon/browserconfig.xml" content="/images/favicon/browserconfig.xml" />
/>
<meta name="theme-color" content="#ffffff" /> <meta name="theme-color" content="#ffffff" />
</head> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div> <div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body> </body>
</html> </html>

View File

@ -2,114 +2,77 @@
"name": "nginxproxymanager", "name": "nginxproxymanager",
"version": "3.0.0", "version": "3.0.0",
"private": true, "private": true,
"dependencies": {
"@chakra-ui/react": "^2.5.5",
"@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6",
"@testing-library/jest-dom": "5.16.5",
"@testing-library/react": "14.0.0",
"@types/humps": "^2.0.2",
"@types/jest": "29.5.0",
"@types/lodash": "4.14.192",
"@types/node": "18.15.11",
"@types/react": "18.0.34",
"@types/react-dom": "18.0.11",
"@types/react-router-dom": "5.3.3",
"@types/react-syntax-highlighter": "^15.5.6",
"@types/react-table": "^7.7.14",
"@types/styled-components": "5.1.26",
"@typescript-eslint/eslint-plugin": "^5.58.0",
"@typescript-eslint/parser": "^5.58.0",
"ajv": "^8.12.0",
"babel-eslint": "^10.1.0",
"chakra-react-select": "^4.6.0",
"classnames": "^2.3.2",
"country-flag-icons": "^1.5.7",
"date-fns": "2.29.3",
"eslint": "^8.38.0",
"eslint-config-prettier": "^8.8.0",
"eslint-config-react-app": "^7.0.1",
"eslint-loader": "^4.0.2",
"eslint-plugin-flowtype": "^8.0.3",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"formik": "^2.2.9",
"framer-motion": "^10.11.2",
"humps": "^2.0.1",
"jest-date-mock": "1.0.8",
"jest-fetch-mock": "3.0.3",
"jest-junit": "^15.0.0",
"jest-localstorage-mock": "2.4.26",
"jest-runner-eslint": "2.0.0",
"lodash": "4.17.21",
"moment": "2.29.4",
"node-sass": "^8.0.0",
"prettier": "2.8.7",
"query-string": "8.1.0",
"react": "^18.2.0",
"react-async": "10.0.1",
"react-dom": "18.2.0",
"react-focus-lock": "^2.9.4",
"react-icons": "^4.8.0",
"react-intl": "^6.3.2",
"react-markdown": "^8.0.6",
"react-query": "^3.39.3",
"react-router-dom": "^6.10.0",
"react-scripts": "5.0.1",
"react-syntax-highlighter": "^15.5.0",
"react-table": "7.8.0",
"rooks": "7.11.0",
"tmp": "^0.2.1",
"typescript": "^5.0.4"
},
"scripts": { "scripts": {
"start": "react-scripts start", "dev": "vite",
"build": "react-scripts build", "build": "tsc && vite build",
"lint": "yarn jest --config jest.eslint.js --watch", "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"lint:ci": "yarn lint --watchAll=false", "lint:ci": "yarn lint --watchAll=false",
"test": "react-scripts test", "lint:fix": "eslint --fix --ext .ts --ext .tsx .",
"test:coverage": "yarn test --coverage --watchAll=false", "preview": "vite preview",
"test:ci": "yarn test:coverage",
"eject": "react-scripts eject",
"prettier": "prettier \"**/*.+(js|json|yml|css|ts|tsx)\"", "prettier": "prettier \"**/*.+(js|json|yml|css|ts|tsx)\"",
"format": "yarn prettier -- --write", "format": "yarn prettier -- --write",
"lint:fix": "eslint --fix --ext .ts --ext .tsx .",
"locale-extract": "formatjs extract 'src/**/*.tsx'", "locale-extract": "formatjs extract 'src/**/*.tsx'",
"locale-compile": "formatjs compile-folder src/locale/src src/locale/lang", "locale-compile": "formatjs compile-folder src/locale/src src/locale/lang",
"check-locales": "./check-locales.js" "check-locales": "./check-locales.js"
}, },
"browserslist": { "dependencies": {
"production": [ "@chakra-ui/react": "^2.8.0",
">0.2%", "@emotion/react": "^11.11.1",
"not dead", "@emotion/styled": "^11.11.0",
"not op_mini all" "@tanstack/react-query": "^4.29.25",
], "@tanstack/react-query-devtools": "^4.29.25",
"development": [ "ajv": "^8.12.0",
"last 1 chrome version", "chakra-react-select": "^4.6.0",
"last 1 firefox version", "classnames": "^2.3.2",
"last 1 safari version" "country-flag-icons": "^1.5.7",
] "date-fns": "2.30.0",
}, "formik": "^2.4.2",
"jest": { "framer-motion": "^10.13.0",
"globalSetup": "<rootDir>/globalSetup.js", "humps": "^2.0.1",
"collectCoverageFrom": [ "lodash": "4.17.21",
"src/**/*.{js,jsx,ts,tsx}", "moment": "2.29.4",
"!src/testUtils/*" "query-string": "8.1.0",
], "react": "^18.2.0",
"coverageThreshold": { "react-async": "10.0.1",
"global": { "react-dom": "18.2.0",
"branches": 0, "react-focus-lock": "^2.9.5",
"functions": 0, "react-icons": "^4.10.1",
"lines": 0, "react-intl": "^6.4.4",
"statements": 0 "react-markdown": "^8.0.7",
} "react-router-dom": "^6.14.2",
} "react-syntax-highlighter": "^15.5.0",
"react-table": "7.8.0",
"rooks": "7.14.1",
"tmp": "^0.2.1"
}, },
"devDependencies": { "devDependencies": {
"@formatjs/cli": "^6.0.4", "@formatjs/cli": "^6.1.3",
"@types/country-flag-icons": "^1.2.0" "@types/country-flag-icons": "^1.2.0",
"@types/humps": "^2.0.3",
"@types/lodash": "4.14.195",
"@types/node": "20.4.2",
"@types/react": "18.2.15",
"@types/react-dom": "18.2.7",
"@types/react-router-dom": "5.3.3",
"@types/react-syntax-highlighter": "^15.5.7",
"@types/react-table": "^7.7.14",
"@types/styled-components": "5.1.26",
"@typescript-eslint/eslint-plugin": "^6.1.0",
"@typescript-eslint/parser": "^6.1.0",
"@vitejs/plugin-react": "^4.0.3",
"eslint": "^8.45.0",
"eslint-config-prettier": "^8.8.0",
"eslint-import-resolver-typescript": "^3.5.5",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
"prettier": "^3.0.0",
"sass": "^1.64.0",
"typescript": "^5.1.6",
"vite": "^4.4.4",
"vite-plugin-checker": "^0.6.1"
} }
} }

View File

@ -1,11 +0,0 @@
import * as React from "react";
import * as ReactDOM from "react-dom";
import App from "./App";
it("renders without crashing", () => {
const div = document.createElement("div");
ReactDOM.render(<App />, div);
ReactDOM.unmountComponentAtNode(div);
});

View File

@ -1,9 +1,10 @@
import { ChakraProvider } from "@chakra-ui/react"; import { ChakraProvider } from "@chakra-ui/react";
import { AuthProvider, LocaleProvider } from "context"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { intl } from "locale"; import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import { RawIntlProvider } from "react-intl"; import { RawIntlProvider } from "react-intl";
import { QueryClient, QueryClientProvider } from "react-query";
import { ReactQueryDevtools } from "react-query/devtools"; import { AuthProvider, LocaleProvider } from "src/context";
import { intl } from "src/locale";
import Router from "./Router"; import Router from "./Router";
import lightTheme from "./theme/customTheme"; import lightTheme from "./theme/customTheme";
@ -21,7 +22,7 @@ function App() {
<Router /> <Router />
</AuthProvider> </AuthProvider>
</ChakraProvider> </ChakraProvider>
<ReactQueryDevtools /> <ReactQueryDevtools position="bottom-right" panelPosition="right" />
</QueryClientProvider> </QueryClientProvider>
</LocaleProvider> </LocaleProvider>
</RawIntlProvider> </RawIntlProvider>

View File

@ -1,25 +1,26 @@
import { lazy, Suspense } from "react"; import { lazy, Suspense } from "react";
import { SiteWrapper, SpinnerPage, Unhealthy } from "components";
import { useAuthState, useLocaleState } from "context";
import { useHealth } from "hooks";
import { BrowserRouter, Routes, Route } from "react-router-dom"; import { BrowserRouter, Routes, Route } from "react-router-dom";
const AccessLists = lazy(() => import("pages/AccessLists")); import { SiteWrapper, SpinnerPage, Unhealthy } from "src/components";
const AuditLog = lazy(() => import("pages/AuditLog")); import { useAuthState, useLocaleState } from "src/context";
const Certificates = lazy(() => import("pages/Certificates")); import { useHealth } from "src/hooks";
const AccessLists = lazy(() => import("src/pages/AccessLists"));
const AuditLog = lazy(() => import("src/pages/AuditLog"));
const Certificates = lazy(() => import("src/pages/Certificates"));
const CertificateAuthorities = lazy( const CertificateAuthorities = lazy(
() => import("pages/CertificateAuthorities"), () => import("src/pages/CertificateAuthorities"),
); );
const Dashboard = lazy(() => import("pages/Dashboard")); const Dashboard = lazy(() => import("src/pages/Dashboard"));
const DNSProviders = lazy(() => import("pages/DNSProviders")); const DNSProviders = lazy(() => import("src/pages/DNSProviders"));
const Hosts = lazy(() => import("pages/Hosts")); const Hosts = lazy(() => import("src/pages/Hosts"));
const NginxTemplates = lazy(() => import("pages/NginxTemplates")); const NginxTemplates = lazy(() => import("src/pages/NginxTemplates"));
const Login = lazy(() => import("pages/Login")); const Login = lazy(() => import("src/pages/Login"));
const GeneralSettings = lazy(() => import("pages/Settings")); const GeneralSettings = lazy(() => import("src/pages/Settings"));
const Setup = lazy(() => import("pages/Setup")); const Setup = lazy(() => import("src/pages/Setup"));
const Upstreams = lazy(() => import("pages/Upstreams")); const Upstreams = lazy(() => import("src/pages/Upstreams"));
const Users = lazy(() => import("pages/Users")); const Users = lazy(() => import("src/pages/Users"));
function Router() { function Router() {
const health = useHealth(); const health = useHealth();

View File

@ -1,7 +1,8 @@
import { camelizeKeys, decamelizeKeys } from "humps"; import { camelizeKeys, decamelizeKeys } from "humps";
import AuthStore from "modules/AuthStore";
import queryString from "query-string"; import queryString from "query-string";
import AuthStore from "src/modules/AuthStore";
const contentTypeHeader = "Content-Type"; const contentTypeHeader = "Content-Type";
interface BuildUrlArgs { interface BuildUrlArgs {

View File

@ -9,7 +9,7 @@ export async function createDNSProvider(
): Promise<DNSProvider> { ): Promise<DNSProvider> {
// Because the meta property of the data should not be decamelized, // Because the meta property of the data should not be decamelized,
// we're going to decamelize the rest here instead of in base.ts // we're going to decamelize the rest here instead of in base.ts
let dcData: any = decamelizeKeys(data); const dcData: any = decamelizeKeys(data);
if (typeof data.meta !== "undefined") { if (typeof data.meta !== "undefined") {
dcData.meta = data.meta; dcData.meta = data.meta;
} }

View File

@ -13,7 +13,7 @@ export async function setDNSProvider(
// Because the meta property of the data should not be decamelized, // Because the meta property of the data should not be decamelized,
// we're going to decamelize the rest here instead of in base.ts // we're going to decamelize the rest here instead of in base.ts
let dcData: any = decamelizeKeys(data); const dcData: any = decamelizeKeys(data);
if (typeof data.meta !== "undefined") { if (typeof data.meta !== "undefined") {
dcData.meta = data.meta; dcData.meta = data.meta;
} }

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -7,7 +7,8 @@ import {
Tooltip, Tooltip,
useColorModeValue, useColorModeValue,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { intl } from "locale";
import { intl } from "src/locale";
function Footer() { function Footer() {
return ( return (
@ -47,12 +48,12 @@ function Footer() {
rel="noopener noreferrer"> rel="noopener noreferrer">
{intl.formatMessage({ id: "footer.github" })} {intl.formatMessage({ id: "footer.github" })}
</Link> </Link>
<Tooltip label={process.env.REACT_APP_COMMIT}> <Tooltip label={import.meta.env.VITE_APP_COMMIT}>
<Link <Link
href="https://github.com/NginxProxyManager/nginx-proxy-manager/releases?utm_source=npm" href="https://github.com/NginxProxyManager/nginx-proxy-manager/releases?utm_source=npm"
isExternal isExternal
rel="noopener noreferrer"> rel="noopener noreferrer">
v{process.env.REACT_APP_VERSION} v{import.meta.env.VITE_APP_VERSION}
</Link> </Link>
</Tooltip> </Tooltip>
</Stack> </Stack>

View File

@ -8,11 +8,11 @@ import {
DrawerBody, DrawerBody,
useDisclosure, useDisclosure,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { getLocale } from "locale";
import { FiHelpCircle } from "react-icons/fi"; import { FiHelpCircle } from "react-icons/fi";
import ReactMarkdown from "react-markdown"; import ReactMarkdown from "react-markdown";
import { getHelpFile } from "../../locale/src/HelpDoc"; import { getLocale } from "src/locale";
import { getHelpFile } from "src/locale/src/HelpDoc";
interface HelpDrawerProps { interface HelpDrawerProps {
/** /**

View File

@ -1,5 +1,6 @@
import { Box } from "@chakra-ui/react"; import { Box } from "@chakra-ui/react";
import { Loader } from "components";
import { Loader } from "src/components";
function Loading() { function Loading() {
return ( return (

View File

@ -7,14 +7,15 @@ import {
MenuList, MenuList,
MenuItem, MenuItem,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { Flag } from "components";
import { useLocaleState } from "context"; import { Flag } from "src/components";
import { useLocaleState } from "src/context";
import { import {
changeLocale, changeLocale,
getFlagCodeForLocale, getFlagCodeForLocale,
intl, intl,
localeOptions, localeOptions,
} from "locale"; } from "src/locale";
interface LocalPickerProps { interface LocalPickerProps {
onChange?: any; onChange?: any;

View File

@ -1,5 +1,6 @@
import { useDisclosure } from "@chakra-ui/react"; import { useDisclosure } from "@chakra-ui/react";
import { NavigationHeader, NavigationMenu } from "components";
import { NavigationHeader, NavigationMenu } from "src/components";
function Navigation() { function Navigation() {
const { const {

View File

@ -17,13 +17,14 @@ import {
useColorModeValue, useColorModeValue,
useDisclosure, useDisclosure,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { LocalePicker, ThemeSwitcher } from "components";
import { useAuthState } from "context";
import { useUser } from "hooks";
import { intl } from "locale";
import { ChangePasswordModal, ProfileModal } from "modals";
import { FiLock, FiLogOut, FiMenu, FiUser, FiX } from "react-icons/fi"; import { FiLock, FiLogOut, FiMenu, FiUser, FiX } from "react-icons/fi";
import { LocalePicker, ThemeSwitcher } from "src/components";
import { useAuthState } from "src/context";
import { useUser } from "src/hooks";
import { intl } from "src/locale";
import { ChangePasswordModal, ProfileModal } from "src/modals";
interface NavigationHeaderProps { interface NavigationHeaderProps {
mobileNavIsOpen: boolean; mobileNavIsOpen: boolean;
toggleMobileNav: () => void; toggleMobileNav: () => void;

View File

@ -19,7 +19,6 @@ import {
Container, Container,
useBreakpointValue, useBreakpointValue,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { intl } from "locale";
import { import {
FiHome, FiHome,
FiSettings, FiSettings,
@ -32,6 +31,8 @@ import {
} from "react-icons/fi"; } from "react-icons/fi";
import { Link as RouterLink, useLocation } from "react-router-dom"; import { Link as RouterLink, useLocation } from "react-router-dom";
import { intl } from "src/locale";
interface NavItem { interface NavItem {
/** Displayed label */ /** Displayed label */
label: string; label: string;

View File

@ -1,7 +1,8 @@
import { MouseEventHandler } from "react"; import { MouseEventHandler } from "react";
import { Heading, Stack, Text, useColorModeValue } from "@chakra-ui/react"; import { Heading, Stack, Text, useColorModeValue } from "@chakra-ui/react";
import { intl } from "locale";
import { intl } from "src/locale";
interface AdminPermissionSelectorProps { interface AdminPermissionSelectorProps {
selected?: boolean; selected?: boolean;

View File

@ -8,7 +8,8 @@ import {
Text, Text,
useColorModeValue, useColorModeValue,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { intl } from "locale";
import { intl } from "src/locale";
interface PermissionSelectorProps { interface PermissionSelectorProps {
capabilities: string[]; capabilities: string[];

View File

@ -1,11 +1,12 @@
import { useEffect, ReactNode } from "react"; import { useEffect, ReactNode } from "react";
import { Box, Container, useToast } from "@chakra-ui/react"; import { Box, Container, useToast } from "@chakra-ui/react";
import { getSSEToken, SSEMessage } from "api/npm"; import { useQueryClient } from "@tanstack/react-query";
import { Footer, Navigation } from "components";
import { intl } from "locale"; import { getSSEToken, SSEMessage } from "src/api/npm";
import AuthStore from "modules/AuthStore"; import { Footer, Navigation } from "src/components";
import { useQueryClient } from "react-query"; import { intl } from "src/locale";
import AuthStore from "src/modules/AuthStore";
interface Props { interface Props {
children?: ReactNode; children?: ReactNode;
@ -26,7 +27,7 @@ function SiteWrapper({ children }: Props) {
const j: SSEMessage = JSON.parse(e.data); const j: SSEMessage = JSON.parse(e.data);
if (j) { if (j) {
if (j.affects) { if (j.affects) {
queryClient.invalidateQueries(j.affects); queryClient.invalidateQueries([j.affects]);
} }
if (j.type) { if (j.type) {
toast({ toast({

View File

@ -9,9 +9,10 @@ import {
PopoverArrow, PopoverArrow,
PopoverBody, PopoverBody,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { Monospace, RowAction, RowActionsMenu } from "components";
import { intl } from "locale"; import { Monospace, RowAction, RowActionsMenu } from "src/components";
import getNiceDNSProvider from "modules/Acmesh"; import { intl } from "src/locale";
import getNiceDNSProvider from "src/modules/Acmesh";
const errorColor = "red.400"; const errorColor = "red.400";

View File

@ -17,8 +17,6 @@ import {
Tr, Tr,
VStack, VStack,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { TablePagination } from "components";
import { intl } from "locale";
import { import {
FiChevronsLeft, FiChevronsLeft,
FiChevronLeft, FiChevronLeft,
@ -29,6 +27,9 @@ import {
FiX, FiX,
} from "react-icons/fi"; } from "react-icons/fi";
import { TablePagination } from "src/components";
import { intl } from "src/locale";
export interface TableLayoutProps { export interface TableLayoutProps {
pagination: TablePagination; pagination: TablePagination;
getTableProps: any; getTableProps: any;
@ -102,10 +103,11 @@ function TableLayout({
<> <>
<Table size="sm" {...getTableProps()}> <Table size="sm" {...getTableProps()}>
<Thead> <Thead>
{headerGroups.map((headerGroup: any) => ( {headerGroups.map((headerGroup: any, idx: any) => (
<Tr {...headerGroup.getHeaderGroupProps()}> <Tr key={idx} {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column: any) => ( {headerGroup.headers.map((column: any, idx2: any) => (
<Th <Th
key={idx2}
userSelect="none" userSelect="none"
className={column.className} className={column.className}
isNumeric={column.isNumeric}> isNumeric={column.isNumeric}>
@ -134,12 +136,13 @@ function TableLayout({
</Thead> </Thead>
<Tbody {...getTableBodyProps()}> <Tbody {...getTableBodyProps()}>
{rows.length {rows.length
? rows.map((row: any) => { ? rows.map((row: any, idx: any) => {
prepareRow(row); prepareRow(row);
return ( return (
<Tr {...row.getRowProps()}> <Tr key={idx} {...row.getRowProps()}>
{row.cells.map((cell: any) => ( {row.cells.map((cell: any, idx2: any) => (
<Td <Td
key={idx2}
{...cell.getCellProps([ {...cell.getCellProps([
{ {
className: cell.column.className, className: cell.column.className,

View File

@ -13,13 +13,14 @@ import {
useDisclosure, useDisclosure,
Select, Select,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { PrettyButton } from "components";
import { Formik, Form, Field } from "formik"; import { Formik, Form, Field } from "formik";
import { intl } from "locale";
import { validateString } from "modules/Validations";
import FocusLock from "react-focus-lock"; import FocusLock from "react-focus-lock";
import { FiFilter } from "react-icons/fi"; import { FiFilter } from "react-icons/fi";
import { PrettyButton } from "src/components";
import { intl } from "src/locale";
import { validateString } from "src/modules/Validations";
function TextFilter({ column: { filterValue, setFilter } }: any) { function TextFilter({ column: { filterValue, setFilter } }: any) {
const { onOpen, onClose, isOpen } = useDisclosure(); const { onOpen, onClose, isOpen } = useDisclosure();

View File

@ -4,9 +4,10 @@ import {
IconButtonProps, IconButtonProps,
useColorMode, useColorMode,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { intl } from "locale";
import { FiSun, FiMoon } from "react-icons/fi"; import { FiSun, FiMoon } from "react-icons/fi";
import { intl } from "src/locale";
interface ThemeSwitcherProps { interface ThemeSwitcherProps {
background?: "normal" | "transparent"; background?: "normal" | "transparent";
} }

View File

@ -1,8 +1,9 @@
import { Box, Flex, Heading, Text, Stack } from "@chakra-ui/react"; import { Box, Flex, Heading, Text, Stack } from "@chakra-ui/react";
import { LocalePicker, ThemeSwitcher } from "components";
import { intl } from "locale";
import { FaTimes } from "react-icons/fa"; import { FaTimes } from "react-icons/fa";
import { LocalePicker, ThemeSwitcher } from "src/components";
import { intl } from "src/locale";
function Unhealthy() { function Unhealthy() {
return ( return (
<> <>

View File

@ -1,10 +1,11 @@
import { ReactNode, createContext, useContext, useState } from "react"; import { ReactNode, createContext, useContext, useState } from "react";
import { getToken, refreshToken, TokenResponse } from "api/npm"; import { useQueryClient } from "@tanstack/react-query";
import AuthStore from "modules/AuthStore";
import { useQueryClient } from "react-query";
import { useIntervalWhen } from "rooks"; import { useIntervalWhen } from "rooks";
import { getToken, refreshToken, TokenResponse } from "src/api/npm";
import AuthStore from "src/modules/AuthStore";
// Context // Context
export interface AuthContextType { export interface AuthContextType {
authenticated: boolean; authenticated: boolean;
@ -44,7 +45,7 @@ function AuthProvider({
const logout = () => { const logout = () => {
AuthStore.clear(); AuthStore.clear();
setAuthenticated(false); setAuthenticated(false);
queryClient.invalidateQueries("user"); queryClient.clear();
}; };
const refresh = async () => { const refresh = async () => {

View File

@ -1,6 +1,6 @@
import { createContext, ReactNode, useContext, useState } from "react"; import { createContext, ReactNode, useContext, useState } from "react";
import { getLocale } from "locale"; import { getLocale } from "src/locale";
// Context // Context
export interface LocaleContextType { export interface LocaleContextType {

View File

@ -1,10 +1,11 @@
import { useQuery } from "@tanstack/react-query";
import { import {
getAccessLists, getAccessLists,
AccessListsResponse, AccessListsResponse,
tableSortToAPI, tableSortToAPI,
tableFiltersToAPI, tableFiltersToAPI,
} from "api/npm"; } from "src/api/npm";
import { useQuery } from "react-query";
const fetchAccessLists = ( const fetchAccessLists = (
offset = 0, offset = 0,
@ -27,15 +28,13 @@ const useAccessLists = (
filters?: any, filters?: any,
options = {}, options = {},
) => { ) => {
return useQuery<AccessListsResponse, Error>( return useQuery<AccessListsResponse, Error>({
["access-lists", { offset, limit, sortBy, filters }], queryKey: ["access-lists", { offset, limit, sortBy, filters }],
() => fetchAccessLists(offset, limit, sortBy, filters), queryFn: () => fetchAccessLists(offset, limit, sortBy, filters),
{ keepPreviousData: true,
keepPreviousData: true, staleTime: 15 * 1000, // 15 seconds
staleTime: 15 * 1000, // 15 seconds ...options,
...options, });
},
);
}; };
export { useAccessLists }; export { useAccessLists };

View File

@ -1,24 +1,23 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { import {
createCertificate, createCertificate,
getCertificate, getCertificate,
setCertificate, setCertificate,
Certificate, Certificate,
} from "api/npm"; } from "src/api/npm";
import { useMutation, useQuery, useQueryClient } from "react-query";
const fetchCertificate = (id: any) => { const fetchCertificate = (id: any) => {
return getCertificate(id); return getCertificate(id);
}; };
const useCertificate = (id: number, options = {}) => { const useCertificate = (id: number, options = {}) => {
return useQuery<Certificate, Error>( return useQuery<Certificate, Error>({
["certificate", id], queryKey: ["certificate", id],
() => fetchCertificate(id), queryFn: () => fetchCertificate(id),
{ staleTime: 60 * 1000, // 1 minute
staleTime: 60 * 1000, // 1 minute ...options,
...options, });
},
);
}; };
const useSetCertificate = () => { const useSetCertificate = () => {
@ -44,10 +43,10 @@ const useSetCertificate = () => {
return () => return () =>
queryClient.setQueryData(["certificate", values.id], previousObject); queryClient.setQueryData(["certificate", values.id], previousObject);
}, },
onError: (error, values, rollback: any) => rollback(), onError: (_, __, rollback: any) => rollback(),
onSuccess: async ({ id }: Certificate) => { onSuccess: async ({ id }: Certificate) => {
queryClient.invalidateQueries(["certificate", id]); queryClient.invalidateQueries(["certificate", id]);
queryClient.invalidateQueries("certificates"); queryClient.invalidateQueries(["certificates"]);
}, },
}, },
); );

View File

@ -1,10 +1,11 @@
import { useQuery } from "@tanstack/react-query";
import { import {
CertificateAuthoritiesResponse, CertificateAuthoritiesResponse,
getCertificateAuthorities, getCertificateAuthorities,
tableSortToAPI, tableSortToAPI,
tableFiltersToAPI, tableFiltersToAPI,
} from "api/npm"; } from "src/api/npm";
import { useQuery } from "react-query";
const fetchCertificateAuthorities = ( const fetchCertificateAuthorities = (
offset = 0, offset = 0,
@ -27,15 +28,13 @@ const useCertificateAuthorities = (
filters?: any, filters?: any,
options = {}, options = {},
) => { ) => {
return useQuery<CertificateAuthoritiesResponse, Error>( return useQuery<CertificateAuthoritiesResponse, Error>({
["certificate-authorities", { offset, limit, sortBy, filters }], queryKey: ["certificate-authorities", { offset, limit, sortBy, filters }],
() => fetchCertificateAuthorities(offset, limit, sortBy, filters), queryFn: () => fetchCertificateAuthorities(offset, limit, sortBy, filters),
{ keepPreviousData: true,
keepPreviousData: true, staleTime: 15 * 1000, // 15 seconds
staleTime: 15 * 1000, // 15 seconds ...options,
...options, });
},
);
}; };
export { fetchCertificateAuthorities, useCertificateAuthorities }; export { fetchCertificateAuthorities, useCertificateAuthorities };

View File

@ -1,24 +1,23 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { import {
createCertificateAuthority, createCertificateAuthority,
getCertificateAuthority, getCertificateAuthority,
setCertificateAuthority, setCertificateAuthority,
CertificateAuthority, CertificateAuthority,
} from "api/npm"; } from "src/api/npm";
import { useMutation, useQuery, useQueryClient } from "react-query";
const fetchCertificateAuthority = (id: any) => { const fetchCertificateAuthority = (id: any) => {
return getCertificateAuthority(id); return getCertificateAuthority(id);
}; };
const useCertificateAuthority = (id: number, options = {}) => { const useCertificateAuthority = (id: number, options = {}) => {
return useQuery<CertificateAuthority, Error>( return useQuery<CertificateAuthority, Error>({
["certificate-authority", id], queryKey: ["certificate-authority", id],
() => fetchCertificateAuthority(id), queryFn: () => fetchCertificateAuthority(id),
{ staleTime: 60 * 1000, // 1 minute
staleTime: 60 * 1000, // 1 minute ...options,
...options, });
},
);
}; };
const useSetCertificateAuthority = () => { const useSetCertificateAuthority = () => {
@ -50,10 +49,10 @@ const useSetCertificateAuthority = () => {
previousObject, previousObject,
); );
}, },
onError: (error, values, rollback: any) => rollback(), onError: (_, __, rollback: any) => rollback(),
onSuccess: async ({ id }: CertificateAuthority) => { onSuccess: async ({ id }: CertificateAuthority) => {
queryClient.invalidateQueries(["certificate-authority", id]); queryClient.invalidateQueries(["certificate-authority", id]);
queryClient.invalidateQueries("certificate-authorities"); queryClient.invalidateQueries(["certificate-authorities"]);
}, },
}, },
); );

View File

@ -1,10 +1,11 @@
import { useQuery } from "@tanstack/react-query";
import { import {
getCertificates, getCertificates,
CertificatesResponse, CertificatesResponse,
tableSortToAPI, tableSortToAPI,
tableFiltersToAPI, tableFiltersToAPI,
} from "api/npm"; } from "src/api/npm";
import { useQuery } from "react-query";
const fetchCertificates = ( const fetchCertificates = (
offset = 0, offset = 0,
@ -27,15 +28,13 @@ const useCertificates = (
filters?: any, filters?: any,
options = {}, options = {},
) => { ) => {
return useQuery<CertificatesResponse, Error>( return useQuery<CertificatesResponse, Error>({
["certificates", { offset, limit, sortBy, filters }], queryKey: ["certificates", { offset, limit, sortBy, filters }],
() => fetchCertificates(offset, limit, sortBy, filters), queryFn: () => fetchCertificates(offset, limit, sortBy, filters),
{ keepPreviousData: true,
keepPreviousData: true, staleTime: 15 * 1000, // 15 seconds
staleTime: 15 * 1000, // 15 seconds ...options,
...options, });
},
);
}; };
export { fetchCertificates, useCertificates }; export { fetchCertificates, useCertificates };

View File

@ -1,24 +1,23 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { import {
createDNSProvider, createDNSProvider,
getDNSProvider, getDNSProvider,
setDNSProvider, setDNSProvider,
DNSProvider, DNSProvider,
} from "api/npm"; } from "src/api/npm";
import { useMutation, useQuery, useQueryClient } from "react-query";
const fetchDNSProvider = (id: any) => { const fetchDNSProvider = (id: any) => {
return getDNSProvider(id); return getDNSProvider(id);
}; };
const useDNSProvider = (id: number, options = {}) => { const useDNSProvider = (id: number, options = {}) => {
return useQuery<DNSProvider, Error>( return useQuery<DNSProvider, Error>({
["dns-provider", id], queryKey: ["dns-provider", id],
() => fetchDNSProvider(id), queryFn: () => fetchDNSProvider(id),
{ staleTime: 60 * 1000, // 1 minute
staleTime: 60 * 1000, // 1 minute ...options,
...options, });
},
);
}; };
const useSetDNSProvider = () => { const useSetDNSProvider = () => {
@ -44,10 +43,10 @@ const useSetDNSProvider = () => {
return () => return () =>
queryClient.setQueryData(["dns-provider", values.id], previousObject); queryClient.setQueryData(["dns-provider", values.id], previousObject);
}, },
onError: (error, values, rollback: any) => rollback(), onError: (_, __, rollback: any) => rollback(),
onSuccess: async ({ id }: DNSProvider) => { onSuccess: async ({ id }: DNSProvider) => {
queryClient.invalidateQueries(["dns-provider", id]); queryClient.invalidateQueries(["dns-provider", id]);
queryClient.invalidateQueries("dns-providers"); queryClient.invalidateQueries(["dns-providers"]);
}, },
}, },
); );

View File

@ -1,10 +1,11 @@
import { useQuery } from "@tanstack/react-query";
import { import {
getDNSProviders, getDNSProviders,
DNSProvidersResponse, DNSProvidersResponse,
tableSortToAPI, tableSortToAPI,
tableFiltersToAPI, tableFiltersToAPI,
} from "api/npm"; } from "src/api/npm";
import { useQuery } from "react-query";
const fetchDNSProviders = ( const fetchDNSProviders = (
offset = 0, offset = 0,
@ -27,15 +28,13 @@ const useDNSProviders = (
filters?: any, filters?: any,
options = {}, options = {},
) => { ) => {
return useQuery<DNSProvidersResponse, Error>( return useQuery<DNSProvidersResponse, Error>({
["dns-providers", { offset, limit, sortBy, filters }], queryKey: ["dns-providers", { offset, limit, sortBy, filters }],
() => fetchDNSProviders(offset, limit, sortBy, filters), queryFn: () => fetchDNSProviders(offset, limit, sortBy, filters),
{ keepPreviousData: true,
keepPreviousData: true, staleTime: 15 * 1000, // 15 seconds
staleTime: 15 * 1000, // 15 seconds ...options,
...options, });
},
);
}; };
export { useDNSProviders }; export { useDNSProviders };

View File

@ -1,16 +1,15 @@
import { DNSProvidersAcmesh, getDNSProvidersAcmesh } from "api/npm"; import { useQuery } from "@tanstack/react-query";
import { useQuery } from "react-query";
import { DNSProvidersAcmesh, getDNSProvidersAcmesh } from "src/api/npm";
const useDNSProvidersAcmesh = (options = {}) => { const useDNSProvidersAcmesh = (options = {}) => {
return useQuery<DNSProvidersAcmesh[], Error>( return useQuery<DNSProvidersAcmesh[], Error>({
["dns-providers-acmesh"], queryKey: ["dns-providers-acmesh"],
() => getDNSProvidersAcmesh(), queryFn: () => getDNSProvidersAcmesh(),
{ keepPreviousData: true,
keepPreviousData: true, staleTime: 60 * 60 * 1000, // 1 hour
staleTime: 60 * 60 * 1000, // 1 hour ...options,
...options, });
},
);
}; };
export { useDNSProvidersAcmesh }; export { useDNSProvidersAcmesh };

View File

@ -1,10 +1,13 @@
import { getHealth, HealthResponse } from "api/npm"; import { useQuery } from "@tanstack/react-query";
import { useQuery } from "react-query";
import { getHealth, HealthResponse } from "src/api/npm";
const fetchHealth = () => getHealth(); const fetchHealth = () => getHealth();
const useHealth = (options = {}) => { const useHealth = (options = {}) => {
return useQuery<HealthResponse, Error>("health", fetchHealth, { return useQuery<HealthResponse, Error>({
queryKey: ["health"],
queryFn: fetchHealth,
refetchOnWindowFocus: false, refetchOnWindowFocus: false,
retry: 5, retry: 5,
refetchInterval: 15 * 1000, // 15 seconds refetchInterval: 15 * 1000, // 15 seconds

View File

@ -1,10 +1,11 @@
import { useQuery } from "@tanstack/react-query";
import { import {
getHosts, getHosts,
HostsResponse, HostsResponse,
tableSortToAPI, tableSortToAPI,
tableFiltersToAPI, tableFiltersToAPI,
} from "api/npm"; } from "src/api/npm";
import { useQuery } from "react-query";
const fetchHosts = (offset = 0, limit = 10, sortBy?: any, filters?: any) => { const fetchHosts = (offset = 0, limit = 10, sortBy?: any, filters?: any) => {
return getHosts( return getHosts(
@ -22,15 +23,13 @@ const useHosts = (
filters?: any, filters?: any,
options = {}, options = {},
) => { ) => {
return useQuery<HostsResponse, Error>( return useQuery<HostsResponse, Error>({
["hosts", { offset, limit, sortBy, filters }], queryKey: ["hosts", { offset, limit, sortBy, filters }],
() => fetchHosts(offset, limit, sortBy, filters), queryFn: () => fetchHosts(offset, limit, sortBy, filters),
{ keepPreviousData: true,
keepPreviousData: true, staleTime: 15 * 1000, // 15 seconds
staleTime: 15 * 1000, // 15 seconds ...options,
...options, });
},
);
}; };
export { fetchHosts, useHosts }; export { fetchHosts, useHosts };

View File

@ -1,10 +1,11 @@
import { useQuery } from "@tanstack/react-query";
import { import {
getNginxTemplates, getNginxTemplates,
NginxTemplatesResponse, NginxTemplatesResponse,
tableSortToAPI, tableSortToAPI,
tableFiltersToAPI, tableFiltersToAPI,
} from "api/npm"; } from "src/api/npm";
import { useQuery } from "react-query";
const fetchNginxTemplates = ( const fetchNginxTemplates = (
offset = 0, offset = 0,
@ -27,15 +28,13 @@ const useNginxTemplates = (
filters?: any, filters?: any,
options = {}, options = {},
) => { ) => {
return useQuery<NginxTemplatesResponse, Error>( return useQuery<NginxTemplatesResponse, Error>({
["nginx-templates", { offset, limit, sortBy, filters }], queryKey: ["nginx-templates", { offset, limit, sortBy, filters }],
() => fetchNginxTemplates(offset, limit, sortBy, filters), queryFn: () => fetchNginxTemplates(offset, limit, sortBy, filters),
{ keepPreviousData: true,
keepPreviousData: true, staleTime: 15 * 1000, // 15 seconds
staleTime: 15 * 1000, // 15 seconds ...options,
...options, });
},
);
}; };
export { fetchNginxTemplates, useNginxTemplates }; export { fetchNginxTemplates, useNginxTemplates };

View File

@ -1,10 +1,11 @@
import { useQuery } from "@tanstack/react-query";
import { import {
getSettings, getSettings,
SettingsResponse, SettingsResponse,
tableSortToAPI, tableSortToAPI,
tableFiltersToAPI, tableFiltersToAPI,
} from "api/npm"; } from "src/api/npm";
import { useQuery } from "react-query";
const fetchSettings = (offset = 0, limit = 10, sortBy?: any, filters?: any) => { const fetchSettings = (offset = 0, limit = 10, sortBy?: any, filters?: any) => {
return getSettings( return getSettings(
@ -22,15 +23,13 @@ const useSettings = (
filters?: any, filters?: any,
options = {}, options = {},
) => { ) => {
return useQuery<SettingsResponse, Error>( return useQuery<SettingsResponse, Error>({
["settings", { offset, limit, sortBy, filters }], queryKey: ["settings", { offset, limit, sortBy, filters }],
() => fetchSettings(offset, limit, sortBy, filters), queryFn: () => fetchSettings(offset, limit, sortBy, filters),
{ keepPreviousData: true,
keepPreviousData: true, staleTime: 15 * 1000, // 15 seconds
staleTime: 15 * 1000, // 15 seconds ...options,
...options, });
},
);
}; };
export { fetchSettings, useSettings }; export { fetchSettings, useSettings };

View File

@ -1,19 +1,18 @@
import { getUpstreamNginxConfig } from "api/npm"; import { useQuery } from "@tanstack/react-query";
import { useQuery } from "react-query";
import { getUpstreamNginxConfig } from "src/api/npm";
const fetchUpstreamNginxConfig = (id: any) => { const fetchUpstreamNginxConfig = (id: any) => {
return getUpstreamNginxConfig(id); return getUpstreamNginxConfig(id);
}; };
const useUpstreamNginxConfig = (id: number, options = {}) => { const useUpstreamNginxConfig = (id: number, options = {}) => {
return useQuery<string, Error>( return useQuery<string, Error>({
["upstream-nginx-config", id], queryKey: ["upstream-nginx-config", id],
() => fetchUpstreamNginxConfig(id), queryFn: () => fetchUpstreamNginxConfig(id),
{ staleTime: 30 * 1000, // 30 seconds
staleTime: 30 * 1000, // 30 seconds ...options,
...options, });
},
);
}; };
export { useUpstreamNginxConfig }; export { useUpstreamNginxConfig };

View File

@ -1,10 +1,11 @@
import { useQuery } from "@tanstack/react-query";
import { import {
getUpstreams, getUpstreams,
HostsResponse, HostsResponse,
tableSortToAPI, tableSortToAPI,
tableFiltersToAPI, tableFiltersToAPI,
} from "api/npm"; } from "src/api/npm";
import { useQuery } from "react-query";
const fetchUpstreams = ( const fetchUpstreams = (
offset = 0, offset = 0,
@ -27,15 +28,13 @@ const useUpstreams = (
filters?: any, filters?: any,
options = {}, options = {},
) => { ) => {
return useQuery<HostsResponse, Error>( return useQuery<HostsResponse, Error>({
["upstreams", { offset, limit, sortBy, filters }], queryKey: ["upstreams", { offset, limit, sortBy, filters }],
() => fetchUpstreams(offset, limit, sortBy, filters), queryFn: () => fetchUpstreams(offset, limit, sortBy, filters),
{ keepPreviousData: true,
keepPreviousData: true, staleTime: 15 * 1000, // 15 seconds
staleTime: 15 * 1000, // 15 seconds ...options,
...options, });
},
);
}; };
export { fetchUpstreams, useUpstreams }; export { fetchUpstreams, useUpstreams };

View File

@ -1,12 +1,15 @@
import { getUser, setUser, User } from "api/npm"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useMutation, useQuery, useQueryClient } from "react-query";
import { getUser, setUser, User } from "src/api/npm";
const fetchUser = (id: any) => { const fetchUser = (id: any) => {
return getUser(id, { expand: "capabilities" }); return getUser(id, { expand: "capabilities" });
}; };
const useUser = (id: string | number, options = {}) => { const useUser = (id: string | number, options = {}) => {
return useQuery<User, Error>(["user", id], () => fetchUser(id), { return useQuery<User, Error>({
queryKey: ["user", id],
queryFn: () => fetchUser(id),
staleTime: 60 * 1000, // 1 minute staleTime: 60 * 1000, // 1 minute
...options, ...options,
}); });
@ -26,10 +29,10 @@ const useSetUser = () => {
return () => return () =>
queryClient.setQueryData(["user", values.id], previousObject); queryClient.setQueryData(["user", values.id], previousObject);
}, },
onError: (error, values, rollback: any) => rollback(), onError: (_, __, rollback: any) => rollback(),
onSuccess: async ({ id }: User) => { onSuccess: async ({ id }: User) => {
queryClient.invalidateQueries(["user", id]); queryClient.invalidateQueries(["user", id]);
queryClient.invalidateQueries("users"); queryClient.invalidateQueries(["users"]);
}, },
}); });
}; };

View File

@ -1,10 +1,11 @@
import { useQuery } from "@tanstack/react-query";
import { import {
getUsers, getUsers,
UsersResponse, UsersResponse,
tableSortToAPI, tableSortToAPI,
tableFiltersToAPI, tableFiltersToAPI,
} from "api/npm"; } from "src/api/npm";
import { useQuery } from "react-query";
const fetchUsers = (offset = 0, limit = 10, sortBy?: any, filters?: any) => { const fetchUsers = (offset = 0, limit = 10, sortBy?: any, filters?: any) => {
return getUsers( return getUsers(
@ -22,15 +23,13 @@ const useUsers = (
filters?: any, filters?: any,
options = {}, options = {},
) => { ) => {
return useQuery<UsersResponse, Error>( return useQuery<UsersResponse, Error>({
["users", { offset, limit, sortBy, filters }], queryKey: ["users", { offset, limit, sortBy, filters }],
() => fetchUsers(offset, limit, sortBy, filters), queryFn: () => fetchUsers(offset, limit, sortBy, filters),
{ keepPreviousData: true,
keepPreviousData: true, staleTime: 15 * 1000, // 15 seconds
staleTime: 15 * 1000, // 15 seconds ...options,
...options, });
},
);
}; };
export { fetchUsers, useUsers }; export { fetchUsers, useUsers };

View File

@ -19,10 +19,7 @@ declare global {
} }
} }
const root = ReactDOM.createRoot( ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
document.getElementById("root") as HTMLElement,
);
root.render(
<React.StrictMode> <React.StrictMode>
<ColorModeScript initialColorMode={customTheme.config.initialColorMode} /> <ColorModeScript initialColorMode={customTheme.config.initialColorMode} />
<App /> <App />

View File

@ -16,12 +16,13 @@ import {
Stack, Stack,
useToast, useToast,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { CertificateAuthority } from "api/npm";
import { PrettyButton } from "components";
import { Formik, Form, Field } from "formik"; import { Formik, Form, Field } from "formik";
import { useSetCertificateAuthority } from "hooks";
import { intl } from "locale"; import { CertificateAuthority } from "src/api/npm";
import { validateNumber, validateString } from "modules/Validations"; import { PrettyButton } from "src/components";
import { useSetCertificateAuthority } from "src/hooks";
import { intl } from "src/locale";
import { validateNumber, validateString } from "src/modules/Validations";
interface AccessListCreateModalProps { interface AccessListCreateModalProps {
isOpen: boolean; isOpen: boolean;

View File

@ -15,12 +15,13 @@ import {
Stack, Stack,
useToast, useToast,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { CertificateAuthority } from "api/npm";
import { PrettyButton } from "components";
import { Formik, Form, Field } from "formik"; import { Formik, Form, Field } from "formik";
import { useSetCertificateAuthority } from "hooks";
import { intl } from "locale"; import { CertificateAuthority } from "src/api/npm";
import { validateNumber, validateString } from "modules/Validations"; import { PrettyButton } from "src/components";
import { useSetCertificateAuthority } from "src/hooks";
import { intl } from "src/locale";
import { validateNumber, validateString } from "src/modules/Validations";
interface CertificateAuthorityCreateModalProps { interface CertificateAuthorityCreateModalProps {
isOpen: boolean; isOpen: boolean;

View File

@ -15,12 +15,13 @@ import {
Stack, Stack,
useToast, useToast,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { CertificateAuthority } from "api/npm";
import { PrettyButton } from "components";
import { Formik, Form, Field } from "formik"; import { Formik, Form, Field } from "formik";
import { useCertificateAuthority, useSetCertificateAuthority } from "hooks";
import { intl } from "locale"; import { CertificateAuthority } from "src/api/npm";
import { validateNumber, validateString } from "modules/Validations"; import { PrettyButton } from "src/components";
import { useCertificateAuthority, useSetCertificateAuthority } from "src/hooks";
import { intl } from "src/locale";
import { validateNumber, validateString } from "src/modules/Validations";
interface CertificateAuthorityEditModalProps { interface CertificateAuthorityEditModalProps {
editId: number; editId: number;

View File

@ -10,11 +10,12 @@ import {
Stack, Stack,
useToast, useToast,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { Certificate } from "api/npm";
import { PrettyButton } from "components";
import { Formik, Form } from "formik"; import { Formik, Form } from "formik";
import { useSetCertificate } from "hooks";
import { intl } from "locale"; import { Certificate } from "src/api/npm";
import { PrettyButton } from "src/components";
import { useSetCertificate } from "src/hooks";
import { intl } from "src/locale";
import CustomForm from "./CustomForm"; import CustomForm from "./CustomForm";
import DNSForm from "./DNSForm"; import DNSForm from "./DNSForm";

View File

@ -4,10 +4,11 @@ import {
FormLabel, FormLabel,
Select, Select,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { CertificateAuthority } from "api/npm";
import { Field, useFormikContext } from "formik"; import { Field, useFormikContext } from "formik";
import { useCertificateAuthorities } from "hooks";
import { intl } from "locale"; import { CertificateAuthority } from "src/api/npm";
import { useCertificateAuthorities } from "src/hooks";
import { intl } from "src/locale";
const fieldName = "certificateAuthorityId"; const fieldName = "certificateAuthorityId";

View File

@ -4,10 +4,11 @@ import {
FormLabel, FormLabel,
Select, Select,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { DNSProvider } from "api/npm";
import { Field, useFormikContext } from "formik"; import { Field, useFormikContext } from "formik";
import { useDNSProviders } from "hooks";
import { intl } from "locale"; import { DNSProvider } from "src/api/npm";
import { useDNSProviders } from "src/hooks";
import { intl } from "src/locale";
const fieldName = "dnsProviderId"; const fieldName = "dnsProviderId";

View File

@ -6,7 +6,8 @@ import {
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { CreatableSelect, OptionBase } from "chakra-react-select"; import { CreatableSelect, OptionBase } from "chakra-react-select";
import { Field, useFormikContext } from "formik"; import { Field, useFormikContext } from "formik";
import { intl } from "locale";
import { intl } from "src/locale";
interface SelectOption extends OptionBase { interface SelectOption extends OptionBase {
label: string; label: string;
@ -16,13 +17,12 @@ interface DomainNamesFieldProps {
maxDomains?: number; maxDomains?: number;
isWildcardPermitted?: boolean; isWildcardPermitted?: boolean;
dnsProviderWildcardSupported?: boolean; dnsProviderWildcardSupported?: boolean;
onChange?: (i: string[]) => any; // onChange?: (i: string[]) => any;
} }
function DomainNamesField({ function DomainNamesField({
maxDomains, maxDomains,
isWildcardPermitted, isWildcardPermitted,
dnsProviderWildcardSupported, dnsProviderWildcardSupported, // onChange,
onChange,
}: DomainNamesFieldProps) { }: DomainNamesFieldProps) {
const { values, setFieldValue } = useFormikContext(); const { values, setFieldValue } = useFormikContext();
@ -76,7 +76,7 @@ function DomainNamesField({
setFieldValue("domainNames", doms); setFieldValue("domainNames", doms);
}; };
let helperTexts: string[] = []; const helperTexts: string[] = [];
if (maxDomains) { if (maxDomains) {
helperTexts.push( helperTexts.push(
intl.formatMessage({ id: "domain_names.max" }, { count: maxDomains }), intl.formatMessage({ id: "domain_names.max" }, { count: maxDomains }),
@ -110,7 +110,7 @@ function DomainNamesField({
/> />
{helperTexts.length {helperTexts.length
? helperTexts.map((i) => { ? helperTexts.map((i) => {
return <FormHelperText>{i}</FormHelperText>; return <FormHelperText key={i}>{i}</FormHelperText>;
}) })
: null} : null}
<FormErrorMessage>{form.errors.domainNames}</FormErrorMessage> <FormErrorMessage>{form.errors.domainNames}</FormErrorMessage>

View File

@ -5,7 +5,8 @@ import {
Switch, Switch,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { Field } from "formik"; import { Field } from "formik";
import { intl } from "locale";
import { intl } from "src/locale";
const fieldName = "isEcc"; const fieldName = "isEcc";

View File

@ -5,8 +5,9 @@ import {
Input, Input,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { Field } from "formik"; import { Field } from "formik";
import { intl } from "locale";
import { validateString } from "modules/Validations"; import { intl } from "src/locale";
import { validateString } from "src/modules/Validations";
function NameField() { function NameField() {
return ( return (

View File

@ -15,12 +15,13 @@ import {
Stack, Stack,
useToast, useToast,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { CertificateAuthority } from "api/npm";
import { PrettyButton } from "components";
import { Formik, Form, Field } from "formik"; import { Formik, Form, Field } from "formik";
import { useCertificateAuthority, useSetCertificateAuthority } from "hooks";
import { intl } from "locale"; import { CertificateAuthority } from "src/api/npm";
import { validateNumber, validateString } from "modules/Validations"; import { PrettyButton } from "src/components";
import { useCertificateAuthority, useSetCertificateAuthority } from "src/hooks";
import { intl } from "src/locale";
import { validateNumber, validateString } from "src/modules/Validations";
interface CertificateEditModalProps { interface CertificateEditModalProps {
editId: number; editId: number;

View File

@ -14,11 +14,12 @@ import {
Stack, Stack,
useToast, useToast,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { setAuth } from "api/npm";
import { PrettyButton } from "components";
import { Formik, Form, Field } from "formik"; import { Formik, Form, Field } from "formik";
import { intl } from "locale";
import { validateString } from "modules/Validations"; import { setAuth } from "src/api/npm";
import { PrettyButton } from "src/components";
import { intl } from "src/locale";
import { validateString } from "src/modules/Validations";
interface ChangePasswordModalProps { interface ChangePasswordModalProps {
isOpen: boolean; isOpen: boolean;
@ -75,7 +76,7 @@ function ChangePasswordModal({ isOpen, onClose }: ChangePasswordModalProps) {
} }
return errors; return errors;
}}> }}>
{({ isSubmitting, values }: any) => ( {({ isSubmitting }: any) => (
<Form data-testid="change-password"> <Form data-testid="change-password">
<ModalHeader> <ModalHeader>
{intl.formatMessage({ id: "change-password" })} {intl.formatMessage({ id: "change-password" })}

View File

@ -19,16 +19,17 @@ import {
useToast, useToast,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import Ajv, { Schema } from "ajv"; import Ajv, { Schema } from "ajv";
import { Formik, Form, Field, getIn } from "formik";
import { import {
DNSProvider, DNSProvider,
DNSProvidersAcmesh, DNSProvidersAcmesh,
DNSProvidersAcmeshProperty, DNSProvidersAcmeshProperty,
} from "api/npm"; } from "src/api/npm";
import { PrettyButton } from "components"; import { PrettyButton } from "src/components";
import { Formik, Form, Field, getIn } from "formik"; import { useSetDNSProvider, useDNSProvidersAcmesh } from "src/hooks";
import { useSetDNSProvider, useDNSProvidersAcmesh } from "hooks"; import { intl } from "src/locale";
import { intl } from "locale"; import { validateString } from "src/modules/Validations";
import { validateString } from "modules/Validations";
interface DNSProviderCreateModalProps { interface DNSProviderCreateModalProps {
isOpen: boolean; isOpen: boolean;
@ -82,7 +83,7 @@ function DNSProviderCreateModal({
try { try {
const valid = ajv.validate(fullItem as Schema, payload.meta); const valid = ajv.validate(fullItem as Schema, payload.meta);
if (!valid) { if (!valid) {
let errs: any = {}; const errs: any = {};
ajv.errors?.forEach((e: any) => { ajv.errors?.forEach((e: any) => {
errs["meta"] = { errs["meta"] = {
[e.instancePath.substring(1)]: e.message, [e.instancePath.substring(1)]: e.message,
@ -129,7 +130,7 @@ function DNSProviderCreateModal({
} }
let type = "text"; let type = "text";
let props: any = {}; const props: any = {};
if (f.type === "string") { if (f.type === "string") {
props.minLength = f.minLength || null; props.minLength = f.minLength || null;
@ -174,7 +175,7 @@ function DNSProviderCreateModal({
} as DNSProvider } as DNSProvider
} }
onSubmit={onSubmit}> onSubmit={onSubmit}>
{({ isSubmitting, handleChange, values, setValues }) => ( {({ isSubmitting, handleChange, values }) => (
<Form> <Form>
<ModalHeader> <ModalHeader>
{intl.formatMessage({ id: "dns-provider.create" })} {intl.formatMessage({ id: "dns-provider.create" })}
@ -244,11 +245,12 @@ function DNSProviderCreateModal({
)} )}
</Field> </Field>
{itemProperties {itemProperties
? Object.keys(itemProperties).map((fieldName, _) => { ? Object.keys(itemProperties).map((fieldName) => {
const f = itemProperties[fieldName]; const f = itemProperties[fieldName];
const name = `meta[${fieldName}]`; const name = `meta[${fieldName}]`;
return ( return (
<Field <Field
key={fieldName}
name={`meta[${fieldName}]`} name={`meta[${fieldName}]`}
type={ type={
f.type === "boolean" f.type === "boolean"

View File

@ -15,12 +15,13 @@ import {
Stack, Stack,
useToast, useToast,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { CertificateAuthority } from "api/npm";
import { PrettyButton } from "components";
import { Formik, Form, Field } from "formik"; import { Formik, Form, Field } from "formik";
import { useSetCertificateAuthority } from "hooks";
import { intl } from "locale"; import { CertificateAuthority } from "src/api/npm";
import { validateNumber, validateString } from "modules/Validations"; import { PrettyButton } from "src/components";
import { useSetCertificateAuthority } from "src/hooks";
import { intl } from "src/locale";
import { validateNumber, validateString } from "src/modules/Validations";
interface HostCreateModalProps { interface HostCreateModalProps {
isOpen: boolean; isOpen: boolean;

View File

@ -14,11 +14,12 @@ import {
Stack, Stack,
useToast, useToast,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { PrettyButton } from "components";
import { Formik, Form, Field } from "formik"; import { Formik, Form, Field } from "formik";
import { useUser, useSetUser } from "hooks";
import { intl } from "locale"; import { PrettyButton } from "src/components";
import { validateEmail, validateString } from "modules/Validations"; import { useUser, useSetUser } from "src/hooks";
import { intl } from "src/locale";
import { validateEmail, validateString } from "src/modules/Validations";
interface ProfileModalProps { interface ProfileModalProps {
isOpen: boolean; isOpen: boolean;

View File

@ -14,11 +14,12 @@ import {
Stack, Stack,
useToast, useToast,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { setAuth } from "api/npm";
import { PrettyButton } from "components";
import { Formik, Form, Field } from "formik"; import { Formik, Form, Field } from "formik";
import { intl } from "locale";
import { validateString } from "modules/Validations"; import { setAuth } from "src/api/npm";
import { PrettyButton } from "src/components";
import { intl } from "src/locale";
import { validateString } from "src/modules/Validations";
interface SetPasswordModalProps { interface SetPasswordModalProps {
userId: number; userId: number;
@ -75,7 +76,7 @@ function SetPasswordModal({ userId, isOpen, onClose }: SetPasswordModalProps) {
} }
return errors; return errors;
}}> }}>
{({ isSubmitting, values }: any) => ( {({ isSubmitting }: any) => (
<Form> <Form>
<ModalHeader> <ModalHeader>
{intl.formatMessage({ id: "set-password" })} {intl.formatMessage({ id: "set-password" })}

View File

@ -16,12 +16,13 @@ import {
Stack, Stack,
useToast, useToast,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { CertificateAuthority } from "api/npm";
import { PrettyButton } from "components";
import { Formik, Form, Field } from "formik"; import { Formik, Form, Field } from "formik";
import { useSetCertificateAuthority } from "hooks";
import { intl } from "locale"; import { CertificateAuthority } from "src/api/npm";
import { validateNumber, validateString } from "modules/Validations"; import { PrettyButton } from "src/components";
import { useSetCertificateAuthority } from "src/hooks";
import { intl } from "src/locale";
import { validateNumber, validateString } from "src/modules/Validations";
interface UpstreamCreateModalProps { interface UpstreamCreateModalProps {
isOpen: boolean; isOpen: boolean;

View File

@ -16,12 +16,13 @@ import {
Stack, Stack,
useToast, useToast,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { CertificateAuthority } from "api/npm";
import { PrettyButton } from "components";
import { Formik, Form, Field } from "formik"; import { Formik, Form, Field } from "formik";
import { useCertificateAuthority, useSetCertificateAuthority } from "hooks";
import { intl } from "locale"; import { CertificateAuthority } from "src/api/npm";
import { validateNumber, validateString } from "modules/Validations"; import { PrettyButton } from "src/components";
import { useCertificateAuthority, useSetCertificateAuthority } from "src/hooks";
import { intl } from "src/locale";
import { validateNumber, validateString } from "src/modules/Validations";
interface UpstreamEditModalProps { interface UpstreamEditModalProps {
editId: number; editId: number;

View File

@ -6,12 +6,13 @@ import {
ModalCloseButton, ModalCloseButton,
ModalBody, ModalBody,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { useUpstreamNginxConfig } from "hooks";
import { intl } from "locale";
import { Light as SyntaxHighlighter } from "react-syntax-highlighter"; import { Light as SyntaxHighlighter } from "react-syntax-highlighter";
import sh from "react-syntax-highlighter/dist/esm/languages/hljs/bash"; import sh from "react-syntax-highlighter/dist/esm/languages/hljs/bash";
import nord from "react-syntax-highlighter/dist/esm/styles/hljs/nord"; import nord from "react-syntax-highlighter/dist/esm/styles/hljs/nord";
import { useUpstreamNginxConfig } from "src/hooks";
import { intl } from "src/locale";
interface UpstreamNginxConfigModalProps { interface UpstreamNginxConfigModalProps {
upstreamId: number; upstreamId: number;
isOpen: boolean; isOpen: boolean;

View File

@ -21,16 +21,17 @@ import {
TabPanels, TabPanels,
useToast, useToast,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { createUser } from "api/npm"; import { useQueryClient } from "@tanstack/react-query";
import { Formik, Form, Field } from "formik";
import { createUser } from "src/api/npm";
import { import {
AdminPermissionSelector, AdminPermissionSelector,
PermissionSelector, PermissionSelector,
PrettyButton, PrettyButton,
} from "components"; } from "src/components";
import { Formik, Form, Field } from "formik"; import { intl } from "src/locale";
import { intl } from "locale"; import { validateEmail, validateString } from "src/modules/Validations";
import { validateEmail, validateString } from "modules/Validations";
import { useQueryClient } from "react-query";
interface Payload { interface Payload {
name: string; name: string;
@ -50,7 +51,7 @@ function UserCreateModal({ isOpen, onClose }: UserCreateModalProps) {
const [capabilityOption, setCapabilityOption] = useState("admin"); const [capabilityOption, setCapabilityOption] = useState("admin");
const onSubmit = async (values: Payload, { setSubmitting }: any) => { const onSubmit = async (values: Payload, { setSubmitting }: any) => {
const { password, ...payload } = { const { ...payload } = {
...values, ...values,
...{ ...{
isDisabled: false, isDisabled: false,
@ -78,7 +79,7 @@ function UserCreateModal({ isOpen, onClose }: UserCreateModalProps) {
const response = await createUser(payload); const response = await createUser(payload);
if (response && typeof response.id !== "undefined" && response.id) { if (response && typeof response.id !== "undefined" && response.id) {
// ok // ok
queryClient.invalidateQueries("users"); queryClient.invalidateQueries(["users"]);
onClose(); onClose();
resetForm(); resetForm();
} else { } else {

View File

@ -22,15 +22,16 @@ import {
TabPanels, TabPanels,
useToast, useToast,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { Formik, Form, Field } from "formik";
import { import {
AdminPermissionSelector, AdminPermissionSelector,
PermissionSelector, PermissionSelector,
PrettyButton, PrettyButton,
} from "components"; } from "src/components";
import { Formik, Form, Field } from "formik"; import { useUser, useSetUser } from "src/hooks";
import { useUser, useSetUser } from "hooks"; import { intl } from "src/locale";
import { intl } from "locale"; import { validateEmail, validateString } from "src/modules/Validations";
import { validateEmail, validateString } from "modules/Validations";
interface UserEditModalProps { interface UserEditModalProps {
userId: number; userId: number;

View File

@ -1,4 +1,4 @@
import { TokenResponse } from "api/npm"; import { TokenResponse } from "src/api/npm";
export const TOKEN_KEY = "authentications"; export const TOKEN_KEY = "authentications";

View File

@ -1,4 +1,4 @@
import { intl } from "locale"; import { intl } from "src/locale";
const validateString = (minLength = 0, maxLength = 0) => { const validateString = (minLength = 0, maxLength = 0) => {
if (minLength <= 0 && maxLength <= 0) { if (minLength <= 0 && maxLength <= 0) {

View File

@ -1,5 +1,8 @@
import { useEffect, useMemo } from "react"; import { useEffect, useMemo } from "react";
import { FiEdit } from "react-icons/fi";
import { useSortBy, useFilters, useTable, usePagination } from "react-table";
import { import {
tableEvents, tableEvents,
ActionsFormatter, ActionsFormatter,
@ -9,10 +12,8 @@ import {
TablePagination, TablePagination,
TableSortBy, TableSortBy,
TextFilter, TextFilter,
} from "components"; } from "src/components";
import { intl } from "locale"; import { intl } from "src/locale";
import { FiEdit } from "react-icons/fi";
import { useSortBy, useFilters, useTable, usePagination } from "react-table";
export interface TableProps { export interface TableProps {
data: any; data: any;
@ -48,7 +49,7 @@ function Table({
Cell: ActionsFormatter([ Cell: ActionsFormatter([
{ {
title: intl.formatMessage({ id: "action.edit" }), title: intl.formatMessage({ id: "action.edit" }),
onClick: (e: any, data: any) => { onClick: (_: any, data: any) => {
alert(JSON.stringify(data, null, 2)); alert(JSON.stringify(data, null, 2));
}, },
icon: <FiEdit />, icon: <FiEdit />,

View File

@ -1,14 +1,15 @@
import { useEffect, useReducer, useState } from "react"; import { useEffect, useReducer, useState } from "react";
import { Alert, AlertIcon } from "@chakra-ui/react"; import { Alert, AlertIcon } from "@chakra-ui/react";
import { import {
EmptyList, EmptyList,
PrettyButton, PrettyButton,
SpinnerPage, SpinnerPage,
tableEventReducer, tableEventReducer,
} from "components"; } from "src/components";
import { useAccessLists } from "hooks"; import { useAccessLists } from "src/hooks";
import { intl } from "locale"; import { intl } from "src/locale";
import Table from "./Table"; import Table from "./Table";

View File

@ -1,9 +1,10 @@
import { useState } from "react"; import { useState } from "react";
import { Heading, HStack } from "@chakra-ui/react"; import { Heading, HStack } from "@chakra-ui/react";
import { HelpDrawer, PrettyButton } from "components";
import { intl } from "locale"; import { HelpDrawer, PrettyButton } from "src/components";
import { AccessListCreateModal } from "modals"; import { intl } from "src/locale";
import { AccessListCreateModal } from "src/modals";
import TableWrapper from "./TableWrapper"; import TableWrapper from "./TableWrapper";

View File

@ -1,5 +1,6 @@
import { Heading } from "@chakra-ui/react"; import { Heading } from "@chakra-ui/react";
import { intl } from "locale";
import { intl } from "src/locale";
function AuditLog() { function AuditLog() {
return ( return (

View File

@ -1,5 +1,8 @@
import { useEffect, useMemo, useState } from "react"; import { useEffect, useMemo, useState } from "react";
import { FiEdit } from "react-icons/fi";
import { useSortBy, useFilters, useTable, usePagination } from "react-table";
import { import {
tableEvents, tableEvents,
ActionsFormatter, ActionsFormatter,
@ -9,11 +12,9 @@ import {
TablePagination, TablePagination,
TableSortBy, TableSortBy,
TextFilter, TextFilter,
} from "components"; } from "src/components";
import { intl } from "locale"; import { intl } from "src/locale";
import { CertificateAuthorityEditModal } from "modals"; import { CertificateAuthorityEditModal } from "src/modals";
import { FiEdit } from "react-icons/fi";
import { useSortBy, useFilters, useTable, usePagination } from "react-table";
export interface TableProps { export interface TableProps {
data: any; data: any;
@ -58,7 +59,7 @@ function Table({
title: intl.formatMessage({ title: intl.formatMessage({
id: "action.edit", id: "action.edit",
}), }),
onClick: (e: any, { id }: any) => setEditId(id), onClick: (_: any, { id }: any) => setEditId(id),
icon: <FiEdit />, icon: <FiEdit />,
disabled: (data: any) => data.isReadonly, disabled: (data: any) => data.isReadonly,
}, },

View File

@ -1,8 +1,9 @@
import { useEffect, useReducer, useState } from "react"; import { useEffect, useReducer, useState } from "react";
import { Alert, AlertIcon } from "@chakra-ui/react"; import { Alert, AlertIcon } from "@chakra-ui/react";
import { SpinnerPage, tableEventReducer } from "components";
import { useCertificateAuthorities } from "hooks"; import { SpinnerPage, tableEventReducer } from "src/components";
import { useCertificateAuthorities } from "src/hooks";
import Table from "./Table"; import Table from "./Table";

View File

@ -1,9 +1,10 @@
import { useState } from "react"; import { useState } from "react";
import { Heading, HStack } from "@chakra-ui/react"; import { Heading, HStack } from "@chakra-ui/react";
import { HelpDrawer, PrettyButton } from "components";
import { intl } from "locale"; import { HelpDrawer, PrettyButton } from "src/components";
import { CertificateAuthorityCreateModal } from "modals"; import { intl } from "src/locale";
import { CertificateAuthorityCreateModal } from "src/modals";
import TableWrapper from "./TableWrapper"; import TableWrapper from "./TableWrapper";

View File

@ -1,5 +1,8 @@
import { useEffect, useMemo, useState } from "react"; import { useEffect, useMemo, useState } from "react";
import { FiDownload, FiEdit, FiRefreshCw, FiTrash2 } from "react-icons/fi";
import { useSortBy, useFilters, useTable, usePagination } from "react-table";
import { import {
tableEvents, tableEvents,
ActionsFormatter, ActionsFormatter,
@ -13,11 +16,9 @@ import {
TablePagination, TablePagination,
TableSortBy, TableSortBy,
TextFilter, TextFilter,
} from "components"; } from "src/components";
import { intl } from "locale"; import { intl } from "src/locale";
import { CertificateEditModal } from "modals"; import { CertificateEditModal } from "src/modals";
import { FiDownload, FiEdit, FiRefreshCw, FiTrash2 } from "react-icons/fi";
import { useSortBy, useFilters, useTable, usePagination } from "react-table";
export interface TableProps { export interface TableProps {
data: any; data: any;
@ -78,7 +79,7 @@ function Table({
title: intl.formatMessage({ title: intl.formatMessage({
id: "action.edit", id: "action.edit",
}), }),
onClick: (e: any, { id }: any) => alert(id), onClick: (_: any, { id }: any) => alert(id),
icon: <FiEdit />, icon: <FiEdit />,
disabled: (data: any) => disabled: (data: any) =>
data.type === "dns" || data.type === "http", data.type === "dns" || data.type === "http",
@ -87,7 +88,7 @@ function Table({
title: intl.formatMessage({ title: intl.formatMessage({
id: "action.renew", id: "action.renew",
}), }),
onClick: (e: any, { id }: any) => onRenewal(id), onClick: (_: any, { id }: any) => onRenewal(id),
icon: <FiRefreshCw />, icon: <FiRefreshCw />,
disabled: (data: any) => disabled: (data: any) =>
data.type !== "dns" && data.type !== "http", data.type !== "dns" && data.type !== "http",
@ -96,7 +97,7 @@ function Table({
title: intl.formatMessage({ title: intl.formatMessage({
id: "action.download", id: "action.download",
}), }),
onClick: (e: any, { id }: any) => alert(id), onClick: (_: any, { id }: any) => alert(id),
icon: <FiDownload />, icon: <FiDownload />,
disabled: (data: any) => data.isReadonly, disabled: (data: any) => data.isReadonly,
}, },
@ -104,7 +105,7 @@ function Table({
title: intl.formatMessage({ title: intl.formatMessage({
id: "action.delete", id: "action.delete",
}), }),
onClick: (e: any, { id }: any) => alert(id), onClick: (_: any, { id }: any) => alert(id),
icon: <FiTrash2 />, icon: <FiTrash2 />,
disabled: (data: any) => data.isReadonly, disabled: (data: any) => data.isReadonly,
}, },

View File

@ -1,11 +1,12 @@
import { useEffect, useReducer, useState } from "react"; import { useEffect, useReducer, useState } from "react";
import { Alert, AlertIcon, useToast } from "@chakra-ui/react"; import { Alert, AlertIcon, useToast } from "@chakra-ui/react";
import { renewCertificate } from "api/npm"; import { useQueryClient } from "@tanstack/react-query";
import { EmptyList, SpinnerPage, tableEventReducer } from "components";
import { useCertificates } from "hooks"; import { renewCertificate } from "src/api/npm";
import { intl } from "locale"; import { EmptyList, SpinnerPage, tableEventReducer } from "src/components";
import { useQueryClient } from "react-query"; import { useCertificates } from "src/hooks";
import { intl } from "src/locale";
import Table from "./Table"; import Table from "./Table";
@ -54,7 +55,7 @@ function TableWrapper() {
isClosable: true, isClosable: true,
}); });
setTimeout(() => { setTimeout(() => {
queryClient.invalidateQueries("certificates"); queryClient.invalidateQueries(["certificates"]);
}, 500); }, 500);
} catch (err: any) { } catch (err: any) {
toast({ toast({

View File

@ -8,12 +8,13 @@ import {
MenuItem, MenuItem,
MenuDivider, MenuDivider,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { HelpDrawer, PrettyMenuButton } from "components";
import { useDNSProviders } from "hooks";
import { intl } from "locale";
import { CertificateCreateModal } from "modals";
import { FiGlobe, FiServer, FiShieldOff, FiUpload } from "react-icons/fi"; import { FiGlobe, FiServer, FiShieldOff, FiUpload } from "react-icons/fi";
import { HelpDrawer, PrettyMenuButton } from "src/components";
import { useDNSProviders } from "src/hooks";
import { intl } from "src/locale";
import { CertificateCreateModal } from "src/modals";
import TableWrapper from "./TableWrapper"; import TableWrapper from "./TableWrapper";
function Certificates() { function Certificates() {

View File

@ -1,5 +1,8 @@
import { useEffect, useMemo } from "react"; import { useEffect, useMemo } from "react";
import { FiEdit } from "react-icons/fi";
import { useSortBy, useFilters, useTable, usePagination } from "react-table";
import { import {
tableEvents, tableEvents,
ActionsFormatter, ActionsFormatter,
@ -11,10 +14,8 @@ import {
TablePagination, TablePagination,
TableSortBy, TableSortBy,
TextFilter, TextFilter,
} from "components"; } from "src/components";
import { intl } from "locale"; import { intl } from "src/locale";
import { FiEdit } from "react-icons/fi";
import { useSortBy, useFilters, useTable, usePagination } from "react-table";
export interface TableProps { export interface TableProps {
data: any; data: any;
@ -63,7 +64,7 @@ function Table({
Cell: ActionsFormatter([ Cell: ActionsFormatter([
{ {
title: intl.formatMessage({ id: "action.edit" }), title: intl.formatMessage({ id: "action.edit" }),
onClick: (e: any, data: any) => { onClick: (_: any, data: any) => {
alert(JSON.stringify(data, null, 2)); alert(JSON.stringify(data, null, 2));
}, },
icon: <FiEdit />, icon: <FiEdit />,

View File

@ -1,14 +1,15 @@
import { useEffect, useReducer, useState } from "react"; import { useEffect, useReducer, useState } from "react";
import { Alert, AlertIcon } from "@chakra-ui/react"; import { Alert, AlertIcon } from "@chakra-ui/react";
import { import {
EmptyList, EmptyList,
PrettyButton, PrettyButton,
SpinnerPage, SpinnerPage,
tableEventReducer, tableEventReducer,
} from "components"; } from "src/components";
import { useDNSProviders } from "hooks"; import { useDNSProviders } from "src/hooks";
import { intl } from "locale"; import { intl } from "src/locale";
import Table from "./Table"; import Table from "./Table";

View File

@ -1,9 +1,10 @@
import { useState } from "react"; import { useState } from "react";
import { Heading, HStack } from "@chakra-ui/react"; import { Heading, HStack } from "@chakra-ui/react";
import { HelpDrawer, PrettyButton } from "components";
import { intl } from "locale"; import { HelpDrawer, PrettyButton } from "src/components";
import { DNSProviderCreateModal } from "modals"; import { intl } from "src/locale";
import { DNSProviderCreateModal } from "src/modals";
import TableWrapper from "./TableWrapper"; import TableWrapper from "./TableWrapper";

View File

@ -1,5 +1,6 @@
import { Heading } from "@chakra-ui/react"; import { Heading } from "@chakra-ui/react";
import { intl } from "locale";
import { intl } from "src/locale";
function Dashboard() { function Dashboard() {
return ( return (

View File

@ -1,5 +1,8 @@
import { useEffect, useMemo } from "react"; import { useEffect, useMemo } from "react";
import { FiEdit } from "react-icons/fi";
import { useSortBy, useFilters, useTable, usePagination } from "react-table";
import { import {
tableEvents, tableEvents,
ActionsFormatter, ActionsFormatter,
@ -13,10 +16,8 @@ import {
TablePagination, TablePagination,
TableSortBy, TableSortBy,
TextFilter, TextFilter,
} from "components"; } from "src/components";
import { intl } from "locale"; import { intl } from "src/locale";
import { FiEdit } from "react-icons/fi";
import { useSortBy, useFilters, useTable, usePagination } from "react-table";
export interface TableProps { export interface TableProps {
data: any; data: any;
@ -74,7 +75,7 @@ function Table({
Cell: ActionsFormatter([ Cell: ActionsFormatter([
{ {
title: intl.formatMessage({ id: "action.edit" }), title: intl.formatMessage({ id: "action.edit" }),
onClick: (e: any, data: any) => { onClick: (_: any, data: any) => {
alert(JSON.stringify(data, null, 2)); alert(JSON.stringify(data, null, 2));
}, },
icon: <FiEdit />, icon: <FiEdit />,

View File

@ -1,14 +1,15 @@
import { useEffect, useReducer, useState } from "react"; import { useEffect, useReducer, useState } from "react";
import { Alert, AlertIcon } from "@chakra-ui/react"; import { Alert, AlertIcon } from "@chakra-ui/react";
import { import {
EmptyList, EmptyList,
PrettyButton, PrettyButton,
SpinnerPage, SpinnerPage,
tableEventReducer, tableEventReducer,
} from "components"; } from "src/components";
import { useHosts } from "hooks"; import { useHosts } from "src/hooks";
import { intl } from "locale"; import { intl } from "src/locale";
import Table from "./Table"; import Table from "./Table";

View File

@ -1,9 +1,10 @@
import { useState } from "react"; import { useState } from "react";
import { Heading, HStack } from "@chakra-ui/react"; import { Heading, HStack } from "@chakra-ui/react";
import { HelpDrawer, PrettyButton } from "components";
import { intl } from "locale"; import { HelpDrawer, PrettyButton } from "src/components";
import { HostCreateModal } from "modals"; import { intl } from "src/locale";
import { HostCreateModal } from "src/modals";
import TableWrapper from "./TableWrapper"; import TableWrapper from "./TableWrapper";

View File

@ -12,13 +12,14 @@ import {
useColorModeValue, useColorModeValue,
useToast, useToast,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { LocalePicker, PrettyButton, ThemeSwitcher } from "components";
import { useAuthState } from "context";
import { Formik, Form, Field } from "formik"; import { Formik, Form, Field } from "formik";
import { intl } from "locale";
import { validateEmail, validateString } from "modules/Validations";
import logo from "../../img/logo-256.png"; import { LocalePicker, PrettyButton, ThemeSwitcher } from "src/components";
import { useAuthState } from "src/context";
import { intl } from "src/locale";
import { validateEmail, validateString } from "src/modules/Validations";
// import logo from "../../img/logo-256.png";
function Login() { function Login() {
const toast = useToast(); const toast = useToast();
@ -67,7 +68,7 @@ function Login() {
<Stack spacing={8} mx="auto" maxW="md" w="full" py={4} px={6}> <Stack spacing={8} mx="auto" maxW="md" w="full" py={4} px={6}>
<Box> <Box>
<Center> <Center>
<img src={logo} width={100} alt="Logo" /> <img src="/images/logo-256.png" width={100} alt="Logo" />
</Center> </Center>
</Box> </Box>
<Box <Box

View File

@ -1,5 +1,8 @@
import { useEffect, useMemo } from "react"; import { useEffect, useMemo } from "react";
import { FiEdit } from "react-icons/fi";
import { useSortBy, useFilters, useTable, usePagination } from "react-table";
import { import {
tableEvents, tableEvents,
ActionsFormatter, ActionsFormatter,
@ -10,15 +13,13 @@ import {
TablePagination, TablePagination,
TableSortBy, TableSortBy,
TextFilter, TextFilter,
} from "components"; } from "src/components";
import { intl } from "locale"; import { intl } from "src/locale";
import { FiEdit } from "react-icons/fi";
import { useSortBy, useFilters, useTable, usePagination } from "react-table";
const rowActions = [ const rowActions = [
{ {
title: intl.formatMessage({ id: "action.edit" }), title: intl.formatMessage({ id: "action.edit" }),
onClick: (e: any, data: any) => { onClick: (_: any, data: any) => {
alert(JSON.stringify(data, null, 2)); alert(JSON.stringify(data, null, 2));
}, },
icon: <FiEdit />, icon: <FiEdit />,

View File

@ -1,14 +1,15 @@
import { useEffect, useReducer, useState } from "react"; import { useEffect, useReducer, useState } from "react";
import { Alert, AlertIcon, Heading, HStack } from "@chakra-ui/react"; import { Alert, AlertIcon, Heading, HStack } from "@chakra-ui/react";
import { import {
HelpDrawer, HelpDrawer,
PrettyButton, PrettyButton,
SpinnerPage, SpinnerPage,
tableEventReducer, tableEventReducer,
} from "components"; } from "src/components";
import { useNginxTemplates } from "hooks"; import { useNginxTemplates } from "src/hooks";
import { intl } from "locale"; import { intl } from "src/locale";
import { NginxTemplatesTable } from "./NginxTemplatesTable"; import { NginxTemplatesTable } from "./NginxTemplatesTable";

View File

@ -1,5 +1,8 @@
import { useEffect, useMemo } from "react"; import { useEffect, useMemo } from "react";
import { FiEdit } from "react-icons/fi";
import { useSortBy, useFilters, useTable, usePagination } from "react-table";
import { import {
tableEvents, tableEvents,
ActionsFormatter, ActionsFormatter,
@ -8,15 +11,13 @@ import {
TablePagination, TablePagination,
TableSortBy, TableSortBy,
TextFilter, TextFilter,
} from "components"; } from "src/components";
import { intl } from "locale"; import { intl } from "src/locale";
import { FiEdit } from "react-icons/fi";
import { useSortBy, useFilters, useTable, usePagination } from "react-table";
const rowActions = [ const rowActions = [
{ {
title: intl.formatMessage({ id: "action.edit" }), title: intl.formatMessage({ id: "action.edit" }),
onClick: (e: any, data: any) => { onClick: (_: any, data: any) => {
alert(JSON.stringify(data, null, 2)); alert(JSON.stringify(data, null, 2));
}, },
icon: <FiEdit />, icon: <FiEdit />,

Some files were not shown because too many files have changed in this diff Show More