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
|
||||
|
||||
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/).
|
||||
|
||||
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);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<script type="module" src="src/index"></script></head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
@@ -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"]
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -43,7 +43,7 @@ function AdminApplicationSettings({ appKey }) {
|
||||
'data-test': 'snackbar-save-admin-apps-settings-success',
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
} catch {
|
||||
throw new Error('Failed while saving!');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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'), {
|
||||
|
||||
@@ -24,7 +24,6 @@ import useCurrentUserAbility from 'hooks/useCurrentUserAbility';
|
||||
import Footer from './Footer';
|
||||
|
||||
function createDrawerLinks({
|
||||
canCreateFlows,
|
||||
canReadRole,
|
||||
canReadUser,
|
||||
canUpdateConfig,
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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) }),
|
||||
]),
|
||||
};
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ function AppConnectionRow(props) {
|
||||
{ connectionId: id },
|
||||
{
|
||||
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 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,
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -20,7 +20,7 @@ function CodeEditor(props) {
|
||||
'data-test': dataTest,
|
||||
} = props;
|
||||
|
||||
const handleEditorOnMount = (editor, monaco) => {
|
||||
const handleEditorOnMount = (editor) => {
|
||||
editorRef.current = editor;
|
||||
|
||||
editor.onDidContentSizeChange((event) => {
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -55,9 +55,10 @@ Item.propTypes = {
|
||||
onOptionClick: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
const renderItemFactory =
|
||||
({ onOptionClick }) =>
|
||||
(props) => <Item onOptionClick={onOptionClick} {...props} />;
|
||||
const renderItemFactory = ({ onOptionClick }) =>
|
||||
function RenderItem(props) {
|
||||
return <Item onOptionClick={onOptionClick} {...props} />;
|
||||
};
|
||||
|
||||
const Options = (props) => {
|
||||
const formatMessage = useFormatMessage();
|
||||
|
||||
@@ -89,7 +89,7 @@ function ControlledCustomAutocomplete(props) {
|
||||
};
|
||||
|
||||
const resizeObserver = React.useMemo(function syncCustomOptionsPosition() {
|
||||
return new ResizeObserver(() => {
|
||||
return new window.ResizeObserver(() => {
|
||||
forceUpdate();
|
||||
});
|
||||
}, []);
|
||||
|
||||
@@ -4,8 +4,6 @@ import { AdapterLuxon } from '@mui/x-date-pickers/AdapterLuxon';
|
||||
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
||||
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
||||
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
|
||||
export default function DatePickerInput({
|
||||
onChange,
|
||||
defaultValue = '',
|
||||
@@ -15,7 +13,6 @@ export default function DatePickerInput({
|
||||
maxDate,
|
||||
}) {
|
||||
const intl = useIntl();
|
||||
const formatMessage = useFormatMessage();
|
||||
|
||||
const props = {
|
||||
label,
|
||||
|
||||
@@ -39,7 +39,9 @@ function DeleteApiTokenButton(props) {
|
||||
},
|
||||
},
|
||||
);
|
||||
} catch {}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}, [deleteApiToken]);
|
||||
|
||||
const handleClose = () => {
|
||||
|
||||
@@ -43,7 +43,9 @@ function DeleteRoleButton(props) {
|
||||
'data-test': 'snackbar-delete-role-success',
|
||||
},
|
||||
});
|
||||
} catch {}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}, [deleteRole, enqueueSnackbar, formatMessage]);
|
||||
|
||||
const handleClose = () => {
|
||||
|
||||
@@ -39,7 +39,9 @@ function DeleteUserButton(props) {
|
||||
'data-test': 'snackbar-delete-user-success',
|
||||
},
|
||||
});
|
||||
} catch {}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}, [deleteUser]);
|
||||
|
||||
const handleClose = () => {
|
||||
|
||||
@@ -12,7 +12,7 @@ import { Drawer as BaseDrawer } from './style';
|
||||
|
||||
const iOS =
|
||||
typeof navigator !== 'undefined' &&
|
||||
/iPad|iPhone|iPod/.test(navigator.userAgent);
|
||||
/iPad|iPhone|iPod/.test(window.navigator.userAgent);
|
||||
|
||||
function Drawer(props) {
|
||||
const { links = [], bottomLinks = [], ...drawerProps } = props;
|
||||
|
||||
@@ -27,8 +27,9 @@ import useUpdateFlow from 'hooks/useUpdateFlow';
|
||||
import useUpdateFlowStatus from 'hooks/useUpdateFlowStatus';
|
||||
import FlowFolder from './FlowFolder';
|
||||
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() {
|
||||
const { flowId } = useParams();
|
||||
@@ -48,7 +49,7 @@ export default function EditorLayout() {
|
||||
});
|
||||
};
|
||||
|
||||
const onExportFlow = async (name) => {
|
||||
const onExportFlow = async () => {
|
||||
const flowExport = await exportFlow();
|
||||
|
||||
downloadJsonAsFile({
|
||||
|
||||
@@ -17,7 +17,7 @@ export default function Edge({
|
||||
const { flowActive, onStepAdd, isCreateStepPending } =
|
||||
useContext(EdgesContext);
|
||||
|
||||
const [edgePath, labelX, labelY] = getStraightPath({
|
||||
const [, labelX, labelY] = getStraightPath({
|
||||
sourceX,
|
||||
sourceY,
|
||||
targetX,
|
||||
|
||||
@@ -8,7 +8,7 @@ export const NodeWrapper = styled(Box)(({ theme }) => ({
|
||||
padding: theme.spacing(0, 2.5),
|
||||
}));
|
||||
|
||||
export const NodeInnerWrapper = styled(Box)(({ theme }) => ({
|
||||
export const NodeInnerWrapper = styled(Box)(() => ({
|
||||
maxWidth: 900,
|
||||
flex: 1,
|
||||
}));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Stack } from '@mui/material';
|
||||
import { styled } from '@mui/material/styles';
|
||||
|
||||
export const EditorWrapper = styled(Stack)(({ theme }) => ({
|
||||
export const EditorWrapper = styled(Stack)(() => ({
|
||||
flexGrow: 1,
|
||||
'& > div': {
|
||||
flexGrow: 1,
|
||||
|
||||
@@ -7,20 +7,16 @@ import {
|
||||
InputLabel,
|
||||
MenuItem,
|
||||
Select,
|
||||
Typography,
|
||||
useMediaQuery,
|
||||
} from '@mui/material';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import { DateTime } from 'luxon';
|
||||
import { useState } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
|
||||
import Can from 'components/Can';
|
||||
import DatePickerInput from 'components/DatePickerInput';
|
||||
import useExecutionFilters from 'hooks/useExecutionFilters';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
|
||||
export default function ExecutionFilters({ onFilterChange }) {
|
||||
export default function ExecutionFilters() {
|
||||
const theme = useTheme();
|
||||
const formatMessage = useFormatMessage();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
||||
|
||||
@@ -185,7 +185,7 @@ ContextMenu.propTypes = {
|
||||
onClose: PropTypes.func.isRequired,
|
||||
anchorEl: PropTypes.oneOfType([
|
||||
PropTypes.func,
|
||||
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
||||
PropTypes.shape({ current: PropTypes.instanceOf(window.Element) }),
|
||||
]).isRequired,
|
||||
onDuplicateFlow: PropTypes.func,
|
||||
appKey: PropTypes.string,
|
||||
|
||||
@@ -6,19 +6,17 @@ import {
|
||||
InputLabel,
|
||||
MenuItem,
|
||||
Select,
|
||||
Typography,
|
||||
useMediaQuery,
|
||||
Collapse,
|
||||
} from '@mui/material';
|
||||
import FilterAltIcon from '@mui/icons-material/FilterAlt';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
|
||||
import Can from 'components/Can';
|
||||
import useCurrentUserRuleConditions from 'hooks/useCurrentUserRuleConditions';
|
||||
import useFlowFilters from 'hooks/useFlowFilters';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
|
||||
export default function FlowFilters({ onFilterChange }) {
|
||||
export default function FlowFilters() {
|
||||
const theme = useTheme();
|
||||
const formatMessage = useFormatMessage();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
||||
|
||||
@@ -43,8 +43,9 @@ import useActions from 'hooks/useActions';
|
||||
import useTriggerSubsteps from 'hooks/useTriggerSubsteps';
|
||||
import useActionSubsteps from 'hooks/useActionSubsteps';
|
||||
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 errorIcon = <ErrorIcon color="error" />;
|
||||
|
||||
@@ -48,7 +48,7 @@ FlowStepContextMenu.propTypes = {
|
||||
onDelete: PropTypes.func,
|
||||
anchorEl: PropTypes.oneOfType([
|
||||
PropTypes.func,
|
||||
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
||||
PropTypes.shape({ current: PropTypes.instanceOf(window.Element) }),
|
||||
]),
|
||||
deletable: PropTypes.bool.isRequired,
|
||||
flowId: PropTypes.string.isRequired,
|
||||
|
||||
@@ -10,8 +10,9 @@ import FlowSubstepTitle from 'components/FlowSubstepTitle';
|
||||
import InputCreator from 'components/InputCreator';
|
||||
import FilterConditions from './FilterConditions';
|
||||
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) {
|
||||
const {
|
||||
|
||||
@@ -3,7 +3,6 @@ import { Link, useSearchParams, useNavigate } from 'react-router-dom';
|
||||
import Box from '@mui/material/Box';
|
||||
import Stack from '@mui/material/Stack';
|
||||
import Card from '@mui/material/Card';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import EditIcon from '@mui/icons-material/Edit';
|
||||
@@ -24,7 +23,6 @@ import useFormatMessage from 'hooks/useFormatMessage';
|
||||
import useFolders from 'hooks/useFolders';
|
||||
import useDeleteFolder from 'hooks/useDeleteFolder';
|
||||
import useEnqueueSnackbar from 'hooks/useEnqueueSnackbar';
|
||||
import objectifyUrlSearchParams from 'helpers/objectifyUrlSearchParams';
|
||||
import useFlowFilters from 'hooks/useFlowFilters';
|
||||
|
||||
import { ListItemIcon } from './style';
|
||||
|
||||
@@ -87,7 +87,7 @@ function Form(props) {
|
||||
return (
|
||||
<FormProvider {...methods}>
|
||||
<form
|
||||
onSubmit={methods.handleSubmit(async (data, event) => {
|
||||
onSubmit={methods.handleSubmit(async (data) => {
|
||||
try {
|
||||
return await onSubmit?.(data);
|
||||
} catch (errors) {
|
||||
|
||||
@@ -55,10 +55,10 @@ function ImportFlowDialog(props) {
|
||||
}
|
||||
};
|
||||
|
||||
const handleImportFlow = (event) => {
|
||||
const handleImportFlow = () => {
|
||||
if (!selectedFile) return;
|
||||
|
||||
const fileReader = new FileReader();
|
||||
const fileReader = new window.FileReader();
|
||||
|
||||
fileReader.onload = async function readFileLoaded(e) {
|
||||
const flowData = parseFlowFile(e.target.result);
|
||||
|
||||
@@ -6,7 +6,7 @@ import englishMessages from 'locales/en.json';
|
||||
const IntlProvider = ({ children }) => {
|
||||
return (
|
||||
<BaseIntlProvider
|
||||
locale={navigator.language.split('-')[0]}
|
||||
locale={window.navigator.language.split('-')[0]}
|
||||
defaultLocale="en"
|
||||
messages={englishMessages}
|
||||
>
|
||||
|
||||
@@ -2,13 +2,10 @@ import styled from '@emotion/styled';
|
||||
import Box from '@mui/material/Box';
|
||||
import Divider from '@mui/material/Divider';
|
||||
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 useAutomatischConfig from 'hooks/useAutomatischConfig';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
import useVersion from 'hooks/useVersion';
|
||||
|
||||
const LogoImage = styled('img')(() => ({
|
||||
maxWidth: 'auto',
|
||||
@@ -16,7 +13,7 @@ const LogoImage = styled('img')(() => ({
|
||||
}));
|
||||
|
||||
const LayoutFooter = () => {
|
||||
const { data: config, isPending: isConfigPending } = useAutomatischConfig();
|
||||
const { data: config } = useAutomatischConfig();
|
||||
const formatMessage = useFormatMessage();
|
||||
|
||||
if (config?.data.enableFooter !== true) return null;
|
||||
@@ -34,22 +31,20 @@ const LayoutFooter = () => {
|
||||
href: config.data.footerTosUrl,
|
||||
text: formatMessage('footer.tosLinkText'),
|
||||
},
|
||||
|
||||
{
|
||||
key: 'privacy-policy',
|
||||
show: !!config.data.footerPrivacyPolicyUrl,
|
||||
href: config.data.footerPrivacyPolicyUrl,
|
||||
text: formatMessage('footer.privacyPolicyLinkText'),
|
||||
},
|
||||
|
||||
{
|
||||
key: 'imprint',
|
||||
show: !!config.data.footerImprintUrl,
|
||||
href: config.data.footerImprintUrl,
|
||||
text: formatMessage('footer.imprintLinkText'),
|
||||
},
|
||||
,
|
||||
];
|
||||
|
||||
return (
|
||||
<Box mt="auto" position="sticky" bottom={0}>
|
||||
<Box bgcolor="common.white" mt={4}>
|
||||
|
||||
@@ -15,7 +15,7 @@ function ListItemLink(props) {
|
||||
React.forwardRef(function InLineLink(linkProps, ref) {
|
||||
try {
|
||||
// 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 (
|
||||
<a
|
||||
{...linkProps}
|
||||
|
||||
@@ -40,7 +40,9 @@ function LoginForm() {
|
||||
});
|
||||
const { token } = data;
|
||||
authentication.updateToken(token);
|
||||
} catch {}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const renderError = () => {
|
||||
@@ -49,7 +51,7 @@ function LoginForm() {
|
||||
];
|
||||
|
||||
return errors.map((error) => (
|
||||
<Alert severity="error" sx={{ mt: 2 }}>
|
||||
<Alert key={error} severity="error" sx={{ mt: 2 }}>
|
||||
{error}
|
||||
</Alert>
|
||||
));
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { ReactComponent as MationLogoSvg } from './assets/mation-logo.svg';
|
||||
import MationLogoSvg from './assets/mation-logo.svg';
|
||||
|
||||
const MationLogo = () => {
|
||||
return <MationLogoSvg />;
|
||||
return <img src={MationLogoSvg} alt="Mation Logo" />;
|
||||
};
|
||||
|
||||
export default MationLogo;
|
||||
|
||||
@@ -3,22 +3,11 @@ import { useFormContext } from 'react-hook-form';
|
||||
import PropTypes from 'prop-types';
|
||||
import ControlledCheckbox from 'components/ControlledCheckbox';
|
||||
|
||||
const AllEntitiesPermissions = ({
|
||||
action,
|
||||
subject,
|
||||
disabled,
|
||||
name,
|
||||
syncIsCreator,
|
||||
}) => {
|
||||
const { getValues, formState, resetField } = useFormContext();
|
||||
const AllEntitiesPermissions = ({ action, subject, disabled, name }) => {
|
||||
const { getValues, resetField } = useFormContext();
|
||||
|
||||
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 ownEntitiesFieldTouched =
|
||||
formState.touchedFields?.[name]?.[subject.key]?.[action.key]
|
||||
?.ownEntities === true;
|
||||
|
||||
const currentValue = getValues(fieldName);
|
||||
|
||||
@@ -28,16 +17,6 @@ const AllEntitiesPermissions = ({
|
||||
}
|
||||
}, [ownEntitiesFieldName, currentValue]);
|
||||
|
||||
const handleSyncIsCreator = (newValue) => {
|
||||
if (syncIsCreator && defaultValue === false && !ownEntitiesFieldTouched) {
|
||||
resetField(ownEntitiesFieldName, { defaultValue: newValue });
|
||||
}
|
||||
|
||||
if (newValue === true) {
|
||||
resetField(ownEntitiesFieldName, { defaultValue: true });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ControlledCheckbox
|
||||
disabled={disabled}
|
||||
|
||||
@@ -42,7 +42,7 @@ Popper.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.array.isRequired,
|
||||
onSuggestionClick: PropTypes.func,
|
||||
|
||||
@@ -28,11 +28,10 @@ const getPartialArray = (array, length = array.length) => {
|
||||
return array.slice(0, length);
|
||||
};
|
||||
|
||||
const renderItemFactory =
|
||||
({ onSuggestionClick }) =>
|
||||
(props) => (
|
||||
<SuggestionItem {...props} onSuggestionClick={onSuggestionClick} />
|
||||
);
|
||||
const renderItemFactory = ({ onSuggestionClick }) =>
|
||||
function RenderItem(props) {
|
||||
return <SuggestionItem {...props} onSuggestionClick={onSuggestionClick} />;
|
||||
};
|
||||
|
||||
const Suggestions = (props) => {
|
||||
const formatMessage = useFormatMessage();
|
||||
|
||||
@@ -50,7 +50,9 @@ export default function ResetPasswordForm() {
|
||||
},
|
||||
});
|
||||
navigate(URLS.LOGIN);
|
||||
} catch {}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const renderError = () => {
|
||||
@@ -63,7 +65,7 @@ export default function ResetPasswordForm() {
|
||||
];
|
||||
|
||||
return errors.map((error) => (
|
||||
<Alert severity="error" sx={{ mt: 2 }}>
|
||||
<Alert key={error} severity="error" sx={{ mt: 2 }}>
|
||||
{error}
|
||||
</Alert>
|
||||
));
|
||||
|
||||
@@ -23,7 +23,7 @@ export default function SplitButton(props) {
|
||||
setOpen((prevOpen) => !prevOpen);
|
||||
};
|
||||
|
||||
const handleClose = (event) => {
|
||||
const handleClose = () => {
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
|
||||
@@ -15,8 +15,9 @@ import WebhookUrlInfo from 'components/WebhookUrlInfo';
|
||||
import FlowSubstepTitle from 'components/FlowSubstepTitle';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
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) {
|
||||
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) => {
|
||||
/**
|
||||
* In case `backendUrl` is a host, we append the url to it.
|
||||
**/
|
||||
try {
|
||||
return new URL(url, backendUrl).toString();
|
||||
} catch (e) {
|
||||
return new window.URL(url, backendUrl).toString();
|
||||
} catch {
|
||||
/*
|
||||
* In case `backendUrl` is not qualified, we utilize `url` alone.
|
||||
**/
|
||||
@@ -15,8 +15,9 @@ const computeUrl = (url, backendUrl) => {
|
||||
};
|
||||
|
||||
const config = {
|
||||
baseUrl: process.env.REACT_APP_BASE_URL,
|
||||
baseUrl: import.meta.env.VITE_BASE_URL,
|
||||
restApiUrl: computeUrl('/internal/api', backendUrl),
|
||||
useNewFlowEditor: import.meta.env.VITE_USE_NEW_FLOW_EDITOR === 'true',
|
||||
supportEmailAddress: 'support@automatisch.io',
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
const parseUrlSearchParams = (event) => {
|
||||
const searchParams = new URLSearchParams(event.data.payload.search);
|
||||
const hashParams = new URLSearchParams(event.data.payload.hash.substring(1));
|
||||
const searchParams = new window.URLSearchParams(event.data.payload.search);
|
||||
const hashParams = new window.URLSearchParams(
|
||||
event.data.payload.hash.substring(1),
|
||||
);
|
||||
const searchParamsObject = getObjectOfEntries(searchParams.entries());
|
||||
const hashParamsObject = getObjectOfEntries(hashParams.entries());
|
||||
|
||||
@@ -33,9 +35,9 @@ export const processPopupMessage = (popup) => {
|
||||
let closeCheckIntervalId;
|
||||
|
||||
if (popup) {
|
||||
closeCheckIntervalId = setInterval(() => {
|
||||
closeCheckIntervalId = window.setInterval(() => {
|
||||
if (popup.closed) {
|
||||
clearInterval(closeCheckIntervalId);
|
||||
window.clearInterval(closeCheckIntervalId);
|
||||
|
||||
reject({ message: 'Error occured while verifying credentials!' });
|
||||
}
|
||||
@@ -51,7 +53,7 @@ export const processPopupMessage = (popup) => {
|
||||
window.removeEventListener('message', messageHandler);
|
||||
|
||||
if (closeCheckIntervalId) {
|
||||
clearInterval(closeCheckIntervalId);
|
||||
window.clearInterval(closeCheckIntervalId);
|
||||
}
|
||||
|
||||
resolve(data);
|
||||
|
||||
@@ -2,13 +2,13 @@ const NAMESPACE = 'automatisch';
|
||||
const makeKey = (key) => `${NAMESPACE}.${key}`;
|
||||
|
||||
export const setItem = (key, value) => {
|
||||
return localStorage.setItem(makeKey(key), value);
|
||||
return window.localStorage.setItem(makeKey(key), value);
|
||||
};
|
||||
|
||||
export const getItem = (key) => {
|
||||
return localStorage.getItem(makeKey(key));
|
||||
return window.localStorage.getItem(makeKey(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 from '@mui/material/Link';
|
||||
|
||||
export const generateInternalLink = (link) => (str) => (
|
||||
<Link component={RouterLink} to={link}>
|
||||
{str}
|
||||
</Link>
|
||||
);
|
||||
export const generateInternalLink = (link) =>
|
||||
function LinkVariable(str) {
|
||||
return (
|
||||
<Link component={RouterLink} to={link}>
|
||||
{str}
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export const generateExternalLink = (link) => (str) => (
|
||||
<Link href={link} target="_blank">
|
||||
{str}
|
||||
</Link>
|
||||
);
|
||||
export const generateExternalLink = (link) =>
|
||||
function LinkVariable(str) {
|
||||
return (
|
||||
<Link href={link} target="_blank">
|
||||
{str}
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export const makeBold = (str) => <strong>{str}</strong>;
|
||||
|
||||
@@ -5,13 +5,13 @@ export default function useAdminDeleteRole(roleId) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const query = useMutation({
|
||||
mutationFn: async (payload) => {
|
||||
mutationFn: async () => {
|
||||
const { data } = await api.delete(`/v1/admin/roles/${roleId}`);
|
||||
|
||||
return data;
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({
|
||||
onSuccess: async () => {
|
||||
await queryClient.invalidateQueries({
|
||||
queryKey: ['admin', 'roles'],
|
||||
});
|
||||
},
|
||||
|
||||
@@ -10,7 +10,7 @@ const appendTrailingSlash = (url) => {
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
const { data: automatischInfo } = useAutomatischInfo();
|
||||
const docsUrlWithTrailingSlash = appendTrailingSlash(automatischInfo?.docsUrl);
|
||||
const docsUrlWithTrailingSlash = appendTrailingSlash(
|
||||
automatischInfo?.docsUrl,
|
||||
);
|
||||
const docsUrl = docsUrlWithTrailingSlash || 'https://automatisch.io/docs/';
|
||||
|
||||
const absoluteUrl = new URL(path, docsUrl).toString();
|
||||
const absoluteUrl = new window.URL(path, docsUrl).toString();
|
||||
|
||||
return absoluteUrl;
|
||||
}
|
||||
|
||||
@@ -12,11 +12,11 @@ export default function useDownloadJsonAsFile() {
|
||||
replacement: '-',
|
||||
});
|
||||
|
||||
const fileBlob = new Blob([stringifiedContents], {
|
||||
const fileBlob = new window.Blob([stringifiedContents], {
|
||||
type: 'application/json',
|
||||
});
|
||||
|
||||
const fileObjectUrl = URL.createObjectURL(fileBlob);
|
||||
const fileObjectUrl = window.URL.createObjectURL(fileBlob);
|
||||
|
||||
const temporaryDownloadLink = document.createElement('a');
|
||||
temporaryDownloadLink.href = fileObjectUrl;
|
||||
|
||||
@@ -92,7 +92,7 @@ function useDynamicData(stepId, schema) {
|
||||
lastComputedVariables.current = variables;
|
||||
|
||||
return variables;
|
||||
} catch (err) {
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ function useDynamicFields(stepId, schema) {
|
||||
}
|
||||
lastComputedVariables.current = variables;
|
||||
return variables;
|
||||
} catch (err) {
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useMutation } from '@tanstack/react-query';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
import api from 'helpers/api';
|
||||
import objectifyUrlSearchParams from 'helpers/objectifyUrlSearchParams';
|
||||
|
||||
export default function useExecutionFilters() {
|
||||
@@ -21,7 +19,8 @@ export default function useExecutionFilters() {
|
||||
const endDateTime = parseInt(endDateTimeString, 10);
|
||||
|
||||
const filterByStatus = (status) => {
|
||||
setSearchParams((current) => {
|
||||
setSearchParams(() => {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { status: currentStatus, ...rest } = searchParamsObject;
|
||||
|
||||
if (status) {
|
||||
@@ -35,7 +34,8 @@ export default function useExecutionFilters() {
|
||||
const filterByStartDateTime = (startDateTime) => {
|
||||
const startDateTimeString = startDateTime?.toMillis();
|
||||
|
||||
setSearchParams((current) => {
|
||||
setSearchParams(() => {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { startDateTime: currentStartDateTime, ...rest } =
|
||||
searchParamsObject;
|
||||
|
||||
@@ -50,7 +50,8 @@ export default function useExecutionFilters() {
|
||||
const filterByEndDateTime = (endDateTime) => {
|
||||
const endDateTimeString = endDateTime?.endOf('day').toMillis();
|
||||
|
||||
setSearchParams((current) => {
|
||||
setSearchParams(() => {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { endDateTime: currentEndDateTime, ...rest } = searchParamsObject;
|
||||
|
||||
if (endDateTimeString) {
|
||||
@@ -65,13 +66,14 @@ export default function useExecutionFilters() {
|
||||
const searchParamsObject = objectifyUrlSearchParams(searchParams);
|
||||
|
||||
if (value === undefined) {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { [key]: keyToRemove, ...remainingSearchParams } =
|
||||
searchParamsObject;
|
||||
|
||||
return new URLSearchParams(remainingSearchParams).toString();
|
||||
return new window.URLSearchParams(remainingSearchParams).toString();
|
||||
}
|
||||
|
||||
return new URLSearchParams({
|
||||
return new window.URLSearchParams({
|
||||
...searchParamsObject,
|
||||
[key]: value,
|
||||
}).toString();
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useMutation } from '@tanstack/react-query';
|
||||
|
||||
import api from 'helpers/api';
|
||||
import objectifyUrlSearchParams from 'helpers/objectifyUrlSearchParams';
|
||||
|
||||
export default function useFlowFilters() {
|
||||
@@ -14,7 +12,8 @@ export default function useFlowFilters() {
|
||||
searchParamsObject.onlyOwnedFlows === 'true' || undefined;
|
||||
|
||||
const filterByStatus = (status) => {
|
||||
setSearchParams((current) => {
|
||||
setSearchParams(() => {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { status: currentStatus, ...rest } = searchParamsObject;
|
||||
|
||||
if (status) {
|
||||
@@ -26,7 +25,8 @@ export default function useFlowFilters() {
|
||||
};
|
||||
|
||||
const filterByOwnership = (onlyOwnedFlows) => {
|
||||
setSearchParams((current) => {
|
||||
setSearchParams(() => {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { onlyOwnedFlows: currentOnlyOwnedFlows, ...rest } =
|
||||
searchParamsObject;
|
||||
|
||||
@@ -42,13 +42,14 @@ export default function useFlowFilters() {
|
||||
const searchParamsObject = objectifyUrlSearchParams(searchParams);
|
||||
|
||||
if (value === undefined) {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { [key]: keyToRemove, ...remainingSearchParams } =
|
||||
searchParamsObject;
|
||||
|
||||
return new URLSearchParams(remainingSearchParams).toString();
|
||||
return new window.URLSearchParams(remainingSearchParams).toString();
|
||||
}
|
||||
|
||||
return new URLSearchParams({
|
||||
return new window.URLSearchParams({
|
||||
...searchParamsObject,
|
||||
[key]: value,
|
||||
}).toString();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import userAbility from 'helpers/userAbility';
|
||||
import useCurrentUser from 'hooks/useCurrentUser';
|
||||
|
||||
export default function useIsCurrentUserAdmin() {
|
||||
|
||||
@@ -4,10 +4,10 @@ import api from 'helpers/api';
|
||||
import React from 'react';
|
||||
|
||||
export default function useLazyApps({ appName } = {}, { onSuccess } = {}) {
|
||||
const abortControllerRef = React.useRef(new AbortController());
|
||||
const abortControllerRef = React.useRef(new window.AbortController());
|
||||
|
||||
React.useEffect(() => {
|
||||
abortControllerRef.current = new AbortController();
|
||||
abortControllerRef.current = new window.AbortController();
|
||||
|
||||
return () => {
|
||||
abortControllerRef.current?.abort();
|
||||
|
||||
@@ -8,8 +8,7 @@ import MetadataProvider from 'components/MetadataProvider';
|
||||
import { AuthenticationProvider } from 'contexts/Authentication';
|
||||
import QueryClientProvider from 'components/QueryClientProvider';
|
||||
import Router from 'components/Router';
|
||||
import routes from 'routes';
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
import routes from './routes';
|
||||
|
||||
// Sets the default locale to English for all luxon DateTime instances created afterwards.
|
||||
Settings.defaultLocale = 'en';
|
||||
@@ -32,8 +31,3 @@ root.render(
|
||||
</SnackbarProvider>
|
||||
</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 }}
|
||||
noValidate
|
||||
automaticValidation={false}
|
||||
render={({ formState: { errors, isDirty } }) => (
|
||||
render={() => (
|
||||
<Switch
|
||||
name="enableTemplates"
|
||||
disabled={isUpdateConfigPending}
|
||||
|
||||
@@ -30,7 +30,9 @@ export default function CreateFlow() {
|
||||
const flowId = response.data?.id;
|
||||
|
||||
navigateToEditor(flowId);
|
||||
} catch {}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
initiate();
|
||||
|
||||
@@ -25,9 +25,6 @@ export default function Executions() {
|
||||
const navigate = useNavigate();
|
||||
const page = parseInt(searchParams.get('page') || '', 10) || 1;
|
||||
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 {
|
||||
@@ -61,7 +58,7 @@ export default function Executions() {
|
||||
const getPathWithSearchParams = (page) => {
|
||||
const searchParamsObject = objectifyUrlSearchParams(searchParams);
|
||||
|
||||
const newSearchParams = new URLSearchParams({
|
||||
const newSearchParams = new window.URLSearchParams({
|
||||
...searchParamsObject,
|
||||
page,
|
||||
});
|
||||
|
||||
@@ -73,7 +73,7 @@ export default function Flows() {
|
||||
const getPathWithSearchParams = (page) => {
|
||||
const searchParamsObject = objectifyUrlSearchParams(searchParams);
|
||||
|
||||
const newSearchParams = new URLSearchParams({
|
||||
const newSearchParams = new window.URLSearchParams({
|
||||
...searchParamsObject,
|
||||
page,
|
||||
});
|
||||
|
||||
@@ -87,7 +87,7 @@ export default function UserInterface() {
|
||||
'data-test': 'snackbar-update-user-interface-success',
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
} catch {
|
||||
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 Execution from 'pages/Execution';
|
||||
import Flows from 'pages/Flows';
|
||||
import Flow from 'pages/Flow';
|
||||
import Login from 'pages/Login';
|
||||
import AcceptInvitation from 'pages/AcceptInvitation';
|
||||
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