Feat/single entity select relation picker (#345)

* - Implemented recoil scoped state
- Implemented SingleEntitySelect
- Implemented keyboard shortcut up/down select

* Added useRecoilScopedValue

* Fix storybook

* Fix storybook

* Fix storybook

* Fix storybook

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Lucas Bordeau
2023-06-21 22:29:07 +02:00
committed by GitHub
parent 8a330b9746
commit e679f45615
23 changed files with 653 additions and 180 deletions

View File

@ -1,44 +1,90 @@
import { useRef, useState } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import { v4 } from 'uuid';
import { relationPickerSearchFilterScopedState } from '@/relation-picker/states/relationPickerSearchFilterScopedState';
import { isCreateModeScopedState } from '@/ui/components/editable-cell/states/isCreateModeScopedState';
import { DoubleTextInput } from '@/ui/components/inputs/DoubleTextInput';
import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef';
import { useRecoilScopedState } from '@/ui/hooks/useRecoilScopedState';
import { logError } from '@/utils/logs/logError';
import {
Person,
useInsertCompanyMutation,
useUpdatePeopleMutation,
} from '~/generated/graphql';
type OwnProps = {
initialCompanyName: string;
onCreate: (companyName: string, companyDomainName: string) => void;
people: Pick<Person, 'id'>;
};
export function PeopleCompanyCreateCell({
initialCompanyName,
onCreate,
}: OwnProps) {
const [companyName, setCompanyName] = useState(initialCompanyName);
export function PeopleCompanyCreateCell({ people }: OwnProps) {
const [, setIsCreating] = useRecoilScopedState(isCreateModeScopedState);
const [currentSearchFilter] = useRecoilScopedState(
relationPickerSearchFilterScopedState,
);
const [companyName, setCompanyName] = useState(currentSearchFilter);
const [companyDomainName, setCompanyDomainName] = useState('');
const [insertCompany] = useInsertCompanyMutation();
const [updatePeople] = useUpdatePeopleMutation();
const containerRef = useRef(null);
useListenClickOutsideArrayOfRef([containerRef], () => {
onCreate(companyName, companyDomainName);
});
function handleDoubleTextChange(leftValue: string, rightValue: string): void {
setCompanyDomainName(leftValue);
setCompanyName(rightValue);
}
async function handleCompanyCreate(
companyName: string,
companyDomainName: string,
) {
const newCompanyId = v4();
try {
await insertCompany({
variables: {
id: newCompanyId,
name: companyName,
domainName: companyDomainName,
address: '',
createdAt: new Date().toISOString(),
},
});
await updatePeople({
variables: {
...people,
companyId: newCompanyId,
},
});
} catch (error) {
// TODO: handle error better
logError(error);
}
setIsCreating(false);
}
useHotkeys(
'enter, escape',
() => {
onCreate(companyName, companyDomainName);
handleCompanyCreate(companyName, companyDomainName);
},
{
enableOnFormTags: true,
enableOnContentEditable: true,
preventDefault: true,
},
[containerRef, companyName, companyDomainName, onCreate],
[companyName, companyDomainName, handleCompanyCreate],
);
function handleDoubleTextChange(leftValue: string, rightValue: string): void {
setCompanyDomainName(leftValue);
setCompanyName(rightValue);
}
useListenClickOutsideArrayOfRef([containerRef], () => {
handleCompanyCreate(companyName, companyDomainName);
});
return (
<DoubleTextInput