## Summary
- Move Modal UI components (`Modal`, `ModalContent`, `ModalHeader`,
`ModalFooter`, `ModalBackdrop`) from `twenty-front` to `twenty-ui` as
stateless, reusable components
- Create `ModalStatefulWrapper` in `twenty-front` that connects Jotai
state (`isModalOpenedComponentState`) to the stateless `Modal` via an
`isOpen` prop
- Rename `modalVariant` prop to `overlay` with clearer values: `'dark'`
(default), `'light'` (in-container), `'transparent'` (invisible panel).
Remove unused `'medium'` overlay
- Rename `modalId` to `modalInstanceId` across the entire modal zone
(~30 consumer files)
- Extract `ModalProps` to its own file in
`twenty-ui/types/ModalProps.ts`; extract `ModalStatefulWrapperProps` to
its own file using `Pick<ModalProps, ...>` for shared props
- Extract `ModalBackdrop` to its own file and export from `twenty-ui`;
use it in `UserOrMetadataLoader` instead of a local styled component
- Use `ModalFooter` in `StepNavigationButton` and `ModalHeader` in
`SpreadsheetImportStepperContainer` instead of duplicated `styled.div`
definitions
- Remove unused `onClose` prop from stateless `Modal`; fix `typeof
document` guard in `ModalStatefulWrapper`
- Split shared types into individual files: `ModalSize.ts`,
`ModalPadding.ts`, `ModalOverlay.ts`
- Extract wyw profiling instrumentation from `vite.config.ts` into
reusable `createWywProfilingPlugin` with parametrized threshold and
improved logging
- Delete old `Modal.tsx`, `Modal.styles.ts`, `ModalContent.tsx`,
`ModalHeader.tsx`, `ModalFooter.tsx` from `twenty-front`
- Add comprehensive Storybook stories in `twenty-ui` covering Default,
Confirmation, Small, ExtraLarge, Closed, and Interactive variants
## Summary
This PR adds the `lingui/no-unlocalized-strings` ESLint rule to detect
untranslated strings and fixes translation issues across multiple
components.
## Changes
### ESLint Configuration (`eslint.config.react.mjs`)
- Added comprehensive `ignore` patterns for non-translatable strings
(CSS values, HTML attributes, technical identifiers)
- Added `ignoreNames` for props that don't need translation (className,
data-*, aria-*, etc.)
- Added `ignoreFunctions` for console methods, URL APIs, and other
non-user-facing functions
- Disabled rule for debug files, storybook, and test files
### Components Fixed (~19 files)
- Object record components (field inputs, pickers, merge dialogs)
- Settings components (accounts, admin panel)
- Serverless function components
- Record table and title cell components
## Status
🚧 **Work in Progress** - ~124 files remaining to fix
This PR is being submitted as draft to allow progressive fixing of
remaining translation issues.
## Testing
- Run `npx eslint "src/**/*.tsx"` in `packages/twenty-front` to check
remaining issues
# Complete color refactoring
Closes https://github.com/twentyhq/core-team-issues/issues/1779
- Updated all colors to use Radix colors with P3 color space allowing
for brighter colors
- Created our own gray scale interpolated on Radix's scale to have the
same values for grays as the old ones in the app
- Introduced dark and light colors as well as there transparent versions
- Added many new colors from radix that can be used in the tags or in
the graphs
- Updated multiple color utilities to match new behaviors
- Changed the computation of Avatar colors to return only colors from
the theme (before it was random hsl)
These changes allow the user to use new colors in tags or charts, the
colors are brighter and with better contrast. We have a full range of
color variations from 1 to 12 where before we only had 4 adaptative
colors.
All these changes will allow us to develop custom themes for the user
soon, where users can choose their accent colors, background colors and
there contrast.
This PR removes any V2 naming in state management logic and some minor
utils and hooks.
It has a lot of changes but nearly all of them were made by the rename
functionality of vscode which is deterministic, so it shouldn't
introduce any regression.
QA has been made on this PR on the main features of the app without any
noticeable issue.
Also renamed some other v2 naming related items :
- TextInputV2 => TextInput
- TextInput => SettingsTextInput
- ObjectFilterDropdownFilterSelectMenuItemV2 =>
ObjectFilterDropdownFilterSelectMenuItem
- useInitDraftValueV2 => useInitDraftValue
- useOpenRecordTableCellV2 => useOpenRecordTableCell
Fixes#12093
This bug was quite hard to fix because it was an issue with the
`AnimatePresence` component of the framer motion library.
After investigating the issue with @Devessier, here is what we
understood:
Since the modal component has an exit animation but wasn't wrapped
inside an `AnimatePresence` component, the animation seemed to never be
marked as complete when we closed the modal and the component did not
appear anymore but was still in the dom.
This caused an issue when closing the side panel because the state
cleanup function of the command menu is triggered when its closing
animation is complete. This cleanup function emits a right drawer close
event, which is listened by the record table row to update it's state.
The `onExitComplete` was never triggered because the exit animation of
the modal was never considered as complete, and since it's a children
animation of the command menu `AnimatePresence`, this animation was
never considered as complete either (see [PresenceChild
doc](https://github.com/motiondivision/motion/blob/main/packages/framer-motion/src/components/AnimatePresence/PresenceChild.tsx).
This caused the cleanup function to never be executed and the close
event to never be emitted, so the row stayed active.
Before:
https://github.com/user-attachments/assets/a165039b-6203-43d6-b992-dcfb4dfb8f2b
After:
https://github.com/user-attachments/assets/42eab2e8-62c9-4c25-85d6-78210d7ebe89
We previously used classnames to exclude elements from the click outside
listener.
With this PR we can now use `data-click-outside-id` instead of
`classNames` to target the elements we want to exclude from the click
outside listener.
We can also add `data-globally-prevent-click-outside` to a component to
globally prevent triggering click outside listeners for other
components. This attribute is especially useful for confirmation modals
and snackbar items.
Fixes#11785:
https://github.com/user-attachments/assets/318baa7e-0f82-4e3a-a447-bf981328462d
# Modal API Refactoring
This PR refactors the modal system to use an imperative approach for
setting hotkey scopes, addressing race conditions that occurred with the
previous effect-based implementation.
Fixes#11986Closes#12087
## Key Changes:
- **New Modal API**: Introduced a `useModal` hook with `openModal`,
`closeModal`, and `toggleModal` functions, similar to the existing
dropdown API
- **Modal Identification**: Added a `modalId` prop to uniquely identify
modals
- **State Management**: Introduced `isModalOpenedComponentState` and
removed individual boolean state atoms (like
`isRemoveSortingModalOpenState`)
- **Modal Constants**: Added consistent modal ID constants (e.g.,
`FavoriteFolderDeleteModalId`, `RecordIndexRemoveSortingModalId`) for
better maintainability
- **Mount Effects**: Created mount effect components (like
`AuthModalMountEffect`) to handle initial modal opening where needed
## Implementation Details:
- Modified `Modal` and `ConfirmationModal` components to accept the new
`modalId` prop
- Added a component-state-based approach using
`ModalComponentInstanceContext` to track modal state
- Introduced imperative modal handlers that properly manage hotkey
scopes
- Components like `ActionModal` and `AttachmentList` now use the new
`useModal` hook for better control over modal state
## Benefits:
- **Race Condition Prevention**: Hotkey scopes are now set imperatively,
eliminating race conditions
- **Consistent API**: Modal and dropdown now share similar patterns,
improving developer experience
## Tests to do before merging:
1. Action Modals (Modal triggered by an action, for example the delete
action)
2. Auth Modal (`AuthModal.tsx` and `AuthModalMountEffect.tsx`)
- Test that auth modal opens automatically on mount
- Verify authentication flow works properly
3. Email Verification Sent Modal (in `SignInUp.tsx`)
- Verify this modal displays correctly
4. Attachment Preview Modal (in `AttachmentList.tsx`)
- Test opening preview modal by clicking on attachments
- Verify close, download functionality works
- Test modal navigation and interactions
5. Favorite Folder Delete Modal (`CurrentWorkspaceMemberFavorites.tsx`)
- Test deletion confirmation flow
- Check that modal opens when attempting to delete folders with
favorites
6. Record Board Remove Sorting Modal (`RecordBoard.tsx` using
`RecordIndexRemoveSortingModalId`)
- Test that modal appears when trying to drag records with sorting
enabled
- Verify sorting removal works correctly
7. Record Group Reorder Confirmation Modal
(`RecordGroupReorderConfirmationModal.tsx`)
- Test group reordering with sorting enabled
- Verify confirmation modal properly handles sorting removal
8. Confirmation Modal (base component used by several modals)
- Test all variants with different confirmation options
For each modal, verify:
- Opening/closing behavior
- Hotkey support (Esc to close, Enter to confirm where applicable)
- Click outside behavior
- Proper z-index stacking
- Any modal-specific functionality
# Introduction
closes https://github.com/twentyhq/core-team-issues/issues/591
Same than for `twenty-shared` made in
https://github.com/twentyhq/twenty/pull/11083.
## TODO
- [x] Manual migrate twenty-website twenty-ui imports
## What's next:
- Generate barrel and migration script factorization within own package
+ tests
- Refactoring using preconstruct ? TimeBox
- Lint circular dependencies
- Lint import from barrel and forbid them
### Preconstruct
We need custom rollup plugins addition, but preconstruct does not expose
its rollup configuration. It might be possible to handle this using the
babel overrides. But was a big tunnel.
We could give it a try afterwards ! ( allowing cjs interop and stuff
like that )
Stuck to vite lib app
Closed related PRs:
- https://github.com/twentyhq/twenty/pull/11294
- https://github.com/twentyhq/twenty/pull/11203
Fixes#10004
- Fixed `useListenClickOutside` which wasn't working with
`excludeClassNames` for `comparePixels` mode
- Added `emitCloseEvent` parameter to the `closeRightDrawer` function
because closing the right drawer after deleting a note or a task was
triggering an update after the deletion.
This bug was only for the old version of the command menu.
This PR fixes all followup that @Bonapara add on Discord.
- [x] When no group by is set, clicking on group by should open the
"field selection" menu
- [x] When closed, chevron should be "chevron-right" instead of
"chevron-up"
- [x] Sort : Add ability to switch from alphabetical to manual when
moving a option in sort alphabetical
- [x] Add subtext for group by and sort
- [x] Group by menu display bug
- [x] Changing the sort should not close the menu
- [x] Group by Activation -> shows empty state + is slow
- [x] Switching from Kanban view Settings to Table Options menu displays
an empty menu
- [x] Unnecessary spacing under groups
- [x] When no "select" are set on an object, redirect the user directly
to the new Select field page
- [x] Sort : Default should be manual
- [x] Hidding "no value" displays all options and remove the "hide empty
group" toggle
- [x] Hide Empty group option disappeared
- [x] Group by should not be persisted on "Locked/Main view" (**For now
we just disable the group by on main view**)
- [x] Hide Empty group should not be activated by default on
Opportunities Kanban view
- [ ] Animate the group opening/closing (**We'll be done later**)
Performance improvement:
https://github.com/user-attachments/assets/fd2acf66-0e56-45d0-8b2f-99c62e57d6f7https://github.com/user-attachments/assets/80f1a2e1-9f77-4923-b85d-acb9cad96886
Also fix#9036
---------
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Closes#7499
- Modifies context store states to be component states
- Introduces the concept of `mainContextStore` which will dictate the
available actions inside the command K
- Adds contextual actions inside the right drawer
- Creates a new type of modal variant
In this PR:
- Allow the `<ConfirmationModal />` to take additional buttons to
display between the cancel and the confirm buttons.
- Create a modal that's displayed when the user tries wants to use a
workflow version as draft while a draft version already exists. The
displayed modal contains a link to the current draft version and a
button to confirm the overriding of the current draft version.
A demo:
https://github.com/user-attachments/assets/6349f418-1b11-45b3-9f5e-061ca74c2966Closestwentyhq/private-issues#114
Fixes https://github.com/twentyhq/twenty/issues/6912
By clicking Enter key over and over, user can repeat action Expected:
When 'yes' is typed in popup and user clicks Enter key once, popup
should disappear and correlated action should be performed only once
Implementation:
- Added loading state for buttons onClick and onEnter to disable the
button when the "Delete Api Key" and "Regenerate Api Key" function is
called.
- Added a new function to handle modal close and logic handling on
clicking enter key.
---------
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
# Description
Fix bug bypassing verification in the confirmation modal when pressing
Enter
# Demo
Tested for webhook case (similar to other cases):
1. Press Enter when invalid verification => not delete webhook
2. Press Enter when valid verification => delete webhook
https://github.com/user-attachments/assets/81aa0aaa-7361-4584-b7ae-b29525f33664
# Ref
Fixes#6663
In this PR:
- revert de-optimization of icons bundle for storybook. This was forcing
the browser to load ~3k files while running stories
- adding lazy loading on Settings route to improve developer experience
(some files will be loaded later)
- fix FE tests: unit, modules stories, pages stories
---------
Co-authored-by: Charles Bochet <charles@twenty.com>
Hi @Bonapara,
Issue #6385
I encountered an issue with the Modal component where its width was
fixed at 400px. While the container housing the Modal adjusted its size
based on the screen width, the Modal itself remained at 400px regardless
of the screen size.
I have implemented a change to address this problem. Could you please
review the changes and let me know your thoughts?
Thank you!
https://github.com/user-attachments/assets/8358aacb-d6c3-440e-895e-7abc4f8a3534
---------
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>