Fix Tasks and Activities - Part 1 (#2624)

Fixed
This commit is contained in:
Lucas Bordeau
2023-11-21 23:29:40 +01:00
committed by GitHub
parent 77733f2bc8
commit a67199e0c3
18 changed files with 240 additions and 162 deletions

View File

@ -5,7 +5,7 @@ import { Comment as CommentType } from '@/activities/types/Comment';
import { CommentHeader } from './CommentHeader'; import { CommentHeader } from './CommentHeader';
type CommentProps = { type CommentProps = {
comment: Omit<CommentType, 'activityId'>; comment: CommentType;
actionBar?: React.ReactNode; actionBar?: React.ReactNode;
}; };

View File

@ -8,11 +8,6 @@ import {
beautifyPastDateRelativeToNow, beautifyPastDateRelativeToNow,
} from '~/utils/date-utils'; } from '~/utils/date-utils';
type CommentHeaderProps = {
comment: Pick<Comment, 'id' | 'author' | 'createdAt'>;
actionBar?: React.ReactNode;
};
const StyledContainer = styled.div` const StyledContainer = styled.div`
align-items: center; align-items: center;
display: flex; display: flex;
@ -61,6 +56,11 @@ const StyledTooltip = styled(Tooltip)`
padding: 8px; padding: 8px;
`; `;
type CommentHeaderProps = {
comment: Pick<Comment, 'id' | 'author' | 'createdAt'>;
actionBar?: React.ReactNode;
};
export const CommentHeader = ({ comment, actionBar }: CommentHeaderProps) => { export const CommentHeader = ({ comment, actionBar }: CommentHeaderProps) => {
const beautifiedCreatedAt = beautifyPastDateRelativeToNow(comment.createdAt); const beautifiedCreatedAt = beautifyPastDateRelativeToNow(comment.createdAt);
const exactCreatedAt = beautifyExactDateTime(comment.createdAt); const exactCreatedAt = beautifyExactDateTime(comment.createdAt);

View File

@ -4,7 +4,7 @@ import { Comment } from '@/activities/types/Comment';
export const mockComment: Pick< export const mockComment: Pick<
Comment, Comment,
'id' | 'author' | 'createdAt' | 'body' | 'updatedAt' 'id' | 'author' | 'createdAt' | 'body' | 'updatedAt' | 'activityId'
> = { > = {
id: 'fake_comment_1_uuid', id: 'fake_comment_1_uuid',
body: 'Hello, this is a comment.', body: 'Hello, this is a comment.',
@ -18,11 +18,12 @@ export const mockComment: Pick<
}, },
createdAt: DateTime.fromFormat('2021-03-12', 'yyyy-MM-dd').toISO() ?? '', createdAt: DateTime.fromFormat('2021-03-12', 'yyyy-MM-dd').toISO() ?? '',
updatedAt: DateTime.fromFormat('2021-03-13', 'yyyy-MM-dd').toISO() ?? '', updatedAt: DateTime.fromFormat('2021-03-13', 'yyyy-MM-dd').toISO() ?? '',
activityId: 'fake_activity_1_uuid',
}; };
export const mockCommentWithLongValues: Pick< export const mockCommentWithLongValues: Pick<
Comment, Comment,
'id' | 'author' | 'createdAt' | 'body' | 'updatedAt' 'id' | 'author' | 'createdAt' | 'body' | 'updatedAt' | 'activityId'
> = { > = {
id: 'fake_comment_2_uuid', id: 'fake_comment_2_uuid',
body: 'Hello, this is a comment. Hello, this is a comment. Hello, this is a comment. Hello, this is a comment. Hello, this is a comment. Hello, this is a comment.', body: 'Hello, this is a comment. Hello, this is a comment. Hello, this is a comment. Hello, this is a comment. Hello, this is a comment. Hello, this is a comment.',
@ -36,4 +37,5 @@ export const mockCommentWithLongValues: Pick<
}, },
createdAt: DateTime.fromFormat('2021-03-12', 'yyyy-MM-dd').toISO() ?? '', createdAt: DateTime.fromFormat('2021-03-12', 'yyyy-MM-dd').toISO() ?? '',
updatedAt: DateTime.fromFormat('2021-03-13', 'yyyy-MM-dd').toISO() ?? '', updatedAt: DateTime.fromFormat('2021-03-13', 'yyyy-MM-dd').toISO() ?? '',
activityId: 'fake_activity_1_uuid',
}; };

View File

@ -23,7 +23,7 @@ export const ActivityBodyEditor = ({
}: ActivityBodyEditorProps) => { }: ActivityBodyEditorProps) => {
const [body, setBody] = useState<string | null>(null); const [body, setBody] = useState<string | null>(null);
const { updateOneObject } = useUpdateOneObjectRecord({ const { updateOneObject } = useUpdateOneObjectRecord({
objectNameSingular: 'Activity', objectNameSingular: 'activity',
}); });
useEffect(() => { useEffect(() => {

View File

@ -6,21 +6,15 @@ import { v4 } from 'uuid';
import { Comment } from '@/activities/comment/Comment'; import { Comment } from '@/activities/comment/Comment';
import { Activity } from '@/activities/types/Activity'; import { Activity } from '@/activities/types/Activity';
import { Comment as CommentType } from '@/activities/types/Comment'; import { Comment as CommentType } from '@/activities/types/Comment';
import { currentUserState } from '@/auth/states/currentUserState'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { useCreateOneObjectRecord } from '@/object-record/hooks/useCreateOneObjectRecord'; import { useCreateOneObjectRecord } from '@/object-record/hooks/useCreateOneObjectRecord';
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
import { import {
AutosizeTextInput, AutosizeTextInput,
AutosizeTextInputVariant, AutosizeTextInputVariant,
} from '@/ui/input/components/AutosizeTextInput'; } from '@/ui/input/components/AutosizeTextInput';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
type ActivityCommentsProps = {
activity: Pick<Activity, 'id'> & {
comments: Array<CommentType>;
};
scrollableContainerRef: React.RefObject<HTMLDivElement>;
};
const StyledThreadItemListContainer = styled.div` const StyledThreadItemListContainer = styled.div`
align-items: flex-start; align-items: flex-start;
border-top: 1px solid ${({ theme }) => theme.border.color.light}; border-top: 1px solid ${({ theme }) => theme.border.color.light};
@ -57,16 +51,31 @@ const StyledThreadCommentTitle = styled.div`
text-transform: uppercase; text-transform: uppercase;
`; `;
type ActivityCommentsProps = {
activity: Pick<Activity, 'id'>;
scrollableContainerRef: React.RefObject<HTMLDivElement>;
};
export const ActivityComments = ({ export const ActivityComments = ({
activity, activity,
scrollableContainerRef, scrollableContainerRef,
}: ActivityCommentsProps) => { }: ActivityCommentsProps) => {
const currentUser = useRecoilValue(currentUserState);
const { createOneObject } = useCreateOneObjectRecord({ const { createOneObject } = useCreateOneObjectRecord({
objectNameSingular: 'comment', objectNameSingular: 'comment',
}); });
if (!currentUser) { const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
const { objects: comments } = useFindManyObjectRecords({
objectNamePlural: 'comments',
filter: {
activityId: {
eq: activity?.id ?? '',
},
},
});
if (!currentWorkspaceMember) {
return <></>; return <></>;
} }
@ -76,10 +85,10 @@ export const ActivityComments = ({
} }
createOneObject?.({ createOneObject?.({
commentId: v4(), id: v4(),
authorId: currentUser?.id ?? '', authorId: currentWorkspaceMember?.id ?? '',
activityId: activity?.id ?? '', activityId: activity?.id ?? '',
commentText: commentText, body: commentText,
createdAt: new Date().toISOString(), createdAt: new Date().toISOString(),
}); });
}; };
@ -93,26 +102,28 @@ export const ActivityComments = ({
}); });
}; };
console.log('asd', { activity, comments });
return ( return (
<> <>
{activity?.comments.length > 0 && ( {comments.length > 0 && (
<> <>
<StyledThreadItemListContainer> <StyledThreadItemListContainer>
<StyledThreadCommentTitle>Comments</StyledThreadCommentTitle> <StyledThreadCommentTitle>Comments</StyledThreadCommentTitle>
{activity?.comments?.map((comment) => ( {comments?.map((comment) => (
<Comment key={comment.id} comment={comment} /> <Comment key={comment.id} comment={comment as CommentType} />
))} ))}
</StyledThreadItemListContainer> </StyledThreadItemListContainer>
</> </>
)} )}
<StyledCommentActionBar> <StyledCommentActionBar>
{currentUser && ( {currentWorkspaceMember && (
<AutosizeTextInput <AutosizeTextInput
onValidate={handleSendComment} onValidate={handleSendComment}
onFocus={handleFocus} onFocus={handleFocus}
variant={AutosizeTextInputVariant.Button} variant={AutosizeTextInputVariant.Button}
placeholder={activity?.comments.length > 0 ? 'Reply...' : undefined} placeholder={comments.length > 0 ? 'Reply...' : undefined}
/> />
)} )}
</StyledCommentActionBar> </StyledCommentActionBar>

View File

@ -13,8 +13,6 @@ import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember'; import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
import { debounce } from '~/utils/debounce'; import { debounce } from '~/utils/debounce';
import { ActivityRelationEditableField } from '../editable-fields/components/ActivityRelationEditableField';
import { ActivityTitle } from './ActivityTitle'; import { ActivityTitle } from './ActivityTitle';
import '@blocknote/core/style.css'; import '@blocknote/core/style.css';
@ -75,6 +73,10 @@ export const ActivityEditor = ({
const [hasUserManuallySetTitle, setHasUserManuallySetTitle] = const [hasUserManuallySetTitle, setHasUserManuallySetTitle] =
useState<boolean>(false); useState<boolean>(false);
console.log({
activity,
});
const [title, setTitle] = useState<string | null>(activity.title ?? ''); const [title, setTitle] = useState<string | null>(activity.title ?? '');
const [completedAt, setCompletedAt] = useState<string | null>( const [completedAt, setCompletedAt] = useState<string | null>(
activity.completedAt ?? '', activity.completedAt ?? '',
@ -149,7 +151,7 @@ export const ActivityEditor = ({
</RecoilScope> */} </RecoilScope> */}
</> </>
)} )}
<ActivityRelationEditableField activity={activity} /> {/* <ActivityRelationEditableField activity={activity} /> */}
</PropertyBox> </PropertyBox>
</StyledTopContainer> </StyledTopContainer>
<ActivityBodyEditor <ActivityBodyEditor
@ -159,10 +161,7 @@ export const ActivityEditor = ({
</StyledUpperPartContainer> </StyledUpperPartContainer>
{showComment && ( {showComment && (
<ActivityComments <ActivityComments
activity={{ activity={activity}
id: activity.id,
comments: activity.comments ?? [],
}}
scrollableContainerRef={containerRef} scrollableContainerRef={containerRef}
/> />
)} )}

View File

@ -1,10 +1,7 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { ActivityTarget } from '@/activities/types/ActivityTarget';
import { CompanyChip } from '@/companies/components/CompanyChip'; import { CompanyChip } from '@/companies/components/CompanyChip';
import { Company } from '@/companies/types/Company';
import { PersonChip } from '@/people/components/PersonChip'; import { PersonChip } from '@/people/components/PersonChip';
import { Person } from '@/people/types/Person';
import { getLogoUrlFromDomainName } from '~/utils'; import { getLogoUrlFromDomainName } from '~/utils';
const StyledContainer = styled.div` const StyledContainer = styled.div`
@ -13,23 +10,15 @@ const StyledContainer = styled.div`
gap: ${({ theme }) => theme.spacing(1)}; gap: ${({ theme }) => theme.spacing(1)};
`; `;
export const ActivityTargetChips = ({ // TODO: fix edges pagination formatting on n+N
targets, export const ActivityTargetChips = ({ targets }: { targets?: any }) => {
}: {
targets?: Array<
Pick<ActivityTarget, 'id'> & {
person?: Pick<Person, 'id' | 'name' | 'avatarUrl'> | null;
company?: Pick<Company, 'id' | 'domainName' | 'name'> | null;
}
> | null;
}) => {
if (!targets) { if (!targets) {
return null; return null;
} }
return ( return (
<StyledContainer> <StyledContainer>
{targets.map(({ company, person }) => { {targets?.edges?.map(({ company, person }: any) => {
if (company) { if (company) {
return ( return (
<CompanyChip <CompanyChip

View File

@ -1,21 +1,52 @@
import { Note } from '@/activities/types/Note'; import { Note } from '@/activities/types/Note';
import { useOptimisticEffect } from '@/apollo/optimistic-effect/hooks/useOptimisticEffect';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { getRecordOptimisticEffectDefinition } from '@/object-record/graphql/optimistic-effect-definition/getRecordOptimisticEffectDefinition';
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords'; import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
import { ActivityTargetableEntity } from '../../types/ActivityTargetableEntity'; import { ActivityTargetableEntity } from '../../types/ActivityTargetableEntity';
export const useNotes = (entity: ActivityTargetableEntity) => { export const useNotes = (entity: ActivityTargetableEntity) => {
const { objects: notes } = useFindManyObjectRecords({ const { objects: activityTargets } = useFindManyObjectRecords({
objectNamePlural: 'activities', objectNamePlural: 'activityTargets',
filter: { filter: {
type: { equals: 'None' }, [entity.type === 'Company' ? 'companyId' : 'personId']: { eq: entity.id },
activityTargets: { },
some: { });
OR: [
{ companyId: { equals: entity.id } }, const { objectMetadataItem: activityObjectMetadataItem } =
{ personId: { equals: entity.id } }, useObjectMetadataItem({
], objectNameSingular: 'activity',
}, });
},
const { registerOptimisticEffect } = useOptimisticEffect({
objectNameSingular: activityObjectMetadataItem?.nameSingular,
});
const filter = {
id: {
in: activityTargets?.map((activityTarget) => activityTarget.activityId),
},
type: { eq: 'Note' },
};
const orderBy = {
createdAt: 'AscNullsFirst',
};
const { objects: notes } = useFindManyObjectRecords({
skip: !activityTargets?.length,
objectNamePlural: 'activities',
filter,
orderBy,
onCompleted: () => {
if (activityObjectMetadataItem) {
registerOptimisticEffect({
variables: { orderBy, filter },
definition: getRecordOptimisticEffectDefinition({
objectMetadataItem: activityObjectMetadataItem,
}),
});
}
}, },
}); });

View File

@ -35,7 +35,7 @@ export const RightDrawerActivity = ({
); );
const { object: activity } = useFindOneObjectRecord({ const { object: activity } = useFindOneObjectRecord({
objectNameSingular: 'activityId', objectNameSingular: 'activity',
objectRecordId: activityId, objectRecordId: activityId,
skip: !activityId, skip: !activityId,
onCompleted: (activity: Activity) => { onCompleted: (activity: Activity) => {

View File

@ -2,55 +2,108 @@ import { DateTime } from 'luxon';
import { Activity } from '@/activities/types/Activity'; import { Activity } from '@/activities/types/Activity';
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity'; import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
import { useOptimisticEffect } from '@/apollo/optimistic-effect/hooks/useOptimisticEffect';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { getRecordOptimisticEffectDefinition } from '@/object-record/graphql/optimistic-effect-definition/getRecordOptimisticEffectDefinition';
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords'; import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter'; import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
import { turnFiltersIntoWhereClauseV2 } from '@/ui/object/object-filter-dropdown/utils/turnFiltersIntoWhereClauseV2';
import { parseDate } from '~/utils/date-utils'; import { parseDate } from '~/utils/date-utils';
export const useTasks = (entity?: ActivityTargetableEntity) => { export const useTasks = (entity?: ActivityTargetableEntity) => {
const { selectedFilter } = useFilter(); const { selectedFilter } = useFilter();
const whereFilters = entity const { objects: activityTargets } = useFindManyObjectRecords({
? { objectNamePlural: 'activityTargets',
activityTargets: { filter: {
some: { [entity?.type === 'Company' ? 'companyId' : 'personId']: {
OR: [ eq: entity?.id,
{ companyId: { equals: entity.id } }, },
{ personId: { equals: entity.id } }, },
], });
},
}, const { objectMetadataItem: activityObjectMetadataItem } =
} useObjectMetadataItem({
: Object.assign({}, turnFiltersIntoWhereClauseV2([], [])); objectNameSingular: 'activity',
});
const { registerOptimisticEffect } = useOptimisticEffect({
objectNameSingular: activityObjectMetadataItem?.nameSingular,
});
const { objects: completeTasksData } = useFindManyObjectRecords({ const { objects: completeTasksData } = useFindManyObjectRecords({
objectNamePlural: 'activities', objectNamePlural: 'activities',
skip: !entity && !selectedFilter, skip: !entity && !selectedFilter,
filter: { filter: {
type: { equals: 'Task' },
completedAt: { is: 'NOT_NULL' }, completedAt: { is: 'NOT_NULL' },
...whereFilters, id: {
}, in: activityTargets?.map((activityTarget) => activityTarget.activityId),
orderBy: [
{
createdAt: 'AscNullIsFirst',
}, },
], type: { eq: 'Task' },
},
orderBy: {
createdAt: 'DescNullsFirst',
},
onCompleted: () => {
if (activityObjectMetadataItem) {
registerOptimisticEffect({
variables: {
filter: {
completedAt: { is: 'NOT_NULL' },
id: {
in: activityTargets?.map(
(activityTarget) => activityTarget.activityId,
),
},
type: { eq: 'Task' },
},
orderBy: {
createdAt: 'DescNullsFirst',
},
},
definition: getRecordOptimisticEffectDefinition({
objectMetadataItem: activityObjectMetadataItem,
}),
});
}
},
}); });
const { objects: incompleteTaskData } = useFindManyObjectRecords({ const { objects: incompleteTaskData } = useFindManyObjectRecords({
objectNamePlural: 'activities', objectNamePlural: 'activities',
skip: !entity && !selectedFilter, skip: !entity && !selectedFilter,
filter: { filter: {
type: { equals: 'Task' },
completedAt: { is: 'NULL' }, completedAt: { is: 'NULL' },
...whereFilters, id: {
}, in: activityTargets?.map((activityTarget) => activityTarget.activityId),
orderBy: [
{
createdAt: 'DescNullIsFirst',
}, },
], type: { eq: 'Task' },
},
orderBy: {
createdAt: 'DescNullsFirst',
},
onCompleted: () => {
if (activityObjectMetadataItem) {
registerOptimisticEffect({
variables: {
filter: {
completedAt: { is: 'NULL' },
id: {
in: activityTargets?.map(
(activityTarget) => activityTarget.activityId,
),
},
type: { eq: 'Task' },
},
orderBy: {
createdAt: 'DescNullsFirst',
},
},
definition: getRecordOptimisticEffectDefinition({
objectMetadataItem: activityObjectMetadataItem,
}),
});
}
},
}); });
const todayOrPreviousTasks = incompleteTaskData?.filter((task) => { const todayOrPreviousTasks = incompleteTaskData?.filter((task) => {

View File

@ -51,10 +51,7 @@ export const Timeline = ({ entity }: { entity: ActivityTargetableEntity }) => {
const { objects: activityTargets, loading } = useFindManyObjectRecords({ const { objects: activityTargets, loading } = useFindManyObjectRecords({
objectNamePlural: 'activityTargets', objectNamePlural: 'activityTargets',
filter: { filter: {
or: { [entity.type === 'Company' ? 'companyId' : 'personId']: { eq: entity.id },
companyId: { eq: entity.id },
personId: { eq: entity.id },
},
}, },
}); });
@ -62,7 +59,9 @@ export const Timeline = ({ entity }: { entity: ActivityTargetableEntity }) => {
skip: !activityTargets?.length, skip: !activityTargets?.length,
objectNamePlural: 'activities', objectNamePlural: 'activities',
filter: { filter: {
activityTargets: { in: activityTargets?.map((at) => at.id) }, id: {
in: activityTargets?.map((activityTarget) => activityTarget.activityId),
},
}, },
orderBy: { orderBy: {
createdAt: 'AscNullsFirst', createdAt: 'AscNullsFirst',

View File

@ -24,26 +24,25 @@ export const useCreateOneObjectRecord = <T>({
// TODO: type this with a minimal type at least with Record<string, any> // TODO: type this with a minimal type at least with Record<string, any>
const [mutate] = useMutation(createOneMutation); const [mutate] = useMutation(createOneMutation);
const createOneObject = const createOneObject = async (input: Record<string, any>) => {
objectNameSingular && foundObjectMetadataItem if (!foundObjectMetadataItem || !objectNameSingular) {
? async (input: Record<string, any>) => { return null;
const createdObject = await mutate({ }
variables: {
input: { ...input, id: v4() },
},
});
triggerOptimisticEffects( const createdObject = await mutate({
`${capitalize(foundObjectMetadataItem.nameSingular)}Edge`, variables: {
createdObject.data[ input: { ...input, id: v4() },
`create${capitalize(foundObjectMetadataItem.nameSingular)}` },
], });
);
return createdObject.data[ triggerOptimisticEffects(
`create${capitalize(objectNameSingular)}` `${capitalize(foundObjectMetadataItem.nameSingular)}Edge`,
] as T; createdObject.data[
} `create${capitalize(foundObjectMetadataItem.nameSingular)}`
: undefined; ],
);
return createdObject.data[`create${capitalize(objectNameSingular)}`] as T;
};
return { return {
createOneObject, createOneObject,

View File

@ -23,20 +23,18 @@ export const useDeleteOneObjectRecord = <T>({
const deleteOneObject = useCallback( const deleteOneObject = useCallback(
async (idToDelete: string) => { async (idToDelete: string) => {
if (objectNameSingular && foundObjectMetadataItem) { if (!foundObjectMetadataItem || !objectNameSingular) {
const deletedObject = await mutate({ return null;
variables: {
idToDelete,
},
refetchQueries: [getOperationName(findManyQuery) ?? ''],
});
return deletedObject.data[
`create${capitalize(objectNameSingular)}`
] as T;
} }
return null; const deletedObject = await mutate({
variables: {
idToDelete,
},
refetchQueries: [getOperationName(findManyQuery) ?? ''],
});
return deletedObject.data[`create${capitalize(objectNameSingular)}`] as T;
}, },
[foundObjectMetadataItem, mutate, objectNameSingular, findManyQuery], [foundObjectMetadataItem, mutate, objectNameSingular, findManyQuery],
); );

View File

@ -48,20 +48,17 @@ export const useFindManyObjectRecords = <
isFetchingMoreObjectsFamilyState(objectNamePlural), isFetchingMoreObjectsFamilyState(objectNamePlural),
); );
const { const { objectMetadataItem, objectNotFoundInMetadata, findManyQuery } =
objectMetadataItem: foundObjectMetadataItem, useObjectMetadataItem({
objectNotFoundInMetadata, objectNamePlural,
findManyQuery, });
} = useObjectMetadataItem({
objectNamePlural,
});
const { enqueueSnackBar } = useSnackBar(); const { enqueueSnackBar } = useSnackBar();
const { data, loading, error, fetchMore } = useQuery< const { data, loading, error, fetchMore } = useQuery<
PaginatedObjectType<ObjectType> PaginatedObjectType<ObjectType>
>(findManyQuery, { >(findManyQuery, {
skip: skip || !foundObjectMetadataItem || !objectNamePlural, skip: skip || !objectMetadataItem || !objectNamePlural,
variables: { variables: {
filter: filter ?? {}, filter: filter ?? {},
orderBy: orderBy ?? {}, orderBy: orderBy ?? {},
@ -130,7 +127,7 @@ export const useFindManyObjectRecords = <
return Object.assign({}, prev, { return Object.assign({}, prev, {
[objectNamePlural]: { [objectNamePlural]: {
__typename: `${capitalize( __typename: `${capitalize(
foundObjectMetadataItem?.nameSingular ?? '', objectMetadataItem?.nameSingular ?? '',
)}Connection`, )}Connection`,
edges: newEdges, edges: newEdges,
pageInfo: fetchMoreResult?.[objectNamePlural].pageInfo, pageInfo: fetchMoreResult?.[objectNamePlural].pageInfo,
@ -156,7 +153,7 @@ export const useFindManyObjectRecords = <
fetchMore, fetchMore,
filter, filter,
orderBy, orderBy,
foundObjectMetadataItem, objectMetadataItem,
hasNextPage, hasNextPage,
setIsFetchingMoreObjects, setIsFetchingMoreObjects,
enqueueSnackBar, enqueueSnackBar,
@ -174,6 +171,7 @@ export const useFindManyObjectRecords = <
); );
return { return {
objectMetadataItem,
objects, objects,
loading, loading,
error, error,

View File

@ -18,29 +18,28 @@ export const useUpdateOneObjectRecord = <T>({
// TODO: type this with a minimal type at least with Record<string, any> // TODO: type this with a minimal type at least with Record<string, any>
const [mutate] = useMutation(updateOneMutation); const [mutate] = useMutation(updateOneMutation);
const updateOneObject = const updateOneObject = async ({
objectNameSingular && foundObjectMetadataItem idToUpdate,
? async ({ input,
idToUpdate, }: {
input, idToUpdate: string;
}: { input: Record<string, any>;
idToUpdate: string; }) => {
input: Record<string, any>; if (!foundObjectMetadataItem || !objectNameSingular) {
}) => { return null;
const updatedObject = await mutate({ }
variables: {
idToUpdate: idToUpdate,
input: {
...input,
},
},
});
return updatedObject.data[ const updatedObject = await mutate({
`update${capitalize(objectNameSingular)}` variables: {
] as T; idToUpdate: idToUpdate,
} input: {
: undefined; ...input,
},
},
});
return updatedObject.data[`update${capitalize(objectNameSingular)}`] as T;
};
return { return {
updateOneObject, updateOneObject,

View File

@ -259,7 +259,7 @@ export const seedActivityFieldMetadata = async (
workspaceId: SeedWorkspaceId, workspaceId: SeedWorkspaceId,
isActive: true, isActive: true,
type: FieldMetadataType.RELATION, type: FieldMetadataType.RELATION,
name: 'Comments', name: 'comments',
label: 'Comments', label: 'Comments',
targetColumnMap: {}, targetColumnMap: {},
description: 'Activity comments', description: 'Activity comments',

View File

@ -130,7 +130,7 @@ export const seedCommentFieldMetadata = async (
targetColumnMap: {}, targetColumnMap: {},
description: 'Comment author', description: 'Comment author',
icon: 'IconCircleUser', icon: 'IconCircleUser',
isNullable: false, isNullable: true,
isSystem: false, isSystem: false,
defaultValue: undefined, defaultValue: undefined,
}, },
@ -146,7 +146,7 @@ export const seedCommentFieldMetadata = async (
targetColumnMap: {}, targetColumnMap: {},
description: 'Comment author id foreign key', description: 'Comment author id foreign key',
icon: undefined, icon: undefined,
isNullable: false, isNullable: true,
isSystem: true, isSystem: true,
defaultValue: undefined, defaultValue: undefined,
}, },
@ -162,7 +162,7 @@ export const seedCommentFieldMetadata = async (
targetColumnMap: {}, targetColumnMap: {},
description: 'Comment activity', description: 'Comment activity',
icon: 'IconNotes', icon: 'IconNotes',
isNullable: false, isNullable: true,
isSystem: false, isSystem: false,
defaultValue: undefined, defaultValue: undefined,
}, },
@ -178,7 +178,7 @@ export const seedCommentFieldMetadata = async (
targetColumnMap: {}, targetColumnMap: {},
description: 'Activity id foreign key', description: 'Activity id foreign key',
icon: undefined, icon: undefined,
isNullable: false, isNullable: true,
isSystem: true, isSystem: true,
defaultValue: undefined, defaultValue: undefined,
}, },

View File

@ -37,7 +37,7 @@ const commentMetadata = {
}, },
description: 'Comment author', description: 'Comment author',
icon: 'IconCircleUser', icon: 'IconCircleUser',
isNullable: false, isNullable: true,
}, },
{ {
isCustom: false, isCustom: false,
@ -50,7 +50,7 @@ const commentMetadata = {
}, },
description: 'Comment activity', description: 'Comment activity',
icon: 'IconNotes', icon: 'IconNotes',
isNullable: false, isNullable: true,
}, },
], ],
}; };