85c50f149d
## 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" />
122 lines
4.4 KiB
TypeScript
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>
|
|
);
|
|
};
|