Skip to content

Fix bulk imports adding entries to navigation history#14575

Merged
koppor merged 29 commits into
JabRef:mainfrom
shubhamk0205:fix-for-issue-13878-v2
Jan 26, 2026
Merged

Fix bulk imports adding entries to navigation history#14575
koppor merged 29 commits into
JabRef:mainfrom
shubhamk0205:fix-for-issue-13878-v2

Conversation

@shubhamk0205

@shubhamk0205 shubhamk0205 commented Dec 11, 2025

Copy link
Copy Markdown
Contributor

Closes #13878

Prevent bulk import operations from polluting the navigation history. When multiple entries are imported at once, automatic selection changes are now suppressed from being recorded in the navigation history. This ensures that only user-driven navigation actions are tracked, keeping the Back/Forward buttons functional and predictable.

Steps to test

  1. Open JabRef and create a new library
  2. Import multiple entries at once (e.g., via File → Import → BibTeX, or drag-and-drop multiple .bib files)
  3. After the import completes, verify that:
    • The Back/Forward navigation buttons remain disabled (or show the correct state based on actual user navigation, not the bulk import)
    • Manually selecting different entries adds them to navigation history as expected
    • Using Back/Forward buttons only navigates through entries you actually visited, not entries from the bulk import

Expected behavior: Bulk imports should not enable Back/Forward navigation or add entries to navigation history. Only manual entry selections should affect navigation history.

Mandatory checks

  • I own the copyright of the code submitted and I license it under the MIT license
  • I manually tested my changes in running JabRef (always required)
  • I added JUnit tests for changes (if applicable)
  • [/] I added screenshots in the PR description (if change is visible to the user)
  • I described the change in CHANGELOG.md in a way that is understandable for the average user (if change is visible to the user)
  • [/] I checked the user documentation: Is the information available and up to date? If not, I created an issue at https://github.com/JabRef/user-documentation/issues or, even better, I submitted a pull request updating file(s) in https://github.com/JabRef/user-documentation/tree/main/en.
Fixed.issue.mp4

@subhramit

Copy link
Copy Markdown
Member

Please add a video of the fixed functionality.

@koppor koppor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a follow up to #14550

Architecture wrong. We commented at the other PR. Please re-think

@github-actions github-actions Bot added the status: changes-required Pull requests that are not yet complete label Dec 12, 2025
@shubhamk0205 shubhamk0205 force-pushed the fix-for-issue-13878-v2 branch 2 times, most recently from 239209f to a8a68c2 Compare December 14, 2025 13:23
@shubhamk0205

Copy link
Copy Markdown
Contributor Author

the jablib unit test is failing for a file i haven't changed
file - org.jabref.logic.bibtex.comparator.MetaDataDiffTest at line 55

@shubhamk0205

Copy link
Copy Markdown
Contributor Author

also @subhramit i have added the video please review it .

