V2 onboarding (#2543)
* fix cannot query avatarUrl * create workspace working * fix bugs related to refetch queries * onboarding working * updated dependency array * improve error handling * update types, remove as any, remove console logs * small fix
This commit is contained in:
@ -14,10 +14,6 @@ export const useOnboardingStatus = (): OnboardingStatus | undefined => {
|
|||||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||||
const isLoggedIn = useIsLogged();
|
const isLoggedIn = useIsLogged();
|
||||||
|
|
||||||
console.log(
|
|
||||||
getOnboardingStatus(isLoggedIn, currentWorkspaceMember, currentWorkspace),
|
|
||||||
);
|
|
||||||
|
|
||||||
return getOnboardingStatus(
|
return getOnboardingStatus(
|
||||||
isLoggedIn,
|
isLoggedIn,
|
||||||
currentWorkspaceMember,
|
currentWorkspaceMember,
|
||||||
|
|||||||
@ -1,18 +1,8 @@
|
|||||||
import { atom } from 'recoil';
|
import { atom } from 'recoil';
|
||||||
|
|
||||||
import { ColorScheme } from '~/generated-metadata/graphql';
|
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
|
||||||
|
|
||||||
export type CurrentWorkspaceMember = {
|
export const currentWorkspaceMemberState = atom<WorkspaceMember | null>({
|
||||||
id: string;
|
|
||||||
locale: string;
|
|
||||||
colorScheme: ColorScheme;
|
|
||||||
allowImpersonation: boolean;
|
|
||||||
firstName: string;
|
|
||||||
lastName: string;
|
|
||||||
avatarUrl: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const currentWorkspaceMemberState = atom<CurrentWorkspaceMember | null>({
|
|
||||||
key: 'currentWorkspaceMemberState',
|
key: 'currentWorkspaceMemberState',
|
||||||
default: null,
|
default: null,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { CurrentWorkspaceMember } from '@/auth/states/currentWorkspaceMemberState';
|
|
||||||
import { CurrentWorkspace } from '@/auth/states/currentWorkspaceState';
|
import { CurrentWorkspace } from '@/auth/states/currentWorkspaceState';
|
||||||
|
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
|
||||||
|
|
||||||
export enum OnboardingStatus {
|
export enum OnboardingStatus {
|
||||||
OngoingUserCreation = 'ongoing_user_creation',
|
OngoingUserCreation = 'ongoing_user_creation',
|
||||||
@ -10,7 +10,7 @@ export enum OnboardingStatus {
|
|||||||
|
|
||||||
export const getOnboardingStatus = (
|
export const getOnboardingStatus = (
|
||||||
isLoggedIn: boolean,
|
isLoggedIn: boolean,
|
||||||
currentWorkspaceMember: CurrentWorkspaceMember | null,
|
currentWorkspaceMember: WorkspaceMember | null,
|
||||||
currentWorkspace: CurrentWorkspace | null,
|
currentWorkspace: CurrentWorkspace | null,
|
||||||
) => {
|
) => {
|
||||||
if (!isLoggedIn) {
|
if (!isLoggedIn) {
|
||||||
|
|||||||
@ -6,22 +6,6 @@ import { EntitiesForMultipleEntitySelect } from '@/ui/input/relation-picker/comp
|
|||||||
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
type SelectStringKeys<T> = NonNullable<
|
|
||||||
{
|
|
||||||
[K in keyof T]: K extends '__typename'
|
|
||||||
? never
|
|
||||||
: T[K] extends string | undefined | null
|
|
||||||
? K
|
|
||||||
: never;
|
|
||||||
}[keyof T]
|
|
||||||
>;
|
|
||||||
|
|
||||||
type ExtractEntityTypeFromQueryResponse<T> = T extends {
|
|
||||||
searchResults: Array<infer U>;
|
|
||||||
}
|
|
||||||
? U
|
|
||||||
: never;
|
|
||||||
|
|
||||||
type SearchFilter = { fieldNames: string[]; filter: string | number };
|
type SearchFilter = { fieldNames: string[]; filter: string | number };
|
||||||
|
|
||||||
export type OrderBy =
|
export type OrderBy =
|
||||||
|
|||||||
@ -54,21 +54,27 @@ export const NameFields = ({
|
|||||||
onLastNameUpdate(lastName);
|
onLastNameUpdate(lastName);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
if (!currentWorkspaceMember?.id) {
|
||||||
|
throw new Error('User is not logged in');
|
||||||
|
}
|
||||||
|
|
||||||
if (autoSave) {
|
if (autoSave) {
|
||||||
if (!updateOneObject || objectNotFoundInMetadata) {
|
if (!updateOneObject || objectNotFoundInMetadata) {
|
||||||
return;
|
throw new Error('Object not found in metadata');
|
||||||
}
|
}
|
||||||
await updateOneObject({
|
await updateOneObject({
|
||||||
idToUpdate: currentWorkspaceMember?.id ?? '',
|
idToUpdate: currentWorkspaceMember?.id,
|
||||||
input: {
|
input: {
|
||||||
firstName,
|
firstName,
|
||||||
lastName,
|
lastName,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
setCurrentWorkspaceMember(
|
setCurrentWorkspaceMember({
|
||||||
(current) => ({ ...current, firstName, lastName } as any),
|
...currentWorkspaceMember,
|
||||||
);
|
firstName,
|
||||||
|
lastName,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logError(error);
|
logError(error);
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { getOperationName } from '@apollo/client/utilities';
|
|
||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||||
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
|
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
|
||||||
import { ImageInput } from '@/ui/input/components/ImageInput';
|
import { ImageInput } from '@/ui/input/components/ImageInput';
|
||||||
import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser';
|
|
||||||
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
|
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
|
||||||
import { useUploadProfilePictureMutation } from '~/generated/graphql';
|
import { useUploadProfilePictureMutation } from '~/generated/graphql';
|
||||||
|
|
||||||
@ -35,6 +33,9 @@ export const ProfilePictureUploader = () => {
|
|||||||
setUploadController(controller);
|
setUploadController(controller);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (!currentWorkspaceMember?.id) {
|
||||||
|
throw new Error('User is not logged in');
|
||||||
|
}
|
||||||
const result = await uploadPicture({
|
const result = await uploadPicture({
|
||||||
variables: {
|
variables: {
|
||||||
file,
|
file,
|
||||||
@ -44,7 +45,6 @@ export const ProfilePictureUploader = () => {
|
|||||||
signal: controller.signal,
|
signal: controller.signal,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
refetchQueries: [getOperationName(GET_CURRENT_USER) ?? ''],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
setUploadController(null);
|
setUploadController(null);
|
||||||
@ -53,21 +53,19 @@ export const ProfilePictureUploader = () => {
|
|||||||
const avatarUrl = result?.data?.uploadProfilePicture;
|
const avatarUrl = result?.data?.uploadProfilePicture;
|
||||||
|
|
||||||
if (!avatarUrl) {
|
if (!avatarUrl) {
|
||||||
return;
|
throw new Error('Avatar URL not found');
|
||||||
}
|
}
|
||||||
if (!updateOneObject || objectNotFoundInMetadata) {
|
if (!updateOneObject || objectNotFoundInMetadata) {
|
||||||
return;
|
throw new Error('Object not found in metadata');
|
||||||
}
|
}
|
||||||
await updateOneObject({
|
await updateOneObject({
|
||||||
idToUpdate: currentWorkspaceMember?.id ?? '',
|
idToUpdate: currentWorkspaceMember?.id,
|
||||||
input: {
|
input: {
|
||||||
avatarUrl,
|
avatarUrl,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
setCurrentWorkspaceMember(
|
setCurrentWorkspaceMember({ ...currentWorkspaceMember, avatarUrl });
|
||||||
(current) => ({ ...current, avatarUrl } as any),
|
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -84,18 +82,19 @@ export const ProfilePictureUploader = () => {
|
|||||||
|
|
||||||
const handleRemove = async () => {
|
const handleRemove = async () => {
|
||||||
if (!updateOneObject || objectNotFoundInMetadata) {
|
if (!updateOneObject || objectNotFoundInMetadata) {
|
||||||
return;
|
throw new Error('Object not found in metadata');
|
||||||
|
}
|
||||||
|
if (!currentWorkspaceMember?.id) {
|
||||||
|
throw new Error('User is not logged in');
|
||||||
}
|
}
|
||||||
await updateOneObject({
|
await updateOneObject({
|
||||||
idToUpdate: currentWorkspaceMember?.id ?? '',
|
idToUpdate: currentWorkspaceMember?.id,
|
||||||
input: {
|
input: {
|
||||||
avatarUrl: null,
|
avatarUrl: null,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
setCurrentWorkspaceMember(
|
setCurrentWorkspaceMember({ ...currentWorkspaceMember, avatarUrl: null });
|
||||||
(current) => ({ ...current, avatarUrl: null } as any),
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -20,21 +20,21 @@ export const ToggleField = () => {
|
|||||||
const handleChange = async (value: boolean) => {
|
const handleChange = async (value: boolean) => {
|
||||||
try {
|
try {
|
||||||
if (!updateOneObject || objectNotFoundInMetadata) {
|
if (!updateOneObject || objectNotFoundInMetadata) {
|
||||||
return;
|
throw new Error('Object not found in metadata');
|
||||||
|
}
|
||||||
|
if (!currentWorkspaceMember?.id) {
|
||||||
|
throw new Error('User is not logged in');
|
||||||
}
|
}
|
||||||
await updateOneObject({
|
await updateOneObject({
|
||||||
idToUpdate: currentWorkspaceMember?.id ?? '',
|
idToUpdate: currentWorkspaceMember?.id,
|
||||||
input: {
|
input: {
|
||||||
allowImpersonation: value,
|
allowImpersonation: value,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
setCurrentWorkspaceMember(
|
setCurrentWorkspaceMember({
|
||||||
(current) =>
|
...currentWorkspaceMember,
|
||||||
({
|
allowImpersonation: value,
|
||||||
...current,
|
});
|
||||||
allowImpersonation: value,
|
|
||||||
} as any),
|
|
||||||
);
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
enqueueSnackBar(err?.message, {
|
enqueueSnackBar(err?.message, {
|
||||||
variant: 'error',
|
variant: 'error',
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
import { getOperationName } from '@apollo/client/utilities';
|
import { useRecoilState } from 'recoil';
|
||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
|
|
||||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||||
import { ImageInput } from '@/ui/input/components/ImageInput';
|
import { ImageInput } from '@/ui/input/components/ImageInput';
|
||||||
import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser';
|
|
||||||
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
|
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
|
||||||
import {
|
import {
|
||||||
useRemoveWorkspaceLogoMutation,
|
useRemoveWorkspaceLogoMutation,
|
||||||
@ -13,23 +11,41 @@ import {
|
|||||||
export const WorkspaceLogoUploader = () => {
|
export const WorkspaceLogoUploader = () => {
|
||||||
const [uploadLogo] = useUploadWorkspaceLogoMutation();
|
const [uploadLogo] = useUploadWorkspaceLogoMutation();
|
||||||
const [removeLogo] = useRemoveWorkspaceLogoMutation();
|
const [removeLogo] = useRemoveWorkspaceLogoMutation();
|
||||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
const [currentWorkspace, setCurrentWorkspace] = useRecoilState(
|
||||||
|
currentWorkspaceState,
|
||||||
|
);
|
||||||
|
|
||||||
const onUpload = async (file: File) => {
|
const onUpload = async (file: File) => {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!currentWorkspace?.id) {
|
||||||
|
throw new Error('Workspace id not found');
|
||||||
|
}
|
||||||
await uploadLogo({
|
await uploadLogo({
|
||||||
variables: {
|
variables: {
|
||||||
file,
|
file,
|
||||||
},
|
},
|
||||||
refetchQueries: [getOperationName(GET_CURRENT_USER) ?? ''],
|
onCompleted: (data) => {
|
||||||
|
setCurrentWorkspace({
|
||||||
|
...currentWorkspace,
|
||||||
|
logo: data.uploadWorkspaceLogo,
|
||||||
|
});
|
||||||
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onRemove = async () => {
|
const onRemove = async () => {
|
||||||
|
if (!currentWorkspace?.id) {
|
||||||
|
throw new Error('Workspace id not found');
|
||||||
|
}
|
||||||
await removeLogo({
|
await removeLogo({
|
||||||
refetchQueries: [getOperationName(GET_CURRENT_USER) ?? ''],
|
onCompleted: () => {
|
||||||
|
setCurrentWorkspace({
|
||||||
|
...currentWorkspace,
|
||||||
|
logo: null,
|
||||||
|
});
|
||||||
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { ColorScheme } from '~/generated/graphql';
|
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
|
||||||
|
|
||||||
import { ColorSchemeCard } from './ColorSchemeCard';
|
import { ColorSchemeCard } from './ColorSchemeCard';
|
||||||
|
|
||||||
@ -37,25 +37,25 @@ export const ColorSchemePicker = ({
|
|||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<StyledCardContainer>
|
<StyledCardContainer>
|
||||||
<ColorSchemeCard
|
<ColorSchemeCard
|
||||||
onClick={() => onChange(ColorScheme.Light)}
|
onClick={() => onChange('Light')}
|
||||||
variant="light"
|
variant="light"
|
||||||
selected={value === ColorScheme.Light}
|
selected={value === 'Light'}
|
||||||
/>
|
/>
|
||||||
<StyledLabel>Light</StyledLabel>
|
<StyledLabel>Light</StyledLabel>
|
||||||
</StyledCardContainer>
|
</StyledCardContainer>
|
||||||
<StyledCardContainer>
|
<StyledCardContainer>
|
||||||
<ColorSchemeCard
|
<ColorSchemeCard
|
||||||
onClick={() => onChange(ColorScheme.Dark)}
|
onClick={() => onChange('Dark')}
|
||||||
variant="dark"
|
variant="dark"
|
||||||
selected={value === ColorScheme.Dark}
|
selected={value === 'Dark'}
|
||||||
/>
|
/>
|
||||||
<StyledLabel>Dark</StyledLabel>
|
<StyledLabel>Dark</StyledLabel>
|
||||||
</StyledCardContainer>
|
</StyledCardContainer>
|
||||||
<StyledCardContainer>
|
<StyledCardContainer>
|
||||||
<ColorSchemeCard
|
<ColorSchemeCard
|
||||||
onClick={() => onChange(ColorScheme.System)}
|
onClick={() => onChange('System')}
|
||||||
variant="system"
|
variant="system"
|
||||||
selected={value === ColorScheme.System}
|
selected={value === 'System'}
|
||||||
/>
|
/>
|
||||||
<StyledLabel>System settings</StyledLabel>
|
<StyledLabel>System settings</StyledLabel>
|
||||||
</StyledCardContainer>
|
</StyledCardContainer>
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { currentUserState } from '@/auth/states/currentUserState';
|
|
||||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||||
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
|
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
|
||||||
|
|
||||||
@ -53,7 +52,6 @@ type NavWorkspaceButtonProps = {
|
|||||||
const NavWorkspaceButton = ({
|
const NavWorkspaceButton = ({
|
||||||
showCollapseButton,
|
showCollapseButton,
|
||||||
}: NavWorkspaceButtonProps) => {
|
}: NavWorkspaceButtonProps) => {
|
||||||
const currentUser = useRecoilValue(currentUserState);
|
|
||||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||||
|
|
||||||
const DEFAULT_LOGO =
|
const DEFAULT_LOGO =
|
||||||
|
|||||||
@ -3,13 +3,11 @@ import styled from '@emotion/styled';
|
|||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { currentUserState } from '@/auth/states/currentUserState';
|
import { currentUserState } from '@/auth/states/currentUserState';
|
||||||
import {
|
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||||
CurrentWorkspaceMember,
|
|
||||||
currentWorkspaceMemberState,
|
|
||||||
} from '@/auth/states/currentWorkspaceMemberState';
|
|
||||||
import { supportChatState } from '@/client-config/states/supportChatState';
|
import { supportChatState } from '@/client-config/states/supportChatState';
|
||||||
import { IconHelpCircle } from '@/ui/display/icon';
|
import { IconHelpCircle } from '@/ui/display/icon';
|
||||||
import { Button } from '@/ui/input/button/components/Button';
|
import { Button } from '@/ui/input/button/components/Button';
|
||||||
|
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
|
||||||
import { User } from '~/generated/graphql';
|
import { User } from '~/generated/graphql';
|
||||||
|
|
||||||
const StyledButtonContainer = styled.div`
|
const StyledButtonContainer = styled.div`
|
||||||
@ -42,10 +40,7 @@ const SupportChat = () => {
|
|||||||
(
|
(
|
||||||
chatId: string,
|
chatId: string,
|
||||||
currentUser: Pick<User, 'email' | 'supportUserHash'>,
|
currentUser: Pick<User, 'email' | 'supportUserHash'>,
|
||||||
currentWorkspaceMember: Pick<
|
currentWorkspaceMember: Pick<WorkspaceMember, 'firstName' | 'lastName'>,
|
||||||
CurrentWorkspaceMember,
|
|
||||||
'firstName' | 'lastName'
|
|
||||||
>,
|
|
||||||
) => {
|
) => {
|
||||||
const url = 'https://chat-assets.frontapp.com/v1/chat.bundle.js';
|
const url = 'https://chat-assets.frontapp.com/v1/chat.bundle.js';
|
||||||
const script = document.querySelector(`script[src="${url}"]`);
|
const script = document.querySelector(`script[src="${url}"]`);
|
||||||
|
|||||||
@ -82,8 +82,6 @@ type RecordTableProps = {
|
|||||||
export const RecordTable = ({ updateEntityMutation }: RecordTableProps) => {
|
export const RecordTable = ({ updateEntityMutation }: RecordTableProps) => {
|
||||||
const tableBodyRef = useRef<HTMLDivElement>(null);
|
const tableBodyRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
console.log('record table');
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
leaveTableFocus,
|
leaveTableFocus,
|
||||||
setRowSelectedState,
|
setRowSelectedState,
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { useRecoilState } from 'recoil';
|
|||||||
|
|
||||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||||
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
|
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
|
||||||
import { ColorScheme } from '~/generated/graphql';
|
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
|
||||||
|
|
||||||
export const useColorScheme = () => {
|
export const useColorScheme = () => {
|
||||||
const [currentWorkspaceMember] = useRecoilState(currentWorkspaceMemberState);
|
const [currentWorkspaceMember] = useRecoilState(currentWorkspaceMemberState);
|
||||||
@ -12,7 +12,7 @@ export const useColorScheme = () => {
|
|||||||
useUpdateOneObjectRecord({
|
useUpdateOneObjectRecord({
|
||||||
objectNamePlural: 'workspaceMembersV2',
|
objectNamePlural: 'workspaceMembersV2',
|
||||||
});
|
});
|
||||||
const colorScheme = currentWorkspaceMember?.colorScheme ?? ColorScheme.System;
|
const colorScheme = currentWorkspaceMember?.colorScheme ?? 'System';
|
||||||
|
|
||||||
const setColorScheme = useCallback(
|
const setColorScheme = useCallback(
|
||||||
async (value: ColorScheme) => {
|
async (value: ColorScheme) => {
|
||||||
|
|||||||
@ -18,10 +18,6 @@ export type UserPickerProps = {
|
|||||||
initialSearchFilter?: string | null;
|
initialSearchFilter?: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type UserForSelect = EntityForSelect & {
|
|
||||||
entityType: Entity.WorkspaceMember;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const UserPicker = ({
|
export const UserPicker = ({
|
||||||
userId,
|
userId,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
|
|||||||
@ -1,6 +1,11 @@
|
|||||||
|
export type ColorScheme = 'Dark' | 'Light' | 'System';
|
||||||
|
|
||||||
export type WorkspaceMember = {
|
export type WorkspaceMember = {
|
||||||
id: string;
|
id: string;
|
||||||
firstName: string;
|
firstName: string;
|
||||||
lastName: string;
|
lastName: string;
|
||||||
avatarUrl: string;
|
avatarUrl: string | null;
|
||||||
|
locale: string;
|
||||||
|
colorScheme: ColorScheme;
|
||||||
|
allowImpersonation: boolean;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { Controller, SubmitHandler, useForm } from 'react-hook-form';
|
import { Controller, SubmitHandler, useForm } from 'react-hook-form';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { getOperationName } from '@apollo/client/utilities';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
@ -10,8 +9,8 @@ import { z } from 'zod';
|
|||||||
|
|
||||||
import { SubTitle } from '@/auth/components/SubTitle';
|
import { SubTitle } from '@/auth/components/SubTitle';
|
||||||
import { Title } from '@/auth/components/Title';
|
import { Title } from '@/auth/components/Title';
|
||||||
import { currentUserState } from '@/auth/states/currentUserState';
|
|
||||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||||
|
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
|
||||||
import { ProfilePictureUploader } from '@/settings/profile/components/ProfilePictureUploader';
|
import { ProfilePictureUploader } from '@/settings/profile/components/ProfilePictureUploader';
|
||||||
import { PageHotkeyScope } from '@/types/PageHotkeyScope';
|
import { PageHotkeyScope } from '@/types/PageHotkeyScope';
|
||||||
import { H2Title } from '@/ui/display/typography/components/H2Title';
|
import { H2Title } from '@/ui/display/typography/components/H2Title';
|
||||||
@ -19,8 +18,6 @@ import { useSnackBar } from '@/ui/feedback/snack-bar/hooks/useSnackBar';
|
|||||||
import { MainButton } from '@/ui/input/button/components/MainButton';
|
import { MainButton } from '@/ui/input/button/components/MainButton';
|
||||||
import { TextInput } from '@/ui/input/components/TextInput';
|
import { TextInput } from '@/ui/input/components/TextInput';
|
||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||||
import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser';
|
|
||||||
import { useUpdateUserMutation } from '~/generated/graphql';
|
|
||||||
|
|
||||||
const StyledContentContainer = styled.div`
|
const StyledContentContainer = styled.div`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -57,10 +54,14 @@ export const CreateProfile = () => {
|
|||||||
|
|
||||||
const { enqueueSnackBar } = useSnackBar();
|
const { enqueueSnackBar } = useSnackBar();
|
||||||
|
|
||||||
const [currentUser] = useRecoilState(currentUserState);
|
const [currentWorkspaceMember, setCurrentWorkspaceMember] = useRecoilState(
|
||||||
const [currentWorkspaceMember] = useRecoilState(currentWorkspaceMemberState);
|
currentWorkspaceMemberState,
|
||||||
|
);
|
||||||
|
|
||||||
const [updateUser] = useUpdateUserMutation();
|
const { updateOneObject, objectNotFoundInMetadata } =
|
||||||
|
useUpdateOneObjectRecord({
|
||||||
|
objectNameSingular: 'workspaceMemberV2',
|
||||||
|
});
|
||||||
|
|
||||||
// Form
|
// Form
|
||||||
const {
|
const {
|
||||||
@ -80,31 +81,37 @@ export const CreateProfile = () => {
|
|||||||
const onSubmit: SubmitHandler<Form> = useCallback(
|
const onSubmit: SubmitHandler<Form> = useCallback(
|
||||||
async (data) => {
|
async (data) => {
|
||||||
try {
|
try {
|
||||||
if (!currentUser?.id) {
|
if (!currentWorkspaceMember?.id) {
|
||||||
throw new Error('User is not logged in');
|
throw new Error('User is not logged in');
|
||||||
}
|
}
|
||||||
if (!data.firstName || !data.lastName) {
|
if (!data.firstName || !data.lastName) {
|
||||||
throw new Error('First name or last name is missing');
|
throw new Error('First name or last name is missing');
|
||||||
}
|
}
|
||||||
|
if (!updateOneObject || objectNotFoundInMetadata) {
|
||||||
|
throw new Error('Object not found in metadata');
|
||||||
|
}
|
||||||
|
|
||||||
const result = await updateUser({
|
const result = await updateOneObject({
|
||||||
variables: {
|
idToUpdate: currentWorkspaceMember?.id,
|
||||||
where: {
|
input: {
|
||||||
id: currentUser?.id,
|
firstName: data.firstName,
|
||||||
},
|
lastName: data.lastName,
|
||||||
data: {
|
|
||||||
firstName: data.firstName,
|
|
||||||
lastName: data.lastName,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
refetchQueries: [getOperationName(GET_CURRENT_USER) ?? ''],
|
|
||||||
awaitRefetchQueries: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result.errors || !result.data?.updateUser) {
|
if (result.errors || !result.data?.updateWorkspaceMemberV2) {
|
||||||
throw result.errors;
|
throw result.errors ?? new Error('Unknown error');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setCurrentWorkspaceMember(
|
||||||
|
(current) =>
|
||||||
|
({
|
||||||
|
...current,
|
||||||
|
firstName: data.firstName,
|
||||||
|
lastName: data.lastName,
|
||||||
|
} as any),
|
||||||
|
);
|
||||||
|
|
||||||
navigate('/');
|
navigate('/');
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
enqueueSnackBar(error?.message, {
|
enqueueSnackBar(error?.message, {
|
||||||
@ -112,7 +119,14 @@ export const CreateProfile = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[currentUser?.id, enqueueSnackBar, navigate, updateUser],
|
[
|
||||||
|
currentWorkspaceMember?.id,
|
||||||
|
enqueueSnackBar,
|
||||||
|
navigate,
|
||||||
|
objectNotFoundInMetadata,
|
||||||
|
setCurrentWorkspaceMember,
|
||||||
|
updateOneObject,
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { Controller, SubmitHandler, useForm } from 'react-hook-form';
|
import { Controller, SubmitHandler, useForm } from 'react-hook-form';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { getOperationName } from '@apollo/client/utilities';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
@ -15,7 +14,6 @@ import { useSnackBar } from '@/ui/feedback/snack-bar/hooks/useSnackBar';
|
|||||||
import { MainButton } from '@/ui/input/button/components/MainButton';
|
import { MainButton } from '@/ui/input/button/components/MainButton';
|
||||||
import { TextInput } from '@/ui/input/components/TextInput';
|
import { TextInput } from '@/ui/input/components/TextInput';
|
||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||||
import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser';
|
|
||||||
import { useUpdateWorkspaceMutation } from '~/generated/graphql';
|
import { useUpdateWorkspaceMutation } from '~/generated/graphql';
|
||||||
|
|
||||||
const StyledContentContainer = styled.div`
|
const StyledContentContainer = styled.div`
|
||||||
@ -69,8 +67,6 @@ export const CreateWorkspace = () => {
|
|||||||
displayName: data.name,
|
displayName: data.name,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
refetchQueries: [getOperationName(GET_CURRENT_USER) ?? ''],
|
|
||||||
awaitRefetchQueries: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result.errors || !result.data?.updateWorkspace) {
|
if (result.errors || !result.data?.updateWorkspace) {
|
||||||
|
|||||||
@ -89,6 +89,20 @@ const workspaceMemberMetadata = {
|
|||||||
icon: 'IconLanguage',
|
icon: 'IconLanguage',
|
||||||
isNullable: false,
|
isNullable: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
isCustom: false,
|
||||||
|
isActive: true,
|
||||||
|
type: FieldMetadataType.TEXT,
|
||||||
|
name: 'avatarUrl',
|
||||||
|
label: 'Avatar Url',
|
||||||
|
targetColumnMap: {
|
||||||
|
value: 'avatarUrl',
|
||||||
|
},
|
||||||
|
description: 'Workspace member avatar',
|
||||||
|
icon: 'IconFileUpload',
|
||||||
|
isNullable: true,
|
||||||
|
isSystem: false,
|
||||||
|
},
|
||||||
// Relations
|
// Relations
|
||||||
{
|
{
|
||||||
isCustom: false,
|
isCustom: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user