Added generic relation cell (#969)
* Added generic relation cell * Deactivated debug * Added default warning * Put back display component * Removed unused types
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
import { useContext } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
|
||||
import { GenericEditableCell } from '@/people/table/components/GenericEditableCell';
|
||||
import { GenericEditableCell } from '@/ui/table/components/GenericEditableCell';
|
||||
|
||||
import { RecoilScope } from '../../recoil-scope/components/RecoilScope';
|
||||
import { useCurrentRowSelected } from '../hooks/useCurrentRowSelected';
|
||||
|
||||
@ -6,9 +6,8 @@ import { useListenClickOutside } from '@/ui/hooks/useListenClickOutside';
|
||||
|
||||
import { useLeaveTableFocus } from '../hooks/useLeaveTableFocus';
|
||||
import { useMapKeyboardToSoftFocus } from '../hooks/useMapKeyboardToSoftFocus';
|
||||
import { EntityUpdateFieldHookContext } from '../states/EntityUpdateFieldHookContext';
|
||||
import { EntityUpdateMutationHookContext } from '../states/EntityUpdateMutationHookContext';
|
||||
import { TableHeader } from '../table-header/components/TableHeader';
|
||||
import { EntityUpdateFieldHook } from '../types/CellUpdateFieldHook';
|
||||
|
||||
import { EntityTableBody } from './EntityTableBodyV2';
|
||||
import { EntityTableHeader } from './EntityTableHeaderV2';
|
||||
@ -90,7 +89,7 @@ type OwnProps<SortField> = {
|
||||
availableSorts?: Array<SortType<SortField>>;
|
||||
onSortsUpdate?: (sorts: Array<SelectedSortType<SortField>>) => void;
|
||||
onRowSelectionChange?: (rowSelection: string[]) => void;
|
||||
useUpdateField: EntityUpdateFieldHook;
|
||||
useUpdateEntityMutation: any;
|
||||
};
|
||||
|
||||
export function EntityTable<SortField>({
|
||||
@ -98,7 +97,7 @@ export function EntityTable<SortField>({
|
||||
viewIcon,
|
||||
availableSorts,
|
||||
onSortsUpdate,
|
||||
useUpdateField,
|
||||
useUpdateEntityMutation,
|
||||
}: OwnProps<SortField>) {
|
||||
const tableBodyRef = React.useRef<HTMLDivElement>(null);
|
||||
|
||||
@ -114,7 +113,7 @@ export function EntityTable<SortField>({
|
||||
});
|
||||
|
||||
return (
|
||||
<EntityUpdateFieldHookContext.Provider value={useUpdateField}>
|
||||
<EntityUpdateMutationHookContext.Provider value={useUpdateEntityMutation}>
|
||||
<StyledTableWithHeader>
|
||||
<StyledTableContainer ref={tableBodyRef}>
|
||||
<TableHeader
|
||||
@ -131,6 +130,6 @@ export function EntityTable<SortField>({
|
||||
</StyledTableWrapper>
|
||||
</StyledTableContainer>
|
||||
</StyledTableWithHeader>
|
||||
</EntityUpdateFieldHookContext.Provider>
|
||||
</EntityUpdateMutationHookContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
import { EntityFieldMetadata } from '@/ui/table/types/EntityFieldMetadata';
|
||||
|
||||
import { GenericEditableRelationCell } from './GenericEditableRelationCell';
|
||||
import { GenericEditableTextCell } from './GenericEditableTextCell';
|
||||
|
||||
type OwnProps = {
|
||||
entityFieldMetadata: EntityFieldMetadata;
|
||||
};
|
||||
|
||||
export function GenericEditableCell({ entityFieldMetadata }: OwnProps) {
|
||||
switch (entityFieldMetadata.type) {
|
||||
case 'text':
|
||||
return (
|
||||
<GenericEditableTextCell
|
||||
fieldName={entityFieldMetadata.fieldName}
|
||||
placeholder={entityFieldMetadata.label}
|
||||
editModeHorizontalAlign="left"
|
||||
/>
|
||||
);
|
||||
case 'relation': {
|
||||
return (
|
||||
<GenericEditableRelationCell fieldMetadata={entityFieldMetadata} />
|
||||
);
|
||||
}
|
||||
default:
|
||||
console.warn(
|
||||
`Unknown field type: ${entityFieldMetadata.type} in GenericEditableCell`,
|
||||
);
|
||||
return <></>;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
import { RelationPickerHotkeyScope } from '@/ui/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
|
||||
import { EntityFieldMetadata } from '@/ui/table/types/EntityFieldMetadata';
|
||||
|
||||
import { GenericEditableRelationCellDisplayMode } from './GenericEditableRelationCellDisplayMode';
|
||||
import { GenericEditableRelationCellEditMode } from './GenericEditableRelationCellEditMode';
|
||||
|
||||
type OwnProps = {
|
||||
fieldMetadata: EntityFieldMetadata;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
export function GenericEditableRelationCell({
|
||||
fieldMetadata,
|
||||
editModeHorizontalAlign,
|
||||
placeholder,
|
||||
}: OwnProps) {
|
||||
return (
|
||||
<EditableCell
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
editHotkeyScope={{ scope: RelationPickerHotkeyScope.RelationPicker }}
|
||||
editModeContent={
|
||||
<GenericEditableRelationCellEditMode fieldMetadata={fieldMetadata} />
|
||||
}
|
||||
nonEditModeContent={
|
||||
<GenericEditableRelationCellDisplayMode
|
||||
fieldMetadata={fieldMetadata}
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
}
|
||||
></EditableCell>
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { CompanyChip } from '@/companies/components/CompanyChip';
|
||||
import { Entity } from '@/ui/relation-picker/types/EntityTypeForSelect';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
|
||||
import { EntityFieldMetadata } from '@/ui/table/types/EntityFieldMetadata';
|
||||
import { getLogoUrlFromDomainName } from '~/utils';
|
||||
|
||||
type OwnProps = {
|
||||
fieldMetadata: EntityFieldMetadata;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
export function GenericEditableRelationCellDisplayMode({
|
||||
fieldMetadata,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
const fieldValue = useRecoilValue<any | null>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: fieldMetadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
switch (fieldMetadata.relationType) {
|
||||
case Entity.Company: {
|
||||
return (
|
||||
<CompanyChip
|
||||
id={fieldValue?.id ?? ''}
|
||||
name={fieldValue?.name ?? ''}
|
||||
pictureUrl={getLogoUrlFromDomainName(fieldValue?.domainName)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
default:
|
||||
console.warn(
|
||||
`Unknown relation type: "${fieldMetadata.relationType}" in GenericEditableRelationCellEditMode`,
|
||||
);
|
||||
return <> </>;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { CompanyPickerCell } from '@/companies/components/CompanyPickerCell';
|
||||
import { useUpdateEntityField } from '@/people/hooks/useUpdateEntityField';
|
||||
import { EntityForSelect } from '@/ui/relation-picker/types/EntityForSelect';
|
||||
import { Entity } from '@/ui/relation-picker/types/EntityTypeForSelect';
|
||||
import { useEditableCell } from '@/ui/table/editable-cell/hooks/useEditableCell';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
|
||||
import { EntityFieldMetadata } from '@/ui/table/types/EntityFieldMetadata';
|
||||
|
||||
type OwnProps = {
|
||||
fieldMetadata: EntityFieldMetadata;
|
||||
};
|
||||
|
||||
export function GenericEditableRelationCellEditMode({
|
||||
fieldMetadata,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
const { closeEditableCell } = useEditableCell();
|
||||
|
||||
const [fieldValueEntity] = useRecoilState<any | null>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: fieldMetadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
const updateEntityField = useUpdateEntityField();
|
||||
|
||||
function handleEntitySubmit(newFieldEntity: EntityForSelect | null) {
|
||||
if (
|
||||
newFieldEntity?.id !== fieldValueEntity?.id &&
|
||||
currentRowEntityId &&
|
||||
updateEntityField
|
||||
) {
|
||||
updateEntityField(
|
||||
currentRowEntityId,
|
||||
fieldMetadata.fieldName,
|
||||
newFieldEntity,
|
||||
);
|
||||
}
|
||||
|
||||
closeEditableCell();
|
||||
}
|
||||
|
||||
function handleCancel() {
|
||||
closeEditableCell();
|
||||
}
|
||||
|
||||
switch (fieldMetadata.relationType) {
|
||||
case Entity.Company: {
|
||||
return (
|
||||
<CompanyPickerCell
|
||||
companyId={fieldValueEntity?.id ?? null}
|
||||
onSubmit={handleEntitySubmit}
|
||||
onCancel={handleCancel}
|
||||
/>
|
||||
);
|
||||
}
|
||||
default:
|
||||
console.warn(
|
||||
`Unknown relation type: "${fieldMetadata.relationType}" in GenericEditableRelationCellEditMode`,
|
||||
);
|
||||
return <></>;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { InplaceInputTextDisplayMode } from '@/ui/display/component/InplaceInputTextDisplayMode';
|
||||
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
|
||||
|
||||
import { GenericEditableTextCellEditMode } from './GenericEditableTextCellEditMode';
|
||||
|
||||
type OwnProps = {
|
||||
fieldName: string;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
export function GenericEditableTextCell({
|
||||
fieldName,
|
||||
editModeHorizontalAlign,
|
||||
placeholder,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
const fieldValue = useRecoilValue<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
return (
|
||||
<EditableCell
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
editModeContent={
|
||||
<GenericEditableTextCellEditMode
|
||||
fieldName={fieldName}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
}
|
||||
nonEditModeContent={
|
||||
<InplaceInputTextDisplayMode>{fieldValue}</InplaceInputTextDisplayMode>
|
||||
}
|
||||
></EditableCell>
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { useUpdateEntityField } from '@/people/hooks/useUpdateEntityField';
|
||||
import { InplaceInputTextEditMode } from '@/ui/inplace-input/components/InplaceInputTextEditMode';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
|
||||
|
||||
type OwnProps = {
|
||||
fieldName: string;
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
export function GenericEditableTextCellEditMode({
|
||||
fieldName,
|
||||
placeholder,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
const [fieldValue, setFieldValue] = useRecoilState<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
const updateField = useUpdateEntityField();
|
||||
|
||||
function handleSubmit(newText: string) {
|
||||
if (newText === fieldValue) return;
|
||||
|
||||
setFieldValue(newText);
|
||||
|
||||
if (currentRowEntityId && updateField) {
|
||||
updateField(currentRowEntityId, fieldName, newText);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<InplaceInputTextEditMode
|
||||
placeholder={placeholder ?? ''}
|
||||
autoFocus
|
||||
value={fieldValue ?? ''}
|
||||
onSubmit={handleSubmit}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user