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

fix(web): fixed the template editor react-hook-form dirty state #2674

Merged
merged 7 commits into from Feb 7, 2023

Conversation

LetItRock
Copy link
Contributor

@LetItRock LetItRock commented Feb 3, 2023

What change does this PR introduce?

Notification Template Editor - fixed the react-hook-form dirty state issue, which was causing the create/update button to not work properly.

The changes:

  • refactored code and moved the logic to context
  • applied the default values for the fields
  • changed the form controllers to not point to values that are objects, arrays
  • fixed issues with variable management

Why was this change needed?

Other information (Screenshots)

Screen.Recording.2023-02-03.at.03.51.33.mov

@LetItRock LetItRock self-assigned this Feb 3, 2023
@linear
Copy link

linear bot commented Feb 3, 2023

NV-1587 Changes made prompt shouldn't be shown

To reproduce:

  • Visit a saved template
  • Go to existing step edit screen
  • Go back to the workflow page
  • Click on Test Workflow
  • A prompt is shown even when I haven't done any change.

@ghost
Copy link

ghost commented Feb 3, 2023

👇 Click on the image for a new way to code review
  • Make big changes easier — review code in small groups of related files

  • Know where to start — see the whole change at a glance

  • Take a code tour — explore the change with an interactive tour

  • Make comments and review — all fully sync’ed with github

    Try it now!

Review these changes using an interactive CodeSee Map

Legend

CodeSee Map Legend

@@ -103,7 +103,7 @@ function createNotification() {

cy.getByTestId('emailSubject').type('this is email subject');

cy.getByTestId('submit-btn').click();
cy.getByTestId('notification-template-submit-btn').click();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

template editor: renamed the data-test-id name for the Create/Update button

@@ -37,6 +37,7 @@
"@emotion/react": "^11.7.1",
"@emotion/styled": "^11.6.0",
"@handlebars/parser": "^2.1.0",
"@hookform/devtools": "^4.3.0",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

added this library to debug the react-hook-form

@@ -77,6 +78,7 @@
"lodash.clonedeep": "^4.5.0",
"lodash.get": "^4.3.2",
"lodash.set": "^4.3.2",
"lodash.isequal": "^4.5.0",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

added this library to compare the variables arrays when parsing template fields, more about that later

import { ActivePageEnum } from '../../pages/templates/editor/TemplateEditorPage';
import { TemplatePushEditor } from './TemplatePushEditor';
import { TemplateChatEditor } from './chat-editor/TemplateChatEditor';

export const TemplateEditor = ({ activePage, templateId, activeStep }) => {
const { integrations } = useActiveIntegrations();
const { control, errors, watch } = useTemplateController(templateId);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refactored this hook, there is no sense to hold the react-hook-form functionality inside, instead better to use useFormContext directly as we do in many other places.

Comment on lines -10 to -40
const reducer = (state, action) => {
switch (action.type) {
case actionEditMode:
return {
...state,
editMode: action.payload,
};
case actionIsDirty:
return {
...state,
isDirty: action.payload,
};
case actionIsEmbedModalVisible:
return {
...state,
isEmbedModalVisible: action.payload,
};
case actionTrigger:
return {
...state,
trigger: action.payload,
};
case actionCreatedTemplateId:
return {
...state,
createdTemplateId: action.payload,
};
default:
throw new Error('Unspecified reducer action');
}
};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed the reducer from here, some of the actions were not used, so I've replaced it with the useState


export const ReplyCallback = ({ control, index, errors }) => {
const { environment } = useEnvController();
const { getValues } = useFormContext();
const replyCallbackActive = getValues(`steps.${index}.replyCallback.active`);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

getValues only have an acces to the value during the render, but it doesn't listen to the value changes

@@ -90,7 +89,7 @@ export function SelectedStep({
<Divider my={30} />
{steps.map((i, index) => {
return (
<When truthy={index === activeStep}>
<When key={index} truthy={index === activeStep}>
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 the react warning in the console

Comment on lines +223 to +227
const FilterButton = styled(Button)`
background: ${({ theme }) => (theme.colorScheme === 'dark' ? colors.B20 : colors.white)};
box-shadow: 0px 5px 20px rgb(0 0 0 / 20%);
:hover {
background-color: ${({ dark }) => (dark ? colors.B20 : colors.white)};
background-color: ${({ theme }) => (theme.colorScheme === 'dark' ? colors.B20 : colors.white)};
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 another react warning in the console

return (
<When truthy={index === activeStep}>
<When key={step._id || step.id} truthy={index === activeStep}>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

another react warning

Comment on lines +45 to +52
variables: [
{
defaultValue: '',
name: 'firstName',
required: false,
type: 'String',
},
],
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added the missing variables array, after I've fixed all the variable management issues the tests were not passing because of this causing the form to be dirty.

Copy link
Contributor

@p-fernandez p-fernandez left a comment

Choose a reason for hiding this comment

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

🌟
Great great job. Very good decisions. 👏🏻

},
});
setTrigger(response.triggers[0]);
reset(data);
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the reason that here we reset the data but in line 217 we reset the payloadToCreate? I would expect data to be reset in both. What am I missing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

not sure, it was like that before... I feel it doesn't have an impact on the form at all because after creation we redirect the user to the /templates route

@@ -27,7 +26,7 @@ export function EmailContentCard({
const { readonly } = useEnvController();
const { control, setValue, watch } = useFormContext(); // retrieve all hook methods
const contentType = watch(`steps.${index}.template.contentType`);
const [activeTab, setActiveTab] = useState<string | null>(EDITOR);
const activeTab = contentType === 'customHtml' ? CUSTOM_CODE : EDITOR;
Copy link
Contributor

Choose a reason for hiding this comment

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

Time ago I created a type MessageTemplateContentType that holds customHtml and editor. I think I should convert it to an enum and be used in situations like here. What would it be your take on that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, I saw that one, but obviously couldn't use it here, so I went the easiest way 🥲 but saw couple more places where it might be useful

@ainouzgali
Copy link
Contributor

@LetItRock This is such amazing work! This will improve significantly user experience and sooo many bugs. Yay!
Can this be merged? Or are you still working on it?

Copy link
Contributor

@ainouzgali ainouzgali left a comment

Choose a reason for hiding this comment

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

🚀

@LetItRock LetItRock merged commit d08f3be into next Feb 7, 2023
@LetItRock LetItRock deleted the nv-1587-template-editor-react-hook-form-fix branch February 7, 2023 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants