mirror of
https://github.com/discourse/discourse.git
synced 2026-08-08 17:53:55 +08:00
Previously, the custom sidebar section editor and the server assumed a section's base title and link names were written in the site's current *default* locale, so changing the default locale scrambled which language each stored value mapped to and offered the wrong set of translation targets ([meta](https://meta.discourse.org/t/408327)). This change keys the editor, the same-locale de-duplication and the collision cleanup off each record's own source locale — now surfaced as an editable "Section language" — and reorganises the translation UI around languages rather than fields. ### Notable behaviour changes - Links keep their own source language, so saving a section no longer relabels a link authored in a different one. - A localization colliding with its record's source is now destroyed instead of being left behind to shadow the base string. The collision is matched **exactly**, so a regional variant like `en_GB` under an `en` source is preserved. - Localization permissions are evaluated against the visibility being *submitted*, so making a section public and translating it in one save no longer 403s and loses the edit. - `create` now enforces localization permissions, which it previously skipped entirely — an admin could write localizations onto a private section. A non-admin submitting localizations on create now gets a `403` instead of a silent drop, matching `update`. - A submitted locale is validated at the request boundary: an unsupported or over-long value returns `400` rather than an unhandled `500`. A value already stored on the record is still accepted, so AI-detected locales outside the supported list stay editable. ### UI <img width="821" height="646" alt="2026-07-29 @ 14 56 10" src="https://github.com/user-attachments/assets/19dad480-9f77-4f5b-b1a6-ed29689839a8" /> <img width="820" height="666" alt="2026-07-29 @ 14 56 16" src="https://github.com/user-attachments/assets/a9377282-d4b2-43af-91a6-700e10c50ce6" /> Translations moved from inline per-field rows to a single "Manage translations" entry point opening a language-major panel — one group per language holding the section title and every link name. The old layout rendered `1 + links × languages` rows with an add button per field, which stopped being usable at three links and two languages. A blank field means "not translated yet" rather than invalid, and clearing a saved translation now asks for confirmation before removing it.
118 lines
3.6 KiB
Ruby
Vendored
118 lines
3.6 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
RSpec.describe "Editing Sidebar Community Section" do
|
|
fab!(:admin)
|
|
fab!(:user)
|
|
|
|
let(:sidebar) { PageObjects::Components::NavigationMenu::Sidebar.new }
|
|
let(:sidebar_header_dropdown) { PageObjects::Components::NavigationMenu::HeaderDropdown.new }
|
|
|
|
it "should not display the edit section button to non admins" do
|
|
sign_in(user)
|
|
|
|
visit("/latest")
|
|
|
|
sidebar.click_community_section_more_button
|
|
|
|
expect(sidebar).to have_no_customize_community_section_button
|
|
end
|
|
|
|
it "allows admin to edit community section and reset to default" do
|
|
sign_in(admin)
|
|
|
|
visit("/latest")
|
|
|
|
expect(sidebar.primary_section_icons("community")).to eq(
|
|
%w[layer-group user inbox flag wrench paper-plane ellipsis-vertical],
|
|
)
|
|
|
|
modal = sidebar.click_community_section_more_button.click_customize_community_section_button
|
|
modal.fill_link("Topics", "/latest", "paper-plane")
|
|
modal.topics_link.drag_to(modal.review_link, delay: 0.4)
|
|
modal.save
|
|
modal.confirm_update
|
|
|
|
page.refresh
|
|
|
|
expect(sidebar.primary_section_links("community")).to eq(
|
|
["My posts", "My messages", "Topics", "Review", "Admin", "Invite", "More"],
|
|
)
|
|
|
|
expect(sidebar.primary_section_icons("community")).to eq(
|
|
%w[user inbox paper-plane flag wrench paper-plane ellipsis-vertical],
|
|
)
|
|
|
|
modal = sidebar.click_community_section_more_button.click_customize_community_section_button
|
|
modal.reset
|
|
|
|
expect(sidebar).to have_section("Community")
|
|
|
|
expect(sidebar.primary_section_links("community")).to eq(
|
|
["Topics", "My posts", "My messages", "Review", "Admin", "Invite", "More"],
|
|
)
|
|
|
|
expect(sidebar.primary_section_icons("community")).to eq(
|
|
%w[layer-group user inbox flag wrench paper-plane ellipsis-vertical],
|
|
)
|
|
end
|
|
|
|
it "lets an admin localize manually created Community section links" do
|
|
SiteSetting.content_localization_enabled = true
|
|
SiteSetting.content_localization_supported_locales = "ja"
|
|
user.update!(locale: "ja")
|
|
|
|
sign_in(admin)
|
|
|
|
visit("/latest")
|
|
|
|
modal = sidebar.click_community_section_more_button.click_customize_community_section_button
|
|
modal.add_link
|
|
modal.fill_last_link("Solutions Leaderboard", "/solutions-leaderboard")
|
|
modal.open_translations
|
|
modal.add_language("ja")
|
|
modal.fill_translation("ja", "Solutions Leaderboard", "ソリューションリーダーボード")
|
|
modal.close_translations
|
|
modal.add_link
|
|
modal.fill_last_link("Untranslated Link", "/untranslated-link")
|
|
modal.save
|
|
modal.confirm_update
|
|
|
|
sign_in(user)
|
|
|
|
visit("/latest")
|
|
|
|
expect(sidebar).to have_community_section_link("ソリューションリーダーボード", href: "/solutions-leaderboard")
|
|
expect(sidebar).to have_community_section_link("Untranslated Link", href: "/untranslated-link")
|
|
end
|
|
|
|
it "allows admin to edit community section when no secondary section links" do
|
|
SidebarSection
|
|
.where(title: "Community")
|
|
.first
|
|
.sidebar_section_links
|
|
.where.not(position: 0)
|
|
.destroy_all
|
|
|
|
sign_in(admin)
|
|
|
|
visit("/latest")
|
|
|
|
modal = sidebar.click_customize_community_section_button
|
|
|
|
expect(modal).to be_visible
|
|
end
|
|
|
|
it "should allow admins to open modal to edit the section when `navigation_menu` site setting is `header dropdown`" do
|
|
SiteSetting.navigation_menu = "header dropdown"
|
|
|
|
sign_in(admin)
|
|
|
|
visit("/latest")
|
|
|
|
sidebar_header_dropdown.open
|
|
expect(sidebar_header_dropdown).to have_dropdown_visible
|
|
modal = sidebar_header_dropdown.click_customize_community_section_button
|
|
|
|
expect(modal).to be_visible
|
|
end
|
|
end
|