Skip to content

Commit

Permalink
feat(dashboard): get step issues from workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
ChmaraX committed Dec 3, 2024
1 parent ef822ac commit 4c59b6f
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { useCallback, useEffect, useMemo } from 'react';
import merge from 'lodash.merge';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { type StepDataDto, StepTypeEnum, UpdateWorkflowDto, type WorkflowResponseDto } from '@novu/shared';
import type { StepDataDto, StepIssuesDto, UpdateWorkflowDto, WorkflowResponseDto } from '@novu/shared';
import { StepTypeEnum } from '@novu/shared';

import { flattenIssues, updateStepControlValuesInWorkflow } from '@/components/workflow-editor/step-utils';
import { buildDefaultValues, buildDefaultValuesOfDataSchema, buildDynamicZodSchema } from '@/utils/schema';
Expand Down Expand Up @@ -38,12 +39,13 @@ export type StepInlineFormProps = {
};

type ConfigureStepInlineFormProps = StepInlineFormProps & {
issues?: StepIssuesDto;
update: (data: UpdateWorkflowDto) => void;
updateStepCache: (step: Partial<StepDataDto>) => void;
};

export const ConfigureStepInlineForm = (props: ConfigureStepInlineFormProps) => {
const { workflow, step, update, updateStepCache } = props;
const { workflow, step, issues, update, updateStepCache } = props;
const schema = useMemo(() => buildDynamicZodSchema(step.controls.dataSchema ?? {}), [step.controls.dataSchema]);

const defaultValues = useMemo(() => {
Expand All @@ -66,11 +68,11 @@ export const ConfigureStepInlineForm = (props: ConfigureStepInlineFormProps) =>
});

const setIssuesFromStep = useCallback(() => {
const stepIssues = flattenIssues(step.issues?.controls);
const stepIssues = flattenIssues(issues?.controls);
Object.entries(stepIssues).forEach(([key, value]) => {
form.setError(key as string, { message: value });
});
}, [form, step]);
}, [form, issues]);

