Merge pull request #2471 from automatisch/aut-1560
refactor(web): replace CRA with Vite
This commit is contained in:
@@ -1,4 +0,0 @@
|
|||||||
node_modules
|
|
||||||
build
|
|
||||||
source
|
|
||||||
.eslintrc.js
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
extends: [
|
|
||||||
'react-app',
|
|
||||||
'plugin:@tanstack/eslint-plugin-query/recommended',
|
|
||||||
'prettier',
|
|
||||||
],
|
|
||||||
rules: {
|
|
||||||
'react/prop-types': 'warn',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
# Getting Started with Create React App
|
# Getting Started
|
||||||
|
|
||||||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
|
||||||
|
|
||||||
## Available Scripts
|
## Available Scripts
|
||||||
|
|
||||||
@@ -9,16 +7,11 @@ In the project directory, you can run:
|
|||||||
### `yarn start`
|
### `yarn start`
|
||||||
|
|
||||||
Runs the app in the development mode.\
|
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.\
|
The page will reload if you make edits.\
|
||||||
You will also see any lint errors in the console.
|
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`
|
### `yarn build`
|
||||||
|
|
||||||
Builds the app for production to the `build` folder.\
|
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!
|
Your app is ready to be deployed!
|
||||||
|
|
||||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
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/).
|
|
||||||
|
|||||||
39
packages/web/eslint.config.mjs
Normal file
39
packages/web/eslint.config.mjs
Normal file
@@ -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,
|
||||||
|
];
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
transform: translateY(-40px);
|
transform: translateY(-40px);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
<script type="module" src="src/index"></script></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>
|
||||||
@@ -1,6 +1,17 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"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"]
|
"include": ["src"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,6 @@
|
|||||||
"@mui/material": "^5.11.10",
|
"@mui/material": "^5.11.10",
|
||||||
"@mui/x-date-pickers": "^7.28.0",
|
"@mui/x-date-pickers": "^7.28.0",
|
||||||
"@tanstack/react-query": "^5.24.1",
|
"@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",
|
"@xyflow/react": "^12.4.4",
|
||||||
"axios": "^1.6.0",
|
"axios": "^1.6.0",
|
||||||
"clipboard-copy": "^4.0.1",
|
"clipboard-copy": "^4.0.1",
|
||||||
@@ -29,29 +26,26 @@
|
|||||||
"notistack": "^3.0.1",
|
"notistack": "^3.0.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^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-intl": "^5.20.12",
|
||||||
"react-json-tree": "^0.16.2",
|
"react-json-tree": "^0.16.2",
|
||||||
"react-router-dom": "^6.0.2",
|
"react-router-dom": "^6.0.2",
|
||||||
"react-scripts": "5.0.0",
|
|
||||||
"react-window": "^1.8.9",
|
"react-window": "^1.8.9",
|
||||||
"slate": "^0.94.1",
|
"slate": "^0.94.1",
|
||||||
"slate-history": "^0.93.0",
|
"slate-history": "^0.93.0",
|
||||||
"slate-react": "^0.94.2",
|
"slate-react": "^0.94.2",
|
||||||
"slugify": "^1.6.6",
|
"slugify": "^1.6.6",
|
||||||
"uuid": "^9.0.0",
|
"uuid": "^9.0.0",
|
||||||
"web-vitals": "^1.0.1",
|
|
||||||
"yup": "^0.32.11"
|
"yup": "^0.32.11"
|
||||||
},
|
},
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "react-scripts start",
|
"dev": "vite",
|
||||||
"build": "react-scripts build",
|
"build": "vite build",
|
||||||
"build:watch": "yarn nodemon --exec react-scripts build --watch 'src/**/*.ts' --watch 'public/**/*' --ext ts,html",
|
"build:watch": "yarn nodemon --exec vite build --watch 'src/**/*.ts' --watch 'public/**/*' --ext ts,html",
|
||||||
"test": "react-scripts test",
|
|
||||||
"eject": "react-scripts eject",
|
|
||||||
"lint": "eslint src --ext .js,.jsx",
|
"lint": "eslint src --ext .js,.jsx",
|
||||||
"prepack": "yarn build"
|
"prepack": "yarn build",
|
||||||
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"/build"
|
"/build"
|
||||||
@@ -85,16 +79,24 @@
|
|||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"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",
|
"@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-prettier": "^9.1.0",
|
||||||
"eslint-config-react-app": "^7.0.1",
|
"eslint-config-react-app": "^7.0.1",
|
||||||
"prettier": "^3.2.5"
|
"eslint-plugin-react-hooks": "^5.2.0",
|
||||||
},
|
"globals": "^16.0.0",
|
||||||
"eslintConfig": {
|
"prettier": "^3.2.5",
|
||||||
"extends": [
|
"vite": "^6.1.0",
|
||||||
"./.eslintrc.js"
|
"vite-plugin-eslint": "^1.8.1",
|
||||||
]
|
"vite-tsconfig-paths": "^4.3.2"
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ AccountDropdownMenu.propTypes = {
|
|||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
anchorEl: PropTypes.oneOfType([
|
anchorEl: PropTypes.oneOfType([
|
||||||
PropTypes.func,
|
PropTypes.func,
|
||||||
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
PropTypes.shape({ current: PropTypes.instanceOf(window.Element) }),
|
||||||
]),
|
]),
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ function AdminApplicationSettings({ appKey }) {
|
|||||||
'data-test': 'snackbar-save-admin-apps-settings-success',
|
'data-test': 'snackbar-save-admin-apps-settings-success',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch {
|
||||||
throw new Error('Failed while saving!');
|
throw new Error('Failed while saving!');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -37,18 +37,17 @@ function AdminApplicationUpdateOAuthClient(props) {
|
|||||||
if (!adminOAuthClient) {
|
if (!adminOAuthClient) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { name, active, ...formattedAuthDefaults } = values;
|
|
||||||
|
|
||||||
setAuthDefaultsUpdatePending(true);
|
setAuthDefaultsUpdatePending(true);
|
||||||
await updateOAuthClient({
|
|
||||||
formattedAuthDefaults,
|
await updateOAuthClient(values.formattedAuthDefaults).finally(() => {
|
||||||
}).finally(() => {
|
|
||||||
setAuthDefaultsUpdatePending(false);
|
setAuthDefaultsUpdatePending(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
setDefaultValues((prev) => ({
|
setDefaultValues((prev) => ({
|
||||||
name: prev.name,
|
name: prev.name,
|
||||||
active: prev.active,
|
active: prev.active,
|
||||||
...formattedAuthDefaults,
|
...values.formattedAuthDefaults,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
enqueueSnackbar(formatMessage('updateOAuthClient.success'), {
|
enqueueSnackbar(formatMessage('updateOAuthClient.success'), {
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import useCurrentUserAbility from 'hooks/useCurrentUserAbility';
|
|||||||
import Footer from './Footer';
|
import Footer from './Footer';
|
||||||
|
|
||||||
function createDrawerLinks({
|
function createDrawerLinks({
|
||||||
canCreateFlows,
|
|
||||||
canReadRole,
|
canReadRole,
|
||||||
canReadUser,
|
canReadUser,
|
||||||
canUpdateConfig,
|
canUpdateConfig,
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ AdminTemplateContextMenu.propTypes = {
|
|||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
anchorEl: PropTypes.oneOfType([
|
anchorEl: PropTypes.oneOfType([
|
||||||
PropTypes.func,
|
PropTypes.func,
|
||||||
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
PropTypes.shape({ current: PropTypes.instanceOf(window.Element) }),
|
||||||
]).isRequired,
|
]).isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ ContextMenu.propTypes = {
|
|||||||
onMenuItemClick: PropTypes.func.isRequired,
|
onMenuItemClick: PropTypes.func.isRequired,
|
||||||
anchorEl: PropTypes.oneOfType([
|
anchorEl: PropTypes.oneOfType([
|
||||||
PropTypes.func,
|
PropTypes.func,
|
||||||
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
PropTypes.shape({ current: PropTypes.instanceOf(window.Element) }),
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ function AppConnectionRow(props) {
|
|||||||
{ connectionId: id },
|
{ connectionId: id },
|
||||||
{
|
{
|
||||||
onSettled: () => {
|
onSettled: () => {
|
||||||
setTimeout(() => setVerificationVisible(false), 3000);
|
window.setTimeout(() => setVerificationVisible(false), 3000);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ import FlowSubstepTitle from 'components/FlowSubstepTitle';
|
|||||||
import { StepPropType, SubstepPropType } from 'propTypes/propTypes';
|
import { StepPropType, SubstepPropType } from 'propTypes/propTypes';
|
||||||
import useTriggers from 'hooks/useTriggers';
|
import useTriggers from 'hooks/useTriggers';
|
||||||
import useActions from 'hooks/useActions';
|
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) => ({
|
const optionGenerator = (app) => ({
|
||||||
label: app.name,
|
label: app.name,
|
||||||
|
|||||||
@@ -24,8 +24,9 @@ import useAppConnections from 'hooks/useAppConnections';
|
|||||||
import useTestConnection from 'hooks/useTestConnection';
|
import useTestConnection from 'hooks/useTestConnection';
|
||||||
import useOAuthClients from 'hooks/useOAuthClients';
|
import useOAuthClients from 'hooks/useOAuthClients';
|
||||||
import useEnqueueSnackbar from 'hooks/useEnqueueSnackbar';
|
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_CONNECTION_VALUE = 'ADD_CONNECTION';
|
||||||
const ADD_SHARED_CONNECTION_VALUE = 'ADD_SHARED_CONNECTION';
|
const ADD_SHARED_CONNECTION_VALUE = 'ADD_SHARED_CONNECTION';
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ function CodeEditor(props) {
|
|||||||
'data-test': dataTest,
|
'data-test': dataTest,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const handleEditorOnMount = (editor, monaco) => {
|
const handleEditorOnMount = (editor) => {
|
||||||
editorRef.current = editor;
|
editorRef.current = editor;
|
||||||
|
|
||||||
editor.onDidContentSizeChange((event) => {
|
editor.onDidContentSizeChange((event) => {
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ CustomOptions.propTypes = {
|
|||||||
open: PropTypes.bool.isRequired,
|
open: PropTypes.bool.isRequired,
|
||||||
anchorEl: PropTypes.oneOfType([
|
anchorEl: PropTypes.oneOfType([
|
||||||
PropTypes.func,
|
PropTypes.func,
|
||||||
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
PropTypes.shape({ current: PropTypes.instanceOf(window.Element) }),
|
||||||
]),
|
]),
|
||||||
data: PropTypes.arrayOf(
|
data: PropTypes.arrayOf(
|
||||||
PropTypes.shape({
|
PropTypes.shape({
|
||||||
|
|||||||
@@ -55,9 +55,10 @@ Item.propTypes = {
|
|||||||
onOptionClick: PropTypes.func.isRequired,
|
onOptionClick: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderItemFactory =
|
const renderItemFactory = ({ onOptionClick }) =>
|
||||||
({ onOptionClick }) =>
|
function RenderItem(props) {
|
||||||
(props) => <Item onOptionClick={onOptionClick} {...props} />;
|
return <Item onOptionClick={onOptionClick} {...props} />;
|
||||||
|
};
|
||||||
|
|
||||||
const Options = (props) => {
|
const Options = (props) => {
|
||||||
const formatMessage = useFormatMessage();
|
const formatMessage = useFormatMessage();
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ function ControlledCustomAutocomplete(props) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const resizeObserver = React.useMemo(function syncCustomOptionsPosition() {
|
const resizeObserver = React.useMemo(function syncCustomOptionsPosition() {
|
||||||
return new ResizeObserver(() => {
|
return new window.ResizeObserver(() => {
|
||||||
forceUpdate();
|
forceUpdate();
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import { AdapterLuxon } from '@mui/x-date-pickers/AdapterLuxon';
|
|||||||
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
||||||
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
||||||
|
|
||||||
import useFormatMessage from 'hooks/useFormatMessage';
|
|
||||||
|
|
||||||
export default function DatePickerInput({
|
export default function DatePickerInput({
|
||||||
onChange,
|
onChange,
|
||||||
defaultValue = '',
|
defaultValue = '',
|
||||||
@@ -15,7 +13,6 @@ export default function DatePickerInput({
|
|||||||
maxDate,
|
maxDate,
|
||||||
}) {
|
}) {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const formatMessage = useFormatMessage();
|
|
||||||
|
|
||||||
const props = {
|
const props = {
|
||||||
label,
|
label,
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ function DeleteApiTokenButton(props) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} catch {}
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
}, [deleteApiToken]);
|
}, [deleteApiToken]);
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ function DeleteRoleButton(props) {
|
|||||||
'data-test': 'snackbar-delete-role-success',
|
'data-test': 'snackbar-delete-role-success',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch {}
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
}, [deleteRole, enqueueSnackbar, formatMessage]);
|
}, [deleteRole, enqueueSnackbar, formatMessage]);
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ function DeleteUserButton(props) {
|
|||||||
'data-test': 'snackbar-delete-user-success',
|
'data-test': 'snackbar-delete-user-success',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch {}
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
}, [deleteUser]);
|
}, [deleteUser]);
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { Drawer as BaseDrawer } from './style';
|
|||||||
|
|
||||||
const iOS =
|
const iOS =
|
||||||
typeof navigator !== 'undefined' &&
|
typeof navigator !== 'undefined' &&
|
||||||
/iPad|iPhone|iPod/.test(navigator.userAgent);
|
/iPad|iPhone|iPod/.test(window.navigator.userAgent);
|
||||||
|
|
||||||
function Drawer(props) {
|
function Drawer(props) {
|
||||||
const { links = [], bottomLinks = [], ...drawerProps } = props;
|
const { links = [], bottomLinks = [], ...drawerProps } = props;
|
||||||
|
|||||||
@@ -27,8 +27,9 @@ import useUpdateFlow from 'hooks/useUpdateFlow';
|
|||||||
import useUpdateFlowStatus from 'hooks/useUpdateFlowStatus';
|
import useUpdateFlowStatus from 'hooks/useUpdateFlowStatus';
|
||||||
import FlowFolder from './FlowFolder';
|
import FlowFolder from './FlowFolder';
|
||||||
import { TopBar } from './style';
|
import { TopBar } from './style';
|
||||||
|
import appConfig from 'config/app.js';
|
||||||
|
|
||||||
const useNewFlowEditor = process.env.REACT_APP_USE_NEW_FLOW_EDITOR === 'true';
|
const useNewFlowEditor = appConfig.useNewFlowEditor;
|
||||||
|
|
||||||
export default function EditorLayout() {
|
export default function EditorLayout() {
|
||||||
const { flowId } = useParams();
|
const { flowId } = useParams();
|
||||||
@@ -48,7 +49,7 @@ export default function EditorLayout() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onExportFlow = async (name) => {
|
const onExportFlow = async () => {
|
||||||
const flowExport = await exportFlow();
|
const flowExport = await exportFlow();
|
||||||
|
|
||||||
downloadJsonAsFile({
|
downloadJsonAsFile({
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export default function Edge({
|
|||||||
const { flowActive, onStepAdd, isCreateStepPending } =
|
const { flowActive, onStepAdd, isCreateStepPending } =
|
||||||
useContext(EdgesContext);
|
useContext(EdgesContext);
|
||||||
|
|
||||||
const [edgePath, labelX, labelY] = getStraightPath({
|
const [, labelX, labelY] = getStraightPath({
|
||||||
sourceX,
|
sourceX,
|
||||||
sourceY,
|
sourceY,
|
||||||
targetX,
|
targetX,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export const NodeWrapper = styled(Box)(({ theme }) => ({
|
|||||||
padding: theme.spacing(0, 2.5),
|
padding: theme.spacing(0, 2.5),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const NodeInnerWrapper = styled(Box)(({ theme }) => ({
|
export const NodeInnerWrapper = styled(Box)(() => ({
|
||||||
maxWidth: 900,
|
maxWidth: 900,
|
||||||
flex: 1,
|
flex: 1,
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Stack } from '@mui/material';
|
import { Stack } from '@mui/material';
|
||||||
import { styled } from '@mui/material/styles';
|
import { styled } from '@mui/material/styles';
|
||||||
|
|
||||||
export const EditorWrapper = styled(Stack)(({ theme }) => ({
|
export const EditorWrapper = styled(Stack)(() => ({
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
'& > div': {
|
'& > div': {
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
|
|||||||
@@ -7,20 +7,16 @@ import {
|
|||||||
InputLabel,
|
InputLabel,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
Select,
|
Select,
|
||||||
Typography,
|
|
||||||
useMediaQuery,
|
useMediaQuery,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { useTheme } from '@mui/material/styles';
|
import { useTheme } from '@mui/material/styles';
|
||||||
import { DateTime } from 'luxon';
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
|
||||||
|
|
||||||
import Can from 'components/Can';
|
|
||||||
import DatePickerInput from 'components/DatePickerInput';
|
import DatePickerInput from 'components/DatePickerInput';
|
||||||
import useExecutionFilters from 'hooks/useExecutionFilters';
|
import useExecutionFilters from 'hooks/useExecutionFilters';
|
||||||
import useFormatMessage from 'hooks/useFormatMessage';
|
import useFormatMessage from 'hooks/useFormatMessage';
|
||||||
|
|
||||||
export default function ExecutionFilters({ onFilterChange }) {
|
export default function ExecutionFilters() {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const formatMessage = useFormatMessage();
|
const formatMessage = useFormatMessage();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ ContextMenu.propTypes = {
|
|||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
anchorEl: PropTypes.oneOfType([
|
anchorEl: PropTypes.oneOfType([
|
||||||
PropTypes.func,
|
PropTypes.func,
|
||||||
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
PropTypes.shape({ current: PropTypes.instanceOf(window.Element) }),
|
||||||
]).isRequired,
|
]).isRequired,
|
||||||
onDuplicateFlow: PropTypes.func,
|
onDuplicateFlow: PropTypes.func,
|
||||||
appKey: PropTypes.string,
|
appKey: PropTypes.string,
|
||||||
|
|||||||
@@ -6,19 +6,17 @@ import {
|
|||||||
InputLabel,
|
InputLabel,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
Select,
|
Select,
|
||||||
Typography,
|
|
||||||
useMediaQuery,
|
useMediaQuery,
|
||||||
Collapse,
|
Collapse,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import FilterAltIcon from '@mui/icons-material/FilterAlt';
|
import FilterAltIcon from '@mui/icons-material/FilterAlt';
|
||||||
import { useTheme } from '@mui/material/styles';
|
import { useTheme } from '@mui/material/styles';
|
||||||
|
|
||||||
import Can from 'components/Can';
|
|
||||||
import useCurrentUserRuleConditions from 'hooks/useCurrentUserRuleConditions';
|
import useCurrentUserRuleConditions from 'hooks/useCurrentUserRuleConditions';
|
||||||
import useFlowFilters from 'hooks/useFlowFilters';
|
import useFlowFilters from 'hooks/useFlowFilters';
|
||||||
import useFormatMessage from 'hooks/useFormatMessage';
|
import useFormatMessage from 'hooks/useFormatMessage';
|
||||||
|
|
||||||
export default function FlowFilters({ onFilterChange }) {
|
export default function FlowFilters() {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const formatMessage = useFormatMessage();
|
const formatMessage = useFormatMessage();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
||||||
|
|||||||
@@ -43,8 +43,9 @@ import useActions from 'hooks/useActions';
|
|||||||
import useTriggerSubsteps from 'hooks/useTriggerSubsteps';
|
import useTriggerSubsteps from 'hooks/useTriggerSubsteps';
|
||||||
import useActionSubsteps from 'hooks/useActionSubsteps';
|
import useActionSubsteps from 'hooks/useActionSubsteps';
|
||||||
import useStepWithTestExecutions from 'hooks/useStepWithTestExecutions';
|
import useStepWithTestExecutions from 'hooks/useStepWithTestExecutions';
|
||||||
|
import appConfig from 'config/app.js';
|
||||||
|
|
||||||
const useNewFlowEditor = process.env.REACT_APP_USE_NEW_FLOW_EDITOR === 'true';
|
const useNewFlowEditor = appConfig.useNewFlowEditor;
|
||||||
|
|
||||||
const validIcon = <CheckCircleIcon color="success" />;
|
const validIcon = <CheckCircleIcon color="success" />;
|
||||||
const errorIcon = <ErrorIcon color="error" />;
|
const errorIcon = <ErrorIcon color="error" />;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ FlowStepContextMenu.propTypes = {
|
|||||||
onDelete: PropTypes.func,
|
onDelete: PropTypes.func,
|
||||||
anchorEl: PropTypes.oneOfType([
|
anchorEl: PropTypes.oneOfType([
|
||||||
PropTypes.func,
|
PropTypes.func,
|
||||||
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
PropTypes.shape({ current: PropTypes.instanceOf(window.Element) }),
|
||||||
]),
|
]),
|
||||||
deletable: PropTypes.bool.isRequired,
|
deletable: PropTypes.bool.isRequired,
|
||||||
flowId: PropTypes.string.isRequired,
|
flowId: PropTypes.string.isRequired,
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ import FlowSubstepTitle from 'components/FlowSubstepTitle';
|
|||||||
import InputCreator from 'components/InputCreator';
|
import InputCreator from 'components/InputCreator';
|
||||||
import FilterConditions from './FilterConditions';
|
import FilterConditions from './FilterConditions';
|
||||||
import { StepPropType, SubstepPropType } from 'propTypes/propTypes';
|
import { StepPropType, SubstepPropType } from 'propTypes/propTypes';
|
||||||
|
import appConfig from 'config/app.js';
|
||||||
|
|
||||||
const useNewFlowEditor = process.env.REACT_APP_USE_NEW_FLOW_EDITOR === 'true';
|
const useNewFlowEditor = appConfig.useNewFlowEditor;
|
||||||
|
|
||||||
function FlowSubstep(props) {
|
function FlowSubstep(props) {
|
||||||
const {
|
const {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { Link, useSearchParams, useNavigate } from 'react-router-dom';
|
|||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import Stack from '@mui/material/Stack';
|
import Stack from '@mui/material/Stack';
|
||||||
import Card from '@mui/material/Card';
|
import Card from '@mui/material/Card';
|
||||||
import Typography from '@mui/material/Typography';
|
|
||||||
import IconButton from '@mui/material/IconButton';
|
import IconButton from '@mui/material/IconButton';
|
||||||
import DeleteIcon from '@mui/icons-material/Delete';
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
import EditIcon from '@mui/icons-material/Edit';
|
import EditIcon from '@mui/icons-material/Edit';
|
||||||
@@ -24,7 +23,6 @@ import useFormatMessage from 'hooks/useFormatMessage';
|
|||||||
import useFolders from 'hooks/useFolders';
|
import useFolders from 'hooks/useFolders';
|
||||||
import useDeleteFolder from 'hooks/useDeleteFolder';
|
import useDeleteFolder from 'hooks/useDeleteFolder';
|
||||||
import useEnqueueSnackbar from 'hooks/useEnqueueSnackbar';
|
import useEnqueueSnackbar from 'hooks/useEnqueueSnackbar';
|
||||||
import objectifyUrlSearchParams from 'helpers/objectifyUrlSearchParams';
|
|
||||||
import useFlowFilters from 'hooks/useFlowFilters';
|
import useFlowFilters from 'hooks/useFlowFilters';
|
||||||
|
|
||||||
import { ListItemIcon } from './style';
|
import { ListItemIcon } from './style';
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ function Form(props) {
|
|||||||
return (
|
return (
|
||||||
<FormProvider {...methods}>
|
<FormProvider {...methods}>
|
||||||
<form
|
<form
|
||||||
onSubmit={methods.handleSubmit(async (data, event) => {
|
onSubmit={methods.handleSubmit(async (data) => {
|
||||||
try {
|
try {
|
||||||
return await onSubmit?.(data);
|
return await onSubmit?.(data);
|
||||||
} catch (errors) {
|
} catch (errors) {
|
||||||
|
|||||||
@@ -55,10 +55,10 @@ function ImportFlowDialog(props) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleImportFlow = (event) => {
|
const handleImportFlow = () => {
|
||||||
if (!selectedFile) return;
|
if (!selectedFile) return;
|
||||||
|
|
||||||
const fileReader = new FileReader();
|
const fileReader = new window.FileReader();
|
||||||
|
|
||||||
fileReader.onload = async function readFileLoaded(e) {
|
fileReader.onload = async function readFileLoaded(e) {
|
||||||
const flowData = parseFlowFile(e.target.result);
|
const flowData = parseFlowFile(e.target.result);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import englishMessages from 'locales/en.json';
|
|||||||
const IntlProvider = ({ children }) => {
|
const IntlProvider = ({ children }) => {
|
||||||
return (
|
return (
|
||||||
<BaseIntlProvider
|
<BaseIntlProvider
|
||||||
locale={navigator.language.split('-')[0]}
|
locale={window.navigator.language.split('-')[0]}
|
||||||
defaultLocale="en"
|
defaultLocale="en"
|
||||||
messages={englishMessages}
|
messages={englishMessages}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -2,13 +2,10 @@ import styled from '@emotion/styled';
|
|||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import Divider from '@mui/material/Divider';
|
import Divider from '@mui/material/Divider';
|
||||||
import Link from '@mui/material/Link';
|
import Link from '@mui/material/Link';
|
||||||
import Stack from '@mui/material/Stack';
|
|
||||||
import SvgIcon from '@mui/material/SvgIcon';
|
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
|
|
||||||
import useAutomatischConfig from 'hooks/useAutomatischConfig';
|
import useAutomatischConfig from 'hooks/useAutomatischConfig';
|
||||||
import useFormatMessage from 'hooks/useFormatMessage';
|
import useFormatMessage from 'hooks/useFormatMessage';
|
||||||
import useVersion from 'hooks/useVersion';
|
|
||||||
|
|
||||||
const LogoImage = styled('img')(() => ({
|
const LogoImage = styled('img')(() => ({
|
||||||
maxWidth: 'auto',
|
maxWidth: 'auto',
|
||||||
@@ -16,7 +13,7 @@ const LogoImage = styled('img')(() => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
const LayoutFooter = () => {
|
const LayoutFooter = () => {
|
||||||
const { data: config, isPending: isConfigPending } = useAutomatischConfig();
|
const { data: config } = useAutomatischConfig();
|
||||||
const formatMessage = useFormatMessage();
|
const formatMessage = useFormatMessage();
|
||||||
|
|
||||||
if (config?.data.enableFooter !== true) return null;
|
if (config?.data.enableFooter !== true) return null;
|
||||||
@@ -34,22 +31,20 @@ const LayoutFooter = () => {
|
|||||||
href: config.data.footerTosUrl,
|
href: config.data.footerTosUrl,
|
||||||
text: formatMessage('footer.tosLinkText'),
|
text: formatMessage('footer.tosLinkText'),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
key: 'privacy-policy',
|
key: 'privacy-policy',
|
||||||
show: !!config.data.footerPrivacyPolicyUrl,
|
show: !!config.data.footerPrivacyPolicyUrl,
|
||||||
href: config.data.footerPrivacyPolicyUrl,
|
href: config.data.footerPrivacyPolicyUrl,
|
||||||
text: formatMessage('footer.privacyPolicyLinkText'),
|
text: formatMessage('footer.privacyPolicyLinkText'),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
key: 'imprint',
|
key: 'imprint',
|
||||||
show: !!config.data.footerImprintUrl,
|
show: !!config.data.footerImprintUrl,
|
||||||
href: config.data.footerImprintUrl,
|
href: config.data.footerImprintUrl,
|
||||||
text: formatMessage('footer.imprintLinkText'),
|
text: formatMessage('footer.imprintLinkText'),
|
||||||
},
|
},
|
||||||
,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box mt="auto" position="sticky" bottom={0}>
|
<Box mt="auto" position="sticky" bottom={0}>
|
||||||
<Box bgcolor="common.white" mt={4}>
|
<Box bgcolor="common.white" mt={4}>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ function ListItemLink(props) {
|
|||||||
React.forwardRef(function InLineLink(linkProps, ref) {
|
React.forwardRef(function InLineLink(linkProps, ref) {
|
||||||
try {
|
try {
|
||||||
// challenge the link to check if it's absolute URL
|
// challenge the link to check if it's absolute URL
|
||||||
new URL(to); // should throw an error if it's not an absolute URL
|
new window.URL(to); // should throw an error if it's not an absolute URL
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
{...linkProps}
|
{...linkProps}
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ function LoginForm() {
|
|||||||
});
|
});
|
||||||
const { token } = data;
|
const { token } = data;
|
||||||
authentication.updateToken(token);
|
authentication.updateToken(token);
|
||||||
} catch {}
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderError = () => {
|
const renderError = () => {
|
||||||
@@ -49,7 +51,7 @@ function LoginForm() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
return errors.map((error) => (
|
return errors.map((error) => (
|
||||||
<Alert severity="error" sx={{ mt: 2 }}>
|
<Alert key={error} severity="error" sx={{ mt: 2 }}>
|
||||||
{error}
|
{error}
|
||||||
</Alert>
|
</Alert>
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { ReactComponent as MationLogoSvg } from './assets/mation-logo.svg';
|
import MationLogoSvg from './assets/mation-logo.svg';
|
||||||
|
|
||||||
const MationLogo = () => {
|
const MationLogo = () => {
|
||||||
return <MationLogoSvg />;
|
return <img src={MationLogoSvg} alt="Mation Logo" />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MationLogo;
|
export default MationLogo;
|
||||||
|
|||||||
@@ -3,22 +3,11 @@ import { useFormContext } from 'react-hook-form';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ControlledCheckbox from 'components/ControlledCheckbox';
|
import ControlledCheckbox from 'components/ControlledCheckbox';
|
||||||
|
|
||||||
const AllEntitiesPermissions = ({
|
const AllEntitiesPermissions = ({ action, subject, disabled, name }) => {
|
||||||
action,
|
const { getValues, resetField } = useFormContext();
|
||||||
subject,
|
|
||||||
disabled,
|
|
||||||
name,
|
|
||||||
syncIsCreator,
|
|
||||||
}) => {
|
|
||||||
const { getValues, formState, resetField } = useFormContext();
|
|
||||||
|
|
||||||
const fieldName = `${name}.${subject.key}.${action.key}.allEntities`;
|
const fieldName = `${name}.${subject.key}.${action.key}.allEntities`;
|
||||||
const defaultValue =
|
|
||||||
formState.defaultValues?.[name]?.[subject.key]?.[action.key].allEntities;
|
|
||||||
const ownEntitiesFieldName = `${name}.${subject.key}.${action.key}.ownEntities`;
|
const ownEntitiesFieldName = `${name}.${subject.key}.${action.key}.ownEntities`;
|
||||||
const ownEntitiesFieldTouched =
|
|
||||||
formState.touchedFields?.[name]?.[subject.key]?.[action.key]
|
|
||||||
?.ownEntities === true;
|
|
||||||
|
|
||||||
const currentValue = getValues(fieldName);
|
const currentValue = getValues(fieldName);
|
||||||
|
|
||||||
@@ -28,16 +17,6 @@ const AllEntitiesPermissions = ({
|
|||||||
}
|
}
|
||||||
}, [ownEntitiesFieldName, currentValue]);
|
}, [ownEntitiesFieldName, currentValue]);
|
||||||
|
|
||||||
const handleSyncIsCreator = (newValue) => {
|
|
||||||
if (syncIsCreator && defaultValue === false && !ownEntitiesFieldTouched) {
|
|
||||||
resetField(ownEntitiesFieldName, { defaultValue: newValue });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newValue === true) {
|
|
||||||
resetField(ownEntitiesFieldName, { defaultValue: true });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ControlledCheckbox
|
<ControlledCheckbox
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ Popper.propTypes = {
|
|||||||
open: PropTypes.bool.isRequired,
|
open: PropTypes.bool.isRequired,
|
||||||
anchorEl: PropTypes.oneOfType([
|
anchorEl: PropTypes.oneOfType([
|
||||||
PropTypes.func,
|
PropTypes.func,
|
||||||
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
PropTypes.shape({ current: PropTypes.instanceOf(window.Element) }),
|
||||||
]),
|
]),
|
||||||
data: PropTypes.array.isRequired,
|
data: PropTypes.array.isRequired,
|
||||||
onSuggestionClick: PropTypes.func,
|
onSuggestionClick: PropTypes.func,
|
||||||
|
|||||||
@@ -28,11 +28,10 @@ const getPartialArray = (array, length = array.length) => {
|
|||||||
return array.slice(0, length);
|
return array.slice(0, length);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderItemFactory =
|
const renderItemFactory = ({ onSuggestionClick }) =>
|
||||||
({ onSuggestionClick }) =>
|
function RenderItem(props) {
|
||||||
(props) => (
|
return <SuggestionItem {...props} onSuggestionClick={onSuggestionClick} />;
|
||||||
<SuggestionItem {...props} onSuggestionClick={onSuggestionClick} />
|
};
|
||||||
);
|
|
||||||
|
|
||||||
const Suggestions = (props) => {
|
const Suggestions = (props) => {
|
||||||
const formatMessage = useFormatMessage();
|
const formatMessage = useFormatMessage();
|
||||||
|
|||||||
@@ -50,7 +50,9 @@ export default function ResetPasswordForm() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
navigate(URLS.LOGIN);
|
navigate(URLS.LOGIN);
|
||||||
} catch {}
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderError = () => {
|
const renderError = () => {
|
||||||
@@ -63,7 +65,7 @@ export default function ResetPasswordForm() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
return errors.map((error) => (
|
return errors.map((error) => (
|
||||||
<Alert severity="error" sx={{ mt: 2 }}>
|
<Alert key={error} severity="error" sx={{ mt: 2 }}>
|
||||||
{error}
|
{error}
|
||||||
</Alert>
|
</Alert>
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export default function SplitButton(props) {
|
|||||||
setOpen((prevOpen) => !prevOpen);
|
setOpen((prevOpen) => !prevOpen);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClose = (event) => {
|
const handleClose = () => {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,9 @@ import WebhookUrlInfo from 'components/WebhookUrlInfo';
|
|||||||
import FlowSubstepTitle from 'components/FlowSubstepTitle';
|
import FlowSubstepTitle from 'components/FlowSubstepTitle';
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
import { StepPropType, SubstepPropType } from 'propTypes/propTypes';
|
import { StepPropType, SubstepPropType } from 'propTypes/propTypes';
|
||||||
|
import appConfig from 'config/app.js';
|
||||||
|
|
||||||
const useNewFlowEditor = process.env.REACT_APP_USE_NEW_FLOW_EDITOR === 'true';
|
const useNewFlowEditor = appConfig.useNewFlowEditor;
|
||||||
|
|
||||||
function TestSubstep(props) {
|
function TestSubstep(props) {
|
||||||
const {
|
const {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
const backendUrl = process.env.REACT_APP_BACKEND_URL;
|
const backendUrl = import.meta.env.VITE_BACKEND_URL;
|
||||||
|
|
||||||
const computeUrl = (url, backendUrl) => {
|
const computeUrl = (url, backendUrl) => {
|
||||||
/**
|
/**
|
||||||
* In case `backendUrl` is a host, we append the url to it.
|
* In case `backendUrl` is a host, we append the url to it.
|
||||||
**/
|
**/
|
||||||
try {
|
try {
|
||||||
return new URL(url, backendUrl).toString();
|
return new window.URL(url, backendUrl).toString();
|
||||||
} catch (e) {
|
} catch {
|
||||||
/*
|
/*
|
||||||
* In case `backendUrl` is not qualified, we utilize `url` alone.
|
* In case `backendUrl` is not qualified, we utilize `url` alone.
|
||||||
**/
|
**/
|
||||||
@@ -15,8 +15,9 @@ const computeUrl = (url, backendUrl) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
baseUrl: process.env.REACT_APP_BASE_URL,
|
baseUrl: import.meta.env.VITE_BASE_URL,
|
||||||
restApiUrl: computeUrl('/internal/api', backendUrl),
|
restApiUrl: computeUrl('/internal/api', backendUrl),
|
||||||
|
useNewFlowEditor: import.meta.env.VITE_USE_NEW_FLOW_EDITOR === 'true',
|
||||||
supportEmailAddress: 'support@automatisch.io',
|
supportEmailAddress: 'support@automatisch.io',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
const parseUrlSearchParams = (event) => {
|
const parseUrlSearchParams = (event) => {
|
||||||
const searchParams = new URLSearchParams(event.data.payload.search);
|
const searchParams = new window.URLSearchParams(event.data.payload.search);
|
||||||
const hashParams = new URLSearchParams(event.data.payload.hash.substring(1));
|
const hashParams = new window.URLSearchParams(
|
||||||
|
event.data.payload.hash.substring(1),
|
||||||
|
);
|
||||||
const searchParamsObject = getObjectOfEntries(searchParams.entries());
|
const searchParamsObject = getObjectOfEntries(searchParams.entries());
|
||||||
const hashParamsObject = getObjectOfEntries(hashParams.entries());
|
const hashParamsObject = getObjectOfEntries(hashParams.entries());
|
||||||
|
|
||||||
@@ -33,9 +35,9 @@ export const processPopupMessage = (popup) => {
|
|||||||
let closeCheckIntervalId;
|
let closeCheckIntervalId;
|
||||||
|
|
||||||
if (popup) {
|
if (popup) {
|
||||||
closeCheckIntervalId = setInterval(() => {
|
closeCheckIntervalId = window.setInterval(() => {
|
||||||
if (popup.closed) {
|
if (popup.closed) {
|
||||||
clearInterval(closeCheckIntervalId);
|
window.clearInterval(closeCheckIntervalId);
|
||||||
|
|
||||||
reject({ message: 'Error occured while verifying credentials!' });
|
reject({ message: 'Error occured while verifying credentials!' });
|
||||||
}
|
}
|
||||||
@@ -51,7 +53,7 @@ export const processPopupMessage = (popup) => {
|
|||||||
window.removeEventListener('message', messageHandler);
|
window.removeEventListener('message', messageHandler);
|
||||||
|
|
||||||
if (closeCheckIntervalId) {
|
if (closeCheckIntervalId) {
|
||||||
clearInterval(closeCheckIntervalId);
|
window.clearInterval(closeCheckIntervalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(data);
|
resolve(data);
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ const NAMESPACE = 'automatisch';
|
|||||||
const makeKey = (key) => `${NAMESPACE}.${key}`;
|
const makeKey = (key) => `${NAMESPACE}.${key}`;
|
||||||
|
|
||||||
export const setItem = (key, value) => {
|
export const setItem = (key, value) => {
|
||||||
return localStorage.setItem(makeKey(key), value);
|
return window.localStorage.setItem(makeKey(key), value);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getItem = (key) => {
|
export const getItem = (key) => {
|
||||||
return localStorage.getItem(makeKey(key));
|
return window.localStorage.getItem(makeKey(key));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeItem = (key) => {
|
export const removeItem = (key) => {
|
||||||
return localStorage.removeItem(makeKey(key));
|
return window.localStorage.removeItem(makeKey(key));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,16 +1,22 @@
|
|||||||
import { Link as RouterLink } from 'react-router-dom';
|
import { Link as RouterLink } from 'react-router-dom';
|
||||||
import Link from '@mui/material/Link';
|
import Link from '@mui/material/Link';
|
||||||
|
|
||||||
export const generateInternalLink = (link) => (str) => (
|
export const generateInternalLink = (link) =>
|
||||||
<Link component={RouterLink} to={link}>
|
function LinkVariable(str) {
|
||||||
{str}
|
return (
|
||||||
</Link>
|
<Link component={RouterLink} to={link}>
|
||||||
);
|
{str}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const generateExternalLink = (link) => (str) => (
|
export const generateExternalLink = (link) =>
|
||||||
<Link href={link} target="_blank">
|
function LinkVariable(str) {
|
||||||
{str}
|
return (
|
||||||
</Link>
|
<Link href={link} target="_blank">
|
||||||
);
|
{str}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const makeBold = (str) => <strong>{str}</strong>;
|
export const makeBold = (str) => <strong>{str}</strong>;
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ export default function useAdminDeleteRole(roleId) {
|
|||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const query = useMutation({
|
const query = useMutation({
|
||||||
mutationFn: async (payload) => {
|
mutationFn: async () => {
|
||||||
const { data } = await api.delete(`/v1/admin/roles/${roleId}`);
|
const { data } = await api.delete(`/v1/admin/roles/${roleId}`);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: async () => {
|
||||||
queryClient.invalidateQueries({
|
await queryClient.invalidateQueries({
|
||||||
queryKey: ['admin', 'roles'],
|
queryKey: ['admin', 'roles'],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const appendTrailingSlash = (url) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Per instance, there may be different documentation. However, the paths are assumed the same.
|
* Per instance, there may be different documentation. However, the paths are assumed the same.
|
||||||
@@ -18,10 +18,12 @@ const appendTrailingSlash = (url) => {
|
|||||||
*/
|
*/
|
||||||
export default function useDocsUrl(path) {
|
export default function useDocsUrl(path) {
|
||||||
const { data: automatischInfo } = useAutomatischInfo();
|
const { data: automatischInfo } = useAutomatischInfo();
|
||||||
const docsUrlWithTrailingSlash = appendTrailingSlash(automatischInfo?.docsUrl);
|
const docsUrlWithTrailingSlash = appendTrailingSlash(
|
||||||
|
automatischInfo?.docsUrl,
|
||||||
|
);
|
||||||
const docsUrl = docsUrlWithTrailingSlash || 'https://automatisch.io/docs/';
|
const docsUrl = docsUrlWithTrailingSlash || 'https://automatisch.io/docs/';
|
||||||
|
|
||||||
const absoluteUrl = new URL(path, docsUrl).toString();
|
const absoluteUrl = new window.URL(path, docsUrl).toString();
|
||||||
|
|
||||||
return absoluteUrl;
|
return absoluteUrl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ export default function useDownloadJsonAsFile() {
|
|||||||
replacement: '-',
|
replacement: '-',
|
||||||
});
|
});
|
||||||
|
|
||||||
const fileBlob = new Blob([stringifiedContents], {
|
const fileBlob = new window.Blob([stringifiedContents], {
|
||||||
type: 'application/json',
|
type: 'application/json',
|
||||||
});
|
});
|
||||||
|
|
||||||
const fileObjectUrl = URL.createObjectURL(fileBlob);
|
const fileObjectUrl = window.URL.createObjectURL(fileBlob);
|
||||||
|
|
||||||
const temporaryDownloadLink = document.createElement('a');
|
const temporaryDownloadLink = document.createElement('a');
|
||||||
temporaryDownloadLink.href = fileObjectUrl;
|
temporaryDownloadLink.href = fileObjectUrl;
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ function useDynamicData(stepId, schema) {
|
|||||||
lastComputedVariables.current = variables;
|
lastComputedVariables.current = variables;
|
||||||
|
|
||||||
return variables;
|
return variables;
|
||||||
} catch (err) {
|
} catch {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ function useDynamicFields(stepId, schema) {
|
|||||||
}
|
}
|
||||||
lastComputedVariables.current = variables;
|
lastComputedVariables.current = variables;
|
||||||
return variables;
|
return variables;
|
||||||
} catch (err) {
|
} catch {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { useMutation } from '@tanstack/react-query';
|
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
|
|
||||||
import api from 'helpers/api';
|
|
||||||
import objectifyUrlSearchParams from 'helpers/objectifyUrlSearchParams';
|
import objectifyUrlSearchParams from 'helpers/objectifyUrlSearchParams';
|
||||||
|
|
||||||
export default function useExecutionFilters() {
|
export default function useExecutionFilters() {
|
||||||
@@ -21,7 +19,8 @@ export default function useExecutionFilters() {
|
|||||||
const endDateTime = parseInt(endDateTimeString, 10);
|
const endDateTime = parseInt(endDateTimeString, 10);
|
||||||
|
|
||||||
const filterByStatus = (status) => {
|
const filterByStatus = (status) => {
|
||||||
setSearchParams((current) => {
|
setSearchParams(() => {
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
const { status: currentStatus, ...rest } = searchParamsObject;
|
const { status: currentStatus, ...rest } = searchParamsObject;
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
@@ -35,7 +34,8 @@ export default function useExecutionFilters() {
|
|||||||
const filterByStartDateTime = (startDateTime) => {
|
const filterByStartDateTime = (startDateTime) => {
|
||||||
const startDateTimeString = startDateTime?.toMillis();
|
const startDateTimeString = startDateTime?.toMillis();
|
||||||
|
|
||||||
setSearchParams((current) => {
|
setSearchParams(() => {
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
const { startDateTime: currentStartDateTime, ...rest } =
|
const { startDateTime: currentStartDateTime, ...rest } =
|
||||||
searchParamsObject;
|
searchParamsObject;
|
||||||
|
|
||||||
@@ -50,7 +50,8 @@ export default function useExecutionFilters() {
|
|||||||
const filterByEndDateTime = (endDateTime) => {
|
const filterByEndDateTime = (endDateTime) => {
|
||||||
const endDateTimeString = endDateTime?.endOf('day').toMillis();
|
const endDateTimeString = endDateTime?.endOf('day').toMillis();
|
||||||
|
|
||||||
setSearchParams((current) => {
|
setSearchParams(() => {
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
const { endDateTime: currentEndDateTime, ...rest } = searchParamsObject;
|
const { endDateTime: currentEndDateTime, ...rest } = searchParamsObject;
|
||||||
|
|
||||||
if (endDateTimeString) {
|
if (endDateTimeString) {
|
||||||
@@ -65,13 +66,14 @@ export default function useExecutionFilters() {
|
|||||||
const searchParamsObject = objectifyUrlSearchParams(searchParams);
|
const searchParamsObject = objectifyUrlSearchParams(searchParams);
|
||||||
|
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
const { [key]: keyToRemove, ...remainingSearchParams } =
|
const { [key]: keyToRemove, ...remainingSearchParams } =
|
||||||
searchParamsObject;
|
searchParamsObject;
|
||||||
|
|
||||||
return new URLSearchParams(remainingSearchParams).toString();
|
return new window.URLSearchParams(remainingSearchParams).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new URLSearchParams({
|
return new window.URLSearchParams({
|
||||||
...searchParamsObject,
|
...searchParamsObject,
|
||||||
[key]: value,
|
[key]: value,
|
||||||
}).toString();
|
}).toString();
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { useMutation } from '@tanstack/react-query';
|
|
||||||
|
|
||||||
import api from 'helpers/api';
|
|
||||||
import objectifyUrlSearchParams from 'helpers/objectifyUrlSearchParams';
|
import objectifyUrlSearchParams from 'helpers/objectifyUrlSearchParams';
|
||||||
|
|
||||||
export default function useFlowFilters() {
|
export default function useFlowFilters() {
|
||||||
@@ -14,7 +12,8 @@ export default function useFlowFilters() {
|
|||||||
searchParamsObject.onlyOwnedFlows === 'true' || undefined;
|
searchParamsObject.onlyOwnedFlows === 'true' || undefined;
|
||||||
|
|
||||||
const filterByStatus = (status) => {
|
const filterByStatus = (status) => {
|
||||||
setSearchParams((current) => {
|
setSearchParams(() => {
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
const { status: currentStatus, ...rest } = searchParamsObject;
|
const { status: currentStatus, ...rest } = searchParamsObject;
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
@@ -26,7 +25,8 @@ export default function useFlowFilters() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const filterByOwnership = (onlyOwnedFlows) => {
|
const filterByOwnership = (onlyOwnedFlows) => {
|
||||||
setSearchParams((current) => {
|
setSearchParams(() => {
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
const { onlyOwnedFlows: currentOnlyOwnedFlows, ...rest } =
|
const { onlyOwnedFlows: currentOnlyOwnedFlows, ...rest } =
|
||||||
searchParamsObject;
|
searchParamsObject;
|
||||||
|
|
||||||
@@ -42,13 +42,14 @@ export default function useFlowFilters() {
|
|||||||
const searchParamsObject = objectifyUrlSearchParams(searchParams);
|
const searchParamsObject = objectifyUrlSearchParams(searchParams);
|
||||||
|
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
const { [key]: keyToRemove, ...remainingSearchParams } =
|
const { [key]: keyToRemove, ...remainingSearchParams } =
|
||||||
searchParamsObject;
|
searchParamsObject;
|
||||||
|
|
||||||
return new URLSearchParams(remainingSearchParams).toString();
|
return new window.URLSearchParams(remainingSearchParams).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new URLSearchParams({
|
return new window.URLSearchParams({
|
||||||
...searchParamsObject,
|
...searchParamsObject,
|
||||||
[key]: value,
|
[key]: value,
|
||||||
}).toString();
|
}).toString();
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import userAbility from 'helpers/userAbility';
|
|
||||||
import useCurrentUser from 'hooks/useCurrentUser';
|
import useCurrentUser from 'hooks/useCurrentUser';
|
||||||
|
|
||||||
export default function useIsCurrentUserAdmin() {
|
export default function useIsCurrentUserAdmin() {
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import api from 'helpers/api';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
export default function useLazyApps({ appName } = {}, { onSuccess } = {}) {
|
export default function useLazyApps({ appName } = {}, { onSuccess } = {}) {
|
||||||
const abortControllerRef = React.useRef(new AbortController());
|
const abortControllerRef = React.useRef(new window.AbortController());
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
abortControllerRef.current = new AbortController();
|
abortControllerRef.current = new window.AbortController();
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
abortControllerRef.current?.abort();
|
abortControllerRef.current?.abort();
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ import MetadataProvider from 'components/MetadataProvider';
|
|||||||
import { AuthenticationProvider } from 'contexts/Authentication';
|
import { AuthenticationProvider } from 'contexts/Authentication';
|
||||||
import QueryClientProvider from 'components/QueryClientProvider';
|
import QueryClientProvider from 'components/QueryClientProvider';
|
||||||
import Router from 'components/Router';
|
import Router from 'components/Router';
|
||||||
import routes from 'routes';
|
import routes from './routes';
|
||||||
import reportWebVitals from './reportWebVitals';
|
|
||||||
|
|
||||||
// Sets the default locale to English for all luxon DateTime instances created afterwards.
|
// Sets the default locale to English for all luxon DateTime instances created afterwards.
|
||||||
Settings.defaultLocale = 'en';
|
Settings.defaultLocale = 'en';
|
||||||
@@ -32,8 +31,3 @@ root.render(
|
|||||||
</SnackbarProvider>
|
</SnackbarProvider>
|
||||||
</Router>,
|
</Router>,
|
||||||
);
|
);
|
||||||
|
|
||||||
// If you want to start measuring performance in your app, pass a function
|
|
||||||
// to log results (for example: reportWebVitals(console.log))
|
|
||||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
|
||||||
reportWebVitals();
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ function AdminTemplates() {
|
|||||||
defaultValues={{ enableTemplates: config?.data.enableTemplates }}
|
defaultValues={{ enableTemplates: config?.data.enableTemplates }}
|
||||||
noValidate
|
noValidate
|
||||||
automaticValidation={false}
|
automaticValidation={false}
|
||||||
render={({ formState: { errors, isDirty } }) => (
|
render={() => (
|
||||||
<Switch
|
<Switch
|
||||||
name="enableTemplates"
|
name="enableTemplates"
|
||||||
disabled={isUpdateConfigPending}
|
disabled={isUpdateConfigPending}
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ export default function CreateFlow() {
|
|||||||
const flowId = response.data?.id;
|
const flowId = response.data?.id;
|
||||||
|
|
||||||
navigateToEditor(flowId);
|
navigateToEditor(flowId);
|
||||||
} catch {}
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initiate();
|
initiate();
|
||||||
|
|||||||
@@ -25,9 +25,6 @@ export default function Executions() {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const page = parseInt(searchParams.get('page') || '', 10) || 1;
|
const page = parseInt(searchParams.get('page') || '', 10) || 1;
|
||||||
const name = searchParams.get('name') || '';
|
const name = searchParams.get('name') || '';
|
||||||
const status = searchParams.get('status');
|
|
||||||
const startDateTime = searchParams.get('startDateTime');
|
|
||||||
const endDateTime = searchParams.get('endDateTime');
|
|
||||||
const [searchValue, setSearchValue] = React.useState(name);
|
const [searchValue, setSearchValue] = React.useState(name);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -61,7 +58,7 @@ export default function Executions() {
|
|||||||
const getPathWithSearchParams = (page) => {
|
const getPathWithSearchParams = (page) => {
|
||||||
const searchParamsObject = objectifyUrlSearchParams(searchParams);
|
const searchParamsObject = objectifyUrlSearchParams(searchParams);
|
||||||
|
|
||||||
const newSearchParams = new URLSearchParams({
|
const newSearchParams = new window.URLSearchParams({
|
||||||
...searchParamsObject,
|
...searchParamsObject,
|
||||||
page,
|
page,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ export default function Flows() {
|
|||||||
const getPathWithSearchParams = (page) => {
|
const getPathWithSearchParams = (page) => {
|
||||||
const searchParamsObject = objectifyUrlSearchParams(searchParams);
|
const searchParamsObject = objectifyUrlSearchParams(searchParams);
|
||||||
|
|
||||||
const newSearchParams = new URLSearchParams({
|
const newSearchParams = new window.URLSearchParams({
|
||||||
...searchParamsObject,
|
...searchParamsObject,
|
||||||
page,
|
page,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export default function UserInterface() {
|
|||||||
'data-test': 'snackbar-update-user-interface-success',
|
'data-test': 'snackbar-update-user-interface-success',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch {
|
||||||
throw new Error('Failed while updating!');
|
throw new Error('Failed while updating!');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
const reportWebVitals = (onPerfEntry) => {
|
|
||||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
|
||||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
|
||||||
getCLS(onPerfEntry);
|
|
||||||
getFID(onPerfEntry);
|
|
||||||
getFCP(onPerfEntry);
|
|
||||||
getLCP(onPerfEntry);
|
|
||||||
getTTFB(onPerfEntry);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
export default reportWebVitals;
|
|
||||||
@@ -15,7 +15,6 @@ import Application from 'pages/Application';
|
|||||||
import Executions from 'pages/Executions';
|
import Executions from 'pages/Executions';
|
||||||
import Execution from 'pages/Execution';
|
import Execution from 'pages/Execution';
|
||||||
import Flows from 'pages/Flows';
|
import Flows from 'pages/Flows';
|
||||||
import Flow from 'pages/Flow';
|
|
||||||
import Login from 'pages/Login';
|
import Login from 'pages/Login';
|
||||||
import AcceptInvitation from 'pages/AcceptInvitation';
|
import AcceptInvitation from 'pages/AcceptInvitation';
|
||||||
import LoginCallback from 'pages/LoginCallback';
|
import LoginCallback from 'pages/LoginCallback';
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
|
||||||
// allows you to do things like:
|
|
||||||
// expect(element).toHaveTextContent(/react/i)
|
|
||||||
// learn more: https://github.com/testing-library/jest-dom
|
|
||||||
import '@testing-library/jest-dom';
|
|
||||||
47
packages/web/vite.config.js
Normal file
47
packages/web/vite.config.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import eslint from 'vite-plugin-eslint';
|
||||||
|
|
||||||
|
export default defineConfig(() => {
|
||||||
|
return {
|
||||||
|
// https://github.com/vitejs/vite/issues/1973#issuecomment-787571499
|
||||||
|
define: {
|
||||||
|
'process.env': {},
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
outDir: 'build',
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
react({
|
||||||
|
jsxImportSource: '@emotion/react',
|
||||||
|
babel: {
|
||||||
|
plugins: ['@emotion/babel-plugin'],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
eslint({
|
||||||
|
eslintPath: require.resolve('eslint'),
|
||||||
|
cache: false,
|
||||||
|
include: ['src/**/*.js', 'src/**/*.jsx'],
|
||||||
|
exclude: ['node_modules'],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
components: path.resolve(__dirname, './src/components'),
|
||||||
|
config: path.resolve(__dirname, './src/config'),
|
||||||
|
contexts: path.resolve(__dirname, './src/contexts'),
|
||||||
|
helpers: path.resolve(__dirname, './src/helpers'),
|
||||||
|
hooks: path.resolve(__dirname, './src/hooks'),
|
||||||
|
locales: path.resolve(__dirname, './src/locales'),
|
||||||
|
pages: path.resolve(__dirname, './src/pages'),
|
||||||
|
propTypes: path.resolve(__dirname, './src/propTypes'),
|
||||||
|
styles: path.resolve(__dirname, './src/styles'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
open: true,
|
||||||
|
port: process.env.PORT || 3001,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user