feat: make substeps updatable

This commit is contained in:
Ali BARIN
2022-01-31 22:12:08 +01:00
committed by Ömer Faruk Aydın
parent 6c0ba197c6
commit 91a1c8b793
9 changed files with 64 additions and 26 deletions

View File

@@ -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
} }

View File

@@ -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 }
} }

View File

@@ -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 }
} }

View File

@@ -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,20 +197,24 @@ 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) => (
<ListItemButton onClick={() => toggleSubstep(index + 1)} selected={currentSubstep === (index + 1)} divider> <React.Fragment key={`${substep?.name}-${index}`}>
<Typography variant="body2"> <ListItemButton onClick={() => toggleSubstep(index + 1)} selected={currentSubstep === (index + 1)} divider>
{substep.name as string} <Typography variant="body2">
</Typography> {substep.name as string}
</ListItemButton> </Typography>
<Collapse in={currentSubstep === (index + 1)} timeout="auto" unmountOnExit> </ListItemButton>
<ListItem sx={{ pt: 2 }}> <Collapse in={currentSubstep === (index + 1)} timeout="auto" unmountOnExit>
<ListItem sx={{ pt: 2 }}>
</ListItem> {substep?.arguments?.map((argument: AppFields) => (
</Collapse> <InputCreator key={argument?.key} schema={argument} onBlur={onParameterChange} />
</React.Fragment> ))}
))} </ListItem>
</Collapse>
</React.Fragment>
))}
</Form>
</List> </List>
</Content> </Content>

View File

@@ -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}>

View File

@@ -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}

View File

@@ -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}}
/> />

View File

@@ -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
} }

View File

@@ -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,