fix: Adjust save button behaviour in identifier settings

This commit is contained in:
Tomas Hykel
2026-05-07 23:37:05 +02:00
parent bd7a0cfde1
commit ae3f4aa689
6 changed files with 28 additions and 12 deletions
@@ -77,7 +77,7 @@
scheme: :primary,
type: :submit,
form: form_id,
hidden: show_autofix_section?,
hidden: true,
data: { admin__work_packages_identifier_target: "saveButton" }
)
) { t("button_save") } %>
@@ -101,7 +101,8 @@ module WorkPackages
{
data: {
controller: "admin--work-packages-identifier",
admin__work_packages_identifier_has_problematic_projects_value: has_problematic_projects?
admin__work_packages_identifier_has_problematic_projects_value: has_problematic_projects?,
admin__work_packages_identifier_current_value_value: Setting[:work_packages_identifier]
}
}
end
@@ -33,36 +33,49 @@ import { Controller } from '@hotwired/stimulus';
export default class WorkPackagesIdentifierController extends Controller {
static values = {
hasProblematicProjects: Boolean,
currentValue: String,
};
static targets = ['autofixSection', 'saveButton', 'autofixButton'];
declare readonly hasProblematicProjectsValue:boolean;
declare readonly currentValueValue:string;
declare readonly autofixSectionTarget:HTMLElement;
declare readonly saveButtonTarget:HTMLButtonElement;
declare readonly autofixButtonTarget:HTMLButtonElement;
declare readonly hasSaveButtonTarget:boolean;
private readonly resetBeforeCache = ():void => {
if (this.hasSaveButtonTarget) this.saveButtonTarget.hidden = true;
};
connect() {
document.addEventListener('turbo:before-cache', this.resetBeforeCache);
this.updateVisibility();
}
disconnect() {
document.removeEventListener('turbo:before-cache', this.resetBeforeCache);
}
handleChange() {
this.updateVisibility();
}
private updateVisibility() {
const showAutofix = this.isSemanticSelected() && this.hasProblematicProjectsValue;
const selectedValue = this.selectedValue();
const showAutofix = selectedValue === 'semantic' && this.hasProblematicProjectsValue;
const isDirty = selectedValue !== this.currentValueValue;
this.autofixSectionTarget.hidden = !showAutofix;
this.saveButtonTarget.hidden = showAutofix;
this.saveButtonTarget.hidden = showAutofix || !isDirty;
this.autofixButtonTarget.hidden = !showAutofix;
}
private isSemanticSelected():boolean {
const checked = this.element.querySelector<HTMLInputElement>(
private selectedValue():string | undefined {
return this.element.querySelector<HTMLInputElement>(
'input[name="settings[work_packages_identifier]"]:checked',
);
return checked?.value === 'semantic';
)?.value;
}
}
@@ -130,9 +130,9 @@ RSpec.describe WorkPackages::Admin::Settings::IdentifierSettingsFormComponent, t
expect(ProjectIdentifiers::IdentifierAutofix::PreviewQuery).to have_received(:new).once
end
it "renders the save button" do
it "renders the save button (hidden until a change is made)" do
render_component(component)
expect(page).to have_button("Save")
expect(page).to have_button("Save", visible: :all)
end
it "does not render in-progress or success content" do
@@ -49,6 +49,7 @@ RSpec.describe "Work packages identifier admin settings", :js do
context "when no projects have problematic identifiers" do
it "saves the setting without showing a dialog" do
visit_settings
choose "Project-based semantic identifiers"
click_button "Save"
@@ -60,9 +61,10 @@ RSpec.describe "Work packages identifier admin settings", :js do
context "when a project has a problematic identifier" do
shared_let(:project) { create(:project, identifier: "bad-id", name: "Bad Project") }
context "when saving with the current classic setting" do
context "when switching from semantic to classic", with_settings: { work_packages_identifier: "semantic" } do
it "saves without showing the confirmation dialog" do
visit_settings
choose "Instance-wide numerical sequence (default)"
# The autofix section is hidden when classic is selected
expect(page).to have_css(
@@ -160,7 +160,7 @@ RSpec.describe ProjectIdentifiers::IdentifierAutofix::ProblematicIdentifiers do
end
end
describe "#reserved_identifiers_by_error_reasons" do
describe "#reserved_identifiers_for_admin_preview" do
subject(:exclusion) { analysis.reserved_identifiers_for_admin_preview }
let!(:valid_project) { create_project_with_raw_identifier(name: "Alpha", identifier: "ALPHA") }