Skip to content
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

Add workflow email action #7279

Merged
merged 13 commits into from
Oct 1, 2024
Merged

Add workflow email action #7279

merged 13 commits into from
Oct 1, 2024

Conversation

Devessier
Copy link
Contributor

@Devessier Devessier commented Sep 27, 2024

  • Add the SAVE_EMAIL action. This action requires more setting parameters than the Serverless Function action.
  • Changed the way we computed the workflow diagram. It now preserves some properties, like the selected property. That's necessary to not close the right drawer when the workflow back-end data change.
  • Added the possibility to set a label to a TextArea. This uses a <label> HTML element and the useId() hook to create an id linking the label with the input.

@Devessier Devessier marked this pull request as ready for review September 27, 2024 16:06
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Summary

This pull request introduces significant enhancements to the workflow system, particularly focusing on adding a new 'SEND_EMAIL' action type. Here's a concise summary of the major changes:

  • Implemented a new 'SEND_EMAIL' action type with dedicated components for editing email actions
  • Enhanced the TextArea component with label support, improving accessibility
  • Refactored the workflow diagram generation and merging process to preserve UI state
  • Updated the WorkflowDiagramStepNode to visually distinguish between different action types
  • Introduced a reusable WorkflowEditActionFormBase component for consistent action form layouts
  • Added unit tests for the new mergeWorkflowDiagrams function to ensure correct functionality

These changes significantly expand the capabilities of the workflow system while improving code modularity and maintainability.

17 file(s) reviewed, 7 comment(s)
Edit PR Review Bot Settings

Comment on lines +100 to +103
value={value}
onChange={(event) =>
onChange?.(turnIntoEmptyStringIfWhitespacesOnly(event.target.value))
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider memoizing this onChange callback to prevent unnecessary re-renders

Comment on lines +80 to +84
onChange={(email) => {
field.onChange(email);

handleSave();
}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: onChange prop receives 'email' but it's actually the subject. Rename for clarity

Comment on lines +98 to +102
onChange={(email) => {
field.onChange(email);

handleSave();
}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: onChange prop receives 'email' but it's actually the body. Rename for clarity

Comment on lines +36 to +38
subject: 'hello',
title: 'hello',
template: '{{title}}',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider using more descriptive placeholder values for subject, title, and template

Comment on lines +35 to +47
settings: {
subject: 'hello',
title: 'hello',
template: '{{title}}',
errorHandlingOptions: {
continueOnFailure: {
value: false,
},
retryOnFailure: {
value: false,
},
},
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Email recipient information is missing from the default settings

const nodeWithPreservedProperties = nodePropertiesToPreserve.reduce(
(nodeToSet, propertyToPreserve) => {
return Object.assign(nodeToSet, {
[propertyToPreserve]: previousNode?.[propertyToPreserve],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: This may overwrite nextNode properties if they exist in nodePropertiesToPreserve. Ensure this is the intended behavior

Copy link
Contributor

@thomtrp thomtrp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work 🔥

Just a couple of comments. Also, to avoid spreading switch everywhere, could you put those into utils. So you can put all utils into the workflow folder

@@ -57,6 +73,8 @@ export const TextArea = ({
}: TextAreaProps) => {
const computedMinRows = Math.min(minRows, MAX_ROWS);

const inputId = useId();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we usually use v4(). Do we need an id that is not an uuid maybe?

Copy link
Contributor Author

@Devessier Devessier Sep 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I documented this change in my issue about using real <label> HTML elements for inputs. (#7281)

I saw that a UUID v4 was generated in a render function to serve as an input id:

UUIDs are expensive to compute as cryptographically secure identifiers with low collision probabilities. However, these properties aren't necessary for an input's ID.

It's also better to have a consistent identifier that doesn't change every time. Assistive technologies like screen readers will behave better with a consistent identifier.

Furthermore, generating a UUID in a render function will re-compute it every time the component is rendered. As generating a UUID comes with a cost, it's better to either memoize it or not use an UUID.

The new useId() React hook returns a short and memoized ID with no collision probability. It also works well with server-side rendering, as the ID will be the same whether the component is rendered client-side or server-side.

It's important to mention that I only recommend using the useId() hook to generate DOM identifiers, like an input id. The useId() hook is not meant to generate other kinds of identifiers best served with a UUID v4.

/>
);
if (stepDefinition.type === 'action') {
if (stepDefinition.definition.type === 'CODE') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use a switch, we will add more types soon

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you use the type from packages/twenty-front/src/modules/workflow/constants/Actions.ts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will work on that tomorrow. Thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed 👍

@@ -26,6 +26,27 @@ export const getStepDefaultDefinition = (
},
};
}
case 'SEND_EMAIL': {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

packages/twenty-front/src/modules/workflow/utils/getStepDefaultDefinition.ts should be suffixed with .util.ts

@@ -33,11 +33,25 @@ export const WorkflowDiagramStepNode = ({
);
}
case 'action': {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be moved into an util next to the others

onTriggerUpdate={updateTrigger}
/>
);
switch (stepDefinition.type) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

@@ -0,0 +1,3 @@
export const assertUnreachable = (x: never, errorMessage?: string): never => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Devessier Devessier merged commit cde255a into main Oct 1, 2024
7 of 13 checks passed
@Devessier Devessier deleted the add-workflow-email-action branch October 1, 2024 12:22
Copy link

github-actions bot commented Oct 1, 2024

Thanks @Devessier for your contribution!
This marks your 10th PR on the repo. You're top 3% of all our contributors 🎉
See contributor page - Share on LinkedIn - Share on Twitter

Contributions

harshit078 pushed a commit to harshit078/twenty that referenced this pull request Oct 14, 2024
- Add the SAVE_EMAIL action. This action requires more setting
parameters than the Serverless Function action.
- Changed the way we computed the workflow diagram. It now preserves
some properties, like the `selected` property. That's necessary to not
close the right drawer when the workflow back-end data change.
- Added the possibility to set a label to a TextArea. This uses a
`<label>` HTML element and the `useId()` hook to create an id linking
the label with the input.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants