Revert "Connect - Relation on FE Importer (#13213)" (#13313)

This reverts commit cc71394863.

Regression introduced in https://github.com/twentyhq/twenty/pull/13213
The import/export use an upsert logic and when it goes through the
"update" path it fails due to the connect not being implemented yet
(should be in https://github.com/twentyhq/core-team-issues/issues/1230)

---------

Co-authored-by: prastoin <paul@twenty.com>
This commit is contained in:
Weiko
2025-07-21 17:03:42 +02:00
committed by GitHub
parent f6aa556a16
commit 79f3fbb016
90 changed files with 1159 additions and 1572 deletions
@@ -1,8 +1,8 @@
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { getFieldMetadataTypeLabel } from '@/object-record/object-filter-dropdown/utils/getFieldMetadataTypeLabel';
import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType';
import { DO_NOT_IMPORT_OPTION_KEY } from '@/spreadsheet-import/constants/DoNotImportOptionKey';
import { useSpreadsheetImportInternal } from '@/spreadsheet-import/hooks/useSpreadsheetImportInternal';
import { hasNestedFields } from '@/spreadsheet-import/utils/spreadsheetImportHasNestedFields';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
@@ -139,7 +139,7 @@ export const MatchColumnSelectFieldSelectDropdownContent = ({
LeftIcon={getIcon(field.icon)}
text={field.label}
contextualText={getFieldMetadataTypeLabel(field.type)}
hasSubMenu={hasNestedFields(field)}
hasSubMenu={isCompositeFieldType(field.type)}
/>
))}
</DropdownMenuItemsContainer>
@@ -1,7 +1,9 @@
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { SpreadsheetImportFieldOption } from '@/spreadsheet-import/types/SpreadsheetImportFieldOption';
import { getSubFieldOptions } from '@/spreadsheet-import/utils/spreadsheetImportGetSubFieldOptions';
import { hasNestedFields } from '@/spreadsheet-import/utils/spreadsheetImportHasNestedFields';
import { getCompositeSubFieldLabel } from '@/object-record/object-filter-dropdown/utils/getCompositeSubFieldLabel';
import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType';
import { getSubFieldOptionKey } from '@/object-record/spreadsheet-import/utils/getSubFieldOptionKey';
import { SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS } from '@/settings/data-model/constants/SettingsCompositeFieldTypeConfigs';
import { CompositeFieldType } from '@/settings/data-model/types/CompositeFieldType';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
@@ -10,8 +12,15 @@ import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/Dropdow
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useState } from 'react';
import { IconChevronLeft, OverflowingTextWithTooltip } from 'twenty-ui/display';
import { isDefined } from 'twenty-shared/utils';
import {
IconChevronLeft,
OverflowingTextWithTooltip,
useIcons,
} from 'twenty-ui/display';
import { SelectOption } from 'twenty-ui/input';
import { MenuItem } from 'twenty-ui/navigation';
import { ReadonlyDeep } from 'type-fest';
export const MatchColumnSelectSubFieldSelectDropdownContent = ({
fieldMetadataItem,
@@ -21,11 +30,13 @@ export const MatchColumnSelectSubFieldSelectDropdownContent = ({
}: {
fieldMetadataItem: FieldMetadataItem;
onSubFieldSelect: (subFieldNameSelected: string) => void;
options: readonly Readonly<SpreadsheetImportFieldOption>[];
options: readonly ReadonlyDeep<SelectOption>[];
onBack: () => void;
}) => {
const [searchFilter, setSearchFilter] = useState('');
const { getIcon } = useIcons();
const handleFilterChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const value = event.currentTarget.value;
@@ -41,15 +52,31 @@ export const MatchColumnSelectSubFieldSelectDropdownContent = ({
onBack();
};
if (!hasNestedFields(fieldMetadataItem)) {
if (!isCompositeFieldType(fieldMetadataItem.type)) {
return <></>;
}
const subFieldOptions = getSubFieldOptions(
fieldMetadataItem,
options,
searchFilter,
);
const fieldMetadataItemSettings =
SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS[fieldMetadataItem.type];
const subFieldsThatExistInOptions = fieldMetadataItemSettings.subFields
.filter(({ subFieldName }) => {
const optionKey = getSubFieldOptionKey(fieldMetadataItem, subFieldName);
const correspondingOption = options.find(
(option) => option.value === optionKey,
);
return isDefined(correspondingOption);
})
.filter(({ subFieldName }) =>
getCompositeSubFieldLabel(
fieldMetadataItem.type as CompositeFieldType,
subFieldName,
)
.toLowerCase()
.includes(searchFilter.toLowerCase()),
);
return (
<DropdownContent widthInPixels={GenericDropdownContentWidth.ExtraLarge}>
@@ -70,17 +97,24 @@ export const MatchColumnSelectSubFieldSelectDropdownContent = ({
/>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer hasMaxHeight>
{subFieldOptions.map(
({ value, shortLabelForNestedField, Icon, disabled }) => (
<MenuItem
key={value}
onClick={() => handleSubFieldSelect(value)}
LeftIcon={Icon}
text={shortLabelForNestedField}
disabled={disabled}
/>
),
)}
{subFieldsThatExistInOptions.map(({ subFieldName }) => (
<MenuItem
key={subFieldName}
onClick={() => handleSubFieldSelect(subFieldName)}
LeftIcon={getIcon(fieldMetadataItem.icon)}
text={getCompositeSubFieldLabel(
fieldMetadataItem.type as CompositeFieldType,
subFieldName,
)}
disabled={
options.find(
(option) =>
option.value ===
getSubFieldOptionKey(fieldMetadataItem, subFieldName),
)?.disabled
}
/>
))}
</DropdownMenuItemsContainer>
</DropdownContent>
);
@@ -3,11 +3,10 @@ import { ReadonlyDeep } from 'type-fest';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType';
import { getSubFieldOptionKey } from '@/object-record/spreadsheet-import/utils/getSubFieldOptionKey';
import { MatchColumnSelectFieldSelectDropdownContent } from '@/spreadsheet-import/components/MatchColumnSelectFieldSelectDropdownContent';
import { MatchColumnSelectSubFieldSelectDropdownContent } from '@/spreadsheet-import/components/MatchColumnSelectSubFieldSelectDropdownContent';
import { DO_NOT_IMPORT_OPTION_KEY } from '@/spreadsheet-import/constants/DoNotImportOptionKey';
import { SpreadsheetImportFieldOption } from '@/spreadsheet-import/types/SpreadsheetImportFieldOption';
import { hasNestedFields } from '@/spreadsheet-import/utils/spreadsheetImportHasNestedFields';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import styled from '@emotion/styled';
@@ -20,7 +19,7 @@ interface MatchColumnToFieldSelectProps {
columnIndex: string;
onChange: (value: ReadonlyDeep<SelectOption> | null) => void;
value?: ReadonlyDeep<SelectOption>;
options: readonly Readonly<SpreadsheetImportFieldOption>[];
options: readonly ReadonlyDeep<SelectOption>[];
suggestedOptions: readonly ReadonlyDeep<SelectOption>[];
placeholder?: string;
}
@@ -71,7 +70,12 @@ export const MatchColumnToFieldSelect = ({
}
const correspondingOption = options.find((option) => {
return option.value === subFieldNameSelected;
const optionKey = getSubFieldOptionKey(
selectedFieldMetadataItem,
subFieldNameSelected,
);
return option.value === optionKey;
});
if (isDefined(correspondingOption)) {
@@ -108,9 +112,9 @@ export const MatchColumnToFieldSelect = ({
closeDropdown(dropdownId);
};
const shouldShowNestedField =
const shouldShowSubField =
isDefined(selectedFieldMetadataItem) &&
hasNestedFields(selectedFieldMetadataItem);
isCompositeFieldType(selectedFieldMetadataItem.type);
return (
<Dropdown
@@ -125,7 +129,7 @@ export const MatchColumnToFieldSelect = ({
/>
}
dropdownComponents={
shouldShowNestedField ? (
shouldShowSubField ? (
<MatchColumnSelectSubFieldSelectDropdownContent
fieldMetadataItem={selectedFieldMetadataItem}
onSubFieldSelect={handleSubFieldSelect}
@@ -5,16 +5,16 @@ import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
export const RsiContext = createContext({} as any);
type ReactSpreadsheetImportContextProviderProps = {
type ReactSpreadsheetImportContextProviderProps<T extends string> = {
children: React.ReactNode;
values: SpreadsheetImportDialogOptions;
values: SpreadsheetImportDialogOptions<T>;
};
export const ReactSpreadsheetImportContextProvider = ({
export const ReactSpreadsheetImportContextProvider = <T extends string>({
children,
values,
}: ReactSpreadsheetImportContextProviderProps) => {
if (isUndefinedOrNull(values.spreadsheetImportFields)) {
}: ReactSpreadsheetImportContextProviderProps<T>) => {
if (isUndefinedOrNull(values.fields)) {
throw new Error('Fields must be provided to spreadsheet-import');
}