mirror of
https://github.com/discourse/discourse.git
synced 2026-08-05 18:57:20 -05:00
FIX: Use localized auto group names instead of hardcoded English (#37757)
Automatic group names (everyone, staff, admins, etc.) are translated based on the site's default locale. However, the `AUTO_GROUPS` JS constant had hardcoded English names which were used directly in several places — most notably during category creation. This caused the "everyone" group to always display its English name in the permissions table, even on sites with a different default locale. This removes the `name` and `display_name` fields from `AUTO_GROUPS`, keeping only `id` and `automatic`. A new `groupsById` getter on the `Site` model provides a lookup map built from server-provided group data (which contains the properly localized names). All consumers now resolve group names via `site.groupsById[groupId].name` instead of reading from the constant. The avatar-flair system is also refactored from name-based to ID-based lookups, and group identity checks in `user.js` now compare by `id` rather than `name`. https://meta.discourse.org/t/395225
This commit is contained in:
+1
-4
@@ -39,10 +39,7 @@ export default class AdminConfigAreasAboutContactInformation extends Component {
|
||||
@action
|
||||
setContactGroup(groupIds, { set }) {
|
||||
this.contactGroupId = groupIds[0];
|
||||
set(
|
||||
"contactGroupName",
|
||||
this.site.groups.find((group) => group.id === groupIds[0])?.name
|
||||
);
|
||||
set("contactGroupName", this.site.groupsById[groupIds[0]]?.name);
|
||||
}
|
||||
|
||||
@action
|
||||
|
||||
@@ -26,6 +26,7 @@ import { eq } from "discourse/truth-helpers";
|
||||
import { i18n } from "discourse-i18n";
|
||||
|
||||
export default class UpcomingChangeItem extends Component {
|
||||
@service site;
|
||||
@service toasts;
|
||||
|
||||
@tracked bufferedGroups = this.args.change.groups;
|
||||
@@ -246,7 +247,7 @@ export default class UpcomingChangeItem extends Component {
|
||||
await this.toggleChange(isEnabled, newValue);
|
||||
|
||||
if (newValue === "staff") {
|
||||
this.groupsChanged(AUTO_GROUPS.staff.name);
|
||||
this.groupsChanged(this.site.groupsById[AUTO_GROUPS.staff.id].name);
|
||||
} else if (newValue === "everyone" || newValue === "no_one") {
|
||||
this.groupsChanged("");
|
||||
}
|
||||
|
||||
@@ -22,12 +22,6 @@ import IconPicker from "discourse/select-kit/components/icon-picker";
|
||||
import { eq, or } from "discourse/truth-helpers";
|
||||
import { i18n } from "discourse-i18n";
|
||||
|
||||
const EVERYONE_FULL_PERMISSION = {
|
||||
group_id: AUTO_GROUPS.everyone.id,
|
||||
group_name: AUTO_GROUPS.everyone.name,
|
||||
permission_type: PermissionType.FULL,
|
||||
};
|
||||
|
||||
export default class UpsertCategoryGeneral extends Component {
|
||||
@service site;
|
||||
@service siteSettings;
|
||||
@@ -44,6 +38,15 @@ export default class UpsertCategoryGeneral extends Component {
|
||||
|
||||
#previousPermissions = null;
|
||||
|
||||
// This needs to be dynamic because the name of the everyone group can be changed by admins
|
||||
get #everyoneFullPermission() {
|
||||
return {
|
||||
group_id: AUTO_GROUPS.everyone.id,
|
||||
group_name: this.site.groupsById[AUTO_GROUPS.everyone.id].name,
|
||||
permission_type: PermissionType.FULL,
|
||||
};
|
||||
}
|
||||
|
||||
get isParentRestricted() {
|
||||
const parentId = this.args.transientData.parent_category_id;
|
||||
if (!parentId) {
|
||||
@@ -101,10 +104,9 @@ export default class UpsertCategoryGeneral extends Component {
|
||||
@action
|
||||
onChangeAccessGroups(groupIds) {
|
||||
const newPermissions = groupIds.map((groupId) => {
|
||||
const group = this.site.groups.find((g) => g.id === groupId);
|
||||
return {
|
||||
group_id: groupId,
|
||||
group_name: group?.name,
|
||||
group_name: this.site.groupsById[groupId]?.name,
|
||||
permission_type: PermissionType.FULL,
|
||||
};
|
||||
});
|
||||
@@ -200,7 +202,7 @@ export default class UpsertCategoryGeneral extends Component {
|
||||
};
|
||||
|
||||
if (value === "public") {
|
||||
this.#setFormPermissions([EVERYONE_FULL_PERMISSION]);
|
||||
this.#setFormPermissions([this.#everyoneFullPermission]);
|
||||
} else if (value === "group_restricted") {
|
||||
if (this.#previousPermissions?.length) {
|
||||
this.#setFormPermissions(this.#previousPermissions);
|
||||
@@ -214,7 +216,7 @@ export default class UpsertCategoryGeneral extends Component {
|
||||
async onParentCategoryChange(parentCategoryId) {
|
||||
if (!parentCategoryId) {
|
||||
this.categoryVisibilityState = null;
|
||||
this.#setFormPermissions([EVERYONE_FULL_PERMISSION]);
|
||||
this.#setFormPermissions([this.#everyoneFullPermission]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -239,7 +241,7 @@ export default class UpsertCategoryGeneral extends Component {
|
||||
|
||||
this.#setFormPermissions(newPermissions);
|
||||
} else {
|
||||
this.#setFormPermissions([EVERYONE_FULL_PERMISSION]);
|
||||
this.#setFormPermissions([this.#everyoneFullPermission]);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -109,11 +109,10 @@ export default class UpsertCategorySecurity extends Component {
|
||||
|
||||
@action
|
||||
onSelectGroup(groupId) {
|
||||
const group = this.site.groups.find((g) => g.id === groupId);
|
||||
const newPermissions = [
|
||||
...(this.permissions || []),
|
||||
{
|
||||
group_name: group?.name,
|
||||
group_name: this.site.groupsById[groupId]?.name,
|
||||
group_id: groupId,
|
||||
permission_type: this.minimumPermission,
|
||||
},
|
||||
|
||||
@@ -78,7 +78,7 @@ export default class NewCategory extends DiscourseRoute {
|
||||
return [
|
||||
{
|
||||
group_id: AUTO_GROUPS.everyone.id,
|
||||
group_name: AUTO_GROUPS.everyone.name,
|
||||
group_name: this.site.groupsById[AUTO_GROUPS.everyone.id].name,
|
||||
permission_type: PermissionType.FULL,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -3,9 +3,9 @@ import { AUTO_GROUPS } from "discourse/lib/constants";
|
||||
let _autoGroupFlair, _noAutoFlair;
|
||||
|
||||
// All automatic groups except "everyone" (which doesn't have flair)
|
||||
const FLAIR_GROUP_NAMES = Object.values(AUTO_GROUPS)
|
||||
const FLAIR_AUTO_GROUP_IDS = Object.values(AUTO_GROUPS)
|
||||
.filter((g) => g.id !== AUTO_GROUPS.everyone.id)
|
||||
.map((g) => g.name);
|
||||
.map((g) => g.id);
|
||||
|
||||
export default function autoGroupFlairForUser(site, user) {
|
||||
if (!_autoGroupFlair) {
|
||||
@@ -17,24 +17,25 @@ export default function autoGroupFlairForUser(site, user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (user.admin && _autoGroupFlair.admins) {
|
||||
return _autoGroupFlair.admins;
|
||||
if (user.admin && _autoGroupFlair[AUTO_GROUPS.admins.id]) {
|
||||
return _autoGroupFlair[AUTO_GROUPS.admins.id];
|
||||
}
|
||||
|
||||
if (user.moderator && _autoGroupFlair.moderators) {
|
||||
return _autoGroupFlair.moderators;
|
||||
if (user.moderator && _autoGroupFlair[AUTO_GROUPS.moderators.id]) {
|
||||
return _autoGroupFlair[AUTO_GROUPS.moderators.id];
|
||||
}
|
||||
|
||||
if (_autoGroupFlair.staff && (user.admin || user.moderator)) {
|
||||
return _autoGroupFlair.staff;
|
||||
if ((user.admin || user.moderator) && _autoGroupFlair[AUTO_GROUPS.staff.id]) {
|
||||
return _autoGroupFlair[AUTO_GROUPS.staff.id];
|
||||
}
|
||||
|
||||
let trustLevel = user.trust_level || user.trustLevel;
|
||||
|
||||
if (trustLevel) {
|
||||
for (let i = trustLevel; i >= 0; i--) {
|
||||
if (_autoGroupFlair[`trust_level_${i}`]) {
|
||||
return _autoGroupFlair[`trust_level_${i}`];
|
||||
const group = AUTO_GROUPS[`trust_level_${i}`];
|
||||
if (group && _autoGroupFlair[group.id]) {
|
||||
return _autoGroupFlair[group.id];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,11 +50,11 @@ function initializeAutoGroupFlair(site) {
|
||||
_autoGroupFlair = {};
|
||||
_noAutoFlair = true;
|
||||
|
||||
FLAIR_GROUP_NAMES.forEach((groupName) => {
|
||||
const group = site.groups?.find((item) => item.name === groupName);
|
||||
if (group && group.flair_url) {
|
||||
FLAIR_AUTO_GROUP_IDS.forEach((groupId) => {
|
||||
const group = site.groupsById[groupId];
|
||||
if (group?.flair_url) {
|
||||
_noAutoFlair = false;
|
||||
_autoGroupFlair[groupName] = {
|
||||
_autoGroupFlair[groupId] = {
|
||||
flair_name: group.name.replace(/_/g, " "),
|
||||
flair_url: group.flair_url,
|
||||
flair_bg_color: group.flair_bg_color,
|
||||
|
||||
@@ -27,50 +27,15 @@ export const CATEGORY_STYLE_TYPES = { square: 0, icon: 1, emoji: 2 };
|
||||
export const CATEGORY_TEXT_COLORS = ["FFFFFF", "000000"];
|
||||
|
||||
export const AUTO_GROUPS = {
|
||||
everyone: {
|
||||
id: 0,
|
||||
automatic: true,
|
||||
name: "everyone",
|
||||
display_name: "everyone",
|
||||
},
|
||||
admins: { id: 1, automatic: true, name: "admins", display_name: "admins" },
|
||||
moderators: {
|
||||
id: 2,
|
||||
automatic: true,
|
||||
name: "moderators",
|
||||
display_name: "moderators",
|
||||
},
|
||||
staff: { id: 3, automatic: true, name: "staff", display_name: "staff" },
|
||||
trust_level_0: {
|
||||
id: 10,
|
||||
automatic: true,
|
||||
name: "trust_level_0",
|
||||
display_name: "trust_level_0",
|
||||
},
|
||||
trust_level_1: {
|
||||
id: 11,
|
||||
automatic: true,
|
||||
name: "trust_level_1",
|
||||
display_name: "trust_level_1",
|
||||
},
|
||||
trust_level_2: {
|
||||
id: 12,
|
||||
automatic: true,
|
||||
name: "trust_level_2",
|
||||
display_name: "trust_level_2",
|
||||
},
|
||||
trust_level_3: {
|
||||
id: 13,
|
||||
automatic: true,
|
||||
name: "trust_level_3",
|
||||
display_name: "trust_level_3",
|
||||
},
|
||||
trust_level_4: {
|
||||
id: 14,
|
||||
automatic: true,
|
||||
name: "trust_level_4",
|
||||
display_name: "trust_level_4",
|
||||
},
|
||||
everyone: { id: 0, automatic: true, name: "everyone" },
|
||||
admins: { id: 1, automatic: true, name: "admins" },
|
||||
moderators: { id: 2, automatic: true, name: "moderators" },
|
||||
staff: { id: 3, automatic: true, name: "staff" },
|
||||
trust_level_0: { id: 10, automatic: true, name: "trust_level_0" },
|
||||
trust_level_1: { id: 11, automatic: true, name: "trust_level_1" },
|
||||
trust_level_2: { id: 12, automatic: true, name: "trust_level_2" },
|
||||
trust_level_3: { id: 13, automatic: true, name: "trust_level_3" },
|
||||
trust_level_4: { id: 14, automatic: true, name: "trust_level_4" },
|
||||
};
|
||||
|
||||
export const GROUP_SMTP_SSL_MODES = { none: 0, ssl_tls: 1, starttls: 2 };
|
||||
|
||||
@@ -849,7 +849,8 @@ export default class Category extends RestModel {
|
||||
permissions.forEach((p) => (rval[p.group_name] = p.permission_type));
|
||||
} else {
|
||||
// empty permissions => staff-only access
|
||||
rval[AUTO_GROUPS.staff.name] = PermissionType.FULL;
|
||||
rval[Site.currentProp("groupsById")[AUTO_GROUPS.staff.id].name] =
|
||||
PermissionType.FULL;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { htmlSafe } from "@ember/template";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import { TrackedArray } from "@ember-compat/tracked-built-ins";
|
||||
import { removeValueFromArray } from "discourse/lib/array-tools";
|
||||
import { AUTO_GROUPS } from "discourse/lib/constants";
|
||||
import discourseComputed from "discourse/lib/decorators";
|
||||
import deprecated, { withSilencedDeprecations } from "discourse/lib/deprecated";
|
||||
import { isRailsTesting, isTesting } from "discourse/lib/environment";
|
||||
@@ -101,6 +102,13 @@ export default class Site extends RestModel {
|
||||
this.topicCountDesc = ["topic_count:desc"];
|
||||
}
|
||||
|
||||
get groupsById() {
|
||||
const map = {};
|
||||
Object.values(AUTO_GROUPS).forEach((g) => (map[g.id] = g));
|
||||
this.groups?.forEach((g) => (map[g.id] = g));
|
||||
return map;
|
||||
}
|
||||
|
||||
@dependentKeyCompat
|
||||
get desktopView() {
|
||||
return !this.mobileView;
|
||||
|
||||
@@ -792,7 +792,7 @@ export default class User extends RestModel.extend(Evented) {
|
||||
const groups = this.groups || [];
|
||||
|
||||
return groups.filter((group) => {
|
||||
return !group.automatic || group.name === AUTO_GROUPS.moderators.name;
|
||||
return !group.automatic || group.id === AUTO_GROUPS.moderators.id;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -2,33 +2,34 @@ import { render } from "@ember/test-helpers";
|
||||
import { module, test } from "qunit";
|
||||
import UserAvatarFlair from "discourse/components/user-avatar-flair";
|
||||
import { resetFlair } from "discourse/lib/avatar-flair";
|
||||
import { AUTO_GROUPS } from "discourse/lib/constants";
|
||||
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
||||
|
||||
function setupSiteGroups(that) {
|
||||
that.site.groups = [
|
||||
{
|
||||
id: 1,
|
||||
id: AUTO_GROUPS.admins.id,
|
||||
name: "admins",
|
||||
flair_url: "bars",
|
||||
flair_bg_color: "CC000A",
|
||||
flair_color: "FFFFFA",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
id: AUTO_GROUPS.staff.id,
|
||||
name: "staff",
|
||||
flair_url: "bars",
|
||||
flair_bg_color: "CC0005",
|
||||
flair_color: "FFFFF5",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
id: AUTO_GROUPS.trust_level_1.id,
|
||||
name: "trust_level_1",
|
||||
flair_url: "dice-one",
|
||||
flair_bg_color: "CC0001",
|
||||
flair_color: "FFFFF1",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
id: AUTO_GROUPS.trust_level_2.id,
|
||||
name: "trust_level_2",
|
||||
flair_url: "dice-two",
|
||||
flair_bg_color: "CC0002",
|
||||
|
||||
@@ -20,14 +20,7 @@ task "javascript:update_constants" => :environment do
|
||||
|
||||
auto_groups =
|
||||
Group::AUTO_GROUPS.inject({}) do |result, (group_name, group_id)|
|
||||
result.merge(
|
||||
group_name => {
|
||||
id: group_id,
|
||||
automatic: true,
|
||||
name: group_name,
|
||||
display_name: group_name,
|
||||
},
|
||||
)
|
||||
result.merge(group_name => { id: group_id, automatic: true, name: group_name })
|
||||
end
|
||||
|
||||
MAIN_FONT_KEYS = %w[helvetica inter lato montserrat open_sans poppins roboto merriweather mukta]
|
||||
|
||||
+2
-4
@@ -33,6 +33,7 @@ import RagUploader from "./rag-uploader";
|
||||
|
||||
export default class PersonaEditor extends Component {
|
||||
@service router;
|
||||
@service site;
|
||||
@service dialog;
|
||||
@service toasts;
|
||||
@service siteSettings;
|
||||
@@ -108,10 +109,7 @@ export default class PersonaEditor extends Component {
|
||||
(g) => g.id === AUTO_GROUPS.everyone.id
|
||||
);
|
||||
if (!hasEveryoneGroup) {
|
||||
groups.push({
|
||||
id: AUTO_GROUPS.everyone.id,
|
||||
name: AUTO_GROUPS.everyone.name,
|
||||
});
|
||||
groups.push(this.site.groupsById[AUTO_GROUPS.everyone.id]);
|
||||
}
|
||||
|
||||
this.allGroups = groups;
|
||||
|
||||
Reference in New Issue
Block a user