Refactor useDropdownV2 (#12875)
# What this PR does This PR introduces what’s needed to progressively refactor the useDropdown hooks we have. It removes useDropdownV2 and renames useDropdown used for multi-page dropdowns to useDropdownContextStateManagement ## The 3 useDropdown hooks There are currently 3 useDropdown hooks : One is used for managing states in some dropdowns that have multiple inner pages with contexts and without recoil. It is limited and would need a separate refactoring, thus I just renamed it. Then we have useDropdown and useDropdownV2, which followed our multiple versions of recoil state management wrappers. Now that the state management has been stabilized, we can merge everything on the last version. ## What this refactor will allow next This refactor will allow to refactor the legacy recoil state management, because useDropdown is depending on legacy recoil states with scopeId. Because there are only a dozen of those legacy states left, and the dropdown’s ones are the harder to refactor, because swapping them as-is causes a big QA, and if we have a big QA to do on all dropdowns, better refactor the whole dropdown management and have everything clean. After this refactor, we will be able to delete the legacy dropdown states, and proceed with the other legacy states, then removing all the legacy recoil state mangament. ## How do we allow progressive refactoring ? There are many places where useDropdown is used. To have an easier refactoring process, we want to merge multiple small pull requests so that it is easier to QA and review. For this we will maintain both legacy component state and component state V2 in parallel for isDropdownOpen, so that the new hooks `useOpenDropdown` , `useCloseDropdown` are doing the same thing than `useDropdown` and `useDropdownV2` . Thus for the moment, whether we use the legacy hooks or the new ones, the effects are the same. And we can have dropdowns operating on the old states and the new states living side by side in the app. ## QA Component | Status | Comments -- | -- | -- CommandMenuActionMenuDropdown | Ok | RecordIndexActionMenuDropdown | Ok | RecordShowRightDrawerOpenRecordButton | Ok | useCloseActionMenu | Ok | CommandMenuContextChipGroups | Ok | useCommandMenuCloseAnimationCompleteCleanup | Ok | ObjectOptionsDropdown | Ok | ObjectOptionsDropdownContent | Ok | ObjectOptionsDropdownFieldsContent | Ok | ObjectOptionsDropdownHiddenFieldsContent | Ok | ObjectOptionsDropdownHiddenRecordGroupsContent | Ok | ObjectOptionsDropdownLayoutContent | Ok | ObjectOptionsDropdownLayoutOpenInContent | Ok | ObjectOptionsDropdownMenuContent | Ok | ObjectOptionsDropdownRecordGroupFieldsContent | Ok | ObjectOptionsDropdownRecordGroupsContent | Ok | ObjectOptionsDropdownRecordGroupSortContent | Ok | RecordBoardColumnHeaderAggregateDropdown | Ok | AggregateDropdownContent | Ok | RecordBoardColumnHeaderAggregateDropdownFieldsContent | Ok | RecordBoardColumnHeaderAggregateDropdownMenuContent | Ok | RecordBoardColumnHeaderAggregateDropdownMenuContent | Ok | RecordBoardColumnHeaderAggregateDropdownOptionsContent | Ok | RecordBoard | Ok | Used closeAnyOpenDropdown instead for a better UX RecordBoardCard | Ok | useRecordBoardSelection | Ok | RecordTableColumnAggregateFooterDropdownContent | Ok | RecordTableColumnFooterWithDropdown | Ok | useOpenRecordFilterChipFromTableHeader | Ok | useCloseAnyOpenDropdown | Ok | useCloseDropdownFromOutside | Removed | Removed because unused useDropdownV2 | Removed | Removed because all calls have been removed useOpenDropdownFromOutside | Removed | Removed because unused useCloseAndResetViewPicker | Ok | WorkflowVariablesDropdown | Ok |
This commit is contained in:
@ -8,7 +8,7 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
|||||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
|
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
|
||||||
import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2';
|
import { useToggleDropdown } from '@/ui/layout/dropdown/hooks/useToggleDropdown';
|
||||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||||
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
||||||
@ -30,12 +30,14 @@ export const CommandMenuActionMenuDropdown = () => {
|
|||||||
|
|
||||||
const dropdownId =
|
const dropdownId =
|
||||||
getRightDrawerActionMenuDropdownIdFromActionMenuId(actionMenuId);
|
getRightDrawerActionMenuDropdownIdFromActionMenuId(actionMenuId);
|
||||||
const { toggleDropdown } = useDropdownV2();
|
const { toggleDropdown } = useToggleDropdown();
|
||||||
|
|
||||||
const hotkeysConfig = {
|
const hotkeysConfig = {
|
||||||
keys: ['ctrl+o', 'meta+o'],
|
keys: ['ctrl+o', 'meta+o'],
|
||||||
callback: () => {
|
callback: () => {
|
||||||
toggleDropdown(dropdownId);
|
toggleDropdown({
|
||||||
|
dropdownComponentInstanceIdFromProps: dropdownId,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
scope: AppHotkeyScope.CommandMenuOpen,
|
scope: AppHotkeyScope.CommandMenuOpen,
|
||||||
dependencies: [toggleDropdown],
|
dependencies: [toggleDropdown],
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
|||||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
|
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
|
||||||
import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2';
|
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||||
@ -48,7 +48,7 @@ export const RecordIndexActionMenuDropdown = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const dropdownId = getActionMenuDropdownIdFromActionMenuId(actionMenuId);
|
const dropdownId = getActionMenuDropdownIdFromActionMenuId(actionMenuId);
|
||||||
const { closeDropdown } = useDropdownV2();
|
const { closeDropdown } = useCloseDropdown();
|
||||||
|
|
||||||
const actionMenuDropdownPosition = useRecoilValue(
|
const actionMenuDropdownPosition = useRecoilValue(
|
||||||
extractComponentState(
|
extractComponentState(
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi
|
|||||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
import { AppPath } from '@/types/AppPath';
|
import { AppPath } from '@/types/AppPath';
|
||||||
import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2';
|
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||||
import { getShowPageTabListComponentId } from '@/ui/layout/show-page/utils/getShowPageTabListComponentId';
|
import { getShowPageTabListComponentId } from '@/ui/layout/show-page/utils/getShowPageTabListComponentId';
|
||||||
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
|
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
|
||||||
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
||||||
@ -74,7 +74,7 @@ export const RecordShowRightDrawerOpenRecordButton = ({
|
|||||||
ActionMenuComponentInstanceContext,
|
ActionMenuComponentInstanceContext,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { closeDropdown } = useDropdownV2();
|
const { closeDropdown } = useCloseDropdown();
|
||||||
|
|
||||||
const handleOpenRecord = useRecoilCallback(
|
const handleOpenRecord = useRecoilCallback(
|
||||||
({ snapshot, reset }) =>
|
({ snapshot, reset }) =>
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { ActionMenuComponentInstanceContext } from '@/action-menu/states/context
|
|||||||
import { getActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getActionMenuDropdownIdFromActionMenuId';
|
import { getActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getActionMenuDropdownIdFromActionMenuId';
|
||||||
import { getRightDrawerActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getRightDrawerActionMenuDropdownIdFromActionMenuId';
|
import { getRightDrawerActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getRightDrawerActionMenuDropdownIdFromActionMenuId';
|
||||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||||
import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2';
|
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
@ -19,7 +19,7 @@ export const useCloseActionMenu = ({
|
|||||||
|
|
||||||
const { closeCommandMenu } = useCommandMenu();
|
const { closeCommandMenu } = useCommandMenu();
|
||||||
|
|
||||||
const { closeDropdown } = useDropdownV2();
|
const { closeDropdown } = useCloseDropdown();
|
||||||
|
|
||||||
const actionMenuId = useAvailableComponentInstanceIdOrThrow(
|
const actionMenuId = useAvailableComponentInstanceIdOrThrow(
|
||||||
ActionMenuComponentInstanceContext,
|
ActionMenuComponentInstanceContext,
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { COMMAND_MENU_CONTEXT_CHIP_GROUPS_DROPDOWN_ID } from '@/command-menu/con
|
|||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2';
|
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { MenuItem } from 'twenty-ui/navigation';
|
import { MenuItem } from 'twenty-ui/navigation';
|
||||||
import {
|
import {
|
||||||
@ -15,7 +15,7 @@ export const CommandMenuContextChipGroups = ({
|
|||||||
}: {
|
}: {
|
||||||
contextChips: CommandMenuContextChipProps[];
|
contextChips: CommandMenuContextChipProps[];
|
||||||
}) => {
|
}) => {
|
||||||
const { closeDropdown } = useDropdownV2();
|
const { closeDropdown } = useCloseDropdown();
|
||||||
|
|
||||||
if (contextChips.length === 0) {
|
if (contextChips.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -25,8 +25,8 @@ const mockResetContextStoreStates = jest.fn();
|
|||||||
const mockResetSelectedItem = jest.fn();
|
const mockResetSelectedItem = jest.fn();
|
||||||
const mockEmitSidePanelCloseEvent = jest.fn();
|
const mockEmitSidePanelCloseEvent = jest.fn();
|
||||||
|
|
||||||
jest.mock('@/ui/layout/dropdown/hooks/useDropdownV2', () => ({
|
jest.mock('@/ui/layout/dropdown/hooks/useCloseDropdown', () => ({
|
||||||
useDropdownV2: () => ({
|
useCloseDropdown: () => ({
|
||||||
closeDropdown: mockCloseDropdown,
|
closeDropdown: mockCloseDropdown,
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import { isCommandMenuClosingState } from '@/command-menu/states/isCommandMenuCl
|
|||||||
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
||||||
import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages';
|
import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages';
|
||||||
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
|
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
|
||||||
import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2';
|
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||||
import { emitSidePanelCloseEvent } from '@/ui/layout/right-drawer/utils/emitSidePanelCloseEvent';
|
import { emitSidePanelCloseEvent } from '@/ui/layout/right-drawer/utils/emitSidePanelCloseEvent';
|
||||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||||
import { getShowPageTabListComponentId } from '@/ui/layout/show-page/utils/getShowPageTabListComponentId';
|
import { getShowPageTabListComponentId } from '@/ui/layout/show-page/utils/getShowPageTabListComponentId';
|
||||||
@ -27,7 +27,7 @@ export const useCommandMenuCloseAnimationCompleteCleanup = () => {
|
|||||||
|
|
||||||
const { resetContextStoreStates } = useResetContextStoreStates();
|
const { resetContextStoreStates } = useResetContextStoreStates();
|
||||||
|
|
||||||
const { closeDropdown } = useDropdownV2();
|
const { closeDropdown } = useCloseDropdown();
|
||||||
|
|
||||||
const commandMenuCloseAnimationCompleteCleanup = useRecoilCallback(
|
const commandMenuCloseAnimationCompleteCleanup = useRecoilCallback(
|
||||||
({ snapshot, set }) =>
|
({ snapshot, set }) =>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
|
|
||||||
export const useCurrentContentId = <T>() => {
|
export const useDropdownContextCurrentContentId = <T>() => {
|
||||||
const [currentContentId, setCurrentContentId] = useState<T | null>(null);
|
const [currentContentId, setCurrentContentId] = useState<T | null>(null);
|
||||||
|
|
||||||
const [previousContentId, setPreviousContentId] = useState<T | null>(null);
|
const [previousContentId, setPreviousContentId] = useState<T | null>(null);
|
||||||
@ -4,7 +4,13 @@ import { RecordTableColumnAggregateFooterDropdownContextValue } from '@/object-r
|
|||||||
import { useDropdown as useDropdownUi } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown as useDropdownUi } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { Context, useCallback, useContext } from 'react';
|
import { Context, useCallback, useContext } from 'react';
|
||||||
|
|
||||||
export const useDropdown = <
|
/**
|
||||||
|
*
|
||||||
|
* @deprecated This hook is deprecated because it uses context instead of recoil and synchronous hooks like we do in the application
|
||||||
|
*
|
||||||
|
* TODO: refactor this generic way to handle multiple pages in a dropdown with state management and specific code paths in a dedicated module, instead of using context with generic union types.
|
||||||
|
*/
|
||||||
|
export const useDropdownContextStateManagement = <
|
||||||
T extends
|
T extends
|
||||||
| RecordBoardColumnHeaderAggregateDropdownContextValue
|
| RecordBoardColumnHeaderAggregateDropdownContextValue
|
||||||
| RecordTableColumnAggregateFooterDropdownContextValue
|
| RecordTableColumnAggregateFooterDropdownContextValue
|
||||||
@ -18,7 +24,7 @@ export const useDropdown = <
|
|||||||
|
|
||||||
if (!dropdownContext) {
|
if (!dropdownContext) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`useDropdown must be used within a context provider (${context.Provider.name})`,
|
`useDropdownContextStateManagement must be used within a context provider (${context.Provider.name})`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const dropdownId = dropdownContext.dropdownId;
|
const dropdownId = dropdownContext.dropdownId;
|
||||||
@ -1,5 +1,4 @@
|
|||||||
import { DROPDOWN_OFFSET_Y } from '@/dropdown/constants/DropdownOffsetY';
|
import { useDropdownContextCurrentContentId } from '@/dropdown-context-state-management/hooks/useDropdownContextCurrentContentId';
|
||||||
import { useCurrentContentId } from '@/dropdown/hooks/useCurrentContentId';
|
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { ObjectOptionsDropdownContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownContent';
|
import { ObjectOptionsDropdownContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownContent';
|
||||||
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
|
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
|
||||||
@ -9,6 +8,7 @@ import { RecordGroupReorderConfirmationModal } from '@/object-record/record-grou
|
|||||||
import { useRecordGroupReorderConfirmationModal } from '@/object-record/record-group/hooks/useRecordGroupReorderConfirmationModal';
|
import { useRecordGroupReorderConfirmationModal } from '@/object-record/record-group/hooks/useRecordGroupReorderConfirmationModal';
|
||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
|
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
|
||||||
|
import { DROPDOWN_OFFSET_Y } from '@/ui/layout/dropdown/constants/DropdownOffsetY';
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { ViewType } from '@/views/types/ViewType';
|
import { ViewType } from '@/views/types/ViewType';
|
||||||
import { Trans } from '@lingui/react/macro';
|
import { Trans } from '@lingui/react/macro';
|
||||||
@ -25,7 +25,7 @@ export const ObjectOptionsDropdown = ({
|
|||||||
viewType,
|
viewType,
|
||||||
}: ObjectOptionsDropdownProps) => {
|
}: ObjectOptionsDropdownProps) => {
|
||||||
const { currentContentId, handleContentChange, handleResetContent } =
|
const { currentContentId, handleContentChange, handleResetContent } =
|
||||||
useCurrentContentId<ObjectOptionsContentId>();
|
useDropdownContextCurrentContentId<ObjectOptionsContentId>();
|
||||||
|
|
||||||
const { isDropdownOpen } = useDropdown(OBJECT_OPTIONS_DROPDOWN_ID);
|
const { isDropdownOpen } = useDropdown(OBJECT_OPTIONS_DROPDOWN_ID);
|
||||||
const {
|
const {
|
||||||
|
|||||||
@ -7,10 +7,10 @@ import { ObjectOptionsDropdownMenuContent } from '@/object-record/object-options
|
|||||||
import { ObjectOptionsDropdownRecordGroupFieldsContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupFieldsContent';
|
import { ObjectOptionsDropdownRecordGroupFieldsContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupFieldsContent';
|
||||||
import { ObjectOptionsDropdownRecordGroupsContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupsContent';
|
import { ObjectOptionsDropdownRecordGroupsContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupsContent';
|
||||||
import { ObjectOptionsDropdownRecordGroupSortContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupSortContent';
|
import { ObjectOptionsDropdownRecordGroupSortContent } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupSortContent';
|
||||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
|
||||||
|
|
||||||
export const ObjectOptionsDropdownContent = () => {
|
export const ObjectOptionsDropdownContent = () => {
|
||||||
const { currentContentId } = useOptionsDropdown();
|
const { currentContentId } = useObjectOptionsDropdown();
|
||||||
|
|
||||||
switch (currentContentId) {
|
switch (currentContentId) {
|
||||||
case 'layout':
|
case 'layout':
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
|
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
|
||||||
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
|
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
|
||||||
import { useObjectOptionsForTable } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForTable';
|
import { useObjectOptionsForTable } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForTable';
|
||||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
|
||||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||||
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
|
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
|
||||||
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
|
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
|
||||||
@ -20,7 +20,7 @@ export const ObjectOptionsDropdownFieldsContent = () => {
|
|||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
onContentChange,
|
onContentChange,
|
||||||
resetContent,
|
resetContent,
|
||||||
} = useOptionsDropdown();
|
} = useObjectOptionsDropdown();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
handleColumnVisibilityChange,
|
handleColumnVisibilityChange,
|
||||||
|
|||||||
@ -3,9 +3,9 @@ import { useSetRecoilState } from 'recoil';
|
|||||||
|
|
||||||
import { useObjectNamePluralFromSingular } from '@/object-metadata/hooks/useObjectNamePluralFromSingular';
|
import { useObjectNamePluralFromSingular } from '@/object-metadata/hooks/useObjectNamePluralFromSingular';
|
||||||
|
|
||||||
|
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
|
||||||
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
|
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
|
||||||
import { useObjectOptionsForTable } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForTable';
|
import { useObjectOptionsForTable } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForTable';
|
||||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
|
||||||
import { SettingsPath } from '@/types/SettingsPath';
|
import { SettingsPath } from '@/types/SettingsPath';
|
||||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||||
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
|
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
|
||||||
@ -28,7 +28,7 @@ export const ObjectOptionsDropdownHiddenFieldsContent = () => {
|
|||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
onContentChange,
|
onContentChange,
|
||||||
closeDropdown,
|
closeDropdown,
|
||||||
} = useOptionsDropdown();
|
} = useObjectOptionsDropdown();
|
||||||
|
|
||||||
const { objectNamePlural } = useObjectNamePluralFromSingular({
|
const { objectNamePlural } = useObjectNamePluralFromSingular({
|
||||||
objectNameSingular: objectMetadataItem.nameSingular,
|
objectNameSingular: objectMetadataItem.nameSingular,
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { useEffect } from 'react';
|
|||||||
|
|
||||||
import { useObjectNamePluralFromSingular } from '@/object-metadata/hooks/useObjectNamePluralFromSingular';
|
import { useObjectNamePluralFromSingular } from '@/object-metadata/hooks/useObjectNamePluralFromSingular';
|
||||||
|
|
||||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
|
||||||
import { RecordGroupsVisibilityDropdownSection } from '@/object-record/record-group/components/RecordGroupsVisibilityDropdownSection';
|
import { RecordGroupsVisibilityDropdownSection } from '@/object-record/record-group/components/RecordGroupsVisibilityDropdownSection';
|
||||||
import { useRecordGroupVisibility } from '@/object-record/record-group/hooks/useRecordGroupVisibility';
|
import { useRecordGroupVisibility } from '@/object-record/record-group/hooks/useRecordGroupVisibility';
|
||||||
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
||||||
@ -30,7 +30,7 @@ export const ObjectOptionsDropdownHiddenRecordGroupsContent = () => {
|
|||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
onContentChange,
|
onContentChange,
|
||||||
closeDropdown,
|
closeDropdown,
|
||||||
} = useOptionsDropdown();
|
} = useObjectOptionsDropdown();
|
||||||
|
|
||||||
const recordGroupFieldMetadata = useRecoilComponentValueV2(
|
const recordGroupFieldMetadata = useRecoilComponentValueV2(
|
||||||
recordGroupFieldMetadataComponentState,
|
recordGroupFieldMetadataComponentState,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
|
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
|
||||||
|
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
|
||||||
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
|
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
|
||||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
|
||||||
import { useSetViewTypeFromLayoutOptionsMenu } from '@/object-record/object-options-dropdown/hooks/useSetViewTypeFromLayoutOptionsMenu';
|
import { useSetViewTypeFromLayoutOptionsMenu } from '@/object-record/object-options-dropdown/hooks/useSetViewTypeFromLayoutOptionsMenu';
|
||||||
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
||||||
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
|
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
|
||||||
@ -43,7 +43,7 @@ export const ObjectOptionsDropdownLayoutContent = () => {
|
|||||||
resetContent,
|
resetContent,
|
||||||
onContentChange,
|
onContentChange,
|
||||||
dropdownId,
|
dropdownId,
|
||||||
} = useOptionsDropdown();
|
} = useObjectOptionsDropdown();
|
||||||
|
|
||||||
const { isCompactModeActive, setAndPersistIsCompactModeActive } =
|
const { isCompactModeActive, setAndPersistIsCompactModeActive } =
|
||||||
useObjectOptionsForBoard({
|
useObjectOptionsForBoard({
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
|
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
|
||||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
|
||||||
import { useUpdateObjectViewOptions } from '@/object-record/object-options-dropdown/hooks/useUpdateObjectViewOptions';
|
import { useUpdateObjectViewOptions } from '@/object-record/object-options-dropdown/hooks/useUpdateObjectViewOptions';
|
||||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||||
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
|
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
|
||||||
@ -25,7 +25,7 @@ import {
|
|||||||
import { MenuItemSelect } from 'twenty-ui/navigation';
|
import { MenuItemSelect } from 'twenty-ui/navigation';
|
||||||
|
|
||||||
export const ObjectOptionsDropdownLayoutOpenInContent = () => {
|
export const ObjectOptionsDropdownLayoutOpenInContent = () => {
|
||||||
const { onContentChange } = useOptionsDropdown();
|
const { onContentChange } = useObjectOptionsDropdown();
|
||||||
const recordIndexOpenRecordIn = useRecoilValue(recordIndexOpenRecordInState);
|
const recordIndexOpenRecordIn = useRecoilValue(recordIndexOpenRecordInState);
|
||||||
const { currentView } = useGetCurrentViewOnly();
|
const { currentView } = useGetCurrentViewOnly();
|
||||||
const { setAndPersistOpenRecordIn } = useUpdateObjectViewOptions();
|
const { setAndPersistOpenRecordIn } = useUpdateObjectViewOptions();
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { ObjectOptionsDropdownMenuViewName } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownMenuViewName';
|
import { ObjectOptionsDropdownMenuViewName } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownMenuViewName';
|
||||||
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
|
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
|
||||||
|
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
|
||||||
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
|
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
|
||||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
|
||||||
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
||||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||||
@ -33,7 +33,7 @@ import { MenuItem } from 'twenty-ui/navigation';
|
|||||||
export const ObjectOptionsDropdownMenuContent = () => {
|
export const ObjectOptionsDropdownMenuContent = () => {
|
||||||
const { t } = useLingui();
|
const { t } = useLingui();
|
||||||
const { recordIndexId, objectMetadataItem, onContentChange, closeDropdown } =
|
const { recordIndexId, objectMetadataItem, onContentChange, closeDropdown } =
|
||||||
useOptionsDropdown();
|
useObjectOptionsDropdown();
|
||||||
|
|
||||||
const { currentView } = useGetCurrentViewOnly();
|
const { currentView } = useGetCurrentViewOnly();
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { useEffect } from 'react';
|
|||||||
import { useObjectNamePluralFromSingular } from '@/object-metadata/hooks/useObjectNamePluralFromSingular';
|
import { useObjectNamePluralFromSingular } from '@/object-metadata/hooks/useObjectNamePluralFromSingular';
|
||||||
|
|
||||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
|
||||||
import { useSearchRecordGroupField } from '@/object-record/object-options-dropdown/hooks/useSearchRecordGroupField';
|
import { useSearchRecordGroupField } from '@/object-record/object-options-dropdown/hooks/useSearchRecordGroupField';
|
||||||
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
||||||
import { hiddenRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/hiddenRecordGroupIdsComponentSelector';
|
import { hiddenRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/hiddenRecordGroupIdsComponentSelector';
|
||||||
@ -42,7 +42,7 @@ export const ObjectOptionsDropdownRecordGroupFieldsContent = () => {
|
|||||||
onContentChange,
|
onContentChange,
|
||||||
resetContent,
|
resetContent,
|
||||||
closeDropdown,
|
closeDropdown,
|
||||||
} = useOptionsDropdown();
|
} = useObjectOptionsDropdown();
|
||||||
|
|
||||||
const { objectNamePlural } = useObjectNamePluralFromSingular({
|
const { objectNamePlural } = useObjectNamePluralFromSingular({
|
||||||
objectNameSingular: objectMetadataItem.nameSingular,
|
objectNameSingular: objectMetadataItem.nameSingular,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
|
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
|
||||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
|
||||||
import { hiddenRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/hiddenRecordGroupIdsComponentSelector';
|
import { hiddenRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/hiddenRecordGroupIdsComponentSelector';
|
||||||
import { RecordGroupSort } from '@/object-record/record-group/types/RecordGroupSort';
|
import { RecordGroupSort } from '@/object-record/record-group/types/RecordGroupSort';
|
||||||
import { recordIndexRecordGroupSortComponentState } from '@/object-record/record-index/states/recordIndexRecordGroupSortComponentState';
|
import { recordIndexRecordGroupSortComponentState } from '@/object-record/record-index/states/recordIndexRecordGroupSortComponentState';
|
||||||
@ -24,7 +24,7 @@ import {
|
|||||||
import { MenuItemSelect } from 'twenty-ui/navigation';
|
import { MenuItemSelect } from 'twenty-ui/navigation';
|
||||||
|
|
||||||
export const ObjectOptionsDropdownRecordGroupSortContent = () => {
|
export const ObjectOptionsDropdownRecordGroupSortContent = () => {
|
||||||
const { currentContentId, onContentChange } = useOptionsDropdown();
|
const { currentContentId, onContentChange } = useObjectOptionsDropdown();
|
||||||
|
|
||||||
const hiddenRecordGroupIds = useRecoilComponentValueV2(
|
const hiddenRecordGroupIds = useRecoilComponentValueV2(
|
||||||
hiddenRecordGroupIdsComponentSelector,
|
hiddenRecordGroupIdsComponentSelector,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
|
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
|
||||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
|
||||||
import { RecordGroupsVisibilityDropdownSection } from '@/object-record/record-group/components/RecordGroupsVisibilityDropdownSection';
|
import { RecordGroupsVisibilityDropdownSection } from '@/object-record/record-group/components/RecordGroupsVisibilityDropdownSection';
|
||||||
import { useRecordGroupVisibility } from '@/object-record/record-group/hooks/useRecordGroupVisibility';
|
import { useRecordGroupVisibility } from '@/object-record/record-group/hooks/useRecordGroupVisibility';
|
||||||
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
||||||
@ -43,7 +43,7 @@ export const ObjectOptionsDropdownRecordGroupsContent = () => {
|
|||||||
onContentChange,
|
onContentChange,
|
||||||
resetContent,
|
resetContent,
|
||||||
handleRecordGroupOrderChangeWithModal,
|
handleRecordGroupOrderChangeWithModal,
|
||||||
} = useOptionsDropdown();
|
} = useObjectOptionsDropdown();
|
||||||
|
|
||||||
const { currentView } = useGetCurrentViewOnly();
|
const { currentView } = useGetCurrentViewOnly();
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { act } from 'react';
|
|||||||
|
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
|
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
|
||||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
|
||||||
import { ObjectOptionsDropdownContext } from '@/object-record/object-options-dropdown/states/contexts/ObjectOptionsDropdownContext';
|
import { ObjectOptionsDropdownContext } from '@/object-record/object-options-dropdown/states/contexts/ObjectOptionsDropdownContext';
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { ViewType } from '@/views/types/ViewType';
|
import { ViewType } from '@/views/types/ViewType';
|
||||||
@ -61,7 +61,7 @@ describe('useOptionsDropdown', () => {
|
|||||||
{children}
|
{children}
|
||||||
</ObjectOptionsDropdownContext.Provider>
|
</ObjectOptionsDropdownContext.Provider>
|
||||||
);
|
);
|
||||||
return renderHook(() => useOptionsDropdown(), { wrapper });
|
return renderHook(() => useObjectOptionsDropdown(), { wrapper });
|
||||||
};
|
};
|
||||||
|
|
||||||
it('provides closeDropdown functionality from the context', () => {
|
it('provides closeDropdown functionality from the context', () => {
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
import { useDropdown } from '@/dropdown/hooks/useDropdown';
|
import { useDropdownContextStateManagement } from '@/dropdown-context-state-management/hooks/useDropdownContextStateManagement';
|
||||||
import { ObjectOptionsDropdownContext } from '@/object-record/object-options-dropdown/states/contexts/ObjectOptionsDropdownContext';
|
import { ObjectOptionsDropdownContext } from '@/object-record/object-options-dropdown/states/contexts/ObjectOptionsDropdownContext';
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
|
|
||||||
export const useOptionsDropdown = () => {
|
export const useObjectOptionsDropdown = () => {
|
||||||
const context = useContext(ObjectOptionsDropdownContext);
|
const context = useContext(ObjectOptionsDropdownContext);
|
||||||
|
|
||||||
if (!context) {
|
if (!context) {
|
||||||
throw new Error('useOptionsDropdown must be used within a context');
|
throw new Error('useObjectOptionsDropdown must be used within a context');
|
||||||
}
|
}
|
||||||
|
|
||||||
const { closeDropdown } = useDropdown({
|
const { closeDropdown } = useDropdownContextStateManagement({
|
||||||
context: ObjectOptionsDropdownContext,
|
context: ObjectOptionsDropdownContext,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -4,7 +4,6 @@ import { useContext, useRef } from 'react';
|
|||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
import { ACTION_MENU_DROPDOWN_CLICK_OUTSIDE_ID } from '@/action-menu/constants/ActionMenuDropdownClickOutsideId';
|
import { ACTION_MENU_DROPDOWN_CLICK_OUTSIDE_ID } from '@/action-menu/constants/ActionMenuDropdownClickOutsideId';
|
||||||
import { getActionMenuIdFromRecordIndexId } from '@/action-menu/utils/getActionMenuIdFromRecordIndexId';
|
|
||||||
import { COMMAND_MENU_CLICK_OUTSIDE_ID } from '@/command-menu/constants/CommandMenuClickOutsideId';
|
import { COMMAND_MENU_CLICK_OUTSIDE_ID } from '@/command-menu/constants/CommandMenuClickOutsideId';
|
||||||
import { RecordBoardHeader } from '@/object-record/record-board/components/RecordBoardHeader';
|
import { RecordBoardHeader } from '@/object-record/record-board/components/RecordBoardHeader';
|
||||||
import { RecordBoardScrollToFocusedCardEffect } from '@/object-record/record-board/components/RecordBoardScrollToFocusedCardEffect';
|
import { RecordBoardScrollToFocusedCardEffect } from '@/object-record/record-board/components/RecordBoardScrollToFocusedCardEffect';
|
||||||
@ -26,7 +25,7 @@ import { RECORD_INDEX_REMOVE_SORTING_MODAL_ID } from '@/object-record/record-ind
|
|||||||
import { recordIndexRecordIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRecordIdsByGroupComponentFamilyState';
|
import { recordIndexRecordIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRecordIdsByGroupComponentFamilyState';
|
||||||
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
|
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
|
||||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2';
|
import { useCloseAnyOpenDropdown } from '@/ui/layout/dropdown/hooks/useCloseAnyOpenDropdown';
|
||||||
import { MODAL_BACKDROP_CLICK_OUTSIDE_ID } from '@/ui/layout/modal/constants/ModalBackdropClickOutsideId';
|
import { MODAL_BACKDROP_CLICK_OUTSIDE_ID } from '@/ui/layout/modal/constants/ModalBackdropClickOutsideId';
|
||||||
import { useModal } from '@/ui/layout/modal/hooks/useModal';
|
import { useModal } from '@/ui/layout/modal/hooks/useModal';
|
||||||
import { PAGE_ACTION_CONTAINER_CLICK_OUTSIDE_ID } from '@/ui/layout/page/constants/PageActionContainerClickOutsideId';
|
import { PAGE_ACTION_CONTAINER_CLICK_OUTSIDE_ID } from '@/ui/layout/page/constants/PageActionContainerClickOutsideId';
|
||||||
@ -81,15 +80,13 @@ export const RecordBoard = () => {
|
|||||||
RECORD_BOARD_CLICK_OUTSIDE_LISTENER_ID,
|
RECORD_BOARD_CLICK_OUTSIDE_LISTENER_ID,
|
||||||
);
|
);
|
||||||
|
|
||||||
const actionMenuId = getActionMenuIdFromRecordIndexId(recordBoardId);
|
const { closeAnyOpenDropdown } = useCloseAnyOpenDropdown();
|
||||||
|
|
||||||
const { closeDropdown } = useDropdownV2();
|
|
||||||
|
|
||||||
const { deactivateBoardCard } = useActiveRecordBoardCard(recordBoardId);
|
const { deactivateBoardCard } = useActiveRecordBoardCard(recordBoardId);
|
||||||
const { unfocusBoardCard } = useFocusedRecordBoardCard(recordBoardId);
|
const { unfocusBoardCard } = useFocusedRecordBoardCard(recordBoardId);
|
||||||
|
|
||||||
const handleDragSelectionStart = () => {
|
const handleDragSelectionStart = () => {
|
||||||
closeDropdown(actionMenuId);
|
closeAnyOpenDropdown();
|
||||||
|
|
||||||
toggleClickOutside(false);
|
toggleClickOutside(false);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { getActionMenuIdFromRecordIndexId } from '@/action-menu/utils/getActionM
|
|||||||
import { RecordBoardComponentInstanceContext } from '@/object-record/record-board/states/contexts/RecordBoardComponentInstanceContext';
|
import { RecordBoardComponentInstanceContext } from '@/object-record/record-board/states/contexts/RecordBoardComponentInstanceContext';
|
||||||
import { isRecordBoardCardSelectedComponentFamilyState } from '@/object-record/record-board/states/isRecordBoardCardSelectedComponentFamilyState';
|
import { isRecordBoardCardSelectedComponentFamilyState } from '@/object-record/record-board/states/isRecordBoardCardSelectedComponentFamilyState';
|
||||||
import { recordBoardSelectedRecordIdsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardSelectedRecordIdsComponentSelector';
|
import { recordBoardSelectedRecordIdsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardSelectedRecordIdsComponentSelector';
|
||||||
import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2';
|
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||||
@ -28,7 +28,7 @@ export const useRecordBoardSelection = (recordBoardId?: string) => {
|
|||||||
recordBoardId,
|
recordBoardId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { closeDropdown } = useDropdownV2();
|
const { closeDropdown } = useCloseDropdown();
|
||||||
|
|
||||||
const dropdownId = getActionMenuDropdownIdFromActionMenuId(
|
const dropdownId = getActionMenuDropdownIdFromActionMenuId(
|
||||||
getActionMenuIdFromRecordIndexId(instanceIdFromProps),
|
getActionMenuIdFromRecordIndexId(instanceIdFromProps),
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import { RecordBoardCardBody } from '@/object-record/record-board/record-board-c
|
|||||||
import { RecordBoardCardHeader } from '@/object-record/record-board/record-board-card/components/RecordBoardCardHeader';
|
import { RecordBoardCardHeader } from '@/object-record/record-board/record-board-card/components/RecordBoardCardHeader';
|
||||||
import { RECORD_BOARD_CARD_CLICK_OUTSIDE_ID } from '@/object-record/record-board/record-board-card/constants/RecordBoardCardClickOutsideId';
|
import { RECORD_BOARD_CARD_CLICK_OUTSIDE_ID } from '@/object-record/record-board/record-board-card/constants/RecordBoardCardClickOutsideId';
|
||||||
import { useOpenRecordFromIndexView } from '@/object-record/record-index/hooks/useOpenRecordFromIndexView';
|
import { useOpenRecordFromIndexView } from '@/object-record/record-index/hooks/useOpenRecordFromIndexView';
|
||||||
import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2';
|
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
|
||||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||||
import { useScrollWrapperElement } from '@/ui/utilities/scroll/hooks/useScrollWrapperElement';
|
import { useScrollWrapperElement } from '@/ui/utilities/scroll/hooks/useScrollWrapperElement';
|
||||||
import { useRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyStateV2';
|
import { useRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyStateV2';
|
||||||
@ -140,22 +140,25 @@ export const RecordBoardCard = () => {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
const { openDropdown } = useDropdownV2();
|
const { openDropdown } = useOpenDropdown();
|
||||||
|
|
||||||
const { openRecordFromIndexView } = useOpenRecordFromIndexView();
|
const { openRecordFromIndexView } = useOpenRecordFromIndexView();
|
||||||
const { activateBoardCard } = useActiveRecordBoardCard(recordBoardId);
|
const { activateBoardCard } = useActiveRecordBoardCard(recordBoardId);
|
||||||
const { unfocusBoardCard } = useFocusedRecordBoardCard(recordBoardId);
|
const { unfocusBoardCard } = useFocusedRecordBoardCard(recordBoardId);
|
||||||
|
|
||||||
const handleActionMenuDropdown = (event: React.MouseEvent) => {
|
const handleContextMenuOpen = (event: React.MouseEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
setIsCurrentCardSelected(true);
|
setIsCurrentCardSelected(true);
|
||||||
setActionMenuDropdownPosition({
|
setActionMenuDropdownPosition({
|
||||||
x: event.clientX,
|
x: event.clientX,
|
||||||
y: event.clientY,
|
y: event.clientY,
|
||||||
});
|
});
|
||||||
openDropdown(actionMenuDropdownId, {
|
openDropdown({
|
||||||
enableGlobalHotkeysWithModifiers: true,
|
dropdownComponentInstanceIdFromProps: actionMenuDropdownId,
|
||||||
enableGlobalHotkeysConflictingWithKeyboard: false,
|
globalHotkeysConfig: {
|
||||||
|
enableGlobalHotkeysWithModifiers: true,
|
||||||
|
enableGlobalHotkeysConflictingWithKeyboard: false,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -185,7 +188,7 @@ export const RecordBoardCard = () => {
|
|||||||
return (
|
return (
|
||||||
<StyledBoardCardWrapper
|
<StyledBoardCardWrapper
|
||||||
data-click-outside-id={RECORD_BOARD_CARD_CLICK_OUTSIDE_ID}
|
data-click-outside-id={RECORD_BOARD_CARD_CLICK_OUTSIDE_ID}
|
||||||
onContextMenu={handleActionMenuDropdown}
|
onContextMenu={handleContextMenuOpen}
|
||||||
>
|
>
|
||||||
<InView>
|
<InView>
|
||||||
<StyledBoardCard
|
<StyledBoardCard
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { DROPDOWN_OFFSET_Y } from '@/dropdown/constants/DropdownOffsetY';
|
import { useDropdownContextCurrentContentId } from '@/dropdown-context-state-management/hooks/useDropdownContextCurrentContentId';
|
||||||
import { useCurrentContentId } from '@/dropdown/hooks/useCurrentContentId';
|
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { RecordBoardColumnHeaderAggregateDropdownComponentInstanceContext } from '@/object-record/record-board/contexts/RecordBoardColumnHeaderAggregateDropdownComponentInstanceContext';
|
import { RecordBoardColumnHeaderAggregateDropdownComponentInstanceContext } from '@/object-record/record-board/contexts/RecordBoardColumnHeaderAggregateDropdownComponentInstanceContext';
|
||||||
import { RecordBoardColumnHeaderAggregateDropdownButton } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownButton';
|
import { RecordBoardColumnHeaderAggregateDropdownButton } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownButton';
|
||||||
@ -7,6 +6,7 @@ import { AggregateDropdownContent } from '@/object-record/record-board/record-bo
|
|||||||
import { RecordBoardColumnHeaderAggregateDropdownContext } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownContext';
|
import { RecordBoardColumnHeaderAggregateDropdownContext } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownContext';
|
||||||
import { RecordBoardColumnHeaderAggregateContentId } from '@/object-record/record-board/types/RecordBoardColumnHeaderAggregateContentId';
|
import { RecordBoardColumnHeaderAggregateContentId } from '@/object-record/record-board/types/RecordBoardColumnHeaderAggregateContentId';
|
||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
|
import { DROPDOWN_OFFSET_Y } from '@/ui/layout/dropdown/constants/DropdownOffsetY';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
type RecordBoardColumnHeaderAggregateDropdownProps = {
|
type RecordBoardColumnHeaderAggregateDropdownProps = {
|
||||||
@ -31,7 +31,8 @@ export const RecordBoardColumnHeaderAggregateDropdown = ({
|
|||||||
handleContentChange,
|
handleContentChange,
|
||||||
handleResetContent,
|
handleResetContent,
|
||||||
previousContentId,
|
previousContentId,
|
||||||
} = useCurrentContentId<RecordBoardColumnHeaderAggregateContentId>();
|
} =
|
||||||
|
useDropdownContextCurrentContentId<RecordBoardColumnHeaderAggregateContentId>();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordBoardColumnHeaderAggregateDropdownComponentInstanceContext.Provider
|
<RecordBoardColumnHeaderAggregateDropdownComponentInstanceContext.Provider
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useDropdown } from '@/dropdown/hooks/useDropdown';
|
import { useDropdownContextStateManagement } from '@/dropdown-context-state-management/hooks/useDropdownContextStateManagement';
|
||||||
import { RecordBoardColumnHeaderAggregateDropdownContext } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownContext';
|
import { RecordBoardColumnHeaderAggregateDropdownContext } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownContext';
|
||||||
import { RecordBoardColumnHeaderAggregateDropdownFieldsContent } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownFieldsContent';
|
import { RecordBoardColumnHeaderAggregateDropdownFieldsContent } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownFieldsContent';
|
||||||
import { RecordBoardColumnHeaderAggregateDropdownMenuContent } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownMenuContent';
|
import { RecordBoardColumnHeaderAggregateDropdownMenuContent } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownMenuContent';
|
||||||
@ -12,9 +12,10 @@ import { getAvailableFieldsIdsForAggregationFromObjectFields } from '@/object-re
|
|||||||
import { t } from '@lingui/core/macro';
|
import { t } from '@lingui/core/macro';
|
||||||
|
|
||||||
export const AggregateDropdownContent = () => {
|
export const AggregateDropdownContent = () => {
|
||||||
const { currentContentId, objectMetadataItem } = useDropdown({
|
const { currentContentId, objectMetadataItem } =
|
||||||
context: RecordBoardColumnHeaderAggregateDropdownContext,
|
useDropdownContextStateManagement({
|
||||||
});
|
context: RecordBoardColumnHeaderAggregateDropdownContext,
|
||||||
|
});
|
||||||
|
|
||||||
switch (currentContentId) {
|
switch (currentContentId) {
|
||||||
case 'countAggregateOperationsOptions': {
|
case 'countAggregateOperationsOptions': {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useDropdown } from '@/dropdown/hooks/useDropdown';
|
import { useDropdownContextStateManagement } from '@/dropdown-context-state-management/hooks/useDropdownContextStateManagement';
|
||||||
import { RecordBoardColumnHeaderAggregateDropdownContext } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownContext';
|
import { RecordBoardColumnHeaderAggregateDropdownContext } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownContext';
|
||||||
import { aggregateOperationComponentState } from '@/object-record/record-board/record-board-column/states/aggregateOperationComponentState';
|
import { aggregateOperationComponentState } from '@/object-record/record-board/record-board-column/states/aggregateOperationComponentState';
|
||||||
import { availableFieldIdsForAggregateOperationComponentState } from '@/object-record/record-board/record-board-column/states/availableFieldIdsForAggregateOperationComponentState';
|
import { availableFieldIdsForAggregateOperationComponentState } from '@/object-record/record-board/record-board-column/states/availableFieldIdsForAggregateOperationComponentState';
|
||||||
@ -27,7 +27,7 @@ export const RecordBoardColumnHeaderAggregateDropdownFieldsContent = () => {
|
|||||||
onContentChange,
|
onContentChange,
|
||||||
resetContent,
|
resetContent,
|
||||||
previousContentId,
|
previousContentId,
|
||||||
} = useDropdown({
|
} = useDropdownContextStateManagement({
|
||||||
context: RecordBoardColumnHeaderAggregateDropdownContext,
|
context: RecordBoardColumnHeaderAggregateDropdownContext,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
import { useDropdown } from '@/dropdown/hooks/useDropdown';
|
import { useDropdownContextStateManagement } from '@/dropdown-context-state-management/hooks/useDropdownContextStateManagement';
|
||||||
import {
|
import {
|
||||||
RecordBoardColumnHeaderAggregateDropdownContext,
|
RecordBoardColumnHeaderAggregateDropdownContext,
|
||||||
RecordBoardColumnHeaderAggregateDropdownContextValue,
|
RecordBoardColumnHeaderAggregateDropdownContextValue,
|
||||||
@ -17,9 +17,11 @@ export const RecordBoardColumnHeaderAggregateDropdownMenuContent = () => {
|
|||||||
const { t } = useLingui();
|
const { t } = useLingui();
|
||||||
|
|
||||||
const { onContentChange, closeDropdown } =
|
const { onContentChange, closeDropdown } =
|
||||||
useDropdown<RecordBoardColumnHeaderAggregateDropdownContextValue>({
|
useDropdownContextStateManagement<RecordBoardColumnHeaderAggregateDropdownContextValue>(
|
||||||
context: RecordBoardColumnHeaderAggregateDropdownContext,
|
{
|
||||||
});
|
context: RecordBoardColumnHeaderAggregateDropdownContext,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
[Key.Escape],
|
[Key.Escape],
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useDropdown } from '@/dropdown/hooks/useDropdown';
|
import { useDropdownContextStateManagement } from '@/dropdown-context-state-management/hooks/useDropdownContextStateManagement';
|
||||||
import {
|
import {
|
||||||
RecordBoardColumnHeaderAggregateDropdownContext,
|
RecordBoardColumnHeaderAggregateDropdownContext,
|
||||||
RecordBoardColumnHeaderAggregateDropdownContextValue,
|
RecordBoardColumnHeaderAggregateDropdownContextValue,
|
||||||
@ -32,9 +32,11 @@ export const RecordBoardColumnHeaderAggregateDropdownOptionsContent = ({
|
|||||||
title: string;
|
title: string;
|
||||||
}) => {
|
}) => {
|
||||||
const { onContentChange, closeDropdown, resetContent } =
|
const { onContentChange, closeDropdown, resetContent } =
|
||||||
useDropdown<RecordBoardColumnHeaderAggregateDropdownContextValue>({
|
useDropdownContextStateManagement<RecordBoardColumnHeaderAggregateDropdownContextValue>(
|
||||||
context: RecordBoardColumnHeaderAggregateDropdownContext,
|
{
|
||||||
});
|
context: RecordBoardColumnHeaderAggregateDropdownContext,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
[Key.Escape],
|
[Key.Escape],
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useDropdown } from '@/dropdown/hooks/useDropdown';
|
import { useDropdownContextStateManagement } from '@/dropdown-context-state-management/hooks/useDropdownContextStateManagement';
|
||||||
import { AggregateOperations } from '@/object-record/record-table/constants/AggregateOperations';
|
import { AggregateOperations } from '@/object-record/record-table/constants/AggregateOperations';
|
||||||
import { DateAggregateOperations } from '@/object-record/record-table/constants/DateAggregateOperations';
|
import { DateAggregateOperations } from '@/object-record/record-table/constants/DateAggregateOperations';
|
||||||
import { RecordTableColumnAggregateFooterDropdownSubmenuContent } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateDropdownSubmenuContent';
|
import { RecordTableColumnAggregateFooterDropdownSubmenuContent } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateDropdownSubmenuContent';
|
||||||
@ -14,9 +14,10 @@ import { useLingui } from '@lingui/react/macro';
|
|||||||
|
|
||||||
export const RecordTableColumnAggregateFooterDropdownContent = () => {
|
export const RecordTableColumnAggregateFooterDropdownContent = () => {
|
||||||
const { t } = useLingui();
|
const { t } = useLingui();
|
||||||
const { currentContentId, fieldMetadataType } = useDropdown({
|
const { currentContentId, fieldMetadataType } =
|
||||||
context: RecordTableColumnAggregateFooterDropdownContext,
|
useDropdownContextStateManagement({
|
||||||
});
|
context: RecordTableColumnAggregateFooterDropdownContext,
|
||||||
|
});
|
||||||
|
|
||||||
const availableAggregateOperations =
|
const availableAggregateOperations =
|
||||||
getAvailableAggregateOperationsForFieldMetadataType({
|
getAvailableAggregateOperationsForFieldMetadataType({
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useCurrentContentId } from '@/dropdown/hooks/useCurrentContentId';
|
import { useDropdownContextCurrentContentId } from '@/dropdown-context-state-management/hooks/useDropdownContextCurrentContentId';
|
||||||
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||||
import { RecordTableColumnAggregateFooterCellContext } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterCellContext';
|
import { RecordTableColumnAggregateFooterCellContext } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterCellContext';
|
||||||
import { RecordTableColumnAggregateFooterDropdownContent } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterDropdownContent';
|
import { RecordTableColumnAggregateFooterDropdownContent } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterDropdownContent';
|
||||||
@ -19,7 +19,7 @@ export const RecordTableColumnFooterWithDropdown = ({
|
|||||||
isFirstCell,
|
isFirstCell,
|
||||||
}: RecordTableColumnFooterWithDropdownProps) => {
|
}: RecordTableColumnFooterWithDropdownProps) => {
|
||||||
const { currentContentId, handleContentChange, handleResetContent } =
|
const { currentContentId, handleContentChange, handleResetContent } =
|
||||||
useCurrentContentId<RecordTableFooterAggregateContentId>();
|
useDropdownContextCurrentContentId<RecordTableFooterAggregateContentId>();
|
||||||
|
|
||||||
const { fieldMetadataId } = useContext(
|
const { fieldMetadataId } = useContext(
|
||||||
RecordTableColumnAggregateFooterCellContext,
|
RecordTableColumnAggregateFooterCellContext,
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { useCreateEmptyRecordFilterFromFieldMetadataItem } from '@/object-record
|
|||||||
import { useFilterableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext';
|
import { useFilterableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext';
|
||||||
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
|
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
|
||||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2';
|
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useSetEditableFilterChipDropdownStates } from '@/views/hooks/useSetEditableFilterChipDropdownStates';
|
import { useSetEditableFilterChipDropdownStates } from '@/views/hooks/useSetEditableFilterChipDropdownStates';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
@ -20,7 +20,7 @@ export const useOpenRecordFilterChipFromTableHeader = () => {
|
|||||||
|
|
||||||
const { upsertRecordFilter } = useUpsertRecordFilter();
|
const { upsertRecordFilter } = useUpsertRecordFilter();
|
||||||
|
|
||||||
const { openDropdown } = useDropdownV2();
|
const { openDropdown } = useOpenDropdown();
|
||||||
|
|
||||||
const { setEditableFilterChipDropdownStates } =
|
const { setEditableFilterChipDropdownStates } =
|
||||||
useSetEditableFilterChipDropdownStates();
|
useSetEditableFilterChipDropdownStates();
|
||||||
@ -45,7 +45,10 @@ export const useOpenRecordFilterChipFromTableHeader = () => {
|
|||||||
|
|
||||||
if (isDefined(existingNonAdvancedRecordFilter)) {
|
if (isDefined(existingNonAdvancedRecordFilter)) {
|
||||||
setEditableFilterChipDropdownStates(existingNonAdvancedRecordFilter);
|
setEditableFilterChipDropdownStates(existingNonAdvancedRecordFilter);
|
||||||
openDropdown(existingNonAdvancedRecordFilter.id);
|
openDropdown({
|
||||||
|
dropdownComponentInstanceIdFromProps:
|
||||||
|
existingNonAdvancedRecordFilter.id,
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +59,7 @@ export const useOpenRecordFilterChipFromTableHeader = () => {
|
|||||||
upsertRecordFilter(newRecordFilter);
|
upsertRecordFilter(newRecordFilter);
|
||||||
|
|
||||||
setEditableFilterChipDropdownStates(newRecordFilter);
|
setEditableFilterChipDropdownStates(newRecordFilter);
|
||||||
openDropdown(newRecordFilter.id);
|
openDropdown({ dropdownComponentInstanceIdFromProps: newRecordFilter.id });
|
||||||
};
|
};
|
||||||
|
|
||||||
return { openRecordFilterChipFromTableHeader };
|
return { openRecordFilterChipFromTableHeader };
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { DropdownOnToggleEffect } from '@/ui/layout/dropdown/components/Dropdown
|
|||||||
import { DropdownInternalContainer } from '@/ui/layout/dropdown/components/internal/DropdownInternalContainer';
|
import { DropdownInternalContainer } from '@/ui/layout/dropdown/components/internal/DropdownInternalContainer';
|
||||||
import { DROPDOWN_RESIZE_MIN_HEIGHT } from '@/ui/layout/dropdown/constants/DropdownResizeMinHeight';
|
import { DROPDOWN_RESIZE_MIN_HEIGHT } from '@/ui/layout/dropdown/constants/DropdownResizeMinHeight';
|
||||||
import { DROPDOWN_RESIZE_MIN_WIDTH } from '@/ui/layout/dropdown/constants/DropdownResizeMinWidth';
|
import { DROPDOWN_RESIZE_MIN_WIDTH } from '@/ui/layout/dropdown/constants/DropdownResizeMinWidth';
|
||||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponeInstanceContext';
|
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||||
import { dropdownMaxHeightComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxHeightComponentState';
|
import { dropdownMaxHeightComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxHeightComponentState';
|
||||||
import { dropdownMaxWidthComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxWidthComponentState';
|
import { dropdownMaxWidthComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxWidthComponentState';
|
||||||
|
|||||||
@ -3,20 +3,36 @@ import { renderHook } from '@testing-library/react';
|
|||||||
import { act } from 'react';
|
import { act } from 'react';
|
||||||
import { RecoilRoot } from 'recoil';
|
import { RecoilRoot } from 'recoil';
|
||||||
|
|
||||||
|
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||||
import { useCloseAnyOpenDropdown } from '@/ui/layout/dropdown/hooks/useCloseAnyOpenDropdown';
|
import { useCloseAnyOpenDropdown } from '@/ui/layout/dropdown/hooks/useCloseAnyOpenDropdown';
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
|
||||||
|
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
|
|
||||||
const dropdownId = 'test-dropdown-id';
|
const dropdownId = 'test-dropdown-id';
|
||||||
|
|
||||||
const Wrapper = ({ children }: { children: React.ReactNode }) => {
|
const Wrapper = ({ children }: { children: React.ReactNode }) => {
|
||||||
return <RecoilRoot>{children}</RecoilRoot>;
|
return (
|
||||||
|
<RecoilRoot>
|
||||||
|
<DropdownComponentInstanceContext.Provider
|
||||||
|
value={{ instanceId: dropdownId }}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</DropdownComponentInstanceContext.Provider>
|
||||||
|
</RecoilRoot>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('useCloseAnyOpenDropdown', () => {
|
describe('useCloseAnyOpenDropdown', () => {
|
||||||
it('should open dropdown and then close it with closeAnyOpenDropdown', async () => {
|
it('should open dropdown and then close it with closeAnyOpenDropdown', async () => {
|
||||||
const { result } = renderHook(
|
const { result } = renderHook(
|
||||||
() => {
|
() => {
|
||||||
const { openDropdown, isDropdownOpen } = useDropdown(dropdownId);
|
const isDropdownOpen = useRecoilComponentValueV2(
|
||||||
|
isDropdownOpenComponentStateV2,
|
||||||
|
dropdownId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const { openDropdown } = useOpenDropdown();
|
||||||
|
|
||||||
const { closeAnyOpenDropdown } = useCloseAnyOpenDropdown();
|
const { closeAnyOpenDropdown } = useCloseAnyOpenDropdown();
|
||||||
|
|
||||||
|
|||||||
@ -1,43 +0,0 @@
|
|||||||
import { expect } from '@storybook/test';
|
|
||||||
import { renderHook } from '@testing-library/react';
|
|
||||||
import { act } from 'react';
|
|
||||||
import { RecoilRoot } from 'recoil';
|
|
||||||
|
|
||||||
import { useCloseDropdownFromOutside } from '@/ui/layout/dropdown/hooks/useCloseDropdownFromOutside';
|
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
|
||||||
|
|
||||||
const dropdownId = 'test-dropdown-id';
|
|
||||||
|
|
||||||
const Wrapper = ({ children }: { children: React.ReactNode }) => {
|
|
||||||
return <RecoilRoot>{children}</RecoilRoot>;
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('useCloseDropdownFromOutside', () => {
|
|
||||||
it('should close open dropdown', async () => {
|
|
||||||
const { result } = renderHook(
|
|
||||||
() => {
|
|
||||||
const { isDropdownOpen, openDropdown } = useDropdown(dropdownId);
|
|
||||||
const { closeDropdownFromOutside } = useCloseDropdownFromOutside();
|
|
||||||
|
|
||||||
return { closeDropdownFromOutside, isDropdownOpen, openDropdown };
|
|
||||||
},
|
|
||||||
{
|
|
||||||
wrapper: Wrapper,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(result.current.isDropdownOpen).toBe(false);
|
|
||||||
|
|
||||||
act(() => {
|
|
||||||
result.current.openDropdown();
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.current.isDropdownOpen).toBe(true);
|
|
||||||
|
|
||||||
act(() => {
|
|
||||||
result.current.closeDropdownFromOutside(dropdownId);
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.current.isDropdownOpen).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { useCloseDropdownFromOutside } from '@/ui/layout/dropdown/hooks/useCloseDropdownFromOutside';
|
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||||
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
|
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
|
||||||
import { previousDropdownFocusIdState } from '@/ui/layout/dropdown/states/previousDropdownFocusIdState';
|
import { previousDropdownFocusIdState } from '@/ui/layout/dropdown/states/previousDropdownFocusIdState';
|
||||||
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
|
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
|
||||||
@ -6,7 +6,7 @@ import { useRecoilCallback } from 'recoil';
|
|||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
export const useCloseAnyOpenDropdown = () => {
|
export const useCloseAnyOpenDropdown = () => {
|
||||||
const { closeDropdownFromOutside } = useCloseDropdownFromOutside();
|
const { closeDropdown } = useCloseDropdown();
|
||||||
|
|
||||||
const { removeFocusItemFromFocusStackById } =
|
const { removeFocusItemFromFocusStackById } =
|
||||||
useRemoveFocusItemFromFocusStackById();
|
useRemoveFocusItemFromFocusStackById();
|
||||||
@ -33,14 +33,14 @@ export const useCloseAnyOpenDropdown = () => {
|
|||||||
const thereIsOneNestedDropdownOpen = isDefined(previousDropdownFocusId);
|
const thereIsOneNestedDropdownOpen = isDefined(previousDropdownFocusId);
|
||||||
|
|
||||||
if (isDefined(activeDropdownFocusId)) {
|
if (isDefined(activeDropdownFocusId)) {
|
||||||
closeDropdownFromOutside(activeDropdownFocusId);
|
closeDropdown(activeDropdownFocusId);
|
||||||
removeFocusItemFromFocusStackById({
|
removeFocusItemFromFocusStackById({
|
||||||
focusId: activeDropdownFocusId,
|
focusId: activeDropdownFocusId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thereIsOneNestedDropdownOpen) {
|
if (thereIsOneNestedDropdownOpen) {
|
||||||
closeDropdownFromOutside(previousDropdownFocusId);
|
closeDropdown(previousDropdownFocusId);
|
||||||
removeFocusItemFromFocusStackById({
|
removeFocusItemFromFocusStackById({
|
||||||
focusId: previousDropdownFocusId,
|
focusId: previousDropdownFocusId,
|
||||||
});
|
});
|
||||||
@ -49,7 +49,7 @@ export const useCloseAnyOpenDropdown = () => {
|
|||||||
set(previousDropdownFocusIdState, null);
|
set(previousDropdownFocusIdState, null);
|
||||||
set(activeDropdownFocusIdState, null);
|
set(activeDropdownFocusIdState, null);
|
||||||
},
|
},
|
||||||
[closeDropdownFromOutside, removeFocusItemFromFocusStackById],
|
[closeDropdown, removeFocusItemFromFocusStackById],
|
||||||
);
|
);
|
||||||
|
|
||||||
return { closeAnyOpenDropdown };
|
return { closeAnyOpenDropdown };
|
||||||
|
|||||||
@ -0,0 +1,79 @@
|
|||||||
|
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||||
|
import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId';
|
||||||
|
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||||
|
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
|
||||||
|
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
|
||||||
|
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
|
||||||
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
|
export const useCloseDropdown = () => {
|
||||||
|
const { goBackToPreviousDropdownFocusId } =
|
||||||
|
useGoBackToPreviousDropdownFocusId();
|
||||||
|
|
||||||
|
const { removeFocusItemFromFocusStackById } =
|
||||||
|
useRemoveFocusItemFromFocusStackById();
|
||||||
|
|
||||||
|
const dropdownComponentInstanceIdFromContext =
|
||||||
|
useAvailableComponentInstanceId(DropdownComponentInstanceContext);
|
||||||
|
|
||||||
|
const closeDropdown = useRecoilCallback(
|
||||||
|
({ set, snapshot }) =>
|
||||||
|
(dropdownComponentInstanceIdFromProps?: string) => {
|
||||||
|
const dropdownComponentInstanceId =
|
||||||
|
dropdownComponentInstanceIdFromProps ??
|
||||||
|
dropdownComponentInstanceIdFromContext;
|
||||||
|
|
||||||
|
if (!isDefined(dropdownComponentInstanceId)) {
|
||||||
|
throw new Error('Dropdown component instance ID is not defined');
|
||||||
|
}
|
||||||
|
|
||||||
|
const isDropdownOpen = snapshot
|
||||||
|
.getLoadable(
|
||||||
|
isDropdownOpenComponentStateV2.atomFamily({
|
||||||
|
instanceId: dropdownComponentInstanceId,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.getValue();
|
||||||
|
|
||||||
|
const isDropdownOpenLegacy = snapshot
|
||||||
|
.getLoadable(
|
||||||
|
isDropdownOpenComponentState({
|
||||||
|
scopeId: dropdownComponentInstanceId,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.getValue();
|
||||||
|
|
||||||
|
if (isDropdownOpen || isDropdownOpenLegacy) {
|
||||||
|
removeFocusItemFromFocusStackById({
|
||||||
|
focusId: dropdownComponentInstanceId,
|
||||||
|
});
|
||||||
|
|
||||||
|
goBackToPreviousDropdownFocusId();
|
||||||
|
|
||||||
|
set(
|
||||||
|
isDropdownOpenComponentStateV2.atomFamily({
|
||||||
|
instanceId: dropdownComponentInstanceId,
|
||||||
|
}),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
set(
|
||||||
|
isDropdownOpenComponentState({
|
||||||
|
scopeId: dropdownComponentInstanceId,
|
||||||
|
}),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
removeFocusItemFromFocusStackById,
|
||||||
|
goBackToPreviousDropdownFocusId,
|
||||||
|
dropdownComponentInstanceIdFromContext,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
closeDropdown,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -1,14 +0,0 @@
|
|||||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
|
||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
export const useCloseDropdownFromOutside = () => {
|
|
||||||
const closeDropdownFromOutside = useRecoilCallback(
|
|
||||||
({ set }) =>
|
|
||||||
(dropdownId: string) => {
|
|
||||||
set(isDropdownOpenComponentState({ scopeId: dropdownId }), false);
|
|
||||||
},
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
|
|
||||||
return { closeDropdownFromOutside };
|
|
||||||
};
|
|
||||||
@ -10,6 +10,13 @@ import { GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysCo
|
|||||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @deprecated This hook is deprecated, use a specific hook instead :
|
||||||
|
* - `useOpenDropdown`
|
||||||
|
* - `useCloseDropdown`
|
||||||
|
* - `useToggleDropdown`
|
||||||
|
*/
|
||||||
export const useDropdown = (dropdownId?: string) => {
|
export const useDropdown = (dropdownId?: string) => {
|
||||||
const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack();
|
const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack();
|
||||||
const { removeFocusItemFromFocusStackById } =
|
const { removeFocusItemFromFocusStackById } =
|
||||||
|
|||||||
@ -1,106 +0,0 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId';
|
|
||||||
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
|
|
||||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
|
||||||
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
|
|
||||||
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
|
|
||||||
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
|
||||||
import { GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysConfig';
|
|
||||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
|
||||||
|
|
||||||
export const useDropdownV2 = () => {
|
|
||||||
const { goBackToPreviousDropdownFocusId } =
|
|
||||||
useGoBackToPreviousDropdownFocusId();
|
|
||||||
|
|
||||||
const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack();
|
|
||||||
|
|
||||||
const { removeFocusItemFromFocusStackById } =
|
|
||||||
useRemoveFocusItemFromFocusStackById();
|
|
||||||
|
|
||||||
const { setActiveDropdownFocusIdAndMemorizePrevious } =
|
|
||||||
useSetActiveDropdownFocusIdAndMemorizePrevious();
|
|
||||||
|
|
||||||
const closeDropdown = useRecoilCallback(
|
|
||||||
({ set, snapshot }) =>
|
|
||||||
(specificComponentId: string) => {
|
|
||||||
const scopeId = specificComponentId;
|
|
||||||
|
|
||||||
const isDropdownOpen = snapshot
|
|
||||||
.getLoadable(isDropdownOpenComponentState({ scopeId }))
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
if (isDropdownOpen) {
|
|
||||||
removeFocusItemFromFocusStackById({
|
|
||||||
focusId: scopeId,
|
|
||||||
});
|
|
||||||
goBackToPreviousDropdownFocusId();
|
|
||||||
set(
|
|
||||||
isDropdownOpenComponentState({
|
|
||||||
scopeId,
|
|
||||||
}),
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[removeFocusItemFromFocusStackById, goBackToPreviousDropdownFocusId],
|
|
||||||
);
|
|
||||||
|
|
||||||
const openDropdown = useRecoilCallback(
|
|
||||||
({ set }) =>
|
|
||||||
(
|
|
||||||
specificComponentId: string,
|
|
||||||
globalHotkeysConfig?: Partial<GlobalHotkeysConfig>,
|
|
||||||
) => {
|
|
||||||
const scopeId = specificComponentId;
|
|
||||||
|
|
||||||
set(
|
|
||||||
isDropdownOpenComponentState({
|
|
||||||
scopeId,
|
|
||||||
}),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
setActiveDropdownFocusIdAndMemorizePrevious(specificComponentId);
|
|
||||||
|
|
||||||
pushFocusItemToFocusStack({
|
|
||||||
focusId: scopeId,
|
|
||||||
component: {
|
|
||||||
type: FocusComponentType.DROPDOWN,
|
|
||||||
instanceId: scopeId,
|
|
||||||
},
|
|
||||||
globalHotkeysConfig,
|
|
||||||
// TODO: Remove this once we've fully migrated away from hotkey scopes
|
|
||||||
hotkeyScope: { scope: 'dropdown' } as HotkeyScope,
|
|
||||||
memoizeKey: 'global',
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[pushFocusItemToFocusStack, setActiveDropdownFocusIdAndMemorizePrevious],
|
|
||||||
);
|
|
||||||
|
|
||||||
const toggleDropdown = useRecoilCallback(
|
|
||||||
({ snapshot }) =>
|
|
||||||
(
|
|
||||||
specificComponentId: string,
|
|
||||||
globalHotkeysConfig?: Partial<GlobalHotkeysConfig>,
|
|
||||||
) => {
|
|
||||||
const scopeId = specificComponentId;
|
|
||||||
const isDropdownOpen = snapshot
|
|
||||||
.getLoadable(isDropdownOpenComponentState({ scopeId }))
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
if (isDropdownOpen) {
|
|
||||||
closeDropdown(specificComponentId);
|
|
||||||
} else {
|
|
||||||
openDropdown(specificComponentId, globalHotkeysConfig);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[closeDropdown, openDropdown],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
closeDropdown,
|
|
||||||
openDropdown,
|
|
||||||
toggleDropdown,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||||
|
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
|
||||||
|
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||||
|
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
|
||||||
|
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
|
||||||
|
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
||||||
|
import { GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysConfig';
|
||||||
|
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||||
|
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
|
||||||
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
|
type OpenDropdownArgs = {
|
||||||
|
dropdownComponentInstanceIdFromProps?: string;
|
||||||
|
globalHotkeysConfig?: Partial<GlobalHotkeysConfig>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useOpenDropdown = () => {
|
||||||
|
const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack();
|
||||||
|
|
||||||
|
const { setActiveDropdownFocusIdAndMemorizePrevious } =
|
||||||
|
useSetActiveDropdownFocusIdAndMemorizePrevious();
|
||||||
|
const dropdownComponentInstanceIdFromContext =
|
||||||
|
useAvailableComponentInstanceId(DropdownComponentInstanceContext);
|
||||||
|
|
||||||
|
const openDropdown = useRecoilCallback(
|
||||||
|
({ set }) =>
|
||||||
|
(args?: OpenDropdownArgs | null | undefined) => {
|
||||||
|
const dropdownComponentInstanceId =
|
||||||
|
args?.dropdownComponentInstanceIdFromProps ??
|
||||||
|
dropdownComponentInstanceIdFromContext;
|
||||||
|
|
||||||
|
if (!isDefined(dropdownComponentInstanceId)) {
|
||||||
|
throw new Error('Dropdown component instance ID is not defined');
|
||||||
|
}
|
||||||
|
|
||||||
|
set(
|
||||||
|
isDropdownOpenComponentState({
|
||||||
|
scopeId: dropdownComponentInstanceId,
|
||||||
|
}),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
set(
|
||||||
|
isDropdownOpenComponentStateV2.atomFamily({
|
||||||
|
instanceId: dropdownComponentInstanceId,
|
||||||
|
}),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
setActiveDropdownFocusIdAndMemorizePrevious(
|
||||||
|
dropdownComponentInstanceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
pushFocusItemToFocusStack({
|
||||||
|
focusId: dropdownComponentInstanceId,
|
||||||
|
component: {
|
||||||
|
type: FocusComponentType.DROPDOWN,
|
||||||
|
instanceId: dropdownComponentInstanceId,
|
||||||
|
},
|
||||||
|
globalHotkeysConfig: args?.globalHotkeysConfig ?? undefined,
|
||||||
|
// TODO: Remove this once we've fully migrated away from hotkey scopes
|
||||||
|
hotkeyScope: { scope: 'dropdown' } as HotkeyScope,
|
||||||
|
memoizeKey: 'global',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[
|
||||||
|
pushFocusItemToFocusStack,
|
||||||
|
setActiveDropdownFocusIdAndMemorizePrevious,
|
||||||
|
dropdownComponentInstanceIdFromContext,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
openDropdown,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||||
|
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||||
|
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
|
||||||
|
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||||
|
import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
|
||||||
|
import { GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysConfig';
|
||||||
|
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
|
||||||
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
|
export const useToggleDropdown = () => {
|
||||||
|
const dropdownComponentInstanceIdFromContext =
|
||||||
|
useAvailableComponentInstanceId(DropdownComponentInstanceContext);
|
||||||
|
|
||||||
|
const { openDropdown } = useOpenDropdown();
|
||||||
|
const { closeDropdown } = useCloseDropdown();
|
||||||
|
|
||||||
|
const toggleDropdown = useRecoilCallback(
|
||||||
|
({ snapshot }) =>
|
||||||
|
({
|
||||||
|
dropdownComponentInstanceIdFromProps,
|
||||||
|
globalHotkeysConfig,
|
||||||
|
}: {
|
||||||
|
dropdownComponentInstanceIdFromProps?: string;
|
||||||
|
globalHotkeysConfig?: Partial<GlobalHotkeysConfig>;
|
||||||
|
}) => {
|
||||||
|
const dropdownComponentInstanceId =
|
||||||
|
dropdownComponentInstanceIdFromProps ??
|
||||||
|
dropdownComponentInstanceIdFromContext;
|
||||||
|
|
||||||
|
if (!isDefined(dropdownComponentInstanceId)) {
|
||||||
|
throw new Error('Dropdown component instance ID is not defined');
|
||||||
|
}
|
||||||
|
|
||||||
|
const isDropdownOpen = snapshot
|
||||||
|
.getLoadable(
|
||||||
|
isDropdownOpenComponentStateV2.atomFamily({
|
||||||
|
instanceId: dropdownComponentInstanceId,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.getValue();
|
||||||
|
|
||||||
|
const isDropdownOpenLegacy = snapshot
|
||||||
|
.getLoadable(
|
||||||
|
isDropdownOpenComponentState({
|
||||||
|
scopeId: dropdownComponentInstanceId,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.getValue();
|
||||||
|
|
||||||
|
if (isDropdownOpen || isDropdownOpenLegacy) {
|
||||||
|
closeDropdown(dropdownComponentInstanceId);
|
||||||
|
} else {
|
||||||
|
openDropdown({
|
||||||
|
dropdownComponentInstanceIdFromProps: dropdownComponentInstanceId,
|
||||||
|
globalHotkeysConfig,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[closeDropdown, openDropdown, dropdownComponentInstanceIdFromContext],
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
toggleDropdown,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -1,4 +1,5 @@
|
|||||||
import { createState } from 'twenty-ui/utilities';
|
import { createState } from 'twenty-ui/utilities';
|
||||||
|
|
||||||
export const activeDropdownFocusIdState = createState<string | null>({
|
export const activeDropdownFocusIdState = createState<string | null>({
|
||||||
key: 'activeDropdownFocusIdState',
|
key: 'activeDropdownFocusIdState',
|
||||||
defaultValue: null,
|
defaultValue: null,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponeInstanceContext';
|
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||||
|
|
||||||
export const dropdownMaxHeightComponentState = createComponentStateV2<
|
export const dropdownMaxHeightComponentState = createComponentStateV2<
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponeInstanceContext';
|
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||||
|
|
||||||
export const dropdownMaxWidthComponentState = createComponentStateV2<
|
export const dropdownMaxWidthComponentState = createComponentStateV2<
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use `isDropdownOpenComponentStateV2` instead.
|
||||||
|
*/
|
||||||
export const isDropdownOpenComponentState = createComponentState<boolean>({
|
export const isDropdownOpenComponentState = createComponentState<boolean>({
|
||||||
key: 'isDropdownOpenComponentState',
|
key: 'isDropdownOpenComponentState',
|
||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
|
|||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||||
|
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||||
|
|
||||||
|
export const isDropdownOpenComponentStateV2 = createComponentStateV2<boolean>({
|
||||||
|
key: 'isDropdownOpenComponentStateV2',
|
||||||
|
defaultValue: false,
|
||||||
|
componentInstanceContext: DropdownComponentInstanceContext,
|
||||||
|
});
|
||||||
@ -1,4 +1,5 @@
|
|||||||
import { createState } from 'twenty-ui/utilities';
|
import { createState } from 'twenty-ui/utilities';
|
||||||
|
|
||||||
export const previousDropdownFocusIdState = createState<string | null>({
|
export const previousDropdownFocusIdState = createState<string | null>({
|
||||||
key: 'previousDropdownFocusIdState',
|
key: 'previousDropdownFocusIdState',
|
||||||
defaultValue: null,
|
defaultValue: null,
|
||||||
|
|||||||
@ -0,0 +1,19 @@
|
|||||||
|
import { useComponentInstanceStateContext } from '@/ui/utilities/state/component-state/hooks/useComponentInstanceStateContext';
|
||||||
|
import { ComponentInstanceStateContext } from '@/ui/utilities/state/component-state/types/ComponentInstanceStateContext';
|
||||||
|
import { isNonEmptyString } from '@sniptt/guards';
|
||||||
|
|
||||||
|
export const useAvailableComponentInstanceId = <
|
||||||
|
T extends { instanceId: string },
|
||||||
|
>(
|
||||||
|
Context: ComponentInstanceStateContext<T>,
|
||||||
|
): string | null => {
|
||||||
|
const instanceStateContext = useComponentInstanceStateContext(Context);
|
||||||
|
|
||||||
|
const instanceIdFromContext = instanceStateContext?.instanceId;
|
||||||
|
|
||||||
|
if (isNonEmptyString(instanceIdFromContext)) {
|
||||||
|
return instanceIdFromContext;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2';
|
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||||
import { VIEW_PICKER_DROPDOWN_ID } from '@/views/view-picker/constants/ViewPickerDropdownId';
|
import { VIEW_PICKER_DROPDOWN_ID } from '@/views/view-picker/constants/ViewPickerDropdownId';
|
||||||
import { VIEW_PICKER_KANBAN_FIELD_DROPDOWN_ID } from '@/views/view-picker/constants/ViewPickerKanbanFieldDropdownId';
|
import { VIEW_PICKER_KANBAN_FIELD_DROPDOWN_ID } from '@/views/view-picker/constants/ViewPickerKanbanFieldDropdownId';
|
||||||
@ -17,7 +17,7 @@ export const useCloseAndResetViewPicker = () => {
|
|||||||
viewPickerIsPersistingComponentState,
|
viewPickerIsPersistingComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { closeDropdown } = useDropdownV2();
|
const { closeDropdown } = useCloseDropdown();
|
||||||
|
|
||||||
const closeAndResetViewPicker = useCallback(() => {
|
const closeAndResetViewPicker = useCallback(() => {
|
||||||
setViewPickerIsPersisting(false);
|
setViewPickerIsPersisting(false);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer';
|
import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer';
|
||||||
import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2';
|
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||||
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
||||||
import { WorkflowVariablesDropdownFieldItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownFieldItems';
|
import { WorkflowVariablesDropdownFieldItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownFieldItems';
|
||||||
@ -51,7 +51,7 @@ export const WorkflowVariablesDropdown = ({
|
|||||||
const isDropdownOpen = useRecoilValue(
|
const isDropdownOpen = useRecoilValue(
|
||||||
extractComponentState(isDropdownOpenComponentState, dropdownId),
|
extractComponentState(isDropdownOpenComponentState, dropdownId),
|
||||||
);
|
);
|
||||||
const { closeDropdown } = useDropdownV2();
|
const { closeDropdown } = useCloseDropdown();
|
||||||
const availableVariablesInWorkflowStep = useAvailableVariablesInWorkflowStep({
|
const availableVariablesInWorkflowStep = useAvailableVariablesInWorkflowStep({
|
||||||
objectNameSingularToSelect,
|
objectNameSingularToSelect,
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user