Add optimistic rendering for table relations (#1296)
* Add optimistic rendering for table relations * fix pr * fix pr * fix pr * Fix PR --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -12,12 +12,16 @@ import { useInsertOneCompanyMutation } from '~/generated/graphql';
|
|||||||
|
|
||||||
export type OwnProps = {
|
export type OwnProps = {
|
||||||
companyId: string | null;
|
companyId: string | null;
|
||||||
onSubmit: (newCompany: EntityForSelect | null) => void;
|
onSubmit: (newCompany: CompanyPickerSelectedCompany | null) => void;
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
createModeEnabled?: boolean;
|
createModeEnabled?: boolean;
|
||||||
width?: number;
|
width?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type CompanyPickerSelectedCompany = EntityForSelect & {
|
||||||
|
domainName: string;
|
||||||
|
};
|
||||||
|
|
||||||
export function CompanyPickerCell({
|
export function CompanyPickerCell({
|
||||||
companyId,
|
companyId,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
@ -42,10 +46,10 @@ export function CompanyPickerCell({
|
|||||||
selectedIds: [companyId ?? ''],
|
selectedIds: [companyId ?? ''],
|
||||||
});
|
});
|
||||||
|
|
||||||
async function handleEntitySelected(
|
async function handleCompanySelected(
|
||||||
entity: EntityForSelect | null | undefined,
|
company: CompanyPickerSelectedCompany | null | undefined,
|
||||||
) {
|
) {
|
||||||
onSubmit(entity ?? null);
|
onSubmit(company ?? null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleStartCreation() {
|
function handleStartCreation() {
|
||||||
@ -69,6 +73,7 @@ export function CompanyPickerCell({
|
|||||||
id: companyCreated.id,
|
id: companyCreated.id,
|
||||||
name: companyCreated.name,
|
name: companyCreated.name,
|
||||||
entityType: Entity.Company,
|
entityType: Entity.Company,
|
||||||
|
domainName: companyCreated.domainName,
|
||||||
});
|
});
|
||||||
setIsCreating(false);
|
setIsCreating(false);
|
||||||
}
|
}
|
||||||
@ -86,7 +91,7 @@ export function CompanyPickerCell({
|
|||||||
width={width}
|
width={width}
|
||||||
onCreate={createModeEnabled ? handleStartCreation : undefined}
|
onCreate={createModeEnabled ? handleStartCreation : undefined}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
onEntitySelected={handleEntitySelected}
|
onEntitySelected={handleCompanySelected}
|
||||||
entities={{
|
entities={{
|
||||||
entitiesToSelect: companies.entitiesToSelect,
|
entitiesToSelect: companies.entitiesToSelect,
|
||||||
selectedEntity: companies.selectedEntities[0],
|
selectedEntity: companies.selectedEntities[0],
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity';
|
import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity';
|
||||||
import { ActivityTargetableEntityForSelect } from '@/activities/types/ActivityTargetableEntityForSelect';
|
|
||||||
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
||||||
import { useSearchCompanyQuery } from '~/generated/graphql';
|
import { useSearchCompanyQuery } from '~/generated/graphql';
|
||||||
import { getLogoUrlFromDomainName } from '~/utils';
|
import { getLogoUrlFromDomainName } from '~/utils';
|
||||||
@ -18,14 +17,14 @@ export function useFilteredSearchCompanyQuery({
|
|||||||
searchOnFields: ['name'],
|
searchOnFields: ['name'],
|
||||||
orderByField: 'name',
|
orderByField: 'name',
|
||||||
selectedIds: selectedIds,
|
selectedIds: selectedIds,
|
||||||
mappingFunction: (company) =>
|
mappingFunction: (company) => ({
|
||||||
({
|
id: company.id,
|
||||||
id: company.id,
|
entityType: ActivityTargetableEntityType.Company,
|
||||||
entityType: ActivityTargetableEntityType.Company,
|
name: company.name,
|
||||||
name: company.name,
|
avatarUrl: getLogoUrlFromDomainName(company.domainName),
|
||||||
avatarUrl: getLogoUrlFromDomainName(company.domainName),
|
domainName: company.domainName,
|
||||||
avatarType: 'squared',
|
avatarType: 'squared',
|
||||||
} as ActivityTargetableEntityForSelect),
|
}),
|
||||||
searchFilter,
|
searchFilter,
|
||||||
limit,
|
limit,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { CompanyPickerCell } from '@/companies/components/CompanyPickerCell';
|
import {
|
||||||
|
CompanyPickerCell,
|
||||||
|
CompanyPickerSelectedCompany,
|
||||||
|
} from '@/companies/components/CompanyPickerCell';
|
||||||
import {
|
import {
|
||||||
ViewFieldDefinition,
|
ViewFieldDefinition,
|
||||||
ViewFieldRelationMetadata,
|
ViewFieldRelationMetadata,
|
||||||
@ -22,21 +25,67 @@ export function GenericEditableRelationCellEditMode({ viewField }: OwnProps) {
|
|||||||
|
|
||||||
const { closeEditableCell } = useEditableCell();
|
const { closeEditableCell } = useEditableCell();
|
||||||
|
|
||||||
const [fieldValueEntity] = useRecoilState<any | null>(
|
const [fieldValueEntity, setFieldValueEntity] = useRecoilState<any | null>(
|
||||||
tableEntityFieldFamilySelector({
|
tableEntityFieldFamilySelector({
|
||||||
entityId: currentRowEntityId ?? '',
|
entityId: currentRowEntityId ?? '',
|
||||||
fieldName: viewField.metadata.fieldName,
|
fieldName: viewField.metadata.fieldName,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const updateEntityField = useUpdateEntityField();
|
const updateEntityField = useUpdateEntityField();
|
||||||
|
|
||||||
function handleEntitySubmit(newFieldEntity: EntityForSelect | null) {
|
function updateCachedPersonField(newFieldEntity: EntityForSelect | null) {
|
||||||
|
if (newFieldEntity === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setFieldValueEntity({
|
||||||
|
avatarUrl: newFieldEntity?.avatarUrl ?? '',
|
||||||
|
entityType: Entity.Company,
|
||||||
|
id: newFieldEntity?.id ?? '',
|
||||||
|
displayName: newFieldEntity?.name ?? '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCachedCompanyField(
|
||||||
|
newFieldEntity: CompanyPickerSelectedCompany | null,
|
||||||
|
) {
|
||||||
|
if (newFieldEntity === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setFieldValueEntity({
|
||||||
|
id: newFieldEntity?.id ?? '',
|
||||||
|
name: newFieldEntity?.name ?? '',
|
||||||
|
domainName: newFieldEntity?.domainName ?? '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCompanySubmit(
|
||||||
|
newFieldEntity: CompanyPickerSelectedCompany | null,
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
newFieldEntity &&
|
||||||
|
newFieldEntity?.id !== fieldValueEntity?.id &&
|
||||||
|
currentRowEntityId &&
|
||||||
|
updateEntityField
|
||||||
|
) {
|
||||||
|
updateCachedCompanyField(newFieldEntity);
|
||||||
|
updateEntityField<ViewFieldRelationMetadata, EntityForSelect>(
|
||||||
|
currentRowEntityId,
|
||||||
|
viewField,
|
||||||
|
newFieldEntity,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
closeEditableCell();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handlePersonSubmit(newFieldEntity: EntityForSelect | null) {
|
||||||
if (
|
if (
|
||||||
newFieldEntity?.id !== fieldValueEntity?.id &&
|
newFieldEntity?.id !== fieldValueEntity?.id &&
|
||||||
currentRowEntityId &&
|
currentRowEntityId &&
|
||||||
updateEntityField
|
updateEntityField
|
||||||
) {
|
) {
|
||||||
|
updateCachedPersonField(newFieldEntity);
|
||||||
updateEntityField(currentRowEntityId, viewField, newFieldEntity);
|
updateEntityField(currentRowEntityId, viewField, newFieldEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +101,7 @@ export function GenericEditableRelationCellEditMode({ viewField }: OwnProps) {
|
|||||||
return (
|
return (
|
||||||
<CompanyPickerCell
|
<CompanyPickerCell
|
||||||
companyId={fieldValueEntity?.id ?? null}
|
companyId={fieldValueEntity?.id ?? null}
|
||||||
onSubmit={handleEntitySubmit}
|
onSubmit={handleCompanySubmit}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
width={viewField.columnSize}
|
width={viewField.columnSize}
|
||||||
createModeEnabled
|
createModeEnabled
|
||||||
@ -63,7 +112,7 @@ export function GenericEditableRelationCellEditMode({ viewField }: OwnProps) {
|
|||||||
return (
|
return (
|
||||||
<UserPicker
|
<UserPicker
|
||||||
userId={fieldValueEntity?.id ?? null}
|
userId={fieldValueEntity?.id ?? null}
|
||||||
onSubmit={handleEntitySubmit}
|
onSubmit={handlePersonSubmit}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
width={viewField.columnSize}
|
width={viewField.columnSize}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -46,7 +46,7 @@ import { EntityUpdateMutationContext } from '../contexts/EntityUpdateMutationHoo
|
|||||||
export function useUpdateEntityField() {
|
export function useUpdateEntityField() {
|
||||||
const updateEntity = useContext(EntityUpdateMutationContext);
|
const updateEntity = useContext(EntityUpdateMutationContext);
|
||||||
|
|
||||||
return function updatePeopleField<
|
return function updateEntityField<
|
||||||
MetadataType extends ViewFieldMetadata,
|
MetadataType extends ViewFieldMetadata,
|
||||||
ValueType extends MetadataType extends ViewFieldDoubleTextMetadata
|
ValueType extends MetadataType extends ViewFieldDoubleTextMetadata
|
||||||
? ViewFieldDoubleTextValue
|
? ViewFieldDoubleTextValue
|
||||||
|
|||||||
Reference in New Issue
Block a user