Fix: validation for user profile details (#2693)
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
Reference in New Issue
Block a user