feat: make substeps updatable
This commit is contained in:

committed by
Ömer Faruk Aydın

parent
6c0ba197c6
commit
91a1c8b793
@@ -241,7 +241,8 @@
|
||||
"name": "Set up a trigger",
|
||||
"arguments": [
|
||||
{
|
||||
"name": "username",
|
||||
"label": "Username",
|
||||
"key": "username",
|
||||
"type": "string",
|
||||
"required": true
|
||||
}
|
||||
@@ -266,7 +267,8 @@
|
||||
"name": "Set up action",
|
||||
"arguments": [
|
||||
{
|
||||
"name": "tweet",
|
||||
"label": "Tweet body",
|
||||
"key": "tweet",
|
||||
"type": "string",
|
||||
"required": true
|
||||
}
|
||||
|
@@ -17,7 +17,8 @@ const actionType = new GraphQLObjectType({
|
||||
new GraphQLObjectType({
|
||||
name: 'ActionSubStepArgument',
|
||||
fields: {
|
||||
name: { type: GraphQLString },
|
||||
label: { type: GraphQLString },
|
||||
key: { type: GraphQLString },
|
||||
type: { type: GraphQLString },
|
||||
required: { type: GraphQLBoolean }
|
||||
}
|
||||
|
@@ -17,7 +17,8 @@ const triggerType = new GraphQLObjectType({
|
||||
new GraphQLObjectType({
|
||||
name: 'TriggerSubStepArgument',
|
||||
fields: {
|
||||
name: { type: GraphQLString },
|
||||
label: { type: GraphQLString },
|
||||
key: { type: GraphQLString },
|
||||
type: { type: GraphQLString },
|
||||
required: { type: GraphQLBoolean }
|
||||
}
|
||||
|
@@ -13,11 +13,13 @@ import Autocomplete from '@mui/material/Autocomplete';
|
||||
import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
|
||||
import Form from 'components/Form';
|
||||
import InputCreator from 'components/InputCreator';
|
||||
import FlowStepContextMenu from 'components/FlowStepContextMenu';
|
||||
import AppIcon from 'components/AppIcon';
|
||||
import { GET_APPS } from 'graphql/queries/get-apps';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
import type { App } from 'types/app';
|
||||
import type { App, AppFields } from 'types/app';
|
||||
import type { Step } from 'types/step';
|
||||
import { StepType } from 'types/step';
|
||||
import { Content, Header, Wrapper } from './style';
|
||||
@@ -101,6 +103,18 @@ export default function FlowStep(props: FlowStepProps): React.ReactElement | nul
|
||||
}
|
||||
}, []);
|
||||
|
||||
const onParameterChange = React.useCallback((event: React.SyntheticEvent) => {
|
||||
const { name, value } = event.target as HTMLInputElement;
|
||||
|
||||
setStep((step) => ({
|
||||
...step,
|
||||
parameters: {
|
||||
...step.parameters,
|
||||
[name]: value
|
||||
}
|
||||
}));
|
||||
}, []);
|
||||
|
||||
if (!apps) return null;
|
||||
|
||||
const onContextMenuClose = (event: React.SyntheticEvent) => {
|
||||
@@ -183,20 +197,24 @@ export default function FlowStep(props: FlowStepProps): React.ReactElement | nul
|
||||
</ListItem>
|
||||
</Collapse>
|
||||
|
||||
{substeps?.length > 0 && substeps.map((substep: Record<string, unknown>, index: number) => (
|
||||
<React.Fragment key={substep?.key as string}>
|
||||
<ListItemButton onClick={() => toggleSubstep(index + 1)} selected={currentSubstep === (index + 1)} divider>
|
||||
<Typography variant="body2">
|
||||
{substep.name as string}
|
||||
</Typography>
|
||||
</ListItemButton>
|
||||
<Collapse in={currentSubstep === (index + 1)} timeout="auto" unmountOnExit>
|
||||
<ListItem sx={{ pt: 2 }}>
|
||||
|
||||
</ListItem>
|
||||
</Collapse>
|
||||
</React.Fragment>
|
||||
))}
|
||||
<Form defaultValues={step.parameters}>
|
||||
{substeps?.length > 0 && substeps.map((substep: { name: string, arguments: AppFields[] }, index: number) => (
|
||||
<React.Fragment key={`${substep?.name}-${index}`}>
|
||||
<ListItemButton onClick={() => toggleSubstep(index + 1)} selected={currentSubstep === (index + 1)} divider>
|
||||
<Typography variant="body2">
|
||||
{substep.name as string}
|
||||
</Typography>
|
||||
</ListItemButton>
|
||||
<Collapse in={currentSubstep === (index + 1)} timeout="auto" unmountOnExit>
|
||||
<ListItem sx={{ pt: 2 }}>
|
||||
{substep?.arguments?.map((argument: AppFields) => (
|
||||
<InputCreator key={argument?.key} schema={argument} onBlur={onParameterChange} />
|
||||
))}
|
||||
</ListItem>
|
||||
</Collapse>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</Form>
|
||||
</List>
|
||||
</Content>
|
||||
|
||||
|
@@ -1,14 +1,20 @@
|
||||
import * as React from 'react';
|
||||
import { FormProvider, useForm, FieldValues, SubmitHandler, UseFormReturn } from 'react-hook-form';
|
||||
import type { UseFormProps } from 'react-hook-form';
|
||||
|
||||
type FormProps = {
|
||||
children: React.ReactNode;
|
||||
onSubmit: SubmitHandler<FieldValues>;
|
||||
defaultValues?: UseFormProps['defaultValues'];
|
||||
onSubmit?: SubmitHandler<FieldValues>;
|
||||
}
|
||||
|
||||
const noop = () => null;
|
||||
|
||||
export default function Form(props: FormProps): React.ReactElement {
|
||||
const { children, onSubmit, ...formProps } = props;
|
||||
const methods: UseFormReturn = useForm();
|
||||
const { children, onSubmit = noop, defaultValues, ...formProps } = props;
|
||||
const methods: UseFormReturn = useForm({
|
||||
defaultValues,
|
||||
});
|
||||
|
||||
return (
|
||||
<FormProvider {...methods}>
|
||||
|
@@ -6,12 +6,14 @@ import TextField from 'components/TextField';
|
||||
|
||||
type InputCreatorProps = {
|
||||
onChange?: React.ChangeEventHandler;
|
||||
onBlur?: React.FocusEventHandler;
|
||||
schema: AppFields;
|
||||
};
|
||||
|
||||
export default function InputCreator(props: InputCreatorProps): React.ReactElement {
|
||||
const {
|
||||
onChange,
|
||||
onBlur,
|
||||
schema,
|
||||
} = props;
|
||||
|
||||
@@ -21,7 +23,7 @@ export default function InputCreator(props: InputCreatorProps): React.ReactEleme
|
||||
key: name,
|
||||
label,
|
||||
required,
|
||||
readOnly,
|
||||
readOnly = false,
|
||||
value,
|
||||
description,
|
||||
clickToCopy,
|
||||
@@ -35,6 +37,7 @@ export default function InputCreator(props: InputCreatorProps): React.ReactEleme
|
||||
disabled={readOnly}
|
||||
readOnly={readOnly}
|
||||
onChange={onChange}
|
||||
onBlur={onBlur}
|
||||
name={name}
|
||||
size="small"
|
||||
label={label}
|
||||
|
@@ -38,6 +38,8 @@ export default function TextField(props: TextFieldProps): React.ReactElement {
|
||||
shouldUnregister,
|
||||
clickToCopy,
|
||||
readOnly,
|
||||
onBlur,
|
||||
onChange,
|
||||
...textFieldProps
|
||||
} = props;
|
||||
|
||||
@@ -48,10 +50,12 @@ export default function TextField(props: TextFieldProps): React.ReactElement {
|
||||
defaultValue={defaultValue || ''}
|
||||
control={control}
|
||||
shouldUnregister={shouldUnregister}
|
||||
render={({ field: { ref, ...field } }) => (
|
||||
render={({ field: { ref, onChange: controllerOnChange, onBlur: controllerOnBlur, ...field } }) => (
|
||||
<MuiTextField
|
||||
{...textFieldProps}
|
||||
{...field}
|
||||
onChange={(...args) => { controllerOnChange(...args); onChange?.(...args); }}
|
||||
onBlur={(...args) => { controllerOnBlur(); onBlur?.(...args); }}
|
||||
inputRef={(element) => { inputRef.current = element; ref(element); }}
|
||||
InputProps={{ readOnly, endAdornment: clickToCopy ? createCopyAdornment(inputRef) : null}}
|
||||
/>
|
||||
|
@@ -59,7 +59,8 @@ export const GET_APPS = gql`
|
||||
subSteps {
|
||||
name
|
||||
arguments {
|
||||
name
|
||||
label
|
||||
key
|
||||
type
|
||||
required
|
||||
}
|
||||
@@ -72,7 +73,8 @@ export const GET_APPS = gql`
|
||||
subSteps {
|
||||
name
|
||||
arguments {
|
||||
name
|
||||
label
|
||||
key
|
||||
type
|
||||
required
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
type AppFields = {
|
||||
key: string;
|
||||
name: string;
|
||||
label: string;
|
||||
type: string;
|
||||
required: boolean,
|
||||
|
Reference in New Issue
Block a user