diff --git a/front/src/generated/graphql.tsx b/front/src/generated/graphql.tsx index fbfdfb967..e0c1cc13b 100644 --- a/front/src/generated/graphql.tsx +++ b/front/src/generated/graphql.tsx @@ -3196,7 +3196,7 @@ export type GetFavoritesQueryVariables = Exact<{ [key: string]: never; }>; export type GetFavoritesQuery = { __typename?: 'Query', findFavorites: Array<{ __typename?: 'Favorite', id: string, person?: { __typename?: 'Person', id: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null } | null, company?: { __typename?: 'Company', id: string, name: string, domainName: string, accountOwner?: { __typename?: 'User', id: string, displayName: string, avatarUrl?: string | null } | null } | null }> }; -export type InsertPersonFragmentFragment = { __typename?: 'Person', id: string, firstName?: string | null, lastName?: string | null, displayName: string, createdAt: string }; +export type PersonFieldsFragmentFragment = { __typename?: 'Person', id: string, phone?: string | null, email?: string | null, city?: string | null, firstName?: string | null, lastName?: string | null, displayName: string, jobTitle?: string | null, linkedinUrl?: string | null, xUrl?: string | null, avatarUrl?: string | null, createdAt: string, _activityCount: number, company?: { __typename?: 'Company', id: string, name: string, domainName: string } | null }; export type DeleteManyPersonMutationVariables = Exact<{ ids?: InputMaybe | Scalars['String']>; @@ -3217,7 +3217,7 @@ export type InsertOnePersonMutationVariables = Exact<{ }>; -export type InsertOnePersonMutation = { __typename?: 'Mutation', createOnePerson: { __typename?: 'Person', id: string, firstName?: string | null, lastName?: string | null, displayName: string, createdAt: string } }; +export type InsertOnePersonMutation = { __typename?: 'Mutation', createOnePerson: { __typename?: 'Person', id: string, phone?: string | null, email?: string | null, city?: string | null, firstName?: string | null, lastName?: string | null, displayName: string, jobTitle?: string | null, linkedinUrl?: string | null, xUrl?: string | null, avatarUrl?: string | null, createdAt: string, _activityCount: number, company?: { __typename?: 'Company', id: string, name: string, domainName: string } | null } }; export type RemovePersonPictureMutationVariables = Exact<{ where: PersonWhereUniqueInput; @@ -3707,7 +3707,7 @@ export const UserQueryFragmentFragmentDoc = gql` } `; export const CompanyFieldsFragmentFragmentDoc = gql` - fragment CompanyFieldsFragment on Company { + fragment companyFieldsFragment on Company { accountOwner { id email @@ -3726,13 +3726,26 @@ export const CompanyFieldsFragmentFragmentDoc = gql` name } `; -export const InsertPersonFragmentFragmentDoc = gql` - fragment InsertPersonFragment on Person { +export const PersonFieldsFragmentFragmentDoc = gql` + fragment personFieldsFragment on Person { id + phone + email + city firstName lastName displayName + jobTitle + linkedinUrl + xUrl + avatarUrl createdAt + _activityCount + company { + id + name + domainName + } } `; export const AddActivityTargetsOnActivityDocument = gql` @@ -4535,7 +4548,7 @@ export type InsertManyCompanyMutationOptions = Apollo.BaseMutationOptions; /** @@ -5855,7 +5868,7 @@ export type SearchActivityQueryResult = Apollo.QueryResult & { @@ -86,6 +88,7 @@ export function ActivityAssigneePicker({ }, }, }, + refetchQueries: [getOperationName(GET_ACTIVITIES) ?? ''], }); } diff --git a/front/src/modules/activities/components/ActivityEditor.tsx b/front/src/modules/activities/components/ActivityEditor.tsx index 826893f8c..326233c72 100644 --- a/front/src/modules/activities/components/ActivityEditor.tsx +++ b/front/src/modules/activities/components/ActivityEditor.tsx @@ -119,6 +119,7 @@ export function ActivityEditor({ title: newTitle, }, }, + refetchQueries: [getOperationName(GET_ACTIVITIES) ?? ''], }); }, [activity.id, cachedActivity, updateActivityMutation], diff --git a/front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts b/front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts index 8b0057b8e..c8a2c8237 100644 --- a/front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts +++ b/front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts @@ -30,10 +30,15 @@ export function useOpenCreateActivityDrawer() { ); const [, setViewableActivityId] = useRecoilState(viewableActivityIdState); - return function openCreateActivityDrawer( - type: ActivityType, - entities?: ActivityTargetableEntity[], - ) { + return function openCreateActivityDrawer({ + type, + targetableEntities, + assigneeId, + }: { + type: ActivityType; + targetableEntities?: ActivityTargetableEntity[]; + assigneeId?: string; + }) { const now = new Date().toISOString(); return createActivityMutation({ @@ -43,11 +48,13 @@ export function useOpenCreateActivityDrawer() { createdAt: now, updatedAt: now, author: { connect: { id: currentUser?.id ?? '' } }, - assignee: { connect: { id: currentUser?.id ?? '' } }, + assignee: { connect: { id: assigneeId ?? currentUser?.id ?? '' } }, type: type, activityTargets: { createMany: { - data: entities ? getRelationData(entities) : [], + data: targetableEntities + ? getRelationData(targetableEntities) + : [], skipDuplicates: true, }, }, @@ -63,7 +70,7 @@ export function useOpenCreateActivityDrawer() { onCompleted(data) { setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false }); setViewableActivityId(data.createOneActivity.id); - setActivityTargetableEntityArray(entities ?? []); + setActivityTargetableEntityArray(targetableEntities ?? []); openRightDrawer(RightDrawerPages.CreateActivity); }, }); diff --git a/front/src/modules/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds.ts b/front/src/modules/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds.ts index f7359fe2a..695bbce5f 100644 --- a/front/src/modules/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds.ts +++ b/front/src/modules/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds.ts @@ -24,6 +24,9 @@ export function useOpenCreateActivityDrawerForSelectedRowIds() { type: entityType, id, })); - openCreateActivityDrawer(type, activityTargetableEntityArray); + openCreateActivityDrawer({ + type, + targetableEntities: activityTargetableEntityArray, + }); }; } diff --git a/front/src/modules/activities/notes/components/Notes.tsx b/front/src/modules/activities/notes/components/Notes.tsx index be2db5abe..007358de9 100644 --- a/front/src/modules/activities/notes/components/Notes.tsx +++ b/front/src/modules/activities/notes/components/Notes.tsx @@ -59,7 +59,12 @@ export function Notes({ entity }: { entity: ActivityTargetableEntity }) { Icon={IconNotes} title="New note" variant="secondary" - onClick={() => openCreateActivity(ActivityType.Note, [entity])} + onClick={() => + openCreateActivity({ + type: ActivityType.Note, + targetableEntities: [entity], + }) + } /> ); @@ -76,7 +81,12 @@ export function Notes({ entity }: { entity: ActivityTargetableEntity }) { size="small" variant="secondary" title="Add note" - onClick={() => openCreateActivity(ActivityType.Note, [entity])} + onClick={() => + openCreateActivity({ + type: ActivityType.Note, + targetableEntities: [entity], + }) + } > } /> diff --git a/front/src/modules/activities/tasks/components/AddTaskButton.tsx b/front/src/modules/activities/tasks/components/AddTaskButton.tsx index a945a449c..074bd804a 100644 --- a/front/src/modules/activities/tasks/components/AddTaskButton.tsx +++ b/front/src/modules/activities/tasks/components/AddTaskButton.tsx @@ -5,13 +5,13 @@ import { IconPlus } from '@/ui/icon'; import { ActivityType } from '~/generated/graphql'; export function AddTaskButton({ - entity, + activityTargetEntity, }: { - entity?: ActivityTargetableEntity; + activityTargetEntity?: ActivityTargetableEntity; }) { const openCreateActivity = useOpenCreateActivityDrawer(); - if (!entity) { + if (!activityTargetEntity) { return <>; } @@ -21,7 +21,12 @@ export function AddTaskButton({ size="small" variant="secondary" title="Add task" - onClick={() => openCreateActivity(ActivityType.Task, [entity])} + onClick={() => + openCreateActivity({ + type: ActivityType.Task, + targetableEntities: [activityTargetEntity], + }) + } > ); } diff --git a/front/src/modules/activities/tasks/components/PageAddTaskButton.tsx b/front/src/modules/activities/tasks/components/PageAddTaskButton.tsx new file mode 100644 index 000000000..1243cf713 --- /dev/null +++ b/front/src/modules/activities/tasks/components/PageAddTaskButton.tsx @@ -0,0 +1,34 @@ +import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer'; +import { TasksRecoilScopeContext } from '@/activities/states/recoil-scope-contexts/TasksRecoilScopeContext'; +import { DropdownRecoilScopeContext } from '@/ui/dropdown/states/recoil-scope-contexts/DropdownRecoilScopeContext'; +import { PageAddButton } from '@/ui/layout/components/PageAddButton'; +import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope'; +import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue'; +import { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState'; +import { ActivityType } from '~/generated/graphql'; + +export function PageAddTaskButton() { + const openCreateActivity = useOpenCreateActivityDrawer(); + + const filters = useRecoilScopedValue( + filtersScopedState, + TasksRecoilScopeContext, + ); + + const assigneeIdFilter = filters.find( + (filter) => filter.key === 'assigneeId', + ); + + function handleClick() { + openCreateActivity({ + type: ActivityType.Task, + assigneeId: assigneeIdFilter?.value, + }); + } + + return ( + + + + ); +} diff --git a/front/src/modules/activities/tasks/components/TaskGroups.tsx b/front/src/modules/activities/tasks/components/TaskGroups.tsx index f038717f0..fcdd37b59 100644 --- a/front/src/modules/activities/tasks/components/TaskGroups.tsx +++ b/front/src/modules/activities/tasks/components/TaskGroups.tsx @@ -83,7 +83,10 @@ export function TaskGroups({ entity, showAddButton }: OwnProps) { title="New task" variant={'secondary'} onClick={() => - openCreateActivity(ActivityType.Task, entity ? [entity] : undefined) + openCreateActivity({ + type: ActivityType.Task, + targetableEntities: entity ? [entity] : undefined, + }) } /> @@ -95,21 +98,27 @@ export function TaskGroups({ entity, showAddButton }: OwnProps) { {activeTabId === 'done' ? ( } + button={ + showAddButton && + } /> ) : ( <> } + button={ + showAddButton && + } /> + !todayOrPreviousTasks?.length && ( + + ) } /> + !upcomingTasks?.length && ( + + ) } /> diff --git a/front/src/modules/activities/timeline/components/Timeline.tsx b/front/src/modules/activities/timeline/components/Timeline.tsx index 235618aef..159130c47 100644 --- a/front/src/modules/activities/timeline/components/Timeline.tsx +++ b/front/src/modules/activities/timeline/components/Timeline.tsx @@ -77,8 +77,18 @@ export function Timeline({ entity }: { entity: ActivityTargetableEntity }) { No activity yet Create one: openCreateActivity(ActivityType.Note, [entity])} - onTaskClick={() => openCreateActivity(ActivityType.Task, [entity])} + onNoteClick={() => + openCreateActivity({ + type: ActivityType.Note, + targetableEntities: [entity], + }) + } + onTaskClick={() => + openCreateActivity({ + type: ActivityType.Task, + targetableEntities: [entity], + }) + } /> ); diff --git a/front/src/modules/apollo/optimistic-effect/hooks/useOptimisticEffect.ts b/front/src/modules/apollo/optimistic-effect/hooks/useOptimisticEffect.ts index 17e584a07..95b5602f5 100644 --- a/front/src/modules/apollo/optimistic-effect/hooks/useOptimisticEffect.ts +++ b/front/src/modules/apollo/optimistic-effect/hooks/useOptimisticEffect.ts @@ -1,39 +1,111 @@ -import { useApolloClient } from '@apollo/client'; +import { + ApolloCache, + DocumentNode, + OperationVariables, + useApolloClient, +} from '@apollo/client'; import { useRecoilCallback } from 'recoil'; +import { GET_COMPANIES } from '@/companies/graphql/queries/getCompanies'; +import { GET_PEOPLE } from '@/people/graphql/queries/getPeople'; +import { GetCompaniesQuery, GetPeopleQuery } from '~/generated/graphql'; + import { optimisticEffectState } from '../states/optimisticEffectState'; -import { OptimisticEffect } from '../types/OptimisticEffect'; +import { OptimisticEffectDefinition } from '../types/OptimisticEffectDefinition'; export function useOptimisticEffect() { const apolloClient = useApolloClient(); const registerOptimisticEffect = useRecoilCallback( ({ snapshot, set }) => - (optimisticEffect: OptimisticEffect) => { - const { key } = optimisticEffect; + ({ + variables, + definition, + }: { + variables: OperationVariables; + definition: OptimisticEffectDefinition; + }) => { const optimisticEffects = snapshot .getLoadable(optimisticEffectState) .getValue(); + function optimisticEffectWriter({ + cache, + newData, + query, + variables, + }: { + cache: ApolloCache; + newData: unknown[]; + variables: OperationVariables; + query: DocumentNode; + }) { + const existingData = cache.readQuery({ + query, + variables, + }); + + if (!existingData) { + return; + } + + if (query === GET_PEOPLE) { + cache.writeQuery({ + query, + variables, + data: { + people: definition.resolver({ + currentData: (existingData as GetPeopleQuery).people, + newData, + variables, + }), + }, + }); + } + + if (query === GET_COMPANIES) { + cache.writeQuery({ + query, + variables, + data: { + companies: definition.resolver({ + currentData: (existingData as GetCompaniesQuery).companies, + newData, + variables, + }), + }, + }); + } + } + + const optimisticEffect = { + key: definition.key, + variables, + typename: definition.typename, + query: definition.query, + writer: optimisticEffectWriter, + }; + set(optimisticEffectState, { ...optimisticEffects, - [key]: optimisticEffect, + [definition.key]: optimisticEffect, }); }, ); const triggerOptimisticEffects = useRecoilCallback( ({ snapshot }) => - (typename: string, entities: any[]) => { + (typename: string, newData: any[]) => { const optimisticEffects = snapshot .getLoadable(optimisticEffectState) .getValue(); Object.values(optimisticEffects).forEach((optimisticEffect) => { if (optimisticEffect.typename === typename) { - optimisticEffect.resolver({ + optimisticEffect.writer({ cache: apolloClient.cache, - entities, + query: optimisticEffect.query, + newData, variables: optimisticEffect.variables, }); } diff --git a/front/src/modules/apollo/optimistic-effect/states/optimisticEffectState.ts b/front/src/modules/apollo/optimistic-effect/states/optimisticEffectState.ts index 37219471e..a0eed30ee 100644 --- a/front/src/modules/apollo/optimistic-effect/states/optimisticEffectState.ts +++ b/front/src/modules/apollo/optimistic-effect/states/optimisticEffectState.ts @@ -1,9 +1,9 @@ import { atom } from 'recoil'; -import { OptimisticEffect } from '../types/OptimisticEffect'; +import { OptimisticEffect } from '../types/internal/OptimisticEffect'; export const optimisticEffectState = atom< - Record> + Record> >({ key: 'optimisticEffectState', default: {}, diff --git a/front/src/modules/apollo/optimistic-effect/types/OptimisticEffect.ts b/front/src/modules/apollo/optimistic-effect/types/OptimisticEffect.ts deleted file mode 100644 index ff8431599..000000000 --- a/front/src/modules/apollo/optimistic-effect/types/OptimisticEffect.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ApolloCache } from '@apollo/client'; - -type OptimisticEffectResolver = ({ - cache, - entities, - variables, -}: { - cache: ApolloCache; - entities: T[]; - variables: QueryVariables; -}) => void; - -export type OptimisticEffect = { - key: string; - typename: string; - variables: QueryVariables; - resolver: OptimisticEffectResolver; -}; diff --git a/front/src/modules/apollo/optimistic-effect/types/OptimisticEffectDefinition.ts b/front/src/modules/apollo/optimistic-effect/types/OptimisticEffectDefinition.ts new file mode 100644 index 000000000..9e7e1bc8a --- /dev/null +++ b/front/src/modules/apollo/optimistic-effect/types/OptimisticEffectDefinition.ts @@ -0,0 +1,10 @@ +import { DocumentNode } from 'graphql'; + +import { OptimisticEffectResolver } from './OptimisticEffectResolver'; + +export type OptimisticEffectDefinition = { + key: string; + query: DocumentNode; + typename: string; + resolver: OptimisticEffectResolver; +}; diff --git a/front/src/modules/apollo/optimistic-effect/types/OptimisticEffectResolver.ts b/front/src/modules/apollo/optimistic-effect/types/OptimisticEffectResolver.ts new file mode 100644 index 000000000..a1ca99aa7 --- /dev/null +++ b/front/src/modules/apollo/optimistic-effect/types/OptimisticEffectResolver.ts @@ -0,0 +1,11 @@ +import { OperationVariables } from '@apollo/client'; + +export type OptimisticEffectResolver = ({ + currentData, + newData, + variables, +}: { + currentData: T[]; + newData: T[]; + variables: OperationVariables; +}) => void; diff --git a/front/src/modules/apollo/optimistic-effect/types/internal/OptimisticEffect.ts b/front/src/modules/apollo/optimistic-effect/types/internal/OptimisticEffect.ts new file mode 100644 index 000000000..eeedf4f22 --- /dev/null +++ b/front/src/modules/apollo/optimistic-effect/types/internal/OptimisticEffect.ts @@ -0,0 +1,21 @@ +import { ApolloCache, DocumentNode, OperationVariables } from '@apollo/client'; + +type OptimisticEffectWriter = ({ + cache, + newData, + variables, + query, +}: { + cache: ApolloCache; + query: DocumentNode; + newData: T[]; + variables: OperationVariables; +}) => void; + +export type OptimisticEffect = { + key: string; + query: DocumentNode; + typename: string; + variables: OperationVariables; + writer: OptimisticEffectWriter; +}; diff --git a/front/src/modules/companies/graphql/fragments/companyFieldsFragment.ts b/front/src/modules/companies/graphql/fragments/companyFieldsFragment.ts index af48e99c3..1a71207e6 100644 --- a/front/src/modules/companies/graphql/fragments/companyFieldsFragment.ts +++ b/front/src/modules/companies/graphql/fragments/companyFieldsFragment.ts @@ -1,7 +1,7 @@ import { gql } from '@apollo/client'; export const COMPANY_FIELDS_FRAGMENT = gql` - fragment CompanyFieldsFragment on Company { + fragment companyFieldsFragment on Company { accountOwner { id email @@ -18,5 +18,6 @@ export const COMPANY_FIELDS_FRAGMENT = gql` idealCustomerProfile id name + _activityCount } `; diff --git a/front/src/modules/companies/graphql/mutations/insertOneCompany.ts b/front/src/modules/companies/graphql/mutations/insertOneCompany.ts index 6b63c03b9..9e99d3ea3 100644 --- a/front/src/modules/companies/graphql/mutations/insertOneCompany.ts +++ b/front/src/modules/companies/graphql/mutations/insertOneCompany.ts @@ -3,7 +3,7 @@ import { gql } from '@apollo/client'; export const INSERT_ONE_COMPANY = gql` mutation InsertOneCompany($data: CompanyCreateInput!) { createOneCompany(data: $data) { - ...CompanyFieldsFragment + ...companyFieldsFragment } } `; diff --git a/front/src/modules/companies/graphql/mutations/updateOneCompany.ts b/front/src/modules/companies/graphql/mutations/updateOneCompany.ts index 88e4e1e21..b705988f5 100644 --- a/front/src/modules/companies/graphql/mutations/updateOneCompany.ts +++ b/front/src/modules/companies/graphql/mutations/updateOneCompany.ts @@ -6,7 +6,7 @@ export const UPDATE_ONE_COMPANY = gql` $data: CompanyUpdateInput! ) { updateOneCompany(data: $data, where: $where) { - ...CompanyFieldsFragment + ...companyFieldsFragment } } `; diff --git a/front/src/modules/companies/graphql/optimistic-effect-definitions/getCompaniesOptimisticEffectDefinition.ts b/front/src/modules/companies/graphql/optimistic-effect-definitions/getCompaniesOptimisticEffectDefinition.ts new file mode 100644 index 000000000..c30f4d4e4 --- /dev/null +++ b/front/src/modules/companies/graphql/optimistic-effect-definitions/getCompaniesOptimisticEffectDefinition.ts @@ -0,0 +1,18 @@ +import { Company } from '~/generated/graphql'; + +import { GET_COMPANIES } from '../queries/getCompanies'; + +export const getCompaniesOptimisticEffectDefinition = { + key: 'generic-entity-table-data-companies', + typename: 'Company', + query: GET_COMPANIES, + resolver: ({ + currentData, + newData, + }: { + currentData: Company[]; + newData: Company[]; + }) => { + return [...newData, ...currentData]; + }, +}; diff --git a/front/src/modules/companies/graphql/optimistic-effects/getCompaniesOptimisticEffect.ts b/front/src/modules/companies/graphql/optimistic-effects/getCompaniesOptimisticEffect.ts deleted file mode 100644 index 1327d288b..000000000 --- a/front/src/modules/companies/graphql/optimistic-effects/getCompaniesOptimisticEffect.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { ApolloCache } from '@apollo/client'; - -import { - Company, - GetCompaniesQuery, - GetCompaniesQueryVariables, -} from '~/generated/graphql'; - -import { GET_COMPANIES } from '../queries/getCompanies'; - -function optimisticEffectResolver({ - cache, - entities, - variables, -}: { - cache: ApolloCache; - entities: Company[]; - variables: GetCompaniesQueryVariables; -}) { - const existingData = cache.readQuery({ - query: GET_COMPANIES, - variables: { orderBy: variables.orderBy, where: variables.where }, - }); - - if (!existingData) { - return; - } - - cache.writeQuery({ - query: GET_COMPANIES, - variables: { orderBy: variables.orderBy, where: variables.where }, - data: { - companies: [...entities, ...existingData.companies], - }, - }); -} - -export function getCompaniesOptimisticEffect( - variables: GetCompaniesQueryVariables, -) { - return { - key: 'generic-entity-table-data-companies', - variables: variables, - typename: 'Company', - resolver: optimisticEffectResolver, - }; -} diff --git a/front/src/modules/companies/table/components/CompanyTable.tsx b/front/src/modules/companies/table/components/CompanyTable.tsx index 50156d646..47acdc3b9 100644 --- a/front/src/modules/companies/table/components/CompanyTable.tsx +++ b/front/src/modules/companies/table/components/CompanyTable.tsx @@ -1,5 +1,5 @@ import { companiesAvailableColumnDefinitions } from '@/companies/constants/companiesAvailableColumnDefinitions'; -import { getCompaniesOptimisticEffect } from '@/companies/graphql/optimistic-effects/getCompaniesOptimisticEffect'; +import { getCompaniesOptimisticEffectDefinition } from '@/companies/graphql/optimistic-effect-definitions/getCompaniesOptimisticEffectDefinition'; import { useCompanyTableActionBarEntries } from '@/companies/hooks/useCompanyTableActionBarEntries'; import { useCompanyTableContextMenuEntries } from '@/companies/hooks/useCompanyTableContextMenuEntries'; import { useSpreadsheetCompanyImport } from '@/companies/hooks/useSpreadsheetCompanyImport'; @@ -53,7 +53,9 @@ export function CompanyTable() { ; - entities: Person[]; - variables: GetPeopleQueryVariables; -}) { - const existingData = cache.readQuery({ - query: GET_PEOPLE, - variables: { orderBy: variables.orderBy, where: variables.where }, - }); - - if (!existingData) { - return; - } - - cache.writeQuery({ - query: GET_PEOPLE, - variables: { orderBy: variables.orderBy, where: variables.where }, - data: { - people: [...entities, ...existingData.people], - }, - }); -} - -export function getPeopleOptimisticEffect(variables: GetPeopleQueryVariables) { - return { - key: 'generic-entity-table-data-person', - variables: variables, - typename: 'Person', - resolver: optimisticEffectResolver, - }; -} diff --git a/front/src/modules/people/graphql/optimistic-effect-definitions/getPeopleOptimisticEffectDefinition.ts b/front/src/modules/people/graphql/optimistic-effect-definitions/getPeopleOptimisticEffectDefinition.ts new file mode 100644 index 000000000..3a07458e2 --- /dev/null +++ b/front/src/modules/people/graphql/optimistic-effect-definitions/getPeopleOptimisticEffectDefinition.ts @@ -0,0 +1,18 @@ +import { Person } from '~/generated/graphql'; + +import { GET_PEOPLE } from '../queries/getPeople'; + +export const getPeopleOptimisticEffectDefinition = { + key: 'generic-entity-table-data-people', + typename: 'Person', + query: GET_PEOPLE, + resolver: ({ + currentData, + newData, + }: { + currentData: Person[]; + newData: Person[]; + }) => { + return [...newData, ...currentData]; + }, +}; diff --git a/front/src/modules/people/table/components/PeopleTable.tsx b/front/src/modules/people/table/components/PeopleTable.tsx index 3ae0032da..5ce3191bc 100644 --- a/front/src/modules/people/table/components/PeopleTable.tsx +++ b/front/src/modules/people/table/components/PeopleTable.tsx @@ -1,5 +1,5 @@ import { peopleAvailableColumnDefinitions } from '@/people/constants/peopleAvailableColumnDefinitions'; -import { getPeopleOptimisticEffect } from '@/people/graphql/optimistic-effect-callback/getPeopleOptimisticEffect'; +import { getPeopleOptimisticEffectDefinition } from '@/people/graphql/optimistic-effect-definitions/getPeopleOptimisticEffectDefinition'; import { usePersonTableContextMenuEntries } from '@/people/hooks/usePeopleTableContextMenuEntries'; import { usePersonTableActionBarEntries } from '@/people/hooks/usePersonTableActionBarEntries'; import { useSpreadsheetPersonImport } from '@/people/hooks/useSpreadsheetPersonImport'; @@ -52,7 +52,9 @@ export function PeopleTable() { ` align-items: center; diff --git a/front/src/modules/ui/table/components/GenericEntityTableData.tsx b/front/src/modules/ui/table/components/GenericEntityTableData.tsx index 963d44dc8..2968eb913 100644 --- a/front/src/modules/ui/table/components/GenericEntityTableData.tsx +++ b/front/src/modules/ui/table/components/GenericEntityTableData.tsx @@ -1,7 +1,7 @@ import { useEffect } from 'react'; import { useOptimisticEffect } from '@/apollo/optimistic-effect/hooks/useOptimisticEffect'; -import { OptimisticEffect } from '@/apollo/optimistic-effect/types/OptimisticEffect'; +import { OptimisticEffectDefinition } from '@/apollo/optimistic-effect/types/OptimisticEffectDefinition'; import { useSetEntityTableData } from '@/ui/table/hooks/useSetEntityTableData'; import { FilterDefinition } from '@/ui/view-bar/types/FilterDefinition'; import { SortOrder } from '~/generated/graphql'; @@ -9,7 +9,7 @@ import { SortOrder } from '~/generated/graphql'; export function GenericEntityTableData({ useGetRequest, getRequestResultKey, - getRequestOptimisticEffect, + getRequestOptimisticEffectDefinition, orderBy = [ { createdAt: SortOrder.Desc, @@ -22,7 +22,7 @@ export function GenericEntityTableData({ }: { useGetRequest: any; getRequestResultKey: string; - getRequestOptimisticEffect: (variables: any) => OptimisticEffect; + getRequestOptimisticEffectDefinition: OptimisticEffectDefinition; orderBy?: any; whereFilters?: any; filterDefinitionArray: FilterDefinition[]; @@ -37,9 +37,10 @@ export function GenericEntityTableData({ onCompleted: (data: any) => { const entities = data[getRequestResultKey] ?? []; setEntityTableData(entities, filterDefinitionArray); - registerOptimisticEffect( - getRequestOptimisticEffect({ orderBy, where: whereFilters }), - ); + registerOptimisticEffect({ + variables: { orderBy, where: whereFilters }, + definition: getRequestOptimisticEffectDefinition, + }); }, }); diff --git a/front/src/pages/companies/Companies.tsx b/front/src/pages/companies/Companies.tsx index a5fb4989b..6ee0735ae 100644 --- a/front/src/pages/companies/Companies.tsx +++ b/front/src/pages/companies/Companies.tsx @@ -43,21 +43,6 @@ export function Companies() { address: '', }, }, - optimisticResponse: { - __typename: 'Mutation', - createOneCompany: { - __typename: 'Company', - id: newCompanyId, - name: '', - domainName: '', - address: '', - createdAt: new Date().toISOString(), - accountOwner: null, - linkedinUrl: '', - idealCustomerProfile: false, - employees: null, - }, - }, update: (_cache, { data }) => { if (data?.createOneCompany) { upsertTableRowIds(data?.createOneCompany.id); diff --git a/front/src/pages/people/People.tsx b/front/src/pages/people/People.tsx index 95cd4931a..837f0d197 100644 --- a/front/src/pages/people/People.tsx +++ b/front/src/pages/people/People.tsx @@ -40,17 +40,6 @@ export function People() { lastName: '', }, }, - optimisticResponse: { - __typename: 'Mutation', - createOnePerson: { - __typename: 'Person', - id: newPersonId, - firstName: '', - lastName: '', - displayName: '', - createdAt: '', - }, - }, update: (_cache, { data }) => { if (data?.createOnePerson) { upsertTableRowIds(data?.createOnePerson.id); diff --git a/front/src/pages/tasks/Tasks.tsx b/front/src/pages/tasks/Tasks.tsx index 6d534bc12..6e15db36c 100644 --- a/front/src/pages/tasks/Tasks.tsx +++ b/front/src/pages/tasks/Tasks.tsx @@ -1,12 +1,10 @@ import styled from '@emotion/styled'; -import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer'; import { TasksRecoilScopeContext } from '@/activities/states/recoil-scope-contexts/TasksRecoilScopeContext'; +import { PageAddTaskButton } from '@/activities/tasks/components/PageAddTaskButton'; import { TaskGroups } from '@/activities/tasks/components/TaskGroups'; -import { DropdownRecoilScopeContext } from '@/ui/dropdown/states/recoil-scope-contexts/DropdownRecoilScopeContext'; import { IconArchive, IconCheck, IconCheckbox } from '@/ui/icon/index'; import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope'; -import { PageAddButton } from '@/ui/layout/components/PageAddButton'; import { PageBody } from '@/ui/layout/components/PageBody'; import { PageContainer } from '@/ui/layout/components/PageContainer'; import { PageHeader } from '@/ui/layout/components/PageHeader'; @@ -14,7 +12,6 @@ import { TabList } from '@/ui/tab/components/TabList'; import { TopBar } from '@/ui/top-bar/TopBar'; import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope'; import { FilterDropdownButton } from '@/ui/view-bar/components/FilterDropdownButton'; -import { ActivityType } from '~/generated/graphql'; const StyledTasksContainer = styled.div` display: flex; @@ -32,8 +29,6 @@ const StyledTabListContainer = styled.div` `; export function Tasks() { - const openCreateActivity = useOpenCreateActivityDrawer(); - const TASK_TABS = [ { id: 'to-do', @@ -49,16 +44,12 @@ export function Tasks() { return ( - - - openCreateActivity(ActivityType.Task)} - /> - - - - - + + + + + + @@ -74,9 +65,9 @@ export function Tasks() { } /> - - - + + + ); } diff --git a/front/src/sync-hooks/PageChangeEffect.tsx b/front/src/sync-hooks/PageChangeEffect.tsx index bcf4f444c..f04087ece 100644 --- a/front/src/sync-hooks/PageChangeEffect.tsx +++ b/front/src/sync-hooks/PageChangeEffect.tsx @@ -191,10 +191,10 @@ export function PageChangeEffect() { type: CommandType.Create, Icon: IconCheckbox, onCommandClick: () => - openCreateActivity( - ActivityType.Task, - entity ? [entity] : undefined, - ), + openCreateActivity({ + type: ActivityType.Task, + targetableEntities: entity ? [entity] : undefined, + }), }, { to: '', @@ -202,10 +202,10 @@ export function PageChangeEffect() { type: CommandType.Create, Icon: IconNotes, onCommandClick: () => - openCreateActivity( - ActivityType.Note, - entity ? [entity] : undefined, - ), + openCreateActivity({ + type: ActivityType.Note, + targetableEntities: entity ? [entity] : undefined, + }), }, ]); break; @@ -225,10 +225,10 @@ export function PageChangeEffect() { type: CommandType.Create, Icon: IconCheckbox, onCommandClick: () => - openCreateActivity( - ActivityType.Task, - entity ? [entity] : undefined, - ), + openCreateActivity({ + type: ActivityType.Task, + targetableEntities: entity ? [entity] : undefined, + }), }, { to: '', @@ -236,10 +236,10 @@ export function PageChangeEffect() { type: CommandType.Create, Icon: IconNotes, onCommandClick: () => - openCreateActivity( - ActivityType.Note, - entity ? [entity] : undefined, - ), + openCreateActivity({ + type: ActivityType.Note, + targetableEntities: entity ? [entity] : undefined, + }), }, ]); break; @@ -251,7 +251,8 @@ export function PageChangeEffect() { label: 'Create Task', type: CommandType.Create, Icon: IconCheckbox, - onCommandClick: () => openCreateActivity(ActivityType.Task), + onCommandClick: () => + openCreateActivity({ type: ActivityType.Task }), }, ]); break;