Skip to content

Reintroduce custom entry editor tabs with two-column preferences UI - #16598

Merged
koppor merged 9 commits into
mainfrom
entry-editor-custom-tabs
Aug 18, 2026
Merged

koppor merged 9 commits into
mainfrom
entry-editor-custom-tabs

Conversation

@koppor

@koppor koppor commented Aug 17, 2026 •

Copy link
Copy Markdown
Member

Summary

🤖 The entry editor rework (#16166) dropped support for user-defined ("custom") entry editor tabs, which broke existing user configurations (#16594). This PR brings custom tabs back and reworks the "Editor tabs" preferences into a two-column editor modeled on the "Custom entry types" page: a Tabs column (visibility checkboxes for built-in tabs, add/remove for custom tabs, drag-and-drop reordering for all tabs) and a Fields column editing the selected custom tab's ordered field list, where a field name may also be a regular expression (e.g. comment-.*) and a field contained in multiple tabs is flagged with a warning sign. Custom tabs are stored as a JSON map ({"tab name": ["field pattern", ...], ...}) under a single preference key (serialized with Jackson, which jabgui already uses); the pre-rework keys are read as a migration fallback and purged on the next store, so tabs configured in older versions (e.g. v6.0-alpha.6) are picked up again automatically.

jabref-contrib-policy:4.2:reviewed​:ok

Analogies: Like honey, this PR preserves what users already gathered — custom tab configurations from older versions flow back in unspoiled. Like chocolate, it is composed of familiar ingredients (the proven "Custom entry types" two-column design) recombined into something immediately recognizable and easy to consume. And like the moon, the custom tabs disappeared for a phase but were never truly gone — this PR completes the cycle and brings them back into full view, with regex support as the new bright side.

Steps to test

  1. Open File → Preferences → Entry editor and scroll to the Editor tabs section.
  2. In the Tabs column, type a name (e.g. General) into "Tab name..." and press Enter — the custom tab appears and is selected.
  3. In the Fields column, add fields (e.g. keywords, doi, comment-.*) via the "Field name" box (autocompletion offers known field names).
  4. Drag rows in either column to reorder tabs and fields.
  5. Add the same field to a second custom tab — a warning sign appears next to it in the Fields column.
  6. Save, open an entry: the custom tabs appear in the entry editor in the configured order, showing the configured fields. Setting a field matching a regex pattern (e.g. comment-test in the Main or source tab) makes it appear on the custom tab immediately.
  7. Restart JabRef: the custom tabs are still there. Users upgrading from v6.0-alpha.6 or earlier get their previously configured custom tabs back automatically.

Preferences UI:

Editor tabs preferences

Custom "General" tab in the entry editor with a comment-test field captured by the comment-.* pattern:

General tab with regex-captured field

Library with a single test entry:

Single entry 16594

Related issues and pull requests

Closes #16594

User documentation PR: JabRef/user-documentation#659

AI usage

Claude Code (model claude-fable-5), AIL4 — the implementation was AI-generated under human direction; the change was manually tested in a running JabRef.

AI CHECKLIST.md walkthrough

1. Code self-review

Nullability and control flow

  • No == null / != null checks — JSpecify annotations (@NullMarked, @Nullable, @NonNull) used instead. (Remaining (tab == null) checks are JavaFX selection-model states in the view, matching surrounding code; (model != null) guards a possibly-absent drag payload.)
  • No Objects.requireNonNull(...) — nullability expressed via JSpecify annotations.
  • New classes annotated with @NullMarked (org.jspecify.annotations.NullMarked).
  • Optional consumed with ifPresent / ifPresentOrElse / map / orElseThrow — never orElse(unusedValue) nor an isPresent() + get() block.
  • StringUtil.isBlank(...) used instead of s == null || s.isBlank().

Exceptions

  • No catch (Exception e) — only PatternSyntaxException is caught (invalid user regex resolves to no fields).
  • No throw new RuntimeException(...) / IllegalStateException(...).
  • [/] Logged exceptions are passed as the last logger argument — no logging added.

Style and idioms

  • New BibEntry objects built with withers (withField, not setField) — in tests.
  • Modern Java used: List.of() / List.copyOf(), SequencedSet, records, pattern-matching switch.
  • Regexes use a precompiled Pattern.compile(...) constant, not String.matches(...) (the user-supplied patterns are compiled per resolution, which is inherent to the feature).
  • [/] Background work uses BackgroundTask — no background work added.
  • No commented-out code, no trivial comments, no AI-disclosure comments in source.
  • Markdown Javadoc (///) uses Markdown syntax, not JavaDoc inline tags.

User-facing text

  • All user-facing text localized (Localization.lang).
  • Sentence case; no trailing !; labels do not end with :.
  • Variance expressed with placeholders ("Remove tab %0"), not string concatenation.

Security

  • [/] No text/html responses touched.

Tests

  • Behavior changes covered: EntryEditorTabModelTest (pattern resolution: literals, regex, order, invalid regex) and extended EntryEditorTabViewModelTest (add/remove custom tabs, duplicate detection, order round-trip, reset).
  • Tests assert object contents with plain JUnit asserts, no @DisplayName, no caught exceptions, no manual temp directories.

2. Verification commands

  • xvfb-run -a ./gradlew :jablib:test --tests "*LocalizationConsistency*" passed (jablib change is localization keys only; GUI tests for the touched classes pass via :jabgui:test).
  • ./gradlew :jabgui:checkstyleMain :jabgui:checkstyleTest passed.
  • ./gradlew :jabgui:modernizer passed.
  • ./gradlew --no-configuration-cache :rewriteRun applied, no remaining diff.
  • Touched Java files reformatted with IntelliJ IDEA using .idea/codeStyles/Project.xml (idea format).
  • [/] npx markdownlint-cli2 — only CHANGELOG.md/docs/requirements list entries changed, following existing formatting.
  • [/] Docker IntelliJ format — not needed, idea format was run directly.

3. Documentation

4. Pull request

  • PR body built from .github/PULL_REQUEST_TEMPLATE.md, every section filled.
  • All checklist items kept and marked.
  • All HTML comments removed from the PR body.
  • PR created with gh pr create --body-file.
  • [/] CHANGELOG uses the issue link, no TODO placeholder.

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • If AI tools were used, I disclosed them in the "AI usage" section and reviewed, understood, and take full ownership of all AI-generated code
  • 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 added a screenshot in the PR description showing a library with a single entry with me as author and as title the issue number
  • I described the change in CHANGELOG.md in a way that can be understood by the average user (if change is visible to the user)
  • I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

🤖 Generated with Claude Code

The entry editor rework (#16166) dropped user-defined tabs. Bring them
back with a preferences UI modeled on the Custom entry types tab: a
"Tabs" column (visibility checkboxes for built-in tabs, add/remove for
custom tabs, drag reordering for all) and a "Fields" column editing the
selected custom tab's ordered field list. Field names may be regular
expressions (e.g. comment-.*), which capture every matching set field of
the entry, refreshed live on field changes. A field listed on more than
one tab is marked with a warning sign.

Custom tabs are persisted under the pre-rework preference keys, so tabs
configured in older versions are picked up again without migration; the
combined tab order is stored in a new entryEditorTabOrder key.

Fixes #16594

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa
@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Restore custom entry editor tabs with two-column preferences

🐞 Bug fix ✨ Enhancement 🧪 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Restores user-defined entry editor tabs and automatically reuses legacy configurations.
• Adds a two-column preferences editor for tab visibility, ordering, fields, and warnings.
• Supports ordered literal and regex field patterns with live entry-editor refreshes.
Diagram

graph TD
  A["Editor tabs UI"] --> B["Working tab models"] --> C["Preferences store"] --> D["Entry tab models"] --> E["Custom fields tab"] --> F["Entry editor"]
  G["BibEntry fields"] --> E
Loading
High-Level Assessment

The approach is appropriate: it restores backward compatibility by reusing the legacy custom-tab keys, avoids migration risk, and confines regex resolution and live refresh behavior to the custom-tab implementation. A separate migration or parallel configuration format would add complexity without improving user outcomes.

Files changed (13) +869 / -83

Enhancement (6) +642 / -75
EntryEditorTabFactory.javaCreate concrete custom field tabs +12/-0

Create concrete custom field tabs

• Extends tab creation to instantiate user-defined field tabs from customized tab models. Custom tabs rely on resolved content rather than a built-in visibility preference.

jabgui/src/main/java/org/jabref/gui/entryeditor/EntryEditorTabFactory.java

EntryEditorTabModel.javaModel custom tabs and resolve field patterns +65/-4

Model custom tabs and resolve field patterns

• Adds a customized tab model with a name and ordered patterns. Literal field names remain visible when unset, while regex patterns resolve matching set fields safely and deterministically.

jabgui/src/main/java/org/jabref/gui/entryeditor/EntryEditorTabModel.java

UserDefinedFieldsTab.javaRender and live-refresh custom field tabs +103/-0

Render and live-refresh custom field tabs

• Adds the concrete entry-editor tab for user-defined fields. It listens for field changes so regex matches and tab visibility update immediately without unnecessarily rebuilding focused editors.

jabgui/src/main/java/org/jabref/gui/entryeditor/UserDefinedFieldsTab.java

EditorTabViewModel.javaAdd mutable preference model for each tab +79/-0

Add mutable preference model for each tab

• Introduces a dialog-scoped tab view model that represents built-in visibility or custom field patterns and converts back to persistent tab models.

jabgui/src/main/java/org/jabref/gui/preferences/entryeditor/EditorTabViewModel.java

EntryEditorTab.javaReplace tab list with two-column tab editor +308/-45

Replace tab list with two-column tab editor

• Reworks Editor tabs preferences into Tabs and Fields tables. Supports custom-tab creation and removal, field autocomplete, duplicate warnings, reset confirmation, and drag reordering of tabs and patterns.

jabgui/src/main/java/org/jabref/gui/preferences/entryeditor/EntryEditorTab.java

EntryEditorTabViewModel.javaManage editable custom tab configurations +75/-26

Manage editable custom tab configurations

• Replaces the old visibility-only working list with editable tab view models. Adds validation, duplicate detection, reset behavior, and ordered persistence while keeping Preview outside the editable list.

jabgui/src/main/java/org/jabref/gui/preferences/entryeditor/EntryEditorTabViewModel.java

Bug fix (1) +78 / -5
JabRefGuiPreferences.javaPersist custom tabs and their display order +78/-5

Persist custom tabs and their display order

• Loads and stores custom tabs using the pre-rework preference keys, recovering older user configurations without migration. Persists a combined order for built-in and custom tabs while preserving Preview first.

jabgui/src/main/java/org/jabref/gui/preferences/JabRefGuiPreferences.java

Documentation (2) +9 / -2
CHANGELOG.mdDescribe restored custom tab configuration +2/-2

Describe restored custom tab configuration

• Revises release notes to describe the two-column tab editor, reordering, custom tabs, and regex field patterns. Clarifies that only default custom tabs were removed while user-defined tabs remain supported.

CHANGELOG.md

entry-editor.mdSpecify custom entry editor tab behavior +7/-0

Specify custom entry editor tab behavior

• Adds a requirement covering custom tabs, ordered field patterns, regex matching, duplicate warnings, drag reordering, and legacy configuration recovery.

docs/requirements/entry-editor.md

Other (4) +140 / -1
DragAndDropDataFormats.javaAdd drag format for editor tab rows +1/-0

Add drag format for editor tab rows

• Defines a local drag-and-drop data format used to reorder entry-editor tab configurations in preferences.

jabgui/src/main/java/org/jabref/gui/DragAndDropDataFormats.java

EntryEditorTabModelTest.javaTest custom field pattern resolution +56/-0

Test custom field pattern resolution

• Covers literal and unknown fields, regex captures, configured ordering, and invalid regular expressions.

jabgui/src/test/java/org/jabref/gui/entryeditor/EntryEditorTabModelTest.java

EntryEditorTabViewModelTest.javaTest custom tab preference editing +71/-1

Test custom tab preference editing

• Covers custom-tab round trips, duplicate names and patterns, duplicate warnings, tab ordering, and reset behavior.

jabgui/src/test/java/org/jabref/gui/preferences/entryeditor/EntryEditorTabViewModelTest.java

JabRef_en.propertiesAdd labels for custom tab preferences +12/-0

Add labels for custom tab preferences

• Adds localized strings for the Tabs and Fields editor, custom-tab actions, duplicate warnings, regex guidance, and reset confirmation.

jablib/src/main/resources/l10n/JabRef_en.properties

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Aug 17, 2026 •

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Leaked BibEntry listener ✓ Resolved 🐞 Bug ☼ Reliability
Description
UserDefinedFieldsTab registers itself on a BibEntry event bus in bindToEntry but never unregisters
when the tab is discarded, so rebuilding/closing the editor leaks the tab instance and keeps
scheduling FieldChangedEvent handlers. EntryEditorViewModel explicitly calls
EntryEditorTab.dispose() before dropping tab instances, so this cleanup is expected to happen there.
Code

jabgui/src/main/java/org/jabref/gui/entryeditor/UserDefinedFieldsTab.java[R78-81]

+        if (subscribedEntry.filter(current -> current == entry).isEmpty()) {
+            subscribedEntry.ifPresent(previous -> previous.unregisterListener(this));
+            entry.registerListener(this);
+            subscribedEntry = Optional.of(entry);
Evidence
The new tab performs a strong event-bus registration on the BibEntry, while the entry editor
lifecycle explicitly disposes tabs before dropping them; without an override, the registration is
never undone and the entry retains the tab instance.

jabgui/src/main/java/org/jabref/gui/entryeditor/UserDefinedFieldsTab.java[76-84]
jabgui/src/main/java/org/jabref/gui/entryeditor/UserDefinedFieldsTab.java[86-103]
jabgui/src/main/java/org/jabref/gui/entryeditor/EntryEditorViewModel.java[212-220]
jabgui/src/main/java/org/jabref/gui/entryeditor/EntryEditorTab.java[71-75]
jablib/src/main/java/org/jabref/model/entry/BibEntry.java[918-929]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`UserDefinedFieldsTab` registers itself via `BibEntry.registerListener(this)` but does not override `EntryEditorTab.dispose()` to unregister from the currently subscribed entry. Since `EntryEditorViewModel.disposeTabs()` calls `EntryEditorTab::dispose` before old tab instances are dropped, the listener remains registered and retains the tab.
## Issue Context
- `BibEntry.registerListener` registers on a strong Guava EventBus, so listeners must be unregistered to avoid retention.
- The base `EntryEditorTab.dispose()` exists specifically to release listeners owned by a tab.
## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/entryeditor/UserDefinedFieldsTab.java[76-103]
- jabgui/src/main/java/org/jabref/gui/entryeditor/EntryEditorTab.java[71-75]
### Implementation sketch
- Override `protected void dispose()` in `UserDefinedFieldsTab`.
- In `dispose()`, call `subscribedEntry.ifPresent(entry -> entry.unregisterListener(this));` and then clear `subscribedEntry`.
- (Optional) If you want to be extra defensive, also clear `hasResolvedFields` / avoid any future `Platform.runLater` work once disposed.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. listen() runLater not coalesced ✓ Resolved 📘 Rule violation ☼ Reliability
Description
UserDefinedFieldsTab.listen schedules a new Platform.runLater callback for every
FieldChangedEvent without a coalescing token/generation guard. This can cause redundant UI rebuild
work and allows older queued callbacks to apply after newer state changes, contrary to the
deferred-callback safety pattern.
Code

jabgui/src/main/java/org/jabref/gui/entryeditor/UserDefinedFieldsTab.java[R91-94]

+        Platform.runLater(() -> {
+            BibEntry entry = event.getBibEntry();
+            if (getCurrentEntry() != entry) {
+                return;
Evidence
The checklist pattern requires guarding deferred JavaFX callbacks against stale state and coalescing
redundant runLater updates. The new code schedules Platform.runLater on every
FieldChangedEvent with no coalescing mechanism (e.g., generation counter / pending flag), so
multiple queued callbacks may redundantly recompute fields and rebuild the panel.

jabgui/src/main/java/org/jabref/gui/entryeditor/UserDefinedFieldsTab.java[90-101]
Best Practice: Learned patterns

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`UserDefinedFieldsTab.listen(FieldChangedEvent)` calls `Platform.runLater` on every event, but does not coalesce multiple pending refreshes or guard against stale queued callbacks beyond checking `getCurrentEntry()`. This can lead to redundant updates and older queued callbacks applying after newer state changes.
## Issue Context
Compliance requires deferred JavaFX callbacks to be protected against stale state and redundant `runLater` work to be coalesced so only the latest scheduled update applies.
## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/entryeditor/UserDefinedFieldsTab.java[90-101]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Duplicate tabs overwritten ✓ Resolved 🐞 Bug ≡ Correctness
Description
applyStoredTabOrder uses a Map keyed by tabOrderId, and for custom tabs tabOrderId is derived only
from the custom tab name; if persisted preferences contain two custom tabs with the same name, one
overwrites the other and disappears. This can silently drop a user’s custom tab configuration when
loading old/manual-edited preferences (and later saving will purge the lost tab).
Code

jabgui/src/main/java/org/jabref/gui/preferences/JabRefGuiPreferences.java[R458-461]

+            if (model.isPreview()) {
+                ordered.add(model);
+            } else {
+                remaining.put(tabOrderId(model), model);
Evidence
Custom tabs are loaded as a simple series with no de-duplication, but ordering uses a Map keyed only
by name-derived IDs, so duplicate names provably cause Map overwrites.

jabgui/src/main/java/org/jabref/gui/preferences/JabRefGuiPreferences.java[438-462]
jabgui/src/main/java/org/jabref/gui/preferences/JabRefGuiPreferences.java[474-488]
jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[1032-1042]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`applyStoredTabOrder` builds `remaining` as `Map<String, EntryEditorTabModel>` and inserts tabs with `remaining.put(tabOrderId(model), model)`. For custom tabs, `tabOrderId` is `"custom:" + name`, so duplicate custom names collide and the earlier tab is overwritten and lost.
## Issue Context
- Custom tab names are loaded from a numbered preference series (`getSeries(CUSTOM_TAB_NAME)`) without uniqueness enforcement.
- The new preferences UI prevents creating duplicates, but existing persisted data (older versions, manual edits, or corrupted prefs) can still contain duplicates.
## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/preferences/JabRefGuiPreferences.java[438-472]
- jabgui/src/main/java/org/jabref/gui/preferences/JabRefGuiPreferences.java[474-488]
- jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[1032-1042]
### Implementation sketch
- Change `remaining` to a multimap-like structure, e.g. `Map<String, ArrayDeque<EntryEditorTabModel>>`.
- While iterating `tabModels`, do `remaining.computeIfAbsent(id, _ -> new ArrayDeque<>()).add(model)`.
- While applying `storedOrder`, poll from the deque (`pollFirst`) and remove the key when empty.
- Append all remaining deque contents in insertion order.
- This keeps the current stable ID format (so no migration needed) while avoiding data loss on duplicates.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can keep summaries lean with Finding overflow, which tucks the rest behind 'View more'

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread jabgui/src/main/java/org/jabref/gui/preferences/JabRefGuiPreferences.java Outdated
Persisted data can contain custom tabs sharing a name (older versions or
hand-edited stores; the preferences UI prevents new duplicates). The
order map keyed by tab ID silently dropped all but the last such tab, so
queue tabs per ID instead and consume one per matching order entry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa
koppor and others added 4 commits August 17, 2026 21:42
BibEntry's event bus holds listeners strongly, so AllFieldsTab and
UserDefinedFieldsTab instances stayed registered (and retained) after
EntryEditorViewModel.disposeTabs() dropped them. Release the
subscription in dispose().

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa
A burst of field changes (imports, fetchers) queued one Platform.runLater
per event. Track a pending-refresh flag so only one callback is queued,
and read the entry's state at callback time instead of the event payload,
so a queued refresh can never apply stale state.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa
Comment on lines +237 to +238
private static final String CUSTOM_TAB_NAME = "customTabName_";
private static final String CUSTOM_TAB_FIELDS = "customTabFields_";

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.

Old style, brittle model of backing store data storage.
Might be better to do simple StringLists or a custom (json?) format in a string.

koppor and others added 2 commits August 17, 2026 22:28
Replace the low-level parallel numbered series (customTabName_i /
customTabFields_i) with one entryEditorCustomTabs key holding a JSON
object {"tab name": ["field pattern", ...], ...} in display order,
serialized with Jackson (already required by jabgui). The old series is
still read as a migration fallback and purged on the next store.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa
Convert the pre-v6.0-alpha.7 numbered series (customTabName_i /
customTabFields_i) to the entryEditorCustomTabs JSON key once at startup
in the migrations package, instead of a read-time fallback in
JabRefGuiPreferences. The old keys are kept for use by older JabRef
versions and ignored once the new key exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa
@calixtus
calixtus enabled auto-merge August 17, 2026 20:44
calixtus
calixtus previously approved these changes Aug 17, 2026
The migration hardcodes the key name locally (V6_0_* convention), like
the other migrations, instead of exposing the constant publicly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa
@calixtus
calixtus added this pull request to the merge queue Aug 17, 2026
@github-actions github-actions Bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label Aug 17, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Aug 17, 2026
@koppor
koppor added this pull request to the merge queue Aug 18, 2026
Merged via the queue into main with commit bc361a1 Aug 18, 2026
73 checks passed
@koppor
koppor deleted the entry-editor-custom-tabs branch August 18, 2026 15:22
Siedlerchr added a commit that referenced this pull request Aug 20, 2026
* main: (22 commits)
  Chore(deps): Bump org.itsallcode.openfasttrace from 3.1.2 to 3.2.0 (#16638)
  Chore(deps): Bump gradle-wrapper from 9.7.0 to 9.7.1 (#16637)
  Chore(deps): Bump net.bytebuddy:byte-buddy in /versions (#16621)
  Chore(deps): Bump org.glassfish.hk2:hk2-utils in /versions (#16632)
  Chore(deps): Bump org.glassfish.hk2:hk2-api in /versions (#16633)
  Chore(deps): Bump org.glassfish.hk2:hk2-locator in /versions (#16631)
  Chore(deps): Bump com.google.guava:guava in /versions (#16630)
  Chore(deps): Bump JetBrains/junie-github-action from 1.7.0 to 1.7.4 (#16629)
  New translations {fileName} ({languageName}) (#16628)
  Chore(deps): Bump com.google.guava:guava in /versions (#16622)
  Chore(deps): Bump com.squareup.okhttp3:okhttp in /versions (#16624)
  Reintroduce custom entry editor tabs with two-column preferences UI (#16598)
  Implemented PagedSearchBasedFetcher Of ScholarApi for List API (#16293)
  Chore(deps): Bump io.github.classgraph:classgraph in /versions (#16600)
  Chore(deps): Bump dev.langchain4j:langchain4j-bom in /versions (#16601)
  Chore(deps): Bump tools.jackson:jackson-bom in /versions (#16602)
  Chore(deps): Bump com.dlsc.gemsfx:gemsfx in /versions (#16599)
  fix equals in group tree viewmodel and add run config for jabref gui (#16605)
  refactor(null): fix nullaways issues in ChainNode (#16606)
  New Crowdin updates (#16612)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: entry-editor 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.

Entry editor introduced breaking changes to custom tabs

2 participants