Skip to content

Conversation

@personalizedrefrigerator
Copy link
Collaborator

@personalizedrefrigerator personalizedrefrigerator commented Nov 3, 2025

Summary

This pull request adds support for selecting multiple notebooks (or tags) in the sidebar on desktop.

Resolves #1556.

Notes

Currently supports:

  • Selecting multiple notebooks/tags using shift-up arrow and shift-down arrow.
  • Selecting multiple notebooks/tags with shift-click and cmd-click (MacOS) or ctrl-click (Windows/Linux).
  • Dragging and dropping multiple notebooks.
  • Moving multiple notebooks to a new location through right-click > move to notebook.
  • Deleting multiple notebooks to the trash.
  • Restoring multiple notebooks from the trash.
  • Deleting multiple tags.

Limitations

  • Fewer actions are available in the right-click menu when multiple notebooks are selected:

    Single-select Multi-select
    screenshot: menu items visible: new notebook, delete notebook, move to notebook, edit, then share notebook, export, toggle own sort order, and copy external link screenshot: Delete notebook and move to notebook shown in right-click menu
  • Confusing behavior: Selecting multiple notebooks or tags only shows items associated with one of the notebooks/tags in the notes list. In particular, only notes associated with the first selected notebook/tag are shown in the notes list.

  • Confusing behavior: Attempting to select both multiple notebooks and tags at the same time can lead to confusing behavior:

    Screencast.from.2025-11-04.15-43-33.webm

    Above, pressing ctrl-click to attempt to add a tag to the selection only visually hides the notebook selection. If a notebook is then added to the selection (again with ctrl-click), the notebook selection becomes visible again, with the notebook added with ctrl-click.

Screen recording

Screencast.from.2025-11-04.15-23-08.webm

The above screen recording demonstrates:

  • Selecting multiple tags, then deleting them through the right-click menu.
  • Selecting multiple notebooks, then moving them to a new location through the right-click menu.
  • Selecting multiple notebooks, then deleting them to the trash.
  • Selecting multiple notebooks in the trash, then restoring them.
  • Moving multiple notebooks through drag-and-drop.

Testing

In addition to the manual testing demonstrated by the screen recording above and the automated tests added by this pull request, I've verified that it's still possible to:

  • Right-click > "Leave notebook" on a shared notebook.
  • Right-click > "Share notebook" to share a notebook with another Joplin Server user.
  • Right-click > Rename a tag.
  • Right-click > export > JEX: Export a notebook as JEX.
  • Start the web app, switch folders, create a note in the current folder.
  • Start the web app, open the tags screen, then list notes associated with a tag.
  • Start the CLI app, create a new notebook, then create a note.
  • Start the CLI app, change the selected notebook, then edit an existing note.

@mrjo118
Copy link
Contributor

mrjo118 commented Nov 3, 2025

Will this add support for exporting a specific selection of notebooks?

@personalizedrefrigerator
Copy link
Collaborator Author

personalizedrefrigerator commented Nov 3, 2025

Will this add support for exporting a specific selection of notebooks?

Not currently, but that would make sense to add (in particular because a user might expect right-click > export to export all selected notebooks). At present, it supports:

  • Deleting multiple notebooks to the trash.
  • Dragging multiple notebooks to a new location.
  • Moving multiple folders to a new location with right-click "Move".
  • Restoring multiple notebooks from trash.

Other actions (e.g. sharing notebooks, exporting) use the primary selected notebook.

Edit: For now, the "Export" right-click menu is hidden when multiple notebooks are selected. If implemented, exporting multiple notebooks will probably be done in a separate pull request.

@personalizedrefrigerator personalizedrefrigerator marked this pull request as ready for review November 4, 2025 23:53
@personalizedrefrigerator personalizedrefrigerator changed the title Desktop: Support selecting multiple notebooks Desktop: Resolves #1556: Support selecting multiple notebooks Nov 4, 2025
Comment on lines +115 to +117
// All context folders
foldersAreDeleted: commandFolders.every(f => !!f.deleted_time),
foldersIncludeReadOnly: commandFolders.some(f => itemIsReadOnlySync(ModelType.Folder, ItemChange.SOURCE_UNSPECIFIED, f as ItemSlice, settings['sync.userId'], state.shareService)),
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New state variables that are computed from all command folders, rather than just one, have been added. Previous variables (e.g. folderIsTrash) continue to apply to the main selected/command folder.

Comment on lines -106 to +107
public commandToStatefulMenuItem(commandName: string, ...args: any[]): MenuItem {
const whenClauseContext = this.service.currentWhenClauseContext();
public commandToStatefulMenuItem(commandName: string, commandTarget?: any, options?: WhenClauseContextOptions): MenuItem {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactoring: commandToStatefulMenuItem now 1) forwards only one argument to the target command, 2) allows specifying the folder/note that the command applies to for the enabled/disabled state:

  • All uses of commandToStatefulMenuItem (code search) pass at most one argument to the command.
  • This allows creating a whenClauseContext for the items the command will act on, rather than the selection.
    • Basing the when clause context on the selection can be problematic if 1) the menu is being shown for an unselected folder, and/or 2) if the folder for the menu is in selectedFolderIds, but the selection isn't shown in the UI because a different item type is selected (e.g. a tag).

For example, this allows disabling the menu item for the deleteFolder command when one of the target folders is read-only, rather than basing this on the selection. (With this PR, it's still possible to right-click > delete unselected folders).

An alternative would be to refactor folderCommandToMenuItem (a new function in useOnRenderItem) to call commandToMenuItem directly.

className={`list-item-container ${selected ? 'selected' : ''}`}
highlightOnHover={true}
onDrop={props.onTagDrop}
onContextMenu={props.onContextMenu}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved onContextMenu: This is for consistency with the FolderItem component and allows the context menu event handler to access HTML properties defined by ListItemWrapper, including data-index. The onContextMenu event handler currently determines the source note/tag based on event.currentTarget.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Select multiple notebooks

2 participants