feat: I can upload a photo on person show page (#1103)

* I can upload a photo on person show page

Co-authored-by: v1b3m <vibenjamin6@gmail.com>
Co-authored-by: RubensRafael <rubensrafael2@live.com>
Co-authored-by: Rubens Rafael <70234898+RubensRafael@users.noreply.github.com>

* Add requested changes

Co-authored-by: v1b3m <vibenjamin6@gmail.com>
Co-authored-by: RubensRafael <rubensrafael2@live.com>
Co-authored-by: Rubens Rafael <70234898+RubensRafael@users.noreply.github.com>

---------

Co-authored-by: v1b3m <vibenjamin6@gmail.com>
Co-authored-by: RubensRafael <rubensrafael2@live.com>
Co-authored-by: Rubens Rafael <70234898+RubensRafael@users.noreply.github.com>
This commit is contained in:
gitstart-twenty
2023-08-10 02:29:10 +08:00
committed by GitHub
parent 1f4df67a89
commit b557766eb0
9 changed files with 205 additions and 11 deletions

View File

@ -848,6 +848,7 @@ export type EnumPipelineProgressableTypeFilter = {
export enum FileFolder {
Attachment = 'Attachment',
PersonPicture = 'PersonPicture',
ProfilePicture = 'ProfilePicture',
WorkspaceLogo = 'WorkspaceLogo'
}
@ -928,6 +929,7 @@ export type Mutation = {
uploadAttachment: Scalars['String'];
uploadFile: Scalars['String'];
uploadImage: Scalars['String'];
uploadPersonPicture: Scalars['String'];
uploadProfilePicture: Scalars['String'];
uploadWorkspaceLogo: Scalars['String'];
verify: Verify;
@ -1094,6 +1096,12 @@ export type MutationUploadImageArgs = {
};
export type MutationUploadPersonPictureArgs = {
file: Scalars['Upload'];
id: Scalars['String'];
};
export type MutationUploadProfilePictureArgs = {
file: Scalars['Upload'];
};
@ -2582,6 +2590,21 @@ export type DeleteManyPersonMutationVariables = Exact<{
export type DeleteManyPersonMutation = { __typename?: 'Mutation', deleteManyPerson: { __typename?: 'AffectedRows', count: number } };
export type UploadPersonPictureMutationVariables = Exact<{
id: Scalars['String'];
file: Scalars['Upload'];
}>;
export type UploadPersonPictureMutation = { __typename?: 'Mutation', uploadPersonPicture: string };
export type RemovePersonPictureMutationVariables = Exact<{
where: PersonWhereUniqueInput;
}>;
export type RemovePersonPictureMutation = { __typename?: 'Mutation', updateOnePerson?: { __typename?: 'Person', id: string, avatarUrl?: string | null } | null };
export type GetPipelinesQueryVariables = Exact<{
where?: InputMaybe<PipelineWhereInput>;
}>;
@ -4398,6 +4421,72 @@ export function useDeleteManyPersonMutation(baseOptions?: Apollo.MutationHookOpt
export type DeleteManyPersonMutationHookResult = ReturnType<typeof useDeleteManyPersonMutation>;
export type DeleteManyPersonMutationResult = Apollo.MutationResult<DeleteManyPersonMutation>;
export type DeleteManyPersonMutationOptions = Apollo.BaseMutationOptions<DeleteManyPersonMutation, DeleteManyPersonMutationVariables>;
export const UploadPersonPictureDocument = gql`
mutation UploadPersonPicture($id: String!, $file: Upload!) {
uploadPersonPicture(id: $id, file: $file)
}
`;
export type UploadPersonPictureMutationFn = Apollo.MutationFunction<UploadPersonPictureMutation, UploadPersonPictureMutationVariables>;
/**
* __useUploadPersonPictureMutation__
*
* To run a mutation, you first call `useUploadPersonPictureMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useUploadPersonPictureMutation` 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 [uploadPersonPictureMutation, { data, loading, error }] = useUploadPersonPictureMutation({
* variables: {
* id: // value for 'id'
* file: // value for 'file'
* },
* });
*/
export function useUploadPersonPictureMutation(baseOptions?: Apollo.MutationHookOptions<UploadPersonPictureMutation, UploadPersonPictureMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<UploadPersonPictureMutation, UploadPersonPictureMutationVariables>(UploadPersonPictureDocument, options);
}
export type UploadPersonPictureMutationHookResult = ReturnType<typeof useUploadPersonPictureMutation>;
export type UploadPersonPictureMutationResult = Apollo.MutationResult<UploadPersonPictureMutation>;
export type UploadPersonPictureMutationOptions = Apollo.BaseMutationOptions<UploadPersonPictureMutation, UploadPersonPictureMutationVariables>;
export const RemovePersonPictureDocument = gql`
mutation RemovePersonPicture($where: PersonWhereUniqueInput!) {
updateOnePerson(data: {avatarUrl: null}, where: $where) {
id
avatarUrl
}
}
`;
export type RemovePersonPictureMutationFn = Apollo.MutationFunction<RemovePersonPictureMutation, RemovePersonPictureMutationVariables>;
/**
* __useRemovePersonPictureMutation__
*
* To run a mutation, you first call `useRemovePersonPictureMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useRemovePersonPictureMutation` 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 [removePersonPictureMutation, { data, loading, error }] = useRemovePersonPictureMutation({
* variables: {
* where: // value for 'where'
* },
* });
*/
export function useRemovePersonPictureMutation(baseOptions?: Apollo.MutationHookOptions<RemovePersonPictureMutation, RemovePersonPictureMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<RemovePersonPictureMutation, RemovePersonPictureMutationVariables>(RemovePersonPictureDocument, options);
}
export type RemovePersonPictureMutationHookResult = ReturnType<typeof useRemovePersonPictureMutation>;
export type RemovePersonPictureMutationResult = Apollo.MutationResult<RemovePersonPictureMutation>;
export type RemovePersonPictureMutationOptions = Apollo.BaseMutationOptions<RemovePersonPictureMutation, RemovePersonPictureMutationVariables>;
export const GetPipelinesDocument = gql`
query GetPipelines($where: PipelineWhereInput) {
findManyPipeline(where: $where) {

View File

@ -54,3 +54,18 @@ export const DELETE_MANY_PERSON = gql`
}
}
`;
export const UPDATE_PERSON_PICTURE = gql`
mutation UploadPersonPicture($id: String!, $file: Upload!) {
uploadPersonPicture(id: $id, file: $file)
}
`;
export const REMOVE_PERSON_PICTURE = gql`
mutation RemovePersonPicture($where: PersonWhereUniqueInput!) {
updateOnePerson(data: { avatarUrl: null }, where: $where) {
id
avatarUrl
}
}
`;

View File

@ -1,3 +1,4 @@
import { ChangeEvent, useRef } from 'react';
import { Tooltip } from 'react-tooltip';
import styled from '@emotion/styled';
import { v4 as uuidV4 } from 'uuid';
@ -16,6 +17,7 @@ type OwnProps = {
title: string;
date: string;
renderTitleEditComponent?: () => JSX.Element;
onUploadPicture?: (file: File) => void;
};
const StyledShowPageSummaryCard = styled.div`
@ -62,27 +64,52 @@ const StyledTooltip = styled(Tooltip)`
padding: ${({ theme }) => theme.spacing(2)};
`;
const StyledAvatarWrapper = styled.div`
cursor: pointer;
`;
const StyledFileInput = styled.input`
display: none;
`;
export function ShowPageSummaryCard({
id,
logoOrAvatar,
title,
date,
renderTitleEditComponent,
onUploadPicture,
}: OwnProps) {
const beautifiedCreatedAt =
date !== '' ? beautifyPastDateRelativeToNow(date) : '';
const exactCreatedAt = date !== '' ? beautifyExactDateTime(date) : '';
const dateElementId = `date-id-${uuidV4()}`;
const inputFileRef = useRef<HTMLInputElement>(null);
const onFileChange = (e: ChangeEvent<HTMLInputElement>) => {
if (e.target.files) onUploadPicture?.(e.target.files[0]);
};
const onAvatarClick = () => {
if (onUploadPicture) inputFileRef?.current?.click?.();
};
return (
<StyledShowPageSummaryCard>
<Avatar
avatarUrl={logoOrAvatar}
size="xl"
colorId={id}
placeholder={title}
type="rounded"
/>
<StyledAvatarWrapper onClick={onAvatarClick}>
<Avatar
avatarUrl={logoOrAvatar}
size="xl"
colorId={id}
placeholder={title}
type="rounded"
/>
<StyledFileInput
ref={inputFileRef}
onChange={onFileChange}
type="file"
/>
</StyledAvatarWrapper>
<StyledInfoContainer>
<StyledTitle>
{renderTitleEditComponent ? (

View File

@ -1,15 +1,19 @@
import { useParams } from 'react-router-dom';
import { getOperationName } from '@apollo/client/utilities';
import { useTheme } from '@emotion/react';
import { Timeline } from '@/activities/timeline/components/Timeline';
import { PersonPropertyBox } from '@/people/components/PersonPropertyBox';
import { usePersonQuery } from '@/people/queries';
import { GET_PERSON, usePersonQuery } from '@/people/queries';
import { IconUser } from '@/ui/icon';
import { WithTopBarContainer } from '@/ui/layout/components/WithTopBarContainer';
import { ShowPageLeftContainer } from '@/ui/layout/show-page/components/ShowPageLeftContainer';
import { ShowPageRightContainer } from '@/ui/layout/show-page/components/ShowPageRightContainer';
import { ShowPageSummaryCard } from '@/ui/layout/show-page/components/ShowPageSummaryCard';
import { CommentableType } from '~/generated/graphql';
import {
CommentableType,
useUploadPersonPictureMutation,
} from '~/generated/graphql';
import { PeopleFullNameEditableField } from '../../modules/people/editable-field/components/PeopleFullNameEditableField';
import { ShowPageContainer } from '../../modules/ui/layout/components/ShowPageContainer';
@ -21,6 +25,20 @@ export function PersonShow() {
const person = data?.findUniquePerson;
const theme = useTheme();
const [uploadPicture] = useUploadPersonPictureMutation();
async function onUploadPicture(file: File) {
if (!file || !person?.id) {
return;
}
await uploadPicture({
variables: {
file,
id: person?.id,
},
refetchQueries: [getOperationName(GET_PERSON) ?? ''],
});
}
return (
<WithTopBarContainer
@ -38,6 +56,7 @@ export function PersonShow() {
renderTitleEditComponent={() =>
person ? <PeopleFullNameEditableField people={person} /> : <></>
}
onUploadPicture={onUploadPicture}
/>
{person && <PersonPropertyBox person={person} />}
</ShowPageLeftContainer>