diff --git a/app/components/settings/user_custom_field_sections/show_component.html.erb b/app/components/settings/user_custom_field_sections/show_component.html.erb index 55234ff31a83..0ce245bec070 100644 --- a/app/components/settings/user_custom_field_sections/show_component.html.erb +++ b/app/components/settings/user_custom_field_sections/show_component.html.erb @@ -9,7 +9,7 @@ end content_container.with_column do render(Primer::Beta::Text.new(font_weight: :bold)) do - @user_custom_field_section.name.presence || t("settings.user_custom_fields.label_untitled_section") + @user_custom_field_section.name end end end diff --git a/app/components/users/profile/attributes_section_component.rb b/app/components/users/profile/attributes_section_component.rb index 59ad8b97c5b1..5c584457d8d8 100644 --- a/app/components/users/profile/attributes_section_component.rb +++ b/app/components/users/profile/attributes_section_component.rb @@ -52,7 +52,7 @@ def attributes end def section_title - @section.name.presence || t("settings.user_custom_fields.label_untitled_section") + @section.name end end end diff --git a/app/forms/custom_fields/details_form.rb b/app/forms/custom_fields/details_form.rb index f19a35f6f8e0..c28703384992 100644 --- a/app/forms/custom_fields/details_form.rb +++ b/app/forms/custom_fields/details_form.rb @@ -55,7 +55,7 @@ class DetailsForm < ApplicationForm required: true ) do |list| section_class_for_model.all.each do |cs| # rubocop:disable Rails/FindEach -- ordered by default_scope; find_each would override it - list.option(value: cs.id, label: cs.name.presence || I18n.t("settings.user_custom_fields.label_untitled_section")) + list.option(value: cs.id, label: cs.name) end end end diff --git a/app/forms/users/form/attributes_form.rb b/app/forms/users/form/attributes_form.rb index bcd00d1edfcf..cbec05f1d98c 100644 --- a/app/forms/users/form/attributes_form.rb +++ b/app/forms/users/form/attributes_form.rb @@ -105,7 +105,7 @@ def render_section(form, section) end def section_title(section) - section.name.presence || I18n.t("settings.user_custom_fields.label_untitled_section") + section.name end def render_built_in(group, key) diff --git a/app/models/user_custom_field_section.rb b/app/models/user_custom_field_section.rb index be787c937225..86552cbf4ef3 100644 --- a/app/models/user_custom_field_section.rb +++ b/app/models/user_custom_field_section.rb @@ -74,8 +74,4 @@ def self.with_filled_fields_for(user, visible_on_user_card: nil) # rubocop:disab [section, ordered] if ordered.any? end end - - def untitled? - name.blank? - end end diff --git a/app/seeders/basic_data/user_custom_field_section_seeder.rb b/app/seeders/basic_data/user_custom_field_section_seeder.rb index ad6f40df824c..76ab1ef28cb6 100644 --- a/app/seeders/basic_data/user_custom_field_section_seeder.rb +++ b/app/seeders/basic_data/user_custom_field_section_seeder.rb @@ -31,14 +31,11 @@ module BasicData class UserCustomFieldSectionSeeder < Seeder def seed_data! - # The default section is intentionally untitled — it renders the I18n fallback - # label in the UI. The name validation is bypassed to match the migration that - # creates the same section for existing installations. - section = UserCustomFieldSection.new( + UserCustomFieldSection.create!( + name: I18n.t("settings.user_custom_fields.label_default_section", locale: Setting.default_language), position: 1, attribute_order: UserCustomFieldSection::BUILT_IN_ATTRIBUTES ) - section.save!(validate: false) end def applicable? diff --git a/config/locales/en.yml b/config/locales/en.yml index f7031199eb12..c21fe47a6664 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -5851,7 +5851,7 @@ en: heading: "User attributes" label_new_attribute: "User attribute" label_new_section: "Section" - label_untitled_section: "User attributes" + label_default_section: "User attributes" new: heading: "New attribute" tabs: diff --git a/db/migrate/20260706104133_backfill_default_user_custom_field_section_name.rb b/db/migrate/20260706104133_backfill_default_user_custom_field_section_name.rb new file mode 100644 index 000000000000..6f6f474d32c8 --- /dev/null +++ b/db/migrate/20260706104133_backfill_default_user_custom_field_section_name.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +class BackfillDefaultUserCustomFieldSectionName < ActiveRecord::Migration[8.1] + def up + execute(<<~SQL.squish) + UPDATE custom_field_sections + SET name = #{quote(default_section_name)}, updated_at = NOW() + WHERE type = 'UserCustomFieldSection' + AND (name IS NULL OR name = '') + SQL + end + + def down + execute(<<~SQL.squish) + UPDATE custom_field_sections + SET name = NULL, updated_at = NOW() + WHERE type = 'UserCustomFieldSection' + AND name = #{quote(default_section_name)} + SQL + end + + private + + def default_section_name + I18n.t("settings.user_custom_fields.label_default_section", locale: default_language) + end + + # Settings may be unavailable when migrating a clean database (e.g. the settings + # table or its seeds are not yet present), so fall back to English. + def default_language + Setting.default_language.presence || "en" + rescue StandardError + "en" + end +end diff --git a/spec/components/users/profile/attributes_section_component_spec.rb b/spec/components/users/profile/attributes_section_component_spec.rb index 38f0fed29c8a..010cb00a7982 100644 --- a/spec/components/users/profile/attributes_section_component_spec.rb +++ b/spec/components/users/profile/attributes_section_component_spec.rb @@ -96,21 +96,4 @@ expect(component.render?).to be(false) end end - - context "with an untitled section" do - shared_let(:custom_field) do - create(:user_custom_field, :string, user_custom_field_section: section) - end - let(:user) { create(:user, custom_values: [build(:custom_value, custom_field:, value: "x")]) } - - before do - section.update_column(:name, nil) - section.update_column(:attribute_order, [custom_field.column_name]) - render_inline(component) - end - - it "renders the I18n fallback label" do - expect(page).to have_text(I18n.t("settings.user_custom_fields.label_untitled_section")) - end - end end diff --git a/spec/models/user_custom_field_section_spec.rb b/spec/models/user_custom_field_section_spec.rb index b85474ff4023..cefc5461668a 100644 --- a/spec/models/user_custom_field_section_spec.rb +++ b/spec/models/user_custom_field_section_spec.rb @@ -39,12 +39,6 @@ end end - describe "#untitled?" do - it { expect(described_class.new(name: nil)).to be_untitled } - it { expect(described_class.new(name: "")).to be_untitled } - it { expect(described_class.new(name: "My section")).not_to be_untitled } - end - describe "#add_to_order" do it "appends to the end when no position given" do section.add_to_order("cf_1")