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