From 91a1c8b79305d84e2b0bb4d4d7a6b35c00ded64b Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Mon, 31 Jan 2022 22:12:08 +0100 Subject: [PATCH] feat: make substeps updatable --- packages/backend/src/apps/twitter/info.json | 6 ++- packages/backend/src/graphql/types/action.ts | 3 +- packages/backend/src/graphql/types/trigger.ts | 3 +- .../web/src/components/FlowStep/index.tsx | 48 +++++++++++++------ packages/web/src/components/Form/index.tsx | 12 +++-- .../web/src/components/InputCreator/index.tsx | 5 +- .../web/src/components/TextField/index.tsx | 6 ++- packages/web/src/graphql/queries/get-apps.ts | 6 ++- packages/web/src/types/app.ts | 1 + 9 files changed, 64 insertions(+), 26 deletions(-) diff --git a/packages/backend/src/apps/twitter/info.json b/packages/backend/src/apps/twitter/info.json index 29b8ad5f..57a296a6 100644 --- a/packages/backend/src/apps/twitter/info.json +++ b/packages/backend/src/apps/twitter/info.json @@ -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 } diff --git a/packages/backend/src/graphql/types/action.ts b/packages/backend/src/graphql/types/action.ts index 4def1d2e..d2ad1630 100644 --- a/packages/backend/src/graphql/types/action.ts +++ b/packages/backend/src/graphql/types/action.ts @@ -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 } } diff --git a/packages/backend/src/graphql/types/trigger.ts b/packages/backend/src/graphql/types/trigger.ts index f2a6b7fa..aab59fee 100644 --- a/packages/backend/src/graphql/types/trigger.ts +++ b/packages/backend/src/graphql/types/trigger.ts @@ -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 } } diff --git a/packages/web/src/components/FlowStep/index.tsx b/packages/web/src/components/FlowStep/index.tsx index 62ddc67a..7a31e11a 100644 --- a/packages/web/src/components/FlowStep/index.tsx +++ b/packages/web/src/components/FlowStep/index.tsx @@ -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 - {substeps?.length > 0 && substeps.map((substep: Record, index: number) => ( - - toggleSubstep(index + 1)} selected={currentSubstep === (index + 1)} divider> - - {substep.name as string} - - - - - - - - - ))} +
+ {substeps?.length > 0 && substeps.map((substep: { name: string, arguments: AppFields[] }, index: number) => ( + + toggleSubstep(index + 1)} selected={currentSubstep === (index + 1)} divider> + + {substep.name as string} + + + + + {substep?.arguments?.map((argument: AppFields) => ( + + ))} + + + + ))} +
diff --git a/packages/web/src/components/Form/index.tsx b/packages/web/src/components/Form/index.tsx index e675ddb6..7444a7e7 100644 --- a/packages/web/src/components/Form/index.tsx +++ b/packages/web/src/components/Form/index.tsx @@ -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; + defaultValues?: UseFormProps['defaultValues']; + onSubmit?: SubmitHandler; } +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 ( diff --git a/packages/web/src/components/InputCreator/index.tsx b/packages/web/src/components/InputCreator/index.tsx index ff1f3cfd..ffd372d4 100644 --- a/packages/web/src/components/InputCreator/index.tsx +++ b/packages/web/src/components/InputCreator/index.tsx @@ -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} diff --git a/packages/web/src/components/TextField/index.tsx b/packages/web/src/components/TextField/index.tsx index cddb4f03..a29c322a 100644 --- a/packages/web/src/components/TextField/index.tsx +++ b/packages/web/src/components/TextField/index.tsx @@ -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 } }) => ( { controllerOnChange(...args); onChange?.(...args); }} + onBlur={(...args) => { controllerOnBlur(); onBlur?.(...args); }} inputRef={(element) => { inputRef.current = element; ref(element); }} InputProps={{ readOnly, endAdornment: clickToCopy ? createCopyAdornment(inputRef) : null}} /> diff --git a/packages/web/src/graphql/queries/get-apps.ts b/packages/web/src/graphql/queries/get-apps.ts index e34c0b87..3236b9fd 100644 --- a/packages/web/src/graphql/queries/get-apps.ts +++ b/packages/web/src/graphql/queries/get-apps.ts @@ -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 } diff --git a/packages/web/src/types/app.ts b/packages/web/src/types/app.ts index 0d918faf..79e2fa8a 100644 --- a/packages/web/src/types/app.ts +++ b/packages/web/src/types/app.ts @@ -1,5 +1,6 @@ type AppFields = { key: string; + name: string; label: string; type: string; required: boolean,