Skip to content

Commit 98f913a

Browse files
magrinjAdityaPimpalkar
authored andcommitted
feat: search activities (twentyhq#972)
1 parent d6d38da commit 98f913a

File tree

4 files changed

+142
-24
lines changed

4 files changed

+142
-24
lines changed

front/src/generated/graphql.tsx

+54-1
Original file line numberDiff line numberDiff line change
@@ -2638,7 +2638,7 @@ export type SearchPeopleQueryVariables = Exact<{
26382638
}>;
26392639

26402640

2641-
export type SearchPeopleQuery = { __typename?: 'Query', searchResults: Array<{ __typename?: 'Person', id: string, phone?: string | null, email?: string | null, city?: string | null, firstName?: string | null, lastName?: string | null, createdAt: string }> };
2641+
export type SearchPeopleQuery = { __typename?: 'Query', searchResults: Array<{ __typename?: 'Person', id: string, phone?: string | null, email?: string | null, city?: string | null, firstName?: string | null, lastName?: string | null, displayName: string, createdAt: string }> };
26422642

26432643
export type SearchUserQueryVariables = Exact<{
26442644
where?: InputMaybe<UserWhereInput>;
@@ -2663,6 +2663,15 @@ export type SearchCompanyQueryVariables = Exact<{
26632663

26642664
export type SearchCompanyQuery = { __typename?: 'Query', searchResults: Array<{ __typename?: 'Company', id: string, name: string, domainName: string }> };
26652665

2666+
export type SearchActivityQueryVariables = Exact<{
2667+
where?: InputMaybe<ActivityWhereInput>;
2668+
limit?: InputMaybe<Scalars['Int']>;
2669+
orderBy?: InputMaybe<Array<ActivityOrderByWithRelationInput> | ActivityOrderByWithRelationInput>;
2670+
}>;
2671+
2672+
2673+
export type SearchActivityQuery = { __typename?: 'Query', searchResults: Array<{ __typename?: 'Activity', id: string, title?: string | null, body?: string | null }> };
2674+
26662675
export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never; }>;
26672676

26682677

@@ -4576,6 +4585,7 @@ export const SearchPeopleDocument = gql`
45764585
city
45774586
firstName
45784587
lastName
4588+
displayName
45794589
createdAt
45804590
}
45814591
}
@@ -4725,6 +4735,49 @@ export function useSearchCompanyLazyQuery(baseOptions?: Apollo.LazyQueryHookOpti
47254735
export type SearchCompanyQueryHookResult = ReturnType<typeof useSearchCompanyQuery>;
47264736
export type SearchCompanyLazyQueryHookResult = ReturnType<typeof useSearchCompanyLazyQuery>;
47274737
export type SearchCompanyQueryResult = Apollo.QueryResult<SearchCompanyQuery, SearchCompanyQueryVariables>;
4738+
export const SearchActivityDocument = gql`
4739+
query SearchActivity($where: ActivityWhereInput, $limit: Int, $orderBy: [ActivityOrderByWithRelationInput!]) {
4740+
searchResults: findManyActivities(
4741+
where: $where
4742+
take: $limit
4743+
orderBy: $orderBy
4744+
) {
4745+
id
4746+
title
4747+
body
4748+
}
4749+
}
4750+
`;
4751+
4752+
/**
4753+
* __useSearchActivityQuery__
4754+
*
4755+
* To run a query within a React component, call `useSearchActivityQuery` and pass it any options that fit your needs.
4756+
* When your component renders, `useSearchActivityQuery` returns an object from Apollo Client that contains loading, error, and data properties
4757+
* you can use to render your UI.
4758+
*
4759+
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
4760+
*
4761+
* @example
4762+
* const { data, loading, error } = useSearchActivityQuery({
4763+
* variables: {
4764+
* where: // value for 'where'
4765+
* limit: // value for 'limit'
4766+
* orderBy: // value for 'orderBy'
4767+
* },
4768+
* });
4769+
*/
4770+
export function useSearchActivityQuery(baseOptions?: Apollo.QueryHookOptions<SearchActivityQuery, SearchActivityQueryVariables>) {
4771+
const options = {...defaultOptions, ...baseOptions}
4772+
return Apollo.useQuery<SearchActivityQuery, SearchActivityQueryVariables>(SearchActivityDocument, options);
4773+
}
4774+
export function useSearchActivityLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<SearchActivityQuery, SearchActivityQueryVariables>) {
4775+
const options = {...defaultOptions, ...baseOptions}
4776+
return Apollo.useLazyQuery<SearchActivityQuery, SearchActivityQueryVariables>(SearchActivityDocument, options);
4777+
}
4778+
export type SearchActivityQueryHookResult = ReturnType<typeof useSearchActivityQuery>;
4779+
export type SearchActivityLazyQueryHookResult = ReturnType<typeof useSearchActivityLazyQuery>;
4780+
export type SearchActivityQueryResult = Apollo.QueryResult<SearchActivityQuery, SearchActivityQueryVariables>;
47284781
export const GetCurrentUserDocument = gql`
47294782
query GetCurrentUser {
47304783
currentUser {

front/src/modules/activities/timeline/components/Timeline.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export function Timeline({ entity }: { entity: CommentableEntity }) {
107107
},
108108
});
109109

110-
const openCreateCommandThread = useOpenCreateActivityDrawer();
110+
const openCreateActivity = useOpenCreateActivityDrawer();
111111

112112
const activities: ActivityForDrawer[] = queryResult?.findManyActivities ?? [];
113113

@@ -121,8 +121,8 @@ export function Timeline({ entity }: { entity: CommentableEntity }) {
121121
<StyledEmptyTimelineTitle>No activity yet</StyledEmptyTimelineTitle>
122122
<StyledEmptyTimelineSubTitle>Create one:</StyledEmptyTimelineSubTitle>
123123
<ActivityCreateButton
124-
onNoteClick={() => openCreateCommandThread(entity, ActivityType.Note)}
125-
onTaskClick={() => openCreateCommandThread(entity, ActivityType.Task)}
124+
onNoteClick={() => openCreateActivity(entity, ActivityType.Note)}
125+
onTaskClick={() => openCreateActivity(entity, ActivityType.Task)}
126126
/>
127127
</StyledTimelineEmptyContainer>
128128
);
@@ -132,8 +132,8 @@ export function Timeline({ entity }: { entity: CommentableEntity }) {
132132
<StyledMainContainer>
133133
<StyledTopActionBar>
134134
<ActivityCreateButton
135-
onNoteClick={() => openCreateCommandThread(entity, ActivityType.Note)}
136-
onTaskClick={() => openCreateCommandThread(entity, ActivityType.Task)}
135+
onNoteClick={() => openCreateActivity(entity, ActivityType.Note)}
136+
onTaskClick={() => openCreateActivity(entity, ActivityType.Task)}
137137
/>
138138
</StyledTopActionBar>
139139
<StyledTimelineContainer>

front/src/modules/command-menu/components/CommandMenu.tsx

+63-18
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
import { useState } from 'react';
22
import { useRecoilValue } from 'recoil';
33

4-
import { useFilteredSearchCompanyQuery } from '@/companies/queries';
5-
import { useFilteredSearchPeopleQuery } from '@/people/queries';
4+
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
65
import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys';
76
import { AppHotkeyScope } from '@/ui/hotkey/types/AppHotkeyScope';
7+
import { IconNotes } from '@/ui/icon';
88
import { Avatar } from '@/users/components/Avatar';
9+
import {
10+
QueryMode,
11+
useSearchActivityQuery,
12+
useSearchCompanyQuery,
13+
useSearchPeopleQuery,
14+
} from '~/generated/graphql';
15+
import { getLogoUrlFromDomainName } from '~/utils';
916

1017
import { useCommandMenu } from '../hooks/useCommandMenu';
1118
import { isCommandMenuOpenedState } from '../states/isCommandMenuOpenedState';
@@ -21,6 +28,7 @@ import {
2128

2229
export function CommandMenu() {
2330
const { openCommandMenu, closeCommandMenu } = useCommandMenu();
31+
const openActivityRightDrawer = useOpenActivityRightDrawer();
2432
const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState);
2533
const [search, setSearch] = useState('');
2634

@@ -33,16 +41,41 @@ export function CommandMenu() {
3341
[openCommandMenu],
3442
);
3543

36-
const people = useFilteredSearchPeopleQuery({
37-
searchFilter: search,
38-
selectedIds: [],
39-
limit: 3,
44+
const { data: peopleData } = useSearchPeopleQuery({
45+
variables: {
46+
where: {
47+
OR: [
48+
{ firstName: { contains: search, mode: QueryMode.Insensitive } },
49+
{ lastName: { contains: search, mode: QueryMode.Insensitive } },
50+
],
51+
},
52+
limit: 3,
53+
},
54+
});
55+
const people = peopleData?.searchResults ?? [];
56+
57+
const { data: companyData } = useSearchCompanyQuery({
58+
variables: {
59+
where: {
60+
OR: [{ name: { contains: search, mode: QueryMode.Insensitive } }],
61+
},
62+
limit: 3,
63+
},
4064
});
41-
const companies = useFilteredSearchCompanyQuery({
42-
searchFilter: search,
43-
selectedIds: [],
44-
limit: 3,
65+
const companies = companyData?.searchResults ?? [];
66+
67+
const { data: activityData } = useSearchActivityQuery({
68+
variables: {
69+
where: {
70+
OR: [
71+
{ title: { contains: search, mode: QueryMode.Insensitive } },
72+
{ body: { contains: search, mode: QueryMode.Insensitive } },
73+
],
74+
},
75+
limit: 3,
76+
},
4577
});
78+
const activities = activityData?.searchResults ?? [];
4679

4780
/*
4881
TODO: Allow performing actions on page through CommandBar
@@ -99,35 +132,35 @@ export function CommandMenu() {
99132
/>
100133
<StyledList>
101134
<StyledEmpty>No results found.</StyledEmpty>
102-
{!!people.entitiesToSelect.length && (
135+
{!!people.length && (
103136
<StyledGroup heading="People">
104-
{people.entitiesToSelect.map((person) => (
137+
{people.map((person) => (
105138
<CommandMenuItem
106139
to={`person/${person.id}`}
107-
label={person.name}
140+
label={person.displayName}
108141
key={person.id}
109142
icon={
110143
<Avatar
111-
avatarUrl={person.avatarUrl}
144+
avatarUrl={null}
112145
size="sm"
113146
colorId={person.id}
114-
placeholder={person.name}
147+
placeholder={person.displayName}
115148
/>
116149
}
117150
/>
118151
))}
119152
</StyledGroup>
120153
)}
121-
{!!companies.entitiesToSelect.length && (
154+
{!!companies.length && (
122155
<StyledGroup heading="Companies">
123-
{companies.entitiesToSelect.map((company) => (
156+
{companies.map((company) => (
124157
<CommandMenuItem
125158
to={`companies/${company.id}`}
126159
label={company.name}
127160
key={company.id}
128161
icon={
129162
<Avatar
130-
avatarUrl={company.avatarUrl}
163+
avatarUrl={getLogoUrlFromDomainName(company.domainName)}
131164
size="sm"
132165
colorId={company.id}
133166
placeholder={company.name}
@@ -137,6 +170,18 @@ export function CommandMenu() {
137170
))}
138171
</StyledGroup>
139172
)}
173+
{!!activities.length && (
174+
<StyledGroup heading="Notes">
175+
{activities.map((activity) => (
176+
<CommandMenuItem
177+
onClick={() => openActivityRightDrawer(activity.id)}
178+
label={activity.title ?? ''}
179+
key={activity.id}
180+
icon={<IconNotes />}
181+
/>
182+
))}
183+
</StyledGroup>
184+
)}
140185
<StyledGroup heading="Navigate">
141186
<CommandMenuItem
142187
to="/people"

front/src/modules/search/queries/search.ts

+20
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ export const SEARCH_PEOPLE_QUERY = gql`
1717
city
1818
firstName
1919
lastName
20+
displayName
21+
avatarUrl
2022
createdAt
2123
}
2224
}
@@ -68,3 +70,21 @@ export const SEARCH_COMPANY_QUERY = gql`
6870
}
6971
}
7072
`;
73+
74+
export const SEARCH_ACTIVITY_QUERY = gql`
75+
query SearchActivity(
76+
$where: ActivityWhereInput
77+
$limit: Int
78+
$orderBy: [ActivityOrderByWithRelationInput!]
79+
) {
80+
searchResults: findManyActivities(
81+
where: $where
82+
take: $limit
83+
orderBy: $orderBy
84+
) {
85+
id
86+
title
87+
body
88+
}
89+
}
90+
`;

0 commit comments

Comments
 (0)