diff --git a/.gitignore b/.gitignore index 5a8c262..45ab3c8 100644 --- a/.gitignore +++ b/.gitignore @@ -20,8 +20,14 @@ Thumbs.db # Other .idea +.yarn node_modules/ web/build bin/ log/ dist/ +# If needed, package-lock.json shall be added +# manually using an explicit git add command. +package-lock.json +# Ditto for yarn, except we're using npm. +yarn.lock diff --git a/web/package.json b/web/package.json index 4863656..cb419eb 100644 --- a/web/package.json +++ b/web/package.json @@ -26,13 +26,9 @@ "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", - "eject": "react-scripts eject" - }, - "eslintConfig": { - "extends": [ - "react-app", - "react-app/jest" - ] + "eject": "react-scripts eject", + "lint": "esw src/ --ext \".ts,.tsx,.js,.jsx\" --color", + "lint:watch": "npm run lint -- --watch" }, "browserslist": { "production": [ @@ -57,9 +53,70 @@ "@types/react-dom": "^17.0.0", "@types/react-router-dom": "^5.1.7", "@types/react-table": "^7.7.7", + "@typescript-eslint/eslint-plugin": "^5.10.2", + "@typescript-eslint/parser": "^5.10.2", "autoprefixer": "^10.4.2", + "eslint": "^8.8.0", + "eslint-plugin-import": "^2.25.4", + "eslint-plugin-react": "^7.28.0", + "eslint-plugin-react-hooks": "^4.3.0", + "eslint-watch": "^8.0.0", "postcss": "^8.4.6", "tailwindcss": "^3.0.18", "typescript": "^4.1.2" + }, + "eslintConfig": { + "root": true, + "extends": [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:import/errors", + "plugin:import/warnings", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:react-hooks/recommended" + ], + "plugins": [ + "react", + "@typescript-eslint" + ], + "rules": { + "react/jsx-uses-react": "off", + "react/react-in-jsx-scope": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-explicit-any": "off" + }, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 11, + "sourceType": "module", + "ecmaFeatures": { + "jsx": true, + "experimentalObjectRestSpread": true + } + }, + "settings": { + "react": { + "version": "detect" + }, + "import/resolver": { + "node": { + "extensions": [ + ".ts", + ".tsx", + ".js", + ".jsx" + ] + } + } + }, + "env": { + "browser": true, + "node": true, + "jquery": false + }, + "globals": {} } } diff --git a/web/src/App.tsx b/web/src/App.tsx index 2118273..6040d10 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -39,4 +39,4 @@ export function App() { ) : null} ) -}; \ No newline at end of file +} \ No newline at end of file diff --git a/web/src/api/APIClient.ts b/web/src/api/APIClient.ts index d87efa2..846f3be 100644 --- a/web/src/api/APIClient.ts +++ b/web/src/api/APIClient.ts @@ -1,7 +1,7 @@ import {baseUrl, sseBaseUrl} from "../utils"; function baseClient(endpoint: string, method: string, { body, ...customConfig}: any = {}) { - let baseURL = baseUrl() + const baseURL = baseUrl() const headers = {'content-type': 'application/json'} const config = { diff --git a/web/src/components/inputs/common.tsx b/web/src/components/inputs/common.tsx index df9b992..14db192 100644 --- a/web/src/components/inputs/common.tsx +++ b/web/src/components/inputs/common.tsx @@ -1,4 +1,3 @@ -import React from "react"; import { Field } from "formik"; interface ErrorFieldProps { @@ -7,7 +6,7 @@ interface ErrorFieldProps { subscribe?: any; } -const ErrorField: React.FC = ({ name, classNames }) => ( +const ErrorField = ({ name, classNames }: ErrorFieldProps) => ( {({ meta: { touched, error } }: any) => touched && error ? {error} : null @@ -21,7 +20,11 @@ interface CheckboxFieldProps { sublabel?: string; } -const CheckboxField: React.FC = ({ name, label, sublabel }) => ( +const CheckboxField = ({ + name, + label, + sublabel +}: CheckboxFieldProps) => (
= ({ name, label, placeholder, columns, className, autoComplete }) => ( +export const TextField = ({ + name, + label, + placeholder, + columns, + autoComplete +}: TextFieldProps) => (
= ({ name, label, placeholder, defaultValue, columns, className, autoComplete, help, required }) => { +export const PasswordField = ({ + name, + label, + placeholder, + defaultValue, + columns, + autoComplete, + help, + required +}: PasswordFieldProps) => { const [isVisible, toggleVisibility] = useToggle(false) return ( @@ -113,17 +125,13 @@ interface NumberFieldProps { name: string; label?: string; placeholder?: string; - className?: string; - required?: boolean; } -const NumberField: React.FC = ({ +export const NumberField = ({ name, label, - placeholder, - required, - className, -}) => ( + placeholder +}: NumberFieldProps) => (
); - -export { TextField, PasswordField, NumberField }; diff --git a/web/src/components/inputs/input_wide.tsx b/web/src/components/inputs/input_wide.tsx index 33c9c75..bfda7ca 100644 --- a/web/src/components/inputs/input_wide.tsx +++ b/web/src/components/inputs/input_wide.tsx @@ -1,5 +1,5 @@ -import React from "react"; -import { Field, FieldProps } from "formik"; +import { Field } from "formik"; +import type { FieldProps } from "formik"; import { classNames } from "../../utils"; import { useToggle } from "../../hooks/hooks"; import { EyeIcon, EyeOffIcon } from "@heroicons/react/solid"; @@ -12,12 +12,19 @@ interface TextFieldWideProps { help?: string; placeholder?: string; defaultValue?: string; - className?: string; required?: boolean; hidden?: boolean; } -const TextFieldWide: React.FC = ({ name, label, help, placeholder, defaultValue, required, hidden, className }) => ( +export const TextFieldWide = ({ + name, + label, + help, + placeholder, + defaultValue, + required, + hidden +}: TextFieldWideProps) => (