-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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 username editing #14242
🪟 🎉 Add username editing #14242
Conversation
@@ -112,6 +114,11 @@ export const AuthenticationProvider: React.FC = ({ children }) => { | |||
queryClient.removeQueries(); | |||
loggedOut(); | |||
}, | |||
async updateName(name: string): Promise<void> { | |||
await userService.changeName(state.currentUser?.authUserId || "", state.currentUser?.userId || "", name); |
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 ""
should never happen. One way you can prevent this is to check if the current user exits, for example:
async updateName(name: string): Promise<void> {
if (!state.currentUser) return;
// Now you can use `state.currentUser.authUserId` without the `?`
}
@@ -0,0 +1,3 @@ | |||
export interface FormValues { |
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 convention for the types filename is types.ts
import { useCurrentUser } from "packages/cloud/services/auth/AuthService"; | ||
import FeedbackBlock from "pages/SettingsPage/components/FeedbackBlock"; | ||
|
||
const NameSection: React.FC = () => { |
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're moving away from exporting defaults, so this can be:
const NameSection: React.FC = () => { | |
export const NameSection: React.FC = () => { |
The same suggestion applies for other areas of the code, then you can just export it directly on the index.ts
file.
</Formik> | ||
</Content> | ||
</SettingsCard> | ||
<NameSection /> |
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 makes it so much cleaner, thanks for extracting 🎉
await userService.changeName(state.currentUser?.authUserId || "", state.currentUser?.userId || "", name); | ||
updateUserName({ value: name }); | ||
return authService.updateProfile(name); |
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.
Add safety checks here to ensure both firebase and our user service get updated, and if one of them fails, rollback and return. the userName state should be updated last when it's guaranteed that both the user service and firebse got the update.
changeName: (values: FormValues, { setSubmitting, setFieldValue }: FormikHelpers<FormValues>) => void; | ||
}; | ||
|
||
const useName: UseNameHook = () => { |
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 hook doesn't return the name, should probably be useChangeName
if (!state.currentUser) { | ||
return state; | ||
} |
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.
As mentioned in a separate comment, this should never happen if we check that the current user exists first.
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 had this error, so that was only workaround here
TS2322: Type '{ name: string; email?: string | undefined; authUserId?: string | undefined; userId?: string | undefined;
status?: UserStatus | undefined; intercomHash?: string | undefined; }' is not assignable to type 'User'.
Types of property 'email' are incompatible.
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.
<LoadingButton type="submit" isLoading={isSubmitting}> | ||
<FormattedMessage id="settings.accountSettings.updateName" /> | ||
</LoadingButton> | ||
<FeedbackBlock errorMessage={errorMessage} successMessage={successMessage} isLoading={isSubmitting} /> |
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.
<FeedbackBlock errorMessage={errorMessage} successMessage={successMessage} isLoading={isSubmitting} /> | |
<FeedbackBlock errorMessage={errorMessage} successMessage={successMessage} /> |
The LoadingButton already gives us a loading indicator.
<FeedbackBlock errorMessage={errorMessage} successMessage={successMessage} isLoading={isSubmitting} /> | |
<FeedbackBlock errorMessage={errorMessage} successMessage={successMessage} isLoading={isSubmitting} /> |
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.
Looking a lot better but needs more validation and some minor things. I tested locally and looks great. Also update with the latest master branch.
switch (err.code) { | ||
default: |
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 switch does not seem necessary
export const NameSection: React.FC = () => { | ||
const { formatMessage } = useIntl(); | ||
const user = useCurrentUser(); | ||
const { changeName, successMessage, errorMessage } = useChangeName(); |
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.
Great use of a hook to keep the component clean.
...pp/src/packages/cloud/views/users/AccountSettingsView/components/NameSection/NameSection.tsx
Outdated
Show resolved
Hide resolved
)} | ||
</Field> | ||
</RowFieldItem> | ||
<LoadingButton type="submit" isLoading={isSubmitting}> |
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.
Should be disabled if the form is not valid
setErrorMessage( | ||
formatMessage({ | ||
id: "settings.accountSettings.updateNameError", | ||
}) + JSON.stringify(err) |
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 error may be confusing to users. It may be better to console.error
this error instead of stringifying it. @timroes is there a way we can send this error to Sentry?
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 logic is copied from PasswordSection. not sure, how the error should be approached here
...pp/src/packages/cloud/views/users/AccountSettingsView/components/NameSection/NameSection.tsx
Show resolved
Hide resolved
# Conflicts: # airbyte-webapp/src/packages/cloud/views/users/AccountSettingsView/AccountSettingsView.tsx
name: user.name, | ||
}} | ||
onSubmit={changeName} | ||
validate={validate} |
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've been using yup
to validate the schema. Search the code for an example.
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.
updated
)} | ||
</Field> | ||
</RowFieldItem> | ||
<LoadingButton disabled={!isValid} type="submit" isLoading={isSubmitting}> |
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.
Just tested and probably we should also check if the form is dirty
before we enable the button. Otherwise, the user can press the button to save the same name over and over.
What
Closes #1268
How
I refactored User Settings Account section, so Name, Email and Password sections follow the same structure
Loom
https://www.loom.com/share/e1f141488f454dc78dc1d1e35a496b92