useEffect(() => {
setIssuesFromStep();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { zodResolver } from '@hookform/resolvers/zod';
import { IEnvironment, StepDataDto, UpdateWorkflowDto, WorkflowOriginEnum, WorkflowResponseDto } from '@novu/shared';
import {
IEnvironment,
StepDataDto,
StepIssuesDto,
UpdateWorkflowDto,
WorkflowOriginEnum,
WorkflowResponseDto,
} from '@novu/shared';
import { motion } from 'motion/react';
import { useMemo, useState } from 'react';
import { useForm } from 'react-hook-form';
Expand Down Expand Up @@ -38,12 +45,13 @@ type ConfigureStepFormProps = {
workflow: WorkflowResponseDto;
environment: IEnvironment;
step: StepDataDto;
issues?: StepIssuesDto;
update: (data: UpdateWorkflowDto) => void;
updateStepCache: (step: Partial<StepDataDto>) => void;
};

export const ConfigureStepForm = (props: ConfigureStepFormProps) => {
const { step, workflow, update, updateStepCache, environment } = props;
const { step, workflow, update, updateStepCache, environment, issues } = props;

const isSupportedStep = !UNSUPPORTED_STEP_TYPES.includes(step.type);
const isReadOnly = !isSupportedStep || workflow.origin === WorkflowOriginEnum.EXTERNAL;
Expand Down Expand Up @@ -162,7 +170,13 @@ export const ConfigureStepForm = (props: ConfigureStepFormProps) => {
<Separator />

{isInlineConfigurableStep && (
<InlineConfigurableStep workflow={workflow} step={step} update={update} updateStepCache={updateStepCache} />
<InlineConfigurableStep
workflow={workflow}
step={step}
issues={issues}
update={update}
updateStepCache={updateStepCache}
/>
)}

{isTemplateConfigurableStep && <TemplateConfigurableStep step={step} firstError={firstError} />}
Expand Down Expand Up @@ -229,18 +243,26 @@ const TemplateConfigurableStep = ({ step, firstError }: { step: StepDataDto; fir
const InlineConfigurableStep = ({
workflow,
step,
issues,
update,
updateStepCache,
}: {
workflow: WorkflowResponseDto;
step: StepDataDto;
issues?: StepIssuesDto;
update: (data: UpdateWorkflowDto) => void;
updateStepCache: (step: Partial<StepDataDto>) => void;
}) => {
return (
<>
<SidebarContent>
<ConfigureStepInlineForm workflow={workflow} step={step} update={update} updateStepCache={updateStepCache} />
<ConfigureStepInlineForm
workflow={workflow}
step={step}
issues={issues}
update={update}
updateStepCache={updateStepCache}
/>
</SidebarContent>
<Separator />
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,13 @@ export type StepEditorProps = {
};

type ConfigureStepTemplateFormProps = StepEditorProps & {
issues?: StepIssuesDto;
update: (data: UpdateWorkflowDto) => void;
updateStepCache: (step: Partial<StepDataDto>) => void;
};

export const ConfigureStepTemplateForm = (props: ConfigureStepTemplateFormProps) => {
const { workflow, step, update, updateStepCache } = props;
const { workflow, step, update, updateStepCache, issues } = props;
const schema = useMemo(() => buildDynamicZodSchema(step.controls.dataSchema ?? {}), [step.controls.dataSchema]);

const defaultValues = useMemo(() => {
Expand All @@ -73,11 +74,11 @@ export const ConfigureStepTemplateForm = (props: ConfigureStepTemplateFormProps)
});

const setIssuesFromStep = useCallback(() => {
const stepIssues = flattenIssues(step.issues?.controls);
const stepIssues = flattenIssues(issues?.controls);
Object.entries(stepIssues).forEach(([key, value]) => {
form.setError(key as string, { message: value });
});
}, [form, step]);
}, [form, issues]);

useEffect(() => {
setIssuesFromStep();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const transitionSetting = { ease: [0.29, 0.83, 0.57, 0.99], duration: 0.4 };
export const ConfigureStepTemplate = () => {
const navigate = useNavigate();
const { workflow, update } = useWorkflow();
const { step, updateStepCache } = useStep();
const { step, updateStepCache, issues } = useStep();
const handleCloseSheet = () => {
navigate('..', { relative: 'path' });
};
Expand Down Expand Up @@ -71,6 +71,7 @@ export const ConfigureStepTemplate = () => {
<ConfigureStepTemplateForm
workflow={workflow}
step={step}
issues={issues}
update={update}
updateStepCache={updateStepCache}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useWorkflow } from '@/components/workflow-editor/workflow-provider';
import { useEnvironment } from '@/context/environment/hooks';

export const ConfigureStep = () => {
const { step, updateStepCache } = useStep();
const { step, updateStepCache, issues } = useStep();
const { workflow, update } = useWorkflow();
const { currentEnvironment } = useEnvironment();

Expand All @@ -19,6 +19,7 @@ export const ConfigureStep = () => {
environment={currentEnvironment}
update={update}
updateStepCache={updateStepCache}
issues={issues}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,54 @@ import { createContext, useMemo, type ReactNode } from 'react';
import { useParams } from 'react-router-dom';

import { useFetchStep } from '@/hooks/use-fetch-step';
import { StepDataDto, StepTypeEnum } from '@novu/shared';
import { QueryObserverResult, RefetchOptions } from '@tanstack/react-query';
import { StepDataDto, StepIssuesDto, StepTypeEnum } from '@novu/shared';
import { createContextHook } from '@/utils/context';
import { Step } from '@/utils/types';
import { STEP_DIVIDER } from '@/utils/step';
import { getEncodedId } from '@/utils/step';
import { useWorkflow } from '@/components/workflow-editor/workflow-provider';

export type StepEditorContextType = {
isPending: boolean;
step?: StepDataDto;
refetch: (options?: RefetchOptions) => Promise<QueryObserverResult<StepDataDto, Error>>;
issues?: StepIssuesDto;
updateStepCache: (step: Partial<StepDataDto>) => void;
};

export const StepContext = createContext<StepEditorContextType>({} as StepEditorContextType);

export const StepProvider = ({ children }: { children: ReactNode }) => {
const { workflow } = useWorkflow();
const { stepSlug = '', workflowSlug = '' } = useParams<{
workflowSlug: string;
stepSlug: string;
}>();
const { step, isPending, refetch, updateStepCache } = useFetchStep({
const { step, isPending, updateStepCache } = useFetchStep({
workflowSlug,
stepSlug,
});

/**
* We need to get the issues from the workflow response
* because the step is not refetched when workflow is updated

Check warning on line 34 in apps/dashboard/src/components/workflow-editor/steps/step-provider.tsx

View workflow job for this annotation

GitHub Actions / Spell check

Unknown word (refetched)
*
* TODO:
* 1. add all step data to workflow response
* 2. remove StepProvider and keep just the WorkflowProvider with step value
*/
const issues = useMemo(() => {
const newIssues = workflow?.steps.find(
(s) =>
getEncodedId({ slug: s.slug, divider: STEP_DIVIDER }) ===
getEncodedId({ slug: stepSlug, divider: STEP_DIVIDER })
)?.issues;

return { ...newIssues };
}, [workflow, stepSlug]);

const value = useMemo(
() => ({ isPending, step, refetch, updateStepCache }),
[isPending, step, refetch, updateStepCache]
() => ({ isPending, step, issues, updateStepCache }),
[isPending, step, issues, updateStepCache]
);

return <StepContext.Provider value={value}>{children}</StepContext.Provider>;
Expand Down
3 changes: 1 addition & 2 deletions apps/dashboard/src/hooks/use-fetch-step.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const useFetchStep = ({ workflowSlug, stepSlug }: { workflowSlug: string;
[currentEnvironment?._id, workflowSlug, stepSlug]
);

const { data, isPending, isRefetching, error, refetch } = useQuery<StepDataDto>({
const { data, isPending, isRefetching, error } = useQuery<StepDataDto>({
queryKey,
queryFn: () => fetchStep({ workflowSlug: workflowSlug, stepSlug: stepSlug }),
enabled: !!currentEnvironment?._id && !!stepSlug && !!workflowSlug,
Expand All @@ -37,7 +37,6 @@ export const useFetchStep = ({ workflowSlug, stepSlug }: { workflowSlug: string;
isPending,
isRefetching,
error,
refetch,
updateStepCache,
};
};

0 comments on commit 4c59b6f

Please sign in to comment.