Commit ce7286b7 authored by aleclofabbro's avatar aleclofabbro

merged as they represent same data access, and - as two saparate - added complexity in several HOCs

parent 165ee20b
......@@ -2,39 +2,34 @@ import * as Types from '../../../graphql/types.generated';
import gql from 'graphql-tag';
export type SettingsPageMeFragment = (
{ __typename: 'Me' }
& { user: (
{ __typename: 'User' }
& Pick<Types.User, 'id' | 'name' | 'location' | 'summary' | 'displayUsername' | 'website' | 'extraInfo'>
& { icon: Types.Maybe<(
{ __typename: 'Content' }
& Pick<Types.Content, 'id' | 'url'>
)>, image: Types.Maybe<(
{ __typename: 'Content' }
& Pick<Types.Content, 'id' | 'url'>
)> }
) }
export type SettingsPageMeUserFragment = (
{ __typename: 'User' }
& Pick<Types.User, 'id' | 'name' | 'location' | 'summary' | 'displayUsername' | 'website' | 'extraInfo'>
& { icon: Types.Maybe<(
{ __typename: 'Content' }
& Pick<Types.Content, 'id' | 'url'>
)>, image: Types.Maybe<(
{ __typename: 'Content' }
& Pick<Types.Content, 'id' | 'url'>
)> }
);
export const SettingsPageMeFragmentDoc = gql`
fragment SettingsPageMe on Me {
user {
export const SettingsPageMeUserFragmentDoc = gql`
fragment SettingsPageMeUser on User {
id
name
icon {
id
name
icon {
id
url
}
image {
id
url
}
location
summary
displayUsername
website
extraInfo
url
}
image {
id
url
}
location
summary
displayUsername
website
extraInfo
}
`;
fragment SettingsPageMe on Me{
user {
id
name
icon{ id, url },
image{ id, url },
location,
summary,
displayUsername,
website,
extraInfo
}
fragment SettingsPageMeUser on User{
id
name
icon{ id, url },
image{ id, url },
location,
summary,
displayUsername,
website,
extraInfo
}
import { useMe } from 'fe/session/useMe';
import { useProfile } from 'fe/user/profile/useProfile';
import { useFormik } from 'formik';
import React, { FC, useMemo } from 'react';
import {
......@@ -27,8 +26,8 @@ export interface SettingsPage {
}
export const SettingsPage: FC<SettingsPage> = ({ basePath }) => {
const { me } = useMe();
const { profile, updateProfile } = useProfile();
const { me, updateProfile } = useMe();
const profile = me?.user;
const initialValues = useMemo<EditProfile>(
() => ({
......
import React, { FC } from 'react';
import Preferences, { EditPreferences } from 'ui/pages/settings/preferences';
import { useFormik } from 'formik';
import { useProfile } from 'fe/user/profile/useProfile';
import * as Yup from 'yup';
import { DOMAIN_REGEX } from 'mn-constants';
import { useMe } from 'fe/session/useMe';
const validationSchema = Yup.object<EditPreferences>({
moodleWebsite: Yup.string().matches(DOMAIN_REGEX)
});
export const PreferencesSettingsSection: FC = () => {
const { profile, updateProfile } = useProfile();
const { me, updateProfile } = useMe();
const profile = me?.user;
const formik = useFormik<EditPreferences>({
enableReinitialize: true,
initialValues: { moodleWebsite: profile?.extraInfo?.LMS?.site || '' },
......
import { useProfile } from 'fe/user/profile/useProfile';
import { LMSPrefsPanel } from './LMSPrefsPanel';
import React, { useMemo, useCallback, useState, useEffect } from 'react';
import { LMSPrefs, sendToMoodle } from './LMSintegration';
......@@ -76,10 +75,8 @@ export const useLMS = (resource: Maybe<ResourceLMS>) => {
};
export const useLMSPrefs = () => {
const { loading: loadingMe } = useMe();
const { profile, updateProfile, loading: loadingProfile } = useProfile();
const loading = loadingMe || loadingProfile;
const { loading, me, updateProfile } = useMe();
const profile = me?.user;
const [currentLMSPrefs, setCurrentLMSPrefs] = useState(
storage.get(LMS_PREFS_KEY) as LMSPrefs | null
);
......
import * as Types from '../../graphql/types.generated';
import { SidebarMeUserFragment } from '../../HOC/modules/Sidebar/Sidebar.generated';
import { SettingsPageMeUserFragment } from '../../HOC/pages/settings/SettingsPage.generated';
import gql from 'graphql-tag';
import { SettingsPageMeUserFragmentDoc } from '../../HOC/pages/settings/SettingsPage.generated';
import { SidebarMeUserFragmentDoc } from '../../HOC/modules/Sidebar/Sidebar.generated';
import * as ApolloReactCommon from '@apollo/react-common';
import * as ApolloReactHooks from '@apollo/react-hooks';
export type MeQueryVariables = {};
......@@ -31,11 +34,30 @@ export type UseMeDataFragment = (
& Pick<Types.Me, 'isInstanceAdmin' | 'email' | 'isConfirmed' | 'wantsEmailDigest' | 'wantsNotifications'>
& { user: (
{ __typename: 'User' }
& Pick<Types.User, 'id' | 'extraInfo'>
& Pick<Types.User, 'id'>
& SettingsPageMeUserFragment
& SidebarMeUserFragment
) }
);
export type MeUpdateMyProfileMutationVariables = {
profile: Types.UpdateProfileInput,
icon?: Types.Maybe<Types.UploadInput>,
image?: Types.Maybe<Types.UploadInput>
};
export type MeUpdateMyProfileMutation = (
{ __typename: 'RootMutationType' }
& { updateProfile: Types.Maybe<(
{ __typename: 'Me' }
& { user: (
{ __typename: 'User' }
& SettingsPageMeUserFragment
) }
)> }
);
export const UseMeDataFragmentDoc = gql`
fragment UseMeData on Me {
isInstanceAdmin
......@@ -45,11 +67,12 @@ export const UseMeDataFragmentDoc = gql`
wantsNotifications
user {
id
...SettingsPageMeUser
...SidebarMeUser
extraInfo
}
}
${SidebarMeUserFragmentDoc}`;
${SettingsPageMeUserFragmentDoc}
${SidebarMeUserFragmentDoc}`;
export const MeDocument = gql`
query me {
me {
......@@ -111,6 +134,42 @@ export function useMeLogoutMutation(baseOptions?: ApolloReactHooks.MutationHookO
export type MeLogoutMutationHookResult = ReturnType<typeof useMeLogoutMutation>;
export type MeLogoutMutationResult = ApolloReactCommon.MutationResult<MeLogoutMutation>;
export type MeLogoutMutationOptions = ApolloReactCommon.BaseMutationOptions<MeLogoutMutation, MeLogoutMutationVariables>;
export const MeUpdateMyProfileDocument = gql`
mutation meUpdateMyProfile($profile: UpdateProfileInput!, $icon: UploadInput, $image: UploadInput) {
updateProfile(profile: $profile, icon: $icon, image: $image) {
user {
...SettingsPageMeUser
}
}
}
${SettingsPageMeUserFragmentDoc}`;
export type MeUpdateMyProfileMutationFn = ApolloReactCommon.MutationFunction<MeUpdateMyProfileMutation, MeUpdateMyProfileMutationVariables>;
/**
* __useMeUpdateMyProfileMutation__
*
* To run a mutation, you first call `useMeUpdateMyProfileMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useMeUpdateMyProfileMutation` 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 [meUpdateMyProfileMutation, { data, loading, error }] = useMeUpdateMyProfileMutation({
* variables: {
* profile: // value for 'profile'
* icon: // value for 'icon'
* image: // value for 'image'
* },
* });
*/
export function useMeUpdateMyProfileMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<MeUpdateMyProfileMutation, MeUpdateMyProfileMutationVariables>) {
return ApolloReactHooks.useMutation<MeUpdateMyProfileMutation, MeUpdateMyProfileMutationVariables>(MeUpdateMyProfileDocument, baseOptions);
}
export type MeUpdateMyProfileMutationHookResult = ReturnType<typeof useMeUpdateMyProfileMutation>;
export type MeUpdateMyProfileMutationResult = ApolloReactCommon.MutationResult<MeUpdateMyProfileMutation>;
export type MeUpdateMyProfileMutationOptions = ApolloReactCommon.BaseMutationOptions<MeUpdateMyProfileMutation, MeUpdateMyProfileMutationVariables>;
export interface MeQueryOperation {
......@@ -149,3 +208,22 @@ export const MeLogoutMutationRefetch = (
context
})
export interface MeUpdateMyProfileMutationOperation {
operationName: 'meUpdateMyProfile'
result: MeUpdateMyProfileMutation
variables: MeUpdateMyProfileMutationVariables
type: 'mutation'
}
export const MeUpdateMyProfileMutationName:MeUpdateMyProfileMutationOperation['operationName'] = 'meUpdateMyProfile'
export const MeUpdateMyProfileMutationRefetch = (
variables:MeUpdateMyProfileMutationVariables,
context?:any
)=>({
query:MeUpdateMyProfileDocument,
variables,
context
})
......@@ -17,8 +17,15 @@ fragment UseMeData on Me {
wantsNotifications
user{
id
...SettingsPageMeUser
...SidebarMeUser
extraInfo
}
}
mutation meUpdateMyProfile($profile:UpdateProfileInput!, $icon: UploadInput, $image: UploadInput) {
updateProfile(profile:$profile, icon: $icon, image: $image){
user {
...SettingsPageMeUser
}
}
}
\ No newline at end of file
......@@ -2,10 +2,38 @@ import { mnCtx } from 'fe/lib/graphql/ctx';
import { useCallback, useMemo } from 'react';
import { useHistory } from 'react-router-dom';
import * as GQL from './me.generated';
import { useCallOrNotifyMustLogin } from 'HOC/lib/notifyMustLogin';
import { getMaybeUploadInput } from 'fe/mutation/upload/getUploadInput';
import Maybe from 'graphql/tsutils/Maybe';
import { UpdateProfileInput } from 'graphql/types.generated';
import { LMSPrefs } from 'fe/lib/moodleLMS/LMSintegration';
import {
withEncodedExtraInfo,
WithExtraInfo
} from 'fe/lib/extraInfo/extraInfo';
type UserProfileExtraInfo = {
LMS?: LMSPrefs;
};
export type UpdateProfileInputWithEI = WithExtraInfo<
UpdateProfileInput,
UserProfileExtraInfo
>;
export interface UpdateProfile {
profile: UpdateProfileInputWithEI;
icon?: Maybe<File | string>;
image?: Maybe<File | string>;
}
export const useMe = () => {
const meQ = GQL.useMeQuery({ context: mnCtx({ noShowError: true }) });
const [logoutMut, logoutStatus] = GQL.useMeLogoutMutation();
const [
updateProfileMutation,
updateProfileMutationStatus
] = GQL.useMeLogoutMutation();
const { push } = useHistory();
const me = meQ.data?.me;
const loading = meQ.loading;
......@@ -27,12 +55,30 @@ export const useMe = () => {
}).finally(() => push('/login'));
}, [me, logoutStatus.loading]);
const updateProfile = useCallOrNotifyMustLogin(
async ({ icon, image, profile }: UpdateProfile) => {
if (updateProfileMutationStatus.loading || !me?.user) {
return;
}
return updateProfileMutation({
variables: {
profile: withEncodedExtraInfo(profile, me.user),
icon: getMaybeUploadInput(icon, me.user.icon?.url),
image: getMaybeUploadInput(image, me.user.image?.url)
},
context: mnCtx({ ctx: 'Profile update' })
});
},
[updateProfileMutation, me, updateProfileMutationStatus]
);
return useMemo(() => {
return {
me,
isAdmin,
logout,
loading
loading,
updateProfile
};
}, [me, loading, isAdmin, logout]);
}, [me, loading, isAdmin, logout, updateProfile]);
};
import * as Types from '../../../graphql/types.generated';
import { SettingsPageMeFragment } from '../../../HOC/pages/settings/SettingsPage.generated';
import gql from 'graphql-tag';
import { SettingsPageMeFragmentDoc } from '../../../HOC/pages/settings/SettingsPage.generated';
import * as ApolloReactCommon from '@apollo/react-common';
import * as ApolloReactHooks from '@apollo/react-hooks';
export type MyProfileQueryVariables = {};
export type MyProfileQuery = (
{ __typename: 'RootQueryType' }
& { me: Types.Maybe<(
{ __typename: 'Me' }
& SettingsPageMeFragment
)> }
);
export type UpdateMyProfileMutationVariables = {
profile: Types.UpdateProfileInput,
icon?: Types.Maybe<Types.UploadInput>,
image?: Types.Maybe<Types.UploadInput>
};
export type UpdateMyProfileMutation = (
{ __typename: 'RootMutationType' }
& { updateProfile: Types.Maybe<(
{ __typename: 'Me' }
& SettingsPageMeFragment
)> }
);
export const MyProfileDocument = gql`
query myProfile {
me {
...SettingsPageMe
}
}
${SettingsPageMeFragmentDoc}`;
/**
* __useMyProfileQuery__
*
* To run a query within a React component, call `useMyProfileQuery` and pass it any options that fit your needs.
* When your component renders, `useMyProfileQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useMyProfileQuery({
* variables: {
* },
* });
*/
export function useMyProfileQuery(baseOptions?: ApolloReactHooks.QueryHookOptions<MyProfileQuery, MyProfileQueryVariables>) {
return ApolloReactHooks.useQuery<MyProfileQuery, MyProfileQueryVariables>(MyProfileDocument, baseOptions);
}
export function useMyProfileLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions<MyProfileQuery, MyProfileQueryVariables>) {
return ApolloReactHooks.useLazyQuery<MyProfileQuery, MyProfileQueryVariables>(MyProfileDocument, baseOptions);
}
export type MyProfileQueryHookResult = ReturnType<typeof useMyProfileQuery>;
export type MyProfileLazyQueryHookResult = ReturnType<typeof useMyProfileLazyQuery>;
export type MyProfileQueryResult = ApolloReactCommon.QueryResult<MyProfileQuery, MyProfileQueryVariables>;
export const UpdateMyProfileDocument = gql`
mutation updateMyProfile($profile: UpdateProfileInput!, $icon: UploadInput, $image: UploadInput) {
updateProfile(profile: $profile, icon: $icon, image: $image) {
...SettingsPageMe
}
}
${SettingsPageMeFragmentDoc}`;
export type UpdateMyProfileMutationFn = ApolloReactCommon.MutationFunction<UpdateMyProfileMutation, UpdateMyProfileMutationVariables>;
/**
* __useUpdateMyProfileMutation__
*
* To run a mutation, you first call `useUpdateMyProfileMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useUpdateMyProfileMutation` 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 [updateMyProfileMutation, { data, loading, error }] = useUpdateMyProfileMutation({
* variables: {
* profile: // value for 'profile'
* icon: // value for 'icon'
* image: // value for 'image'
* },
* });
*/
export function useUpdateMyProfileMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<UpdateMyProfileMutation, UpdateMyProfileMutationVariables>) {
return ApolloReactHooks.useMutation<UpdateMyProfileMutation, UpdateMyProfileMutationVariables>(UpdateMyProfileDocument, baseOptions);
}
export type UpdateMyProfileMutationHookResult = ReturnType<typeof useUpdateMyProfileMutation>;
export type UpdateMyProfileMutationResult = ApolloReactCommon.MutationResult<UpdateMyProfileMutation>;
export type UpdateMyProfileMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateMyProfileMutation, UpdateMyProfileMutationVariables>;
export interface MyProfileQueryOperation {
operationName: 'myProfile'
result: MyProfileQuery
variables: MyProfileQueryVariables
type: 'query'
}
export const MyProfileQueryName:MyProfileQueryOperation['operationName'] = 'myProfile'
export const MyProfileQueryRefetch = (
variables:MyProfileQueryVariables,
context?:any
)=>({
query:MyProfileDocument,
variables,
context
})
export interface UpdateMyProfileMutationOperation {
operationName: 'updateMyProfile'
result: UpdateMyProfileMutation
variables: UpdateMyProfileMutationVariables
type: 'mutation'
}
export const UpdateMyProfileMutationName:UpdateMyProfileMutationOperation['operationName'] = 'updateMyProfile'
export const UpdateMyProfileMutationRefetch = (
variables:UpdateMyProfileMutationVariables,
context?:any
)=>({
query:UpdateMyProfileDocument,
variables,
context
})
query myProfile {
me{
...SettingsPageMe
}
}
mutation updateMyProfile($profile:UpdateProfileInput!, $icon: UploadInput, $image: UploadInput) {
updateProfile(profile:$profile, icon: $icon, image: $image){
...SettingsPageMe
}
}
\ No newline at end of file
import {
withEncodedExtraInfo,
WithExtraInfo
} from 'fe/lib/extraInfo/extraInfo';
import { mnCtx } from 'fe/lib/graphql/ctx';
import { LMSPrefs } from 'fe/lib/moodleLMS/LMSintegration';
import { getMaybeUploadInput } from 'fe/mutation/upload/getUploadInput';
import Maybe from 'graphql/tsutils/Maybe';
import { UpdateProfileInput } from 'graphql/types.generated';
import { useCallOrNotifyMustLogin } from 'HOC/lib/notifyMustLogin';
import { useMemo } from 'react';
import {
useMyProfileQuery,
useUpdateMyProfileMutation
} from './useProfile.generated';
type UserProfileExtraInfo = {
LMS?: LMSPrefs;
};
export type UpdateProfileInputWithEI = WithExtraInfo<
UpdateProfileInput,
UserProfileExtraInfo
>;
export interface UpdateProfile {
profile: UpdateProfileInputWithEI;
icon?: Maybe<File | string>;
image?: Maybe<File | string>;
}
export const useProfile = () => {
const profileQ = useMyProfileQuery({ context: mnCtx({ noShowError: true }) });
const [updateProfileMutation] = useUpdateMyProfileMutation();
const updateProfile = useCallOrNotifyMustLogin(
({ icon, image, profile }: UpdateProfile) =>
updateProfileMutation({
variables: {
profile: withEncodedExtraInfo(profile, profileQ.data?.me?.user),
icon: getMaybeUploadInput(icon, profileQ.data?.me?.user.icon?.url),
image: getMaybeUploadInput(image, profileQ.data?.me?.user.image?.url)
},
context: mnCtx({ ctx: 'Profile update' })
}),
[updateProfileMutation, profileQ]
);
return useMemo(() => {
const user = profileQ.data?.me?.user;
const profile = user as Maybe<
WithExtraInfo<typeof user, UserProfileExtraInfo>
>;
const loading = profileQ.loading;
return {
loading,
profile,
updateProfile
};
}, [updateProfile, profileQ]);
};
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment