diff --git a/app/assets/javascripts/admin/addon/components/admin-config-area-cards/about/extra-groups.gjs b/app/assets/javascripts/admin/addon/components/admin-config-area-cards/about/extra-groups.gjs new file mode 100644 index 00000000000..c36398133a4 --- /dev/null +++ b/app/assets/javascripts/admin/addon/components/admin-config-area-cards/about/extra-groups.gjs @@ -0,0 +1,126 @@ +import Component from "@glimmer/component"; +import { cached } from "@glimmer/tracking"; +import { action } from "@ember/object"; +import { service } from "@ember/service"; +import Form from "discourse/components/form"; +import { ajax } from "discourse/lib/ajax"; +import { popupAjaxError } from "discourse/lib/ajax-error"; +import { i18n } from "discourse-i18n"; +import GroupChooser from "select-kit/components/group-chooser"; + +export default class AdminConfigAreasAboutExtraGroups extends Component { + @service site; + @service toasts; + + @cached + get data() { + return { + aboutPageExtraGroups: + this.args.extraGroups.aboutPageExtraGroups.value + .split("|") + .map(Number) || [], + aboutPageExtraGroupsInitialMembers: + this.args.extraGroups.aboutPageExtraGroupsInitialMembers.value, + aboutPageExtraGroupsOrder: + this.args.extraGroups.aboutPageExtraGroupsOrder.value, + aboutPageExtraGroupsShowDescription: + this.args.extraGroups.aboutPageExtraGroupsShowDescription.value === + "true", + }; + } + + @action + async save(data) { + this.args.setGlobalSavingStatus(true); + try { + await ajax("/admin/config/about.json", { + type: "PUT", + data: { + extra_groups: { + groups: data.aboutPageExtraGroups.join("|"), + initial_members: data.aboutPageExtraGroupsInitialMembers, + order: data.aboutPageExtraGroupsOrder, + show_description: data.aboutPageExtraGroupsShowDescription, + }, + }, + }); + this.toasts.success({ + duration: 30000, + data: { + message: i18n("admin.config_areas.about.toasts.extra_groups_saved"), + }, + }); + } catch (err) { + popupAjaxError(err); + } finally { + this.args.setGlobalSavingStatus(false); + } + } + + get orderings() { + return this.args.extraGroups.aboutPageExtraGroupsOrder.choices; + } + + +} diff --git a/app/assets/javascripts/admin/addon/components/admin-config-areas/about.gjs b/app/assets/javascripts/admin/addon/components/admin-config-areas/about.gjs index 02be84f8da1..7254a6d7e7e 100644 --- a/app/assets/javascripts/admin/addon/components/admin-config-areas/about.gjs +++ b/app/assets/javascripts/admin/addon/components/admin-config-areas/about.gjs @@ -1,12 +1,16 @@ import Component from "@glimmer/component"; import { tracked } from "@glimmer/tracking"; import { action } from "@ember/object"; +import { service } from "@ember/service"; import AdminConfigAreaCard from "admin/components/admin-config-area-card"; import AdminConfigAreasAboutContactInformation from "admin/components/admin-config-area-cards/about/contact-information"; +import AdminConfigAreasAboutExtraGroups from "admin/components/admin-config-area-cards/about/extra-groups"; import AdminConfigAreasAboutGeneralSettings from "admin/components/admin-config-area-cards/about/general-settings"; import AdminConfigAreasAboutYourOrganization from "admin/components/admin-config-area-cards/about/your-organization"; export default class AdminConfigAreasAbout extends Component { + @service siteSettings; + @tracked saving = false; get generalSettings() { @@ -39,6 +43,27 @@ export default class AdminConfigAreasAbout extends Component { }; } + get extraGroups() { + return { + aboutPageExtraGroups: this.#lookupSettingFromData( + "about_page_extra_groups" + ), + aboutPageExtraGroupsInitialMembers: this.#lookupSettingFromData( + "about_page_extra_groups_initial_members" + ), + aboutPageExtraGroupsOrder: this.#lookupSettingFromData( + "about_page_extra_groups_order" + ), + aboutPageExtraGroupsShowDescription: this.#lookupSettingFromData( + "about_page_extra_groups_show_description" + ), + }; + } + + get showExtraGroups() { + return this.siteSettings.show_additional_about_groups === true; + } + @action setSavingStatus(status) { this.saving = status; @@ -91,6 +116,22 @@ export default class AdminConfigAreasAbout extends Component { /> + {{#if this.showExtraGroups}} + + <:content> + + + + {{/if}} diff --git a/app/assets/javascripts/discourse/app/components/about-page-extra-groups.gjs b/app/assets/javascripts/discourse/app/components/about-page-extra-groups.gjs new file mode 100644 index 00000000000..662445f1741 --- /dev/null +++ b/app/assets/javascripts/discourse/app/components/about-page-extra-groups.gjs @@ -0,0 +1,129 @@ +import Component from "@glimmer/component"; +import { tracked } from "@glimmer/tracking"; +import { action } from "@ember/object"; +import { service } from "@ember/service"; +import { htmlSafe } from "@ember/template"; +import AboutPageUsers from "discourse/components/about-page-users"; +import ConditionalLoadingSpinner from "discourse/components/conditional-loading-spinner"; +import { ajax } from "discourse/lib/ajax"; + +export default class AboutPageExtraGroups extends Component { + @service store; + @service site; + @service siteSettings; + + @tracked groups = []; + @tracked loading = false; + + constructor() { + super(...arguments); + this.loadGroups(); + } + + groupName(group) { + return group.full_name || group.name.replace(/[_-]/g, " "); + } + + @action + async loadGroups() { + this.loading = true; + try { + const groupsSetting = + this.siteSettings.about_page_extra_groups?.split("|").map(Number) || []; + + let groupsToFetch = this.site.groups.filter((group) => + groupsSetting.includes(group.id) + ); + + // ordered alphabetically by default + if ( + this.siteSettings.about_page_extra_groups_order === "order of creation" + ) { + groupsToFetch.sort((a, b) => a.id - b.id); + } + + const groupPromises = groupsToFetch.map(async (group) => { + try { + const groupDetails = await this.loadGroupDetails(group.name); + group.members = await this.loadGroupMembers(group.name); + Object.assign(group, groupDetails); + return group; + } catch (error) { + // eslint-disable-next-line no-console + console.error( + `Error loading members for group ${group.name}:`, + error + ); + return null; + } + }); + + const groupsWithMembers = (await Promise.all(groupPromises)).filter( + (group) => group && group.members.length > 0 + ); + + this.groups = groupsWithMembers; + } catch (error) { + // eslint-disable-next-line no-console + console.error("Error loading groups:", error); + this.groups = []; + } finally { + this.loading = false; + } + } + + async loadGroupDetails(groupName) { + try { + const response = await ajax(`/g/${groupName}`); + return response.group; + } catch (error) { + // eslint-disable-next-line no-console + console.error(`Error loading details for group ${groupName}:`, error); + return ""; + } + } + + async loadGroupMembers(groupName) { + try { + const response = await ajax(`/g/${groupName}/members?asc=true`); + return response.members || []; + } catch (error) { + // eslint-disable-next-line no-console + console.error(`Error loading members for group ${groupName}:`, error); + return []; + } + } + + get showGroupDescription() { + return this.siteSettings.about_page_extra_groups_show_description; + } + + get showInitialMembers() { + return this.siteSettings.about_page_extra_groups_initial_members; + } + + +} diff --git a/app/assets/javascripts/discourse/app/components/about-page.gjs b/app/assets/javascripts/discourse/app/components/about-page.gjs index 22bc68054da..bcbd56f3621 100644 --- a/app/assets/javascripts/discourse/app/components/about-page.gjs +++ b/app/assets/javascripts/discourse/app/components/about-page.gjs @@ -3,6 +3,8 @@ import { hash } from "@ember/helper"; import { LinkTo } from "@ember/routing"; import { service } from "@ember/service"; import { htmlSafe } from "@ember/template"; +import { isBlank } from "@ember/utils"; +import AboutPageExtraGroups from "discourse/components/about-page-extra-groups"; import AboutPageUsers from "discourse/components/about-page-users"; import PluginOutlet from "discourse/components/plugin-outlet"; import icon from "discourse/helpers/d-icon"; @@ -230,6 +232,13 @@ export default class AboutPage extends Component { return configs; } + get showExtraGroups() { + return ( + this.siteSettings.show_additional_about_groups === true && + !isBlank(this.siteSettings.about_page_extra_groups) + ); + } +