This PR implements a first real use case, now currentRecordFilters
component state acts as the global record filter reference.
It is set by the view initially and can be reset to view filters state
at any point.
This new state is also modified by two new upsertRecordFilter /
removeRecordFilter hooks that will be drop-in replacement of the actual
upsertCombinedViewFilter and removeCombinediewFilter hooks.
This PR implements the logic to manipulate record filters but only reads
it to make the table find many request, all other features are still
relying on the old view filter implementation.
Advanced filters are ignored because they are hidden and because this
effort is made precisely to allow the completion of the advanced filters
feature.
- Created an new component state
`isRecordEditableNameRenamingComponentState`
- Updated `useCreateNewTableRecord` to open the ShowPage on workflow
creation
- Refactored `RecordEditableName` and its components to remove the
useEffect (This was causing the recordName state to be updated after the
focus on `NavigationDrawerInput`, but we want the text so be selected
after the update).
- Introduced a new component `EditableBreadcrumbItem`
- Created an autosizing text input: This is done by a hack using a span
inside a div and the input position is set to absolute and takes the
size of the div. There are two problems that I didn't manage to fix:
If the text is too long, the title overflows, and the letter spacing is
different between the span and the input creating a small offset.
https://github.com/user-attachments/assets/4aa1e177-7458-4691-b0c8-96567b482206
New text input component:
https://github.com/user-attachments/assets/94565546-fe2b-457d-a1d8-907007e0e2ce
Before the `recordIndexId` was the name plural. This caused problems
because the component states were the same for every view of an object.
When we switched from one view to another, some states weren't reset.
This PR fixes this by:
- Creating an effect at the same level of page change effect to set the
`currentViewId` inside the object `contextStore`
- Adding the `currentViewId` to the `recordIndexId`
Follow ups:
- We need to get rid of
`packages/twenty-front/src/modules/views/states/currentViewIdComponentState.ts`
and use the context store instead
Fixes#9132
## Purpose
Currently, when navigating away from an index page and returning,
previously checked selections remain checked. This fix ensures the
selection context is properly reset on navigation.
## Changes
- Add `RecordIndexResetSelectionEffect` component to handle selection
cleanup
- Integrate effect into `RecordIndexPage`
- Uses existing `useResetTableRowSelection` hook to clear selections
## Testing
1. Go to any index page (e.g., Companies)
2. Select some records using checkboxes
3. Navigate to a detail page
4. Return to the index page
5. Verify that no records are selected
## Demo
I've recorded a short video demonstrating how this PR fixes the issue:
[Loom Video
Link](https://www.loom.com/share/72ca46a5dc194b5092e1944a985fa0d2?sid=55c95d8b-2376-4ac5-b406-6483aa7e341f)
Before fix: Selections persist after navigation
After fix: Selections are properly reset
---------
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
The DX is not great when you need to do a lot of database
resets/command.
Should we disable Typescript validation to speed things up? With this
and caching database:reset takes 1min instead of 2 on my machine.
See also: https://github.com/typeorm/typeorm/issues/4136
And #9291 / #9293
---------
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Closes#8978
- Added new options in the actions config files: `shortLabel`,
`availableOn`
- Added two actions: Navigate to previous records and Navigate to next
records
- Modified `useRecordShowPagePagination` to loop on records when we are
on first record and we hit previous or when we are on last record and we
hit next
- Introduced a new component state
`contextStoreCurrentViewTypeComponentState`
## Context
Refactored all single record actions so they can be defined by a config
file.
This refactoring is made with the idea that later the actions will be
stored in the database, so we needed a way to serialize them.
For each object we can define a config file, if an object has no config
file, it falls back to the default config.
I introduced action hooks, which return:
- `shouldBeRegistered`: `boolean` Whether the action should be
registered.
- `onClick`: `() => void` The code that will be executed when we click
on an action
- `ConfirmationModal`?: `React.ReactNode` (optional) The confirmation
modal which will be displayed on click
This PR also closes#8973
## Next steps
- Refactor multiple records actions
- Refactor no selection actions
- Add tests
Fix#8757
This PR is adding the Add new button on view groups.
Also this PR fix an issue where the pending record can be draggable, and
is causing error.
<img width="1119" alt="Screenshot 2024-12-10 at 4 24 43 PM"
src="https://github.com/user-attachments/assets/4fd01e99-c85e-4a06-a733-cbf3cc32957d">
It also start to issues with the way we're using Context.
We're initializing pretty much all Context like this:
```typescript
export const RecordTableContext = createContext<RecordTableContextProps>(
{} as RecordTableContextProps,
);
```
This is causing issues when by mistake we use the context like this
outside the Provider hierarchy:
```typescript
const context = useContext(RecordTableContext);
```
This is going to fail silently, and all the context variables become
undefined...
To fix this I've introduced an util called `createRequiredContext`, this
one is returning an array containing the provider and the hook to
retrieve the context.
The context is initialized to undefined inside this utility, this way we
can check if the value has been initialized with the provider to check
if we're inside it. It'll throw an error if this one is used outside the
provider.
The return values are properly typed, so `undefined` is not added to the
value of the Context.
I'll create a followup ticket to use this new utility function, if
that's ok and replace it everywhere in the codebase.
We can also consider adding a eslint rule to warn about the use of
`createContext` directly.
Closes#8929
Users with the feature flag `IS_PAGE_HEADER_V2_ENABLED` set to false
will still have the old behavior with the action bar.
To test the PR, test with and without the feature flag.
Something changed, which affected the Favorite folder picker checkbox
styles -- fixed it!
Cleaned up code in `CurrentWorkspaceMemberFavoritesFolders` - removed
redundant filtering since favorites are already filtered in
`usePrefetchedFavoritesData`.
Regarding issue #8569 - I am not sure what to do in this case. Since
Folders data is gated by a feature flag, we can't use it in
`CurrentWorkspaceMemberFavoritesFolders` to ensure the favorite section
renders with empty folders. Currently, the section only appears when at
least one favorite exists - may be leave this section open at all times
or fix this bug after removal of the feature flag?
---------
Co-authored-by: Nitin Koche <nitinkoche@Nitins-MacBook-Pro.local>
Co-authored-by: Charles Bochet <charles@twenty.com>
Fix#4244 and #4356
This pull request introduces the new "view groups" capability, enabling
the reordering, hiding, and showing of columns in Kanban mode. The core
enhancement includes the addition of a new entity named `ViewGroup`,
which manages column behaviors and interactions.
#### Key Changes:
1. **ViewGroup Entity**:
The newly added `ViewGroup` entity is responsible for handling the
organization and state of columns.
This includes:
- The ability to reorder columns.
- The option to hide or show specific columns based on user preferences.
#### Conclusion:
This PR adds a significant new feature that enhances the flexibility of
Kanban views through the `ViewGroup` entity.
We'll later add the view group logic to table view too.
---------
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Closes#7817
Added role attribute to the div element of the Chip component. This
assigns the role of "button" to the container, which is important for
accessibility. It indicates that this div should be treated as a button
by assistive technologies like screen readers.
---------
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.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
Issue Reference: Fixes#7105
Description:
This pull request introduces adjustments to the styling of the
RecordBoardColumnHeader component. The modifications enhance the layout
and visual consistency of the Kanban board headers.
Changes Made:
Margin Adjustment:
Increased the bottom margin from theme.spacing(2) to theme.spacing(6)
for better spacing below the header.
Header Container Enhancements:
Added a background color sourced from the theme
(theme.background.primary) to the header container for improved
visibility and aesthetics.
Set a fixed height of 40px for the header to ensure a consistent size
across different screens.
Applied a fixed position to the header container to keep it visible at
the top during scrolling.
Added padding at the top using theme.spacing(2) for better alignment of
content within the header.
Before :
https://github.com/user-attachments/assets/fd1c2d65-5e50-489a-a388-c0c4e1bd015b
Now :
[now.webm](https://github.com/user-attachments/assets/bd4cfb86-fc14-4902-b84c-99d27b07859e)
---------
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
Closes#7336
Create 3 states:
- `contextStoreCurrentObjectMetadataIdState`: is set when we change
object metadata
- `contextStoreCurrentViewIdState`: is set when we change view
- `contextStoreTargetedRecordIdsState`: is set when we select records
inside a table or a board or when a show page is opened. Is reset when
we change view.
In this PR:
- Refactored components to clarify their behavior. For example, I
renamed the `Workflow` component to `WorkflowVisualizer`. This moved
forward the issue #7010.
- Create two variants of several workflow-related components: one
version for editing and another for viewing. For instance, there is
`WorkflowDiagramCanvasEditable.tsx` and
`WorkflowDiagramCanvasReadonly.tsx`
- Implement the show page for workflow versions. On this page, we
display a readonly workflow visualizer. Users can click on nodes and it
will expand the right drawer.
- I added buttons in the header of the RecordShowPage for workflow
versions: users can activate, deactivate or use the currently viewed
version as the next draft.
**There are many cache desynchronisation and I'll fix them really
soon.**
## Demo
(Turn sound on)
https://github.com/user-attachments/assets/97fafa48-8902-4dab-8b39-f40848bf041e
Fix all the broken CIs :p
This includes an ongoing effort to simplify test maintenance by having 1
unique source of truth about metadata and data mocks (that will later be
generated from a unique source of seeds: dev = demo = test)
Regressions:
- Unit line coverage: 60 > 55
- Storybook Pages branch coverage: 40 > 35
We will need to write tests to increase those coverage
- RelationFieldDisplay perf: 0.2ms to 0.22ms > We might have a
regression here
- Removed perf story about RawJSON > We will need to re-add it
## Setup
This PR can be tested only if some feature flags have specific values:
- `IsWorkflowEnabled` equals `true`
- `IsQueryRunnerTwentyORMEnabled` equals `false`
These feature flags weren't committed to don't break other branches.
## What this PR brings
- Display buttons to activate and deactivate a workflow version and a
button to discard the current draft version. I also scaffolded a "Test"
button, which doesn't do anything for now.
- Wired the activate, deactivate and discard draft buttons to the
backend.
- Made it possible to "edit" active and deactivated versions by
automatically creating a new draft version when the user tries to edit
the version.
- Hide the "Discard Draft", button if the current version is not a draft
or is the first version ever created.
- On the backend, don't consider discarded drafts when checking if a new
draft version can be created.
- On the backend, disallow deleting the first created workflow version.
Otherwise, we will end up with a blank canvas in the front end, and it
will be impossible to recover from it.
- On the backend, disallow running deactivation steps if the workflow
version is not currently active. Previously, we were throwing, which is
unnecessary as it's a valid case.
## Spotted bugs that we must dive into
### Duplicate workflow versions in Apollo cache
https://github.com/user-attachments/assets/7cfffd06-11e0-417a-8da0-f9a5f43b84e2
---------
Co-authored-by: Charles Bochet <charles@twenty.com>
@Bonapara
Addressing issue #6783.
I tried to achieve the exact behavior you were looking for, but I
couldn't get the dropdown to render correctly in that specific column.
I'd love some help to make sure it's working as expected! 😊
Most of the logic is shared with the `useHandleOpportunity` and
`useAddNewCard` hooks, which could be refactored to reduce code debt.
Also, please go harsh with the review because I know there's a lot of
code cleaning required.
I also agree with Charles's point in [this
comment](https://github.com/twentyhq/twenty/issues/6783#issuecomment-2323299840).
Thanks :)
https://github.com/user-attachments/assets/bccdb3f1-3946-4e22-b9a4-b7496ef134c9
Closes#6657
- Fix listeners
- Refactor jobs to take array of events
- Fix calendar events and messages deletion
---------
Co-authored-by: Charles Bochet <charles@twenty.com>
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>
Closes#6434.
We don't want to override the values of the records' address or links as
they are composite field and it is costly to loose the data.
We will need a more unified behaviour here - maybe introduce a Ctrl+Z
option.
---------
Co-authored-by: Charles Bochet <charles@twenty.com>
In this PR, I am:
- removing a useEffect (we use the onCompleted prop of useFindManyQuery
hook)
- moving this logic into a RecordShowPageHeader to avoid re-renders of
the whole tree