Comment on lines -352 to -358
.forEach(linkedFile ->
new LinkedFileViewModel(
linkedFile,
entry,
targetBibDatabaseContext,
taskExecutor,
dialogService,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

please revert all the unrelated formatting changes throughout the PR.
Also, you can run the respective tests locally to check if they are passing (unit, openrewrite, etc) instead of pushing dummy commits for triggering ci. This causes unnecessary noise to those subscribed to the PR.

@github-actions github-actions Bot removed the status: changes-required Pull requests that are not yet complete label Dec 15, 2025
@shubhamk0205 shubhamk0205 requested a review from koppor December 15, 2025 02:06
@subhramit

Copy link
Copy Markdown
Member

@shubhamk0205 you have pushed some commits but on checking files changed, it appears you have not acted on the last review comment. Can you please be a little more mindful and complete them before requesting another review?

@koppor koppor added the status: changes-required Pull requests that are not yet complete label Dec 15, 2025
@github-actions github-actions Bot added status: changes-required Pull requests that are not yet complete and removed status: changes-required Pull requests that are not yet complete labels Dec 15, 2025
@shubhamk0205

Copy link
Copy Markdown
Contributor Author

hey @koppor , @subhramit
just wanted to take a follow up on my PR , please let me know if u need any changes in this PR

-have changed the point of knowledge , now libraryTab decides that is it a bulk import or not instead of importHandler signal .
-have removed unrelated formatting changes .

@github-actions github-actions Bot added the status: changes-required Pull requests that are not yet complete label Dec 22, 2025
@github-actions

Copy link
Copy Markdown
Contributor

Your pull request conflicts with the target branch.

Please merge with your code. For a step-by-step guide to resolve merge conflicts, see https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line.

Comment on lines +107 to +108
if (suppressionDepth > 0) {
suppressionDepth--;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hey, can you explain what the crux of Suppression as a class is? How exactly did you think of this as a solution?
And what does suppressionDepth convey, in simple terms?

It is evident that it works, but we need to brainstorm and ensure that there was no better way to achieve the same thing before going forward with this.

Did you try the two or three solution hints given in the issue? What problems did you face when implementing them?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

hello @subhramit,
thank you for responding and for the questions.

The main crux of Suppression is that during a bulk import it increases suppressionDepth, which prevents entries from being added to the navigation history. I initially used a boolean flag, but switched to a depth-based approach because a boolean can fail in nested scenarios. For example, if importFile1() internally calls importFile2(), the boolean would be reset after importFile2() finishes, while importFile1() is still running.

As for the other approaches:

Clearing the imported entries afterward felt fragile — for example, if the import crashes midway, adding and then removing entries doesn't make sense .

Disabling auto-selection would break the existing behavior of showing the last imported entry.

Given these trade-offs, disabling history updates during bulk import felt like the most robust option. The main challenge I faced was deciding where this suppression should live architecturally , I implemented it as a runWithHistorySuppression() wrapper method in LibraryTab that bulk operation callers use like import handler , drag and drop .
i am open for making any changes and improving this further , if there’s a cleaner direction

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For example, if importFile1() internally calls importFile2(), the boolean would be reset after importFile2() finishes, while importFile1() is still running.

Have you found any concrete examples of that happening in the code?
And if there is, wouldn't switching the boolean flag only at the level of the outermost import call solve it? That is, tracking only the completion of importFile1()?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

where this suppression should live architecturally

History should not suppressed completely, it should "just" be collected into one NamedCompound.

Read on at https://apidia.net/java/OpenJDK/25/?pck=javax.swing.undo&cls=.CompoundEdit for nested undos/redos.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe, I mixed it up - this PR is about navigation; I thought, it has a strong relation to undo/redo.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For example, if importFile1() internally calls importFile2(), the boolean would be reset after importFile2() finishes, while importFile1() is still running.

Have you found any concrete examples of that happening in the code? And if there is, wouldn't switching the boolean flag only at the level of the outermost import call solve it? That is, tracking only the completion of importFile1()?

I checked this and you’re right @subhramit — in ImportHandler, imports are performed in a loop, not in a recursive way.

switching the flag only at the outermost level works. A nesting-aware boolean like this would be enough:

boolean wasAlreadySuppressed = suppressNavigation;
suppressNavigation = true;
try {
    action.run();
} finally {
    if (!wasAlreadySuppressed) {
        suppressNavigation = false;
    }
}

This handles cases where multiple import batches might run sequentially - suppression stays on until all batches complete.

I went with the counter mostly as a defensive choice, but I agree the boolean is simpler and does the job here. Happy to switch to that if you prefer.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please go ahead with it, let us know if you face issues.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

sure on it !!

@github-actions github-actions Bot removed the status: changes-required Pull requests that are not yet complete label Dec 22, 2025
Prevent bulk import operations from polluting the navigation history.
When multiple entries are imported at once, automatic selection changes
are now suppressed from being recorded in the navigation history.

Fixes JabRef#13878
@shubhamk0205 shubhamk0205 requested a review from koppor January 7, 2026 12:32
@shubhamk0205

Copy link
Copy Markdown
Contributor Author

@subhramit @koppor can u provide me some feedback on this

@subhramit

Copy link
Copy Markdown
Member

@subhramit @koppor can u provide me some feedback on this

does it work on your system? a fresh video would be great. I am currently a bit low on time.

@shubhamk0205

Copy link
Copy Markdown
Contributor Author

@subhramit @koppor can u provide me some feedback on this

does it work on your system? a fresh video would be great. I am currently a bit low on time.

yess this works on my device

Recording.2026-01-12.102823compressed.mp4

Comment on lines +854 to +855
// Only show/select individual entry for single-entry imports.
// For bulk imports (size > 1), leave all entries selected.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This comment is confusing - so selection happens in case of both single and multiple entries?
Where is the code for "leaving all entries selected"? Because it will neither trigger the if nor else case.

The side effect of this can be - check if earlier on bulk import all entries were actually selected, because otherwise now if they are not selected, lets say the user wants to remove all the entries imported just after the import action, they will have to manually select the imported entries again first instead of just clicking delete,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You’re right — my bad. I forgot to update the comment. I’ll fix it to accurately describe skipping clearAndSelect() for bulk imports.

@shubhamk0205 shubhamk0205 Jan 13, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

check if earlier on bulk import all entries were actually selected, because otherwise now if they are not selected, lets say the user wants to remove all the entries imported just after the import action, they will have to manually select the imported entries again first instead of just clicking delete,

i checked this ,on bulk import all the entries were not selected , only the first entry was selected from the bulk import

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You’re right — my bad. I forgot to update the comment. I’ll fix it to accurately describe skipping clearAndSelect() for bulk imports.

This is a final heads up to not use AI to communicate. You will be blacklisted from the project if you don't respect our guidelines on using AI.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@subhramit i used ai to refine my speech so i can communicate better , but from going forward i will be writing directly here .

@github-actions github-actions Bot removed the status: changes-required Pull requests that are not yet complete label Jan 13, 2026
@koppor koppor added the status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers label Jan 15, 2026
@github-actions github-actions Bot added status: changes-required Pull requests that are not yet complete and removed status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers labels Jan 26, 2026
Signed-off-by: subhramit <subhramit.bb@live.in>
subhramit
subhramit previously approved these changes Jan 26, 2026
Signed-off-by: subhramit <subhramit.bb@live.in>
subhramit
subhramit previously approved these changes Jan 26, 2026

@koppor koppor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let's try out.

@koppor koppor enabled auto-merge January 26, 2026 21:08
@github-actions github-actions Bot removed the status: changes-required Pull requests that are not yet complete label Jan 26, 2026
@Siedlerchr

Copy link
Copy Markdown
Member

6
/home/runner/work/jabref/jabref/jabgui/src/main/java/org/jabref/gui/LibraryTab.java:815: error: unexpected content
/// @see Issue #13878

@koppor koppor added this pull request to the merge queue Jan 26, 2026
@github-actions github-actions Bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label Jan 26, 2026
Merged via the queue into JabRef:main with commit 97475f5 Jan 26, 2026
52 of 53 checks passed
@shubhamk0205 shubhamk0205 deleted the fix-for-issue-13878-v2 branch January 26, 2026 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: import-load good third issue status: to-be-merged PRs which are accepted and should go into the merge-queue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove/prevent "Ghost" navigation history when using importers

5 participants