diff --git a/packages/web/.eslintignore b/packages/web/.eslintignore deleted file mode 100644 index 49a23822..00000000 --- a/packages/web/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -node_modules -build -source -.eslintrc.js diff --git a/packages/web/.eslintrc.js b/packages/web/.eslintrc.js deleted file mode 100644 index 50134026..00000000 --- a/packages/web/.eslintrc.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - extends: [ - 'react-app', - 'plugin:@tanstack/eslint-plugin-query/recommended', - 'prettier', - ], - rules: { - 'react/prop-types': 'warn', - }, -}; diff --git a/packages/web/README.md b/packages/web/README.md index b58e0af8..a2a17fad 100644 --- a/packages/web/README.md +++ b/packages/web/README.md @@ -1,6 +1,4 @@ -# Getting Started with Create React App - -This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). +# Getting Started ## Available Scripts @@ -9,16 +7,11 @@ In the project directory, you can run: ### `yarn start` Runs the app in the development mode.\ -Open [http://localhost:3000](http://localhost:3000) to view it in the browser. +Open [http://localhost:3001](http://localhost:3001) to view it in the browser. The page will reload if you make edits.\ You will also see any lint errors in the console. -### `yarn test` - -Launches the test runner in the interactive watch mode.\ -See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. - ### `yarn build` Builds the app for production to the `build` folder.\ @@ -28,19 +21,3 @@ The build is minified and the filenames include the hashes.\ Your app is ready to be deployed! See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. - -### `yarn eject` - -**Note: this is a one-way operation. Once you `eject`, you can’t go back!** - -If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. - -Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. - -You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. - -## Learn More - -You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). - -To learn React, check out the [React documentation](https://reactjs.org/). diff --git a/packages/web/eslint.config.mjs b/packages/web/eslint.config.mjs new file mode 100644 index 00000000..fcc3b88a --- /dev/null +++ b/packages/web/eslint.config.mjs @@ -0,0 +1,39 @@ +import js from '@eslint/js'; +import prettier from 'eslint-config-prettier'; +import reactPlugin from 'eslint-plugin-react'; +import reactHooksPlugin from 'eslint-plugin-react-hooks'; +import globals from 'globals'; + +export default [ + js.configs.recommended, + { + files: ['**/*.{js,jsx}'], + languageOptions: { + ecmaVersion: 2022, + sourceType: 'module', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + globals: { + ...globals.browser, + document: 'readonly', + window: 'readonly', + console: 'readonly', + JSX: true, + }, + }, + plugins: { + react: reactPlugin, + 'react-hooks': reactHooksPlugin, + }, + rules: { + ...reactPlugin.configs.recommended.rules, + ...reactHooksPlugin.configs.recommended.rules, + 'react/prop-types': 'warn', + 'react/react-in-jsx-scope': 'off', + }, + }, + prettier, +]; diff --git a/packages/web/public/index.html b/packages/web/index.html similarity index 97% rename from packages/web/public/index.html rename to packages/web/index.html index 3c6345fb..a077737d 100644 --- a/packages/web/public/index.html +++ b/packages/web/index.html @@ -71,7 +71,7 @@ transform: translateY(-40px); } - +
diff --git a/packages/web/jsconfig.json b/packages/web/jsconfig.json index 5875dc5b..8a9c96fb 100644 --- a/packages/web/jsconfig.json +++ b/packages/web/jsconfig.json @@ -1,6 +1,17 @@ { "compilerOptions": { - "baseUrl": "src" + "baseUrl": "src", + "paths": { + "components/*": ["components/*"], + "config/*": ["config/*"], + "contexts/*": ["contexts/*"], + "helpers/*": ["helpers/*"], + "hooks/*": ["hooks/*"], + "locales/*": ["locales/*"], + "pages/*": ["pages/*"], + "propTypes/*": ["propTypes/*"], + "styles/*": ["styles/*"] + } }, "include": ["src"] } diff --git a/packages/web/package.json b/packages/web/package.json index 2d54761a..057cb981 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -16,9 +16,6 @@ "@mui/material": "^5.11.10", "@mui/x-date-pickers": "^7.28.0", "@tanstack/react-query": "^5.24.1", - "@testing-library/jest-dom": "^5.11.4", - "@testing-library/react": "^11.1.0", - "@testing-library/user-event": "^12.1.10", "@xyflow/react": "^12.4.4", "axios": "^1.6.0", "clipboard-copy": "^4.0.1", @@ -29,29 +26,26 @@ "notistack": "^3.0.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-hook-form": "^7.45.2", + "react-hook-form": "7.53.2", "react-intl": "^5.20.12", "react-json-tree": "^0.16.2", "react-router-dom": "^6.0.2", - "react-scripts": "5.0.0", "react-window": "^1.8.9", "slate": "^0.94.1", "slate-history": "^0.93.0", "slate-react": "^0.94.2", "slugify": "^1.6.6", "uuid": "^9.0.0", - "web-vitals": "^1.0.1", "yup": "^0.32.11" }, "main": "index.js", "scripts": { - "dev": "react-scripts start", - "build": "react-scripts build", - "build:watch": "yarn nodemon --exec react-scripts build --watch 'src/**/*.ts' --watch 'public/**/*' --ext ts,html", - "test": "react-scripts test", - "eject": "react-scripts eject", + "dev": "vite", + "build": "vite build", + "build:watch": "yarn nodemon --exec vite build --watch 'src/**/*.ts' --watch 'public/**/*' --ext ts,html", "lint": "eslint src --ext .js,.jsx", - "prepack": "yarn build" + "prepack": "yarn build", + "preview": "vite preview" }, "files": [ "/build" @@ -85,16 +79,24 @@ "access": "public" }, "devDependencies": { - "@tanstack/eslint-plugin-query": "^5.20.1", + "@emotion/babel-plugin": "^11.13.5", + "@svgr/core": "^8.1.0", + "@svgr/plugin-jsx": "^8.1.0", "@tanstack/react-query-devtools": "^5.24.1", + "@testing-library/jest-dom": "^5.11.4", + "@testing-library/react": "^11.1.0", + "@testing-library/user-event": "^12.1.10", + "@vitejs/plugin-react": "^4.3.4", + "@welldone-software/why-did-you-render": "^8", + "eslint": "^9.25.1", "eslint-config-prettier": "^9.1.0", "eslint-config-react-app": "^7.0.1", - "prettier": "^3.2.5" - }, - "eslintConfig": { - "extends": [ - "./.eslintrc.js" - ] + "eslint-plugin-react-hooks": "^5.2.0", + "globals": "^16.0.0", + "prettier": "^3.2.5", + "vite": "^6.1.0", + "vite-plugin-eslint": "^1.8.1", + "vite-tsconfig-paths": "^4.3.2" }, "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/packages/web/src/components/AccountDropdownMenu/index.jsx b/packages/web/src/components/AccountDropdownMenu/index.jsx index 0bfb2ad7..1adb8a46 100644 --- a/packages/web/src/components/AccountDropdownMenu/index.jsx +++ b/packages/web/src/components/AccountDropdownMenu/index.jsx @@ -69,7 +69,7 @@ AccountDropdownMenu.propTypes = { onClose: PropTypes.func.isRequired, anchorEl: PropTypes.oneOfType([ PropTypes.func, - PropTypes.shape({ current: PropTypes.instanceOf(Element) }), + PropTypes.shape({ current: PropTypes.instanceOf(window.Element) }), ]), id: PropTypes.string.isRequired, }; diff --git a/packages/web/src/components/AdminApplicationSettings/index.jsx b/packages/web/src/components/AdminApplicationSettings/index.jsx index 9f20281d..e1d853cf 100644 --- a/packages/web/src/components/AdminApplicationSettings/index.jsx +++ b/packages/web/src/components/AdminApplicationSettings/index.jsx @@ -43,7 +43,7 @@ function AdminApplicationSettings({ appKey }) { 'data-test': 'snackbar-save-admin-apps-settings-success', }, }); - } catch (error) { + } catch { throw new Error('Failed while saving!'); } }; diff --git a/packages/web/src/components/AdminApplicationUpdateOAuthClient/index.jsx b/packages/web/src/components/AdminApplicationUpdateOAuthClient/index.jsx index 96844aec..894ae261 100644 --- a/packages/web/src/components/AdminApplicationUpdateOAuthClient/index.jsx +++ b/packages/web/src/components/AdminApplicationUpdateOAuthClient/index.jsx @@ -37,18 +37,17 @@ function AdminApplicationUpdateOAuthClient(props) { if (!adminOAuthClient) { return; } - const { name, active, ...formattedAuthDefaults } = values; setAuthDefaultsUpdatePending(true); - await updateOAuthClient({ - formattedAuthDefaults, - }).finally(() => { + + await updateOAuthClient(values.formattedAuthDefaults).finally(() => { setAuthDefaultsUpdatePending(false); }); + setDefaultValues((prev) => ({ name: prev.name, active: prev.active, - ...formattedAuthDefaults, + ...values.formattedAuthDefaults, })); enqueueSnackbar(formatMessage('updateOAuthClient.success'), { diff --git a/packages/web/src/components/AdminSettingsLayout/index.jsx b/packages/web/src/components/AdminSettingsLayout/index.jsx index 6fbc024a..1278e6ec 100644 --- a/packages/web/src/components/AdminSettingsLayout/index.jsx +++ b/packages/web/src/components/AdminSettingsLayout/index.jsx @@ -24,7 +24,6 @@ import useCurrentUserAbility from 'hooks/useCurrentUserAbility'; import Footer from './Footer'; function createDrawerLinks({ - canCreateFlows, canReadRole, canReadUser, canUpdateConfig, diff --git a/packages/web/src/components/AdminTemplateContextMenu/index.jsx b/packages/web/src/components/AdminTemplateContextMenu/index.jsx index 9ac9debc..44c282d0 100644 --- a/packages/web/src/components/AdminTemplateContextMenu/index.jsx +++ b/packages/web/src/components/AdminTemplateContextMenu/index.jsx @@ -57,7 +57,7 @@ AdminTemplateContextMenu.propTypes = { onClose: PropTypes.func.isRequired, anchorEl: PropTypes.oneOfType([ PropTypes.func, - PropTypes.shape({ current: PropTypes.instanceOf(Element) }), + PropTypes.shape({ current: PropTypes.instanceOf(window.Element) }), ]).isRequired, }; diff --git a/packages/web/src/components/AppConnectionContextMenu/index.jsx b/packages/web/src/components/AppConnectionContextMenu/index.jsx index d5050e02..d28da0af 100644 --- a/packages/web/src/components/AppConnectionContextMenu/index.jsx +++ b/packages/web/src/components/AppConnectionContextMenu/index.jsx @@ -100,7 +100,7 @@ ContextMenu.propTypes = { onMenuItemClick: PropTypes.func.isRequired, anchorEl: PropTypes.oneOfType([ PropTypes.func, - PropTypes.shape({ current: PropTypes.instanceOf(Element) }), + PropTypes.shape({ current: PropTypes.instanceOf(window.Element) }), ]), }; diff --git a/packages/web/src/components/AppConnectionRow/index.jsx b/packages/web/src/components/AppConnectionRow/index.jsx index dc7e85a6..aafebe95 100644 --- a/packages/web/src/components/AppConnectionRow/index.jsx +++ b/packages/web/src/components/AppConnectionRow/index.jsx @@ -43,7 +43,7 @@ function AppConnectionRow(props) { { connectionId: id }, { onSettled: () => { - setTimeout(() => setVerificationVisible(false), 3000); + window.setTimeout(() => setVerificationVisible(false), 3000); }, }, ); diff --git a/packages/web/src/components/ChooseAppAndEventSubstep/index.jsx b/packages/web/src/components/ChooseAppAndEventSubstep/index.jsx index 2932c8b3..80ad0f72 100644 --- a/packages/web/src/components/ChooseAppAndEventSubstep/index.jsx +++ b/packages/web/src/components/ChooseAppAndEventSubstep/index.jsx @@ -17,8 +17,9 @@ import FlowSubstepTitle from 'components/FlowSubstepTitle'; import { StepPropType, SubstepPropType } from 'propTypes/propTypes'; import useTriggers from 'hooks/useTriggers'; import useActions from 'hooks/useActions'; +import appConfig from 'config/app.js'; -const useNewFlowEditor = process.env.REACT_APP_USE_NEW_FLOW_EDITOR === 'true'; +const useNewFlowEditor = appConfig.useNewFlowEditor; const optionGenerator = (app) => ({ label: app.name, diff --git a/packages/web/src/components/ChooseConnectionSubstep/index.jsx b/packages/web/src/components/ChooseConnectionSubstep/index.jsx index c11a4111..b5f38464 100644 --- a/packages/web/src/components/ChooseConnectionSubstep/index.jsx +++ b/packages/web/src/components/ChooseConnectionSubstep/index.jsx @@ -24,8 +24,9 @@ import useAppConnections from 'hooks/useAppConnections'; import useTestConnection from 'hooks/useTestConnection'; import useOAuthClients from 'hooks/useOAuthClients'; import useEnqueueSnackbar from 'hooks/useEnqueueSnackbar'; +import appConfig from 'config/app.js'; -const useNewFlowEditor = process.env.REACT_APP_USE_NEW_FLOW_EDITOR === 'true'; +const useNewFlowEditor = appConfig.useNewFlowEditor; const ADD_CONNECTION_VALUE = 'ADD_CONNECTION'; const ADD_SHARED_CONNECTION_VALUE = 'ADD_SHARED_CONNECTION'; diff --git a/packages/web/src/components/CodeEditor/index.jsx b/packages/web/src/components/CodeEditor/index.jsx index 643a85c5..cdd5fe62 100644 --- a/packages/web/src/components/CodeEditor/index.jsx +++ b/packages/web/src/components/CodeEditor/index.jsx @@ -20,7 +20,7 @@ function CodeEditor(props) { 'data-test': dataTest, } = props; - const handleEditorOnMount = (editor, monaco) => { + const handleEditorOnMount = (editor) => { editorRef.current = editor; editor.onDidContentSizeChange((event) => { diff --git a/packages/web/src/components/ControlledCustomAutocomplete/CustomOptions.jsx b/packages/web/src/components/ControlledCustomAutocomplete/CustomOptions.jsx index 3de84a9a..b39b5b8a 100644 --- a/packages/web/src/components/ControlledCustomAutocomplete/CustomOptions.jsx +++ b/packages/web/src/components/ControlledCustomAutocomplete/CustomOptions.jsx @@ -78,7 +78,7 @@ CustomOptions.propTypes = { open: PropTypes.bool.isRequired, anchorEl: PropTypes.oneOfType([ PropTypes.func, - PropTypes.shape({ current: PropTypes.instanceOf(Element) }), + PropTypes.shape({ current: PropTypes.instanceOf(window.Element) }), ]), data: PropTypes.arrayOf( PropTypes.shape({ diff --git a/packages/web/src/components/ControlledCustomAutocomplete/Options.jsx b/packages/web/src/components/ControlledCustomAutocomplete/Options.jsx index c8613ab7..3d746e69 100644 --- a/packages/web/src/components/ControlledCustomAutocomplete/Options.jsx +++ b/packages/web/src/components/ControlledCustomAutocomplete/Options.jsx @@ -55,9 +55,10 @@ Item.propTypes = { onOptionClick: PropTypes.func.isRequired, }; -const renderItemFactory = - ({ onOptionClick }) => - (props) =>