feat: add missing propTypes
This commit is contained in:
@@ -68,7 +68,10 @@ function AccountDropdownMenu(props) {
|
||||
AccountDropdownMenu.propTypes = {
|
||||
open: PropTypes.bool.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
anchorEl: PropTypes.oneOfType([PropTypes.element, PropTypes.func]),
|
||||
anchorEl: PropTypes.oneOfType([
|
||||
PropTypes.func,
|
||||
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
||||
]),
|
||||
id: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
|
@@ -76,7 +76,10 @@ const CustomOptions = (props) => {
|
||||
|
||||
CustomOptions.propTypes = {
|
||||
open: PropTypes.bool.isRequired,
|
||||
anchorEl: PropTypes.oneOfType([PropTypes.element, PropTypes.func]).isRequired,
|
||||
anchorEl: PropTypes.oneOfType([
|
||||
PropTypes.func,
|
||||
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
||||
]),
|
||||
data: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
|
@@ -18,10 +18,8 @@ const computeListHeight = (currentLength) => {
|
||||
return LIST_ITEM_HEIGHT * numberOfRenderedItems;
|
||||
};
|
||||
|
||||
const renderItemFactory =
|
||||
({ onOptionClick }) =>
|
||||
(props) => {
|
||||
const { index, style, data } = props;
|
||||
const Item = (props) => {
|
||||
const { index, style, data, onOptionClick } = props;
|
||||
const suboption = data[index];
|
||||
return (
|
||||
<ListItemButton
|
||||
@@ -50,6 +48,19 @@ const renderItemFactory =
|
||||
);
|
||||
};
|
||||
|
||||
Item.propTypes = {
|
||||
index: PropTypes.number.isRequired,
|
||||
style: PropTypes.object,
|
||||
data: PropTypes.array.isRequired,
|
||||
onOptionClick: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
const renderItemFactory =
|
||||
({ onOptionClick }) =>
|
||||
(props) => {
|
||||
<Item onOptionClick={onOptionClick} {...props} />;
|
||||
};
|
||||
|
||||
const Options = (props) => {
|
||||
const formatMessage = useFormatMessage();
|
||||
const { data, onOptionClick } = props;
|
||||
|
@@ -364,6 +364,7 @@ FlowStep.propTypes = {
|
||||
onClose: PropTypes.func,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onContinue: PropTypes.func,
|
||||
flowId: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default FlowStep;
|
||||
|
@@ -43,8 +43,12 @@ function FlowStepContextMenu(props) {
|
||||
FlowStepContextMenu.propTypes = {
|
||||
stepId: PropTypes.string.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
anchorEl: PropTypes.element.isRequired,
|
||||
anchorEl: PropTypes.oneOfType([
|
||||
PropTypes.func,
|
||||
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
||||
]),
|
||||
deletable: PropTypes.bool.isRequired,
|
||||
flowId: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default FlowStepContextMenu;
|
||||
|
@@ -1,7 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import { FormProvider, useForm, useWatch } from 'react-hook-form';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const noop = () => null;
|
||||
export default function Form(props) {
|
||||
|
||||
function Form(props) {
|
||||
const {
|
||||
children,
|
||||
onSubmit = noop,
|
||||
@@ -11,22 +14,27 @@ export default function Form(props) {
|
||||
mode = 'all',
|
||||
...formProps
|
||||
} = props;
|
||||
|
||||
const methods = useForm({
|
||||
defaultValues,
|
||||
reValidateMode: 'onBlur',
|
||||
resolver,
|
||||
mode,
|
||||
});
|
||||
|
||||
const form = useWatch({ control: methods.control });
|
||||
|
||||
/**
|
||||
* For fields having `dependsOn` fields, we need to re-validate the form.
|
||||
*/
|
||||
React.useEffect(() => {
|
||||
methods.trigger();
|
||||
}, [methods.trigger, form]);
|
||||
|
||||
React.useEffect(() => {
|
||||
methods.reset(defaultValues);
|
||||
}, [defaultValues]);
|
||||
|
||||
return (
|
||||
<FormProvider {...methods}>
|
||||
<form onSubmit={methods.handleSubmit(onSubmit)} {...formProps}>
|
||||
@@ -35,3 +43,14 @@ export default function Form(props) {
|
||||
</FormProvider>
|
||||
);
|
||||
}
|
||||
|
||||
Form.propTypes = {
|
||||
children: PropTypes.node,
|
||||
defaultValues: PropTypes.object,
|
||||
onSubmit: PropTypes.func,
|
||||
render: PropTypes.func,
|
||||
resolver: PropTypes.func,
|
||||
mode: PropTypes.oneOf(['onChange', 'onBlur', 'onSubmit', 'onTouched', 'all']),
|
||||
};
|
||||
|
||||
export default Form;
|
||||
|
@@ -1,7 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import Slide from '@mui/material/Slide';
|
||||
import useScrollTrigger from '@mui/material/useScrollTrigger';
|
||||
|
||||
export default function HideOnScroll(props) {
|
||||
const trigger = useScrollTrigger();
|
||||
|
||||
return <Slide appear={false} direction="down" in={!trigger} {...props} />;
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import MuiTextField from '@mui/material/TextField';
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import useDynamicFields from 'hooks/useDynamicFields';
|
||||
import useDynamicData from 'hooks/useDynamicData';
|
||||
@@ -9,11 +10,11 @@ import TextField from 'components/TextField';
|
||||
import ControlledAutocomplete from 'components/ControlledAutocomplete';
|
||||
import ControlledCustomAutocomplete from 'components/ControlledCustomAutocomplete';
|
||||
import DynamicField from 'components/DynamicField';
|
||||
import { FieldPropType } from 'propTypes/propTypes';
|
||||
|
||||
const optionGenerator = (options) =>
|
||||
options?.map(({ name, value }) => ({ label: name, value: value }));
|
||||
|
||||
export default function InputCreator(props) {
|
||||
function InputCreator(props) {
|
||||
const {
|
||||
onChange,
|
||||
onBlur,
|
||||
@@ -131,7 +132,8 @@ export default function InputCreator(props) {
|
||||
<React.Fragment>
|
||||
<PowerInput
|
||||
key={computedName}
|
||||
label={label}
|
||||
// label={label}
|
||||
label="PowerInput"
|
||||
description={description}
|
||||
name={computedName}
|
||||
required={required}
|
||||
@@ -204,3 +206,16 @@ export default function InputCreator(props) {
|
||||
}
|
||||
return <React.Fragment />;
|
||||
}
|
||||
|
||||
InputCreator.propTypes = {
|
||||
onChange: PropTypes.func,
|
||||
onBlur: PropTypes.func,
|
||||
schema: FieldPropType.isRequired,
|
||||
namePrefix: PropTypes.string,
|
||||
stepId: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
showOptionValue: PropTypes.bool,
|
||||
shouldUnregister: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default InputCreator;
|
||||
|
@@ -1,8 +1,12 @@
|
||||
import * as React from 'react';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { Container } from './style';
|
||||
export default function IntermediateStepCount(props) {
|
||||
|
||||
function IntermediateStepCount(props) {
|
||||
const { count } = props;
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Typography variant="subtitle1" sx={{}}>
|
||||
@@ -11,3 +15,9 @@ export default function IntermediateStepCount(props) {
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
IntermediateStepCount.propTypes = {
|
||||
count: PropTypes.number.isRequired,
|
||||
};
|
||||
|
||||
export default IntermediateStepCount;
|
||||
|
@@ -1,5 +1,8 @@
|
||||
import { IntlProvider as BaseIntlProvider } from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import englishMessages from 'locales/en.json';
|
||||
|
||||
const IntlProvider = ({ children }) => {
|
||||
return (
|
||||
<BaseIntlProvider
|
||||
@@ -11,4 +14,9 @@ const IntlProvider = ({ children }) => {
|
||||
</BaseIntlProvider>
|
||||
);
|
||||
};
|
||||
|
||||
IntlProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
export default IntlProvider;
|
||||
|
@@ -1,5 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { JSONTree } from 'react-json-tree';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const theme = {
|
||||
scheme: 'inspector',
|
||||
author: 'Alexander Kuznetsov (alexkuz@gmail.com)',
|
||||
@@ -36,8 +38,10 @@ const theme = {
|
||||
// base0F - Deprecated, Opening/Closing Embedded Language Tags, e.g. <?php ?>
|
||||
base0F: '#a16946',
|
||||
};
|
||||
|
||||
function JSONViewer(props) {
|
||||
const { data } = props;
|
||||
|
||||
return (
|
||||
<JSONTree
|
||||
hideRoot
|
||||
@@ -48,4 +52,9 @@ function JSONViewer(props) {
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
JSONViewer.propTypes = {
|
||||
data: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default JSONViewer;
|
||||
|
@@ -9,6 +9,7 @@ import SwapCallsIcon from '@mui/icons-material/SwapCalls';
|
||||
import HistoryIcon from '@mui/icons-material/History';
|
||||
import NotificationsIcon from '@mui/icons-material/Notifications';
|
||||
import ArrowBackIosNew from '@mui/icons-material/ArrowBackIosNew';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import * as URLS from 'config/urls';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
@@ -75,7 +76,7 @@ const generateDrawerBottomLinks = async ({
|
||||
return links;
|
||||
};
|
||||
|
||||
export default function PublicLayout({ children }) {
|
||||
function PublicLayout({ children }) {
|
||||
const version = useVersion();
|
||||
const { data: configData, isLoading } = useAutomatischConfig();
|
||||
const config = configData?.data;
|
||||
@@ -135,3 +136,9 @@ export default function PublicLayout({ children }) {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
PublicLayout.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
export default PublicLayout;
|
||||
|
@@ -4,9 +4,12 @@ import ListItem from '@mui/material/ListItemButton';
|
||||
import ListItemIcon from '@mui/material/ListItemIcon';
|
||||
import ListItemText from '@mui/material/ListItemText';
|
||||
import { Link } from 'react-router-dom';
|
||||
export default function ListItemLink(props) {
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
function ListItemLink(props) {
|
||||
const { icon, primary, to, onClick, 'data-test': dataTest, target } = props;
|
||||
const selected = useMatch({ path: to, end: true });
|
||||
|
||||
const CustomLink = React.useMemo(
|
||||
() =>
|
||||
React.forwardRef(function InLineLink(linkProps, ref) {
|
||||
@@ -28,6 +31,7 @@ export default function ListItemLink(props) {
|
||||
}),
|
||||
[to],
|
||||
);
|
||||
|
||||
return (
|
||||
<li>
|
||||
<ListItem
|
||||
@@ -47,3 +51,14 @@ export default function ListItemLink(props) {
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
ListItemLink.propTypes = {
|
||||
icon: PropTypes.node.isRequired,
|
||||
primary: PropTypes.string.isRequired,
|
||||
to: PropTypes.string.isRequired,
|
||||
target: PropTypes.oneOf(['_blank']),
|
||||
onClick: PropTypes.func,
|
||||
'data-test': PropTypes.string,
|
||||
};
|
||||
|
||||
export default ListItemLink;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
IconButton,
|
||||
Skeleton,
|
||||
@@ -7,6 +8,7 @@ import {
|
||||
} from '@mui/material';
|
||||
import EditIcon from '@mui/icons-material/Edit';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
|
||||
const ListLoader = ({ rowsNumber, columnsNumber, 'data-test': dataTest }) => {
|
||||
return (
|
||||
<>
|
||||
@@ -38,4 +40,11 @@ const ListLoader = ({ rowsNumber, columnsNumber, 'data-test': dataTest }) => {
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
ListLoader.propTypes = {
|
||||
rowsNumber: PropTypes.number.isRequired,
|
||||
columnsNumber: PropTypes.number.isRequired,
|
||||
'data-test': PropTypes.string,
|
||||
};
|
||||
|
||||
export default ListLoader;
|
||||
|
@@ -1,6 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { ReactComponent as MationLogoSvg } from './assets/mation-logo.svg';
|
||||
|
||||
const MationLogo = () => {
|
||||
return <MationLogoSvg />;
|
||||
};
|
||||
|
||||
export default MationLogo;
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import useAutomatischConfig from 'hooks/useAutomatischConfig';
|
||||
|
||||
@@ -27,10 +28,13 @@ const MetadataProvider = ({ children }) => {
|
||||
newFaviconElement.href = '/browser-tab.ico';
|
||||
}
|
||||
}
|
||||
|
||||
}, [config?.disableFavicon]);
|
||||
|
||||
return <>{children}</>;
|
||||
};
|
||||
|
||||
MetadataProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
export default MetadataProvider;
|
||||
|
@@ -4,9 +4,11 @@ import Card from '@mui/material/Card';
|
||||
import AddCircleIcon from '@mui/icons-material/AddCircle';
|
||||
import CardActionArea from '@mui/material/CardActionArea';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { CardContent } from './style';
|
||||
|
||||
export default function NoResultFound(props) {
|
||||
function NoResultFound(props) {
|
||||
const { text, to } = props;
|
||||
|
||||
const ActionAreaLink = React.useMemo(
|
||||
@@ -29,3 +31,10 @@ export default function NoResultFound(props) {
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
NoResultFound.propTypes = {
|
||||
text: PropTypes.string,
|
||||
to: PropTypes.string,
|
||||
};
|
||||
|
||||
export default NoResultFound;
|
||||
|
@@ -5,16 +5,21 @@ import CardActionArea from '@mui/material/CardActionArea';
|
||||
import CardContent from '@mui/material/CardContent';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { DateTime } from 'luxon';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
|
||||
const getHumanlyDate = (timestamp) =>
|
||||
DateTime.fromMillis(timestamp).toRelative();
|
||||
export default function NotificationCard(props) {
|
||||
|
||||
function NotificationCard(props) {
|
||||
const { name, createdAt, documentationUrl, description } = props;
|
||||
const formatMessage = useFormatMessage();
|
||||
const relativeCreatedAt = getHumanlyDate(new Date(createdAt).getTime());
|
||||
const subheader = formatMessage('notification.releasedAt', {
|
||||
relativeDate: relativeCreatedAt,
|
||||
});
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardActionArea component={'a'} href={documentationUrl} target="_blank">
|
||||
@@ -36,3 +41,12 @@ export default function NotificationCard(props) {
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
NotificationCard.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
createdAt: PropTypes.string.isRequired,
|
||||
documentationUrl: PropTypes.string.isRequired,
|
||||
description: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default NotificationCard;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import Typography from '@mui/material/Typography';
|
||||
|
||||
export default function PageTitle(props) {
|
||||
return <Typography variant="h3" data-test="page-title" {...props} />;
|
||||
}
|
||||
|
@@ -11,7 +11,9 @@ import {
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import SettingsIcon from '@mui/icons-material/Settings';
|
||||
|
||||
import ControlledCheckbox from 'components/ControlledCheckbox';
|
||||
|
||||
const PermissionCatalogFieldLoader = () => {
|
||||
return (
|
||||
<TableContainer>
|
||||
@@ -56,4 +58,5 @@ const PermissionCatalogFieldLoader = () => {
|
||||
</TableContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default PermissionCatalogFieldLoader;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import Button from '@mui/material/Button';
|
||||
import Dialog from '@mui/material/Dialog';
|
||||
import DialogActions from '@mui/material/DialogActions';
|
||||
@@ -15,7 +16,8 @@ import * as React from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import ControlledCheckbox from 'components/ControlledCheckbox';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
export default function PermissionSettings(props) {
|
||||
|
||||
function PermissionSettings(props) {
|
||||
const {
|
||||
onClose,
|
||||
open = false,
|
||||
@@ -27,6 +29,7 @@ export default function PermissionSettings(props) {
|
||||
} = props;
|
||||
const formatMessage = useFormatMessage();
|
||||
const { getValues, resetField } = useFormContext();
|
||||
|
||||
const cancel = () => {
|
||||
for (const action of actions) {
|
||||
for (const condition of conditions) {
|
||||
@@ -36,6 +39,7 @@ export default function PermissionSettings(props) {
|
||||
}
|
||||
onClose();
|
||||
};
|
||||
|
||||
const apply = () => {
|
||||
for (const action of actions) {
|
||||
for (const condition of conditions) {
|
||||
@@ -46,6 +50,7 @@ export default function PermissionSettings(props) {
|
||||
}
|
||||
onClose();
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
@@ -133,3 +138,26 @@ export default function PermissionSettings(props) {
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
PermissionSettings.propTypes = {
|
||||
onClose: PropTypes.func.isRequired,
|
||||
fieldPrefix: PropTypes.string.isRequired,
|
||||
subject: PropTypes.string.isRequired,
|
||||
open: PropTypes.bool,
|
||||
defaultChecked: PropTypes.bool,
|
||||
actions: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
label: PropTypes.string,
|
||||
key: PropTypes.string,
|
||||
subjects: PropTypes.arrayOf(PropTypes.string),
|
||||
}),
|
||||
).isRequired,
|
||||
conditions: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
label: PropTypes.string,
|
||||
key: PropTypes.string,
|
||||
}),
|
||||
).isRequired,
|
||||
};
|
||||
|
||||
export default PermissionSettings;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import SettingsIcon from '@mui/icons-material/Settings';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import Paper from '@mui/material/Paper';
|
||||
@@ -110,4 +111,10 @@ const PermissionCatalogField = ({
|
||||
</TableContainer>
|
||||
);
|
||||
};
|
||||
PermissionCatalogField.propTypes = {
|
||||
name: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
defaultChecked: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default PermissionCatalogField;
|
||||
|
@@ -1,7 +1,9 @@
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
const Portal = ({ children }) => {
|
||||
return typeof document === 'object'
|
||||
? ReactDOM.createPortal(children, document.body)
|
||||
: null;
|
||||
};
|
||||
|
||||
export default Portal;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import Paper from '@mui/material/Paper';
|
||||
import MuiPopper from '@mui/material/Popper';
|
||||
import Tab from '@mui/material/Tab';
|
||||
@@ -5,8 +6,10 @@ import * as React from 'react';
|
||||
import Suggestions from 'components/PowerInput/Suggestions';
|
||||
import TabPanel from 'components/TabPanel';
|
||||
import { Tabs } from './style';
|
||||
|
||||
const Popper = (props) => {
|
||||
const { open, anchorEl, data, onSuggestionClick } = props;
|
||||
|
||||
return (
|
||||
<MuiPopper
|
||||
open={open}
|
||||
@@ -34,4 +37,15 @@ const Popper = (props) => {
|
||||
</MuiPopper>
|
||||
);
|
||||
};
|
||||
|
||||
Popper.propTypes = {
|
||||
open: PropTypes.bool.isRequired,
|
||||
anchorEl: PropTypes.oneOfType([
|
||||
PropTypes.func,
|
||||
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
||||
]),
|
||||
data: PropTypes.array.isRequired,
|
||||
onSuggestionClick: PropTypes.func,
|
||||
};
|
||||
|
||||
export default Popper;
|
||||
|
49
packages/web/src/components/PowerInput/SuggestionItem.jsx
Normal file
49
packages/web/src/components/PowerInput/SuggestionItem.jsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import ListItemButton from '@mui/material/ListItemButton';
|
||||
import ListItemText from '@mui/material/ListItemText';
|
||||
|
||||
const SuggestionItem = (props) => {
|
||||
const { index, style, data, onSuggestionClick } = props;
|
||||
const suboption = data[index];
|
||||
return (
|
||||
<ListItemButton
|
||||
sx={{ pl: 4 }}
|
||||
divider
|
||||
onClick={() => onSuggestionClick(suboption)}
|
||||
data-test="power-input-suggestion-item"
|
||||
key={index}
|
||||
style={style}
|
||||
>
|
||||
<ListItemText
|
||||
primary={suboption.label}
|
||||
primaryTypographyProps={{
|
||||
variant: 'subtitle1',
|
||||
title: 'Property name',
|
||||
sx: { fontWeight: 700 },
|
||||
}}
|
||||
secondary={suboption.sampleValue || ''}
|
||||
secondaryTypographyProps={{
|
||||
variant: 'subtitle2',
|
||||
title: 'Sample value',
|
||||
noWrap: true,
|
||||
}}
|
||||
/>
|
||||
</ListItemButton>
|
||||
);
|
||||
};
|
||||
|
||||
SuggestionItem.propTypes = {
|
||||
index: PropTypes.number.isRequired,
|
||||
style: PropTypes.object,
|
||||
data: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
label: PropTypes.string,
|
||||
sampleValue: PropTypes.string,
|
||||
}),
|
||||
).isRequired,
|
||||
onSuggestionClick: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default SuggestionItem;
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import ExpandLess from '@mui/icons-material/ExpandLess';
|
||||
import ExpandMore from '@mui/icons-material/ExpandMore';
|
||||
import Box from '@mui/material/Box';
|
||||
@@ -13,52 +14,33 @@ import * as React from 'react';
|
||||
import { FixedSizeList } from 'react-window';
|
||||
import SearchInput from 'components/SearchInput';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
import SuggestionItem from './SuggestionItem';
|
||||
|
||||
const SHORT_LIST_LENGTH = 4;
|
||||
const LIST_ITEM_HEIGHT = 64;
|
||||
|
||||
const computeListHeight = (currentLength) => {
|
||||
const numberOfRenderedItems = Math.min(SHORT_LIST_LENGTH, currentLength);
|
||||
return LIST_ITEM_HEIGHT * numberOfRenderedItems;
|
||||
};
|
||||
|
||||
const getPartialArray = (array, length = array.length) => {
|
||||
return array.slice(0, length);
|
||||
};
|
||||
|
||||
const renderItemFactory =
|
||||
({ onSuggestionClick }) =>
|
||||
(props) => {
|
||||
const { index, style, data } = props;
|
||||
const suboption = data[index];
|
||||
return (
|
||||
<ListItemButton
|
||||
sx={{ pl: 4 }}
|
||||
divider
|
||||
onClick={() => onSuggestionClick(suboption)}
|
||||
data-test="power-input-suggestion-item"
|
||||
key={index}
|
||||
style={style}
|
||||
>
|
||||
<ListItemText
|
||||
primary={suboption.label}
|
||||
primaryTypographyProps={{
|
||||
variant: 'subtitle1',
|
||||
title: 'Property name',
|
||||
sx: { fontWeight: 700 },
|
||||
}}
|
||||
secondary={suboption.sampleValue || ''}
|
||||
secondaryTypographyProps={{
|
||||
variant: 'subtitle2',
|
||||
title: 'Sample value',
|
||||
noWrap: true,
|
||||
}}
|
||||
/>
|
||||
</ListItemButton>
|
||||
(props) => (
|
||||
<SuggestionItem {...props} onSuggestionClick={onSuggestionClick} />
|
||||
);
|
||||
};
|
||||
|
||||
const Suggestions = (props) => {
|
||||
const formatMessage = useFormatMessage();
|
||||
const { data, onSuggestionClick = () => null } = props;
|
||||
const [current, setCurrent] = React.useState(0);
|
||||
const [listLength, setListLength] = React.useState(SHORT_LIST_LENGTH);
|
||||
const [filteredData, setFilteredData] = React.useState(data);
|
||||
|
||||
React.useEffect(
|
||||
function syncOptions() {
|
||||
setFilteredData((filteredData) => {
|
||||
@@ -70,6 +52,7 @@ const Suggestions = (props) => {
|
||||
},
|
||||
[data],
|
||||
);
|
||||
|
||||
const renderItem = React.useMemo(
|
||||
() =>
|
||||
renderItemFactory({
|
||||
@@ -77,15 +60,19 @@ const Suggestions = (props) => {
|
||||
}),
|
||||
[onSuggestionClick],
|
||||
);
|
||||
|
||||
const expandList = () => {
|
||||
setListLength(Infinity);
|
||||
};
|
||||
|
||||
const collapseList = () => {
|
||||
setListLength(SHORT_LIST_LENGTH);
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
setListLength(SHORT_LIST_LENGTH);
|
||||
}, [current]);
|
||||
|
||||
const onSearchChange = React.useMemo(
|
||||
() =>
|
||||
throttle((event) => {
|
||||
@@ -111,6 +98,7 @@ const Suggestions = (props) => {
|
||||
}, 400),
|
||||
[data],
|
||||
);
|
||||
|
||||
return (
|
||||
<Paper elevation={0} sx={{ width: '100%' }}>
|
||||
<Box px={2} pb={2}>
|
||||
@@ -182,4 +170,16 @@ const Suggestions = (props) => {
|
||||
</Paper>
|
||||
);
|
||||
};
|
||||
|
||||
Suggestions.propTypes = {
|
||||
data: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
output: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
}),
|
||||
).isRequired,
|
||||
onSuggestionClick: PropTypes.func,
|
||||
};
|
||||
|
||||
export default Suggestions;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
const joinBy = (delimiter = '.', ...args) =>
|
||||
args.filter(Boolean).join(delimiter);
|
||||
|
||||
const process = ({ data, parentKey, index, parentLabel = '' }) => {
|
||||
if (typeof data !== 'object') {
|
||||
return [
|
||||
@@ -10,10 +11,13 @@ const process = ({ data, parentKey, index, parentLabel = '' }) => {
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const entries = Object.entries(data);
|
||||
|
||||
return entries.flatMap(([name, sampleValue]) => {
|
||||
const label = joinBy('.', parentLabel, index?.toString(), name);
|
||||
const value = joinBy('.', parentKey, index?.toString(), name);
|
||||
|
||||
if (Array.isArray(sampleValue)) {
|
||||
return sampleValue.flatMap((item, index) =>
|
||||
process({
|
||||
@@ -21,9 +25,10 @@ const process = ({ data, parentKey, index, parentLabel = '' }) => {
|
||||
parentKey: value,
|
||||
index,
|
||||
parentLabel: label,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof sampleValue === 'object' && sampleValue !== null) {
|
||||
return process({
|
||||
data: sampleValue,
|
||||
@@ -40,8 +45,10 @@ const process = ({ data, parentKey, index, parentLabel = '' }) => {
|
||||
];
|
||||
});
|
||||
};
|
||||
|
||||
export const processStepWithExecutions = (steps) => {
|
||||
if (!steps) return [];
|
||||
|
||||
return steps
|
||||
.filter((step) => {
|
||||
const hasExecutionSteps = !!step.executionSteps?.length;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import ClickAwayListener from '@mui/base/ClickAwayListener';
|
||||
import FormHelperText from '@mui/material/FormHelperText';
|
||||
import InputLabel from '@mui/material/InputLabel';
|
||||
@@ -147,4 +148,21 @@ const PowerInput = (props) => {
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
PowerInput.propTypes = {
|
||||
onChange: PropTypes.func,
|
||||
onBlur: PropTypes.func,
|
||||
defaultValue: PropTypes.string,
|
||||
name: PropTypes.string.isRequired,
|
||||
label: PropTypes.string,
|
||||
type: PropTypes.string,
|
||||
required: PropTypes.bool,
|
||||
readOnly: PropTypes.bool,
|
||||
description: PropTypes.string,
|
||||
docUrl: PropTypes.string,
|
||||
clickToCopy: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
shouldUnregister: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default PowerInput;
|
||||
|
@@ -12,6 +12,7 @@ import TextField from 'components/TextField';
|
||||
import * as URLS from 'config/urls';
|
||||
import { RESET_PASSWORD } from 'graphql/mutations/reset-password.ee';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
|
||||
const validationSchema = yup.object().shape({
|
||||
password: yup.string().required('resetPasswordForm.mandatoryInput'),
|
||||
confirmPassword: yup
|
||||
@@ -19,6 +20,7 @@ const validationSchema = yup.object().shape({
|
||||
.required('resetPasswordForm.mandatoryInput')
|
||||
.oneOf([yup.ref('password')], 'resetPasswordForm.passwordsMustMatch'),
|
||||
});
|
||||
|
||||
export default function ResetPasswordForm() {
|
||||
const enqueueSnackbar = useEnqueueSnackbar();
|
||||
const formatMessage = useFormatMessage();
|
||||
@@ -26,6 +28,7 @@ export default function ResetPasswordForm() {
|
||||
const [searchParams] = useSearchParams();
|
||||
const [resetPassword, { data, loading }] = useMutation(RESET_PASSWORD);
|
||||
const token = searchParams.get('token');
|
||||
|
||||
const handleSubmit = async (values) => {
|
||||
await resetPassword({
|
||||
variables: {
|
||||
@@ -43,6 +46,7 @@ export default function ResetPasswordForm() {
|
||||
});
|
||||
navigate(URLS.LOGIN);
|
||||
};
|
||||
|
||||
return (
|
||||
<Paper sx={{ px: 2, py: 4 }}>
|
||||
<Typography
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import * as React from 'react';
|
||||
import InputLabel from '@mui/material/InputLabel';
|
||||
import OutlinedInput from '@mui/material/OutlinedInput';
|
||||
@@ -5,6 +6,7 @@ import InputAdornment from '@mui/material/InputAdornment';
|
||||
import FormControl from '@mui/material/FormControl';
|
||||
import SearchIcon from '@mui/icons-material/Search';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
|
||||
export default function SearchInput({ onChange }) {
|
||||
const formatMessage = useFormatMessage();
|
||||
return (
|
||||
@@ -29,3 +31,7 @@ export default function SearchInput({ onChange }) {
|
||||
</FormControl>
|
||||
);
|
||||
}
|
||||
|
||||
SearchInput.propTypes = {
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import * as React from 'react';
|
||||
import throttle from 'lodash/throttle';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
@@ -6,9 +7,11 @@ import JSONViewer from 'components/JSONViewer';
|
||||
import SearchInput from 'components/SearchInput';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
import filterObject from 'helpers/filterObject';
|
||||
|
||||
const SearchableJSONViewer = ({ data }) => {
|
||||
const [filteredData, setFilteredData] = React.useState(data);
|
||||
const formatMessage = useFormatMessage();
|
||||
|
||||
const onSearchChange = React.useMemo(
|
||||
() =>
|
||||
throttle((event) => {
|
||||
@@ -26,6 +29,7 @@ const SearchableJSONViewer = ({ data }) => {
|
||||
}, 400),
|
||||
[data],
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box my={2}>
|
||||
@@ -38,4 +42,9 @@ const SearchableJSONViewer = ({ data }) => {
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
SearchableJSONViewer.propTypes = {
|
||||
data: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default SearchableJSONViewer;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import * as React from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import Toolbar from '@mui/material/Toolbar';
|
||||
@@ -11,6 +12,7 @@ import useAutomatischInfo from 'hooks/useAutomatischInfo';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
import AppBar from 'components/AppBar';
|
||||
import Drawer from 'components/Drawer';
|
||||
|
||||
function createDrawerLinks({ isCloud }) {
|
||||
const items = [
|
||||
{
|
||||
@@ -28,7 +30,8 @@ function createDrawerLinks({ isCloud }) {
|
||||
}
|
||||
return items;
|
||||
}
|
||||
export default function SettingsLayout({ children }) {
|
||||
|
||||
function SettingsLayout({ children }) {
|
||||
const { data: automatischInfo } = useAutomatischInfo();
|
||||
const isCloud = automatischInfo?.data.isCloud;
|
||||
const theme = useTheme();
|
||||
@@ -45,6 +48,7 @@ export default function SettingsLayout({ children }) {
|
||||
to: '/',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<AppBar
|
||||
@@ -71,3 +75,9 @@ export default function SettingsLayout({ children }) {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
SettingsLayout.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
export default SettingsLayout;
|
||||
|
@@ -1,6 +1,9 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import Variable from './Variable';
|
||||
|
||||
export default function Element(props) {
|
||||
const { attributes, children, element, disabled } = props;
|
||||
|
||||
switch (element.type) {
|
||||
case 'variable':
|
||||
return <Variable {...props} disabled={disabled} />;
|
||||
@@ -8,3 +11,12 @@ export default function Element(props) {
|
||||
return <p {...attributes}>{children}</p>;
|
||||
}
|
||||
}
|
||||
|
||||
Element.propTypes = {
|
||||
attributes: PropTypes.object.isRequired,
|
||||
children: PropTypes.node.isRequired,
|
||||
element: PropTypes.shape({
|
||||
type: PropTypes.string,
|
||||
}),
|
||||
disabled: PropTypes.bool,
|
||||
};
|
||||
|
@@ -1,6 +1,8 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import Chip from '@mui/material/Chip';
|
||||
import { useSelected, useFocused } from 'slate-react';
|
||||
export default function Variable({ attributes, children, element, disabled }) {
|
||||
|
||||
function Variable({ attributes, children, element, disabled }) {
|
||||
const selected = useSelected();
|
||||
const focused = useFocused();
|
||||
const label = (
|
||||
@@ -24,3 +26,15 @@ export default function Variable({ attributes, children, element, disabled }) {
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Variable.propTypes = {
|
||||
attributes: PropTypes.object.isRequired,
|
||||
children: PropTypes.node.isRequired,
|
||||
element: PropTypes.shape({
|
||||
name: PropTypes.string.isRequired,
|
||||
sampleValue: PropTypes.string.isRequired,
|
||||
}),
|
||||
disabled: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default Variable;
|
||||
|
@@ -1,2 +1,3 @@
|
||||
import { Slate } from 'slate-react';
|
||||
|
||||
export default Slate;
|
||||
|
@@ -1,39 +1,45 @@
|
||||
import { Text } from 'slate';
|
||||
import { withHistory } from 'slate-history';
|
||||
import { ReactEditor, withReact } from 'slate-react';
|
||||
|
||||
function isCustomText(value) {
|
||||
const isText = Text.isText(value);
|
||||
const hasValueProperty = 'value' in value;
|
||||
if (isText && hasValueProperty) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function getStepPosition(id, stepsWithVariables) {
|
||||
const stepIndex = stepsWithVariables.findIndex((stepWithVariables) => {
|
||||
return stepWithVariables.id === id;
|
||||
});
|
||||
return stepIndex + 1;
|
||||
}
|
||||
|
||||
function getVariableName(variable) {
|
||||
return variable.replace(/{{|}}/g, '');
|
||||
}
|
||||
|
||||
function getVariableStepId(variable) {
|
||||
const nameWithoutCurlies = getVariableName(variable);
|
||||
const stepId = nameWithoutCurlies.match(stepIdRegExp)?.[1] || '';
|
||||
return stepId;
|
||||
}
|
||||
|
||||
function getVariableSampleValue(variable, stepsWithVariables) {
|
||||
const variableStepId = getVariableStepId(variable);
|
||||
const stepWithVariables = stepsWithVariables.find(
|
||||
({ id }) => id === variableStepId
|
||||
({ id }) => id === variableStepId,
|
||||
);
|
||||
if (!stepWithVariables) return null;
|
||||
const variableName = getVariableName(variable);
|
||||
const variableData = stepWithVariables.output.find(
|
||||
({ value }) => variableName === value
|
||||
({ value }) => variableName === value,
|
||||
);
|
||||
if (!variableData) return null;
|
||||
return variableData.sampleValue;
|
||||
}
|
||||
|
||||
function getVariableDetails(variable, stepsWithVariables) {
|
||||
const variableName = getVariableName(variable);
|
||||
const stepId = getVariableStepId(variableName);
|
||||
@@ -45,12 +51,15 @@ function getVariableDetails(variable, stepsWithVariables) {
|
||||
label,
|
||||
};
|
||||
}
|
||||
|
||||
const variableRegExp = /({{.*?}})/;
|
||||
const stepIdRegExp = /^step.([\da-zA-Z-]*)/;
|
||||
|
||||
export const deserialize = (value, options, stepsWithVariables) => {
|
||||
const selectedNativeOption = options?.find(
|
||||
(option) => value === option.value
|
||||
(option) => value === option.value,
|
||||
);
|
||||
|
||||
if (selectedNativeOption) {
|
||||
return [
|
||||
{
|
||||
@@ -60,6 +69,7 @@ export const deserialize = (value, options, stepsWithVariables) => {
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
if (value === null || value === undefined || value === '')
|
||||
return [
|
||||
{
|
||||
@@ -67,6 +77,7 @@ export const deserialize = (value, options, stepsWithVariables) => {
|
||||
children: [{ text: '' }],
|
||||
},
|
||||
];
|
||||
|
||||
return value
|
||||
.toString()
|
||||
.split('\n')
|
||||
@@ -79,7 +90,7 @@ export const deserialize = (value, options, stepsWithVariables) => {
|
||||
if (node.match(variableRegExp)) {
|
||||
const variableDetails = getVariableDetails(
|
||||
node,
|
||||
stepsWithVariables
|
||||
stepsWithVariables,
|
||||
);
|
||||
return {
|
||||
type: 'variable',
|
||||
@@ -101,6 +112,7 @@ export const deserialize = (value, options, stepsWithVariables) => {
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export const serialize = (value) => {
|
||||
const serializedNodes = value.map((node) => serializeNode(node));
|
||||
const hasSingleNode = value.length === 1;
|
||||
@@ -114,6 +126,7 @@ export const serialize = (value) => {
|
||||
const serializedValue = serializedNodes.join('\n');
|
||||
return serializedValue;
|
||||
};
|
||||
|
||||
const serializeNode = (node) => {
|
||||
if (isCustomText(node)) {
|
||||
return node.value;
|
||||
@@ -134,6 +147,7 @@ const serializeNode = (node) => {
|
||||
}
|
||||
return node.children.map((n) => serializeNode(n)).join('');
|
||||
};
|
||||
|
||||
export const withVariables = (editor) => {
|
||||
const { isInline, isVoid } = editor;
|
||||
editor.isInline = (element) => {
|
||||
@@ -144,10 +158,11 @@ export const withVariables = (editor) => {
|
||||
};
|
||||
return editor;
|
||||
};
|
||||
|
||||
export const insertVariable = (editor, variableData, stepsWithVariables) => {
|
||||
const variableDetails = getVariableDetails(
|
||||
`{{${variableData.value}}}`,
|
||||
stepsWithVariables
|
||||
stepsWithVariables,
|
||||
);
|
||||
const variable = {
|
||||
type: 'variable',
|
||||
@@ -159,10 +174,12 @@ export const insertVariable = (editor, variableData, stepsWithVariables) => {
|
||||
editor.insertNodes(variable, { select: false });
|
||||
focusEditor(editor);
|
||||
};
|
||||
|
||||
export const focusEditor = (editor) => {
|
||||
ReactEditor.focus(editor);
|
||||
editor.move();
|
||||
};
|
||||
|
||||
export const resetEditor = (editor, options) => {
|
||||
const focus = options?.focus || false;
|
||||
editor.removeNodes({
|
||||
@@ -177,6 +194,7 @@ export const resetEditor = (editor, options) => {
|
||||
focusEditor(editor);
|
||||
}
|
||||
};
|
||||
|
||||
export const overrideEditorValue = (editor, options) => {
|
||||
const { option, focus } = options;
|
||||
const variable = {
|
||||
@@ -201,6 +219,7 @@ export const overrideEditorValue = (editor, options) => {
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const createTextNode = (text) => ({
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
@@ -209,6 +228,7 @@ export const createTextNode = (text) => ({
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export const customizeEditor = (editor) => {
|
||||
return withVariables(withReact(withHistory(editor)));
|
||||
};
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { SnackbarProvider as BaseSnackbarProvider } from 'notistack';
|
||||
|
||||
const SnackbarProvider = (props) => {
|
||||
return (
|
||||
<BaseSnackbarProvider
|
||||
@@ -12,4 +13,5 @@ const SnackbarProvider = (props) => {
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default SnackbarProvider;
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import * as React from 'react';
|
||||
import { Controller, useFormContext } from 'react-hook-form';
|
||||
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||
import MuiSwitch from '@mui/material/Switch';
|
||||
export default function Switch(props) {
|
||||
|
||||
function Switch(props) {
|
||||
const { control } = useFormContext();
|
||||
const inputRef = React.useRef(null);
|
||||
const {
|
||||
@@ -18,6 +20,7 @@ export default function Switch(props) {
|
||||
className,
|
||||
...switchProps
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Controller
|
||||
rules={{ required }}
|
||||
@@ -63,3 +66,18 @@ export default function Switch(props) {
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Switch.propTypes = {
|
||||
required: PropTypes.bool,
|
||||
name: PropTypes.string.isRequired,
|
||||
defaultChecked: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
label: PropTypes.string.isRequired,
|
||||
shouldUnregister: PropTypes.bool,
|
||||
onBlur: PropTypes.func,
|
||||
onChange: PropTypes.func,
|
||||
FormControlLabelProps: PropTypes.object,
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Switch;
|
||||
|
@@ -1,4 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export default function TabPanel(props) {
|
||||
const { children, value, index, ...other } = props;
|
||||
return (
|
||||
@@ -7,3 +9,9 @@ export default function TabPanel(props) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
TabPanel.propTypes = {
|
||||
children: PropTypes.element.isRequired,
|
||||
value: PropTypes.number.isRequired,
|
||||
index: PropTypes.number.isRequired,
|
||||
};
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import * as React from 'react';
|
||||
import { useMutation } from '@apollo/client';
|
||||
import Box from '@mui/material/Box';
|
||||
@@ -14,6 +15,7 @@ import JSONViewer from 'components/JSONViewer';
|
||||
import WebhookUrlInfo from 'components/WebhookUrlInfo';
|
||||
import FlowSubstepTitle from 'components/FlowSubstepTitle';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { StepPropType, SubstepPropType } from 'propTypes/propTypes';
|
||||
|
||||
function serializeErrors(graphQLErrors) {
|
||||
return graphQLErrors?.map((error) => {
|
||||
@@ -154,4 +156,18 @@ function TestSubstep(props) {
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
TestSubstep.propTypes = {
|
||||
substep: SubstepPropType.isRequired,
|
||||
expanded: PropTypes.bool,
|
||||
showWebhookUrl: PropTypes.bool,
|
||||
onExpand: PropTypes.func.isRequired,
|
||||
onCollapse: PropTypes.func.isRequired,
|
||||
onChange: PropTypes.func,
|
||||
onSubmit: PropTypes.func,
|
||||
onContinue: PropTypes.func,
|
||||
step: StepPropType.isRequired,
|
||||
flowId: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default TestSubstep;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import * as React from 'react';
|
||||
import { Controller, useFormContext } from 'react-hook-form';
|
||||
import MuiTextField from '@mui/material/TextField';
|
||||
@@ -5,6 +6,7 @@ import IconButton from '@mui/material/IconButton';
|
||||
import InputAdornment from '@mui/material/InputAdornment';
|
||||
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
||||
import copyInputValue from 'helpers/copyInputValue';
|
||||
|
||||
const createCopyAdornment = (ref) => {
|
||||
return (
|
||||
<InputAdornment position="end">
|
||||
@@ -14,7 +16,8 @@ const createCopyAdornment = (ref) => {
|
||||
</InputAdornment>
|
||||
);
|
||||
};
|
||||
export default function TextField(props) {
|
||||
|
||||
function TextField(props) {
|
||||
const { control } = useFormContext();
|
||||
const inputRef = React.useRef(null);
|
||||
const {
|
||||
@@ -74,3 +77,18 @@ export default function TextField(props) {
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
TextField.propTypes = {
|
||||
required: PropTypes.bool,
|
||||
defaultValue: PropTypes.string,
|
||||
shouldUnregister: PropTypes.bool,
|
||||
name: PropTypes.string.isRequired,
|
||||
clickToCopy: PropTypes.bool,
|
||||
readOnly: PropTypes.bool,
|
||||
'data-test': PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
onBlur: PropTypes.func,
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
export default TextField;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import CssBaseline from '@mui/material/CssBaseline';
|
||||
import { ThemeProvider as BaseThemeProvider } from '@mui/material/styles';
|
||||
import clone from 'lodash/clone';
|
||||
@@ -24,6 +25,7 @@ const customizeTheme = (theme, config) => {
|
||||
|
||||
return shallowDefaultTheme;
|
||||
};
|
||||
|
||||
const ThemeProvider = ({ children, ...props }) => {
|
||||
const { data: automatischInfo, isPending: isAutomatischInfoPending } =
|
||||
useAutomatischInfo();
|
||||
@@ -53,4 +55,8 @@ const ThemeProvider = ({ children, ...props }) => {
|
||||
);
|
||||
};
|
||||
|
||||
ThemeProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
export default ThemeProvider;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { styled } from '@mui/material/styles';
|
||||
import MuiChip, { chipClasses } from '@mui/material/Chip';
|
||||
|
||||
export const Chip = styled(MuiChip)`
|
||||
&.${chipClasses.root} {
|
||||
font-weight: 500;
|
||||
|
@@ -10,6 +10,7 @@ import CardContent from '@mui/material/CardContent';
|
||||
import Divider from '@mui/material/Divider';
|
||||
import Grid from '@mui/material/Grid';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import TrialOverAlert from 'components/TrialOverAlert/index.ee';
|
||||
import SubscriptionCancelledAlert from 'components/SubscriptionCancelledAlert/index.ee';
|
||||
@@ -54,6 +55,13 @@ function BillingCard(props) {
|
||||
);
|
||||
}
|
||||
|
||||
BillingCard.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
title: PropTypes.string,
|
||||
action: PropTypes.string,
|
||||
text: PropTypes.string,
|
||||
};
|
||||
|
||||
function Action(props) {
|
||||
const { action, text } = props;
|
||||
|
||||
@@ -80,6 +88,11 @@ function Action(props) {
|
||||
);
|
||||
}
|
||||
|
||||
Action.propTypes = {
|
||||
action: PropTypes.string,
|
||||
text: PropTypes.string,
|
||||
};
|
||||
|
||||
export default function UsageDataInformation() {
|
||||
const formatMessage = useFormatMessage();
|
||||
const queryClient = useQueryClient();
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTheme } from '@mui/material';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import FirstPageIcon from '@mui/icons-material/FirstPage';
|
||||
@@ -5,21 +6,27 @@ import KeyboardArrowLeft from '@mui/icons-material/KeyboardArrowLeft';
|
||||
import KeyboardArrowRight from '@mui/icons-material/KeyboardArrowRight';
|
||||
import LastPageIcon from '@mui/icons-material/LastPage';
|
||||
import Box from '@mui/material/Box';
|
||||
export default function TablePaginationActions(props) {
|
||||
|
||||
function TablePaginationActions(props) {
|
||||
const theme = useTheme();
|
||||
const { count, page, rowsPerPage, onPageChange } = props;
|
||||
|
||||
const handleFirstPageButtonClick = (event) => {
|
||||
onPageChange(event, 0);
|
||||
};
|
||||
|
||||
const handleBackButtonClick = (event) => {
|
||||
onPageChange(event, page - 1);
|
||||
};
|
||||
|
||||
const handleNextButtonClick = (event) => {
|
||||
onPageChange(event, page + 1);
|
||||
};
|
||||
|
||||
const handleLastPageButtonClick = (event) => {
|
||||
onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1));
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{ flexShrink: 0, ml: 2.5 }}>
|
||||
<IconButton
|
||||
@@ -65,3 +72,12 @@ export default function TablePaginationActions(props) {
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
TablePaginationActions.propTypes = {
|
||||
count: PropTypes.number.isRequired,
|
||||
page: PropTypes.number.isRequired,
|
||||
rowsPerPage: PropTypes.number.isRequired,
|
||||
onPageChange: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default TablePaginationActions;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import * as React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import Typography from '@mui/material/Typography';
|
||||
@@ -5,6 +6,7 @@ import { generateExternalLink } from '../../helpers/translationValues';
|
||||
import { WEBHOOK_DOCS } from '../../config/urls';
|
||||
import TextField from '../TextField';
|
||||
import { Alert } from './style';
|
||||
|
||||
function WebhookUrlInfo(props) {
|
||||
const { webhookUrl, ...alertProps } = props;
|
||||
return (
|
||||
@@ -33,4 +35,8 @@ function WebhookUrlInfo(props) {
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
|
||||
WebhookUrlInfo.propTypes = {
|
||||
webhookUrl: PropTypes.string.isRequired,
|
||||
};
|
||||
export default WebhookUrlInfo;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import * as React from 'react';
|
||||
import { getItem, removeItem, setItem } from 'helpers/storage';
|
||||
import api from 'helpers/api.js';
|
||||
@@ -36,3 +37,7 @@ export const AuthenticationProvider = (props) => {
|
||||
</AuthenticationContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
AuthenticationProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
@@ -1,10 +1,18 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export const EditorContext = React.createContext({
|
||||
readOnly: false,
|
||||
});
|
||||
|
||||
export const EditorProvider = (props) => {
|
||||
const { children, value } = props;
|
||||
return (
|
||||
<EditorContext.Provider value={value}>{children}</EditorContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
EditorProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
value: PropTypes.shape({ readOnly: PropTypes.bool.isRequired }).isRequired,
|
||||
};
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import * as React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
@@ -100,3 +101,7 @@ export const PaddleProvider = (props) => {
|
||||
<PaddleContext.Provider value={value}>{children}</PaddleContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
PaddleProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
@@ -1,5 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { StepPropType } from 'propTypes/propTypes';
|
||||
|
||||
export const StepExecutionsContext = React.createContext([]);
|
||||
|
||||
export const StepExecutionsProvider = (props) => {
|
||||
const { children, value } = props;
|
||||
return (
|
||||
@@ -8,3 +12,8 @@ export const StepExecutionsProvider = (props) => {
|
||||
</StepExecutionsContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
StepExecutionsProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
value: PropTypes.arrayOf(StepPropType),
|
||||
};
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import * as React from 'react';
|
||||
import {
|
||||
Link,
|
||||
@@ -31,6 +32,7 @@ import Container from 'components/Container';
|
||||
import PageTitle from 'components/PageTitle';
|
||||
import useApp from 'hooks/useApp';
|
||||
import Can from 'components/Can';
|
||||
import { AppPropType } from 'propTypes/propTypes';
|
||||
|
||||
const ReconnectConnection = (props) => {
|
||||
const { application, onClose } = props;
|
||||
@@ -45,6 +47,11 @@ const ReconnectConnection = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
ReconnectConnection.propTypes = {
|
||||
application: AppPropType.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default function Application() {
|
||||
const theme = useTheme();
|
||||
const matchSmallScreens = useMediaQuery(theme.breakpoints.down('md'));
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { useMutation } from '@apollo/client';
|
||||
import LoadingButton from '@mui/lab/LoadingButton';
|
||||
import Divider from '@mui/material/Divider';
|
||||
@@ -105,4 +106,12 @@ function RoleMappings({ provider, providerLoading }) {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
RoleMappings.propTypes = {
|
||||
provider: PropTypes.shape({
|
||||
id: PropTypes.oneOf([PropTypes.number, PropTypes.string]).isRequired,
|
||||
}),
|
||||
providerLoading: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default RoleMappings;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { useMutation } from '@apollo/client';
|
||||
import LoadingButton from '@mui/lab/LoadingButton';
|
||||
import Stack from '@mui/material/Stack';
|
||||
@@ -192,4 +193,22 @@ function SamlConfiguration({ provider, providerLoading }) {
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
||||
SamlConfiguration.propTypes = {
|
||||
provider: PropTypes.shape({
|
||||
active: PropTypes.bool,
|
||||
name: PropTypes.string,
|
||||
certificate: PropTypes.string,
|
||||
signatureAlgorithm: PropTypes.oneOf(['sha1', 'sha256', 'sha512']),
|
||||
issuer: PropTypes.string,
|
||||
entryPoint: PropTypes.string,
|
||||
firstnameAttributeName: PropTypes.string,
|
||||
surnameAttributeName: PropTypes.string,
|
||||
emailAttributeName: PropTypes.string,
|
||||
roleAttributeName: PropTypes.string,
|
||||
defaultRoleId: PropTypes.string,
|
||||
}),
|
||||
providerLoading: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default SamlConfiguration;
|
||||
|
Reference in New Issue
Block a user