Skip to content

Change FileKeystore and Folder fields to disable/enable#15685

Merged
Siedlerchr merged 15 commits into
JabRef:mainfrom
gandhroh000:fix_shared_database_fields_enabled
May 7, 2026
Merged

Change FileKeystore and Folder fields to disable/enable#15685
Siedlerchr merged 15 commits into
JabRef:mainfrom
gandhroh000:fix_shared_database_fields_enabled

Conversation

@gandhroh000

@gandhroh000 gandhroh000 commented May 5, 2026

Copy link
Copy Markdown
Contributor

Related issues and pull requests

Closes #15660

PR Description

In the "Connect to Shared Database" page, when the "Use SSL" checkbox was deselected, fileKeyStore would still be showing as a required field, which can be confusing to the user. For reference, only when the SSL connection checkbox is enabled, the fileKeyStore field would be enabled. To change this, it was necessary to add a condition to the SharedDatabaseLoginDialogView. java file that triggered the disabledProperty function, hiding the fileKeyStore entry field.
image

Steps to test

  1. Open a local copy of this version, which has the UI change implemented
  2. Once the JabRef application is open, select the File button in the upper left-hand corner
  3. Once the dropdown menu has expanded, click on the "Connect to shared database."
  4. Once the Shared Database Page has opened, attempt to click the the SSL connection checkbox
  5. Clicking the "Use SSL" checkbox (check box is filled with a checkmark and green color) will visually change the color of the fields (KeyStore, Browse Button, and KeyStore password) to a brighter color.
  6. When the "Use SSL" checkbox is enabled, this will allow the reviewer to interact with the KeyStore, Browse Button, and KeyStore password fields. If any invalid input is detected, such as a missing key, then the connect button will be disabled. When valid input is detected, the connect button will be enabled.
  7. When the "Use SSL" checkbox is disabled (the check box is not filled with a green color and checkmark), the fields mentioned will dim in brightness and will not allow interaction.
  8. Clicking the "Automatically save the library to" checkbox to enable it will cause the Folder entry and Browse button to be enabled, where a user can enter the path of the folder they wish to save information, or browse button, which opens the OS's file explorer system. Incorrect paths or missing paths will cause the Connect button to be disabled
  9. Clicking the "Automatically save the library to" button when it's enabled will disable it, causing the Folder entry and Browse button to dim, which won't allow any interaction

Disabled "Use SSL" button:
image
Enabled "Use SSL" button:
image

Disable the "Automatically save the library to" button:
image
Enable the "Automatically save the library to" button:
image

AI Disclosure

Utilized Google Antigravity IDE to debug and locate issues, provide context regarding overall file and JabRef project structure, and to assess tradeoffs of solution implementations. All code was tested in the JabRef application and actions align with guidelines set by the JabRef repository.

Checklist

  • 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 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

@github-actions github-actions Bot added status: changes-required Pull requests that are not yet complete and removed status: no-bot-comments labels May 5, 2026
@github-actions github-actions Bot added status: no-bot-comments and removed status: changes-required Pull requests that are not yet complete labels May 5, 2026
@gandhroh000 gandhroh000 marked this pull request as ready for review May 5, 2026 19:27
@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Conditionally enable keystore and folder fields in shared database dialog

✨ Enhancement 🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Conditionally disable/enable keystore and folder fields based on SSL and autosave preferences
• Add validation rules that respect SSL and autosave checkbox states
• Fix error messages for host and port validators (swapped labels)
• Include keystoreValidator and folderValidator in form validation
Diagram
flowchart LR
  SSL["SSL Checkbox"] -->|toggled| KeystoreDisable["Disable keystore field"]
  Autosave["Autosave Checkbox"] -->|toggled| FolderDisable["Disable folder field"]
  KeystoreDisable --> Validation["Update validation rules"]
  FolderDisable --> Validation
  Validation --> FormValidator["Add validators to form"]
  FormValidator --> ConnectButton["Enable/disable connect button"]
Loading

Grey Divider

File Changes

1. jabgui/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogView.java ✨ Enhancement +1/-0

Bind keystore field disable property to SSL state

• Bind fileKeystore.disableProperty() to the negation of useSSLProperty() so the field is
 disabled when SSL is not enabled
• Ensures visual consistency with other SSL-dependent fields like browse button and password field

jabgui/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogView.java


2. jabgui/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogViewModel.java 🐞 Bug fix +17/-5

Add conditional validation for keystore and folder fields

• Add EasyBind subscribers to trigger validation updates when SSL or autosave checkboxes are toggled
• Create conditional validation rules keyStoreRule and folderRule that only require valid paths
 when their respective features are enabled
• Fix swapped error messages in hostValidator and portValidator (Host/Port labels were reversed)
• Add keystoreValidator and folderValidator to the formValidator composite validator

