Fix CSV import select field matching (#11361)

This PR fixes a bug that prevented to do the matching of an imported CSV
file that contains a SELECT type column.

Fixes https://github.com/twentyhq/twenty/issues/11220

## Stacking context improvement 

During the development it was clear that we lacked a reliable way to
understand our own z indices for components like modal, portaled
dropdown, overlay background, etc.

So in this PR we introduce a new enum RootStackingContextZIndices, this
enum allows to keep track of our root stacking context component
z-index, and because it is an enum, it prevents any conflict.

See
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_positioned_layout/Stacking_context
for reference.

## Component cleaning

Components have been reorganized in a SubMatchingSelectRow component

The Dropdown component has been used to replace the SelectInput
component which doesn't fit this use case because we are not in a cell,
we just need a simple standalone dropdown, though it would be
interesting to extract the UI part of the SelectInput, to share it here,
the benefit is not obvious since we already have good shared components
like Tag and Dropdown to implement this specific use case.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
This commit is contained in:
Lucas Bordeau
2025-04-03 16:28:15 +02:00
committed by GitHub
parent 752eb93836
commit 5e43839efb
20 changed files with 446 additions and 135 deletions

View File

@ -5,9 +5,10 @@ import { Key } from 'ts-key-enum';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { DialogHotkeyScope } from '../types/DialogHotkeyScope';
import { RootStackingContextZIndices } from '@/ui/layout/constants/RootStackingContextZIndices';
import { isDefined } from 'twenty-shared/utils';
import { Button } from 'twenty-ui/input';
import { DialogHotkeyScope } from '../types/DialogHotkeyScope';
const StyledDialogOverlay = styled(motion.div)`
align-items: center;
@ -19,7 +20,7 @@ const StyledDialogOverlay = styled(motion.div)`
position: fixed;
top: 0;
width: 100vw;
z-index: 9999;
z-index: ${RootStackingContextZIndices.Dialog};
`;
const StyledDialogContainer = styled(motion.div)`

View File

@ -5,22 +5,23 @@ import { useSnackBarManagerScopedStates } from '@/ui/feedback/snack-bar-manager/
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { RootStackingContextZIndices } from '@/ui/layout/constants/RootStackingContextZIndices';
import { SnackBar } from './SnackBar';
import { MOBILE_VIEWPORT } from 'twenty-ui/theme';
const StyledSnackBarContainer = styled.div`
bottom: ${({ theme }) => theme.spacing(3)};
display: flex;
flex-direction: column;
position: fixed;
right: ${({ theme }) => theme.spacing(3)};
bottom: ${({ theme }) => theme.spacing(3)};
z-index: ${({ theme }) => theme.lastLayerZIndex};
z-index: ${RootStackingContextZIndices.SnackBar};
@media (max-width: ${MOBILE_VIEWPORT}px) {
top: 0;
bottom: auto;
left: 0;
right: 0;
top: 0;
}
`;

View File

@ -0,0 +1,24 @@
/**
* Please read this article to understand why we use this enum : https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_positioned_layout/Stacking_context
*
* It is important to keep track of the stacking contexts that are created on top of the root stacking context of the document.
*
* Right now we have to guess it by looking into the developer console
*
* This way we can avoid hazardous fidgeting with z-index CSS properties
* and having to look down the tree in the developer console to see which component is in the root stacking context or not
*
* Using an enum enforces a single z-index for each component in the root stacking context
*
* TODO: add the other remaining components that can appear in the root stacking context
*/
export enum RootStackingContextZIndices {
CommandMenu = 21,
CommandMenuButton = 22,
RootModalBackDrop = 39,
RootModal = 40,
DropdownPortal = 50,
Dialog = 9999,
SnackBar = 10002,
NotFound = 10001,
}

View File

@ -1,3 +1,4 @@
import { RootStackingContextZIndices } from '@/ui/layout/constants/RootStackingContextZIndices';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { useInternalHotkeyScopeManagement } from '@/ui/layout/dropdown/hooks/useInternalHotkeyScopeManagement';
@ -23,7 +24,7 @@ import { Key } from 'ts-key-enum';
export const StyledDropdownContentContainer = styled.div`
display: flex;
z-index: 30;
z-index: ${RootStackingContextZIndices.DropdownPortal};
`;
export type DropdownContentProps = {

View File

@ -1,3 +1,4 @@
import { RootStackingContextZIndices } from '@/ui/layout/constants/RootStackingContextZIndices';
import { ModalHotkeyScope } from '@/ui/layout/modal/components/types/ModalHotkeyScope';
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
@ -31,7 +32,7 @@ const StyledModalDiv = styled(motion.div)<{
}};
overflow-x: hidden;
overflow-y: auto;
z-index: 10000; // should be higher than Backdrop's z-index
z-index: ${RootStackingContextZIndices.RootModal}; // should be higher than Backdrop's z-index
width: ${({ isMobile, size, theme }) => {
if (isMobile) return theme.modal.size.fullscreen;
@ -109,7 +110,7 @@ const StyledBackDrop = styled(motion.div)<{
position: fixed;
top: 0;
width: 100%;
z-index: 9999;
z-index: ${RootStackingContextZIndices.RootModalBackDrop};
user-select: none;
`;

View File

@ -1,5 +1,6 @@
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
import { RootStackingContextZIndices } from '@/ui/layout/constants/RootStackingContextZIndices';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { i18n } from '@lingui/core';
@ -11,7 +12,7 @@ import { AppTooltip, TooltipDelay, TooltipPosition } from 'twenty-ui/display';
import { getOsControlSymbol, useIsMobile } from 'twenty-ui/utilities';
const StyledButtonWrapper = styled.div`
z-index: 30;
z-index: ${RootStackingContextZIndices.CommandMenuButton};
`;
const StyledTooltipWrapper = styled.div`