chore: introduce @automatisch/types
This commit is contained in:

committed by
Ömer Faruk Aydın

parent
bbb6f0b0ff
commit
3391578655
@@ -10,12 +10,12 @@ import useFormatMessage from 'hooks/useFormatMessage';
|
||||
import computeAuthStepVariables from 'helpers/computeAuthStepVariables';
|
||||
import { processStep } from 'helpers/authenticationSteps';
|
||||
import InputCreator from 'components/InputCreator';
|
||||
import type { App } from 'types/app';
|
||||
import type { IApp, IField } from '@automatisch/types';
|
||||
import { Form } from './style';
|
||||
|
||||
type AddAppConnectionProps = {
|
||||
onClose: () => void;
|
||||
application: App;
|
||||
application: IApp;
|
||||
connectionId?: string;
|
||||
};
|
||||
|
||||
@@ -73,7 +73,7 @@ export default function AddAppConnection(props: AddAppConnectionProps): React.Re
|
||||
<DialogContent>
|
||||
<DialogContentText tabIndex={-1} component="div">
|
||||
<Form onSubmit={submitHandler}>
|
||||
{fields?.map(field => (<InputCreator key={field.key} schema={field} />))}
|
||||
{fields?.map((field: IField) => (<InputCreator key={field.key} schema={field} />))}
|
||||
|
||||
<LoadingButton
|
||||
type="submit"
|
||||
|
@@ -16,10 +16,10 @@ import ListItemText from '@mui/material/ListItemText';
|
||||
import InputLabel from '@mui/material/InputLabel';
|
||||
import OutlinedInput from '@mui/material/OutlinedInput';
|
||||
import FormControl from '@mui/material/FormControl';
|
||||
import type { IApp } from '@automatisch/types';
|
||||
|
||||
import * as URLS from 'config/urls';
|
||||
import AppIcon from 'components/AppIcon';
|
||||
import type { App } from 'types/app';
|
||||
import { GET_APPS } from 'graphql/queries/get-apps';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
|
||||
@@ -68,7 +68,7 @@ export default function AddNewAppConnection(props: AddNewAppConnectionProps): Re
|
||||
</FormControl>
|
||||
|
||||
<List sx={{ pt: 2 }}>
|
||||
{data?.getApps?.map((app: App) => (
|
||||
{data?.getApps?.map((app: IApp) => (
|
||||
<ListItem disablePadding key={app.name}>
|
||||
<ListItemButton component={Link} to={URLS.APP_ADD_CONNECTION(app.name.toLowerCase())}>
|
||||
<ListItemIcon sx={{ minWidth: 74 }}>
|
||||
|
@@ -2,15 +2,15 @@ import { useQuery } from '@apollo/client';
|
||||
import { GET_FLOWS } from 'graphql/queries/get-flows';
|
||||
|
||||
import AppFlowRow from 'components/AppFlowRow';
|
||||
import type { Flow } from 'types/flow';
|
||||
import type { IFlow } from '@automatisch/types';
|
||||
|
||||
export default function AppFlows(): React.ReactElement {
|
||||
const { data } = useQuery(GET_FLOWS);
|
||||
const appFlows: Flow[] = data?.getFlows || [];
|
||||
const appFlows: IFlow[] = data?.getFlows || [];
|
||||
|
||||
return (
|
||||
<>
|
||||
{appFlows.map((appFlow: Flow) => (
|
||||
{appFlows.map((appFlow: IFlow) => (
|
||||
<AppFlowRow key={appFlow.id} flow={appFlow} />
|
||||
))}
|
||||
</>
|
||||
|
@@ -8,11 +8,12 @@ import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
import AppIcon from 'components/AppIcon';
|
||||
import * as URLS from 'config/urls';
|
||||
import type { App } from 'types/app';
|
||||
import type { IApp } from '@automatisch/types';
|
||||
|
||||
import { CardContent, Typography } from './style';
|
||||
|
||||
type AppRowProps = {
|
||||
application: App;
|
||||
application: IApp;
|
||||
}
|
||||
|
||||
const countTranslation = (value: React.ReactNode) => (
|
||||
|
@@ -7,22 +7,21 @@ import ListItem from '@mui/material/ListItem';
|
||||
import Autocomplete from '@mui/material/Autocomplete';
|
||||
|
||||
import FlowSubstepTitle from 'components/FlowSubstepTitle';
|
||||
import type { App, AppConnection } from 'types/app';
|
||||
import type { Step, Substep } from 'types/step';
|
||||
import type { IApp, IConnection, IStep, ISubstep, IJSONObject } from '@automatisch/types';
|
||||
import { GET_APP_CONNECTIONS } from 'graphql/queries/get-app-connections';
|
||||
import { TEST_CONNECTION } from 'graphql/queries/test-connection';
|
||||
|
||||
type ChooseAccountSubstepProps = {
|
||||
substep: Substep,
|
||||
substep: ISubstep,
|
||||
expanded?: boolean;
|
||||
onExpand: () => void;
|
||||
onCollapse: () => void;
|
||||
onChange: ({ step }: { step: Step}) => void;
|
||||
onChange: ({ step }: { step: IStep }) => void;
|
||||
onSubmit: () => void;
|
||||
step: Step;
|
||||
step: IStep;
|
||||
};
|
||||
|
||||
const optionGenerator = (connection: AppConnection): { label: string; value: string; } => ({
|
||||
const optionGenerator = (connection: IConnection<IJSONObject>): { label: string; value: string; } => ({
|
||||
label: connection?.data?.screenName as string ?? 'Unnamed',
|
||||
value: connection?.id as string,
|
||||
});
|
||||
@@ -62,7 +61,7 @@ function ChooseAccountSubstep(props: ChooseAccountSubstepProps): React.ReactElem
|
||||
// intentionally no dependencies for initial test
|
||||
}, []);
|
||||
|
||||
const connectionOptions = React.useMemo(() => (data?.getApp as App)?.connections?.map((connection) => optionGenerator(connection)) || [], [data]);
|
||||
const connectionOptions = React.useMemo(() => (data?.getApp as IApp)?.connections?.map((connection) => optionGenerator(connection)) || [], [data]);
|
||||
|
||||
const { name } = substep;
|
||||
|
||||
|
@@ -10,26 +10,24 @@ import Autocomplete from '@mui/material/Autocomplete';
|
||||
|
||||
import { GET_APPS } from 'graphql/queries/get-apps';
|
||||
import FlowSubstepTitle from 'components/FlowSubstepTitle';
|
||||
import type { App } from 'types/app';
|
||||
import type { Step, Substep } from 'types/step';
|
||||
import { StepType } from 'types/step';
|
||||
import type { IApp, IStep, ISubstep } from '@automatisch/types';
|
||||
|
||||
type ChooseAppAndEventSubstepProps = {
|
||||
substep: Substep,
|
||||
substep: ISubstep,
|
||||
expanded?: boolean;
|
||||
onExpand: () => void;
|
||||
onCollapse: () => void;
|
||||
onChange: ({ step }: { step: Step}) => void;
|
||||
onChange: ({ step }: { step: IStep }) => void;
|
||||
onSubmit: () => void;
|
||||
step: Step;
|
||||
step: IStep;
|
||||
};
|
||||
|
||||
const optionGenerator = (app: Record<string, unknown>): { label: string; value: string; } => ({
|
||||
const optionGenerator = (app: IApp): { label: string; value: string; } => ({
|
||||
label: app.name as string,
|
||||
value: app.key as string,
|
||||
});
|
||||
|
||||
const getOption = (options: Record<string, unknown>[], appKey: unknown) => options.find(app => app.value === appKey as string) || null;
|
||||
const getOption = (options: Record<string, unknown>[], appKey: IApp["key"]) => options.find(option => option.value === appKey as string) || null;
|
||||
|
||||
function ChooseAppAndEventSubstep(props: ChooseAppAndEventSubstepProps): React.ReactElement {
|
||||
const {
|
||||
@@ -42,11 +40,11 @@ function ChooseAppAndEventSubstep(props: ChooseAppAndEventSubstepProps): React.R
|
||||
onChange,
|
||||
} = props;
|
||||
|
||||
const isTrigger = step.type === StepType.Trigger;
|
||||
const isTrigger = step.type === 'trigger';
|
||||
|
||||
const { data } = useQuery(GET_APPS, { variables: { onlyWithTriggers: isTrigger }});
|
||||
const apps: App[] = data?.getApps;
|
||||
const app = apps?.find((currentApp: App) => currentApp.key === step.appKey);
|
||||
const apps: IApp[] = data?.getApps;
|
||||
const app = apps?.find((currentApp: IApp) => currentApp.key === step.appKey);
|
||||
|
||||
const appOptions = React.useMemo(() => apps?.map((app) => optionGenerator(app)), [apps]);
|
||||
const actionsOrTriggers = isTrigger ? app?.triggers : app?.actions;
|
||||
@@ -88,7 +86,7 @@ function ChooseAppAndEventSubstep(props: ChooseAppAndEventSubstepProps): React.R
|
||||
onChange({
|
||||
step: {
|
||||
...step,
|
||||
key: null,
|
||||
key: '',
|
||||
appKey,
|
||||
},
|
||||
});
|
||||
|
@@ -8,10 +8,10 @@ import { GET_FLOW } from 'graphql/queries/get-flow';
|
||||
import { CREATE_STEP } from 'graphql/mutations/create-step';
|
||||
import { UPDATE_STEP } from 'graphql/mutations/update-step';
|
||||
import FlowStep from 'components/FlowStep';
|
||||
import type { Flow } from 'types/flow';
|
||||
import type { IFlow } from '@automatisch/types';
|
||||
|
||||
type EditorProps = {
|
||||
flow: Flow;
|
||||
flow: IFlow;
|
||||
};
|
||||
|
||||
function updateHandlerFactory(flowId: string, previousStepId: string) {
|
||||
|
@@ -14,7 +14,7 @@ import Editor from 'components/Editor';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
import { UPDATE_FLOW } from 'graphql/mutations/update-flow';
|
||||
import { GET_FLOW } from 'graphql/queries/get-flow';
|
||||
import type { Flow } from 'types/flow';
|
||||
import type { IFlow } from '@automatisch/types';
|
||||
import * as URLS from 'config/urls';
|
||||
|
||||
export default function EditorLayout(): React.ReactElement {
|
||||
@@ -22,7 +22,7 @@ export default function EditorLayout(): React.ReactElement {
|
||||
const formatMessage = useFormatMessage();
|
||||
const [updateFlow] = useMutation(UPDATE_FLOW);
|
||||
const { data, loading } = useQuery(GET_FLOW, { variables: { id: flowId }});
|
||||
const flow: Flow = data?.getFlow;
|
||||
const flow: IFlow = data?.getFlow;
|
||||
|
||||
const onFlowNameUpdate = React.useCallback(async (name: string) => {
|
||||
await updateFlow({
|
||||
|
@@ -5,12 +5,12 @@ import Box from '@mui/material/Box';
|
||||
import CardActionArea from '@mui/material/CardActionArea';
|
||||
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
|
||||
|
||||
import type { Flow } from 'types/flow';
|
||||
import type { IFlow } from '@automatisch/types';
|
||||
import * as URLS from 'config/urls';
|
||||
import { CardContent, Typography } from './style';
|
||||
|
||||
type FlowRowProps = {
|
||||
flow: Flow;
|
||||
flow: IFlow;
|
||||
}
|
||||
|
||||
export default function FlowRow(props: FlowRowProps): React.ReactElement {
|
||||
|
@@ -10,6 +10,7 @@ import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import ErrorIcon from '@mui/icons-material/Error';
|
||||
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
|
||||
import type { IApp, IField, IStep } from '@automatisch/types';
|
||||
|
||||
import { StepExecutionsProvider } from 'contexts/StepExecutions';
|
||||
import TestSubstep from 'components/TestSubstep';
|
||||
@@ -22,18 +23,15 @@ import AppIcon from 'components/AppIcon';
|
||||
import { GET_APPS } from 'graphql/queries/get-apps';
|
||||
import { GET_STEP_WITH_TEST_EXECUTIONS } from 'graphql/queries/get-step-with-test-executions';
|
||||
import useFormatMessage from 'hooks/useFormatMessage';
|
||||
import type { App, AppFields } from 'types/app';
|
||||
import type { Step } from 'types/step';
|
||||
import { StepType } from 'types/step';
|
||||
import { AppIconWrapper, AppIconStatusIconWrapper, Content, Header, Wrapper } from './style';
|
||||
|
||||
type FlowStepProps = {
|
||||
collapsed?: boolean;
|
||||
step: Step;
|
||||
step: IStep;
|
||||
index?: number;
|
||||
onOpen?: () => void;
|
||||
onClose?: () => void;
|
||||
onChange: (step: Step) => void;
|
||||
onChange: (step: IStep) => void;
|
||||
}
|
||||
|
||||
const validIcon = <CheckCircleIcon color="success" />;
|
||||
@@ -42,9 +40,9 @@ const errorIcon = <ErrorIcon color="error" />;
|
||||
export default function FlowStep(props: FlowStepProps): React.ReactElement | null {
|
||||
const { collapsed, index, onChange } = props;
|
||||
const contextButtonRef = React.useRef<HTMLButtonElement | null>(null);
|
||||
const step: Step = props.step;
|
||||
const step: IStep = props.step;
|
||||
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null);
|
||||
const isTrigger = step.type === StepType.Trigger;
|
||||
const isTrigger = step.type === 'trigger';
|
||||
const formatMessage = useFormatMessage();
|
||||
const [currentSubstep, setCurrentSubstep] = React.useState<number | null>(2);
|
||||
const { data } = useQuery(GET_APPS, { variables: { onlyWithTriggers: isTrigger }});
|
||||
@@ -70,13 +68,13 @@ export default function FlowStep(props: FlowStepProps): React.ReactElement | nul
|
||||
}
|
||||
}, [collapsed, stepWithTestExecutionsCalled, getStepWithTestExecutions, step.id, isTrigger]);
|
||||
|
||||
const apps: App[] = data?.getApps;
|
||||
const app = apps?.find((currentApp: App) => currentApp.key === step.appKey);
|
||||
const apps: IApp[] = data?.getApps;
|
||||
const app = apps?.find((currentApp: IApp) => currentApp.key === step.appKey);
|
||||
|
||||
const actionsOrTriggers = isTrigger ? app?.triggers : app?.actions;
|
||||
const substeps = React.useMemo(() => actionsOrTriggers?.find(({ key }) => key === step.key)?.subSteps || [], [actionsOrTriggers, step?.key]);
|
||||
|
||||
const handleChange = React.useCallback(({ step }: { step: Step }) => {
|
||||
const handleChange = React.useCallback(({ step }: { step: IStep }) => {
|
||||
onChange(step);
|
||||
}, [])
|
||||
|
||||
@@ -85,7 +83,7 @@ export default function FlowStep(props: FlowStepProps): React.ReactElement | nul
|
||||
}, []);
|
||||
|
||||
const handleSubmit = (val: any) => {
|
||||
handleChange({ step: val as Step });
|
||||
handleChange({ step: val as IStep });
|
||||
}
|
||||
|
||||
if (!apps) return null;
|
||||
@@ -143,7 +141,7 @@ export default function FlowStep(props: FlowStepProps): React.ReactElement | nul
|
||||
<Collapse in={!collapsed} unmountOnExit>
|
||||
<Content>
|
||||
<List>
|
||||
<StepExecutionsProvider value={stepWithTestExecutionsData?.getStepWithTestExecutions as Step[]}>
|
||||
<StepExecutionsProvider value={stepWithTestExecutionsData?.getStepWithTestExecutions as IStep[]}>
|
||||
<Form defaultValues={step} onSubmit={handleSubmit}>
|
||||
<ChooseAppAndEventSubstep
|
||||
expanded={currentSubstep === 0}
|
||||
@@ -155,7 +153,7 @@ export default function FlowStep(props: FlowStepProps): React.ReactElement | nul
|
||||
step={step}
|
||||
/>
|
||||
|
||||
{substeps?.length > 0 && substeps.map((substep: { name: string, key: string, arguments: AppFields[] }, index: number) => (
|
||||
{substeps?.length > 0 && substeps.map((substep: { name: string, key: string, arguments: IField[] }, index: number) => (
|
||||
<React.Fragment key={`${substep?.name}-${index}`}>
|
||||
{substep.key === 'chooseAccount' && (
|
||||
<ChooseAccountSubstep
|
||||
|
@@ -6,23 +6,22 @@ import Button from '@mui/material/Button';
|
||||
|
||||
import FlowSubstepTitle from 'components/FlowSubstepTitle';
|
||||
import InputCreator from 'components/InputCreator';
|
||||
import type { Step, Substep } from 'types/step';
|
||||
import type { AppFields } from 'types/app';
|
||||
import type { IField, IStep, ISubstep } from '@automatisch/types';
|
||||
|
||||
type FlowSubstepProps = {
|
||||
substep: Substep,
|
||||
substep: ISubstep,
|
||||
expanded?: boolean;
|
||||
onExpand: () => void;
|
||||
onCollapse: () => void;
|
||||
onChange: ({ step }: { step: Step }) => void;
|
||||
onChange: ({ step }: { step: IStep }) => void;
|
||||
onSubmit: () => void;
|
||||
step: Step;
|
||||
step: IStep;
|
||||
};
|
||||
|
||||
const validateSubstep = (substep: Substep, step: Step) => {
|
||||
const validateSubstep = (substep: ISubstep, step: IStep) => {
|
||||
if (!substep) return true;
|
||||
|
||||
const args: AppFields[] = substep.arguments || [];
|
||||
const args: IField[] = substep.arguments || [];
|
||||
|
||||
return args.every(arg => {
|
||||
if (arg.required === false) { return true; }
|
||||
@@ -50,7 +49,7 @@ function FlowSubstep(props: FlowSubstepProps): React.ReactElement {
|
||||
} = substep;
|
||||
|
||||
const formContext = useFormContext();
|
||||
const [validationStatus, setValidationStatus] = React.useState<boolean | null>(validateSubstep(substep, formContext.getValues() as Step));
|
||||
const [validationStatus, setValidationStatus] = React.useState<boolean | null>(validateSubstep(substep, formContext.getValues() as IStep));
|
||||
|
||||
|
||||
const handleChangeOnBlur = React.useCallback((key: string) => {
|
||||
@@ -73,7 +72,7 @@ function FlowSubstep(props: FlowSubstepProps): React.ReactElement {
|
||||
|
||||
React.useEffect(() => {
|
||||
function validate (step: unknown) {
|
||||
const validationResult = validateSubstep(substep, step as Step);
|
||||
const validationResult = validateSubstep(substep, step as IStep);
|
||||
setValidationStatus(validationResult);
|
||||
};
|
||||
const subscription = formContext.watch(validate);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import type { AppFields } from 'types/app';
|
||||
import type { IField } from '@automatisch/types';
|
||||
|
||||
import PowerInput from 'components/PowerInput';
|
||||
import TextField from 'components/TextField';
|
||||
@@ -8,7 +8,7 @@ import TextField from 'components/TextField';
|
||||
type InputCreatorProps = {
|
||||
onChange?: React.ChangeEventHandler;
|
||||
onBlur?: React.FocusEventHandler;
|
||||
schema: AppFields;
|
||||
schema: IField;
|
||||
namePrefix?: string;
|
||||
};
|
||||
|
||||
|
@@ -10,7 +10,7 @@ import Collapse from '@mui/material/Collapse';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import ExpandLess from '@mui/icons-material/ExpandLess';
|
||||
import ExpandMore from '@mui/icons-material/ExpandMore';
|
||||
import { Step } from 'types/step';
|
||||
import type { IStep } from '@automatisch/types';
|
||||
|
||||
const ListItemText = styled(MuiListItemText)``;
|
||||
|
||||
@@ -61,7 +61,7 @@ const Suggestions = (props: SuggestionsProps) => {
|
||||
<List
|
||||
disablePadding
|
||||
>
|
||||
{data.map((option: Step, index: number) => (
|
||||
{data.map((option: IStep, index: number) => (
|
||||
<>
|
||||
<ListItemButton
|
||||
divider
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Step } from 'types/step';
|
||||
import type { IStep } from '@automatisch/types';
|
||||
|
||||
const joinBy = (delimiter = '.', ...args: string[]) => args.filter(Boolean).join(delimiter);
|
||||
|
||||
@@ -32,10 +32,10 @@ const process = (data: any, parentKey?: any, index?: number): any[] => {
|
||||
});
|
||||
};
|
||||
|
||||
export const processStepWithExecutions = (steps: Step[]): any[] => {
|
||||
export const processStepWithExecutions = (steps: IStep[]): any[] => {
|
||||
if (!steps) return [];
|
||||
|
||||
return steps.map((step: Step, index: number) => ({
|
||||
return steps.map((step: IStep, index: number) => ({
|
||||
id: step.id,
|
||||
// TODO: replace with step.name once introduced
|
||||
name: `${index + 1}. ${step.appKey}`,
|
||||
|
@@ -6,17 +6,16 @@ import Button from '@mui/material/Button';
|
||||
|
||||
import { EXECUTE_FLOW } from 'graphql/mutations/execute-flow';
|
||||
import FlowSubstepTitle from 'components/FlowSubstepTitle';
|
||||
import type { Step, Substep } from 'types/step';
|
||||
import type { AppFields } from 'types/app';
|
||||
import type { IStep, ISubstep } from '@automatisch/types';
|
||||
|
||||
type TestSubstepProps = {
|
||||
substep: Substep,
|
||||
substep: ISubstep,
|
||||
expanded?: boolean;
|
||||
onExpand: () => void;
|
||||
onCollapse: () => void;
|
||||
onChange?: ({ step }: { step: Step }) => void;
|
||||
onChange?: ({ step }: { step: IStep }) => void;
|
||||
onSubmit?: () => void;
|
||||
step: Step;
|
||||
step: IStep;
|
||||
};
|
||||
|
||||
function TestSubstep(props: TestSubstepProps): React.ReactElement {
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import * as React from 'react';
|
||||
import { Step } from 'types/step';
|
||||
import type { IStep } from '@automatisch/types';
|
||||
|
||||
export const StepExecutionsContext = React.createContext<Step[]>([]);
|
||||
export const StepExecutionsContext = React.createContext<IStep[]>([]);
|
||||
|
||||
type StepExecutionsProviderProps = {
|
||||
children: React.ReactNode;
|
||||
value: Step[];
|
||||
value: IStep[];
|
||||
}
|
||||
|
||||
export const StepExecutionsProvider = (props: StepExecutionsProviderProps): React.ReactElement => {
|
||||
|
@@ -8,6 +8,7 @@ export const CREATE_STEP = gql`
|
||||
key
|
||||
appKey
|
||||
parameters
|
||||
status
|
||||
connection {
|
||||
id
|
||||
}
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import type { IAuthenticationStep } from '@automatisch/types';
|
||||
import apolloClient from 'graphql/client';
|
||||
import MUTATIONS from 'graphql/mutations';
|
||||
import appConfig from 'config/app';
|
||||
@@ -7,14 +8,7 @@ enum AuthenticationSteps {
|
||||
OpenWithPopup = 'openWithPopup',
|
||||
}
|
||||
|
||||
type Step = {
|
||||
name: string;
|
||||
variables: Record<string, unknown>;
|
||||
process: (step: any, variables: Record<string, unknown>) => Promise<any>;
|
||||
type: AuthenticationSteps.Mutation | AuthenticationSteps.OpenWithPopup;
|
||||
};
|
||||
|
||||
const processMutation = async (step: Step, variables: Record<string, unknown>) => {
|
||||
const processMutation = async (step: IAuthenticationStep, variables: Record<string, unknown>) => {
|
||||
const mutation = MUTATIONS[step.name];
|
||||
const mutationResponse = await apolloClient.mutate({ mutation, variables });
|
||||
const responseData = mutationResponse.data[step.name];
|
||||
@@ -38,7 +32,7 @@ function getObjectOfEntries(iterator: any) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const processOpenWithPopup = (step: Step, variables: Record<string, string>) => {
|
||||
const processOpenWithPopup = (step: IAuthenticationStep, variables: Record<string, string>) => {
|
||||
return new Promise((resolve) => {
|
||||
const windowFeatures = 'toolbar=no, titlebar=no, menubar=no, width=500, height=700, top=100, left=100';
|
||||
const url = variables.url;
|
||||
@@ -62,7 +56,7 @@ const processOpenWithPopup = (step: Step, variables: Record<string, string>) =>
|
||||
});
|
||||
};
|
||||
|
||||
export const processStep = async (step: Step, variables: Record<string, string>): Promise<any> => {
|
||||
export const processStep = async (step: IAuthenticationStep, variables: Record<string, string>): Promise<any> => {
|
||||
if (step.type === AuthenticationSteps.Mutation) {
|
||||
return processMutation(step, variables);
|
||||
} else if (step.type === AuthenticationSteps.OpenWithPopup) {
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import template from 'lodash.template';
|
||||
import type { IAuthenticationStepField, IJSONObject } from '@automatisch/types';
|
||||
|
||||
const interpolate = /{([\s\S]+?)}/g;
|
||||
|
||||
@@ -6,18 +7,9 @@ type Variables = {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
type VariableSchema = {
|
||||
properties: VariableSchema[];
|
||||
name: string;
|
||||
type: 'string' | 'integer';
|
||||
value: string;
|
||||
}
|
||||
type IVariable = Omit<IAuthenticationStepField, "properties"> & Partial<Pick<IAuthenticationStepField, "properties">>;
|
||||
|
||||
type AggregatedData = {
|
||||
[key: string]: Record<string, unknown> | string;
|
||||
}
|
||||
|
||||
const computeAuthStepVariables = (variableSchema: VariableSchema[], aggregatedData: AggregatedData): Variables => {
|
||||
const computeAuthStepVariables = (variableSchema: IVariable[], aggregatedData: IJSONObject): IJSONObject => {
|
||||
const variables: Variables = {};
|
||||
|
||||
for (const variable of variableSchema) {
|
||||
@@ -27,11 +19,9 @@ const computeAuthStepVariables = (variableSchema: VariableSchema[], aggregatedDa
|
||||
continue;
|
||||
}
|
||||
|
||||
const computedVariable = template(variable.value, { interpolate })(aggregatedData);
|
||||
if (variable.value) {
|
||||
const computedVariable = template(variable.value, { interpolate })(aggregatedData);
|
||||
|
||||
if (variable.type === 'integer') {
|
||||
variables[variable.name] = parseInt(computedVariable, 10);
|
||||
} else {
|
||||
variables[variable.name] = computedVariable;
|
||||
}
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@ import { useQuery } from '@apollo/client';
|
||||
import Box from '@mui/material/Box';
|
||||
import Grid from '@mui/material/Grid';
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import type { IApp } from '@automatisch/types';
|
||||
|
||||
import ConditionalIconButton from 'components/ConditionalIconButton';
|
||||
import Container from 'components/Container';
|
||||
@@ -15,7 +16,6 @@ import SearchInput from 'components/SearchInput';
|
||||
import useFormatMessage from 'hooks/useFormatMessage'
|
||||
import { GET_CONNECTED_APPS } from 'graphql/queries/get-connected-apps';
|
||||
import * as URLS from 'config/urls';
|
||||
import type { App } from 'types/app';
|
||||
|
||||
export default function Applications(): React.ReactElement {
|
||||
const navigate = useNavigate();
|
||||
@@ -69,7 +69,7 @@ export default function Applications(): React.ReactElement {
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
{data?.getConnectedApps?.map((app: App) => (
|
||||
{data?.getConnectedApps?.map((app: IApp) => (
|
||||
<AppRow key={app.name} application={app} />
|
||||
))}
|
||||
|
||||
|
@@ -5,6 +5,7 @@ import { useQuery } from '@apollo/client';
|
||||
import Box from '@mui/material/Box';
|
||||
import Grid from '@mui/material/Grid';
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import type { IFlow } from '@automatisch/types';
|
||||
|
||||
import FlowRow from 'components/FlowRow';
|
||||
import ConditionalIconButton from 'components/ConditionalIconButton';
|
||||
@@ -14,14 +15,13 @@ import SearchInput from 'components/SearchInput';
|
||||
import useFormatMessage from 'hooks/useFormatMessage'
|
||||
import { GET_FLOWS } from 'graphql/queries/get-flows';
|
||||
import * as URLS from 'config/urls';
|
||||
import type { Flow } from 'types/flow';
|
||||
|
||||
export default function Flows(): React.ReactElement {
|
||||
const formatMessage = useFormatMessage();
|
||||
const [flowName, setFlowName] = React.useState('');
|
||||
const { data } = useQuery(GET_FLOWS);
|
||||
|
||||
const flows: Flow[] = data?.getFlows?.filter((flow: Flow) => flow.name?.toLowerCase().includes(flowName.toLowerCase()));
|
||||
const flows: IFlow[] = data?.getFlows?.filter((flow: IFlow) => flow.name?.toLowerCase().includes(flowName.toLowerCase()));
|
||||
|
||||
const onSearchChange = React.useCallback((event) => {
|
||||
setFlowName(event.target.value);
|
||||
|
@@ -1,40 +0,0 @@
|
||||
type AppFields = {
|
||||
key: string;
|
||||
name: string;
|
||||
label: string;
|
||||
type: string;
|
||||
required: boolean;
|
||||
readOnly: boolean;
|
||||
value: string;
|
||||
description: string;
|
||||
docUrl: string;
|
||||
clickToCopy: boolean;
|
||||
variables?: boolean;
|
||||
};
|
||||
|
||||
type AppConnection = {
|
||||
id: string;
|
||||
key: string;
|
||||
verified: boolean;
|
||||
createdAt: string;
|
||||
data: {
|
||||
[key: string]: any;
|
||||
};
|
||||
};
|
||||
|
||||
type App = {
|
||||
key: string;
|
||||
name: string;
|
||||
connectionCount: number;
|
||||
iconUrl: string;
|
||||
docUrl: string;
|
||||
primaryColor: string;
|
||||
fields: AppFields[];
|
||||
authenticationSteps: any[];
|
||||
reconnectionSteps: any[];
|
||||
triggers: any[];
|
||||
actions: any[];
|
||||
connections: AppConnection[];
|
||||
};
|
||||
|
||||
export type { App, AppFields, AppConnection };
|
@@ -1,13 +1,3 @@
|
||||
type ConnectionData = {
|
||||
screenName: string;
|
||||
}
|
||||
import type { IConnection, IJSONObject } from '@automatisch/types';
|
||||
|
||||
type Connection = {
|
||||
id: string;
|
||||
key: string;
|
||||
data: ConnectionData;
|
||||
verified?: boolean;
|
||||
createdAt: string;
|
||||
};
|
||||
|
||||
export type { Connection, ConnectionData };
|
||||
export type Connection = IConnection<IJSONObject>;
|
||||
|
@@ -1,8 +0,0 @@
|
||||
import type { Step } from './step';
|
||||
|
||||
export type Flow = {
|
||||
id: string;
|
||||
name: string;
|
||||
steps: Step[];
|
||||
active: boolean;
|
||||
};
|
@@ -1,25 +0,0 @@
|
||||
import type { AppFields } from './app';
|
||||
import type { Connection } from './connection';
|
||||
|
||||
export enum StepType {
|
||||
Trigger = 'trigger',
|
||||
Action = 'action',
|
||||
}
|
||||
|
||||
export type Step = {
|
||||
id: string;
|
||||
key: string | null;
|
||||
name: string;
|
||||
appKey: string | null;
|
||||
type: StepType;
|
||||
previousStepId: string | null;
|
||||
parameters: Record<string, unknown>;
|
||||
connection: Pick<Connection, 'id' | 'verified'>;
|
||||
status: 'completed' | 'incomplete';
|
||||
output: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export type Substep = {
|
||||
name: string;
|
||||
arguments: AppFields[];
|
||||
};
|
Reference in New Issue
Block a user