feat: search activities (#972)

This commit is contained in:
Jérémy M 2023-07-28 19:02:56 +02:00 committed by GitHub
parent 2304823dc6
commit 3daebd0e0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 142 additions and 24 deletions

View File

@ -2522,7 +2522,7 @@ export type SearchPeopleQueryVariables = Exact<{
}>;
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 }> };
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 }> };
export type SearchUserQueryVariables = Exact<{
where?: InputMaybe<UserWhereInput>;
@ -2547,6 +2547,15 @@ export type SearchCompanyQueryVariables = Exact<{
export type SearchCompanyQuery = { __typename?: 'Query', searchResults: Array<{ __typename?: 'Company', id: string, name: string, domainName: string }> };
export type SearchActivityQueryVariables = Exact<{
where?: InputMaybe<ActivityWhereInput>;
limit?: InputMaybe<Scalars['Int']>;
orderBy?: InputMaybe<Array<ActivityOrderByWithRelationInput> | ActivityOrderByWithRelationInput>;
}>;
export type SearchActivityQuery = { __typename?: 'Query', searchResults: Array<{ __typename?: 'Activity', id: string, title?: string | null, body?: string | null }> };
export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never; }>;
@ -4367,6 +4376,7 @@ export const SearchPeopleDocument = gql`
city
firstName
lastName
displayName
createdAt
}
}
@ -4516,6 +4526,49 @@ export function useSearchCompanyLazyQuery(baseOptions?: Apollo.LazyQueryHookOpti
export type SearchCompanyQueryHookResult = ReturnType<typeof useSearchCompanyQuery>;
export type SearchCompanyLazyQueryHookResult = ReturnType<typeof useSearchCompanyLazyQuery>;
export type SearchCompanyQueryResult = Apollo.QueryResult<SearchCompanyQuery, SearchCompanyQueryVariables>;
export const SearchActivityDocument = gql`
query SearchActivity($where: ActivityWhereInput, $limit: Int, $orderBy: [ActivityOrderByWithRelationInput!]) {
searchResults: findManyActivities(
where: $where
take: $limit
orderBy: $orderBy
) {
id
title
body
}
}
`;
/**
* __useSearchActivityQuery__
*
* To run a query within a React component, call `useSearchActivityQuery` and pass it any options that fit your needs.
* When your component renders, `useSearchActivityQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @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;
*
* @example
* const { data, loading, error } = useSearchActivityQuery({
* variables: {
* where: // value for 'where'
* limit: // value for 'limit'
* orderBy: // value for 'orderBy'
* },
* });
*/
export function useSearchActivityQuery(baseOptions?: Apollo.QueryHookOptions<SearchActivityQuery, SearchActivityQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<SearchActivityQuery, SearchActivityQueryVariables>(SearchActivityDocument, options);
}
export function useSearchActivityLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<SearchActivityQuery, SearchActivityQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<SearchActivityQuery, SearchActivityQueryVariables>(SearchActivityDocument, options);
}
export type SearchActivityQueryHookResult = ReturnType<typeof useSearchActivityQuery>;
export type SearchActivityLazyQueryHookResult = ReturnType<typeof useSearchActivityLazyQuery>;
export type SearchActivityQueryResult = Apollo.QueryResult<SearchActivityQuery, SearchActivityQueryVariables>;
export const GetCurrentUserDocument = gql`
query GetCurrentUser {
currentUser {

View File

@ -107,7 +107,7 @@ export function Timeline({ entity }: { entity: CommentableEntity }) {
},
});
const openCreateCommandThread = useOpenCreateActivityDrawer();
const openCreateActivity = useOpenCreateActivityDrawer();
const activities: ActivityForDrawer[] = queryResult?.findManyActivities ?? [];
@ -121,8 +121,8 @@ export function Timeline({ entity }: { entity: CommentableEntity }) {
<StyledEmptyTimelineTitle>No activity yet</StyledEmptyTimelineTitle>
<StyledEmptyTimelineSubTitle>Create one:</StyledEmptyTimelineSubTitle>
<ActivityCreateButton
onNoteClick={() => openCreateCommandThread(entity, ActivityType.Note)}
onTaskClick={() => openCreateCommandThread(entity, ActivityType.Task)}
onNoteClick={() => openCreateActivity(entity, ActivityType.Note)}
onTaskClick={() => openCreateActivity(entity, ActivityType.Task)}
/>
</StyledTimelineEmptyContainer>
);
@ -132,8 +132,8 @@ export function Timeline({ entity }: { entity: CommentableEntity }) {
<StyledMainContainer>
<StyledTopActionBar>
<ActivityCreateButton
onNoteClick={() => openCreateCommandThread(entity, ActivityType.Note)}
onTaskClick={() => openCreateCommandThread(entity, ActivityType.Task)}
onNoteClick={() => openCreateActivity(entity, ActivityType.Note)}
onTaskClick={() => openCreateActivity(entity, ActivityType.Task)}
/>
</StyledTopActionBar>
<StyledTimelineContainer>

View File

@ -1,11 +1,18 @@
import { useState } from 'react';
import { useRecoilValue } from 'recoil';
import { useFilteredSearchCompanyQuery } from '@/companies/queries';
import { useFilteredSearchPeopleQuery } from '@/people/queries';
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys';
import { AppHotkeyScope } from '@/ui/hotkey/types/AppHotkeyScope';
import { IconNotes } from '@/ui/icon';
import { Avatar } from '@/users/components/Avatar';
import {
QueryMode,
useSearchActivityQuery,
useSearchCompanyQuery,
useSearchPeopleQuery,
} from '~/generated/graphql';
import { getLogoUrlFromDomainName } from '~/utils';
import { useCommandMenu } from '../hooks/useCommandMenu';
import { isCommandMenuOpenedState } from '../states/isCommandMenuOpenedState';
@ -21,6 +28,7 @@ import {
export function CommandMenu() {
const { openCommandMenu, closeCommandMenu } = useCommandMenu();
const openActivityRightDrawer = useOpenActivityRightDrawer();
const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState);
const [search, setSearch] = useState('');
@ -33,16 +41,41 @@ export function CommandMenu() {
[openCommandMenu],
);
const people = useFilteredSearchPeopleQuery({
searchFilter: search,
selectedIds: [],
const { data: peopleData } = useSearchPeopleQuery({
variables: {
where: {
OR: [
{ firstName: { contains: search, mode: QueryMode.Insensitive } },
{ lastName: { contains: search, mode: QueryMode.Insensitive } },
],
},
limit: 3,
},
});
const companies = useFilteredSearchCompanyQuery({
searchFilter: search,
selectedIds: [],
const people = peopleData?.searchResults ?? [];
const { data: companyData } = useSearchCompanyQuery({
variables: {
where: {
OR: [{ name: { contains: search, mode: QueryMode.Insensitive } }],
},
limit: 3,
},
});
const companies = companyData?.searchResults ?? [];
const { data: activityData } = useSearchActivityQuery({
variables: {
where: {
OR: [
{ title: { contains: search, mode: QueryMode.Insensitive } },
{ body: { contains: search, mode: QueryMode.Insensitive } },
],
},
limit: 3,
},
});
const activities = activityData?.searchResults ?? [];
/*
TODO: Allow performing actions on page through CommandBar
@ -99,35 +132,35 @@ export function CommandMenu() {
/>
<StyledList>
<StyledEmpty>No results found.</StyledEmpty>
{!!people.entitiesToSelect.length && (
{!!people.length && (
<StyledGroup heading="People">
{people.entitiesToSelect.map((person) => (
{people.map((person) => (
<CommandMenuItem
to={`person/${person.id}`}
label={person.name}
label={person.displayName}
key={person.id}
icon={
<Avatar
avatarUrl={person.avatarUrl}
avatarUrl={null}
size="sm"
colorId={person.id}
placeholder={person.name}
placeholder={person.displayName}
/>
}
/>
))}
</StyledGroup>
)}
{!!companies.entitiesToSelect.length && (
{!!companies.length && (
<StyledGroup heading="Companies">
{companies.entitiesToSelect.map((company) => (
{companies.map((company) => (
<CommandMenuItem
to={`companies/${company.id}`}
label={company.name}
key={company.id}
icon={
<Avatar
avatarUrl={company.avatarUrl}
avatarUrl={getLogoUrlFromDomainName(company.domainName)}
size="sm"
colorId={company.id}
placeholder={company.name}
@ -137,6 +170,18 @@ export function CommandMenu() {
))}
</StyledGroup>
)}
{!!activities.length && (
<StyledGroup heading="Notes">
{activities.map((activity) => (
<CommandMenuItem
onClick={() => openActivityRightDrawer(activity.id)}
label={activity.title ?? ''}
key={activity.id}
icon={<IconNotes />}
/>
))}
</StyledGroup>
)}
<StyledGroup heading="Navigate">
<CommandMenuItem
to="/people"

View File

@ -17,6 +17,8 @@ export const SEARCH_PEOPLE_QUERY = gql`
city
firstName
lastName
displayName
avatarUrl
createdAt
}
}
@ -68,3 +70,21 @@ export const SEARCH_COMPANY_QUERY = gql`
}
}
`;
export const SEARCH_ACTIVITY_QUERY = gql`
query SearchActivity(
$where: ActivityWhereInput
$limit: Int
$orderBy: [ActivityOrderByWithRelationInput!]
) {
searchResults: findManyActivities(
where: $where
take: $limit
orderBy: $orderBy
) {
id
title
body
}
}
`;