chore: Use types from the web package

This commit is contained in:
Faruk AYDIN
2024-01-15 13:30:48 +01:00
parent 7831f2925b
commit 159931a6ea
77 changed files with 934 additions and 378 deletions

View File

@@ -1,4 +1,4 @@
import type { IApp, IField, IJSONObject } from '@automatisch/types';
import type { IApp, IField, IJSONObject } from 'types';
import LoadingButton from '@mui/lab/LoadingButton';
import Alert from '@mui/material/Alert';
import Dialog from '@mui/material/Dialog';

View File

@@ -19,7 +19,7 @@ import InputLabel from '@mui/material/InputLabel';
import OutlinedInput from '@mui/material/OutlinedInput';
import FormControl from '@mui/material/FormControl';
import Box from '@mui/material/Box';
import type { IApp } from '@automatisch/types';
import type { IApp } from 'types';
import * as URLS from 'config/urls';
import AppIcon from 'components/AppIcon';

View File

@@ -1,5 +1,5 @@
import React from 'react';
import type { IField } from '@automatisch/types';
import type { IField } from 'types';
import LoadingButton from '@mui/lab/LoadingButton';
import Alert from '@mui/material/Alert';
import Dialog from '@mui/material/Dialog';

View File

@@ -1,5 +1,5 @@
import React, { useCallback, useMemo } from 'react';
import type { IApp } from '@automatisch/types';
import type { IApp } from 'types';
import { FieldValues, SubmitHandler } from 'react-hook-form';
import { useMutation } from '@apollo/client';
import { CREATE_APP_CONFIG } from 'graphql/mutations/create-app-config';

View File

@@ -1,6 +1,6 @@
import React, { useCallback, useMemo } from 'react';
import { useParams } from 'react-router-dom';
import type { IApp } from '@automatisch/types';
import type { IApp } from 'types';
import { FieldValues, SubmitHandler } from 'react-hook-form';
import { useMutation } from '@apollo/client';
import { UPDATE_APP_AUTH_CLIENT } from 'graphql/mutations/update-app-auth-client';

View File

@@ -3,7 +3,7 @@ import { Link } from 'react-router-dom';
import Menu from '@mui/material/Menu';
import type { PopoverProps } from '@mui/material/Popover';
import MenuItem from '@mui/material/MenuItem';
import type { IConnection } from '@automatisch/types';
import type { IConnection } from 'types';
import * as URLS from 'config/urls';
import useFormatMessage from 'hooks/useFormatMessage';

View File

