diff --git a/front/src/generated/graphql.tsx b/front/src/generated/graphql.tsx index ccf431f483..54da27ecfa 100644 --- a/front/src/generated/graphql.tsx +++ b/front/src/generated/graphql.tsx @@ -117,8 +117,6 @@ export type ActivityTarget = { __typename?: 'ActivityTarget'; activity: Activity; activityId: Scalars['String']; - commentableId?: Maybe; - commentableType?: Maybe; company?: Maybe; companyId?: Maybe; createdAt: Scalars['DateTime']; @@ -129,8 +127,6 @@ export type ActivityTarget = { }; export type ActivityTargetCreateManyActivityInput = { - commentableId?: InputMaybe; - commentableType?: InputMaybe; companyId?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; @@ -145,8 +141,6 @@ export type ActivityTargetCreateManyActivityInputEnvelope = { export type ActivityTargetCreateManyCompanyInput = { activityId: Scalars['String']; - commentableId?: InputMaybe; - commentableType?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; personId?: InputMaybe; @@ -160,8 +154,6 @@ export type ActivityTargetCreateManyCompanyInputEnvelope = { export type ActivityTargetCreateManyPersonInput = { activityId: Scalars['String']; - commentableId?: InputMaybe; - commentableType?: InputMaybe; companyId?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; @@ -175,8 +167,6 @@ export type ActivityTargetCreateManyPersonInputEnvelope = { export type ActivityTargetCreateManyWorkspaceInput = { activityId: Scalars['String']; - commentableId?: InputMaybe; - commentableType?: InputMaybe; companyId?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; @@ -231,8 +221,6 @@ export type ActivityTargetCreateOrConnectWithoutWorkspaceInput = { }; export type ActivityTargetCreateWithoutActivityInput = { - commentableId?: InputMaybe; - commentableType?: InputMaybe; company?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; @@ -242,8 +230,6 @@ export type ActivityTargetCreateWithoutActivityInput = { export type ActivityTargetCreateWithoutCompanyInput = { activity: ActivityCreateNestedOneWithoutActivityTargetsInput; - commentableId?: InputMaybe; - commentableType?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; person?: InputMaybe; @@ -252,8 +238,6 @@ export type ActivityTargetCreateWithoutCompanyInput = { export type ActivityTargetCreateWithoutPersonInput = { activity: ActivityCreateNestedOneWithoutActivityTargetsInput; - commentableId?: InputMaybe; - commentableType?: InputMaybe; company?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; @@ -262,8 +246,6 @@ export type ActivityTargetCreateWithoutPersonInput = { export type ActivityTargetCreateWithoutWorkspaceInput = { activity: ActivityCreateNestedOneWithoutActivityTargetsInput; - commentableId?: InputMaybe; - commentableType?: InputMaybe; company?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; @@ -286,8 +268,6 @@ export type ActivityTargetScalarWhereInput = { NOT?: InputMaybe>; OR?: InputMaybe>; activityId?: InputMaybe; - commentableId?: InputMaybe; - commentableType?: InputMaybe; companyId?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; @@ -345,8 +325,6 @@ export type ActivityTargetWhereInput = { OR?: InputMaybe>; activity?: InputMaybe; activityId?: InputMaybe; - commentableId?: InputMaybe; - commentableType?: InputMaybe; company?: InputMaybe; companyId?: InputMaybe; createdAt?: InputMaybe; @@ -632,11 +610,6 @@ export type CommentWhereUniqueInput = { id?: InputMaybe; }; -export enum CommentableType { - Company = 'Company', - Person = 'Person' -} - export type Company = { __typename?: 'Company'; ActivityTarget?: Maybe>; @@ -837,13 +810,6 @@ export type EnumColorSchemeFilter = { notIn?: InputMaybe>; }; -export type EnumCommentableTypeNullableFilter = { - equals?: InputMaybe; - in?: InputMaybe>; - not?: InputMaybe; - notIn?: InputMaybe>; -}; - export type EnumPipelineProgressableTypeFilter = { equals?: InputMaybe; in?: InputMaybe>; @@ -1286,13 +1252,6 @@ export type NestedEnumColorSchemeFilter = { notIn?: InputMaybe>; }; -export type NestedEnumCommentableTypeNullableFilter = { - equals?: InputMaybe; - in?: InputMaybe>; - not?: InputMaybe; - notIn?: InputMaybe>; -}; - export type NestedEnumPipelineProgressableTypeFilter = { equals?: InputMaybe; in?: InputMaybe>; @@ -2694,7 +2653,9 @@ export type CreateActivityMutationVariables = Exact<{ }>; -export type CreateActivityMutation = { __typename?: 'Mutation', createOneActivity: { __typename?: 'Activity', id: string, createdAt: string, updatedAt: string, authorId: string, type: ActivityType, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, createdAt: string, updatedAt: string, activityId: string, commentableType?: CommentableType | null, commentableId?: string | null, companyId?: string | null, personId?: string | null }> | null, comments?: Array<{ __typename?: 'Comment', id: string, createdAt: string, updatedAt: string, body: string, author: { __typename?: 'User', id: string } }> | null } }; +export type CreateActivityMutation = { __typename?: 'Mutation', createOneActivity: { __typename?: 'Activity', id: string, createdAt: string, updatedAt: string, authorId: string, type: ActivityType, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, createdAt: string, updatedAt: string, activityId: string, companyId?: string | null, personId?: string | null }> | null, comments?: Array<{ __typename?: 'Comment', id: string, createdAt: string, updatedAt: string, body: string, author: { __typename?: 'User', id: string } }> | null } }; + +export type ActivityQueryFragmentFragment = { __typename?: 'Activity', id: string, createdAt: string, title?: string | null, body?: string | null, type: ActivityType, completedAt?: string | null, dueAt?: string | null, assignee?: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string, avatarUrl?: string | null } | null, author: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string }, comments?: Array<{ __typename?: 'Comment', id: string, body: string, createdAt: string, updatedAt: string, author: { __typename?: 'User', id: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null } }> | null, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, companyId?: string | null, personId?: string | null, company?: { __typename?: 'Company', id: string, name: string, domainName: string } | null, person?: { __typename?: 'Person', id: string, displayName: string, avatarUrl?: string | null } | null }> | null }; export type GetActivitiesByTargetsQueryVariables = Exact<{ activityTargetIds: Array | Scalars['String']; @@ -2702,7 +2663,7 @@ export type GetActivitiesByTargetsQueryVariables = Exact<{ }>; -export type GetActivitiesByTargetsQuery = { __typename?: 'Query', findManyActivities: Array<{ __typename?: 'Activity', id: string, createdAt: string, title?: string | null, body?: string | null, type: ActivityType, completedAt?: string | null, dueAt?: string | null, assignee?: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string, avatarUrl?: string | null } | null, author: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string }, comments?: Array<{ __typename?: 'Comment', id: string, body: string, createdAt: string, updatedAt: string, author: { __typename?: 'User', id: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null } }> | null, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, commentableType?: CommentableType | null, commentableId?: string | null, companyId?: string | null, personId?: string | null }> | null }> }; +export type GetActivitiesByTargetsQuery = { __typename?: 'Query', findManyActivities: Array<{ __typename?: 'Activity', id: string, createdAt: string, title?: string | null, body?: string | null, type: ActivityType, completedAt?: string | null, dueAt?: string | null, assignee?: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string, avatarUrl?: string | null } | null, author: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string }, comments?: Array<{ __typename?: 'Comment', id: string, body: string, createdAt: string, updatedAt: string, author: { __typename?: 'User', id: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null } }> | null, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, companyId?: string | null, personId?: string | null, company?: { __typename?: 'Company', id: string, name: string, domainName: string } | null, person?: { __typename?: 'Person', id: string, displayName: string, avatarUrl?: string | null } | null }> | null }> }; export type GetActivitiesQueryVariables = Exact<{ where: ActivityWhereInput; @@ -2710,14 +2671,14 @@ export type GetActivitiesQueryVariables = Exact<{ }>; -export type GetActivitiesQuery = { __typename?: 'Query', findManyActivities: Array<{ __typename?: 'Activity', id: string, createdAt: string, title?: string | null, body?: string | null, type: ActivityType, completedAt?: string | null, dueAt?: string | null, assignee?: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string, avatarUrl?: string | null } | null, author: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string }, comments?: Array<{ __typename?: 'Comment', id: string }> | null, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, commentableType?: CommentableType | null, commentableId?: string | null, companyId?: string | null, personId?: string | null }> | null }> }; +export type GetActivitiesQuery = { __typename?: 'Query', findManyActivities: Array<{ __typename?: 'Activity', id: string, createdAt: string, title?: string | null, body?: string | null, type: ActivityType, completedAt?: string | null, dueAt?: string | null, assignee?: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string, avatarUrl?: string | null } | null, author: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string }, comments?: Array<{ __typename?: 'Comment', id: string, body: string, createdAt: string, updatedAt: string, author: { __typename?: 'User', id: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null } }> | null, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, companyId?: string | null, personId?: string | null, company?: { __typename?: 'Company', id: string, name: string, domainName: string } | null, person?: { __typename?: 'Person', id: string, displayName: string, avatarUrl?: string | null } | null }> | null }> }; export type GetActivityQueryVariables = Exact<{ activityId: Scalars['String']; }>; -export type GetActivityQuery = { __typename?: 'Query', findManyActivities: Array<{ __typename?: 'Activity', id: string, createdAt: string, body?: string | null, title?: string | null, type: ActivityType, completedAt?: string | null, dueAt?: string | null, assignee?: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string, avatarUrl?: string | null } | null, author: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string }, comments?: Array<{ __typename?: 'Comment', id: string, body: string, createdAt: string, updatedAt: string, author: { __typename?: 'User', id: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null } }> | null, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, commentableType?: CommentableType | null, commentableId?: string | null, companyId?: string | null, personId?: string | null }> | null }> }; +export type GetActivityQuery = { __typename?: 'Query', findManyActivities: Array<{ __typename?: 'Activity', id: string, createdAt: string, title?: string | null, body?: string | null, type: ActivityType, completedAt?: string | null, dueAt?: string | null, assignee?: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string, avatarUrl?: string | null } | null, author: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string }, comments?: Array<{ __typename?: 'Comment', id: string, body: string, createdAt: string, updatedAt: string, author: { __typename?: 'User', id: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null } }> | null, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, companyId?: string | null, personId?: string | null, company?: { __typename?: 'Company', id: string, name: string, domainName: string } | null, person?: { __typename?: 'Person', id: string, displayName: string, avatarUrl?: string | null } | null }> | null }> }; export type AddActivityTargetsOnActivityMutationVariables = Exact<{ activityId: Scalars['String']; @@ -2725,7 +2686,7 @@ export type AddActivityTargetsOnActivityMutationVariables = Exact<{ }>; -export type AddActivityTargetsOnActivityMutation = { __typename?: 'Mutation', updateOneActivity: { __typename?: 'Activity', id: string, createdAt: string, updatedAt: string, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, createdAt: string, updatedAt: string, commentableType?: CommentableType | null, commentableId?: string | null, companyId?: string | null, personId?: string | null }> | null } }; +export type AddActivityTargetsOnActivityMutation = { __typename?: 'Mutation', updateOneActivity: { __typename?: 'Activity', id: string, createdAt: string, updatedAt: string, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, createdAt: string, updatedAt: string, companyId?: string | null, personId?: string | null }> | null } }; export type RemoveActivityTargetsOnActivityMutationVariables = Exact<{ activityId: Scalars['String']; @@ -2733,7 +2694,7 @@ export type RemoveActivityTargetsOnActivityMutationVariables = Exact<{ }>; -export type RemoveActivityTargetsOnActivityMutation = { __typename?: 'Mutation', updateOneActivity: { __typename?: 'Activity', id: string, createdAt: string, updatedAt: string, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, createdAt: string, updatedAt: string, commentableType?: CommentableType | null, commentableId?: string | null, companyId?: string | null, personId?: string | null }> | null } }; +export type RemoveActivityTargetsOnActivityMutation = { __typename?: 'Mutation', updateOneActivity: { __typename?: 'Activity', id: string, createdAt: string, updatedAt: string, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, createdAt: string, updatedAt: string, companyId?: string | null, personId?: string | null }> | null } }; export type DeleteActivityMutationVariables = Exact<{ activityId: Scalars['String']; @@ -3223,6 +3184,58 @@ export type DeleteCurrentWorkspaceMutationVariables = Exact<{ [key: string]: nev export type DeleteCurrentWorkspaceMutation = { __typename?: 'Mutation', deleteCurrentWorkspace: { __typename?: 'Workspace', id: string } }; +export const ActivityQueryFragmentFragmentDoc = gql` + fragment ActivityQueryFragment on Activity { + id + createdAt + title + body + type + completedAt + dueAt + assignee { + id + firstName + lastName + displayName + avatarUrl + } + author { + id + firstName + lastName + displayName + } + comments { + id + body + createdAt + updatedAt + author { + id + displayName + firstName + lastName + avatarUrl + } + } + activityTargets { + id + companyId + personId + company { + id + name + domainName + } + person { + id + displayName + avatarUrl + } + } +} + `; export const ActivityUpdatePartsFragmentDoc = gql` fragment ActivityUpdateParts on Activity { id @@ -3319,8 +3332,6 @@ export const CreateActivityDocument = gql` createdAt updatedAt activityId - commentableType - commentableId companyId personId } @@ -3366,51 +3377,12 @@ export const GetActivitiesByTargetsDocument = gql` query GetActivitiesByTargets($activityTargetIds: [String!]!, $orderBy: [ActivityOrderByWithRelationInput!]) { findManyActivities( orderBy: $orderBy - where: {activityTargets: {some: {commentableId: {in: $activityTargetIds}}}} + where: {activityTargets: {some: {OR: [{personId: {in: $activityTargetIds}}, {companyId: {in: $activityTargetIds}}]}}} ) { - id - createdAt - title - body - type - completedAt - dueAt - assignee { - id - firstName - lastName - displayName - avatarUrl - } - author { - id - firstName - lastName - displayName - } - comments { - id - body - createdAt - updatedAt - author { - id - displayName - firstName - lastName - avatarUrl - } - } - activityTargets { - id - commentableType - commentableId - companyId - personId - } + ...ActivityQueryFragment } } - `; + ${ActivityQueryFragmentFragmentDoc}`; /** * __useGetActivitiesByTargetsQuery__ @@ -3443,39 +3415,10 @@ export type GetActivitiesByTargetsQueryResult = Apollo.QueryResult | null; } & { - activityTargets?: Array< - Pick - > | null; + activityTargets?: Array> | null; }; showComment?: boolean; autoFillTitle?: boolean; diff --git a/front/src/modules/activities/components/ActivityRelationPicker.tsx b/front/src/modules/activities/components/ActivityRelationPicker.tsx deleted file mode 100644 index d3234e278c..0000000000 --- a/front/src/modules/activities/components/ActivityRelationPicker.tsx +++ /dev/null @@ -1,251 +0,0 @@ -import { useCallback, useMemo, useState } from 'react'; -import styled from '@emotion/styled'; -import { - autoUpdate, - flip, - offset, - size, - useFloating, -} from '@floating-ui/react'; - -import { CompanyChip } from '@/companies/components/CompanyChip'; -import { useFilteredSearchCompanyQuery } from '@/companies/queries'; -import { PersonChip } from '@/people/components/PersonChip'; -import { useFilteredSearchPeopleQuery } from '@/people/queries'; -import { MultipleEntitySelect } from '@/ui/input/relation-picker/components/MultipleEntitySelect'; -import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope'; -import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope'; -import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; -import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; -import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope'; -import { Activity, ActivityTarget, CommentableType } from '~/generated/graphql'; -import { assertNotNull } from '~/utils/assert'; - -import { useHandleCheckableActivityTargetChange } from '../hooks/useHandleCheckableActivityTargetChange'; -import { flatMapAndSortEntityForSelectArrayOfArrayByName } from '../utils/flatMapAndSortEntityForSelectArrayByName'; - -type OwnProps = { - activity?: Pick & { - activityTargets: Array< - Pick< - ActivityTarget, - 'id' | 'commentableId' | 'commentableType' | 'companyId' | 'personId' - > - >; - }; -}; - -const StyledContainer = styled.div` - align-items: flex-start; - display: flex; - flex-direction: row; - gap: ${({ theme }) => theme.spacing(2)}; - justify-content: flex-start; - - width: 100%; -`; - -const StyledRelationContainer = styled.div` - --horizontal-padding: ${({ theme }) => theme.spacing(1)}; - --vertical-padding: ${({ theme }) => theme.spacing(1.5)}; - - border: 1px solid transparent; - - cursor: pointer; - - display: flex; - flex-wrap: wrap; - - gap: ${({ theme }) => theme.spacing(2)}; - - &:hover { - background-color: ${({ theme }) => theme.background.secondary}; - border: 1px solid ${({ theme }) => theme.border.color.light}; - } - - min-height: calc(32px - 2 * var(--vertical-padding)); - - overflow: hidden; - - padding: var(--vertical-padding) var(--horizontal-padding); - width: calc(100% - 2 * var(--horizontal-padding)); -`; - -const StyledMenuWrapper = styled.div` - z-index: ${({ theme }) => theme.lastLayerZIndex}; -`; - -export function ActivityRelationPicker({ activity }: OwnProps) { - const [isMenuOpen, setIsMenuOpen] = useState(false); - const [searchFilter, setSearchFilter] = useState(''); - const [selectedEntityIds, setSelectedEntityIds] = useState< - Record - >({}); - const { - setHotkeyScopeAndMemorizePreviousScope, - goBackToPreviousHotkeyScope, - } = usePreviousHotkeyScope(); - - const initialPeopleIds = useMemo( - () => - activity?.activityTargets - ?.filter((relation) => relation.commentableType === 'Person') - .map((relation) => relation.personId || relation.commentableId) - .filter(assertNotNull) ?? [], - [activity?.activityTargets], - ); - - const initialCompanyIds = useMemo( - () => - activity?.activityTargets - ?.filter((relation) => relation.commentableType === 'Company') - .map((relation) => relation.companyId || relation.commentableId) - .filter(assertNotNull) ?? [], - [activity?.activityTargets], - ); - - const initialSelectedEntityIds = useMemo( - () => - [...initialPeopleIds, ...initialCompanyIds].reduce< - Record - >((result, entityId) => ({ ...result, [entityId]: true }), {}), - [initialPeopleIds, initialCompanyIds], - ); - - const personsForMultiSelect = useFilteredSearchPeopleQuery({ - searchFilter, - selectedIds: initialPeopleIds, - }); - - const companiesForMultiSelect = useFilteredSearchCompanyQuery({ - searchFilter, - selectedIds: initialCompanyIds, - }); - - const selectedEntities = flatMapAndSortEntityForSelectArrayOfArrayByName([ - personsForMultiSelect.selectedEntities, - companiesForMultiSelect.selectedEntities, - ]); - - const filteredSelectedEntities = - flatMapAndSortEntityForSelectArrayOfArrayByName([ - personsForMultiSelect.filteredSelectedEntities, - companiesForMultiSelect.filteredSelectedEntities, - ]); - - const entitiesToSelect = flatMapAndSortEntityForSelectArrayOfArrayByName([ - personsForMultiSelect.entitiesToSelect, - companiesForMultiSelect.entitiesToSelect, - ]); - - const handleCheckItemsChange = useHandleCheckableActivityTargetChange({ - activity, - }); - - const exitEditMode = useCallback(() => { - goBackToPreviousHotkeyScope(); - setIsMenuOpen(false); - setSearchFilter(''); - - if (Object.values(selectedEntityIds).some((value) => !!value)) { - handleCheckItemsChange(selectedEntityIds, entitiesToSelect); - } - }, [ - entitiesToSelect, - selectedEntityIds, - goBackToPreviousHotkeyScope, - handleCheckItemsChange, - ]); - - const handleRelationContainerClick = useCallback(() => { - if (isMenuOpen) { - exitEditMode(); - } else { - setIsMenuOpen(true); - setSelectedEntityIds(initialSelectedEntityIds); - setHotkeyScopeAndMemorizePreviousScope( - RelationPickerHotkeyScope.RelationPicker, - ); - } - }, [ - initialSelectedEntityIds, - exitEditMode, - isMenuOpen, - setHotkeyScopeAndMemorizePreviousScope, - ]); - - useScopedHotkeys( - ['esc', 'enter'], - () => { - exitEditMode(); - }, - RelationPickerHotkeyScope.RelationPicker, - [exitEditMode], - ); - - const { refs, floatingStyles } = useFloating({ - strategy: 'absolute', - middleware: [ - offset(({ rects }) => { - return -rects.reference.height; - }), - flip(), - size(), - ], - whileElementsMounted: autoUpdate, - open: isMenuOpen, - placement: 'bottom-start', - }); - - useListenClickOutside({ - refs: [refs.floating, refs.domReference], - callback: () => { - exitEditMode(); - }, - }); - - return ( - - - {selectedEntities?.map((entity) => - entity.entityType === CommentableType.Company ? ( - - ) : ( - - ), - )} - - {isMenuOpen && ( - - - - - - )} - - ); -} diff --git a/front/src/modules/activities/components/ActivityTargetChips.tsx b/front/src/modules/activities/components/ActivityTargetChips.tsx index 5fd3b4ce0c..22e5659a98 100644 --- a/front/src/modules/activities/components/ActivityTargetChips.tsx +++ b/front/src/modules/activities/components/ActivityTargetChips.tsx @@ -2,7 +2,7 @@ import styled from '@emotion/styled'; import { CompanyChip } from '@/companies/components/CompanyChip'; import { PersonChip } from '@/people/components/PersonChip'; -import { GetCompaniesQuery, GetPeopleQuery } from '~/generated/graphql'; +import { ActivityTarget, Company, Person } from '~/generated/graphql'; import { getLogoUrlFromDomainName } from '~/utils'; const StyledContainer = styled.div` @@ -12,32 +12,44 @@ const StyledContainer = styled.div` `; export function ActivityTargetChips({ - targetCompanies, - targetPeople, + targets, }: { - targetCompanies?: GetCompaniesQuery; - targetPeople?: GetPeopleQuery; + targets?: Array< + Pick & { + person?: Pick | null; + company?: Pick | null; + } + > | null; }) { + if (!targets) { + return null; + } + return ( - {targetCompanies?.companies && - targetCompanies.companies.map((company) => ( - - ))} - {targetPeople?.people && - targetPeople.people.map((person) => ( - - ))} + {targets.map(({ company, person }) => { + if (company) { + return ( + + ); + } + if (person) { + return ( + + ); + } + return <>; + })} ); } diff --git a/front/src/modules/activities/components/TaskRow.tsx b/front/src/modules/activities/components/TaskRow.tsx index b26facd1c9..87d09b7ab0 100644 --- a/front/src/modules/activities/components/TaskRow.tsx +++ b/front/src/modules/activities/components/TaskRow.tsx @@ -9,7 +9,6 @@ import { CheckboxShape, } from '@/ui/input/checkbox/components/Checkbox'; import { OverflowingTextWithTooltip } from '@/ui/tooltip/OverflowingTextWithTooltip'; -import { useGetCompaniesQuery, useGetPeopleQuery } from '~/generated/graphql'; import { beautifyExactDate } from '~/utils/date-utils'; import { useCompleteTask } from '../hooks/useCompleteTask'; @@ -62,37 +61,7 @@ const StyledFieldsContainer = styled.div` export function TaskRow({ task }: { task: TaskForList }) { const theme = useTheme(); const openActivityRightDrawer = useOpenActivityRightDrawer(); - const { data: targetPeople } = useGetPeopleQuery({ - variables: { - where: { - id: { - in: task?.activityTargets - ? task?.activityTargets - .filter((target) => target.commentableType === 'Person') - .map( - (target) => (target.personId || target.commentableId) ?? '', - ) - : [], - }, - }, - }, - }); - const { data: targetCompanies } = useGetCompaniesQuery({ - variables: { - where: { - id: { - in: task?.activityTargets - ? task?.activityTargets - .filter((target) => target.commentableType === 'Company') - .map( - (target) => (target.companyId || target.commentableId) ?? '', - ) - : [], - }, - }, - }, - }); const body = JSON.parse(task.body ?? '{}')[0]?.content[0]?.text; const { completeTask } = useCompleteTask(task); @@ -123,10 +92,7 @@ export function TaskRow({ task }: { task: TaskForList }) { )} - + {task.dueAt && beautifyExactDate(task.dueAt)} diff --git a/front/src/modules/activities/components/__stories__/ActivityRelationPicker.stories.tsx b/front/src/modules/activities/components/__stories__/ActivityRelationPicker.stories.tsx deleted file mode 100644 index e8ca2dcd00..0000000000 --- a/front/src/modules/activities/components/__stories__/ActivityRelationPicker.stories.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { MemoryRouter } from 'react-router-dom'; -import styled from '@emotion/styled'; -import type { Meta, StoryObj } from '@storybook/react'; - -import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; -import { graphqlMocks } from '~/testing/graphqlMocks'; -import { mockedActivities } from '~/testing/mock-data/activities'; - -import { ActivityRelationPicker } from '../ActivityRelationPicker'; - -const StyledContainer = styled.div` - width: 400px; -`; - -const meta: Meta = { - title: 'Modules/Comments/ActivityRelationPicker', - component: ActivityRelationPicker, - decorators: [ - (Story) => ( - - - - - - ), - ComponentDecorator, - ], - args: { activity: mockedActivities[0] }, - parameters: { - msw: graphqlMocks, - }, -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = {}; diff --git a/front/src/modules/activities/editable-fields/components/ActivityRelationEditableField.tsx b/front/src/modules/activities/editable-fields/components/ActivityRelationEditableField.tsx index f99d71263a..42f17bd7d7 100644 --- a/front/src/modules/activities/editable-fields/components/ActivityRelationEditableField.tsx +++ b/front/src/modules/activities/editable-fields/components/ActivityRelationEditableField.tsx @@ -4,59 +4,22 @@ import { FieldContext } from '@/ui/editable-field/states/FieldContext'; import { IconArrowUpRight } from '@/ui/icon'; import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope'; import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope'; -import { - Activity, - ActivityTarget, - useGetCompaniesQuery, - useGetPeopleQuery, -} from '~/generated/graphql'; +import { Activity, ActivityTarget, Company, Person } from '~/generated/graphql'; import { ActivityRelationEditableFieldEditMode } from './ActivityRelationEditableFieldEditMode'; type OwnProps = { activity?: Pick & { activityTargets?: Array< - Pick< - ActivityTarget, - 'id' | 'commentableId' | 'commentableType' | 'personId' | 'companyId' - > + Pick & { + person?: Pick; + company?: Pick; + } > | null; }; }; export function ActivityRelationEditableField({ activity }: OwnProps) { - const { data: targetPeople } = useGetPeopleQuery({ - variables: { - where: { - id: { - in: activity?.activityTargets - ? activity?.activityTargets - .filter((target) => target.commentableType === 'Person') - .map( - (target) => (target.personId || target.commentableId) ?? '', - ) - : [], - }, - }, - }, - }); - - const { data: targetCompanies } = useGetCompaniesQuery({ - variables: { - where: { - id: { - in: activity?.activityTargets - ? activity?.activityTargets - .filter((target) => target.commentableType === 'Company') - .map( - (target) => (target.companyId || target.commentableId) ?? '', - ) - : [], - }, - }, - }, - }); - return ( @@ -71,10 +34,7 @@ export function ActivityRelationEditableField({ activity }: OwnProps) { } label="Relations" displayModeContent={ - + } /> diff --git a/front/src/modules/activities/editable-fields/components/ActivityRelationEditableFieldEditMode.tsx b/front/src/modules/activities/editable-fields/components/ActivityRelationEditableFieldEditMode.tsx index 2a3c975012..26e80677cd 100644 --- a/front/src/modules/activities/editable-fields/components/ActivityRelationEditableFieldEditMode.tsx +++ b/front/src/modules/activities/editable-fields/components/ActivityRelationEditableFieldEditMode.tsx @@ -13,10 +13,7 @@ import { assertNotNull } from '~/utils/assert'; type OwnProps = { activity?: Pick & { activityTargets?: Array< - Pick< - ActivityTarget, - 'id' | 'commentableId' | 'commentableType' | 'personId' | 'companyId' - > + Pick > | null; }; }; @@ -33,8 +30,8 @@ export function ActivityRelationEditableFieldEditMode({ activity }: OwnProps) { const initialPeopleIds = useMemo( () => activity?.activityTargets - ?.filter((relation) => relation.commentableType === 'Person') - .map((relation) => relation.personId || relation.commentableId) + ?.filter((relation) => relation.personId !== null) + .map((relation) => relation.personId) .filter(assertNotNull) ?? [], [activity?.activityTargets], ); @@ -42,8 +39,8 @@ export function ActivityRelationEditableFieldEditMode({ activity }: OwnProps) { const initialCompanyIds = useMemo( () => activity?.activityTargets - ?.filter((relation) => relation.commentableType === 'Company') - .map((relation) => relation.companyId || relation.commentableId) + ?.filter((relation) => relation.companyId !== null) + .map((relation) => relation.companyId) .filter(assertNotNull) ?? [], [activity?.activityTargets], ); diff --git a/front/src/modules/activities/hooks/useHandleCheckableActivityTargetChange.ts b/front/src/modules/activities/hooks/useHandleCheckableActivityTargetChange.ts index 8c10b39be1..4352e4b3be 100644 --- a/front/src/modules/activities/hooks/useHandleCheckableActivityTargetChange.ts +++ b/front/src/modules/activities/hooks/useHandleCheckableActivityTargetChange.ts @@ -6,20 +6,20 @@ import { GET_PEOPLE } from '@/people/queries'; import { Activity, ActivityTarget, - CommentableType, useAddActivityTargetsOnActivityMutation, useRemoveActivityTargetsOnActivityMutation, } from '~/generated/graphql'; import { GET_ACTIVITY } from '../queries'; -import { CommentableEntityForSelect } from '../types/CommentableEntityForSelect'; +import { ActivityTargetableEntityType } from '../types/ActivityTargetableEntity'; +import { ActivityTargetableEntityForSelect } from '../types/ActivityTargetableEntityForSelect'; export function useHandleCheckableActivityTargetChange({ activity, }: { activity?: Pick & { activityTargets?: Array< - Pick + Pick > | null; }; }) { @@ -43,14 +43,16 @@ export function useHandleCheckableActivityTargetChange({ return async function handleCheckItemsChange( entityValues: Record, - entities: CommentableEntityForSelect[], + entities: ActivityTargetableEntityForSelect[], ) { if (!activity) { return; } const currentEntityIds = activity.activityTargets - ? activity.activityTargets.map(({ commentableId }) => commentableId) + ? activity.activityTargets.map( + ({ personId, companyId }) => personId ?? companyId, + ) : []; const entitiesToAdd = entities.filter( @@ -64,12 +66,14 @@ export function useHandleCheckableActivityTargetChange({ activityTargetInputs: entitiesToAdd.map((entity) => ({ id: v4(), createdAt: new Date().toISOString(), - commentableType: entity.entityType, - commentableId: entity.id, companyId: - entity.entityType === CommentableType.Company ? entity.id : null, + entity.entityType === ActivityTargetableEntityType.Company + ? entity.id + : null, personId: - entity.entityType === CommentableType.Person ? entity.id : null, + entity.entityType === ActivityTargetableEntityType.Person + ? entity.id + : null, })), }, }); @@ -77,8 +81,9 @@ export function useHandleCheckableActivityTargetChange({ const activityTargetIdsToDelete = activity.activityTargets ? activity.activityTargets .filter( - ({ commentableId }) => - commentableId && !entityValues[commentableId], + ({ personId, companyId }) => + (personId ?? companyId) && + !entityValues[personId ?? companyId ?? ''], ) .map(({ id }) => id) : []; diff --git a/front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts b/front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts index 535f735804..a0d695f3c4 100644 --- a/front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts +++ b/front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts @@ -9,20 +9,19 @@ import { useRightDrawer } from '@/ui/right-drawer/hooks/useRightDrawer'; import { RightDrawerHotkeyScope } from '@/ui/right-drawer/types/RightDrawerHotkeyScope'; import { RightDrawerPages } from '@/ui/right-drawer/types/RightDrawerPages'; import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; -import { - ActivityType, - CommentableType, - useCreateActivityMutation, -} from '~/generated/graphql'; +import { ActivityType, useCreateActivityMutation } from '~/generated/graphql'; import { GET_ACTIVITIES, GET_ACTIVITIES_BY_TARGETS, GET_ACTIVITY, } from '../queries'; -import { commentableEntityArrayState } from '../states/commentableEntityArrayState'; +import { activityTargetableEntityArrayState } from '../states/activityTargetableEntityArrayState'; import { viewableActivityIdState } from '../states/viewableActivityIdState'; -import { CommentableEntity } from '../types/CommentableEntity'; +import { + ActivityTargetableEntity, + ActivityTargetableEntityType, +} from '../types/ActivityTargetableEntity'; export function useOpenCreateActivityDrawer() { const { openRightDrawer } = useRightDrawer(); @@ -30,14 +29,14 @@ export function useOpenCreateActivityDrawer() { const currentUser = useRecoilValue(currentUserState); const setHotkeyScope = useSetHotkeyScope(); - const [, setCommentableEntityArray] = useRecoilState( - commentableEntityArrayState, + const [, setActivityTargetableEntityArray] = useRecoilState( + activityTargetableEntityArrayState, ); const [, setViewableActivityId] = useRecoilState(viewableActivityIdState); return function openCreateActivityDrawer( type: ActivityType, - entities?: CommentableEntity[], + entities?: ActivityTargetableEntity[], ) { const now = new Date().toISOString(); @@ -54,14 +53,14 @@ export function useOpenCreateActivityDrawer() { createMany: { data: entities ? entities.map((entity) => ({ - commentableId: entity.id, - commentableType: entity.type, companyId: - entity.type === CommentableType.Company + entity.type === ActivityTargetableEntityType.Company ? entity.id : null, personId: - entity.type === CommentableType.Person ? entity.id : null, + entity.type === ActivityTargetableEntityType.Person + ? entity.id + : null, id: v4(), createdAt: now, })) @@ -81,7 +80,7 @@ export function useOpenCreateActivityDrawer() { onCompleted(data) { setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false }); setViewableActivityId(data.createOneActivity.id); - setCommentableEntityArray(entities ?? []); + setActivityTargetableEntityArray(entities ?? []); openRightDrawer(RightDrawerPages.CreateActivity); }, }); diff --git a/front/src/modules/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds.ts b/front/src/modules/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds.ts index 554218d254..5f6cda7b89 100644 --- a/front/src/modules/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds.ts +++ b/front/src/modules/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds.ts @@ -1,9 +1,12 @@ import { useRecoilValue } from 'recoil'; import { selectedRowIdsSelector } from '@/ui/table/states/selectedRowIdsSelector'; -import { ActivityType, CommentableType } from '~/generated/graphql'; +import { ActivityType } from '~/generated/graphql'; -import { CommentableEntity } from '../types/CommentableEntity'; +import { + ActivityTargetableEntity, + ActivityTargetableEntityType, +} from '../types/ActivityTargetableEntity'; import { useOpenCreateActivityDrawer } from './useOpenCreateActivityDrawer'; @@ -14,14 +17,13 @@ export function useOpenCreateActivityDrawerForSelectedRowIds() { return function openCreateCommentDrawerForSelectedRowIds( type: ActivityType, - entityType: CommentableType, + entityType: ActivityTargetableEntityType, ) { - const commentableEntityArray: CommentableEntity[] = selectedEntityIds.map( - (id) => ({ + const activityTargetableEntityArray: ActivityTargetableEntity[] = + selectedEntityIds.map((id) => ({ type: entityType, id, - }), - ); - openCreateActivityDrawer(type, commentableEntityArray); + })); + openCreateActivityDrawer(type, activityTargetableEntityArray); }; } diff --git a/front/src/modules/activities/hooks/useOpenTimelineRightDrawer.ts b/front/src/modules/activities/hooks/useOpenTimelineRightDrawer.ts index f36e5ef865..f6cf662b8f 100644 --- a/front/src/modules/activities/hooks/useOpenTimelineRightDrawer.ts +++ b/front/src/modules/activities/hooks/useOpenTimelineRightDrawer.ts @@ -5,22 +5,22 @@ import { RightDrawerHotkeyScope } from '@/ui/right-drawer/types/RightDrawerHotke import { RightDrawerPages } from '@/ui/right-drawer/types/RightDrawerPages'; import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; -import { commentableEntityArrayState } from '../states/commentableEntityArrayState'; -import { CommentableEntity } from '../types/CommentableEntity'; +import { activityTargetableEntityArrayState } from '../states/activityTargetableEntityArrayState'; +import { ActivityTargetableEntity } from '../types/ActivityTargetableEntity'; // TODO: refactor with recoil callback to avoid rerender export function useOpenTimelineRightDrawer() { const { openRightDrawer } = useRightDrawer(); - const [, setCommentableEntityArray] = useRecoilState( - commentableEntityArrayState, + const [, setActivityTargetableEntityArray] = useRecoilState( + activityTargetableEntityArrayState, ); const setHotkeyScope = useSetHotkeyScope(); return function openTimelineRightDrawer( - commentableEntityArray: CommentableEntity[], + activityTargetableEntityArray: ActivityTargetableEntity[], ) { setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false }); - setCommentableEntityArray(commentableEntityArray); + setActivityTargetableEntityArray(activityTargetableEntityArray); openRightDrawer(RightDrawerPages.Timeline); }; } diff --git a/front/src/modules/activities/queries/create.ts b/front/src/modules/activities/queries/create.ts index f79548631a..1fb75bac5d 100644 --- a/front/src/modules/activities/queries/create.ts +++ b/front/src/modules/activities/queries/create.ts @@ -45,8 +45,6 @@ export const CREATE_ACTIVITY_WITH_COMMENT = gql` createdAt updatedAt activityId - commentableType - commentableId companyId personId } diff --git a/front/src/modules/activities/queries/select.ts b/front/src/modules/activities/queries/select.ts index c7acc033d6..eee362d94b 100644 --- a/front/src/modules/activities/queries/select.ts +++ b/front/src/modules/activities/queries/select.ts @@ -1,5 +1,58 @@ import { gql } from '@apollo/client'; +export const ACTIVITY_QUERY_FRAGMENT = gql` + fragment ActivityQueryFragment on Activity { + id + createdAt + title + body + type + completedAt + dueAt + assignee { + id + firstName + lastName + displayName + avatarUrl + } + author { + id + firstName + lastName + displayName + } + comments { + id + body + createdAt + updatedAt + author { + id + displayName + firstName + lastName + avatarUrl + } + } + activityTargets { + id + companyId + personId + company { + id + name + domainName + } + person { + id + displayName + avatarUrl + } + } + } +`; + export const GET_ACTIVITIES_BY_TARGETS = gql` query GetActivitiesByTargets( $activityTargetIds: [String!]! @@ -8,49 +61,17 @@ export const GET_ACTIVITIES_BY_TARGETS = gql` findManyActivities( orderBy: $orderBy where: { - activityTargets: { some: { commentableId: { in: $activityTargetIds } } } - } - ) { - id - createdAt - title - body - type - completedAt - dueAt - assignee { - id - firstName - lastName - displayName - avatarUrl - } - author { - id - firstName - lastName - displayName - } - comments { - id - body - createdAt - updatedAt - author { - id - displayName - firstName - lastName - avatarUrl + activityTargets: { + some: { + OR: [ + { personId: { in: $activityTargetIds } } + { companyId: { in: $activityTargetIds } } + ] + } } } - activityTargets { - id - commentableType - commentableId - companyId - personId - } + ) { + ...ActivityQueryFragment } } `; @@ -61,36 +82,7 @@ export const GET_ACTIVITIES = gql` $orderBy: [ActivityOrderByWithRelationInput!] ) { findManyActivities(orderBy: $orderBy, where: $where) { - id - createdAt - title - body - type - completedAt - dueAt - assignee { - id - firstName - lastName - displayName - avatarUrl - } - author { - id - firstName - lastName - displayName - } - comments { - id - } - activityTargets { - id - commentableType - commentableId - companyId - personId - } + ...ActivityQueryFragment } } `; @@ -98,46 +90,7 @@ export const GET_ACTIVITIES = gql` export const GET_ACTIVITY = gql` query GetActivity($activityId: String!) { findManyActivities(where: { id: { equals: $activityId } }) { - id - createdAt - body - title - type - completedAt - dueAt - assignee { - id - firstName - lastName - displayName - avatarUrl - } - author { - id - firstName - lastName - displayName - } - comments { - id - body - createdAt - updatedAt - author { - id - displayName - firstName - lastName - avatarUrl - } - } - activityTargets { - id - commentableType - commentableId - companyId - personId - } + ...ActivityQueryFragment } } `; diff --git a/front/src/modules/activities/queries/update.ts b/front/src/modules/activities/queries/update.ts index be716efac1..02aa5d782a 100644 --- a/front/src/modules/activities/queries/update.ts +++ b/front/src/modules/activities/queries/update.ts @@ -16,8 +16,6 @@ export const ADD_ACTIVITY_TARGETS = gql` id createdAt updatedAt - commentableType - commentableId companyId personId } @@ -43,8 +41,6 @@ export const REMOVE_ACTIVITY_TARGETS = gql` id createdAt updatedAt - commentableType - commentableId companyId personId } diff --git a/front/src/modules/activities/right-drawer/components/RightDrawerTimeline.tsx b/front/src/modules/activities/right-drawer/components/RightDrawerTimeline.tsx index d8787605bf..bbbcdeb25b 100644 --- a/front/src/modules/activities/right-drawer/components/RightDrawerTimeline.tsx +++ b/front/src/modules/activities/right-drawer/components/RightDrawerTimeline.tsx @@ -1,19 +1,21 @@ -import { useRecoilState } from 'recoil'; +import { useRecoilValue } from 'recoil'; -import { commentableEntityArrayState } from '@/activities/states/commentableEntityArrayState'; +import { activityTargetableEntityArrayState } from '@/activities/states/activityTargetableEntityArrayState'; import { Timeline } from '@/activities/timeline/components/Timeline'; export function RightDrawerTimeline() { - const [commentableEntityArray] = useRecoilState(commentableEntityArrayState); + const activityTargetableEntityArray = useRecoilValue( + activityTargetableEntityArrayState, + ); return ( <> - {commentableEntityArray.map((commentableEntity) => ( + {activityTargetableEntityArray.map((targetableEntity) => ( ))} diff --git a/front/src/modules/activities/states/activityTargetableEntityArrayState.ts b/front/src/modules/activities/states/activityTargetableEntityArrayState.ts new file mode 100644 index 0000000000..25e2da755c --- /dev/null +++ b/front/src/modules/activities/states/activityTargetableEntityArrayState.ts @@ -0,0 +1,10 @@ +import { atom } from 'recoil'; + +import { ActivityTargetableEntity } from '../types/ActivityTargetableEntity'; + +export const activityTargetableEntityArrayState = atom< + ActivityTargetableEntity[] +>({ + key: 'activities/targetable-entity-array', + default: [], +}); diff --git a/front/src/modules/activities/states/commentableEntityArrayState.ts b/front/src/modules/activities/states/commentableEntityArrayState.ts deleted file mode 100644 index 987bb9a3d9..0000000000 --- a/front/src/modules/activities/states/commentableEntityArrayState.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { atom } from 'recoil'; - -import { CommentableEntity } from '../types/CommentableEntity'; - -export const commentableEntityArrayState = atom({ - key: 'activities/commentable-entity-array', - default: [], -}); diff --git a/front/src/modules/activities/timeline/components/Timeline.tsx b/front/src/modules/activities/timeline/components/Timeline.tsx index a5dd649da1..62efcf24cd 100644 --- a/front/src/modules/activities/timeline/components/Timeline.tsx +++ b/front/src/modules/activities/timeline/components/Timeline.tsx @@ -5,7 +5,7 @@ import styled from '@emotion/styled'; import { ActivityCreateButton } from '@/activities/components/ActivityCreateButton'; import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer'; import { ActivityForDrawer } from '@/activities/types/ActivityForDrawer'; -import { CommentableEntity } from '@/activities/types/CommentableEntity'; +import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity'; import { IconCircleDot } from '@/ui/icon'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; import { @@ -93,7 +93,7 @@ const StyledStartIcon = styled.div` width: 20px; `; -export function Timeline({ entity }: { entity: CommentableEntity }) { +export function Timeline({ entity }: { entity: ActivityTargetableEntity }) { const theme = useTheme(); const { data: queryResult, loading } = useGetActivitiesByTargetsQuery({ diff --git a/front/src/modules/activities/types/ActivityTargetableEntity.ts b/front/src/modules/activities/types/ActivityTargetableEntity.ts new file mode 100644 index 0000000000..b9455968d7 --- /dev/null +++ b/front/src/modules/activities/types/ActivityTargetableEntity.ts @@ -0,0 +1,9 @@ +export enum ActivityTargetableEntityType { + Person = 'Person', + Company = 'Company', +} + +export type ActivityTargetableEntity = { + id: string; + type: ActivityTargetableEntityType; +}; diff --git a/front/src/modules/activities/types/ActivityTargetableEntityForSelect.ts b/front/src/modules/activities/types/ActivityTargetableEntityForSelect.ts new file mode 100644 index 0000000000..aa6ca8f923 --- /dev/null +++ b/front/src/modules/activities/types/ActivityTargetableEntityForSelect.ts @@ -0,0 +1,7 @@ +import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect'; + +import { ActivityTargetableEntityType } from './ActivityTargetableEntity'; + +export type ActivityTargetableEntityForSelect = EntityForSelect & { + entityType: ActivityTargetableEntityType; +}; diff --git a/front/src/modules/activities/types/CommentableEntity.ts b/front/src/modules/activities/types/CommentableEntity.ts deleted file mode 100644 index 481e513c80..0000000000 --- a/front/src/modules/activities/types/CommentableEntity.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { CommentableType } from '~/generated/graphql'; - -export type CommentableEntity = { - id: string; - type: CommentableType; -}; diff --git a/front/src/modules/activities/types/CommentableEntityForSelect.ts b/front/src/modules/activities/types/CommentableEntityForSelect.ts deleted file mode 100644 index 07bfdfc27d..0000000000 --- a/front/src/modules/activities/types/CommentableEntityForSelect.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect'; -import { CommentableType } from '~/generated/graphql'; - -export type CommentableEntityForSelect = EntityForSelect & { - entityType: CommentableType; -}; diff --git a/front/src/modules/companies/queries/select.ts b/front/src/modules/companies/queries/select.ts index fdecd5e077..9929f7d4f4 100644 --- a/front/src/modules/companies/queries/select.ts +++ b/front/src/modules/companies/queries/select.ts @@ -1,10 +1,10 @@ import { gql } from '@apollo/client'; -import { CommentableEntityForSelect } from '@/activities/types/CommentableEntityForSelect'; +import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity'; +import { ActivityTargetableEntityForSelect } from '@/activities/types/ActivityTargetableEntityForSelect'; import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery'; import { SelectedSortType } from '@/ui/filter-n-sort/types/interface'; import { - CommentableType, CompanyOrderByWithRelationInput as Companies_Order_By, CompanyWhereInput as Companies_Bool_Exp, SortOrder as Order_By, @@ -65,11 +65,11 @@ export function useFilteredSearchCompanyQuery({ mappingFunction: (company) => ({ id: company.id, - entityType: CommentableType.Company, + entityType: ActivityTargetableEntityType.Company, name: company.name, avatarUrl: getLogoUrlFromDomainName(company.domainName), avatarType: 'squared', - } as CommentableEntityForSelect), + } as ActivityTargetableEntityForSelect), searchFilter, limit, }); diff --git a/front/src/modules/companies/table/components/TableActionBarButtonCreateActivityCompany.tsx b/front/src/modules/companies/table/components/TableActionBarButtonCreateActivityCompany.tsx index cfb5eefdad..86316541e6 100644 --- a/front/src/modules/companies/table/components/TableActionBarButtonCreateActivityCompany.tsx +++ b/front/src/modules/companies/table/components/TableActionBarButtonCreateActivityCompany.tsx @@ -1,14 +1,15 @@ import { useOpenCreateActivityDrawerForSelectedRowIds } from '@/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds'; +import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity'; import { TableActionBarButtonToggleComments } from '@/ui/table/action-bar/components/TableActionBarButtonOpenComments'; import { TableActionBarButtonToggleTasks } from '@/ui/table/action-bar/components/TableActionBarButtonOpenTasks'; -import { ActivityType, CommentableType } from '~/generated/graphql'; +import { ActivityType } from '~/generated/graphql'; export function TableActionBarButtonCreateActivityCompany() { const openCreateActivityRightDrawer = useOpenCreateActivityDrawerForSelectedRowIds(); async function handleButtonClick(type: ActivityType) { - openCreateActivityRightDrawer(type, CommentableType.Company); + openCreateActivityRightDrawer(type, ActivityTargetableEntityType.Company); } return ( diff --git a/front/src/modules/people/queries/select.ts b/front/src/modules/people/queries/select.ts index 3c532687ae..0ef7b37743 100644 --- a/front/src/modules/people/queries/select.ts +++ b/front/src/modules/people/queries/select.ts @@ -1,10 +1,10 @@ import { gql } from '@apollo/client'; -import { CommentableEntityForSelect } from '@/activities/types/CommentableEntityForSelect'; +import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity'; +import { ActivityTargetableEntityForSelect } from '@/activities/types/ActivityTargetableEntityForSelect'; import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery'; import { SelectedSortType } from '@/ui/filter-n-sort/types/interface'; import { - CommentableType, PersonOrderByWithRelationInput as People_Order_By, PersonWhereInput as People_Bool_Exp, SortOrder, @@ -69,11 +69,11 @@ export function useFilteredSearchPeopleQuery({ mappingFunction: (entity) => ({ id: entity.id, - entityType: CommentableType.Person, + entityType: ActivityTargetableEntityType.Person, name: `${entity.firstName} ${entity.lastName}`, avatarUrl: entity.avatarUrl, avatarType: 'rounded', - } as CommentableEntityForSelect), + } as ActivityTargetableEntityForSelect), searchFilter, limit, }); diff --git a/front/src/modules/people/table/components/TableActionBarButtonCreateActivityPeople.tsx b/front/src/modules/people/table/components/TableActionBarButtonCreateActivityPeople.tsx index 9d8e271ca8..550ad48e31 100644 --- a/front/src/modules/people/table/components/TableActionBarButtonCreateActivityPeople.tsx +++ b/front/src/modules/people/table/components/TableActionBarButtonCreateActivityPeople.tsx @@ -1,14 +1,15 @@ import { useOpenCreateActivityDrawerForSelectedRowIds } from '@/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds'; +import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity'; import { TableActionBarButtonToggleComments } from '@/ui/table/action-bar/components/TableActionBarButtonOpenComments'; import { TableActionBarButtonToggleTasks } from '@/ui/table/action-bar/components/TableActionBarButtonOpenTasks'; -import { ActivityType, CommentableType } from '~/generated/graphql'; +import { ActivityType } from '~/generated/graphql'; export function TableActionBarButtonCreateActivityPeople() { const openCreateActivityRightDrawer = useOpenCreateActivityDrawerForSelectedRowIds(); async function handleButtonClick(type: ActivityType) { - openCreateActivityRightDrawer(type, CommentableType.Person); + openCreateActivityRightDrawer(type, ActivityTargetableEntityType.Person); } return ( diff --git a/front/src/modules/ui/input/relation-picker/types/EntityTypeForSelect.ts b/front/src/modules/ui/input/relation-picker/types/EntityTypeForSelect.ts index e27c21f6f9..80d845d6b8 100644 --- a/front/src/modules/ui/input/relation-picker/types/EntityTypeForSelect.ts +++ b/front/src/modules/ui/input/relation-picker/types/EntityTypeForSelect.ts @@ -1,4 +1,5 @@ -import { CommentableType, PipelineProgressableType } from '~/generated/graphql'; +import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity'; +import { PipelineProgressableType } from '~/generated/graphql'; export enum Entity { Company = 'Company', @@ -7,6 +8,6 @@ export enum Entity { } export type EntityTypeForSelect = - | CommentableType + | ActivityTargetableEntityType | PipelineProgressableType | Entity; diff --git a/front/src/pages/companies/CompanyShow.tsx b/front/src/pages/companies/CompanyShow.tsx index b20826e35f..f7d2930215 100644 --- a/front/src/pages/companies/CompanyShow.tsx +++ b/front/src/pages/companies/CompanyShow.tsx @@ -2,6 +2,7 @@ import { useParams } from 'react-router-dom'; import { useTheme } from '@emotion/react'; import { Timeline } from '@/activities/timeline/components/Timeline'; +import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity'; import { CompanyTeam } from '@/companies/components/CompanyTeam'; import { useCompanyQuery } from '@/companies/queries'; import { useFavorites } from '@/favorites/hooks/useFavorites'; @@ -15,10 +16,7 @@ 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, - useUpdateOneCompanyMutation, -} from '~/generated/graphql'; +import { useUpdateOneCompanyMutation } from '~/generated/graphql'; import { getLogoUrlFromDomainName } from '~/utils'; import { CompanyNameEditableField } from '../../modules/companies/editable-field/components/CompanyNameEditableField'; @@ -85,7 +83,10 @@ export function CompanyShow() { diff --git a/front/src/pages/people/PersonShow.tsx b/front/src/pages/people/PersonShow.tsx index 9eebe92c2d..2206bfec00 100644 --- a/front/src/pages/people/PersonShow.tsx +++ b/front/src/pages/people/PersonShow.tsx @@ -3,6 +3,7 @@ import { getOperationName } from '@apollo/client/utilities'; import { useTheme } from '@emotion/react'; import { Timeline } from '@/activities/timeline/components/Timeline'; +import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity'; import { useFavorites } from '@/favorites/hooks/useFavorites'; import { GET_PERSON, usePersonQuery } from '@/people/queries'; import { GenericEditableField } from '@/ui/editable-field/components/GenericEditableField'; @@ -16,7 +17,6 @@ import { ShowPageLeftContainer } from '@/ui/layout/show-page/components/ShowPage import { ShowPageRightContainer } from '@/ui/layout/show-page/components/ShowPageRightContainer'; import { ShowPageSummaryCard } from '@/ui/layout/show-page/components/ShowPageSummaryCard'; import { - CommentableType, useUpdateOnePersonMutation, useUploadPersonPictureMutation, } from '~/generated/graphql'; @@ -100,7 +100,10 @@ export function PersonShow() { diff --git a/front/src/sync-hooks/AuthAutoRouter.tsx b/front/src/sync-hooks/AuthAutoRouter.tsx index a29f94be94..ac9d5d98d0 100644 --- a/front/src/sync-hooks/AuthAutoRouter.tsx +++ b/front/src/sync-hooks/AuthAutoRouter.tsx @@ -3,6 +3,7 @@ import { matchPath, useLocation, useNavigate } from 'react-router-dom'; import { IconCheckbox, IconNotes } from '@tabler/icons-react'; import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer'; +import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity'; import { useEventTracker } from '@/analytics/hooks/useEventTracker'; import { useOnboardingStatus } from '@/auth/hooks/useOnboardingStatus'; import { OnboardingStatus } from '@/auth/utils/getOnboardingStatus'; @@ -16,7 +17,7 @@ import { useSnackBar } from '@/ui/snack-bar/hooks/useSnackBar'; import { TableHotkeyScope } from '@/ui/table/types/TableHotkeyScope'; import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; import { useGetWorkspaceFromInviteHashLazyQuery } from '~/generated/graphql'; -import { ActivityType, CommentableType } from '~/generated/graphql'; +import { ActivityType } from '~/generated/graphql'; import { useIsMatchingLocation } from '../hooks/useIsMatchingLocation'; @@ -177,7 +178,7 @@ export function AuthAutoRouter() { )?.params.id; const entity = !!companyId - ? { id: companyId, type: CommentableType.Company } + ? { id: companyId, type: ActivityTargetableEntityType.Company } : undefined; addToCommandMenu([ @@ -211,7 +212,7 @@ export function AuthAutoRouter() { ?.params.id; const entity = !!personId - ? { id: personId, type: CommentableType.Person } + ? { id: personId, type: ActivityTargetableEntityType.Person } : undefined; addToCommandMenu([ diff --git a/front/src/testing/mock-data/activities.ts b/front/src/testing/mock-data/activities.ts index 6652e92f86..867c268ee1 100644 --- a/front/src/testing/mock-data/activities.ts +++ b/front/src/testing/mock-data/activities.ts @@ -3,7 +3,9 @@ import { ActivityTarget, ActivityType, Comment, - CommentableType, + Company, + Person, + User, } from '~/generated/graphql'; type MockedActivity = Pick< @@ -33,7 +35,11 @@ type MockedActivity = Pick< lastName: string; displayName: string; }; - comments: Array>; + comments: Array< + Pick & { + author: Pick; + } + >; activityTargets: Array< Pick< ActivityTarget, @@ -42,9 +48,13 @@ type MockedActivity = Pick< | 'createdAt' | 'updatedAt' | 'activityId' - | 'commentableId' - | 'commentableType' - > & { activity: Pick } + | 'personId' + | 'companyId' + > & { + activity: Pick; + person?: Pick; + company?: Pick; + } >; }; @@ -106,8 +116,13 @@ export const mockedActivities: Array = [ id: '89bb825c-171e-4bcc-9cf7-43448d6fb300', createdAt: '2023-04-26T10:12:42.33625+00:00', updatedAt: '2023-04-26T10:23:42.33625+00:00', - commentableType: CommentableType.Company, - commentableId: '89bb825c-171e-4bcc-9cf7-43448d6fb278', // airbnb + personId: null, + companyId: '89bb825c-171e-4bcc-9cf7-43448d6fb278', + company: { + id: '89bb825c-171e-4bcc-9cf7-43448d6fb278', + name: 'Airbnb', + domainName: 'airbnb.com', + }, activityId: '89bb825c-171e-4bcc-9cf7-43448d6fb230', activity: { id: '89bb825c-171e-4bcc-9cf7-43448d6fb230', @@ -120,8 +135,13 @@ export const mockedActivities: Array = [ id: '89bb825c-171e-4bcc-9cf7-43448d6fb301', createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), - commentableType: CommentableType.Company, - commentableId: 'b396e6b9-dc5c-4643-bcff-61b6cf7523ae', // aircall + personId: null, + companyId: 'b396e6b9-dc5c-4643-bcff-61b6cf7523ae', + company: { + id: '89bb825c-171e-4bcc-9cf7-43448d6fb278', + name: 'Aircall', + domainName: 'aircall.io', + }, activityId: '89bb825c-171e-4bcc-9cf7-43448d6fb231', activity: { id: '89bb825c-171e-4bcc-9cf7-43448d6fb231', @@ -161,8 +181,12 @@ export const mockedActivities: Array = [ id: '89bb825c-171e-4bcc-9cf7-43448d6fb278', createdAt: '2023-04-26T10:12:42.33625+00:00', updatedAt: '2023-04-26T10:23:42.33625+00:00', - commentableType: CommentableType.Person, - commentableId: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', // Alexandre + personId: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', // Alexandre + person: { + id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', + displayName: 'Alexandre Test', + }, + companyId: null, activityId: '89bb825c-171e-4bcc-9cf7-43448d6fb278', activity: { id: '89bb825c-171e-4bcc-9cf7-43448d6fb278', @@ -175,8 +199,8 @@ export const mockedActivities: Array = [ id: '89bb825c-171e-4bcc-9cf7-43448d6fb278', createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), - commentableType: CommentableType.Person, - commentableId: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6d', // Jean d'Eau + personId: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6d', // Jean d'Eau + companyId: null, activityId: '89bb825c-171e-4bcc-9cf7-43448d6fb278', activity: { id: '89bb825c-171e-4bcc-9cf7-43448d6fb278', diff --git a/server/src/core/company/company-relations.resolver.ts b/server/src/core/company/company-relations.resolver.ts index f238c1b340..e432fddeea 100644 --- a/server/src/core/company/company-relations.resolver.ts +++ b/server/src/core/company/company-relations.resolver.ts @@ -29,8 +29,7 @@ export class CompanyRelationsResolver { where: { activityTargets: { some: { - commentableType: 'Company', - commentableId: company.id, + companyId: company.id, }, }, }, @@ -51,8 +50,7 @@ export class CompanyRelationsResolver { activity: { activityTargets: { some: { - commentableType: 'Company', - commentableId: company.id, + companyId: company.id, }, }, }, @@ -69,8 +67,7 @@ export class CompanyRelationsResolver { where: { activityTargets: { some: { - commentableType: 'Company', - commentableId: company.id, + companyId: company.id, }, }, }, diff --git a/server/src/core/person/person-relations.resolver.ts b/server/src/core/person/person-relations.resolver.ts index eeb34f5e36..7eb96d4669 100644 --- a/server/src/core/person/person-relations.resolver.ts +++ b/server/src/core/person/person-relations.resolver.ts @@ -29,8 +29,7 @@ export class PersonRelationsResolver { where: { activityTargets: { some: { - commentableType: 'Person', - commentableId: person.id, + personId: person.id, }, }, }, @@ -51,8 +50,7 @@ export class PersonRelationsResolver { activity: { activityTargets: { some: { - commentableType: 'Person', - commentableId: person.id, + personId: person.id, }, }, }, @@ -69,8 +67,7 @@ export class PersonRelationsResolver { where: { activityTargets: { some: { - commentableType: 'Person', - commentableId: person.id, + personId: person.id, }, }, }, diff --git a/server/src/database/migrations/20230811232332_remove_activity_commentable_type_and_commentable_id/migration.sql b/server/src/database/migrations/20230811232332_remove_activity_commentable_type_and_commentable_id/migration.sql new file mode 100644 index 0000000000..df5dc619b4 --- /dev/null +++ b/server/src/database/migrations/20230811232332_remove_activity_commentable_type_and_commentable_id/migration.sql @@ -0,0 +1,13 @@ +/* + Warnings: + + - You are about to drop the column `commentableId` on the `activity_targets` table. All the data in the column will be lost. + - You are about to drop the column `commentableType` on the `activity_targets` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "activity_targets" DROP COLUMN "commentableId", +DROP COLUMN "commentableType"; + +-- DropEnum +DROP TYPE "CommentableType"; diff --git a/server/src/database/schema.prisma b/server/src/database/schema.prisma index e80af3a6be..722487d20f 100644 --- a/server/src/database/schema.prisma +++ b/server/src/database/schema.prisma @@ -364,11 +364,6 @@ model Activity { @@map("activities") } -enum CommentableType { - Person - Company -} - model Comment { /// @Validator.IsString() /// @Validator.IsOptional() @@ -400,14 +395,12 @@ model ActivityTarget { /// @Validator.IsOptional() id String @id @default(uuid()) - activity Activity @relation(fields: [activityId], references: [id], onDelete: Cascade) - activityId String - commentableType CommentableType? - commentableId String? + activity Activity @relation(fields: [activityId], references: [id], onDelete: Cascade) + activityId String /// @TypeGraphQL.omit(input: true, output: true) - workspace Workspace @relation(fields: [workspaceId], references: [id]) + workspace Workspace @relation(fields: [workspaceId], references: [id]) /// @TypeGraphQL.omit(input: true, output: true) - workspaceId String + workspaceId String personId String? person Person? @relation(fields: [personId], references: [id], onDelete: Cascade) diff --git a/server/src/database/seeds/comments.ts b/server/src/database/seeds/comments.ts index 18f779d6a5..61700f03ea 100644 --- a/server/src/database/seeds/comments.ts +++ b/server/src/database/seeds/comments.ts @@ -18,8 +18,8 @@ export const seedComments = async (prisma: PrismaClient) => { update: {}, create: { id: 'twenty-fe256b39-3ec3-4fe3-8997-b76aa0bfb600', - commentableType: 'Company', - commentableId: 'twenty-fe256b39-3ec3-4fe3-8997-b76aa0bfa408', + personId: null, + companyId: 'twenty-fe256b39-3ec3-4fe3-8997-b76aa0bfa408', activityId: 'twenty-fe256b39-3ec3-4fe3-8997-b76aa0bfb400', workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419', }, @@ -71,8 +71,8 @@ export const seedComments = async (prisma: PrismaClient) => { update: {}, create: { id: 'twenty-fe256b39-3ec3-4fe3-8997-a76aa0bfb600', - commentableType: 'Person', - commentableId: 'twenty-755035db-623d-41fe-92e7-dd45b7c568e1', + personId: 'twenty-755035db-623d-41fe-92e7-dd45b7c568e1', + companyId: null, activityId: 'twenty-fe256b39-3ec3-4fe3-8997-b76aa0bfc408', workspaceId: 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419', }, @@ -108,8 +108,8 @@ export const seedComments = async (prisma: PrismaClient) => { update: {}, create: { id: 'twenty-dev-fe256b39-3ec3-4fe3-8997-a76aa0bfba00', - commentableType: 'Company', - commentableId: 'twenty-dev-a674fa6c-1455-4c57-afaf-dd5dc086361e', + personId: null, + companyId: 'twenty-dev-a674fa6c-1455-4c57-afaf-dd5dc086361e', activityId: 'twenty-dev-fe256b39-3ec3-4fe3-8997-b76aaabfb408', workspaceId: 'twenty-dev-7ed9d212-1c25-4d02-bf25-6aeccf7ea420', },