## Context
Reverting back the removal of "Log out" button. While it is now
accessible from the workspace picker, suspended workspaces don't have
access to that picker and are locked in the settings pages so I'm adding
back the log out button in the settings menu
<img width="225" alt="Screenshot 2025-03-21 at 15 52 40"
src="https://github.com/user-attachments/assets/d5453868-d043-49e9-9207-2cfdd65838da"
/>
This PR essentially focuses on a refactor of the component hierarchy and
naming in advanced filter dropdown, to make it more readable and easy to
maintain.
This refactor was required because this area of the code is recursive,
so it's better to see the same abstract components in the recursion,
instead of trying to guess whether we have the same components than the
level above or not.
Also keep in mind that this refactor is meant to separate the advanced
filter code path from the view bar simple filter code path, while
reusing what's reusable, so here we have a first attempt at finding the
sweet spot, that we'll be able to duplicate on other filter dropdown use
cases.
- We now use AdvancedFilterRecordFilterGroupRow and
AdvancedFilterRecordFilterRow to make it clearer in the advanced filter
dropdown recursion where we are.
- Children component of AdvancedFilterRecordFilterRow have been
abstracted at the same level to make reading easier
- The field selection dropdown is now in a self-explanatory component
that follows the same naming pattern as other dropdowns in the app :
AdvancedFilterFieldSelectDrodownButton, together with
AdvancedFilterFieldSelectDrodownContent.
- The field selection search in the filter dropdown is now a standalone
component : AdvancedFilterFieldSelectSearchInput
- The UI container of a row has been abstracted in a new
AdvancedFilterDropdownRow
Miscellaneous :
- Renamed a bunch of view filter old naming to record filter naming.
## Context
Currency picker was not working properly, clicking a value was
triggering the clickOutsideListener of the parent and was closing the
select without saving. We are now toggling the click outside listener
based on the state of the currency picker dropdown
This also means the UX changed a bit, now choosing a value or clicking
outside only closes the select (allowing you to choose the amount as
well) and only enter OR clicking outside will save
closes#11013
Fixes the issue where users couldn't delete all text in select field
options. Removed the error throw for empty strings in the
computeOptionValueFromLabel function, allowing proper text deletion.
This error handling was redundant since the form validation already
prevents submission with empty values.
Workflows step details in workflows and versions should be different
from the node tab in run. For most cases, it was using the same
component. But for forms, it will be a different one.
This PR:
- renames form action into formBuilder. formFiller is coming
- put code into a separated folder
- creates a new component for node details
Fixes#11038
# Fix useFindManyRecords withSoftDeleterFilter
The error came from a faulty implementation of the `withSoftDeleted`
parameter inside `useFindManyRecords` and from the fact that
`withSoftDeleted: true` was added to access deleted records actions.
However, this parameter was always set in
`useFindManyRecordsSelectedInContextStore` instead of considering
whether the filter was active or not.
```
const withSoftDeleterFilter = {
or: [{ deletedAt: { is: 'NULL' } }, { deletedAt: { is: 'NOT_NULL' } }],
};
```
The final filter was incorrectly doing an `or` operation between the
base filter and `withSoftDeleterFilter` when it should have been an
`and`:
```
filter: {
...filter,
...(withSoftDeleted ? withSoftDeleterFilter : {}),
}
```
The correct implementation should be:
```
filter:
filter || withSoftDeleted
? {
and: [
...(filter ? [filter] : []),
...(withSoftDeleted ? [withSoftDeleterFilter] : []),
],
}
: undefined,
```
# Fix useFindManyRecordsSelectedInContextStore
- Check if the soft deleted filter is active before using the
`withSoftDeleterFilter` parameter
Updated all instances of the loading prop to isLoading across Button and
related components. This improves readability and ensures consistency in
the codebase.
Reorganized the workspace dropdown rendering logic for improved
readability and maintainability. Ensured consistent handling of
separators and dropdown items, while preserving the existing
functionality.
Fix#11034
In [a previous PR](https://github.com/twentyhq/twenty/pull/11023) I
fixed the issue where users where re-assigned the default role when
signin up using SSO.
The "fix" actually introduced another error, calling
`assignRoleToUserWorkspace` only when a user is signing up to twenty,
forgetting about the case where an existing twenty user signs up to a
different workspace. They should still be assigned the role in that
case.
To fix this and improve clarity, I moved assignRoleToUserWorkspace to
addUserToWorkspace and renamed addUserToWorkspace to
addUserToWorkspaceIfUserNotInWorkspace since this is at each sign in but
does nothing if user is already in the workspace.
I think ideally we should refactor this part to improve readability and
understandability, maybe with different flows for each case: signIn and
signUp, to twenty or to a workspace
This PR fixes some minor bugs on advanced filters.
## Dropdown menu header in filter input
The chevron down icon in the operand dropdown menu header was missing
due to a recent refactor of the DropdownMenuHeader component.
I just removed the unused EndIcon and replaced its usage by
EndComponent.
## Advanced filter dropdown staying open with 0 filters
The behavior we have for non-advanced filters is that the chip should
disappear if the filter gets empty, which is logical, an empty filter is
equivalent to not having filters, so don't want empty chips.
For advanced filters, the principle is the same, except that it's a bit
more complex to handle due to the recursive filter group hierarchy.
Here we create a useRemoveRootRecordFilterGroupIfEmpty hook, that we can
call everywhere a synchronous action should end up removing advanced
filters completely. (instead of using an effect)
This hook is distinct from removeRecordFilterGroup because we want
removeRecordFilterGroup to do only one job and we don't want it to hide
any side effect. It's better to have the side effect in a separate hook
that we call sequentially afterwards, in a self-explanatory manner.
## Miscellaneous
In this PR we add a new component selector to get the root level record
filter group, which is handy in a lot of cases.
The return type of the useChildRecordFiltersAndRecordFilterGroups hook
when it's empty has been fixed, though as discussed with Charles, it
would be better to turn it into selectors, which will certainly be done
in future PRs.
Chores #6389
## Description
This PR addresses inconsistencies in the codebase where elements that
visually function as labels were implemented with custom-styled
components rather than the standardized Label component from the UI
library.
## Changes
I've replaced several custom-styled text elements with the standardized
Label component from twenty-ui to improve consistency and
maintainability across the application. These modifications maintain the
same visual appearance and functionality while standardizing the
implementation.
## Components Modified:
InputLabel: Converted from a styled label to use the Label component
InputHint: Replaced styled div with a styled Label component
TableSection: Introduced a StyledLabel using the Label component for
section headings
StyledDropdownMenuSubheader: Converted from a styled div to a styled
Label component
NavigationDrawerSectionTitle: Replaced internal text element with the
Label component
SettingsCard: Updated description element to use the Label component
SettingsListItemCardContent: Changed description span to use the Label
component
RecordDetailSectionHeader: Added a StyledLabelLink for link text using
the Label component
TaskList: Modified the task count display to use the Label component
CommandGroup: Updated group headings to use the Label component
WorkerMetricsGraph: Replaced no-data message with a Label-based
component
ViewPickerSelectContainer: Changed from a styled div to a styled Label
component
---------
Co-authored-by: Félix Malfait <felix@twenty.com>
- Removed logout item from settings navigation drawer
- Removed logout locator and method from E2E tests
- Removed logout item from NavigationDrawer story
The logout functionality is now exclusively available through the menu
switcher, making the UI more consistent and reducing duplication.
Closes#11036
<img width="851" alt="Screenshot 2025-03-19 at 9 46 33 PM"
src="https://github.com/user-attachments/assets/3d73ec84-a2b7-4c4d-9605-dc83a9a760c1"
/>
---------
Co-authored-by: Félix Malfait <felix@twenty.com>
When logging using a SSO method, we call signInUp service in which we
were wrongfully assigning a role to the user even if the user is signing
in and not signin up.
This went unnoticed during our QA as a different sign-in method is
called when logging with the credentials.
---------
Co-authored-by: Weiko <corentin@twenty.com>
# Introduction
While running https://github.com/twentyhq/twenty/pull/10960 scripts
discovers few issues:
- Invalid named folder `pre-hooks.ts`
- Mock consuming outbound imported module resulting in consumed before
initialization
# Introduction
We want theses configurations to be strictly typed but needed as in
https://github.com/twentyhq/twenty/pull/10960 will browse through all
TypeScript files within the codebase