LibreChat/packages
Marco Beretta 0b995065bc
🗂️ feat: Rework the Projects Dashboard, Sidebar and Scoped Composer (#14866)
* style: Redesign the Projects Dashboard and Sidebar

Give /projects a sticky navbar, quieter search/sort toolbar, and
folder-style cards. Drop the create-dialog close control, restyle
the sidebar Projects row, and align the workspace with the same
layout language.

* feat: Edit a Project Name and Description

Add a shared edit dialog so a project can be renamed and given a
description from the workspace or the sidebar menu. The create flow
already stored descriptions; this is the matching update path.

* feat: Delete a Project from the Workspace

Extract the project delete confirmation into a shared dialog and
expose it on the workspace header so deleting no longer requires
the sidebar menu.

* feat: Add Edit and Delete Actions to Project Cards

Give dashboard cards a more-options menu that opens the same edit
and delete dialogs as the workspace, so those actions are not
workspace-only.

* feat: Match Project Descriptions When Searching Projects

Project search only matched the name, so a project found by its
description was invisible in the sidebar and the projects dashboard.
Match the escaped search term against name or description.

* feat: Let Consumers Place and Size the ControlCombobox Popover

The popover always matched the trigger width, sat 4px from it and used
the same enter animation, which is wrong for a pill-shaped trigger in a
composer and for a full-width field in a dialog.

Add popoverClassName, matchTriggerWidth, gutter and portal so a consumer
can opt out of each. All four keep the current behaviour by default, so
existing comboboxes are unchanged; portal in particular stays true, as
turning it off inside a scrollable dialog would clip the list.

* fix: Re-render Conversation Rows When Pinned State Changes

areConversationListItemFieldsEqual left pinned out of its comparison, so
a row memoised on it kept rendering the stale pin state until some other
tracked field changed.

* fix: Keep the Project Scope When Starting a Chat From a Project

Starting a chat from the project workspace set chatProjectId on the
draft but left the URL on the unscoped route, so a reload or a refresh
of the route dropped the project. Navigate to the project-scoped new
chat URL alongside the draft.

* style: Move the Project Chip Into the Composer

The chip floated above the composer as a separate row, which read as an
unrelated control and pushed the conversation starters down. Render it
inside the composer border as the first row instead, and pass the
project through ChatForm so the memoised form still controls it.

The remove button no longer fades in on hover, since a control that only
appears on hover is unreachable by touch. Its popover opens upward with
a matching bottom-origin animation that honours reduced motion.

* feat: Rebuild the Change Project Dialog on the Searchable Combobox

The dialog used a bare select, so picking a project meant scrolling an
unsearchable native list capped at the default page of 25. Use the
searchable ControlCombobox, request the full first page, and disable
Save until the selection actually differs from the current project.

The combobox opts out of portalling so its search field sits inside the
dialog's focus trap and can be typed in, and the dialog is
overflow-visible so the list is not clipped.

Unassigning now lives on the menu's own Remove From Project action, so
the dialog no longer needs an empty option. Returning focus to the menu
button rather than the menu item fixes focus being lost on close, since
the item unmounts with the menu.

* feat: Add an Overflow Menu to Project Workspace Chats

Chats in a project workspace could only be opened. Managing one meant
finding it again in the sidebar, so add the same actions to the row:
change project, remove from project, and delete.

The row becomes a card matching the project cards, and the endpoint icon
is rendered at landing size rather than in a tinted tile. Its memo
comparison now uses areConversationListItemFieldsEqual, since the render
props comparison ignored fields the row displays.

* feat: Rework the Projects Sidebar Section

The section header duplicated the projects count and the New Project
action already on the dashboard, and spent a row on a chevron button
separate from its label. Collapse it to a single label toggle with an
All Projects action, and drop the per-project count that was hidden on
hover anyway.

The new chat action becomes a real link to the project-scoped URL, so it
can be middle-clicked and opened in a new tab, and modified clicks fall
through to the browser. On the new chat route it commits ?projectId
synchronously, because a deferred search param update lets ChatRoute see
a project-scoped draft on an unscoped URL and wipe it.

Row actions stay visible on devices without hover, where an action that
appears on hover cannot be reached.

* style: Widen the Projects Dashboard and Workspace Layout

The dashboard and the workspace sat on bg-surface-primary at different
max widths, so moving between them shifted the content and the shade did
not match the rest of the app. Put both on bg-presentation at max-w-6xl.

Project and chat cards gain a border, since colour alone separated them
from the background and that separation is thin in light mode. The
translucent blurred headers become opaque, and the scale-on-press
transforms are dropped.

In the workspace the edit and delete actions move out of the heading row
into their own group, so a long project name no longer pushes them
around.

* fix: Reopen the Change Project Dialog From the Conversation Menu

Closing the Ariakit menu in the same handler that opens the dialog made
the menu's own dismissal land on the freshly mounted Radix dialog, which
closed it again before paint, so Change project did nothing.

Leave the menu close to the dialog, which already receives setMenuOpen
and closes it once the assignment succeeds, matching the share and
delete handlers beside it.

* fix: Keep the Project Chat Menu Mounted While its Dialogs Open

Hiding the Ariakit menu in the same handler that opens Change project or
Delete restores focus to the menu trigger, which the dialog mounting
alongside it reads as an outside interaction and closes on, so the
action could do nothing.

Both dialogs already receive setIsMenuOpen and close the menu once they
finish, so leave the close to them, as the conversation menu does.

* perf: Fetch a Project's Chats Only Once its Row is Expanded

Collapse hides its children with CSS and inert rather than unmounting
them, so every project row's chat query ran on sidebar load, up to one
request per project, even with the whole section collapsed.

Gate the query on the row's expanded state. React Query keeps what it
already fetched, so reopening a row is still instant.

* refactor: Move the Bottom Popover Animation Into the Shared Primitive

ControlCombobox owns its popover animations in AnimatePopover.css, so
the upward variant it needs belongs there rather than in the
application stylesheet, where the control's appearance would diverge
from the package that ships it.

The app already loads the package stylesheet, so the animation resolves
the same way the existing variants do.

* fix: Stop Project Names and Descriptions Being Silently Truncated

The dialogs accepted any length and reported success, while the
persistence layer trimmed names to 100 and descriptions to 1000
characters, so reopening a project revealed text had been dropped with
no warning.

Share both limits from data-provider and cap the inputs at them, so the
fields stop where the server would have cut them and the rule has one
definition instead of the three it had.

* fix: Do Not Report the Loaded Page Size as the Project Total

The dashboard counted the projects fetched so far, so an account with
more than one page read as exactly one page's worth and the supposed
total grew with each Load more.

Show the loaded count as a lower bound while another page exists.

* chore: Satisfy the Static Checks for the Projects Rework

Sort the delete dialog's imports to the repository order, and drop the
three English keys this branch orphaned: the sidebar menu now says Edit
project, the dashboard labels its own sort control, and the change
project dialog no longer offers an Unassigned option now that removal
lives on the menu.

* fix: Highlight Only the Route Project in the Sidebar

A leftover conversation project was still lighting a second row after
opening another project's workspace. Prefer the workspace route, and
only fall back to the conversation project outside that view.
2026-08-16 11:06:18 -04:00
..
api 🎯 refactor: Infer Agents Endpoint for Model Specs Naming an Agent (#14889) 2026-08-16 11:04:52 -04:00
client 🗂️ feat: Rework the Projects Dashboard, Sidebar and Scoped Composer (#14866) 2026-08-16 11:06:18 -04:00
data-provider 🗂️ feat: Rework the Projects Dashboard, Sidebar and Scoped Composer (#14866) 2026-08-16 11:06:18 -04:00
data-schemas 🗂️ feat: Rework the Projects Dashboard, Sidebar and Scoped Composer (#14866) 2026-08-16 11:06:18 -04:00