-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(dashboard): add delay step #7131
base: next
Are you sure you want to change the base?
Conversation
✅ Deploy Preview for novu-stg-vite-dashboard-poc ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
apps/dashboard/src/components/workflow-editor/add-step-menu.tsx
Outdated
Show resolved
Hide resolved
apps/dashboard/src/components/workflow-editor/steps/delay/delay-configure.tsx
Outdated
Show resolved
Hide resolved
...cation-generic/src/usecases/tier-restrictions-validate/tier-restrictions-validate.usecase.ts
Show resolved
Hide resolved
}; | ||
|
||
export const ConfigureStepInlineForm = (props: ConfigureStepInlineFormProps) => { | ||
const { workflow, step, issues, update, updateStepCache } = props; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are drilling the props quite deep, we should think about using the hooks here, but I left it like this for consistency.
/** | ||
* We need to get the issues from the workflow response | ||
* because the step is not re-fetched when workflow is updated | ||
* | ||
* 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]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fact that we update both step and workflow with one endpoint, but fetch the updated data from 2 endpoints causes a lot of issues regarding stale data, caching etc etc.
We should fix this asap by fetching everything from workflows response as I suggested here in the comment or some other solution.
LaunchDarkly flag references🔍 1 flag added or modified
|
@novu/client
@novu/framework
@novu/js
@novu/headless
@novu/nextjs
@novu/node
@novu/notification-center
novu
@novu/providers
@novu/react
@novu/react-native
@novu/shared
commit: |
|
||
export type StepEditorContextType = { | ||
isPending: boolean; | ||
step?: StepDataDto; | ||
refetch: (options?: RefetchOptions) => Promise<QueryObserverResult<StepDataDto, Error>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I strongly suggest decoupling the form logic from the form wrapper. That is, the form of every step editor should work both in the first side bar or the second sidebar.
Currently, I noticed a lot of duplication between the template form and the inline form. Introducing a StepForm component to host the form handling that is reused from the different sidebar containers should simplify the logic drastically.
isReadOnly?: boolean; | ||
}; | ||
|
||
export const NumberInputWithSelect = ({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
export const NumberInputWithSelect = ({ | |
export const DurationInput = ({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its a generic component not necessarily a duration, it can be also 10 horses
import { useMemo } from 'react'; | ||
|
||
type InputWithSelectProps = { | ||
fields: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nested in props is always 👿 . how about using two flat props?
unit: 'seconds' | 'minutes' | 'hours' | 'months'
amount: number
This should simplify the logic of the handleChange a lot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SokratisVidros this is what we agreed before with @desiprisg and we use this pattern in other places where the component is using two form fields
selectKey: string; | ||
}; | ||
options: string[]; | ||
defaultOption?: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the default option prop? The unit prop should be the default option otherwise its defaultOption[0]
.
placeholder, | ||
isReadOnly, | ||
}: InputWithSelectProps) => { | ||
const { getFieldState, setValue, getValues, control } = useFormContext(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest making the DurationInput a primitive and then wiring it to the RHF either in workflow editor or with a wrapper component under /components/workflow-editor if necessary.
It will give us way more flexibility and make the component reusable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wrapper component already exists. See here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we can do something about it because this component uses the two form fields, check the FormField
usage.
import { SaveFormContext } from '@/components/workflow-editor/steps/save-form-context'; | ||
import { DelayForm } from '@/components/workflow-editor/steps/delay/delay-form'; | ||
|
||
const STEP_TYPE_TO_INLINE_FORM: Record<StepTypeEnum, (args: StepInlineFormProps) => React.JSX.Element | null> = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code along with calculateDefaultValues
is duplicated between this new component and configure-step-template-form.tsx
We need to make it dry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree.
Also, it will result in the form nested under another form, which we wanted to avoid.
The configure-step-form
should just register all the fields under the controls
in the form I guess, because this is the shape of the step
and that will be updated later with using the update workflow
endpoint.
{
"name": "In-App Step",
"stepId": "some-step-id",
"controls": { ... }
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Later here we will also need to connect custom step controls
from the code created workflows.
import { useMemo } from 'react'; | ||
|
||
type InputWithSelectProps = { | ||
fields: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SokratisVidros this is what we agreed before with @desiprisg and we use this pattern in other places where the component is using two form fields
placeholder, | ||
isReadOnly, | ||
}: InputWithSelectProps) => { | ||
const { getFieldState, setValue, getValues, control } = useFormContext(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we can do something about it because this component uses the two form fields, check the FormField
usage.
@@ -73,6 +75,7 @@ export const AddStepMenu = ({ | |||
onMenuItemClick: (stepType: StepTypeEnum) => void; | |||
}) => { | |||
const [isPopoverOpen, setIsPopoverOpen] = useState(false); | |||
const isDelayDigestEmailEnabled = useFeatureFlag(FeatureFlagsKeysEnum.IS_ND_DELAY_DIGEST_EMAIL_ENABLED); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what ND
means? new dashboard?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
import { SaveFormContext } from '@/components/workflow-editor/steps/save-form-context'; | ||
import { DelayForm } from '@/components/workflow-editor/steps/delay/delay-form'; | ||
|
||
const STEP_TYPE_TO_INLINE_FORM: Record<StepTypeEnum, (args: StepInlineFormProps) => React.JSX.Element | null> = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree.
Also, it will result in the form nested under another form, which we wanted to avoid.
The configure-step-form
should just register all the fields under the controls
in the form I guess, because this is the shape of the step
and that will be updated later with using the update workflow
endpoint.
{
"name": "In-App Step",
"stepId": "some-step-id",
"controls": { ... }
}
import { SaveFormContext } from '@/components/workflow-editor/steps/save-form-context'; | ||
import { DelayForm } from '@/components/workflow-editor/steps/delay/delay-form'; | ||
|
||
const STEP_TYPE_TO_INLINE_FORM: Record<StepTypeEnum, (args: StepInlineFormProps) => React.JSX.Element | null> = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Later here we will also need to connect custom step controls
from the code created workflows.
What changed? Why was the change needed?
Current know issues:
Added logic for control value forms which are on the first sidebar:
wf_delay_step.mp4