Moves system-level operations (auth, billing, admin) to use the
/metadata endpoint instead of /graphql.
This cleans up the endpoint separation so /graphql is purely for core
objects (Company, People, etc.) and /metadata handles all system
operations.
Part of prep work for webhook/API key core migration.
Workflow views and versions are seed being opened by default into record
page. Issue is that:
- new views are set by default to side panel. Updated by copying the
current opensIn value to the new view
- users can still select side panel into their options. Disabling the
button.
<img width="650" alt="Capture d’écran 2025-06-19 à 16 15 34"
src="https://github.com/user-attachments/assets/0ddc3284-0fed-404f-9c1d-225c65549fd1"
/>
This PR is the first part of a refactoring aiming to deprecate the
hotkey scopes api in favor of the new focus stack api which is more
robust.
The refactored components in this PR are the dropdowns and the side
panel/command menu.
- Replaced `useScopedHotkeys` by `useHotkeysOnFocusedElement` for all
dropdown components, selectable lists and the command menu
- Introduced `focusId` for all dropdowns and created a common hotkey
scope `DropdownHotkeyScope` for backward compatibility
- Replaced `setHotkeyScopeAndMemorizePreviousScope` occurrences with
`usePushFocusItemToFocusStack` and `goBackToPreviousHotkeyScope` with
`removeFocusItemFromFocusStack`
Note: Test that the shorcuts and arrow key navigation still work
properly when interacting with dropdowns and the command menu.
Bugs that I have spotted during the QA but which are already present on
main:
- Icon picker select with arrow keys doesn’t work inside dropdowns
- Some dropdowns are not selectable with arrow keys (no selectable list)
- Dropdowns in dropdowns don’t reset the hotkey scope correctly when
closing
- The table click outside is not triggered after closing a table cell
and clicking outside of the table
Opening a date picker when creating a filter now directly applies
today's date to avoid any in-between state issues.
This allows the date picker and the operand selection to behave nicely
when creating a date filter.
Fixes https://github.com/twentyhq/core-team-issues/issues/1049
Fixes#7929
This PR implements a system to capture and preserve the filters and
sorts when navigating from an index view to a record show page. This
information is stored in a context store component state.
This allows users to navigate between records inside the record page
while maintaining context from the index view.
# What
Fully deprecate old relations because we have one bug tied to it and it
make the codebase complex
# How I've made this PR:
1. remove metadata datasource (we only keep 'core') => this was causing
extra complexity in the refactor + flaky reset
2. merge dev and demo datasets => as I needed to update the tests which
is very painful, I don't want to do it twice
3. remove all code tied to RELATION_METADATA /
relation-metadata.resolver, or anything tied to the old relation system
4. Remove ONE_TO_ONE and MANY_TO_MANY that are not supported
5. fix impacts on the different areas : see functional testing below
# Functional testing
## Functional testing from the front-end:
1. Database Reset ✅
2. Sign In ✅
3. Workspace sign-up ✅
5. Browsing table / kanban / show ✅
6. Assigning a record in a one to many / in a many to one ✅
7. Deleting a record involved in a relation ✅ => broken but not tied to
this PR
8. "Add new" from relation picker ✅ => broken but not tied to this PR
9. Creating a Task / Note, Updating a Task / Note relations, Deleting a
Task / Note (from table, show page, right drawer) ✅ => broken but not
tied to this PR
10. creating a relation from settings (custom / standard x oneToMany /
manyToOne) ✅
11. updating a relation from settings should not be possible ✅
12. deleting a relation from settings (custom / standard x oneToMany /
manyToOne) ✅
13. Make sure timeline activity still work (relation were involved
there), espacially with Task / Note => to be double checked ✅ => Cannot
convert undefined or null to object
14. Workspace deletion / User deletion ✅
15. CSV Import should keep working ✅
16. Permissions: I have tested without permissions V2 as it's still hard
to test v2 work and it's not in prod yet ✅
17. Workflows global test ✅
## From the API:
1. Review open-api documentation (REST) ✅
2. Make sure REST Api are still able to fetch relations ==> won't do, we
have a coupling Get/Update/Create there, this requires refactoring
3. Make sure REST Api is still able to update / remove relation => won't
do same
## Automated tests
1. lint + typescript ✅
2. front unit tests: ✅
3. server unit tests 2 ✅
4. front stories: ✅
5. server integration: ✅
6. chromatic check : expected 0
7. e2e check : expected no more that current failures
## Remove // Todos
1. All are captured by functional tests above, nothing additional to do
## (Un)related regressions
1. Table loading state is not working anymore, we see the empty state
before table content
2. Filtering by Creator Tim Ap return empty results
3. Not possible to add Tasks / Notes / Files from show page
# Result
## New seeds that can be easily extended
<img width="1920" alt="image"
src="https://github.com/user-attachments/assets/d290d130-2a5f-44e6-b419-7e42a89eec4b"
/>
## -5k lines of code
## No more 'metadata' dataSource (we only have 'core)
## No more relationMetadata (I haven't drop the table yet it's not
referenced in the code anymore)
## We are ready to fix the 6 months lag between current API results and
our mocked tests
## No more bug on relation creation / deletion
---------
Co-authored-by: Weiko <corentin@twenty.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
This PR introduces LINKS and EMAILS sub-field filtering. It's mainly
about the implementation of secondaryLinks and additionalEmails
sub-fields, which are treated like additionalPhones.
There's also a refactor on the computeViewRecordGqlOperationFilter, a
big file that becomes very difficult to read and maintain. This PR
breaks it down into multiple smaller utils. There's still work to be
done to clean it as it is a central part of the record filter module,
this PR lays the foundation.
This PR cleans up after the refactor of selected filter state and apply
filter logic on record filter.
Since everything is now using the new
objectFilterDropdownCurrentRecordFilter state to derive the value for
all types, we don't need to maintain states for selected record ids and
selected options and the ViewBarFilterEffect that was initializing them.
Details :
- Removed objectFilterDropdownSelectedRecordIdsComponentState
- Removed objectFilterDropdownSelectedOptionValuesComponentState
- Removed ViewBarFilterEffect
This PR refactors the generic module object dropdown filter input.
We have multiple components for each filter type and each one was using
selectedFilterState and the applyRecordFilter hook to read and set its
value.
The main issue was that each component was forced to pass every property
of a RecordFilter to applyRecordFilter to only modify the value
property, thus creating a lot of unnecessary dependencies and tight
coupling between every component and hook that used the record filters.
Now we have each component only reading from a new
objectFilterDropdownCurrentRecordFilterComponentState, scoped to a
ObjectFilterDropdownComponentInstanceContext, thus whether we're in a
view bar dropdown, an editable filter chip dropdown or an advanced
filter dropdown, we know where to read the filter value from.
This component state might even be simplified by only storing the record
filter id, thus avoiding having to synchronize this state with its
counterpart in currentRecordFilterComponentState, but we should try
after the main refactor effort, as those two states aren't in the same
instance context.
We implement a new applyObjectFilterDropdownFilterValue hook to handle
the value setting from an object filter dropdown input component.
There's also a new useApplyObjectFilterDropdownOperand for doing the
same but for operand.
Another important thing that had to be done to keep a synchronous code
path was to set the states of each advanced filter row at the advanced
filter dropdown onOpen event, using useSetAdvancedFilterDropdownStates.
Finally we remove : useApplyRecordFilter, useSelectFilterUsedInDropdown
and selectedFilterComponentState which were making all of this zone
difficult to work with.
Closes https://github.com/twentyhq/core-team-issues/issues/718
Closes https://github.com/twentyhq/core-team-issues/issues/720
**Context**
When creating a new object, it creates the "All ...." view associated.
After new object is created, in `PrefetchRunViewQueryEffect`,
findManyViews returns cached results WITHOUT the new view.
git bisect - regression introduced with
https://github.com/twentyhq/twenty/pull/10272
**Attempt** : Update to 'network-only' fetch policy in
`PrefetchRunViewQueryEffect` -> not working on useQuery apollo hook (🤯)
: query is handle by cache and not network
**Solution**
Based on pattern used for view creation
(`useCreateViewFromCurrentView`), refreshing the view cache with a
`useLazyFindManyRecords` solves the issue. Then, `prefetchViewsState` is
updated in `PrefetchRunViewQueryEffect`
closes : https://github.com/twentyhq/core-team-issues/issues/845
This PR implements a new clean parallel code path for handling the
filter manipulated in an object filter dropdown.
Remember that the object filter dropdown module is the generic, shared
module, that must be vertically implemented in those places : view bar
filter button, record table column header cell, view bar details filter
chip.
So here we implement, just for the text filter input (for example a
FULL_NAME field type), a new parallel code path logic, that runs on a
new state : objectFilterDropdownCurrentRecordFilterState
We still update the selectedFilter state, that is very close to the new
objectFilterDropdownCurrentRecordFilterState, but in order to be
cautious, and allow us to refactor incrementally, we implement a new
parallel code path and let the rest run on selectedFilterState for now.
The new way of working with the filter in the object filter dropdown,
includes smaller and more specific hooks :
- useApplyObjectFilterDropdownFilterValue instead of applyRecordFilter
which API generates a lot of tech debt
- useObjectFilterDropdownFilterValue to get the current value (might be
later removed if too thin)
- useUpsertObjectFilterDropdownCurrentFilter, to abstract a bit some
duplicated logic in useApplyObjectFilterDropdownFilterValue
- useCreateRecordFilterFromObjectFilterDropdownCurrentStates which
differs from the existing
useCreateEmptyRecordFilterFromFieldMetadataItem in that it uses the
current states instead of creating an empty filter with default values.
Those two logics are still very confusing and duplicated everywhere,
creating specific hooks makes it clear now.
This PR shouldn't cause any change in the behavior of the filtering
feature.
Fixes https://github.com/twentyhq/core-team-issues/issues/717
This PR is refactoring a part of the ongoing filter refactor that was
blocking other refactor in that area.
Precisely, the dropdown filter that was used with the editable filter
chip was initialized by two conflicting useEffect, causing many unwanted
and hard to tackle bugs when modifying other places in the code that
used the same dropdown.
We also remove a difficult to maintain pattern around
onToggleColumnFilterComponentState, which was storing a click handler in
a state, we want to avoid this pattern.
The hook useHandleToggleColumnFilter is also removed and replaced by
useOpenRecordFilterChipFromTableHeader.
The code is now synchronous and starts from the user click event that is
triggered on a table cell header filter button click.
Also :
- Created a useSetEditableFilterChipDropdownStates that allows to
separate the code path of filter chip dropdown from the code path of
view bar global filter dropdown (will be continued in another refactor)
- Added useCreateEmptyFilterFromFieldMetadataItem to abstract empty
filter creation when opening a filter dropdown (will be used for other
refactor)
- Created a useOpenDropdownFromOutside hook that will also be used for
other refactor on filter
- Deleted EditableFilterDropdownButtonEffect
- Removed call to ViewBarFilterEffect (will be completely removed in
other refactors)
This PR implements what's missing to have sub-field filtering.
There is a backend modification to save subFieldName, we just add this
field on view filter workspace entity.
This PR adds subFieldName where missing in frontend, notably in
applyFilter calls, that will be refactored soon.
Also fixes a bug in ViewBar where Add Filter button was at the right
side of the ViewBar, while it should be right after the chips section.
Another bug fixed where we wouldn't delete an empty record filter on
dropdown click outside from the view bar, which was already the case
where using the filter chip dropdown.
<img width="512" alt="image"
src="https://github.com/user-attachments/assets/e9a2f8d2-a66f-4800-853a-4df5c6b627a9"
/>
<img width="495" alt="image"
src="https://github.com/user-attachments/assets/7542697b-0689-4095-9c3c-b5e47875355f"
/>
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
This PR fixes a bug that happened when navigating to a filtered view
from a record show page related record section, clicking on 'All'.
The problem was that the QueryParamsFiltersEffect effect component was
overwriting the currentRecordFilter of a different object metadata item
than the current view.
Which when we navigated back on the original view, had emptied the
filters, while they shouldn't change if we only navigate without
refreshing the app.
Fixes https://github.com/twentyhq/core-team-issues/issues/657
# Introduction
In this PR we've migrated `twenty-shared` from a `vite` app
[libary-mode](https://vite.dev/guide/build#library-mode) to a
[preconstruct](https://preconstruct.tools/) "atomic" application ( in
the future would like to introduce preconstruct to handle of all our
atomic dependencies such as `twenty-emails` `twenty-ui` etc it will be
integrated at the monorepo's root directly, would be to invasive in the
first, starting incremental via `twenty-shared`)
For more information regarding the motivations please refer to nor:
- https://github.com/twentyhq/core-team-issues/issues/587
-
https://github.com/twentyhq/core-team-issues/issues/281#issuecomment-2630949682
close https://github.com/twentyhq/core-team-issues/issues/589
close https://github.com/twentyhq/core-team-issues/issues/590
## How to test
In order to ease the review this PR will ship all the codegen at the
very end, the actual meaning full diff is `+2,411 −114`
In order to migrate existing dependent packages to `twenty-shared` multi
barrel new arch you need to run in local:
```sh
yarn tsx packages/twenty-shared/scripts/migrateFromSingleToMultiBarrelImport.ts && \
npx nx run-many -t lint --fix -p twenty-front twenty-ui twenty-server twenty-emails twenty-shared twenty-zapier
```
Note that `migrateFromSingleToMultiBarrelImport` is idempotent, it's atm
included in the PR but should not be merged. ( such as codegen will be
added before merging this script will be removed )
## Misc
- related opened issue preconstruct
https://github.com/preconstruct/preconstruct/issues/617
## Closed related PR
- https://github.com/twentyhq/twenty/pull/11028
- https://github.com/twentyhq/twenty/pull/10993
- https://github.com/twentyhq/twenty/pull/10960
## Upcoming enhancement: ( in others dedicated PRs )
- 1/ refactor generate barrel to export atomic module instead of `*`
- 2/ generate barrel own package with several files and tests
- 3/ Migration twenty-ui the same way
- 4/ Use `preconstruct` at monorepo global level
## Conclusion
As always any suggestions are welcomed !
This PR mainly fixes advanced filters on kanban view.
It also fixes various bugs and cleans some old states.
## Advanced filters on kanban views
Kanban views use a different hook to retrieve data from the backend :
useLoadRecordIndexBoardColumn, this hook wasn't using the new state
currentRecordFilterGroupsComponentState.
## Removal of confusing duplicate states
A few different states were used for filters and states, where we only
need one for filters and one for sorts for all indexes. So we remove
here the different states that can lead to confusion about what state
should be used in what case.
States removed :
- recordIndexFilterState
- recordIndexSortState
- recordIndexViewFilterGroupsState
- tableFiltersComponentState
- tableSortsComponentState
We also remove the logic that was used to manage those states.
## Abstracted non composite field type check into a util
We abstract the check made in mapFieldMetadataToGraphQLQuery into a util
isNonCompositeField, because those kinds of checks should be stored into
a separate unique file that acts as a source of truth.
## Bug with advanced filter rule position not saved
The position of an advanced filter rule wasn't correctly saved in the
backend, here we remove the WorkspaceIsSystem decorator on the
positionInViewFilterGroup fields.
The function that saved view filters was also ignoring the field
positionInViewFilterGroup, we add it back.
## Bug with view picker option dropdown closing weirdly
The view picker option dropdown was closing as soon as we hovered
outside of the option dropdown, which was annoying for the user, here we
apply the same behavior as every dropdown in the app : closing on click
outside.
This PR fixes many bugs on advanced filters, the goal here was to have
CRUD working with other simple filters and sorts.
In order to test this PR you'll have to run a sync metadata.
Fixes https://github.com/twentyhq/core-team-issues/issues/560
## Changed positionInViewFilterGroup field metadata type
This PR changes the type of positionInViewFilterGroup to NUMERIC instead
of POSITION, there certainly was a confusion during the initial
development, where POSITION type seemed relevant but it is not for this
particular feature because the position in a view filter group is not
the position of a record, which is used for displaying and re-ordering
purpose in table and kanban views.
Here the positionInViewFilterGroup is a specific position concept tied
to a custom feature, and it is handled by the specific logic of this
advanced filter dropdown layout.
## Create new ids when duplicating a view
When we use create view from an existing view, the logic in
useCreateViewFromCurrentView will copy over filters, filter groups and
sorts. The problem is that it copies it with the same ids, and that if
the backend manages somehow to create new ids, the ids that are put in
parentViewFilterGroupId are corresponding to the old filter groups not
the duplicated new ones.
So we had to create a map of old id => new id so that everything that
has to be sent to the backend for creation already has the same mapping
of parent id but with new ids generated by the frontend.
## Bug with creating a simple filter
We couldn't create a simple filter when advanced filters were set, this
was because of findDuplicateRecordFilterInNonAdvancedRecordFilters which
wasn't doing what it's naming tells, it wasn't filtering on simple
filters only before looking for duplicates.
## Clean code
- Use lastChildPosition directly from
useChildRecordFiltersAndRecordFilterGroups instead of drilling it down
- Refactored AdvancedFilterDropdownButton to extract the code lower
where it is really needed in AdvancedFilterChip
- Renamed a few View to Record naming where relevant
This PR removes the legacy useGetCurrentView hook that still returned
view with combined filters and sorts, which we don't use anymore.
This allows to remove a bug where we couldn't select the "open in"
settings of a view.
This PR partially fixes advanced filters that were not working even with
feature flag activated.
Bugs fixed here :
- Advanced filters are not applied
- Root advanced filters cannot be created
- Cannot close advanced filters dropdown
- Can create multiple times the same non-advanced filter (reserved for
advanced filters)
upsertRecordFilter and removeRecordFilter have been refactored to take
record filter id instead of field metadata id, because the user should
be allowed to apply multiple filters for the same field.
We now base view filter CRUD directly on id, otherwise it could lead to
inconsistencies between advanced filters and simple filters.
This PR also refactors an important hook :
computeRecordGqlOperationFilter, so that it takes an object instead of
multiple params.
There are still bugs left, they will be taken in other PRs.
This PR implements CRUD for view filter groups with the new logic as
already done for view filters and view sorts.
It also completely removes the old combined view filter group states and
usage.
This PR is quite big but the impact is limited since it only changes
advanced filters module, which is under feature flag at the moment, and
it is already in a broken state so unusable, even if someone activates
the feature flag.
This PR implements hooks and utils logic for handling CRUD and view
filter group comparison.
The main hook is useAreViewFilterGroupsDifferentFromRecordFilterGroups,
like view filters and view sorts.
Inside this hook we implement getViewFilterGroupsToCreate,
getViewFilterGroupsToDelete and getViewFilterGroupsToUpdate.
All of those come with their unit tests.
In this PR we also introduce a new util to prevent nasty bugs happening
when we compare undefined === null,
This util is called compareStrictlyExceptForNullAndUndefined and it
should replace every strict equality comparison between values that can
be null or undefined (which we have a lot)
This could be enforced by a custom ESLint rule, the autofix may also be
implemented (maybe the util should be put in twenty-shared ?)
This PR removes what's left from record filter and record sort previous
logic to handle CRUD and state management with view.
So everything that is named combinedFilter and combinedSort is removed
here.
We implement currentRecordFilters and currentRecordSorts everywhere.
We also remove the event in a state onSortSelectComponentState. (a
pattern we want to avoid)
This PR implements new record sorts CRUD as already done on record
filters, which is based on record sorts state instead of combined view
sorts.
It implements a new useSaveRecordSortsToViewSorts with its underlying
utils, to compute diff between two view sorts array.
The associated unit tests have also been written.
This PR also fixes the bug where the view bar disappeared when deleting
the already saved record sort of a view.
Closes https://github.com/twentyhq/core-team-issues/issues/410
- Added `openRecordIn` column in the `view` entity, which is set to
`SIDE_PANEL` by default
- Created a new option inside the view option dropdown to be able to set
`openRecordIn`
- Updated all record show page openings to reflect the setting behavior
- For `workflow`, `workflowVersion` and `workflowRun` (what I call
workflow objects), we want the default view `openRecordIn` to be set to
`RECORD_PAGE`. When seeding the views for the new workspaces, we set
`openRecordIn` to `RECORD_PAGE` for workflow objects. Since the workflow
objects views `openRecordIn` will be set to the default value
`SIDE_PANEL` for the existing workspaces when the sync metadata runs, I
created a script to run in the 0.43 update to update this value.
- Updated `closeCommandMenu` because of problems introduced by the
animate presence wrapper around the command menu. We now reset the
states at the end of the animation.
Note: We want to be able to open all workflow objects pages in the side
panel, but this requires some refactoring of the workflow module. For
now @Bonapara wanted to allow the possibility to change the
`openRecordIn` setting to `SIDE_PANEL` even for the workflows even if
it's buggy and not ready for the moment. Since this is an experimental
feature, it shouldn't cause too many problems.
This PR adds the same synchronization utils and hooks from view to
record sorts, as we did with view and record filters.
The goal is to apply what's in the view sorts only when needed.
Also added tests for those utils and hooks.
We also add useRemoveRecordSorts.
This PR implements a parallel code path to set record sorts without
impacting the actual sort, like we did on record filter.
We add a ViewBarRecordSortEffect which mirrors
ViewBarRecordFilterEffect.
It also adds availableFieldMetadataItemsForSortFamilySelector to replace
sortDefinitions progressively.
In this huge (sorry!) PR:
- introducing objectMetadataItem in contextStore instead of
objectMetadataId which is more convenient
- splitting some big hooks into smaller parts to avoid re-renders
- removing Effects to avoid re-renders (especially onViewChange)
- making the view prefetch separate from favorites to avoid re-renders
- making the view prefetch load a state and add selectors on top of it
to avoir re-renders
As a result, the performance is WAY better (I suspect the favorite
implementation to trigger a lot of re-renders unfortunately).
However, we are still facing a random app freeze on view creation. I
could not investigate the root cause. As this seems to be already there
in the precedent release, we can move forward but this seems a urgent
follow up to me ==> EDIT: I've found the root cause after a few ours of
deep dive... an infinite loop in RecordTableNoRecordGroupBodyEffect...
prastoin edit: close https://github.com/twentyhq/twenty/issues/10253
---------
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: prastoin <paul@twenty.com>
In this PR, I'm simplifying the lastVisitedView / Object logic:
- removing fallback logic as it's not useful
- splitting hooks into smaller hooks (to avoir re-renders)
- removing componentState on those states that are global
This PR essentially removes the usage of filterDefinition.type, by
replacing it with fieldMetadataItem.type derivation. Thus allowing to
completely remove filterDefinition later on.
In computeFilterRecordGqlOperationFilter, emptyOperationFilter is now
returned before going into the big switch case. This avoids repeating
the same exact call to getEmptyRecordGqlOperationFilter for each type.
Fixed some tests that need
getJestMetadataAndApolloMocksAndActionMenuWrapper to have record filters
properly working with the new implementation. We'll probably want to
refactor the record context store, record index context, etc.
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
# Introduction
At the moment when updating any record cache occurence, we will build a
fragment that will expect all of the object metadata item fields to be
provided.
Which result in the following traces: ( in the video companies aren't
fetch with companyId and other missing fields )
https://github.com/user-attachments/assets/56eab7c1-8f01-45ff-8f5d-78737b788b92
By definition as we're using graphql we might not request every record's
fields each time we wanna consume them.
In this way we will now dynamically compute or expect depending on the
CRUD operation specific fields to be written in the cache, and not all
of them
Tested all optimistic and failure management use cases
## Covering cache
Added coverage only for the `deleteOne` and `deleteMany` hooks, it cover
only the record record cache and not its relations hydratation ( for the
moment )
## Why not closing #9927
Unless I'm mistaken everything done here have fixed the same logs/traces
issue for updates and deletion but not creation.
Which means we still need to investigate the mass upload from import and
prefillRecord behavior
In a nutshell: went over each `updateRecordFromCache` calls, still need
to do all `createRecordInCache` calls
related to #9927
## Conlusion
Sorry for the big PR should have ejected into a specific one for the
`MinimalRecord` refactor
Will also continue covering others hooks later in my week as for the
`deleteOne`
As always any suggestions are welcomed !
This PR progressively introduces fieldMetadataItemUsedInDropdown instead
of filterDefinitionUsedInDropdown where most easy to replace.
This allows to use `fieldMetadataItemUsedInDropdown.id` instead of
`filterDefinition.fieldMetadataId`, which is one easy dependency to
remove on filter definition.
We still derive filterDefinition instead of fully replacing it, because
it will be easier to remove RecordFilterDefinition usage in a bottom-up
approach instead.
In multiple components of the filter dropdown, we try to replace
filterDefinition by fieldMetadataItem derivation : Icon, label, id,
type, etc.
We also introduce the usage of subFieldNameUsedInDropdown instead of
storing it dynamically on filterDefinition, for handling filtering on
composite sub fields.
The method `formatFieldMetadataItemAsFilterDefinition()` that is used to
derive filterDefinition from fieldMetadataItem is what was being used
originally to create the availableFilterDefinition state. (That is
already removed)
Fixed associated unit tests accordingly.
# Introduction
When we create a new `view` from record table that has relation such as
opportunities.
Encountered invariant conditions:
## Unknown fiel `__typename`
`Should never occur, encountered unknown fields __typename in
objectMetadaItem viewGroup`,
### Fixed by ignoring unknown internal fields
## Provided both relation `view` and `viewId`
`Should never provide relation mutation through anything else than the
fieldId e.g companyId and not company, encountered: view`
### Fixed by sending only `viewId` to `createManyRecords` in
`usePersistViewGroupRecords.ts`
# Introduction
Added the `RecordAction` destroy multiple record
## Repro
Select multiples `deletedRecords`, you should be able to see the
`Destroy` pinned CTA ( iso short label with the destroy one ), open
control panel and fin new CTA `Permanently delete records`
https://github.com/user-attachments/assets/31ee8738-9d61-4dec-9a1f-41bb6785e018
## TODO
- [ ] Gain granularity within tests to assert the action should be
registered only when filtering by deleted
## Conclusion
Closes https://github.com/twentyhq/core-team-issues/issues/110
The global record filter refactor will derive everything at runtime from
objectMetadataItemsState, thus removing the need for a filter definition
concept.
Here we don't yet remove available filter definition usage but we
replace the available filter definitions states, we now derive the same
value from objectMetadataItemsState.
This will allow us to progressively remove the usage of the concept of
filter definition, at the end it will then be easy to just remove from
the codebase because nothing will use it anymore.
# Introduction
Avoid having multiple `isDefined` definition across our pacakges
Also avoid importing `isDefined` from `twenty-ui` which exposes a huge
barrel for a such little util function
## In a nutshell
Removed own `isDefined.ts` definition from `twenty-ui` `twenty-front`
and `twenty-server` to move it to `twenty-shared`.
Updated imports for each packages, and added explicit dependencies to
`twenty-shared` if not already in place
Related PR https://github.com/twentyhq/twenty/pull/9941
This PR refactors the record filter saving to view filters.
Before we used states to track the change of view filters, now we just
check if there's a difference between the current record filters and the
current view filters before saving.
We also use this check to show the reset and save buttons.
CRUD operations to perform on view filters are computed by utils , and .
Also added unit tests on those utils.