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:
bosiraphael
2023-11-16 17:09:10 +01:00
committed by GitHub
parent b1b6bbe7d3
commit 0ae9373532
18 changed files with 127 additions and 120 deletions

View File

@ -14,10 +14,6 @@ export const useOnboardingStatus = (): OnboardingStatus | undefined => {
const currentWorkspace = useRecoilValue(currentWorkspaceState);
const isLoggedIn = useIsLogged();
console.log(
getOnboardingStatus(isLoggedIn, currentWorkspaceMember, currentWorkspace),
);
return getOnboardingStatus(
isLoggedIn,
currentWorkspaceMember,

View File

@ -1,18 +1,8 @@
import { atom } from 'recoil';
import { ColorScheme } from '~/generated-metadata/graphql';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
export type CurrentWorkspaceMember = {
id: string;
locale: string;
colorScheme: ColorScheme;
allowImpersonation: boolean;
firstName: string;
lastName: string;
avatarUrl: string;
};
export const currentWorkspaceMemberState = atom<CurrentWorkspaceMember | null>({
export const currentWorkspaceMemberState = atom<WorkspaceMember | null>({
key: 'currentWorkspaceMemberState',
default: null,
});

View File

@ -1,5 +1,5 @@
import { CurrentWorkspaceMember } from '@/auth/states/currentWorkspaceMemberState';
import { CurrentWorkspace } from '@/auth/states/currentWorkspaceState';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
export enum OnboardingStatus {
OngoingUserCreation = 'ongoing_user_creation',
@ -10,7 +10,7 @@ export enum OnboardingStatus {
export const getOnboardingStatus = (
isLoggedIn: boolean,
currentWorkspaceMember: CurrentWorkspaceMember | null,
currentWorkspaceMember: WorkspaceMember | null,
currentWorkspace: CurrentWorkspace | null,
) => {
if (!isLoggedIn) {

View File

@ -6,22 +6,6 @@ import { EntitiesForMultipleEntitySelect } from '@/ui/input/relation-picker/comp
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
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 };
export type OrderBy =

View File

@ -54,21 +54,27 @@ export const NameFields = ({
onLastNameUpdate(lastName);
}
try {
if (!currentWorkspaceMember?.id) {
throw new Error('User is not logged in');
}
if (autoSave) {
if (!updateOneObject || objectNotFoundInMetadata) {
return;
throw new Error('Object not found in metadata');
}
await updateOneObject({
idToUpdate: currentWorkspaceMember?.id ?? '',
idToUpdate: currentWorkspaceMember?.id,
input: {
firstName,
lastName,
},
});
setCurrentWorkspaceMember(
(current) => ({ ...current, firstName, lastName } as any),
);
setCurrentWorkspaceMember({
...currentWorkspaceMember,
firstName,
lastName,
});
}
} catch (error) {
logError(error);

View File

@ -1,11 +1,9 @@
import { useState } from 'react';
import { getOperationName } from '@apollo/client/utilities';
import { useRecoilState } from 'recoil';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
import { ImageInput } from '@/ui/input/components/ImageInput';
import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser';
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
import { useUploadProfilePictureMutation } from '~/generated/graphql';
@ -35,6 +33,9 @@ export const ProfilePictureUploader = () => {
setUploadController(controller);
try {
if (!currentWorkspaceMember?.id) {
throw new Error('User is not logged in');
}
const result = await uploadPicture({
variables: {
file,
@ -44,7 +45,6 @@ export const ProfilePictureUploader = () => {
signal: controller.signal,
},
},
refetchQueries: [getOperationName(GET_CURRENT_USER) ?? ''],
});
setUploadController(null);
@ -53,21 +53,19 @@ export const ProfilePictureUploader = () => {
const avatarUrl = result?.data?.uploadProfilePicture;
if (!avatarUrl) {
return;
throw new Error('Avatar URL not found');
}
if (!updateOneObject || objectNotFoundInMetadata) {
return;
throw new Error('Object not found in metadata');
}
await updateOneObject({
idToUpdate: currentWorkspaceMember?.id ?? '',
idToUpdate: currentWorkspaceMember?.id,
input: {
avatarUrl,
},
});
setCurrentWorkspaceMember(
(current) => ({ ...current, avatarUrl } as any),
);
setCurrentWorkspaceMember({ ...currentWorkspaceMember, avatarUrl });
return result;
} catch (error) {
@ -84,18 +82,19 @@ export const ProfilePictureUploader = () => {
const handleRemove = async () => {
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({
idToUpdate: currentWorkspaceMember?.id ?? '',
idToUpdate: currentWorkspaceMember?.id,
input: {
avatarUrl: null,
},
});
setCurrentWorkspaceMember(
(current) => ({ ...current, avatarUrl: null } as any),
);
setCurrentWorkspaceMember({ ...currentWorkspaceMember, avatarUrl: null });
};
return (

View File

@ -20,21 +20,21 @@ export const ToggleField = () => {
const handleChange = async (value: boolean) => {
try {
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({
idToUpdate: currentWorkspaceMember?.id ?? '',
idToUpdate: currentWorkspaceMember?.id,
input: {
allowImpersonation: value,
},
});
setCurrentWorkspaceMember(
(current) =>
({
...current,
allowImpersonation: value,
} as any),
);
setCurrentWorkspaceMember({
...currentWorkspaceMember,
allowImpersonation: value,
});
} catch (err: any) {
enqueueSnackBar(err?.message, {
variant: 'error',

View File

@ -1,9 +1,7 @@
import { getOperationName } from '@apollo/client/utilities';
import { useRecoilValue } from 'recoil';
import { useRecoilState } from 'recoil';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { ImageInput } from '@/ui/input/components/ImageInput';
import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser';
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
import {
useRemoveWorkspaceLogoMutation,
@ -13,23 +11,41 @@ import {
export const WorkspaceLogoUploader = () => {
const [uploadLogo] = useUploadWorkspaceLogoMutation();
const [removeLogo] = useRemoveWorkspaceLogoMutation();
const currentWorkspace = useRecoilValue(currentWorkspaceState);
const [currentWorkspace, setCurrentWorkspace] = useRecoilState(
currentWorkspaceState,
);
const onUpload = async (file: File) => {
if (!file) {
return;
}
if (!currentWorkspace?.id) {
throw new Error('Workspace id not found');
}
await uploadLogo({
variables: {
file,
},
refetchQueries: [getOperationName(GET_CURRENT_USER) ?? ''],
onCompleted: (data) => {
setCurrentWorkspace({
...currentWorkspace,
logo: data.uploadWorkspaceLogo,
});
},
});
};
const onRemove = async () => {
if (!currentWorkspace?.id) {
throw new Error('Workspace id not found');
}
await removeLogo({
refetchQueries: [getOperationName(GET_CURRENT_USER) ?? ''],
onCompleted: () => {
setCurrentWorkspace({
...currentWorkspace,
logo: null,
});
},
});
};

View File

@ -1,7 +1,7 @@
import React from 'react';
import styled from '@emotion/styled';
import { ColorScheme } from '~/generated/graphql';
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
import { ColorSchemeCard } from './ColorSchemeCard';
@ -37,25 +37,25 @@ export const ColorSchemePicker = ({
<StyledContainer>
<StyledCardContainer>
<ColorSchemeCard
onClick={() => onChange(ColorScheme.Light)}
onClick={() => onChange('Light')}
variant="light"
selected={value === ColorScheme.Light}
selected={value === 'Light'}
/>
<StyledLabel>Light</StyledLabel>
</StyledCardContainer>
<StyledCardContainer>
<ColorSchemeCard
onClick={() => onChange(ColorScheme.Dark)}
onClick={() => onChange('Dark')}
variant="dark"
selected={value === ColorScheme.Dark}
selected={value === 'Dark'}
/>
<StyledLabel>Dark</StyledLabel>
</StyledCardContainer>
<StyledCardContainer>
<ColorSchemeCard
onClick={() => onChange(ColorScheme.System)}
onClick={() => onChange('System')}
variant="system"
selected={value === ColorScheme.System}
selected={value === 'System'}
/>
<StyledLabel>System settings</StyledLabel>
</StyledCardContainer>

View File

@ -1,7 +1,6 @@
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { currentUserState } from '@/auth/states/currentUserState';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
@ -53,7 +52,6 @@ type NavWorkspaceButtonProps = {
const NavWorkspaceButton = ({
showCollapseButton,
}: NavWorkspaceButtonProps) => {
const currentUser = useRecoilValue(currentUserState);
const currentWorkspace = useRecoilValue(currentWorkspaceState);
const DEFAULT_LOGO =

View File

@ -3,13 +3,11 @@ import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { currentUserState } from '@/auth/states/currentUserState';
import {
CurrentWorkspaceMember,
currentWorkspaceMemberState,
} from '@/auth/states/currentWorkspaceMemberState';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { supportChatState } from '@/client-config/states/supportChatState';
import { IconHelpCircle } from '@/ui/display/icon';
import { Button } from '@/ui/input/button/components/Button';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
import { User } from '~/generated/graphql';
const StyledButtonContainer = styled.div`
@ -42,10 +40,7 @@ const SupportChat = () => {
(
chatId: string,
currentUser: Pick<User, 'email' | 'supportUserHash'>,
currentWorkspaceMember: Pick<
CurrentWorkspaceMember,
'firstName' | 'lastName'
>,
currentWorkspaceMember: Pick<WorkspaceMember, 'firstName' | 'lastName'>,
) => {
const url = 'https://chat-assets.frontapp.com/v1/chat.bundle.js';
const script = document.querySelector(`script[src="${url}"]`);

View File

@ -82,8 +82,6 @@ type RecordTableProps = {
export const RecordTable = ({ updateEntityMutation }: RecordTableProps) => {
const tableBodyRef = useRef<HTMLDivElement>(null);
console.log('record table');
const {
leaveTableFocus,
setRowSelectedState,

View File

@ -3,7 +3,7 @@ import { useRecoilState } from 'recoil';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
import { ColorScheme } from '~/generated/graphql';
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
export const useColorScheme = () => {
const [currentWorkspaceMember] = useRecoilState(currentWorkspaceMemberState);
@ -12,7 +12,7 @@ export const useColorScheme = () => {
useUpdateOneObjectRecord({
objectNamePlural: 'workspaceMembersV2',
});
const colorScheme = currentWorkspaceMember?.colorScheme ?? ColorScheme.System;
const colorScheme = currentWorkspaceMember?.colorScheme ?? 'System';
const setColorScheme = useCallback(
async (value: ColorScheme) => {

View File

@ -18,10 +18,6 @@ export type UserPickerProps = {
initialSearchFilter?: string | null;
};
type UserForSelect = EntityForSelect & {
entityType: Entity.WorkspaceMember;
};
export const UserPicker = ({
userId,
onSubmit,

View File

@ -1,6 +1,11 @@
export type ColorScheme = 'Dark' | 'Light' | 'System';
export type WorkspaceMember = {
id: string;
firstName: string;
lastName: string;
avatarUrl: string;
avatarUrl: string | null;
locale: string;
colorScheme: ColorScheme;
allowImpersonation: boolean;
};