This PR replaces the many calls of useDropdown by the new standalone hooks : useCloseDropdown, useOpenDropdown and useToggleDropdown. This will allow to remove useDropdown and then the dropdown recoil component state v1. A big round of QA has been made, with some bugs caught along the way. Closes https://github.com/twentyhq/core-team-issues/issues/1155 Closes https://github.com/twentyhq/core-team-issues/issues/618 ## QA Component|Status|Comment |---|---|---| CurrentWorkspaceMemberFavorites|Ok| FavoriteFolderPickerFooter|Ok| AdvancedFilterAddFilterRuleSelect|Ok| AdvancedFilterRecordFilterGroupOptionsDropdown|Ok| AdvancedFilterRecordFilterOperandSelectContent|Ok| AdvancedFilterRecordFilterOptionsDropdown|Ok| useAdvancedFilterFieldSelectDropdown|Ok| ObjectFilterDropdownBooleanSelect|Ok| ObjectFilterDropdownOptionSelect|Ok| ObjectOptionsDropdown|Ok| ObjectOptionsDropdownLayoutContent|Ok| ObjectSortDropdownButton|Ok| useCloseSortDropdown|Ok| FormDateTimeFieldInput|Ok|Bug detected, cannot select a month or a year, see issue https://github.com/twentyhq/twenty/issues/12922 FormSingleRecordPicker|Ok| MultiItemFieldMenuItem|Ok| RecordDetailRelationRecordsListItem|Ok| RecordDetailRelationSection|Ok| RecordDetailRelationSectionDropdownToMany|Ok| RecordDetailRelationSectionDropdownToOne|Ok| RecordTableColumnAggregateFooterDropdownSubmenuContent|Ok| RecordTableColumnAggregateFooterAggregateOperationMenuItems|Ok| RecordTableColumnAggregateFooterMenuContent|Ok| RecordTableColumnAggregateFooterValueCell|Ok| RecordTableColumnHeadDropdownMenu|Ok| RecordTableHeaderPlusButtonContent|Ok| useTriggerActionMenuDropdown|Ok| MultipleSelectDropdown|Ok| RecordBoardColumnHeaderAggregateDropdownButton|Ok| SettingsDataModelFieldSelectFormOptionRow|Ok| SettingsDataModelNewFieldBreadcrumbDropDown|Ok| SettingsObjectFieldActiveActionDropdown|Ok| SettingsObjectFieldInactiveActionDropdown|Ok| SettingsObjectInactiveMenuDropDown|Ok| SettingsSecurityApprovedAccessDomainRowDropdownMenu|Couldn’t test| SettingsSecuritySSORowDropdownMenu|Couldn’t test| SettingsAccountsRowDropdownMenu|Ok| SettingsRoleAssignment|Ok| SettingsServerlessFunctionTabEnvironmentVariableTableRow|Couldn’t test| MatchColumnToFieldSelect|Ok| SubMatchingSelectDropdownButton|Ok|Removed conflicting duplicate open dropdown SubMatchingSelectRowRightDropdown|Ok| CurrencyPickerDropdownButton|Ok| IconPicker|Ok| DateTimePicker|Ok| PhoneCountryPickerDropdownButton|OK| Select|Ok| Dropdown|Ok|Not QAing all dropdowns in the app because the ones of this QA are enough to show up that Dropdown is behaving correctly on a lot of use cases DropdownMenuInnerSelect|Ok| TabList|Ok|Removed onClickOutside called in dropdown clickable component, validated with Raph who recently worked on this DateInput|Ok| MultiWorkspaceDropdownDefaultComponents|Ok| AdvancedFilterChip|Ok| EditableFilterDropdownButton|Ok| UpdateViewButtonGroup|Ok| ViewBarDetailsAddFilterButton|Ok| ViewBarFilterButton|Ok| ViewBarFilterDropdown|Ok| ViewBarFilterDropdownAdvancedFilterButton|Ok| ViewPickerDropdown|Ok| ViewPickerListContent|Ok| ViewPickerOptionDropdown|Ok| WorkflowEditTriggerDatabaseEventForm|Ok| WorkflowVariablesDropdownWorkflowStepItems|Ok| AttachmentDropdown|Ok| SupportDropdown|Ok| Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com> Co-authored-by: Charles Bochet <charles@twenty.com>
126 lines
4.3 KiB
TypeScript
126 lines
4.3 KiB
TypeScript
import { useCreateFavorite } from '@/favorites/hooks/useCreateFavorite';
|
|
import { useFavorites } from '@/favorites/hooks/useFavorites';
|
|
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
|
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
|
import { MenuItemWithOptionDropdown } from '@/ui/navigation/menu-item/components/MenuItemWithOptionDropdown';
|
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
|
import { View } from '@/views/types/View';
|
|
import { useDeleteViewFromCurrentState } from '@/views/view-picker/hooks/useDeleteViewFromCurrentState';
|
|
import { useViewPickerMode } from '@/views/view-picker/hooks/useViewPickerMode';
|
|
import { viewPickerReferenceViewIdComponentState } from '@/views/view-picker/states/viewPickerReferenceViewIdComponentState';
|
|
import { useLingui } from '@lingui/react/macro';
|
|
import { useState } from 'react';
|
|
import {
|
|
IconHeart,
|
|
IconLock,
|
|
IconPencil,
|
|
IconTrash,
|
|
useIcons,
|
|
} from 'twenty-ui/display';
|
|
import { MenuItem } from 'twenty-ui/navigation';
|
|
|
|
type ViewPickerOptionDropdownProps = {
|
|
isIndexView: boolean;
|
|
view: Pick<View, 'id' | 'name' | 'icon' | '__typename'>;
|
|
onEdit: (event: React.MouseEvent<HTMLElement>, viewId: string) => void;
|
|
handleViewSelect: (viewId: string) => void;
|
|
};
|
|
|
|
export const ViewPickerOptionDropdown = ({
|
|
isIndexView,
|
|
onEdit,
|
|
view,
|
|
handleViewSelect,
|
|
}: ViewPickerOptionDropdownProps) => {
|
|
const dropdownId = `view-picker-options-${view.id}`;
|
|
|
|
const { t } = useLingui();
|
|
const { closeDropdown } = useCloseDropdown();
|
|
const { getIcon } = useIcons();
|
|
const [isHovered, setIsHovered] = useState(false);
|
|
const { deleteViewFromCurrentState } = useDeleteViewFromCurrentState();
|
|
const setViewPickerReferenceViewId = useSetRecoilComponentStateV2(
|
|
viewPickerReferenceViewIdComponentState,
|
|
);
|
|
const { setViewPickerMode } = useViewPickerMode();
|
|
|
|
const { sortedFavorites: favorites } = useFavorites();
|
|
const { createFavorite } = useCreateFavorite();
|
|
|
|
const isFavorite = favorites.some(
|
|
(favorite) =>
|
|
favorite.recordId === view.id && favorite.forWorkspaceMemberId,
|
|
);
|
|
|
|
const handleDelete = () => {
|
|
setViewPickerReferenceViewId(view.id);
|
|
deleteViewFromCurrentState();
|
|
closeDropdown(dropdownId);
|
|
};
|
|
|
|
const handleAddToFavorites = () => {
|
|
if (!isFavorite) {
|
|
createFavorite(view, 'view');
|
|
} else {
|
|
setViewPickerReferenceViewId(view.id);
|
|
setViewPickerMode('favorite-folders-picker');
|
|
}
|
|
closeDropdown(dropdownId);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<MenuItemWithOptionDropdown
|
|
text={view.name}
|
|
LeftIcon={getIcon(view.icon)}
|
|
onClick={() => handleViewSelect(view.id)}
|
|
isIconDisplayedOnHoverOnly={!isIndexView}
|
|
RightIcon={!isHovered && isIndexView ? IconLock : null}
|
|
onMouseEnter={() => setIsHovered(true)}
|
|
onMouseLeave={() => {
|
|
setIsHovered(false);
|
|
}}
|
|
dropdownPlacement="bottom-start"
|
|
dropdownId={`view-picker-options-${view.id}`}
|
|
dropdownContent={
|
|
<DropdownContent>
|
|
<DropdownMenuItemsContainer>
|
|
{isIndexView ? (
|
|
<MenuItem
|
|
LeftIcon={IconHeart}
|
|
text={isFavorite ? t`Manage favorite` : t`Add to Favorite`}
|
|
onClick={handleAddToFavorites}
|
|
/>
|
|
) : (
|
|
<>
|
|
<MenuItem
|
|
LeftIcon={IconHeart}
|
|
text={isFavorite ? t`Manage favorite` : t`Add to Favorite`}
|
|
onClick={handleAddToFavorites}
|
|
/>
|
|
|
|
<MenuItem
|
|
LeftIcon={IconPencil}
|
|
text={t`Edit`}
|
|
onClick={(event) => {
|
|
onEdit(event, view.id);
|
|
closeDropdown(dropdownId);
|
|
}}
|
|
/>
|
|
<MenuItem
|
|
LeftIcon={IconTrash}
|
|
text={t`Delete`}
|
|
onClick={handleDelete}
|
|
accent="danger"
|
|
/>
|
|
</>
|
|
)}
|
|
</DropdownMenuItemsContainer>
|
|
</DropdownContent>
|
|
}
|
|
/>
|
|
</>
|
|
);
|
|
};
|