DEV: Improve the sidebar section expansion handling (#27805)

Handles the cases where the sections titles are Unicode only strings, allowing them to be expanded separately if the Unicode string contains letters.

Also prevents a sidebar section with the header hidden to be displayed collapsed.
This commit is contained in:
Sérgio Saquetim 2024-07-09 18:32:29 -03:00 committed by GitHub
parent dd67375de7
commit bbd67eff08
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 123 additions and 9 deletions

View File

@ -1,5 +1,5 @@
import SidebarCustomSection from "../common/custom-sections";
import SidebarCustomSections from "../common/custom-sections";
export default class SidebarAnonymousCustomSections extends SidebarCustomSection {
export default class SidebarAnonymousCustomSections extends SidebarCustomSections {
anonymous = true;
}

View File

@ -2,7 +2,7 @@ import Component from "@glimmer/component";
import { service } from "@ember/service";
import CustomSection from "./custom-section";
export default class SidebarCustomSection extends Component {
export default class SidebarCustomSections extends Component {
@service currentUser;
@service router;
@service messageBus;

View File

@ -5,6 +5,7 @@ import { action } from "@ember/object";
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
import { service } from "@ember/service";
import { isEmpty } from "@ember/utils";
import concatClass from "discourse/helpers/concat-class";
import {
getCollapsedSidebarSectionKey,
getSidebarSectionContentId,
@ -60,7 +61,7 @@ export default class SidebarSection extends Component {
}
get displaySectionContent() {
if (!isEmpty(this.sidebarState.filter)) {
if (this.args.hideSectionHeader || !isEmpty(this.sidebarState.filter)) {
return true;
}
@ -115,7 +116,15 @@ export default class SidebarSection extends Component {
<div
{{didInsert this.setExpandedState}}
data-section-name={{@sectionName}}
class="sidebar-section-wrapper sidebar-section"
class={{concatClass
"sidebar-section"
"sidebar-section-wrapper"
(if
this.displaySectionContent
"sidebar-section--expanded"
"sidebar-section--collapsed"
)
}}
...attributes
>
{{#unless @hideSectionHeader}}

View File

@ -1,8 +1,8 @@
import { ajax } from "discourse/lib/ajax";
import { bind } from "discourse-common/utils/decorators";
import SidebarCustomSection from "../common/custom-sections";
import SidebarCustomSections from "../common/custom-sections";
export default class SidebarUserCustomSections extends SidebarCustomSection {
export default class SidebarUserCustomSections extends SidebarCustomSections {
constructor() {
super(...arguments);
this.messageBus.subscribe("/refresh-sidebar-sections", this._refresh);

View File

@ -1,9 +1,11 @@
import { tracked } from "@glimmer/tracking";
import { setOwner } from "@ember/application";
import { service } from "@ember/service";
import { isPresent } from "@ember/utils";
import SidebarSectionForm from "discourse/components/modal/sidebar-section-form";
import { ajax } from "discourse/lib/ajax";
import SectionLink from "discourse/lib/sidebar/section-link";
import { unicodeSlugify } from "discourse/lib/utilities";
import { bind } from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
@ -19,7 +21,9 @@ export default class Section {
setOwner(this, owner);
this.section = section;
this.slug = section.slug;
this.slug = isPresent(section.slug)
? section.slug
: unicodeSlugify(section.title);
this.links = this.section.links.map((link) => {
return new SectionLink(link, this, this.router);

View File

@ -372,6 +372,24 @@ export function slugify(string) {
.replace(/-+$/, ""); // Remove trailing dashes
}
export function unicodeSlugify(string) {
try {
return string
.trim()
.toLowerCase()
.normalize("NFD") // normalize the string to remove diacritics
.replace(/\s|_+/g, "-") // replace spaces and underscores with dashes
.replace(/[^\p{Letter}\d\-]+/gu, "") // Remove non-letter characters except for dashes
.replace(/--+/g, "-") // replace multiple dashes with a single dash
.replace(/^-+/, "") // Remove leading dashes
.replace(/-+$/, ""); // Remove trailing dashes
} catch (e) {
// in case the regex construct \p{Letter} is not supported by the browser
// fall back to the basic slugify function
return slugify(string);
}
}
export function toNumber(input) {
return typeof input === "number" ? input : parseFloat(input);
}

View File

@ -20,6 +20,7 @@ import {
setDefaultHomepage,
slugify,
toAsciiPrintable,
unicodeSlugify,
} from "discourse/lib/utilities";
import {
mdTable,
@ -202,6 +203,37 @@ module("Unit | Utilities", function (hooks) {
);
});
test("unicodeSlugify", function (assert) {
const asciiString = "--- 0__( Some--cool Discourse Site! )__0 --- ";
const accentedString = "Créme_Brûlée!";
const unicodeString = "談話";
const unicodeStringWithEmojis = "⌘😁 談話";
assert.strictEqual(
unicodeSlugify(asciiString),
"0-some-cool-discourse-site-0",
"it properly slugifies an ASCII string"
);
assert.strictEqual(
unicodeSlugify(accentedString),
"creme-brulee",
"it removes diacritics"
);
assert.strictEqual(
unicodeSlugify(unicodeString),
"談話",
"it keeps unicode letters"
);
assert.strictEqual(
unicodeSlugify(unicodeStringWithEmojis),
"談話",
"it removes emojis and symbols"
);
});
test("fillMissingDates", function (assert) {
const startDate = "2017-11-12"; // YYYY-MM-DD
const endDate = "2017-12-12"; // YYYY-MM-DD

View File

@ -395,4 +395,39 @@ describe "Custom sidebar sections", type: :system do
expect(section_modal).to have_disabled_save
end
it "allows the user to expand/collapse section containing unicode titles separately" do
sidebar_section1 = Fabricate(:sidebar_section, title: "談話", user: user)
Fabricate(:sidebar_url, name: "Sidebar Latest", value: "/latest").tap do |sidebar_url|
Fabricate(:sidebar_section_link, sidebar_section: sidebar_section1, linkable: sidebar_url)
end
sidebar_section2 = Fabricate(:sidebar_section, title: "", user: user)
Fabricate(:sidebar_url, name: "Sidebar Categories", value: "/categories").tap do |sidebar_url|
Fabricate(:sidebar_section_link, sidebar_section: sidebar_section2, linkable: sidebar_url)
end
sign_in user
visit("/latest")
expect(sidebar).to have_section_expanded("談話")
expect(sidebar).to have_section_expanded("")
sidebar.click_section_header("談話")
expect(sidebar).to have_section_collapsed("談話")
expect(sidebar).to have_section_expanded("")
sidebar.click_section_header("")
expect(sidebar).to have_section_collapsed("談話")
expect(sidebar).to have_section_collapsed("")
sidebar.click_section_header("談話")
expect(sidebar).to have_section_expanded("談話")
expect(sidebar).to have_section_collapsed("")
sidebar.click_section_header("")
expect(sidebar).to have_section_expanded("談話")
expect(sidebar).to have_section_expanded("")
end
end

View File

@ -19,7 +19,11 @@ module PageObjects
end
def find_section(name)
find(".sidebar-section[data-section-name='#{name}']")
find(sidebar_section_selector(name))
end
def click_section_header(name)
find("#{sidebar_section_selector(name)} .sidebar-section-header").click
end
def click_section_link(name)
@ -59,6 +63,14 @@ module PageObjects
has_no_css?(".sidebar-sections [data-section-name='#{name.parameterize}']")
end
def has_section_expanded?(name)
has_css?("#{sidebar_section_selector(name)}.sidebar-section--expanded")
end
def has_section_collapsed?(name)
has_css?("#{sidebar_section_selector(name)}.sidebar-section--collapsed")
end
def switch_to_chat
find(".sidebar__panel-switch-button[data-key='chat']").click
end
@ -183,6 +195,10 @@ module PageObjects
private
def sidebar_section_selector(name)
".sidebar-section[data-section-name='#{name}']"
end
def section_link_present?(name, href: nil, active: false, target: nil, count: 1, present:)
attributes = { exact_text: name }
attributes[:href] = href if href