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

Connection Form Refactor - Connection Form Service #15893

Merged
merged 64 commits into from
Sep 19, 2022

Conversation

krishnaglick
Copy link
Contributor

@krishnaglick krishnaglick commented Aug 23, 2022

Closes #15603

What

The Connection Create/Edit code is a dense and complex jungle. This is first portion of work to simplify it, and increase maintainability.

#16293 and #16303 spun out of this work as ways to improve the reliability and readability of existing code.

Recommended reading order

Start with:

  • airbyte-webapp/src/views/Connection/ConnectionForm/ConnectionForm.tsx
  • airbyte-webapp/src/hooks/services/Connection/ConnectionFormService.tsx
    There was a lot of logic wrapped up in the ConnectionForm. It contains the Formik form, handled passing the dirty state up VIA an ugly chain of logic, coordinated the submit & afterSubmit logic, and a few other misc things. Plus it handled various bits of prop drilling. A lot of this was moved into the ConnectionFormService which keeps us from prop drilling, and separates helps keep the render logic separate.

Then:

  • airbyte-webapp/src/pages/ConnectionPage/pages/ConnectionItemPage/components/ReplicationView.tsx
  • airbyte-webapp/src/components/CreateConnectionContent/CreateConnectionContent.tsx

These two components will likely see greater change in the next PR in this series. There was a lot of back-and-forth with the ConnectionForm:

  • CreateConnectionContent prop-drilled the onSelectFrequency analytics call
  • CreateConnectionContent's onSubmitConnectionStep returned a method to be called afterSubmit in what I felt was an awkward way. This has been streamlined.
  • ReplicationView previously had an awkward, upwards chained bit of tracking to determine if a form is dirty. Now it just utilizes the global form dirty tracking and all that messy logic has been removed.
    There were a few other changes, like the onSubmit returning { submitCancelled: true } now utilizes its try/catch, and both components get to do less prop drilling.

After #16293 and #16303 are merged this diff will look cleaner, but there's various components like StreamHeader.tsx where instead of getting a value from its props, it's just pulling it out of the context.
Lastly there's some testing that's worth looking over!

One final note is OperationsSection.tsx had a Wrapper prop passed in. That's been cleaned up to just import the appropriate wrapping components.

🚨 User Impact 🚨

This work touches the major pieces of our Connection Create and Edit pages. They're quite touchy and core to the application so this potentially has a large user impact if bugs are introduced so please test carefully!

@github-actions github-actions bot added area/platform issues related to the platform area/frontend Related to the Airbyte webapp labels Aug 23, 2022
@krishnaglick krishnaglick marked this pull request as ready for review August 24, 2022 19:50
@krishnaglick krishnaglick requested a review from a team as a code owner August 24, 2022 19:50
Comment on lines 94 to 95
onFrequencySelect,
onCancel,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are in here to prevent prop-drilling.

@krishnaglick krishnaglick force-pushed the kc/connection-form-refactor branch from 9869327 to bf6a647 Compare August 24, 2022 19:59
@teallarson
Copy link
Contributor

Looks like the field for Connection Name input disappeared during connection creation.

@krishnaglick
Copy link
Contributor Author

Looks like the field for Connection Name input disappeared during connection creation.

Should be fixed!

Copy link
Contributor

@teallarson teallarson left a comment

Choose a reason for hiding this comment

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

Test it Day Doc looks good. Testing and code look good.

This should have two PR approvals before merge though.

Copy link
Contributor

@edmundito edmundito left a comment

Choose a reason for hiding this comment

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

Finally got around to doing another pass.

