Skip to content

Commit

Permalink
fix(dashboard): workflow editor name change updates the workflow slug…
Browse files Browse the repository at this point in the history
… in the url (#7064)
  • Loading branch information
LetItRock authored Nov 19, 2024
1 parent 5afb77b commit f630919
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { useState } from 'react';
import * as z from 'zod';
import { useFormContext } from 'react-hook-form';
import { motion } from 'framer-motion';
import { useLayoutEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import * as z from 'zod';
// import { RiArrowRightSLine, RiSettingsLine } from 'react-icons/ri';

import { RouteFill } from '../icons';
import { Input, InputField } from '../primitives/input';
import { Separator } from '../primitives/separator';
Expand All @@ -18,14 +21,40 @@ import { SidebarContent, SidebarHeader } from '@/components/side-navigation/Side
import { PageMeta } from '../page-meta';
import { ConfirmationModal } from '../confirmation-modal';
import { PAUSE_MODAL_DESCRIPTION, PAUSE_MODAL_TITLE } from '@/utils/constants';
import { buildRoute, ROUTES } from '@/utils/routes';
import { useEnvironment } from '@/context/environment/hooks';

export function ConfigureWorkflow() {
const [isPauseModalOpen, setIsPauseModalOpen] = useState(false);
const tagsQuery = useTagsQuery();
const { isReadOnly } = useWorkflowEditorContext();
const { isReadOnly, workflow } = useWorkflowEditorContext();
const { currentEnvironment } = useEnvironment();
const { workflowSlug } = useParams<{ workflowSlug: string }>();
const navigate = useNavigate();
const [isBlurred, setIsBlurred] = useState(false);

const { control, watch, setValue } = useFormContext<z.infer<typeof workflowSchema>>();
const workflowName = watch('name');
const isWorkflowSlugChanged = workflow && workflow?.slug && workflowSlug !== workflow?.slug;
const shouldUpdateWorkflowSlug = isBlurred && isWorkflowSlugChanged;

useLayoutEffect(() => {
if (shouldUpdateWorkflowSlug) {
setTimeout(() => {
navigate(
buildRoute(ROUTES.EDIT_WORKFLOW, {
environmentSlug: currentEnvironment?.slug ?? '',
workflowSlug: workflow?.slug ?? '',
}),
{
replace: true,
state: { skipAnimation: true },
}
);
}, 0);
setIsBlurred(false);
}
}, [shouldUpdateWorkflowSlug, workflow?.slug, currentEnvironment?.slug, navigate]);

const onPauseWorkflow = () => {
setValue('active', false, { shouldValidate: true, shouldDirty: true });
Expand Down Expand Up @@ -100,7 +129,13 @@ export function ConfigureWorkflow() {
<FormLabel>Workflow Name</FormLabel>
<FormControl>
<InputField>
<Input placeholder="Untitled" {...field} disabled={isReadOnly} />
<Input
placeholder="New workflow"
{...field}
disabled={isReadOnly}
onFocus={() => setIsBlurred(false)}
onBlur={() => setIsBlurred(true)}
/>
</InputField>
</FormControl>
<FormMessage />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { StepTypeEnum } from '@novu/shared';
import { StepEditorContext } from './step-editor-context';
import { useFetchStep } from '@/hooks/use-fetch-step';
import { useWorkflowEditorContext } from '../hooks';
import { getStepBase62Id } from '@/utils/step';
import { getEncodedId, STEP_DIVIDER } from '@/utils/step';

export const StepEditorProvider = ({ children }: { children: ReactNode }) => {
const { workflowSlug = '', stepSlug = '' } = useParams<{
Expand All @@ -27,7 +27,12 @@ export const StepEditorProvider = ({ children }: { children: ReactNode }) => {
const navigationStepType = state?.stepType as StepTypeEnum | undefined;
const stepType = useMemo(
() =>
navigationStepType ?? workflow?.steps.find((el) => getStepBase62Id(el.slug) === getStepBase62Id(stepSlug))?.type,
navigationStepType ??
workflow?.steps.find(
(el) =>
getEncodedId({ slug: el.slug, divider: STEP_DIVIDER }) ===
getEncodedId({ slug: stepSlug, divider: STEP_DIVIDER })
)?.type,
[navigationStepType, stepSlug, workflow]
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useFormContext, useWatch } from 'react-hook-form';
import { useParams } from 'react-router-dom';
import * as z from 'zod';
import { workflowSchema } from '../schema';
import { getStepBase62Id } from '@/utils/step';
import { getEncodedId, STEP_DIVIDER } from '@/utils/step';

export const useStep = () => {
const { stepSlug = '' } = useParams<{
Expand All @@ -12,18 +12,18 @@ export const useStep = () => {

const { control } = useFormContext<z.infer<typeof workflowSchema>>();
const steps = useWatch({ name: 'steps', control });
const base62Id = getStepBase62Id(stepSlug);
const base62Id = getEncodedId({ slug: stepSlug, divider: STEP_DIVIDER });

const step = useMemo(() => {
if (Array.isArray(steps)) {
return steps.find((el) => getStepBase62Id(el.slug) === base62Id);
return steps.find((el) => getEncodedId({ slug: el.slug, divider: STEP_DIVIDER }) === base62Id);
}
return undefined;
}, [base62Id, steps]);

const stepIndex = useMemo(() => {
if (Array.isArray(steps)) {
return steps.findIndex((el) => getStepBase62Id(el.slug) === base62Id);
return steps.findIndex((el) => getEncodedId({ slug: el.slug, divider: STEP_DIVIDER }) === base62Id);
}
return -1;
}, [base62Id, steps]);
Expand Down
6 changes: 5 additions & 1 deletion apps/dashboard/src/hooks/use-fetch-step.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import type { StepDataDto } from '@novu/shared';
import { QueryKeys } from '@/utils/query-keys';
import { useEnvironment } from '@/context/environment/hooks';
import { fetchStep } from '@/api/steps';
import { getEncodedId, STEP_DIVIDER } from '@/utils/step';

export const useFetchStep = ({ workflowSlug, stepSlug }: { workflowSlug: string; stepSlug: string }) => {
const { currentEnvironment } = useEnvironment();
const stepId = useMemo(() => getEncodedId({ slug: stepSlug, divider: STEP_DIVIDER }), [stepSlug]);

const { data, isPending, isRefetching, error, refetch } = useQuery<StepDataDto>({
queryKey: [QueryKeys.fetchWorkflow, currentEnvironment?._id, workflowSlug, stepSlug],
queryKey: [QueryKeys.fetchWorkflow, currentEnvironment?._id, workflowSlug, stepId],
queryFn: () => fetchStep({ workflowSlug, stepSlug }),
enabled: !!currentEnvironment?._id && !!stepSlug,
});
Expand Down
9 changes: 8 additions & 1 deletion apps/dashboard/src/hooks/use-fetch-workflow.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import { useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import type { WorkflowResponseDto } from '@novu/shared';
import { QueryKeys } from '@/utils/query-keys';
import { fetchWorkflow } from '@/api/workflows';
import { useEnvironment } from '@/context/environment/hooks';
import { getEncodedId, WORKFLOW_DIVIDER } from '@/utils/step';

export const useFetchWorkflow = ({ workflowSlug }: { workflowSlug?: string }) => {
const { currentEnvironment } = useEnvironment();
const workflowId = useMemo(
() => getEncodedId({ slug: workflowSlug ?? '', divider: WORKFLOW_DIVIDER }),
[workflowSlug]
);

const { data, isPending, error } = useQuery<WorkflowResponseDto>({
queryKey: [QueryKeys.fetchWorkflow, currentEnvironment?._id, workflowSlug],
queryKey: [QueryKeys.fetchWorkflow, currentEnvironment?._id, workflowId],
queryFn: () => fetchWorkflow({ workflowSlug }),
enabled: !!currentEnvironment?._id && !!workflowSlug,
});
Expand Down
14 changes: 11 additions & 3 deletions apps/dashboard/src/hooks/use-update-workflow.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query';
import type { WorkflowResponseDto } from '@novu/shared';
import { updateWorkflow } from '@/api/workflows';
import { useEnvironment } from '@/context/environment/hooks';
import { QueryKeys } from '@/utils/query-keys';
import type { WorkflowResponseDto } from '@novu/shared';
import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query';
import { getEncodedId, WORKFLOW_DIVIDER } from '@/utils/step';

export const useUpdateWorkflow = (
options?: UseMutationOptions<WorkflowResponseDto, unknown, Parameters<typeof updateWorkflow>[0]>
Expand All @@ -14,7 +15,14 @@ export const useUpdateWorkflow = (
mutationFn: updateWorkflow,
...options,
onSuccess: async (data, variables, context) => {
await queryClient.setQueryData([QueryKeys.fetchWorkflow, currentEnvironment?._id, data.slug], data);
await queryClient.setQueryData(
[
QueryKeys.fetchWorkflow,
currentEnvironment?._id,
getEncodedId({ slug: data.slug, divider: WORKFLOW_DIVIDER }),
],
data
);
options?.onSuccess?.(data, variables, context);
},
});
Expand Down
7 changes: 4 additions & 3 deletions apps/dashboard/src/utils/step.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { ShortIsPrefixEnum, StepResponseDto } from '@novu/shared';
import { ShortIsPrefixEnum } from '@novu/shared';

const divider = `_${ShortIsPrefixEnum.STEP}`;
export const WORKFLOW_DIVIDER = `_${ShortIsPrefixEnum.WORKFLOW}`;
export const STEP_DIVIDER = `_${ShortIsPrefixEnum.STEP}`;

export const getStepBase62Id = (slug: StepResponseDto['slug'] | string = divider) => {
export const getEncodedId = ({ slug, divider }: { slug: string; divider: string }) => {
const parts = slug.split(divider);
return parts[parts.length - 1];
};

0 comments on commit f630919

Please sign in to comment.