@@ -11,7 +11,7 @@ import useEnqueueSnackbar from 'hooks/useEnqueueSnackbar';
import { DateTime } from 'luxon';
import * as React from 'react';
import type { IConnection } from '@automatisch/types';
import type { IConnection } from 'types';
import ConnectionContextMenu from 'components/AppConnectionContextMenu';
import { DELETE_CONNECTION } from 'graphql/mutations/delete-connection';
import { TEST_CONNECTION } from 'graphql/queries/test-connection';
@@ -83,8 +83,8 @@ function AppConnectionRow(props: AppConnectionRowProps): React.ReactElement {
enqueueSnackbar(formatMessage('connection.deletedMessage'), {
variant: 'success',
SnackbarProps: {
'data-test': 'snackbar-delete-connection-success'
}
'data-test': 'snackbar-delete-connection-success',
},
});
} else if (action.type === 'test') {
setVerificationVisible(true);

View File

@@ -1,7 +1,7 @@
import * as React from 'react';
import { useQuery } from '@apollo/client';
import type { IConnection } from '@automatisch/types';
import type { IConnection } from 'types';
import { GET_APP_CONNECTIONS } from 'graphql/queries/get-app-connections';
import AppConnectionRow from 'components/AppConnectionRow';
import NoResultFound from 'components/NoResultFound';

View File

@@ -8,7 +8,7 @@ import * as URLS from 'config/urls';
import AppFlowRow from 'components/FlowRow';
import NoResultFound from 'components/NoResultFound';
import useFormatMessage from 'hooks/useFormatMessage';
import type { IFlow } from '@automatisch/types';
import type { IFlow } from 'types';
type AppFlowsProps = {
appKey: string;

View File

@@ -7,7 +7,7 @@ import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
import useFormatMessage from 'hooks/useFormatMessage';
import AppIcon from 'components/AppIcon';
import type { IApp } from '@automatisch/types';
import type { IApp } from 'types';
import { CardContent, Typography } from './style';

View File

@@ -7,13 +7,7 @@ import ListItem from '@mui/material/ListItem';
import TextField from '@mui/material/TextField';
import Autocomplete from '@mui/material/Autocomplete';
import Chip from '@mui/material/Chip';
import type {
IApp,
IStep,
ISubstep,
ITrigger,
IAction,
} from '@automatisch/types';
import type { IApp, IStep, ISubstep, ITrigger, IAction } from 'types';
import useFormatMessage from 'hooks/useFormatMessage';
import useApps from 'hooks/useApps';

View File

@@ -6,7 +6,7 @@ import ListItem from '@mui/material/ListItem';
import TextField from '@mui/material/TextField';
import * as React from 'react';
import type { IApp, IConnection, IStep, ISubstep } from '@automatisch/types';
import type { IApp, IConnection, IStep, ISubstep } from 'types';
import AddAppConnection from 'components/AddAppConnection';
import AppAuthClientsDialog from 'components/AppAuthClientsDialog/index.ee';
import FlowSubstepTitle from 'components/FlowSubstepTitle';

View File

@@ -1,9 +1,12 @@
import * as React from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import FormHelperText from '@mui/material/FormHelperText';
import Autocomplete, { AutocompleteProps, createFilterOptions } from '@mui/material/Autocomplete';
import Autocomplete, {
AutocompleteProps,
createFilterOptions,
} from '@mui/material/Autocomplete';
import Typography from '@mui/material/Typography';
import type { IFieldDropdownOption } from '@automatisch/types';
import type { IFieldDropdownOption } from 'types';
interface ControlledAutocompleteProps
extends AutocompleteProps<IFieldDropdownOption, boolean, boolean, boolean> {
@@ -23,8 +26,8 @@ const filterOptions = createFilterOptions<IFieldDropdownOption>({
stringify: ({ label, value }) => `
${label}
${value}
`
})
`,
});
function ControlledAutocomplete(
props: ControlledAutocompleteProps

View File

@@ -3,7 +3,7 @@ import Popper from '@mui/material/Popper';
import Tab from '@mui/material/Tab';
import * as React from 'react';
import type { IFieldDropdownOption } from '@automatisch/types';
import type { IFieldDropdownOption } from 'types';
import Suggestions from 'components/PowerInput/Suggestions';
import TabPanel from 'components/TabPanel';

View File

@@ -1,4 +1,4 @@
import type { IFieldDropdownOption } from '@automatisch/types';
import type { IFieldDropdownOption } from 'types';
import ListItemButton from '@mui/material/ListItemButton';
import ListItemText from '@mui/material/ListItemText';
import throttle from 'lodash/throttle';
@@ -13,7 +13,7 @@ import { SearchInputWrapper } from './style';
interface OptionsProps {
data: readonly IFieldDropdownOption[];
onOptionClick: (event: React.MouseEvent, option: any) => void;
};
}
const SHORT_LIST_LENGTH = 4;
const LIST_ITEM_HEIGHT = 64;
@@ -21,80 +21,89 @@ const LIST_ITEM_HEIGHT = 64;
const computeListHeight = (currentLength: number) => {
const numberOfRenderedItems = Math.min(SHORT_LIST_LENGTH, currentLength);
return LIST_ITEM_HEIGHT * numberOfRenderedItems;
}
const renderItemFactory = ({ onOptionClick }: Pick<OptionsProps, 'onOptionClick'>) => (props: ListChildComponentProps) => {
const { index, style, data } = props;
const suboption = data[index];
return (
<ListItemButton
sx={{ pl: 4 }}
divider
onClick={(event) => onOptionClick(event, 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.value}
secondaryTypographyProps={{
variant: 'subtitle2',
title: 'Sample value',
noWrap: true,
}}
/>
</ListItemButton>
);
};
const renderItemFactory =
({ onOptionClick }: Pick<OptionsProps, 'onOptionClick'>) =>
(props: ListChildComponentProps) => {
const { index, style, data } = props;
const suboption = data[index];
return (
<ListItemButton
sx={{ pl: 4 }}
divider
onClick={(event) => onOptionClick(event, 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.value}
secondaryTypographyProps={{
variant: 'subtitle2',
title: 'Sample value',
noWrap: true,
}}
/>
</ListItemButton>
);
};
const Options = (props: OptionsProps) => {
const formatMessage = useFormatMessage();
const {
data,
onOptionClick
} = props;
const [filteredData, setFilteredData] = React.useState<readonly IFieldDropdownOption[]>(
data
const { data, onOptionClick } = props;
const [filteredData, setFilteredData] =
React.useState<readonly IFieldDropdownOption[]>(data);
React.useEffect(
function syncOptions() {
setFilteredData((filteredData) => {
if (filteredData.length === 0 && filteredData.length !== data.length) {
return data;
}
return filteredData;
});
},
[data]
);
React.useEffect(function syncOptions() {
setFilteredData((filteredData) => {
if (filteredData.length === 0 && filteredData.length !== data.length) {
return data;
}
return filteredData;
})
}, [data]);
const renderItem = React.useMemo(() => renderItemFactory({
onOptionClick
}), [onOptionClick]);
const renderItem = React.useMemo(
() =>
renderItemFactory({
onOptionClick,
}),
[onOptionClick]
);
const onSearchChange = React.useMemo(
() =>
throttle((event: React.ChangeEvent) => {
const search = (event.target as HTMLInputElement).value.toLowerCase();
() =>
throttle((event: React.ChangeEvent) => {
const search = (event.target as HTMLInputElement).value.toLowerCase();
if (!search) {
setFilteredData(data);
return;
}
if (!search) {
setFilteredData(data);
return;
}
const newFilteredData = data.filter(option => `${option.label}\n${option.value}`.toLowerCase().includes(search.toLowerCase()));
const newFilteredData = data.filter((option) =>
`${option.label}\n${option.value}`
.toLowerCase()
.includes(search.toLowerCase())
);
setFilteredData(newFilteredData);
}, 400),
[data]
);
setFilteredData(newFilteredData);
}, 400),
[data]
);
return (
<>
@@ -122,5 +131,4 @@ const Options = (props: OptionsProps) => {
);
};
export default Options;

View File

@@ -5,7 +5,7 @@ import FormHelperText from '@mui/material/FormHelperText';
import { AutocompleteProps } from '@mui/material/Autocomplete';
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
import ClearIcon from '@mui/icons-material/Clear';
import type { IFieldDropdownOption } from '@automatisch/types';
import type { IFieldDropdownOption } from 'types';
import { ActionButtonsWrapper } from './style';
import ClickAwayListener from '@mui/base/ClickAwayListener';

View File

@@ -8,7 +8,7 @@ import IconButton from '@mui/material/IconButton';
import RemoveIcon from '@mui/icons-material/Remove';
import AddIcon from '@mui/icons-material/Add';
import { IFieldDynamic } from '@automatisch/types';
import { IFieldDynamic } from 'types';
import InputCreator from 'components/InputCreator';
import { EditorContext } from 'contexts/Editor';

View File

@@ -3,7 +3,7 @@ import { useMutation } from '@apollo/client';
import Box from '@mui/material/Box';
import IconButton from '@mui/material/IconButton';
import AddIcon from '@mui/icons-material/Add';
import type { IFlow, IStep } from '@automatisch/types';
import type { IFlow, IStep } from 'types';
import { GET_FLOW } from 'graphql/queries/get-flow';
import { CREATE_STEP } from 'graphql/mutations/create-step';

View File

@@ -17,7 +17,7 @@ import useFormatMessage from 'hooks/useFormatMessage';
import { UPDATE_FLOW_STATUS } from 'graphql/mutations/update-flow-status';
import { UPDATE_FLOW } from 'graphql/mutations/update-flow';
import { GET_FLOW } from 'graphql/queries/get-flow';
import type { IFlow } from '@automatisch/types';
import type { IFlow } from 'types';
import * as URLS from 'config/urls';
export default function EditorLayout(): React.ReactElement {

View File

@@ -4,7 +4,7 @@ import Stack from '@mui/material/Stack';
import Box from '@mui/material/Box';
import Tooltip from '@mui/material/Tooltip';
import Typography from '@mui/material/Typography';
import type { IExecution } from '@automatisch/types';
import type { IExecution } from 'types';
import useFormatMessage from 'hooks/useFormatMessage';

View File

@@ -5,7 +5,7 @@ import CardActionArea from '@mui/material/CardActionArea';
import Chip from '@mui/material/Chip';
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
import { DateTime } from 'luxon';
import type { IExecution } from '@automatisch/types';
import type { IExecution } from 'types';
import * as URLS from 'config/urls';
import useFormatMessage from 'hooks/useFormatMessage';

View File

@@ -8,7 +8,7 @@ import Tab from '@mui/material/Tab';
import Typography from '@mui/material/Typography';
import Tooltip from '@mui/material/Tooltip';
import Box from '@mui/material/Box';
import type { IApp, IExecutionStep, IStep } from '@automatisch/types';
import type { IApp, IExecutionStep, IStep } from 'types';
import TabPanel from 'components/TabPanel';
import SearchableJSONViewer from 'components/SearchableJSONViewer';

View File

@@ -1,5 +1,5 @@
import * as React from 'react';
import type { IStep } from '@automatisch/types';
import type { IStep } from 'types';
import AppIcon from 'components/AppIcon';
import IntermediateStepCount from 'components/IntermediateStepCount';

View File

@@ -7,7 +7,7 @@ import Chip from '@mui/material/Chip';
import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
import { DateTime } from 'luxon';
import type { IFlow } from '@automatisch/types';
import type { IFlow } from 'types';
import FlowAppIcons from 'components/FlowAppIcons';
import FlowContextMenu from 'components/FlowContextMenu';
import useFormatMessage from 'hooks/useFormatMessage';

View File

@@ -14,13 +14,7 @@ import CheckCircleIcon from '@mui/icons-material/CheckCircle';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';
import type { BaseSchema } from 'yup';
import type {
IApp,
ITrigger,
IAction,
IStep,
ISubstep,
} from '@automatisch/types';
import type { IApp, ITrigger, IAction, IStep, ISubstep } from 'types';
import { EditorContext } from 'contexts/Editor';
import { StepExecutionsProvider } from 'contexts/StepExecutions';

View File

@@ -8,7 +8,7 @@ import Divider from '@mui/material/Divider';
import IconButton from '@mui/material/IconButton';
import RemoveIcon from '@mui/icons-material/Remove';
import AddIcon from '@mui/icons-material/Add';
import type { IField, IFieldText, IFieldDropdown } from '@automatisch/types';
import type { IField, IFieldText, IFieldDropdown } from 'types';
import useFormatMessage from 'hooks/useFormatMessage';
import InputCreator from 'components/InputCreator';
@@ -19,7 +19,7 @@ type TGroupItem = {
operator: string;
value: string;
id: string;
}
};
type TGroup = Record<'and', TGroupItem[]>;
@@ -31,7 +31,7 @@ const createGroupItem = (): TGroupItem => ({
});
const createGroup = (): TGroup => ({
and: [createGroupItem()]
and: [createGroupItem()],
});
const operators = [
@@ -69,7 +69,9 @@ const operators = [
},
];
const createStringArgument = (argumentOptions: Omit<IFieldText, 'type' | 'required' | 'variables'>): IField => {
const createStringArgument = (
argumentOptions: Omit<IFieldText, 'type' | 'required' | 'variables'>
): IField => {
return {
...argumentOptions,
type: 'string',
@@ -78,7 +80,9 @@ const createStringArgument = (argumentOptions: Omit<IFieldText, 'type' | 'requir
};
};
const createDropdownArgument = (argumentOptions: Omit<IFieldDropdown, 'type' | 'required'>): IField => {
const createDropdownArgument = (
argumentOptions: Omit<IFieldDropdown, 'type' | 'required'>
): IField => {
return {
...argumentOptions,
required: true,
@@ -91,9 +95,7 @@ type FilterConditionsProps = {
};
function FilterConditions(props: FilterConditionsProps): React.ReactElement {
const {
stepId
} = props;
const { stepId } = props;
const formatMessage = useFormatMessage();
const { control, setValue, getValues } = useFormContext();
const groups = useWatch({ control, name: 'parameters.or' });
@@ -110,7 +112,7 @@ function FilterConditions(props: FilterConditionsProps): React.ReactElement {
const appendGroup = React.useCallback(() => {
const values = getValues('parameters.or');
setValue('parameters.or', values.concat(createGroup()))
setValue('parameters.or', values.concat(createGroup()));
}, []);
const appendGroupItem = React.useCallback((index) => {
@@ -124,65 +126,107 @@ function FilterConditions(props: FilterConditionsProps): React.ReactElement {
if (group.length === 1) {
const groups: TGroup[] = getValues('parameters.or');
setValue('parameters.or', groups.filter((group, index) => index !== groupIndex));
setValue(
'parameters.or',
groups.filter((group, index) => index !== groupIndex)
);
} else {
setValue(`parameters.or.${groupIndex}.and`, group.filter((groupItem, index) => index !== groupItemIndex));
setValue(
`parameters.or.${groupIndex}.and`,
group.filter((groupItem, index) => index !== groupItemIndex)
);
}
}, []);
return (
<React.Fragment>
<Stack sx={{ width: "100%" }} direction="column" spacing={2} mt={2}>
<Stack sx={{ width: '100%' }} direction="column" spacing={2} mt={2}>
{groups?.map((group: TGroup, groupIndex: number) => (
<>
{groupIndex !== 0 && <Divider />}
<Typography variant="subtitle2" gutterBottom>
{groupIndex === 0 && formatMessage('filterConditions.onlyContinueIf')}
{groupIndex !== 0 && formatMessage('filterConditions.orContinueIf')}
{groupIndex === 0 &&
formatMessage('filterConditions.onlyContinueIf')}
{groupIndex !== 0 &&
formatMessage('filterConditions.orContinueIf')}
</Typography>
{group?.and?.map((groupItem: TGroupItem, groupItemIndex: number) => (
<Stack direction="row" spacing={2} key={`item-${groupItem.id}`}>
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={{ xs: 2 }} sx={{ display: 'flex', flex: 1 }}>
<Box sx={{ display: 'flex', flex: '1 0 0px', maxWidth: ['100%', '33%'] }}>
<InputCreator
schema={createStringArgument({ key: `or.${groupIndex}.and.${groupItemIndex}.key`, label: 'Choose field' })}
namePrefix="parameters"
stepId={stepId}
disabled={editorContext.readOnly}
/>
</Box>
{group?.and?.map(
(groupItem: TGroupItem, groupItemIndex: number) => (
<Stack direction="row" spacing={2} key={`item-${groupItem.id}`}>
<Stack
direction={{ xs: 'column', sm: 'row' }}
spacing={{ xs: 2 }}
sx={{ display: 'flex', flex: 1 }}
>
<Box
sx={{
display: 'flex',
flex: '1 0 0px',
maxWidth: ['100%', '33%'],
}}
>
<InputCreator
schema={createStringArgument({
key: `or.${groupIndex}.and.${groupItemIndex}.key`,
label: 'Choose field',
})}
namePrefix="parameters"
stepId={stepId}
disabled={editorContext.readOnly}
/>
</Box>
<Box sx={{ display: 'flex', flex: '1 0 0px', maxWidth: ['100%', '33%'] }}>
<InputCreator
schema={createDropdownArgument({ key: `or.${groupIndex}.and.${groupItemIndex}.operator`, options: operators, label: 'Choose condition' })}
namePrefix="parameters"
stepId={stepId}
disabled={editorContext.readOnly}
/>
</Box>
<Box
sx={{
display: 'flex',
flex: '1 0 0px',
maxWidth: ['100%', '33%'],
}}
>
<InputCreator
schema={createDropdownArgument({
key: `or.${groupIndex}.and.${groupItemIndex}.operator`,
options: operators,
label: 'Choose condition',
})}
namePrefix="parameters"
stepId={stepId}
disabled={editorContext.readOnly}
/>
</Box>
<Box sx={{ display: 'flex', flex: '1 0 0px', maxWidth: ['100%', '33%'] }}>
<InputCreator
schema={createStringArgument({ key: `or.${groupIndex}.and.${groupItemIndex}.value`, label: 'Enter text' })}
namePrefix="parameters"
stepId={stepId}
disabled={editorContext.readOnly}
/>
</Box>
<Box
sx={{
display: 'flex',
flex: '1 0 0px',
maxWidth: ['100%', '33%'],
}}
>
<InputCreator
schema={createStringArgument({
key: `or.${groupIndex}.and.${groupItemIndex}.value`,
label: 'Enter text',
})}
namePrefix="parameters"
stepId={stepId}
disabled={editorContext.readOnly}
/>
</Box>
</Stack>
<IconButton
size="small"
edge="start"
onClick={() => removeGroupItem(groupIndex, groupItemIndex)}
sx={{ width: 61, height: 61 }}
>
<RemoveIcon />
</IconButton>
</Stack>
<IconButton
size="small"
edge="start"
onClick={() => removeGroupItem(groupIndex, groupItemIndex)}
sx={{ width: 61, height: 61 }}
>
<RemoveIcon />
</IconButton>
</Stack>
))}
)
)}
<Stack spacing={1} direction="row">
<IconButton
@@ -194,14 +238,16 @@ function FilterConditions(props: FilterConditionsProps): React.ReactElement {
<AddIcon /> And
</IconButton>
{(groups.length - 1) === groupIndex && <IconButton
size="small"
edge="start"
onClick={appendGroup}
sx={{ width: 61, height: 61 }}
>
<AddIcon /> Or
</IconButton>}
{groups.length - 1 === groupIndex && (
<IconButton
size="small"
edge="start"
onClick={appendGroup}
sx={{ width: 61, height: 61 }}
>
<AddIcon /> Or
</IconButton>
)}
</Stack>
</>
))}

View File

@@ -4,7 +4,7 @@ import Collapse from '@mui/material/Collapse';
import ListItem from '@mui/material/ListItem';
import Button from '@mui/material/Button';
import Stack from '@mui/material/Stack';
import type { IStep, ISubstep } from '@automatisch/types';
import type { IStep, ISubstep } from 'types';
import { EditorContext } from 'contexts/Editor';
import FlowSubstepTitle from 'components/FlowSubstepTitle';
@@ -54,7 +54,7 @@ function FlowSubstep(props: FlowSubstepProps): React.ReactElement {
pb: 3,
flexDirection: 'column',
alignItems: 'flex-start',
position: 'relative'
position: 'relative',
}}
>
{!!args?.length && (

View File

@@ -1,7 +1,7 @@
import * as React from 'react';
import MuiTextField from '@mui/material/TextField';
import CircularProgress from '@mui/material/CircularProgress';
import type { IField, IFieldDropdownOption } from '@automatisch/types';
import type { IField, IFieldDropdownOption } from 'types';
import useDynamicFields from 'hooks/useDynamicFields';
import useDynamicData from 'hooks/useDynamicData';

View File

@@ -1,6 +1,6 @@
import * as React from 'react';
import { JSONTree } from 'react-json-tree';
import type { IJSONObject } from '@automatisch/types';
import type { IJSONObject } from 'types';
type JSONViewerProps = {
data: IJSONObject;

View File

@@ -14,7 +14,7 @@ import Typography from '@mui/material/Typography';
import * as React from 'react';
import { useFormContext } from 'react-hook-form';
import { IPermissionCatalog } from '@automatisch/types';
import { IPermissionCatalog } from 'types';
import ControlledCheckbox from 'components/ControlledCheckbox';
import useFormatMessage from 'hooks/useFormatMessage';
@@ -118,7 +118,9 @@ export default function PermissionSettings(props: PermissionSettingsProps) {
{action.subjects.includes(subject) && (
<ControlledCheckbox
name={`${fieldPrefix}.${action.key}.conditions.${condition.key}`}
dataTest={`${condition.key}-${action.key.toLowerCase()}-checkbox`}
dataTest={`${
condition.key
}-${action.key.toLowerCase()}-checkbox`}
defaultValue={defaultChecked}
disabled={
getValues(

View File

@@ -1,4 +1,4 @@
import type { IStep } from '@automatisch/types';
import type { IStep } from 'types';
import ExpandLess from '@mui/icons-material/ExpandLess';
import ExpandMore from '@mui/icons-material/ExpandMore';
import Box from '@mui/material/Box';
@@ -20,7 +20,7 @@ type SuggestionsProps = {
data: {
id: string;
name: string;
output: Record<string, unknown>[]
output: Record<string, unknown>[];
}[];
onSuggestionClick: (variable: any) => void;
};
@@ -31,69 +31,73 @@ const LIST_ITEM_HEIGHT = 64;
const computeListHeight = (currentLength: number) => {
const numberOfRenderedItems = Math.min(SHORT_LIST_LENGTH, currentLength);
return LIST_ITEM_HEIGHT * numberOfRenderedItems;
}
};
const getPartialArray = (array: any[], length = array.length) => {
return array.slice(0, length);
};
const renderItemFactory = ({ onSuggestionClick }: Pick<SuggestionsProps, 'onSuggestionClick'>) => (props: ListChildComponentProps) => {
const { index, style, data } = props;
const renderItemFactory =
({ onSuggestionClick }: Pick<SuggestionsProps, 'onSuggestionClick'>) =>
(props: ListChildComponentProps) => {
const { index, style, data } = props;
const suboption = data[index];
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>
);
}
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>
);
};
const Suggestions = (props: SuggestionsProps) => {
const formatMessage = useFormatMessage();
const {
data,
onSuggestionClick = () => null
} = props;
const { data, onSuggestionClick = () => null } = props;
const [current, setCurrent] = React.useState<number | null>(0);
const [listLength, setListLength] = React.useState<number>(SHORT_LIST_LENGTH);
const [filteredData, setFilteredData] = React.useState<any[]>(
data
const [filteredData, setFilteredData] = React.useState<any[]>(data);
React.useEffect(
function syncOptions() {
setFilteredData((filteredData) => {
if (filteredData.length === 0 && filteredData.length !== data.length) {
return data;
}
return filteredData;
});
},
[data]
);
React.useEffect(function syncOptions() {
setFilteredData((filteredData) => {
if (filteredData.length === 0 && filteredData.length !== data.length) {
return data;
}
return filteredData;
})
}, [data]);
const renderItem = React.useMemo(() => renderItemFactory({
onSuggestionClick
}), [onSuggestionClick]);
const renderItem = React.useMemo(
() =>
renderItemFactory({
onSuggestionClick,
}),
[onSuggestionClick]
);
const expandList = () => {
setListLength(Infinity);
@@ -122,12 +126,12 @@ const Suggestions = (props: SuggestionsProps) => {
return {
id: stepWithOutput.id,
name: stepWithOutput.name,
output: stepWithOutput.output
.filter(option => `${option.label}\n${option.sampleValue}`
output: stepWithOutput.output.filter((option) =>
`${option.label}\n${option.sampleValue}`
.toLowerCase()
.includes(search.toLowerCase())
)
}
),
};
})
.filter((stepWithOutput) => stepWithOutput.output.length);
@@ -161,14 +165,27 @@ const Suggestions = (props: SuggestionsProps) => {
(current === index ? <ExpandLess /> : <ExpandMore />)}
</ListItemButton>
<Collapse in={current === index || filteredData.length === 1} timeout="auto" unmountOnExit>
<Collapse
in={current === index || filteredData.length === 1}
timeout="auto"
unmountOnExit
>
<FixedSizeList
height={computeListHeight(getPartialArray((option.output as any) || [], listLength).length)}
height={computeListHeight(
getPartialArray((option.output as any) || [], listLength)
.length
)}
width="100%"
itemSize={LIST_ITEM_HEIGHT}
itemCount={getPartialArray((option.output as any) || [], listLength).length}
itemCount={
getPartialArray((option.output as any) || [], listLength)
.length
}
overscanCount={2}
itemData={getPartialArray((option.output as any) || [], listLength)}
itemData={getPartialArray(
(option.output as any) || [],
listLength
)}
data-test="power-input-suggestion-group"
>
{renderItem}

View File

@@ -1,4 +1,4 @@
import type { IStep } from '@automatisch/types';
import type { IStep } from 'types';
const joinBy = (delimiter = '.', ...args: string[]) =>
args.filter(Boolean).join(delimiter);
@@ -10,7 +10,12 @@ type TProcessPayload = {
parentLabel?: string;
};
const process = ({ data, parentKey, index, parentLabel = '' }: TProcessPayload): any[] => {
const process = ({
data,
parentKey,
index,
parentLabel = '',
}: TProcessPayload): any[] => {
if (typeof data !== 'object') {
return [
{
@@ -24,27 +29,19 @@ const process = ({ data, parentKey, index, parentLabel = '' }: TProcessPayload):
const entries = Object.entries(data);
return entries.flatMap(([name, sampleValue]) => {
const label = joinBy(
'.',
parentLabel,
(index as number)?.toString(),
name
);
const label = joinBy('.', parentLabel, (index as number)?.toString(), name);
const value = joinBy(
'.',
parentKey,
(index as number)?.toString(),
name
);
const value = joinBy('.', parentKey, (index as number)?.toString(), name);
if (Array.isArray(sampleValue)) {
return sampleValue.flatMap((item, index) => process({
data: item,
parentKey: value,
index,
parentLabel: label
}));
return sampleValue.flatMap((item, index) =>
process({
data: item,
parentKey: value,
index,
parentLabel: label,
})
);
}
if (typeof sampleValue === 'object' && sampleValue !== null) {
@@ -77,8 +74,9 @@ export const processStepWithExecutions = (steps: IStep[]): any[] => {
.map((step: IStep, index: number) => ({
id: step.id,
// TODO: replace with step.name once introduced
name: `${index + 1}. ${(step.appKey || '').charAt(0)?.toUpperCase() + step.appKey?.slice(1)
}`,
name: `${index + 1}. ${
(step.appKey || '').charAt(0)?.toUpperCase() + step.appKey?.slice(1)
}`,
output: process({
data: step.executionSteps?.[0]?.dataOut || {},
parentKey: `step.${step.id}`,

View File

@@ -3,7 +3,7 @@ import throttle from 'lodash/throttle';
import isEmpty from 'lodash/isEmpty';
import { Box, Typography } from '@mui/material';
import { IJSONObject } from '@automatisch/types';
import { IJSONObject } from 'types';
import JSONViewer from 'components/JSONViewer';
import SearchInput from 'components/SearchInput';
import useFormatMessage from 'hooks/useFormatMessage';

View File

@@ -1,7 +1,7 @@
import { Text, Descendant } from 'slate';
import { withHistory } from 'slate-history';
import { ReactEditor, withReact } from 'slate-react';
import { IFieldDropdownOption } from '@automatisch/types';
import { IFieldDropdownOption } from 'types';
import type {
CustomEditor,

View File

@@ -13,7 +13,7 @@ import { EXECUTE_FLOW } from 'graphql/mutations/execute-flow';
import JSONViewer from 'components/JSONViewer';
import WebhookUrlInfo from 'components/WebhookUrlInfo';
import FlowSubstepTitle from 'components/FlowSubstepTitle';
import type { IStep, ISubstep } from '@automatisch/types';
import type { IStep, ISubstep } from 'types';
type TestSubstepProps = {
substep: ISubstep;
@@ -62,7 +62,7 @@ function TestSubstep(props: TestSubstepProps): React.ReactElement {
EXECUTE_FLOW,
{
refetchQueries: ['GetStepWithTestExecutions'],
context: { autoSnackbar: false }
context: { autoSnackbar: false },
}
);
const response = data?.executeFlow?.data;

View File

@@ -5,7 +5,7 @@ import get from 'lodash/get';
import set from 'lodash/set';
import * as React from 'react';
import { IJSONObject } from '@automatisch/types';
import { IJSONObject } from 'types';
import useConfig from 'hooks/useConfig';
import useAutomatischInfo from 'hooks/useAutomatischInfo';
import { defaultTheme, mationTheme } from 'styles/theme';

View File

@@ -11,7 +11,7 @@ import Divider from '@mui/material/Divider';
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';
import { TBillingCardAction } from '@automatisch/types';
import { TBillingCardAction } from 'types';
import TrialOverAlert from 'components/TrialOverAlert/index.ee';
import SubscriptionCancelledAlert from 'components/SubscriptionCancelledAlert/index.ee';
import CheckoutCompletedAlert from 'components/CheckoutCompletedAlert/index.ee';