Fix edit user settings (#3079)

* Prepare mutation for change password nad user first nad last name

* User mutations

* User and staff mutation hooks

* Split mution for user and staff specific

* Ad props types and refetch after user mutations

* Add save button status for user mutation

* Get rid of maybe

* Improve hooks naming

* useProfileOperations
This commit is contained in:
poulch 2023-02-01 16:50:43 +01:00 committed by GitHub
parent 34cdd75b60
commit c8bb645ae8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 348 additions and 153 deletions

View file

@ -42,12 +42,8 @@ export function useAuthProvider({
notify, notify,
apolloClient, apolloClient,
}: UseAuthProviderOpts): UserContext { }: UseAuthProviderOpts): UserContext {
const { const { login, getExternalAuthUrl, getExternalAccessToken, logout } =
login, useAuth();
getExternalAuthUrl,
getExternalAccessToken,
logout,
} = useAuth();
const navigate = useNavigator(); const navigate = useNavigator();
const { authenticated, authenticating, user } = useAuthState(); const { authenticated, authenticating, user } = useAuthState();
const [requestedExternalPluginId] = useLocalStorage( const [requestedExternalPluginId] = useLocalStorage(

View file

@ -14865,6 +14865,77 @@ export function useStaffMemberUpdateMutation(baseOptions?: ApolloReactHooks.Muta
export type StaffMemberUpdateMutationHookResult = ReturnType<typeof useStaffMemberUpdateMutation>; export type StaffMemberUpdateMutationHookResult = ReturnType<typeof useStaffMemberUpdateMutation>;
export type StaffMemberUpdateMutationResult = Apollo.MutationResult<Types.StaffMemberUpdateMutation>; export type StaffMemberUpdateMutationResult = Apollo.MutationResult<Types.StaffMemberUpdateMutation>;
export type StaffMemberUpdateMutationOptions = Apollo.BaseMutationOptions<Types.StaffMemberUpdateMutation, Types.StaffMemberUpdateMutationVariables>; export type StaffMemberUpdateMutationOptions = Apollo.BaseMutationOptions<Types.StaffMemberUpdateMutation, Types.StaffMemberUpdateMutationVariables>;
export const UserPassowrdChangeDocument = gql`
mutation UserPassowrdChange($newPassword: String!, $oldPassword: String!) {
passwordChange(newPassword: $newPassword, oldPassword: $oldPassword) {
errors {
...AccountError
}
}
}
${AccountErrorFragmentDoc}`;
export type UserPassowrdChangeMutationFn = Apollo.MutationFunction<Types.UserPassowrdChangeMutation, Types.UserPassowrdChangeMutationVariables>;
/**
* __useUserPassowrdChangeMutation__
*
* To run a mutation, you first call `useUserPassowrdChangeMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useUserPassowrdChangeMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [userPassowrdChangeMutation, { data, loading, error }] = useUserPassowrdChangeMutation({
* variables: {
* newPassword: // value for 'newPassword'
* oldPassword: // value for 'oldPassword'
* },
* });
*/
export function useUserPassowrdChangeMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<Types.UserPassowrdChangeMutation, Types.UserPassowrdChangeMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return ApolloReactHooks.useMutation<Types.UserPassowrdChangeMutation, Types.UserPassowrdChangeMutationVariables>(UserPassowrdChangeDocument, options);
}
export type UserPassowrdChangeMutationHookResult = ReturnType<typeof useUserPassowrdChangeMutation>;
export type UserPassowrdChangeMutationResult = Apollo.MutationResult<Types.UserPassowrdChangeMutation>;
export type UserPassowrdChangeMutationOptions = Apollo.BaseMutationOptions<Types.UserPassowrdChangeMutation, Types.UserPassowrdChangeMutationVariables>;
export const UserAccountUpdateDocument = gql`
mutation UserAccountUpdate($input: AccountInput!) {
accountUpdate(input: $input) {
errors {
...AccountError
}
}
}
${AccountErrorFragmentDoc}`;
export type UserAccountUpdateMutationFn = Apollo.MutationFunction<Types.UserAccountUpdateMutation, Types.UserAccountUpdateMutationVariables>;
/**
* __useUserAccountUpdateMutation__
*
* To run a mutation, you first call `useUserAccountUpdateMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useUserAccountUpdateMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [userAccountUpdateMutation, { data, loading, error }] = useUserAccountUpdateMutation({
* variables: {
* input: // value for 'input'
* },
* });
*/
export function useUserAccountUpdateMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<Types.UserAccountUpdateMutation, Types.UserAccountUpdateMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return ApolloReactHooks.useMutation<Types.UserAccountUpdateMutation, Types.UserAccountUpdateMutationVariables>(UserAccountUpdateDocument, options);
}
export type UserAccountUpdateMutationHookResult = ReturnType<typeof useUserAccountUpdateMutation>;
export type UserAccountUpdateMutationResult = Apollo.MutationResult<Types.UserAccountUpdateMutation>;
export type UserAccountUpdateMutationOptions = Apollo.BaseMutationOptions<Types.UserAccountUpdateMutation, Types.UserAccountUpdateMutationVariables>;
export const StaffMemberDeleteDocument = gql` export const StaffMemberDeleteDocument = gql`
mutation StaffMemberDelete($id: ID!) { mutation StaffMemberDelete($id: ID!) {
staffDelete(id: $id) { staffDelete(id: $id) {
@ -14900,8 +14971,8 @@ export function useStaffMemberDeleteMutation(baseOptions?: ApolloReactHooks.Muta
export type StaffMemberDeleteMutationHookResult = ReturnType<typeof useStaffMemberDeleteMutation>; export type StaffMemberDeleteMutationHookResult = ReturnType<typeof useStaffMemberDeleteMutation>;
export type StaffMemberDeleteMutationResult = Apollo.MutationResult<Types.StaffMemberDeleteMutation>; export type StaffMemberDeleteMutationResult = Apollo.MutationResult<Types.StaffMemberDeleteMutation>;
export type StaffMemberDeleteMutationOptions = Apollo.BaseMutationOptions<Types.StaffMemberDeleteMutation, Types.StaffMemberDeleteMutationVariables>; export type StaffMemberDeleteMutationOptions = Apollo.BaseMutationOptions<Types.StaffMemberDeleteMutation, Types.StaffMemberDeleteMutationVariables>;
export const StaffAvatarUpdateDocument = gql` export const UserAvatarUpdateDocument = gql`
mutation StaffAvatarUpdate($image: Upload!) { mutation UserAvatarUpdate($image: Upload!) {
userAvatarUpdate(image: $image) { userAvatarUpdate(image: $image) {
errors { errors {
...AccountError ...AccountError
@ -14915,34 +14986,34 @@ export const StaffAvatarUpdateDocument = gql`
} }
} }
${AccountErrorFragmentDoc}`; ${AccountErrorFragmentDoc}`;
export type StaffAvatarUpdateMutationFn = Apollo.MutationFunction<Types.StaffAvatarUpdateMutation, Types.StaffAvatarUpdateMutationVariables>; export type UserAvatarUpdateMutationFn = Apollo.MutationFunction<Types.UserAvatarUpdateMutation, Types.UserAvatarUpdateMutationVariables>;
/** /**
* __useStaffAvatarUpdateMutation__ * __useUserAvatarUpdateMutation__
* *
* To run a mutation, you first call `useStaffAvatarUpdateMutation` within a React component and pass it any options that fit your needs. * To run a mutation, you first call `useUserAvatarUpdateMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useStaffAvatarUpdateMutation` returns a tuple that includes: * When your component renders, `useUserAvatarUpdateMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation * - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution * - An object with fields that represent the current status of the mutation's execution
* *
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
* *
* @example * @example
* const [staffAvatarUpdateMutation, { data, loading, error }] = useStaffAvatarUpdateMutation({ * const [userAvatarUpdateMutation, { data, loading, error }] = useUserAvatarUpdateMutation({
* variables: { * variables: {
* image: // value for 'image' * image: // value for 'image'
* }, * },
* }); * });
*/ */
export function useStaffAvatarUpdateMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<Types.StaffAvatarUpdateMutation, Types.StaffAvatarUpdateMutationVariables>) { export function useUserAvatarUpdateMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<Types.UserAvatarUpdateMutation, Types.UserAvatarUpdateMutationVariables>) {
const options = {...defaultOptions, ...baseOptions} const options = {...defaultOptions, ...baseOptions}
return ApolloReactHooks.useMutation<Types.StaffAvatarUpdateMutation, Types.StaffAvatarUpdateMutationVariables>(StaffAvatarUpdateDocument, options); return ApolloReactHooks.useMutation<Types.UserAvatarUpdateMutation, Types.UserAvatarUpdateMutationVariables>(UserAvatarUpdateDocument, options);
} }
export type StaffAvatarUpdateMutationHookResult = ReturnType<typeof useStaffAvatarUpdateMutation>; export type UserAvatarUpdateMutationHookResult = ReturnType<typeof useUserAvatarUpdateMutation>;
export type StaffAvatarUpdateMutationResult = Apollo.MutationResult<Types.StaffAvatarUpdateMutation>; export type UserAvatarUpdateMutationResult = Apollo.MutationResult<Types.UserAvatarUpdateMutation>;
export type StaffAvatarUpdateMutationOptions = Apollo.BaseMutationOptions<Types.StaffAvatarUpdateMutation, Types.StaffAvatarUpdateMutationVariables>; export type UserAvatarUpdateMutationOptions = Apollo.BaseMutationOptions<Types.UserAvatarUpdateMutation, Types.UserAvatarUpdateMutationVariables>;
export const StaffAvatarDeleteDocument = gql` export const UserAvatarDeleteDocument = gql`
mutation StaffAvatarDelete { mutation UserAvatarDelete {
userAvatarDelete { userAvatarDelete {
errors { errors {
...AccountError ...AccountError
@ -14956,33 +15027,33 @@ export const StaffAvatarDeleteDocument = gql`
} }
} }
${AccountErrorFragmentDoc}`; ${AccountErrorFragmentDoc}`;
export type StaffAvatarDeleteMutationFn = Apollo.MutationFunction<Types.StaffAvatarDeleteMutation, Types.StaffAvatarDeleteMutationVariables>; export type UserAvatarDeleteMutationFn = Apollo.MutationFunction<Types.UserAvatarDeleteMutation, Types.UserAvatarDeleteMutationVariables>;
/** /**
* __useStaffAvatarDeleteMutation__ * __useUserAvatarDeleteMutation__
* *
* To run a mutation, you first call `useStaffAvatarDeleteMutation` within a React component and pass it any options that fit your needs. * To run a mutation, you first call `useUserAvatarDeleteMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useStaffAvatarDeleteMutation` returns a tuple that includes: * When your component renders, `useUserAvatarDeleteMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation * - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution * - An object with fields that represent the current status of the mutation's execution
* *
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
* *
* @example * @example
* const [staffAvatarDeleteMutation, { data, loading, error }] = useStaffAvatarDeleteMutation({ * const [userAvatarDeleteMutation, { data, loading, error }] = useUserAvatarDeleteMutation({
* variables: { * variables: {
* }, * },
* }); * });
*/ */
export function useStaffAvatarDeleteMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<Types.StaffAvatarDeleteMutation, Types.StaffAvatarDeleteMutationVariables>) { export function useUserAvatarDeleteMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<Types.UserAvatarDeleteMutation, Types.UserAvatarDeleteMutationVariables>) {
const options = {...defaultOptions, ...baseOptions} const options = {...defaultOptions, ...baseOptions}
return ApolloReactHooks.useMutation<Types.StaffAvatarDeleteMutation, Types.StaffAvatarDeleteMutationVariables>(StaffAvatarDeleteDocument, options); return ApolloReactHooks.useMutation<Types.UserAvatarDeleteMutation, Types.UserAvatarDeleteMutationVariables>(UserAvatarDeleteDocument, options);
} }
export type StaffAvatarDeleteMutationHookResult = ReturnType<typeof useStaffAvatarDeleteMutation>; export type UserAvatarDeleteMutationHookResult = ReturnType<typeof useUserAvatarDeleteMutation>;
export type StaffAvatarDeleteMutationResult = Apollo.MutationResult<Types.StaffAvatarDeleteMutation>; export type UserAvatarDeleteMutationResult = Apollo.MutationResult<Types.UserAvatarDeleteMutation>;
export type StaffAvatarDeleteMutationOptions = Apollo.BaseMutationOptions<Types.StaffAvatarDeleteMutation, Types.StaffAvatarDeleteMutationVariables>; export type UserAvatarDeleteMutationOptions = Apollo.BaseMutationOptions<Types.UserAvatarDeleteMutation, Types.UserAvatarDeleteMutationVariables>;
export const ChangeStaffPasswordDocument = gql` export const ChangeUserPasswordDocument = gql`
mutation ChangeStaffPassword($newPassword: String!, $oldPassword: String!) { mutation ChangeUserPassword($newPassword: String!, $oldPassword: String!) {
passwordChange(newPassword: $newPassword, oldPassword: $oldPassword) { passwordChange(newPassword: $newPassword, oldPassword: $oldPassword) {
errors { errors {
...AccountError ...AccountError
@ -14990,33 +15061,33 @@ export const ChangeStaffPasswordDocument = gql`
} }
} }
${AccountErrorFragmentDoc}`; ${AccountErrorFragmentDoc}`;
export type ChangeStaffPasswordMutationFn = Apollo.MutationFunction<Types.ChangeStaffPasswordMutation, Types.ChangeStaffPasswordMutationVariables>; export type ChangeUserPasswordMutationFn = Apollo.MutationFunction<Types.ChangeUserPasswordMutation, Types.ChangeUserPasswordMutationVariables>;
/** /**
* __useChangeStaffPasswordMutation__ * __useChangeUserPasswordMutation__
* *
* To run a mutation, you first call `useChangeStaffPasswordMutation` within a React component and pass it any options that fit your needs. * To run a mutation, you first call `useChangeUserPasswordMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useChangeStaffPasswordMutation` returns a tuple that includes: * When your component renders, `useChangeUserPasswordMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation * - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution * - An object with fields that represent the current status of the mutation's execution
* *
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
* *
* @example * @example
* const [changeStaffPasswordMutation, { data, loading, error }] = useChangeStaffPasswordMutation({ * const [changeUserPasswordMutation, { data, loading, error }] = useChangeUserPasswordMutation({
* variables: { * variables: {
* newPassword: // value for 'newPassword' * newPassword: // value for 'newPassword'
* oldPassword: // value for 'oldPassword' * oldPassword: // value for 'oldPassword'
* }, * },
* }); * });
*/ */
export function useChangeStaffPasswordMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<Types.ChangeStaffPasswordMutation, Types.ChangeStaffPasswordMutationVariables>) { export function useChangeUserPasswordMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<Types.ChangeUserPasswordMutation, Types.ChangeUserPasswordMutationVariables>) {
const options = {...defaultOptions, ...baseOptions} const options = {...defaultOptions, ...baseOptions}
return ApolloReactHooks.useMutation<Types.ChangeStaffPasswordMutation, Types.ChangeStaffPasswordMutationVariables>(ChangeStaffPasswordDocument, options); return ApolloReactHooks.useMutation<Types.ChangeUserPasswordMutation, Types.ChangeUserPasswordMutationVariables>(ChangeUserPasswordDocument, options);
} }
export type ChangeStaffPasswordMutationHookResult = ReturnType<typeof useChangeStaffPasswordMutation>; export type ChangeUserPasswordMutationHookResult = ReturnType<typeof useChangeUserPasswordMutation>;
export type ChangeStaffPasswordMutationResult = Apollo.MutationResult<Types.ChangeStaffPasswordMutation>; export type ChangeUserPasswordMutationResult = Apollo.MutationResult<Types.ChangeUserPasswordMutation>;
export type ChangeStaffPasswordMutationOptions = Apollo.BaseMutationOptions<Types.ChangeStaffPasswordMutation, Types.ChangeStaffPasswordMutationVariables>; export type ChangeUserPasswordMutationOptions = Apollo.BaseMutationOptions<Types.ChangeUserPasswordMutation, Types.ChangeUserPasswordMutationVariables>;
export const StaffListDocument = gql` export const StaffListDocument = gql`
query StaffList($first: Int, $after: String, $last: Int, $before: String, $filter: StaffUserInput, $sort: UserSortingInput) { query StaffList($first: Int, $after: String, $last: Int, $before: String, $filter: StaffUserInput, $sort: UserSortingInput) {
staffUsers( staffUsers(

View file

@ -9144,6 +9144,21 @@ export type StaffMemberUpdateMutationVariables = Exact<{
export type StaffMemberUpdateMutation = { __typename: 'Mutation', staffUpdate: { __typename: 'StaffUpdate', errors: Array<{ __typename: 'StaffError', code: AccountErrorCode, field: string | null, message: string | null }>, user: { __typename: 'User', id: string, email: string, firstName: string, isActive: boolean, lastName: string, permissionGroups: Array<{ __typename: 'Group', id: string, name: string, userCanManage: boolean }> | null, userPermissions: Array<{ __typename: 'UserPermission', code: PermissionEnum, name: string }> | null, avatar: { __typename: 'Image', url: string } | null } | null } | null }; export type StaffMemberUpdateMutation = { __typename: 'Mutation', staffUpdate: { __typename: 'StaffUpdate', errors: Array<{ __typename: 'StaffError', code: AccountErrorCode, field: string | null, message: string | null }>, user: { __typename: 'User', id: string, email: string, firstName: string, isActive: boolean, lastName: string, permissionGroups: Array<{ __typename: 'Group', id: string, name: string, userCanManage: boolean }> | null, userPermissions: Array<{ __typename: 'UserPermission', code: PermissionEnum, name: string }> | null, avatar: { __typename: 'Image', url: string } | null } | null } | null };
export type UserPassowrdChangeMutationVariables = Exact<{
newPassword: Scalars['String'];
oldPassword: Scalars['String'];
}>;
export type UserPassowrdChangeMutation = { __typename: 'Mutation', passwordChange: { __typename: 'PasswordChange', errors: Array<{ __typename: 'AccountError', code: AccountErrorCode, field: string | null, addressType: AddressTypeEnum | null, message: string | null }> } | null };
export type UserAccountUpdateMutationVariables = Exact<{
input: AccountInput;
}>;
export type UserAccountUpdateMutation = { __typename: 'Mutation', accountUpdate: { __typename: 'AccountUpdate', errors: Array<{ __typename: 'AccountError', code: AccountErrorCode, field: string | null, addressType: AddressTypeEnum | null, message: string | null }> } | null };
export type StaffMemberDeleteMutationVariables = Exact<{ export type StaffMemberDeleteMutationVariables = Exact<{
id: Scalars['ID']; id: Scalars['ID'];
}>; }>;
@ -9151,25 +9166,25 @@ export type StaffMemberDeleteMutationVariables = Exact<{
export type StaffMemberDeleteMutation = { __typename: 'Mutation', staffDelete: { __typename: 'StaffDelete', errors: Array<{ __typename: 'StaffError', code: AccountErrorCode, field: string | null, message: string | null }> } | null }; export type StaffMemberDeleteMutation = { __typename: 'Mutation', staffDelete: { __typename: 'StaffDelete', errors: Array<{ __typename: 'StaffError', code: AccountErrorCode, field: string | null, message: string | null }> } | null };
export type StaffAvatarUpdateMutationVariables = Exact<{ export type UserAvatarUpdateMutationVariables = Exact<{
image: Scalars['Upload']; image: Scalars['Upload'];
}>; }>;
export type StaffAvatarUpdateMutation = { __typename: 'Mutation', userAvatarUpdate: { __typename: 'UserAvatarUpdate', errors: Array<{ __typename: 'AccountError', code: AccountErrorCode, field: string | null, addressType: AddressTypeEnum | null, message: string | null }>, user: { __typename: 'User', id: string, avatar: { __typename: 'Image', url: string } | null } | null } | null }; export type UserAvatarUpdateMutation = { __typename: 'Mutation', userAvatarUpdate: { __typename: 'UserAvatarUpdate', errors: Array<{ __typename: 'AccountError', code: AccountErrorCode, field: string | null, addressType: AddressTypeEnum | null, message: string | null }>, user: { __typename: 'User', id: string, avatar: { __typename: 'Image', url: string } | null } | null } | null };
export type StaffAvatarDeleteMutationVariables = Exact<{ [key: string]: never; }>; export type UserAvatarDeleteMutationVariables = Exact<{ [key: string]: never; }>;
export type StaffAvatarDeleteMutation = { __typename: 'Mutation', userAvatarDelete: { __typename: 'UserAvatarDelete', errors: Array<{ __typename: 'AccountError', code: AccountErrorCode, field: string | null, addressType: AddressTypeEnum | null, message: string | null }>, user: { __typename: 'User', id: string, avatar: { __typename: 'Image', url: string } | null } | null } | null }; export type UserAvatarDeleteMutation = { __typename: 'Mutation', userAvatarDelete: { __typename: 'UserAvatarDelete', errors: Array<{ __typename: 'AccountError', code: AccountErrorCode, field: string | null, addressType: AddressTypeEnum | null, message: string | null }>, user: { __typename: 'User', id: string, avatar: { __typename: 'Image', url: string } | null } | null } | null };
export type ChangeStaffPasswordMutationVariables = Exact<{ export type ChangeUserPasswordMutationVariables = Exact<{
newPassword: Scalars['String']; newPassword: Scalars['String'];
oldPassword: Scalars['String']; oldPassword: Scalars['String'];
}>; }>;
export type ChangeStaffPasswordMutation = { __typename: 'Mutation', passwordChange: { __typename: 'PasswordChange', errors: Array<{ __typename: 'AccountError', code: AccountErrorCode, field: string | null, addressType: AddressTypeEnum | null, message: string | null }> } | null }; export type ChangeUserPasswordMutation = { __typename: 'Mutation', passwordChange: { __typename: 'PasswordChange', errors: Array<{ __typename: 'AccountError', code: AccountErrorCode, field: string | null, addressType: AddressTypeEnum | null, message: string | null }> } | null };
export type StaffListQueryVariables = Exact<{ export type StaffListQueryVariables = Exact<{
first?: InputMaybe<Scalars['Int']>; first?: InputMaybe<Scalars['Int']>;

View file

@ -93,16 +93,14 @@ const StaffDetailsPage: React.FC<StaffDetailsPageProps> = ({
const isActive = isMemberActive(staffMember); const isActive = isMemberActive(staffMember);
const permissionGroups = getMemberPermissionGroups(staffMember); const permissionGroups = getMemberPermissionGroups(staffMember);
const [ const [permissionGroupsDisplayValues, setPermissionGroupsDisplayValues] =
permissionGroupsDisplayValues, useStateFromProps<MultiAutocompleteChoiceType[]>(
setPermissionGroupsDisplayValues, permissionGroups.map(group => ({
] = useStateFromProps<MultiAutocompleteChoiceType[]>( disabled: !group.userCanManage,
permissionGroups.map(group => ({ label: group.name,
disabled: !group.userCanManage, value: group.id,
label: group.name, })) || [],
value: group.id, );
})) || [],
);
const initialForm: StaffDetailsFormData = { const initialForm: StaffDetailsFormData = {
email: staffMember?.email || "", email: staffMember?.email || "",

2
src/staff/hooks/index.ts Normal file
View file

@ -0,0 +1,2 @@
export * from "./useStaffUserOperations";
export * from "./useProfileOperations";

View file

@ -0,0 +1,95 @@
import {
useChangeUserPasswordMutation,
useUserAccountUpdateMutation,
useUserAvatarDeleteMutation,
useUserAvatarUpdateMutation,
} from "@dashboard/graphql";
import useNavigator from "@dashboard/hooks/useNavigator";
import useNotifier from "@dashboard/hooks/useNotifier";
import { commonMessages, errorMessages } from "@dashboard/intl";
import { useIntl } from "react-intl";
import { staffMemberDetailsUrl } from "../urls";
interface UseUserMutationProps {
refetch: () => void;
id: string;
closeModal: () => void;
}
export const useProfileOperations = ({
refetch,
id,
closeModal,
}: UseUserMutationProps) => {
const notify = useNotifier();
const intl = useIntl();
const navigate = useNavigator();
const [updateUserAccount, updateUserAccountOpts] =
useUserAccountUpdateMutation({
onCompleted: data => {
if (!data.accountUpdate?.errors.length) {
refetch();
notify({
status: "success",
text: intl.formatMessage(commonMessages.savedChanges),
});
}
},
});
const [updateUserAvatar] = useUserAvatarUpdateMutation({
onCompleted: data => {
if (!data.userAvatarUpdate?.errors.length) {
notify({
status: "success",
text: intl.formatMessage(commonMessages.savedChanges),
});
refetch();
navigate(staffMemberDetailsUrl(id));
} else {
notify({
status: "error",
title: intl.formatMessage(errorMessages.imgageUploadErrorTitle),
text: intl.formatMessage(errorMessages.imageUploadErrorText),
});
}
},
});
const [deleteUserAvatar, deleteAvatarResult] = useUserAvatarDeleteMutation({
onCompleted: data => {
if (!data.userAvatarDelete?.errors.length) {
notify({
status: "success",
text: intl.formatMessage(commonMessages.savedChanges),
});
refetch();
navigate(staffMemberDetailsUrl(id));
}
},
});
const [changePassword, changePasswordOpts] = useChangeUserPasswordMutation({
onCompleted: data => {
if (!data.passwordChange?.errors.length) {
notify({
status: "success",
text: intl.formatMessage(commonMessages.savedChanges),
});
closeModal();
}
},
});
return {
updateUserAccount,
deleteAvatarResult,
deleteUserAvatar,
updateUserAvatar,
changePassword,
changePasswordOpts,
updateUserAccountOpts,
};
};

View file

@ -0,0 +1,47 @@
import {
useStaffMemberDeleteMutation,
useStaffMemberUpdateMutation,
} from "@dashboard/graphql";
import useNavigator from "@dashboard/hooks/useNavigator";
import useNotifier from "@dashboard/hooks/useNotifier";
import { commonMessages } from "@dashboard/intl";
import { useIntl } from "react-intl";
import { staffListUrl } from "../urls";
export const useStaffUserOperations = () => {
const notify = useNotifier();
const intl = useIntl();
const navigate = useNavigator();
const [updateStaffMember, updateStaffMemberOpts] =
useStaffMemberUpdateMutation({
onCompleted: data => {
if (!data.staffUpdate?.errors.length) {
notify({
status: "success",
text: intl.formatMessage(commonMessages.savedChanges),
});
}
},
});
const [deleteStaffMember, deleteResult] = useStaffMemberDeleteMutation({
onCompleted: data => {
if (!data.staffDelete?.errors.length) {
notify({
status: "success",
text: intl.formatMessage(commonMessages.savedChanges),
});
navigate(staffListUrl());
}
},
});
return {
updateStaffMember,
updateStaffMemberOpts,
deleteStaffMember,
deleteResult,
};
};

View file

@ -26,6 +26,26 @@ export const staffMemberUpdateMutation = gql`
} }
`; `;
export const userPassowrdChangeMutation = gql`
mutation UserPassowrdChange($newPassword: String!, $oldPassword: String!) {
passwordChange(newPassword: $newPassword, oldPassword: $oldPassword) {
errors {
...AccountError
}
}
}
`;
export const userAccountUpdateMutation = gql`
mutation UserAccountUpdate($input: AccountInput!) {
accountUpdate(input: $input) {
errors {
...AccountError
}
}
}
`;
export const staffMemberDeleteMutation = gql` export const staffMemberDeleteMutation = gql`
mutation StaffMemberDelete($id: ID!) { mutation StaffMemberDelete($id: ID!) {
staffDelete(id: $id) { staffDelete(id: $id) {
@ -36,8 +56,8 @@ export const staffMemberDeleteMutation = gql`
} }
`; `;
export const staffAvatarUpdateMutation = gql` export const userAvatarUpdateMutation = gql`
mutation StaffAvatarUpdate($image: Upload!) { mutation UserAvatarUpdate($image: Upload!) {
userAvatarUpdate(image: $image) { userAvatarUpdate(image: $image) {
errors { errors {
...AccountError ...AccountError
@ -52,8 +72,8 @@ export const staffAvatarUpdateMutation = gql`
} }
`; `;
export const staffAvatarDeleteMutation = gql` export const userAvatarDeleteMutation = gql`
mutation StaffAvatarDelete { mutation UserAvatarDelete {
userAvatarDelete { userAvatarDelete {
errors { errors {
...AccountError ...AccountError
@ -68,8 +88,8 @@ export const staffAvatarDeleteMutation = gql`
} }
`; `;
export const changeStaffPassword = gql` export const changeUserPassword = gql`
mutation ChangeStaffPassword($newPassword: String!, $oldPassword: String!) { mutation ChangeUserPassword($newPassword: String!, $oldPassword: String!) {
passwordChange(newPassword: $newPassword, oldPassword: $oldPassword) { passwordChange(newPassword: $newPassword, oldPassword: $oldPassword) {
errors { errors {
...AccountError ...AccountError

View file

@ -4,23 +4,9 @@ import NotFoundPage from "@dashboard/components/NotFoundPage";
import { hasPermissions } from "@dashboard/components/RequirePermissions"; import { hasPermissions } from "@dashboard/components/RequirePermissions";
import { WindowTitle } from "@dashboard/components/WindowTitle"; import { WindowTitle } from "@dashboard/components/WindowTitle";
import { DEFAULT_INITIAL_SEARCH_DATA } from "@dashboard/config"; import { DEFAULT_INITIAL_SEARCH_DATA } from "@dashboard/config";
import { import { PermissionEnum, useStaffMemberDetailsQuery } from "@dashboard/graphql";
PermissionEnum,
useChangeStaffPasswordMutation,
useStaffAvatarDeleteMutation,
useStaffAvatarUpdateMutation,
useStaffMemberDeleteMutation,
useStaffMemberDetailsQuery,
useStaffMemberUpdateMutation,
} from "@dashboard/graphql";
import useNavigator from "@dashboard/hooks/useNavigator"; import useNavigator from "@dashboard/hooks/useNavigator";
import useNotifier from "@dashboard/hooks/useNotifier"; import { extractMutationErrors, getStringOrPlaceholder } from "@dashboard/misc";
import { commonMessages, errorMessages } from "@dashboard/intl";
import {
extractMutationErrors,
getStringOrPlaceholder,
maybe,
} from "@dashboard/misc";
import usePermissionGroupSearch from "@dashboard/searches/usePermissionGroupSearch"; import usePermissionGroupSearch from "@dashboard/searches/usePermissionGroupSearch";
import { mapEdgesToItems } from "@dashboard/utils/maps"; import { mapEdgesToItems } from "@dashboard/utils/maps";
import { DialogContentText } from "@material-ui/core"; import { DialogContentText } from "@material-ui/core";
@ -31,6 +17,7 @@ import StaffDetailsPage, {
StaffDetailsFormData, StaffDetailsFormData,
} from "../components/StaffDetailsPage/StaffDetailsPage"; } from "../components/StaffDetailsPage/StaffDetailsPage";
import StaffPasswordResetDialog from "../components/StaffPasswordResetDialog"; import StaffPasswordResetDialog from "../components/StaffPasswordResetDialog";
import { useProfileOperations, useStaffUserOperations } from "../hooks";
import { import {
staffListUrl, staffListUrl,
staffMemberDetailsUrl, staffMemberDetailsUrl,
@ -45,7 +32,6 @@ interface OrderListProps {
export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => { export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
const navigate = useNavigator(); const navigate = useNavigator();
const notify = useNotifier();
const user = useUser(); const user = useUser();
const intl = useIntl(); const intl = useIntl();
@ -64,24 +50,28 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
variables: { id }, variables: { id },
skip: isUserSameAsViewer, skip: isUserSameAsViewer,
}); });
const {
deleteResult,
deleteStaffMember,
updateStaffMember,
updateStaffMemberOpts,
} = useStaffUserOperations();
const {
updateUserAccount,
updateUserAccountOpts,
changePassword,
changePasswordOpts,
deleteAvatarResult,
deleteUserAvatar,
updateUserAvatar,
} = useProfileOperations({ closeModal, id, refetch });
const staffMember = isUserSameAsViewer ? user.user : data?.user; const staffMember = isUserSameAsViewer ? user.user : data?.user;
const hasManageStaffPermission = hasPermissions(user.user.userPermissions, [ const hasManageStaffPermission = hasPermissions(user.user.userPermissions, [
PermissionEnum.MANAGE_STAFF, PermissionEnum.MANAGE_STAFF,
]); ]);
const [changePassword, changePasswordOpts] = useChangeStaffPasswordMutation({
onCompleted: data => {
if (data.passwordChange.errors.length === 0) {
notify({
status: "success",
text: intl.formatMessage(commonMessages.savedChanges),
});
closeModal();
}
},
});
const { const {
loadMore: loadMorePermissionGroups, loadMore: loadMorePermissionGroups,
search: searchPermissionGroups, search: searchPermissionGroups,
@ -91,66 +81,11 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
skip: !hasManageStaffPermission, skip: !hasManageStaffPermission,
}); });
const [updateStaffMember, updateStaffMemberOpts] =
useStaffMemberUpdateMutation({
onCompleted: data => {
if (!maybe(() => data.staffUpdate.errors.length !== 0)) {
notify({
status: "success",
text: intl.formatMessage(commonMessages.savedChanges),
});
}
},
});
const [deleteStaffMember, deleteResult] = useStaffMemberDeleteMutation({
onCompleted: data => {
if (!maybe(() => data.staffDelete.errors.length !== 0)) {
notify({
status: "success",
text: intl.formatMessage(commonMessages.savedChanges),
});
navigate(staffListUrl());
}
},
});
const [updateStaffAvatar] = useStaffAvatarUpdateMutation({
onCompleted: data => {
if (!maybe(() => data.userAvatarUpdate.errors.length !== 0)) {
notify({
status: "success",
text: intl.formatMessage(commonMessages.savedChanges),
});
refetch();
} else {
notify({
status: "error",
title: intl.formatMessage(errorMessages.imgageUploadErrorTitle),
text: intl.formatMessage(errorMessages.imageUploadErrorText),
});
}
},
});
const [deleteStaffAvatar, deleteAvatarResult] = useStaffAvatarDeleteMutation({
onCompleted: data => {
if (!maybe(() => data.userAvatarDelete.errors.length !== 0)) {
notify({
status: "success",
text: intl.formatMessage(commonMessages.savedChanges),
});
navigate(staffMemberDetailsUrl(id));
refetch();
}
},
});
if (staffMember === null) { if (staffMember === null) {
return <NotFoundPage backHref={staffListUrl()} />; return <NotFoundPage backHref={staffListUrl()} />;
} }
const handleUpdate = (formData: StaffDetailsFormData) => const handleStaffUpdate = (formData: StaffDetailsFormData) =>
extractMutationErrors( extractMutationErrors(
updateStaffMember({ updateStaffMember({
variables: { variables: {
@ -168,6 +103,18 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
}), }),
); );
const handleUserUpdate = (formData: StaffDetailsFormData) =>
extractMutationErrors(
updateUserAccount({
variables: {
input: {
firstName: formData.firstName,
lastName: formData.lastName,
},
},
}),
);
return ( return (
<> <>
<WindowTitle title={getStringOrPlaceholder(staffMember?.email)} /> <WindowTitle title={getStringOrPlaceholder(staffMember?.email)} />
@ -193,9 +140,9 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
}), }),
) )
} }
onSubmit={handleUpdate} onSubmit={isUserSameAsViewer ? handleUserUpdate : handleStaffUpdate}
onImageUpload={file => onImageUpload={file =>
updateStaffAvatar({ updateUserAvatar({
variables: { variables: {
image: file, image: file,
}, },
@ -212,7 +159,11 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
searchPermissionGroupsOpts?.data?.search, searchPermissionGroupsOpts?.data?.search,
)} )}
staffMember={staffMember} staffMember={staffMember}
saveButtonBarState={updateStaffMemberOpts.status} saveButtonBarState={
isUserSameAsViewer
? updateUserAccountOpts.status
: updateStaffMemberOpts.status
}
fetchMorePermissionGroups={{ fetchMorePermissionGroups={{
hasMore: hasMore:
searchPermissionGroupsOpts.data?.search?.pageInfo.hasNextPage, searchPermissionGroupsOpts.data?.search?.pageInfo.hasNextPage,
@ -257,7 +208,7 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
confirmButtonState={deleteAvatarResult.status} confirmButtonState={deleteAvatarResult.status}
variant="delete" variant="delete"
onClose={closeModal} onClose={closeModal}
onConfirm={deleteStaffAvatar} onConfirm={deleteUserAvatar}
> >
<DialogContentText> <DialogContentText>
<FormattedMessage <FormattedMessage