jabgui/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogViewModel.java


3. .idea/codeStyles/Project.xml ⚙️ Configuration changes +1/-0

Update code style import layout configuration

• Add module-level import configuration to the import layout table
• Ensures consistent code style formatting for module imports

.idea/codeStyles/Project.xml


View more (1)
4. CHANGELOG.md 📝 Documentation +1/-0

Document shared database dialog field validation fix

• Document the fix for Shared Database Login Dialog field validation based on autosave/useSSL
 preferences
• Reference issue #15660

CHANGELOG.md


Grey Divider

Qodo Logo

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

qodo-free-for-open-source-projects Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (3) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Autosave path must exist ✓ Resolved 🐞 Bug ≡ Correctness
Description
When autosave is enabled, folder validation requires Files.exists(Path.of(input)) and the Connect
button is gated by this validator, so selecting a new (not-yet-created) .bib file path via the Save
dialog will keep Connect disabled. This contradicts the later SaveDatabaseAction.saveAs behavior,
which can create a new file at the chosen path.
Code

jabgui/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogViewModel.java[R137-152]

   Predicate<String> notEmpty = input -> (input != null) && !input.isBlank();
   Predicate<String> fileExists = input -> Files.exists(Path.of(input));
   Predicate<String> notEmptyAndfilesExist = notEmpty.and(fileExists);
+        Predicate<String> keyStoreRule = input -> !useSSL.get() || notEmptyAndfilesExist.test(input);
+        Predicate<String> folderRule = input -> !autosave.get() || notEmptyAndfilesExist.test(input);
   databaseValidator = new FunctionBasedValidator<>(database, notEmpty, ValidationMessage.error(Localization.lang("Required field \"%0\" is empty.", Localization.lang("Library"))));
-        hostValidator = new FunctionBasedValidator<>(host, notEmpty, ValidationMessage.error(Localization.lang("Required field \"%0\" is empty.", Localization.lang("Port"))));
-        portValidator = new FunctionBasedValidator<>(port, notEmpty, ValidationMessage.error(Localization.lang("Required field \"%0\" is empty.", Localization.lang("Host"))));
+        hostValidator = new FunctionBasedValidator<>(host, notEmpty, ValidationMessage.error(Localization.lang("Required field \"%0\" is empty.", Localization.lang("Host"))));
+        portValidator = new FunctionBasedValidator<>(port, notEmpty, ValidationMessage.error(Localization.lang("Required field \"%0\" is empty.", Localization.lang("Port"))));
   userValidator = new FunctionBasedValidator<>(user, notEmpty, ValidationMessage.error(Localization.lang("Required field \"%0\" is empty.", Localization.lang("User"))));
-        folderValidator = new FunctionBasedValidator<>(folder, notEmptyAndfilesExist, ValidationMessage.error(Localization.lang("Please enter a valid file path.")));
-        keystoreValidator = new FunctionBasedValidator<>(keystore, notEmptyAndfilesExist, ValidationMessage.error(Localization.lang("Please enter a valid file path.")));
+        folderValidator = new FunctionBasedValidator<>(folder, folderRule, ValidationMessage.error(Localization.lang("Please enter a valid file path.")));
+        keystoreValidator = new FunctionBasedValidator<>(keystore, keyStoreRule, ValidationMessage.error(Localization.lang("Please enter a valid file path.")));
   formValidator = new CompositeValidator();
-        formValidator.addValidators(databaseValidator, hostValidator, portValidator, userValidator);
+        formValidator.addValidators(databaseValidator, hostValidator, portValidator, userValidator, keystoreValidator, folderValidator);
Evidence
The PR adds folderValidator into the CompositeValidator used to enable/disable the Connect button.
folderValidator still uses an existence check (Files.exists), but the autosave UI uses a save-file
dialog (which returns a path without creating it), and the code later calls
SaveDatabaseAction.saveAs(path) which supports creating a new file—so requiring the file to already
exist prevents valid usage.

jabgui/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogViewModel.java[137-152]
jabgui/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogView.java[79-83]
jabgui/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogViewModel.java[332-340]
jabgui/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogViewModel.java[221-233]
jabgui/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java[87-95]
jabgui/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java[169-196]

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

## Issue description
When `autosave` is enabled, the `folderValidator` requires that the *file path already exists*, which blocks selecting a new save target via the Save dialog (common workflow). The code later saves using `SaveDatabaseAction.saveAs(Path)` which can create the file.
### Issue Context
The Connect button is disabled based on `formValidation().validProperty()`. This PR added `folderValidator` to `formValidator`, so the existence check now blocks connecting.
### Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogViewModel.java[137-152]
### Suggested fix
Change the autosave path predicate to accept a non-empty, syntactically valid path where the **parent directory exists and is writable** (or at least exists), instead of requiring `Files.exists(path)`.
For example:
- Parse with `Path.of(input)` inside a `try/catch` for `InvalidPathException`
- Validate `path.getParent() != null && Files.isDirectory(path.getParent())`
- Optionally validate write permission if desired
- Keep `Files.exists(path)` only for the keystore validator (which really must exist).

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



