mirror of
https://github.com/twentyhq/twenty.git
synced 2025-01-05 10:54:15 +03:00
Add search to cmd bar (#667)
* Move useFilteredSearchEntityQuery from relation picker to search module * refactor duplicated code with useFilteredSearchCompanyQuery * Implement similar pattern for people than for companies with useFilteredSearchEntityQuery * Fix warning from a previous PR * Enable search from menu * Add companies to search * Fix ESLint * Refactor * Fix according to peer review --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
parent
b982788100
commit
7959308e0b
@ -1,6 +1,7 @@
|
|||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
|
|
||||||
|
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||||
import { SettingsNavbar } from '@/settings/components/SettingsNavbar';
|
import { SettingsNavbar } from '@/settings/components/SettingsNavbar';
|
||||||
import {
|
import {
|
||||||
IconBuildingSkyscraper,
|
IconBuildingSkyscraper,
|
||||||
@ -19,6 +20,7 @@ import NavTitle from './modules/ui/layout/navbar/NavTitle';
|
|||||||
export function AppNavbar() {
|
export function AppNavbar() {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const currentPath = useLocation().pathname;
|
const currentPath = useLocation().pathname;
|
||||||
|
const { openCommandMenu } = useCommandMenu();
|
||||||
|
|
||||||
const isSubNavbarDisplayed = useIsSubNavbarDisplayed();
|
const isSubNavbarDisplayed = useIsSubNavbarDisplayed();
|
||||||
|
|
||||||
@ -29,9 +31,10 @@ export function AppNavbar() {
|
|||||||
<>
|
<>
|
||||||
<NavItem
|
<NavItem
|
||||||
label="Search"
|
label="Search"
|
||||||
to="/search"
|
|
||||||
icon={<IconSearch size={theme.icon.size.md} />}
|
icon={<IconSearch size={theme.icon.size.md} />}
|
||||||
soon={true}
|
onClick={() => {
|
||||||
|
openCommandMenu();
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<NavItem
|
<NavItem
|
||||||
label="Inbox"
|
label="Inbox"
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useState } from 'react';
|
||||||
|
import { useTheme } from '@emotion/react';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { usePreviousHotkeyScope } from '@/lib/hotkeys/hooks/usePreviousHotkeyScope';
|
import { useFilteredSearchCompanyQuery } from '@/companies/services';
|
||||||
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { AppHotkeyScope } from '@/lib/hotkeys/types/AppHotkeyScope';
|
import { AppHotkeyScope } from '@/lib/hotkeys/types/AppHotkeyScope';
|
||||||
|
import { useFilteredSearchPeopleQuery } from '@/people/services';
|
||||||
|
import { Avatar } from '@/users/components/Avatar';
|
||||||
|
|
||||||
import { isCommandMenuOpenedState } from '../states/isCommandMenuOpened';
|
import { useCommandMenu } from '../hooks/useCommandMenu';
|
||||||
|
import { isCommandMenuOpenedState } from '../states/isCommandMenuOpenedState';
|
||||||
|
|
||||||
import { CommandMenuItem } from './CommandMenuItem';
|
import { CommandMenuItem } from './CommandMenuItem';
|
||||||
import {
|
import {
|
||||||
@ -16,31 +21,29 @@ import {
|
|||||||
} from './CommandMenuStyles';
|
} from './CommandMenuStyles';
|
||||||
|
|
||||||
export function CommandMenu() {
|
export function CommandMenu() {
|
||||||
const [open, setOpen] = useRecoilState(isCommandMenuOpenedState);
|
const { openCommandMenu, closeCommandMenu } = useCommandMenu();
|
||||||
|
const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState);
|
||||||
|
const [search, setSearch] = useState('');
|
||||||
|
|
||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
'ctrl+k,meta+k',
|
'ctrl+k,meta+k',
|
||||||
() => {
|
() => {
|
||||||
handleOpenChange(!open);
|
openCommandMenu();
|
||||||
},
|
},
|
||||||
AppHotkeyScope.CommandMenu,
|
AppHotkeyScope.CommandMenu,
|
||||||
[setOpen, open, handleOpenChange],
|
[openCommandMenu],
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const people = useFilteredSearchPeopleQuery({
|
||||||
setHotkeyScopeAndMemorizePreviousScope,
|
searchFilter: search,
|
||||||
goBackToPreviousHotkeyScope,
|
selectedIds: [],
|
||||||
} = usePreviousHotkeyScope();
|
limit: 3,
|
||||||
|
});
|
||||||
function handleOpenChange(newOpenState: boolean) {
|
const companies = useFilteredSearchCompanyQuery({
|
||||||
if (newOpenState) {
|
searchFilter: search,
|
||||||
setOpen(true);
|
selectedIds: [],
|
||||||
setHotkeyScopeAndMemorizePreviousScope(AppHotkeyScope.CommandMenu);
|
limit: 3,
|
||||||
} else {
|
});
|
||||||
setOpen(false);
|
|
||||||
goBackToPreviousHotkeyScope();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: Allow performing actions on page through CommandBar
|
TODO: Allow performing actions on page through CommandBar
|
||||||
@ -79,15 +82,64 @@ export function CommandMenu() {
|
|||||||
</StyledGroup>
|
</StyledGroup>
|
||||||
);*/
|
);*/
|
||||||
|
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledDialog
|
<StyledDialog
|
||||||
open={open}
|
open={isCommandMenuOpened}
|
||||||
onOpenChange={handleOpenChange}
|
onOpenChange={(opened) => {
|
||||||
|
if (!opened) {
|
||||||
|
closeCommandMenu();
|
||||||
|
}
|
||||||
|
}}
|
||||||
label="Global Command Menu"
|
label="Global Command Menu"
|
||||||
|
shouldFilter={false}
|
||||||
>
|
>
|
||||||
<StyledInput placeholder="Search" />
|
<StyledInput
|
||||||
|
placeholder="Search"
|
||||||
|
value={search}
|
||||||
|
onValueChange={setSearch}
|
||||||
|
/>
|
||||||
<StyledList>
|
<StyledList>
|
||||||
<StyledEmpty>No results found.</StyledEmpty>
|
<StyledEmpty>No results found.</StyledEmpty>
|
||||||
|
{!!people.entitiesToSelect.length && (
|
||||||
|
<StyledGroup heading="People">
|
||||||
|
{people.entitiesToSelect.map((person) => (
|
||||||
|
<CommandMenuItem
|
||||||
|
to={`person/${person.id}`}
|
||||||
|
label={person.name}
|
||||||
|
key={person.id}
|
||||||
|
icon={
|
||||||
|
<Avatar
|
||||||
|
avatarUrl={person.avatarUrl}
|
||||||
|
size={theme.icon.size.sm}
|
||||||
|
colorId={person.id}
|
||||||
|
placeholder={person.name}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</StyledGroup>
|
||||||
|
)}
|
||||||
|
{!!companies.entitiesToSelect.length && (
|
||||||
|
<StyledGroup heading="Companies">
|
||||||
|
{companies.entitiesToSelect.map((company) => (
|
||||||
|
<CommandMenuItem
|
||||||
|
to={`companies/${company.id}`}
|
||||||
|
label={company.name}
|
||||||
|
key={company.id}
|
||||||
|
icon={
|
||||||
|
<Avatar
|
||||||
|
avatarUrl={company.avatarUrl}
|
||||||
|
size={theme.icon.size.sm}
|
||||||
|
colorId={company.id}
|
||||||
|
placeholder={company.name}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</StyledGroup>
|
||||||
|
)}
|
||||||
<StyledGroup heading="Navigate">
|
<StyledGroup heading="Navigate">
|
||||||
<CommandMenuItem
|
<CommandMenuItem
|
||||||
to="/people"
|
to="/people"
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { useSetRecoilState } from 'recoil';
|
|
||||||
|
|
||||||
import { IconArrowUpRight } from '@/ui/icons';
|
import { IconArrowUpRight } from '@/ui/icons';
|
||||||
|
|
||||||
import { isCommandMenuOpenedState } from '../states/isCommandMenuOpened';
|
import { useCommandMenu } from '../hooks/useCommandMenu';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
StyledIconAndLabelContainer,
|
StyledIconAndLabelContainer,
|
||||||
@ -30,15 +29,15 @@ export function CommandMenuItem({
|
|||||||
icon,
|
icon,
|
||||||
shortcuts,
|
shortcuts,
|
||||||
}: OwnProps) {
|
}: OwnProps) {
|
||||||
const setOpen = useSetRecoilState(isCommandMenuOpenedState);
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const { closeCommandMenu } = useCommandMenu();
|
||||||
|
|
||||||
if (to) {
|
if (to && !icon) {
|
||||||
icon = <IconArrowUpRight />;
|
icon = <IconArrowUpRight />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const onItemClick = () => {
|
const onItemClick = () => {
|
||||||
setOpen(false);
|
closeCommandMenu();
|
||||||
|
|
||||||
if (onClick) {
|
if (onClick) {
|
||||||
onClick();
|
onClick();
|
||||||
|
@ -12,8 +12,8 @@ export const StyledDialog = styled(Command.Dialog)`
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
padding: ${({ theme }) => theme.spacing(1)};
|
padding: ${({ theme }) => theme.spacing(1)};
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 50%;
|
top: 30%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translateX(-50%);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
`;
|
`;
|
||||||
|
31
front/src/modules/command-menu/hooks/useCommandMenu.ts
Normal file
31
front/src/modules/command-menu/hooks/useCommandMenu.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { usePreviousHotkeyScope } from '@/lib/hotkeys/hooks/usePreviousHotkeyScope';
|
||||||
|
import { AppHotkeyScope } from '@/lib/hotkeys/types/AppHotkeyScope';
|
||||||
|
|
||||||
|
import { isCommandMenuOpenedState } from '../states/isCommandMenuOpenedState';
|
||||||
|
|
||||||
|
export function useCommandMenu() {
|
||||||
|
const [, setIsCommandMenuOpenedState] = useRecoilState(
|
||||||
|
isCommandMenuOpenedState,
|
||||||
|
);
|
||||||
|
const {
|
||||||
|
setHotkeyScopeAndMemorizePreviousScope,
|
||||||
|
goBackToPreviousHotkeyScope,
|
||||||
|
} = usePreviousHotkeyScope();
|
||||||
|
|
||||||
|
function openCommandMenu() {
|
||||||
|
setIsCommandMenuOpenedState(true);
|
||||||
|
setHotkeyScopeAndMemorizePreviousScope(AppHotkeyScope.CommandMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeCommandMenu() {
|
||||||
|
setIsCommandMenuOpenedState(false);
|
||||||
|
goBackToPreviousHotkeyScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
openCommandMenu,
|
||||||
|
closeCommandMenu,
|
||||||
|
};
|
||||||
|
}
|
@ -9,24 +9,21 @@ import {
|
|||||||
} from '@floating-ui/react';
|
} from '@floating-ui/react';
|
||||||
|
|
||||||
import { useHandleCheckableCommentThreadTargetChange } from '@/comments/hooks/useHandleCheckableCommentThreadTargetChange';
|
import { useHandleCheckableCommentThreadTargetChange } from '@/comments/hooks/useHandleCheckableCommentThreadTargetChange';
|
||||||
import { CommentableEntityForSelect } from '@/comments/types/CommentableEntityForSelect';
|
|
||||||
import { CompanyChip } from '@/companies/components/CompanyChip';
|
import { CompanyChip } from '@/companies/components/CompanyChip';
|
||||||
|
import { useFilteredSearchCompanyQuery } from '@/companies/services';
|
||||||
import { usePreviousHotkeyScope } from '@/lib/hotkeys/hooks/usePreviousHotkeyScope';
|
import { usePreviousHotkeyScope } from '@/lib/hotkeys/hooks/usePreviousHotkeyScope';
|
||||||
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { PersonChip } from '@/people/components/PersonChip';
|
import { PersonChip } from '@/people/components/PersonChip';
|
||||||
|
import { useFilteredSearchPeopleQuery } from '@/people/services';
|
||||||
import { RecoilScope } from '@/recoil-scope/components/RecoilScope';
|
import { RecoilScope } from '@/recoil-scope/components/RecoilScope';
|
||||||
import { MultipleEntitySelect } from '@/relation-picker/components/MultipleEntitySelect';
|
import { MultipleEntitySelect } from '@/relation-picker/components/MultipleEntitySelect';
|
||||||
import { useFilteredSearchEntityQuery } from '@/relation-picker/hooks/useFilteredSearchEntityQuery';
|
|
||||||
import { RelationPickerHotkeyScope } from '@/relation-picker/types/RelationPickerHotkeyScope';
|
import { RelationPickerHotkeyScope } from '@/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef';
|
import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef';
|
||||||
import { flatMapAndSortEntityForSelectArrayOfArrayByName } from '@/ui/utils/flatMapAndSortEntityForSelectArrayByName';
|
import { flatMapAndSortEntityForSelectArrayOfArrayByName } from '@/ui/utils/flatMapAndSortEntityForSelectArrayByName';
|
||||||
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
|
||||||
import {
|
import {
|
||||||
CommentableType,
|
CommentableType,
|
||||||
CommentThread,
|
CommentThread,
|
||||||
CommentThreadTarget,
|
CommentThreadTarget,
|
||||||
useSearchCompanyQuery,
|
|
||||||
useSearchPeopleQuery,
|
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
@ -90,35 +87,14 @@ export function CommentThreadRelationPicker({ commentThread }: OwnProps) {
|
|||||||
?.filter((relation) => relation.commentableType === 'Company')
|
?.filter((relation) => relation.commentableType === 'Company')
|
||||||
.map((relation) => relation.commentableId) ?? [];
|
.map((relation) => relation.commentableId) ?? [];
|
||||||
|
|
||||||
const personsForMultiSelect = useFilteredSearchEntityQuery({
|
const personsForMultiSelect = useFilteredSearchPeopleQuery({
|
||||||
queryHook: useSearchPeopleQuery,
|
|
||||||
searchOnFields: ['firstName', 'lastName'],
|
|
||||||
orderByField: 'lastName',
|
|
||||||
selectedIds: peopleIds,
|
|
||||||
mappingFunction: (entity) =>
|
|
||||||
({
|
|
||||||
id: entity.id,
|
|
||||||
entityType: CommentableType.Person,
|
|
||||||
name: `${entity.firstName} ${entity.lastName}`,
|
|
||||||
avatarType: 'rounded',
|
|
||||||
} as CommentableEntityForSelect),
|
|
||||||
searchFilter,
|
searchFilter,
|
||||||
|
selectedIds: peopleIds,
|
||||||
});
|
});
|
||||||
|
|
||||||
const companiesForMultiSelect = useFilteredSearchEntityQuery({
|
const companiesForMultiSelect = useFilteredSearchCompanyQuery({
|
||||||
queryHook: useSearchCompanyQuery,
|
|
||||||
searchOnFields: ['name'],
|
|
||||||
orderByField: 'name',
|
|
||||||
selectedIds: companyIds,
|
|
||||||
mappingFunction: (company) =>
|
|
||||||
({
|
|
||||||
id: company.id,
|
|
||||||
entityType: CommentableType.Company,
|
|
||||||
name: company.name,
|
|
||||||
avatarUrl: getLogoUrlFromDomainName(company.domainName),
|
|
||||||
avatarType: 'squared',
|
|
||||||
} as CommentableEntityForSelect),
|
|
||||||
searchFilter,
|
searchFilter,
|
||||||
|
selectedIds: companyIds,
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { SingleEntitySelect } from '@/relation-picker/components/SingleEntitySelect';
|
import { SingleEntitySelect } from '@/relation-picker/components/SingleEntitySelect';
|
||||||
import { useFilteredSearchEntityQuery } from '@/relation-picker/hooks/useFilteredSearchEntityQuery';
|
|
||||||
import { relationPickerSearchFilterScopedState } from '@/relation-picker/states/relationPickerSearchFilterScopedState';
|
import { relationPickerSearchFilterScopedState } from '@/relation-picker/states/relationPickerSearchFilterScopedState';
|
||||||
import { EntityForSelect } from '@/relation-picker/types/EntityForSelect';
|
import { EntityForSelect } from '@/relation-picker/types/EntityForSelect';
|
||||||
import { Entity } from '@/relation-picker/types/EntityTypeForSelect';
|
import { Entity } from '@/relation-picker/types/EntityTypeForSelect';
|
||||||
|
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
||||||
import { useEditableCell } from '@/ui/components/editable-cell/hooks/useEditableCell';
|
import { useEditableCell } from '@/ui/components/editable-cell/hooks/useEditableCell';
|
||||||
import {
|
import {
|
||||||
Company,
|
Company,
|
||||||
|
@ -3,11 +3,9 @@ import { filterDropdownSearchInputScopedState } from '@/lib/filters-and-sorts/st
|
|||||||
import { filterDropdownSelectedEntityIdScopedState } from '@/lib/filters-and-sorts/states/filterDropdownSelectedEntityIdScopedState';
|
import { filterDropdownSelectedEntityIdScopedState } from '@/lib/filters-and-sorts/states/filterDropdownSelectedEntityIdScopedState';
|
||||||
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { useRecoilScopedValue } from '@/recoil-scope/hooks/useRecoilScopedValue';
|
import { useRecoilScopedValue } from '@/recoil-scope/hooks/useRecoilScopedValue';
|
||||||
import { useFilteredSearchEntityQuery } from '@/relation-picker/hooks/useFilteredSearchEntityQuery';
|
|
||||||
import { Entity } from '@/relation-picker/types/EntityTypeForSelect';
|
|
||||||
import { TableContext } from '@/ui/tables/states/TableContext';
|
import { TableContext } from '@/ui/tables/states/TableContext';
|
||||||
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
|
||||||
import { useSearchCompanyQuery } from '~/generated/graphql';
|
import { useFilteredSearchCompanyQuery } from '../services';
|
||||||
|
|
||||||
export function FilterDropdownCompanySearchSelect() {
|
export function FilterDropdownCompanySearchSelect() {
|
||||||
const filterDropdownSearchInput = useRecoilScopedValue(
|
const filterDropdownSearchInput = useRecoilScopedValue(
|
||||||
@ -20,21 +18,11 @@ export function FilterDropdownCompanySearchSelect() {
|
|||||||
TableContext,
|
TableContext,
|
||||||
);
|
);
|
||||||
|
|
||||||
const usersForSelect = useFilteredSearchEntityQuery({
|
const usersForSelect = useFilteredSearchCompanyQuery({
|
||||||
queryHook: useSearchCompanyQuery,
|
searchFilter: filterDropdownSearchInput,
|
||||||
searchOnFields: ['name'],
|
|
||||||
orderByField: 'name',
|
|
||||||
selectedIds: filterDropdownSelectedEntityId
|
selectedIds: filterDropdownSelectedEntityId
|
||||||
? [filterDropdownSelectedEntityId]
|
? [filterDropdownSelectedEntityId]
|
||||||
: [],
|
: [],
|
||||||
mappingFunction: (company) => ({
|
|
||||||
id: company.id,
|
|
||||||
entityType: Entity.User,
|
|
||||||
name: `${company.name}`,
|
|
||||||
avatarType: 'squared',
|
|
||||||
avatarUrl: getLogoUrlFromDomainName(company.domainName),
|
|
||||||
}),
|
|
||||||
searchFilter: filterDropdownSearchInput,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -2,31 +2,16 @@ import { useCallback } from 'react';
|
|||||||
|
|
||||||
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { SingleEntitySelect } from '@/relation-picker/components/SingleEntitySelect';
|
import { SingleEntitySelect } from '@/relation-picker/components/SingleEntitySelect';
|
||||||
import { useFilteredSearchEntityQuery } from '@/relation-picker/hooks/useFilteredSearchEntityQuery';
|
|
||||||
import { relationPickerSearchFilterScopedState } from '@/relation-picker/states/relationPickerSearchFilterScopedState';
|
import { relationPickerSearchFilterScopedState } from '@/relation-picker/states/relationPickerSearchFilterScopedState';
|
||||||
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
|
||||||
import { CommentableType, useSearchCompanyQuery } from '~/generated/graphql';
|
import { useFilteredSearchCompanyQuery } from '../services';
|
||||||
|
|
||||||
export function NewCompanyBoardCard() {
|
export function NewCompanyBoardCard() {
|
||||||
const [searchFilter] = useRecoilScopedState(
|
const [searchFilter] = useRecoilScopedState(
|
||||||
relationPickerSearchFilterScopedState,
|
relationPickerSearchFilterScopedState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const companies = useFilteredSearchEntityQuery({
|
const companies = useFilteredSearchCompanyQuery({ searchFilter });
|
||||||
queryHook: useSearchCompanyQuery,
|
|
||||||
selectedIds: [],
|
|
||||||
searchFilter: searchFilter,
|
|
||||||
mappingFunction: (company) => ({
|
|
||||||
entityType: CommentableType.Company,
|
|
||||||
id: company.id,
|
|
||||||
name: company.name,
|
|
||||||
domainName: company.domainName,
|
|
||||||
avatarType: 'squared',
|
|
||||||
avatarUrl: getLogoUrlFromDomainName(company.domainName),
|
|
||||||
}),
|
|
||||||
orderByField: 'name',
|
|
||||||
searchOnFields: ['name'],
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleEntitySelect = useCallback(async (companyId: string) => {
|
const handleEntitySelect = useCallback(async (companyId: string) => {
|
||||||
return;
|
return;
|
||||||
|
@ -11,20 +11,18 @@ import { pipelineStageIdScopedState } from '@/pipeline-progress/states/pipelineS
|
|||||||
import { RecoilScope } from '@/recoil-scope/components/RecoilScope';
|
import { RecoilScope } from '@/recoil-scope/components/RecoilScope';
|
||||||
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { SingleEntitySelect } from '@/relation-picker/components/SingleEntitySelect';
|
import { SingleEntitySelect } from '@/relation-picker/components/SingleEntitySelect';
|
||||||
import { useFilteredSearchEntityQuery } from '@/relation-picker/hooks/useFilteredSearchEntityQuery';
|
|
||||||
import { relationPickerSearchFilterScopedState } from '@/relation-picker/states/relationPickerSearchFilterScopedState';
|
import { relationPickerSearchFilterScopedState } from '@/relation-picker/states/relationPickerSearchFilterScopedState';
|
||||||
import { RelationPickerHotkeyScope } from '@/relation-picker/types/RelationPickerHotkeyScope';
|
import { RelationPickerHotkeyScope } from '@/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { BoardPipelineStageColumn } from '@/ui/board/components/Board';
|
import { BoardPipelineStageColumn } from '@/ui/board/components/Board';
|
||||||
import { NewButton } from '@/ui/board/components/NewButton';
|
import { NewButton } from '@/ui/board/components/NewButton';
|
||||||
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
|
||||||
import {
|
import {
|
||||||
CommentableType,
|
|
||||||
PipelineProgressableType,
|
PipelineProgressableType,
|
||||||
useCreateOnePipelineProgressMutation,
|
useCreateOnePipelineProgressMutation,
|
||||||
useSearchCompanyQuery,
|
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
import { currentPipelineState } from '~/pages/opportunities/currentPipelineState';
|
import { currentPipelineState } from '~/pages/opportunities/currentPipelineState';
|
||||||
|
|
||||||
|
import { useFilteredSearchCompanyQuery } from '../services';
|
||||||
|
|
||||||
export function NewCompanyProgressButton() {
|
export function NewCompanyProgressButton() {
|
||||||
const [isCreatingCard, setIsCreatingCard] = useState(false);
|
const [isCreatingCard, setIsCreatingCard] = useState(false);
|
||||||
const [board, setBoard] = useRecoilState(boardState);
|
const [board, setBoard] = useRecoilState(boardState);
|
||||||
@ -93,21 +91,7 @@ export function NewCompanyProgressButton() {
|
|||||||
const [searchFilter] = useRecoilScopedState(
|
const [searchFilter] = useRecoilScopedState(
|
||||||
relationPickerSearchFilterScopedState,
|
relationPickerSearchFilterScopedState,
|
||||||
);
|
);
|
||||||
const companies = useFilteredSearchEntityQuery({
|
const companies = useFilteredSearchCompanyQuery({ searchFilter });
|
||||||
queryHook: useSearchCompanyQuery,
|
|
||||||
selectedIds: [],
|
|
||||||
searchFilter: searchFilter,
|
|
||||||
mappingFunction: (company) => ({
|
|
||||||
entityType: CommentableType.Company,
|
|
||||||
id: company.id,
|
|
||||||
name: company.name,
|
|
||||||
domainName: company.domainName,
|
|
||||||
avatarType: 'squared',
|
|
||||||
avatarUrl: getLogoUrlFromDomainName(company.domainName),
|
|
||||||
}),
|
|
||||||
orderByField: 'name',
|
|
||||||
searchOnFields: ['name'],
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
import { CommentableEntityForSelect } from '@/comments/types/CommentableEntityForSelect';
|
||||||
import { SelectedSortType } from '@/lib/filters-and-sorts/interfaces/sorts/interface';
|
import { SelectedSortType } from '@/lib/filters-and-sorts/interfaces/sorts/interface';
|
||||||
|
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
||||||
|
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
||||||
import {
|
import {
|
||||||
|
CommentableType,
|
||||||
CompanyOrderByWithRelationInput as Companies_Order_By,
|
CompanyOrderByWithRelationInput as Companies_Order_By,
|
||||||
CompanyWhereInput as Companies_Bool_Exp,
|
CompanyWhereInput as Companies_Bool_Exp,
|
||||||
SortOrder as Order_By,
|
SortOrder as Order_By,
|
||||||
useGetCompaniesQuery,
|
useGetCompaniesQuery,
|
||||||
|
useSearchCompanyQuery,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
export type CompaniesSelectedSortType = SelectedSortType<Companies_Order_By>;
|
export type CompaniesSelectedSortType = SelectedSortType<Companies_Order_By>;
|
||||||
@ -41,6 +46,33 @@ export function useCompaniesQuery(
|
|||||||
return useGetCompaniesQuery({ variables: { orderBy, where } });
|
return useGetCompaniesQuery({ variables: { orderBy, where } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useFilteredSearchCompanyQuery({
|
||||||
|
searchFilter,
|
||||||
|
selectedIds = [],
|
||||||
|
limit,
|
||||||
|
}: {
|
||||||
|
searchFilter: string;
|
||||||
|
selectedIds?: string[];
|
||||||
|
limit?: number;
|
||||||
|
}) {
|
||||||
|
return useFilteredSearchEntityQuery({
|
||||||
|
queryHook: useSearchCompanyQuery,
|
||||||
|
searchOnFields: ['name'],
|
||||||
|
orderByField: 'name',
|
||||||
|
selectedIds: selectedIds,
|
||||||
|
mappingFunction: (company) =>
|
||||||
|
({
|
||||||
|
id: company.id,
|
||||||
|
entityType: CommentableType.Company,
|
||||||
|
name: company.name,
|
||||||
|
avatarUrl: getLogoUrlFromDomainName(company.domainName),
|
||||||
|
avatarType: 'squared',
|
||||||
|
} as CommentableEntityForSelect),
|
||||||
|
searchFilter,
|
||||||
|
limit,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export const defaultOrderBy: Companies_Order_By[] = [
|
export const defaultOrderBy: Companies_Order_By[] = [
|
||||||
{
|
{
|
||||||
createdAt: Order_By.Desc,
|
createdAt: Order_By.Desc,
|
||||||
|
@ -1,23 +1,16 @@
|
|||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
|
import { useFilteredSearchCompanyQuery } from '@/companies/services';
|
||||||
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { useSetHotkeyScope } from '@/lib/hotkeys/hooks/useSetHotkeyScope';
|
import { useSetHotkeyScope } from '@/lib/hotkeys/hooks/useSetHotkeyScope';
|
||||||
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { SingleEntitySelect } from '@/relation-picker/components/SingleEntitySelect';
|
import { SingleEntitySelect } from '@/relation-picker/components/SingleEntitySelect';
|
||||||
import { useFilteredSearchEntityQuery } from '@/relation-picker/hooks/useFilteredSearchEntityQuery';
|
|
||||||
import { relationPickerSearchFilterScopedState } from '@/relation-picker/states/relationPickerSearchFilterScopedState';
|
import { relationPickerSearchFilterScopedState } from '@/relation-picker/states/relationPickerSearchFilterScopedState';
|
||||||
import { RelationPickerHotkeyScope } from '@/relation-picker/types/RelationPickerHotkeyScope';
|
import { RelationPickerHotkeyScope } from '@/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { useEditableCell } from '@/ui/components/editable-cell/hooks/useEditableCell';
|
import { useEditableCell } from '@/ui/components/editable-cell/hooks/useEditableCell';
|
||||||
import { isCreateModeScopedState } from '@/ui/components/editable-cell/states/isCreateModeScopedState';
|
import { isCreateModeScopedState } from '@/ui/components/editable-cell/states/isCreateModeScopedState';
|
||||||
import { TableHotkeyScope } from '@/ui/tables/types/TableHotkeyScope';
|
import { TableHotkeyScope } from '@/ui/tables/types/TableHotkeyScope';
|
||||||
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
import { Company, Person, useUpdatePeopleMutation } from '~/generated/graphql';
|
||||||
import {
|
|
||||||
CommentableType,
|
|
||||||
Company,
|
|
||||||
Person,
|
|
||||||
useSearchCompanyQuery,
|
|
||||||
useUpdatePeopleMutation,
|
|
||||||
} from '~/generated/graphql';
|
|
||||||
|
|
||||||
export type OwnProps = {
|
export type OwnProps = {
|
||||||
people: Pick<Person, 'id'> & { company?: Pick<Company, 'id'> | null };
|
people: Pick<Person, 'id'> & { company?: Pick<Company, 'id'> | null };
|
||||||
@ -35,19 +28,9 @@ export function PeopleCompanyPicker({ people }: OwnProps) {
|
|||||||
|
|
||||||
const addToScopeStack = useSetHotkeyScope();
|
const addToScopeStack = useSetHotkeyScope();
|
||||||
|
|
||||||
const companies = useFilteredSearchEntityQuery({
|
const companies = useFilteredSearchCompanyQuery({
|
||||||
queryHook: useSearchCompanyQuery,
|
searchFilter,
|
||||||
selectedIds: [people.company?.id ?? ''],
|
selectedIds: people.company?.id ? [people.company.id] : [],
|
||||||
searchFilter: searchFilter,
|
|
||||||
mappingFunction: (company) => ({
|
|
||||||
entityType: CommentableType.Company,
|
|
||||||
id: company.id,
|
|
||||||
name: company.name,
|
|
||||||
avatarType: 'squared',
|
|
||||||
avatarUrl: getLogoUrlFromDomainName(company.domainName),
|
|
||||||
}),
|
|
||||||
orderByField: 'name',
|
|
||||||
searchOnFields: ['name'],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async function handleEntitySelected(entity: any) {
|
async function handleEntitySelected(entity: any) {
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
import { CommentableEntityForSelect } from '@/comments/types/CommentableEntityForSelect';
|
||||||
import { SelectedSortType } from '@/lib/filters-and-sorts/interfaces/sorts/interface';
|
import { SelectedSortType } from '@/lib/filters-and-sorts/interfaces/sorts/interface';
|
||||||
|
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
||||||
import {
|
import {
|
||||||
|
CommentableType,
|
||||||
PersonOrderByWithRelationInput as People_Order_By,
|
PersonOrderByWithRelationInput as People_Order_By,
|
||||||
PersonWhereInput as People_Bool_Exp,
|
PersonWhereInput as People_Bool_Exp,
|
||||||
SortOrder,
|
SortOrder,
|
||||||
useGetPeopleQuery,
|
useGetPeopleQuery,
|
||||||
|
useSearchPeopleQuery,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
export type PeopleSelectedSortType = SelectedSortType<People_Order_By>;
|
export type PeopleSelectedSortType = SelectedSortType<People_Order_By>;
|
||||||
@ -43,6 +47,32 @@ export function usePeopleQuery(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useFilteredSearchPeopleQuery({
|
||||||
|
searchFilter,
|
||||||
|
selectedIds = [],
|
||||||
|
limit,
|
||||||
|
}: {
|
||||||
|
searchFilter: string;
|
||||||
|
selectedIds?: string[];
|
||||||
|
limit?: number;
|
||||||
|
}) {
|
||||||
|
return useFilteredSearchEntityQuery({
|
||||||
|
queryHook: useSearchPeopleQuery,
|
||||||
|
searchOnFields: ['firstName', 'lastName'],
|
||||||
|
orderByField: 'lastName',
|
||||||
|
selectedIds: selectedIds,
|
||||||
|
mappingFunction: (entity) =>
|
||||||
|
({
|
||||||
|
id: entity.id,
|
||||||
|
entityType: CommentableType.Person,
|
||||||
|
name: `${entity.firstName} ${entity.lastName}`,
|
||||||
|
avatarType: 'rounded',
|
||||||
|
} as CommentableEntityForSelect),
|
||||||
|
searchFilter,
|
||||||
|
limit,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export const defaultOrderBy: People_Order_By[] = [
|
export const defaultOrderBy: People_Order_By[] = [
|
||||||
{
|
{
|
||||||
createdAt: SortOrder.Desc,
|
createdAt: SortOrder.Desc,
|
||||||
|
@ -3,8 +3,8 @@ import { filterDropdownSearchInputScopedState } from '@/lib/filters-and-sorts/st
|
|||||||
import { filterDropdownSelectedEntityIdScopedState } from '@/lib/filters-and-sorts/states/filterDropdownSelectedEntityIdScopedState';
|
import { filterDropdownSelectedEntityIdScopedState } from '@/lib/filters-and-sorts/states/filterDropdownSelectedEntityIdScopedState';
|
||||||
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { useRecoilScopedValue } from '@/recoil-scope/hooks/useRecoilScopedValue';
|
import { useRecoilScopedValue } from '@/recoil-scope/hooks/useRecoilScopedValue';
|
||||||
import { useFilteredSearchEntityQuery } from '@/relation-picker/hooks/useFilteredSearchEntityQuery';
|
|
||||||
import { Entity } from '@/relation-picker/types/EntityTypeForSelect';
|
import { Entity } from '@/relation-picker/types/EntityTypeForSelect';
|
||||||
|
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
||||||
import { TableContext } from '@/ui/tables/states/TableContext';
|
import { TableContext } from '@/ui/tables/states/TableContext';
|
||||||
import { useSearchUserQuery } from '~/generated/graphql';
|
import { useSearchUserQuery } from '~/generated/graphql';
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user