Fix: validation for user profile details (#2693)

This commit is contained in:
Mike
2024-08-20 09:34:44 +02:00
committed by GitHub
parent 0b417c9ba0
commit 2f9015df27
9 changed files with 52 additions and 54 deletions
@@ -53,17 +53,17 @@ import { capitalize, cloneDeep } from 'lodash-es'
import { graphql } from '~~/lib/common/generated/gql'
import { useUpdateNotificationPreferences } from '~~/lib/user/composables/management'
import type { NotificationPreferences } from '~~/lib/user/helpers/components'
import type { UserProfileEditDialogNotificationPreferences_UserFragment } from '~~/lib/common/generated/gql/graphql'
import type { SettingsUserNotifications_UserFragment } from '~~/lib/common/generated/gql/graphql'
graphql(`
fragment UserProfileEditDialogNotificationPreferences_User on User {
fragment SettingsUserNotifications_User on User {
id
notificationPreferences
}
`)
const props = defineProps<{
user: UserProfileEditDialogNotificationPreferences_UserFragment
user: SettingsUserNotifications_UserFragment
}>()
const { mutate, loading } = useUpdateNotificationPreferences()
@@ -36,9 +36,9 @@ import { ClipboardIcon } from '@heroicons/vue/24/outline'
graphql(`
fragment SettingsUserProfile_User on User {
...UserProfileEditDialogChangePassword_User
...UserProfileEditDialogDeleteAccount_User
...UserProfileEditDialogBio_User
...SettingsUserProfileChangePassword_User
...SettingsUserProfileDeleteAccount_User
...SettingsUserProfileDetails_User
}
`)
@@ -12,12 +12,12 @@
</div>
</template>
<script setup lang="ts">
import type { UserProfileEditDialogChangePassword_UserFragment } from '~~/lib/common/generated/gql/graphql'
import type { SettingsUserProfileChangePassword_UserFragment } from '~~/lib/common/generated/gql/graphql'
import { graphql } from '~~/lib/common/generated/gql'
import { usePasswordReset } from '~~/lib/auth/composables/passwordReset'
graphql(`
fragment UserProfileEditDialogChangePassword_User on User {
fragment SettingsUserProfileChangePassword_User on User {
id
email
}
@@ -26,7 +26,7 @@ graphql(`
const { sendResetEmail } = usePasswordReset()
const props = defineProps<{
user: UserProfileEditDialogChangePassword_UserFragment
user: SettingsUserProfileChangePassword_UserFragment
}>()
const onClick = async () => {
@@ -22,10 +22,10 @@
</template>
<script setup lang="ts">
import type { UserProfileEditDialogDeleteAccount_UserFragment } from '~~/lib/common/generated/gql/graphql'
import type { SettingsUserProfileDeleteAccount_UserFragment } from '~~/lib/common/generated/gql/graphql'
defineProps<{
user: UserProfileEditDialogDeleteAccount_UserFragment
user: SettingsUserProfileDeleteAccount_UserFragment
}>()
const showDeleteDialog = ref(false)
@@ -47,11 +47,11 @@ import { ExclamationTriangleIcon } from '@heroicons/vue/24/outline'
import { useForm } from 'vee-validate'
import type { GenericValidateFunction } from 'vee-validate'
import { graphql } from '~~/lib/common/generated/gql'
import type { UserProfileEditDialogDeleteAccount_UserFragment } from '~~/lib/common/generated/gql/graphql'
import type { SettingsUserProfileDeleteAccount_UserFragment } from '~~/lib/common/generated/gql/graphql'
import { useDeleteAccount } from '~~/lib/user/composables/management'
graphql(`
fragment UserProfileEditDialogDeleteAccount_User on User {
fragment SettingsUserProfileDeleteAccount_User on User {
id
email
}
@@ -68,7 +68,7 @@ const emit = defineEmits<{
}>()
const props = defineProps<{
user: UserProfileEditDialogDeleteAccount_UserFragment
user: SettingsUserProfileDeleteAccount_UserFragment
}>()
const isOpen = defineModel<boolean>('open', { required: true })
@@ -14,7 +14,7 @@
placeholder="John Doe"
show-label
:rules="[isRequired, isStringOfLength({ maxLength: 512 })]"
@change="save"
@change="save()"
/>
<hr class="mt-4 mb-2" />
<FormTextInput
@@ -25,52 +25,53 @@
placeholder="Example Ltd."
show-label
:rules="[isStringOfLength({ maxLength: 512 })]"
@change="save"
@change="save()"
/>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { useForm } from 'vee-validate'
import { debounce } from 'lodash-es'
import { graphql } from '~~/lib/common/generated/gql'
import type {
UserProfileEditDialogBio_UserFragment,
SettingsUserProfileDetails_UserFragment,
UserUpdateInput
} from '~~/lib/common/generated/gql/graphql'
import { isRequired, isStringOfLength } from '~~/lib/common/helpers/validation'
import { useUpdateUserProfile } from '~~/lib/user/composables/management'
graphql(`
fragment UserProfileEditDialogBio_User on User {
fragment SettingsUserProfileDetails_User on User {
id
name
company
bio
...UserProfileEditDialogAvatar_User
}
`)
type FormValues = { name: string; company: string }
const props = defineProps<{
user: UserProfileEditDialogBio_UserFragment
user: SettingsUserProfileDetails_UserFragment
}>()
const { mutate } = useUpdateUserProfile()
const { handleSubmit } = useForm<FormValues>()
const name = ref('')
const company = ref('')
const bio = ref('')
const save = async () => {
const save = handleSubmit(async () => {
debouncedSave.cancel()
const input: UserUpdateInput = {}
if (name.value !== props.user.name) input.name = name.value
if (company.value !== props.user.company) input.company = company.value
if (bio.value !== props.user.bio) input.bio = bio.value
if (!Object.values(input).length) return
await mutate(input)
}
})
const debouncedSave = debounce(save, 1000)
watch(
@@ -78,10 +79,7 @@ watch(
(user) => {
name.value = user.name
company.value = user.company || ''
bio.value = user.bio || ''
},
{ deep: true, immediate: true }
)
watch(() => [name.value, company.value, bio.value], debouncedSave)
</script>
@@ -93,12 +93,12 @@ const documents = {
"\n fragment SettingsServerProjects_ProjectCollection on ProjectCollection {\n totalCount\n items {\n ...SettingsSharedProjects_Project\n }\n }\n": types.SettingsServerProjects_ProjectCollectionFragmentDoc,
"\n fragment SettingsSharedProjects_Project on Project {\n id\n name\n visibility\n createdAt\n updatedAt\n models {\n totalCount\n }\n versions {\n totalCount\n }\n team {\n id\n user {\n name\n id\n avatar\n }\n }\n }\n": types.SettingsSharedProjects_ProjectFragmentDoc,
"\n fragment SettingsUserEmails_User on User {\n id\n emails {\n ...SettingsUserEmailCards_UserEmail\n }\n }\n": types.SettingsUserEmails_UserFragmentDoc,
"\n fragment UserProfileEditDialogNotificationPreferences_User on User {\n id\n notificationPreferences\n }\n": types.UserProfileEditDialogNotificationPreferences_UserFragmentDoc,
"\n fragment SettingsUserProfile_User on User {\n ...UserProfileEditDialogChangePassword_User\n ...UserProfileEditDialogDeleteAccount_User\n ...UserProfileEditDialogBio_User\n }\n": types.SettingsUserProfile_UserFragmentDoc,
"\n fragment SettingsUserNotifications_User on User {\n id\n notificationPreferences\n }\n": types.SettingsUserNotifications_UserFragmentDoc,
"\n fragment SettingsUserProfile_User on User {\n ...SettingsUserProfileChangePassword_User\n ...SettingsUserProfileDeleteAccount_User\n ...SettingsUserProfileDetails_User\n }\n": types.SettingsUserProfile_UserFragmentDoc,
"\n fragment SettingsUserEmailCards_UserEmail on UserEmail {\n email\n id\n primary\n verified\n }\n": types.SettingsUserEmailCards_UserEmailFragmentDoc,
"\n fragment UserProfileEditDialogChangePassword_User on User {\n id\n email\n }\n": types.UserProfileEditDialogChangePassword_UserFragmentDoc,
"\n fragment UserProfileEditDialogDeleteAccount_User on User {\n id\n email\n }\n": types.UserProfileEditDialogDeleteAccount_UserFragmentDoc,
"\n fragment UserProfileEditDialogBio_User on User {\n id\n name\n company\n bio\n ...UserProfileEditDialogAvatar_User\n }\n": types.UserProfileEditDialogBio_UserFragmentDoc,
"\n fragment SettingsUserProfileChangePassword_User on User {\n id\n email\n }\n": types.SettingsUserProfileChangePassword_UserFragmentDoc,
"\n fragment SettingsUserProfileDeleteAccount_User on User {\n id\n email\n }\n": types.SettingsUserProfileDeleteAccount_UserFragmentDoc,
"\n fragment SettingsUserProfileDetails_User on User {\n id\n name\n company\n ...UserProfileEditDialogAvatar_User\n }\n": types.SettingsUserProfileDetails_UserFragmentDoc,
"\n fragment UserProfileEditDialogAvatar_User on User {\n id\n avatar\n ...ActiveUserAvatar\n }\n": types.UserProfileEditDialogAvatar_UserFragmentDoc,
"\n fragment SettingsWorkspacesGeneral_Workspace on Workspace {\n ...SettingsWorkspaceGeneralDeleteDialog_Workspace\n id\n name\n logo\n description\n }\n": types.SettingsWorkspacesGeneral_WorkspaceFragmentDoc,
"\n fragment SettingsWorkspaceGeneralDeleteDialog_Workspace on Workspace {\n id\n name\n }\n": types.SettingsWorkspaceGeneralDeleteDialog_WorkspaceFragmentDoc,
@@ -258,7 +258,7 @@ const documents = {
"\n mutation UpdateUser($input: UserUpdateInput!) {\n activeUserMutations {\n update(user: $input) {\n id\n name\n bio\n company\n avatar\n }\n }\n }\n": types.UpdateUserDocument,
"\n mutation UpdateNotificationPreferences($input: JSONObject!) {\n userNotificationPreferencesUpdate(preferences: $input)\n }\n": types.UpdateNotificationPreferencesDocument,
"\n mutation DeleteAccount($input: UserDeleteInput!) {\n userDelete(userConfirmation: $input)\n }\n": types.DeleteAccountDocument,
"\n query ProfileEditDialog {\n activeUser {\n ...UserProfileEditDialogBio_User\n ...UserProfileEditDialogNotificationPreferences_User\n ...UserProfileEditDialogDeleteAccount_User\n }\n }\n": types.ProfileEditDialogDocument,
"\n query ProfileEditDialog {\n activeUser {\n ...SettingsUserProfileDetails_User\n ...SettingsUserNotifications_User\n ...SettingsUserProfileDeleteAccount_User\n }\n }\n": types.ProfileEditDialogDocument,
"\n fragment ViewerCommentBubblesData on Comment {\n id\n viewedAt\n viewerState\n }\n": types.ViewerCommentBubblesDataFragmentDoc,
"\n fragment ViewerCommentThread on Comment {\n ...ViewerCommentsListItem\n ...ViewerCommentBubblesData\n ...ViewerCommentsReplyItem\n }\n": types.ViewerCommentThreadFragmentDoc,
"\n fragment ViewerCommentsReplyItem on Comment {\n id\n archived\n rawText\n text {\n doc\n }\n author {\n ...LimitedUserAvatar\n }\n createdAt\n ...ThreadCommentAttachment\n }\n": types.ViewerCommentsReplyItemFragmentDoc,
@@ -635,11 +635,11 @@ export function graphql(source: "\n fragment SettingsUserEmails_User on User {\
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n fragment UserProfileEditDialogNotificationPreferences_User on User {\n id\n notificationPreferences\n }\n"): (typeof documents)["\n fragment UserProfileEditDialogNotificationPreferences_User on User {\n id\n notificationPreferences\n }\n"];
export function graphql(source: "\n fragment SettingsUserNotifications_User on User {\n id\n notificationPreferences\n }\n"): (typeof documents)["\n fragment SettingsUserNotifications_User on User {\n id\n notificationPreferences\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n fragment SettingsUserProfile_User on User {\n ...UserProfileEditDialogChangePassword_User\n ...UserProfileEditDialogDeleteAccount_User\n ...UserProfileEditDialogBio_User\n }\n"): (typeof documents)["\n fragment SettingsUserProfile_User on User {\n ...UserProfileEditDialogChangePassword_User\n ...UserProfileEditDialogDeleteAccount_User\n ...UserProfileEditDialogBio_User\n }\n"];
export function graphql(source: "\n fragment SettingsUserProfile_User on User {\n ...SettingsUserProfileChangePassword_User\n ...SettingsUserProfileDeleteAccount_User\n ...SettingsUserProfileDetails_User\n }\n"): (typeof documents)["\n fragment SettingsUserProfile_User on User {\n ...SettingsUserProfileChangePassword_User\n ...SettingsUserProfileDeleteAccount_User\n ...SettingsUserProfileDetails_User\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
@@ -647,15 +647,15 @@ export function graphql(source: "\n fragment SettingsUserEmailCards_UserEmail o
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n fragment UserProfileEditDialogChangePassword_User on User {\n id\n email\n }\n"): (typeof documents)["\n fragment UserProfileEditDialogChangePassword_User on User {\n id\n email\n }\n"];
export function graphql(source: "\n fragment SettingsUserProfileChangePassword_User on User {\n id\n email\n }\n"): (typeof documents)["\n fragment SettingsUserProfileChangePassword_User on User {\n id\n email\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n fragment UserProfileEditDialogDeleteAccount_User on User {\n id\n email\n }\n"): (typeof documents)["\n fragment UserProfileEditDialogDeleteAccount_User on User {\n id\n email\n }\n"];
export function graphql(source: "\n fragment SettingsUserProfileDeleteAccount_User on User {\n id\n email\n }\n"): (typeof documents)["\n fragment SettingsUserProfileDeleteAccount_User on User {\n id\n email\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n fragment UserProfileEditDialogBio_User on User {\n id\n name\n company\n bio\n ...UserProfileEditDialogAvatar_User\n }\n"): (typeof documents)["\n fragment UserProfileEditDialogBio_User on User {\n id\n name\n company\n bio\n ...UserProfileEditDialogAvatar_User\n }\n"];
export function graphql(source: "\n fragment SettingsUserProfileDetails_User on User {\n id\n name\n company\n ...UserProfileEditDialogAvatar_User\n }\n"): (typeof documents)["\n fragment SettingsUserProfileDetails_User on User {\n id\n name\n company\n ...UserProfileEditDialogAvatar_User\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
@@ -1295,7 +1295,7 @@ export function graphql(source: "\n mutation DeleteAccount($input: UserDeleteIn
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n query ProfileEditDialog {\n activeUser {\n ...UserProfileEditDialogBio_User\n ...UserProfileEditDialogNotificationPreferences_User\n ...UserProfileEditDialogDeleteAccount_User\n }\n }\n"): (typeof documents)["\n query ProfileEditDialog {\n activeUser {\n ...UserProfileEditDialogBio_User\n ...UserProfileEditDialogNotificationPreferences_User\n ...UserProfileEditDialogDeleteAccount_User\n }\n }\n"];
export function graphql(source: "\n query ProfileEditDialog {\n activeUser {\n ...SettingsUserProfileDetails_User\n ...SettingsUserNotifications_User\n ...SettingsUserProfileDeleteAccount_User\n }\n }\n"): (typeof documents)["\n query ProfileEditDialog {\n activeUser {\n ...SettingsUserProfileDetails_User\n ...SettingsUserNotifications_User\n ...SettingsUserProfileDeleteAccount_User\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
File diff suppressed because one or more lines are too long
@@ -3,9 +3,9 @@ import { graphql } from '~~/lib/common/generated/gql'
export const profileEditDialogQuery = graphql(`
query ProfileEditDialog {
activeUser {
...UserProfileEditDialogBio_User
...UserProfileEditDialogNotificationPreferences_User
...UserProfileEditDialogDeleteAccount_User
...SettingsUserProfileDetails_User
...SettingsUserNotifications_User
...SettingsUserProfileDeleteAccount_User
}
}
`)