Comment on lines 103 to 104
const changedForms = useChangedFormsById();
const formDirty = useMemo(() => !!changedForms?.[0]?.[formId], [changedForms, formId]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Good alternative to tracking the state of the form without all that extra stuff!

Would this be cleaner? The useChangedFormsById behaves similar to a useState:

Suggested change
const changedForms = useChangedFormsById();
const formDirty = useMemo(() => !!changedForms?.[0]?.[formId], [changedForms, formId]);
const [changedFormsById] = useChangedFormsById();
const formDirty = useMemo(() => !!changedFormsById?.[formId], [changedForms, formId]);

// We only want to go to the new connection if we _do not_ have an after submit action.
if (!afterSubmitConnection) {
// We have to clear the form change to prevent the dirty-form tracking modal from appearing.
clearFormChange(formId);
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks too high in the component tree and should be called from the Connection form. The reason is that the ConnectionForm sets up the ConnectionChangeTracker, and should be responsible for clearing it after submission. In this case, this component, which has no idea what the form does, assumes that the tracker is being used.

Copy link
Contributor

Choose a reason for hiding this comment

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

The next PR brings the FormikContext "out" a layer at which point this would be the right place for this call. Does it seem reasonable to leave this for now knowing it will be much more readily adressable in the next PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This will be changed in part 2.

return {
submitCancelled: true,
};
throw new ModalCancel();
Copy link
Contributor

Choose a reason for hiding this comment

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

Throwing should only be used when there is a misuse of the function or an error. In this case, this is a valid action that the user can take. This forces the developer using to catch errors and remember to check that one of them is actually a cancel action.

@lmossman
Copy link
Contributor

@krishnaglick I'm getting a build error when running this locally now, same one as in CI: https://github.com/airbytehq/airbyte/actions/runs/3047952989/jobs/4912510015#step:7:144
I'm gonna update the branch to pull in the most recent changes from master so that I can run this locally, hopefully that is fine!

const formId = useUniqueFormId();
const { clearFormChange } = useFormChangeTrackerService();
const [changedFormsById] = useChangedFormsById();
const formDirty = useMemo(() => !!changedFormsById?.[formId], [changedFormsById, formId]);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This all will get pulled out in part 2.

Comment on lines +80 to +82
if (!(e instanceof ModalCancel)) {
setSubmitError(e);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This will be changed in part 2.

return {
submitCancelled: true,
};
throw new ModalCancel();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This will be changed in part 2.

connection.syncCatalog.streams,
mode,
]
);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Declared at the appropriate level now.

@krishnaglick krishnaglick requested review from timroes and removed request for timroes September 15, 2022 18:56
@krishnaglick
Copy link
Contributor Author

Thanks for the all-clear Edmundo!
I'm going to merge this Monday, don't want to blow up on-call just in case

@krishnaglick krishnaglick merged commit 94e9dc9 into master Sep 19, 2022
@krishnaglick krishnaglick deleted the kc/connection-form-refactor branch September 19, 2022 15:07
robbinhan pushed a commit to robbinhan/airbyte that referenced this pull request Sep 29, 2022
* Work started

* Minor cleanup

* Some cleanup

* Lots moved into context

* WIP, stepping in the right direction

* WIP testing

* Post-merge fix

* Observables!

* WIP tests

* Tests!

* CI test

* CI?

* perhaps

* Only show name field during create

* Fix Build

* Fix build

* Fixing a bug

* Fix failing test

* Fixes e2e

* Type consolidation

* useCallback, improvements to connection create onAfter, and removing dirty tracking

* cleanup

* Removing an unused prop

* errorStatusMessage and mapFormPropsToOperation tests

* useUniqueFormId and useInitialValues tests

* Cleanup, onFrequencySelect is moved to its use location, better test wrapper,  and expanding use of FormError

* Better formSubmit handling for new connection

* Commenting and some cleanup

* Comments!

* Fixing errors from the merge

* mock data cleanup

* Better TODO

* onFrequencySelect is now always called

* Edmundo CR

* Remove whitespace

* Bridging changes to bring things inline

* Builds and tests run

Co-authored-by: Lake Mossman <lake@airbyte.io>
jhammarstedt pushed a commit to jhammarstedt/airbyte that referenced this pull request Oct 31, 2022
* Work started

* Minor cleanup

* Some cleanup

* Lots moved into context

* WIP, stepping in the right direction

* WIP testing

* Post-merge fix

* Observables!

* WIP tests

* Tests!

* CI test

* CI?

* perhaps

* Only show name field during create

* Fix Build

* Fix build

* Fixing a bug

* Fix failing test

* Fixes e2e

* Type consolidation

* useCallback, improvements to connection create onAfter, and removing dirty tracking

* cleanup

* Removing an unused prop

* errorStatusMessage and mapFormPropsToOperation tests

* useUniqueFormId and useInitialValues tests

* Cleanup, onFrequencySelect is moved to its use location, better test wrapper,  and expanding use of FormError

* Better formSubmit handling for new connection

* Commenting and some cleanup

* Comments!

* Fixing errors from the merge

* mock data cleanup

* Better TODO

* onFrequencySelect is now always called

* Edmundo CR

* Remove whitespace

* Bridging changes to bring things inline

* Builds and tests run

Co-authored-by: Lake Mossman <lake@airbyte.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/frontend Related to the Airbyte webapp area/platform issues related to the platform
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create ConnectionFormService and migrate Connection workflow to use it
5 participants