Remediation recommended

2. setValue(null) used for refresh 📘 Rule violation ☼ Reliability
Description
The new subscriptions force validation updates by setting keystore/folder to null, introducing
new null flows that can propagate through bindings/validators and risk NPEs or inconsistent UI
state. The compliance checklist explicitly requires avoiding passing null in new/modified code.
Code

jabgui/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogViewModel.java[R126-134]

+        EasyBind.subscribe(useSSL, selected -> {
+            String current = keystore.getValue();
+            keystore.setValue(null);
+            keystore.setValue(current);
+        });
+        EasyBind.subscribe(autosave, selected -> {
+            String current = folder.getValue();
+            folder.setValue(null);
+            folder.setValue(current);
Evidence
PR Compliance ID 10 forbids introducing new null passing; the PR adds keystore.setValue(null)
and folder.setValue(null) as part of change listeners to refresh validation.

AGENTS.md
jabgui/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogViewModel.java[126-134]

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

## Issue description
The view model refreshes validation by temporarily setting bound string properties to `null` (e.g., `keystore.setValue(null)`), which introduces new null flows.
## Issue Context
This was added to force revalidation when `useSSL`/`autosave` toggles change the effective requiredness of fields.
## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogViewModel.java[126-134]

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


3. Duplicate toggle refresh logic 📘 Rule violation ⚙ Maintainability
Description
The PR adds two near-identical EasyBind.subscribe blocks to refresh validation state, duplicating
the same pattern and making the constructor harder to maintain. This should be centralized (e.g., a
small helper) or replaced with a validator approach that reacts to both the toggle and the field
value.
Code

jabgui/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogViewModel.java[R126-135]

+        EasyBind.subscribe(useSSL, selected -> {
+            String current = keystore.getValue();
+            keystore.setValue(null);
+            keystore.setValue(current);
+        });
+        EasyBind.subscribe(autosave, selected -> {
+            String current = folder.getValue();
+            folder.setValue(null);
+            folder.setValue(current);
+        });
Evidence
PR Compliance ID 4 requires avoiding duplication; the added useSSL and autosave subscriptions
repeat the same refresh pattern for different properties.

AGENTS.md
jabgui/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogViewModel.java[126-135]

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

## Issue description
Two new subscriptions duplicate the same "save current → change value → restore" refresh pattern.
## Issue Context
This duplication was introduced to refresh validation when `useSSL` and `autosave` toggles change.
## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogViewModel.java[126-135]

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


4. Unrelated .idea code style edit ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
The PR includes an IDE code-style configuration change unrelated to the functional UI/validation
fix, increasing diff noise and risking unintended formatting churn for other contributors.
Compliance requires keeping diffs focused and avoiding unrelated formatting/config changes.
Code

.idea/codeStyles/Project.xml[24]

+          <package name="" withSubpackages="true" static="false" module="true" />
Evidence
PR Compliance ID 3 requires avoiding unrelated formatting-only changes; the PR adds an import layout
rule entry in IntelliJ project code style settings without direct linkage to the described bug fix.

AGENTS.md
.idea/codeStyles/Project.xml[24-24]

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

## Issue description
An unrelated IntelliJ code style configuration line was added, creating non-functional diff noise.
## Issue Context
This PR is about enabling/disabling fields in the shared database dialog; IDE formatting configuration changes are not required for that.
## Fix Focus Areas
- .idea/codeStyles/Project.xml[24-24]

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


View more (1)
5. Changelog entry too implementation-focused 📘 Rule violation ⚙ Maintainability
Description
The CHANGELOG entry mentions internal concepts (autosave/useSSL preferences) rather than
describing the user-visible behavior change in end-user terms. Compliance requires end-user-focused,
professional CHANGELOG entries.
Code

CHANGELOG.md[108]

+- We fixed the Shared Database Login Dialog by ensuring that fields were required based on the autosave/useSSL preferences. [#15660](https://github.com/JabRef/jabref/issues/15660)
Evidence
PR Compliance ID 21/27 require end-user-focused, professionally worded CHANGELOG entries; the added
line describes internal preference names instead of the visible outcome (keystore/folder fields only
required when the corresponding option is enabled).

AGENTS.md
CHANGELOG.md[108-108]
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
The new CHANGELOG entry is phrased in terms of internal preferences (`autosave/useSSL`) rather than user-visible behavior.
## Issue Context
This PR changes when the keystore and folder fields are enabled/required in the shared database connection dialog.
## Fix Focus Areas
- CHANGELOG.md[108-108]

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


Grey Divider

Qodo Logo

Comment thread .idea/codeStyles/Project.xml Outdated
@gandhroh000

Copy link
Copy Markdown
Contributor Author

Resolved the qodo action and ensured that the save path was working.

@Siedlerchr Siedlerchr added the status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers label May 6, 2026

@pluto-han pluto-han left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

i think, a change in view is enough

Comment on lines +143 to +155
if (!autosave.get()) {
return true;
} else if (input != null) {
try {
Path p = Path.of(input.trim());
p = p.getParent();
return (p != null) && Files.isDirectory(p);
} catch (InvalidPathException e) {
return false;
}
}
return false;
};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

also unrelated change.

@gandhroh000 gandhroh000 May 7, 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.

Thanks for checking, though this is the rule used in the validation function to ensure that either the autosave button is not enabled or the file path that the user has entered is indeed valid, as there is a manual input and browse input available. If this isn't set up and an incorrect directory location is passed, then the dialog will throw syntax errors and won't be able to progress further. In previous closed pull request (#15661) qodo recognized that these validators weren't used and inputs weren't being validating. That's why there was a need to implement this rule. Earlier tried to combine two different observables, but that didn't work (will explain in subsequent comments.)

Comment on lines +132 to +136
EasyBind.subscribe(autosave, selected -> {
String current = folder.getValue();
folder.setValue(null);
folder.setValue(current);
});

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Unrelated change

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.

This "crude toggle technique" is used as when attempting to simplify the process and combine two observables using EasyBind, unfortunately the system is smart enough to only need to activate or check the validation rule when the input it needs is changed (folder in this case) which is why there was a need to use this technique and trigger a change in the folder, thereby the rule would be evaluated and the Connect button would enable or disable appropriately.

@gandhroh000

Copy link
Copy Markdown
Contributor Author

i think, a change in view is enough

Hi @pluto-han thank you for your comments and I'd be happy to explain. The three comments you made regarding changes in ViewModel were necessary as the validation functions were firstly not using the autosave or useSSL fields to confirm that the information entered there was indeed accurate and should be processed (as these fields control whether the folder and keystore fields will be processed as input and checked). I will make further comments explaining each design choice, under each of your comments.

@Siedlerchr Siedlerchr 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.

Thanks for the comment/explanations!

@Siedlerchr Siedlerchr added this pull request to the merge queue May 7, 2026
@github-actions github-actions Bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label May 7, 2026
Merged via the queue into JabRef:main with commit eed1237 May 7, 2026
90 checks passed
Siedlerchr added a commit to pluto-han/jabref that referenced this pull request May 11, 2026
* upstream/main: (21 commits)
  chore(deps): update dependency com.konghq:unirest-modules-gson to v4.10.0 (JabRef#15715)
  Add manual tests (JabRef#15351)
  Refactored the comments for UnlinkedFilesCrawler (JabRef#15709)
  Replace inline styles with CSS classes (JabRef#15694)
  add test case for multiple authors in csl citaiton (JabRef#15707)
  fix invalid desktop file for linux (JabRef#15702)
  Change FileKeystore and Folder fields to disable/enable (JabRef#15685)
  Chore(deps): Bump org.openrewrite.recipe:rewrite-recipe-bom from 3.30.0 to 3.30.1 (JabRef#15696)
  New Crowdin updates (JabRef#15693)
  Chore(deps): Bump dev.langchain4j:langchain4j-bom in /versions (JabRef#15698)
  Chore(deps): Bump org.apache.logging.log4j:log4j-to-slf4j in /versions (JabRef#15700)
  chore(deps): update dependency org.apache.logging.log4j:log4j-to-slf4j to v2.26.0 (JabRef#15699)
  Chore(deps): Bump org.openrewrite.rewrite from 7.32.1 to 7.32.2 (JabRef#15697)
  Chore(deps): Bump jablib/src/main/resources/csl-locales (JabRef#15689)
  Fix month checker regex (JabRef#15678)
  Chore(deps): Bump com.dlsc.gemsfx:gemsfx in /versions (JabRef#15692)
  Chore(deps): Bump org.hisp.dhis:json-tree in /versions (JabRef#15691)
  Chore(deps): Bump jablib/src/main/resources/csl-styles (JabRef#15690)
  New Crowdin updates (JabRef#15687)
  Chore(deps): Bump com.konghq:unirest-java-core in /versions (JabRef#15683)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: no-bot-comments status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers 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.

Shared Database Login Dialog - Keystore Field Not Disabled when "Use SSL" Box Disabled

3 participants