Files
twenty/packages/twenty-front/src/modules/spreadsheet-import/components/MatchColumnSelectSubFieldSelectDropdownContent.tsx
T
Weiko 85c50f149d [Permissions][FE] Design followup 5 (#12793)
## Context
- We now display workspace member full name and email in role assignment
picker
- Replaced Forbidden by "Not shared" with lock icon
- Fix Disabled for Danger accent
- Fix avatar URL

<img width="575" alt="Screenshot 2025-06-23 at 16 38 56"
src="https://github.com/user-attachments/assets/08430bfe-29c4-4ac4-821c-9062dfad7150"
/>
<img width="756" alt="Screenshot 2025-06-23 at 16 21 36"
src="https://github.com/user-attachments/assets/c19f31bd-fe9d-415d-aa55-62fa3e228c49"
/>
<img width="373" alt="Screenshot 2025-06-23 at 17 13 08"
src="https://github.com/user-attachments/assets/e2f7878c-7c5a-40b4-a482-8e99292257c3"
/>
<img width="342" alt="Screenshot 2025-06-23 at 17 37 49"
src="https://github.com/user-attachments/assets/04169e85-14dd-4aed-bd71-7aefd601a894"
/>
<img width="434" alt="Screenshot 2025-06-23 at 17 37 35"
src="https://github.com/user-attachments/assets/7caf0967-c4dd-4d0f-90c8-259a85182b19"
/>
2025-06-23 19:15:58 +02:00

122 lines
4.4 KiB
TypeScript

import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
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';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useState } from 'react';
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,
onSubFieldSelect,
options,
onBack,
}: {
fieldMetadataItem: FieldMetadataItem;
onSubFieldSelect: (subFieldNameSelected: string) => void;
options: readonly ReadonlyDeep<SelectOption>[];
onBack: () => void;
}) => {
const [searchFilter, setSearchFilter] = useState('');
const { getIcon } = useIcons();
const handleFilterChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const value = event.currentTarget.value;
setSearchFilter(value);
};
const handleSubFieldSelect = (subFieldName: string) => {
onSubFieldSelect(subFieldName);
};
const handleSubMenuBack = () => {
setSearchFilter('');
onBack();
};
if (!isCompositeFieldType(fieldMetadataItem.type)) {
return <></>;
}
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}>
<DropdownMenuHeader
StartComponent={
<DropdownMenuHeaderLeftComponent
onClick={handleSubMenuBack}
Icon={IconChevronLeft}
/>
}
>
<OverflowingTextWithTooltip text={fieldMetadataItem.label} />
</DropdownMenuHeader>
<DropdownMenuSearchInput
value={searchFilter}
onChange={handleFilterChange}
autoFocus
/>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer hasMaxHeight>
{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>
);
};