DEV: Wiring for the admin about config page (#27492)

This commit continues work laid out by ffec8163b0 for the admin config page for the /about page. The last commit set up the user interface, and this one sets up all the wiring needed to make the input fields and save buttons actually work.

Internal topic: t/128544.
This commit is contained in:
Osama Sayegh 2024-07-01 05:40:37 +03:00 committed by GitHub
parent e8a41011eb
commit 4c1c25027d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 725 additions and 49 deletions

View File

@ -6,7 +6,7 @@ export default class AdminConfigAreaCard extends Component {
@tracked collapsed = false;
<template>
<section class="admin-config-area-card">
<section class="admin-config-area-card" ...attributes>
<h3 class="admin-config-area-card__title">{{i18n @heading}}</h3>
<div class="admin-config-area-card__content">
{{yield}}

View File

@ -1,20 +1,78 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { fn, hash } from "@ember/helper";
import { on } from "@ember/modifier";
import { action } from "@ember/object";
import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import withEventValue from "discourse/helpers/with-event-value";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
import i18n from "discourse-common/helpers/i18n";
import I18n from "discourse-i18n";
import GroupChooser from "select-kit/components/group-chooser";
import UserChooser from "select-kit/components/user-chooser";
export default class AdminConfigAreasAboutContactInformation extends Component {
@service site;
@service toasts;
@tracked
contactUsername = this.args.contactInformation.contactUsername.value || null;
@tracked
contactGroupId = this.site.groups.find(
(group) => group.name === this.contactGroupName
)?.id;
communityOwner = this.args.contactInformation.communityOwner.value;
contactEmail = this.args.contactInformation.contactEmail.value;
contactURL = this.args.contactInformation.contactURL.value;
contactGroupName = this.args.contactInformation.contactGroupName.value;
@action
save() {
this.args.saveCallback();
// eslint-disable-next-line no-console
console.log("contact information");
onContactUsernameChange(usernames) {
this.contactUsername = usernames[0];
}
@action
onContactGroupIdChange(ids, groups) {
this.contactGroupId = ids[0];
this.contactGroupName = groups[0]?.name;
}
@action
async save() {
try {
this.args.setGlobalSavingStatus(true);
await ajax("/admin/config/about.json", {
type: "PUT",
data: {
contact_information: {
community_owner: this.communityOwner,
contact_email: this.contactEmail,
contact_url: this.contactURL,
contact_username: this.contactUsername,
contact_group_name: this.contactGroupName,
},
},
});
this.toasts.success({
duration: 3000,
data: {
message: I18n.t(
"admin.config_areas.about.toasts.contact_information_saved"
),
},
});
} catch (err) {
popupAjaxError(err);
} finally {
this.args.setGlobalSavingStatus(false);
}
}
<template>
<div class="control-group">
<div class="control-group community-owner-input">
<label>
<span>{{i18n "admin.config_areas.about.community_owner"}}</span>
<span class="admin-config-area-card__label-optional">{{i18n
@ -24,9 +82,13 @@ export default class AdminConfigAreasAboutContactInformation extends Component {
<p class="admin-config-area-card__additional-help">
{{i18n "admin.config_areas.about.community_owner_help"}}
</p>
<input type="text" />
<input
{{on "input" (withEventValue (fn (mut this.communityOwner)))}}
type="text"
value={{this.communityOwner}}
/>
</div>
<div class="control-group">
<div class="control-group contact-email-input">
<label>
<span>{{i18n "admin.config_areas.about.contact_email"}}</span>
<span class="admin-config-area-card__label-optional">{{i18n
@ -36,9 +98,13 @@ export default class AdminConfigAreasAboutContactInformation extends Component {
<p class="admin-config-area-card__additional-help">
{{i18n "admin.config_areas.about.contact_email_help"}}
</p>
<input type="text" />
<input
{{on "input" (withEventValue (fn (mut this.contactEmail)))}}
type="text"
value={{this.contactEmail}}
/>
</div>
<div class="control-group">
<div class="control-group contact-url-input">
<label>
<span>{{i18n "admin.config_areas.about.contact_url"}}</span>
<span class="admin-config-area-card__label-optional">{{i18n
@ -48,9 +114,13 @@ export default class AdminConfigAreasAboutContactInformation extends Component {
<p class="admin-config-area-card__additional-help">
{{i18n "admin.config_areas.about.contact_url_help"}}
</p>
<input type="text" />
<input
{{on "input" (withEventValue (fn (mut this.contactURL)))}}
type="text"
value={{this.contactURL}}
/>
</div>
<div class="control-group">
<div class="control-group site-contact-username-input">
<label>
<span>{{i18n "admin.config_areas.about.site_contact_name"}}</span>
<span class="admin-config-area-card__label-optional">{{i18n
@ -60,9 +130,13 @@ export default class AdminConfigAreasAboutContactInformation extends Component {
<p class="admin-config-area-card__additional-help">
{{i18n "admin.config_areas.about.site_contact_name_help"}}
</p>
<UserChooser />
<UserChooser
@value={{this.contactUsername}}
@onChange={{this.onContactUsernameChange}}
@options={{hash maximum=1}}
/>
</div>
<div class="control-group">
<div class="control-group site-contact-group-input">
<label>
<span>{{i18n "admin.config_areas.about.site_contact_group"}}</span>
<span class="admin-config-area-card__label-optional">{{i18n
@ -72,12 +146,18 @@ export default class AdminConfigAreasAboutContactInformation extends Component {
<p class="admin-config-area-card__additional-help">
{{i18n "admin.config_areas.about.site_contact_group_help"}}
</p>
<GroupChooser />
<GroupChooser
@content={{this.site.groups}}
@value={{this.contactGroupId}}
@onChange={{this.onContactGroupIdChange}}
@options={{hash maximum=1}}
/>
</div>
<DButton
@label="admin.config_areas.about.update"
@action={{this.save}}
class="btn-primary"
@disabled={{@globalSavingStatus}}
class="btn-primary admin-config-area-card__btn-save"
/>
</template>
}

View File

@ -1,37 +1,82 @@
import Component from "@glimmer/component";
import { fn } from "@ember/helper";
import { on } from "@ember/modifier";
import { action } from "@ember/object";
import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import DEditor from "discourse/components/d-editor";
import UppyImageUploader from "discourse/components/uppy-image-uploader";
import withEventValue from "discourse/helpers/with-event-value";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
import i18n from "discourse-common/helpers/i18n";
import I18n from "discourse-i18n";
export default class AdminConfigAreasAboutGeneralSettings extends Component {
@service toasts;
name = this.args.generalSettings.title.value;
summary = this.args.generalSettings.siteDescription.value;
extendedDescription = this.args.generalSettings.extendedSiteDescription.value;
aboutBannerImage = this.args.generalSettings.aboutBannerImage.value;
@action
save() {
this.args.saveCallback();
// eslint-disable-next-line no-console
console.log("general settings");
async save() {
try {
this.args.setGlobalSavingStatus(true);
await ajax("/admin/config/about.json", {
type: "PUT",
data: {
general_settings: {
name: this.name,
summary: this.summary,
extended_description: this.extendedDescription,
about_banner_image: this.aboutBannerImage,
},
},
});
this.toasts.success({
duration: 3000,
data: {
message: I18n.t(
"admin.config_areas.about.toasts.general_settings_saved"
),
},
});
} catch (err) {
popupAjaxError(err);
} finally {
this.args.setGlobalSavingStatus(false);
}
}
<template>
<div class="control-group">
<div class="control-group community-name-input">
<label>{{i18n "admin.config_areas.about.community_name"}}</label>
<input type="text" />
<input
{{on "input" (withEventValue (fn (mut this.name)))}}
type="text"
value={{this.name}}
/>
</div>
<div class="control-group">
<div class="control-group community-summary-input">
<label>{{i18n "admin.config_areas.about.community_summary"}}</label>
<input type="text" />
<input
{{on "input" (withEventValue (fn (mut this.summary)))}}
type="text"
value={{this.summary}}
/>
</div>
<div class="control-group">
<div class="control-group community-description-input">
<label>
<span>{{i18n "admin.config_areas.about.community_description"}}</span>
<span class="admin-config-area-card__label-optional">{{i18n
"admin.config_areas.about.optional"
}}</span>
</label>
<DEditor />
<DEditor @value={{this.extendedDescription}} />
</div>
<div class="control-group">
<div class="control-group banner-image-uploader">
<label>
<span>{{i18n "admin.config_areas.about.banner_image"}}</span>
<span class="admin-config-area-card__label-optional">{{i18n
@ -41,12 +86,16 @@ export default class AdminConfigAreasAboutGeneralSettings extends Component {
<p class="admin-config-area-card__additional-help">
{{i18n "admin.config_areas.about.banner_image_help"}}
</p>
<UppyImageUploader />
<UppyImageUploader
@type="site_setting"
@imageUrl={{this.aboutBannerImage}}
/>
</div>
<DButton
@label="admin.config_areas.about.update"
@action={{this.save}}
class="btn-primary"
@disabled={{@globalSavingStatus}}
class="btn-primary admin-config-area-card__btn-save"
/>
</template>
}

View File

@ -1,18 +1,53 @@
import Component from "@glimmer/component";
import { fn } from "@ember/helper";
import { on } from "@ember/modifier";
import { action } from "@ember/object";
import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import withEventValue from "discourse/helpers/with-event-value";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
import i18n from "discourse-common/helpers/i18n";
import I18n from "discourse-i18n";
export default class AdminConfigAreasAboutYourOrganization extends Component {
@service toasts;
companyName = this.args.yourOrganization.companyName.value;
governingLaw = this.args.yourOrganization.governingLaw.value;
cityForDisputes = this.args.yourOrganization.cityForDisputes.value;
@action
save() {
this.args.saveCallback();
// eslint-disable-next-line no-console
console.log("your organization");
async save() {
this.args.setGlobalSavingStatus(true);
try {
await ajax("/admin/config/about.json", {
type: "PUT",
data: {
your_organization: {
company_name: this.companyName,
governing_law: this.governingLaw,
city_for_disputes: this.cityForDisputes,
},
},
});
this.toasts.success({
duration: 30000,
data: {
message: I18n.t(
"admin.config_areas.about.toasts.your_organization_saved"
),
},
});
} catch (err) {
popupAjaxError(err);
} finally {
this.args.setGlobalSavingStatus(false);
}
}
<template>
<div class="control-group">
<div class="control-group company-name-input">
<label>
<span>{{i18n "admin.config_areas.about.company_name"}}</span>
<span class="admin-config-area-card__label-optional">{{i18n
@ -25,9 +60,13 @@ export default class AdminConfigAreasAboutYourOrganization extends Component {
<p class="admin-config-area-card__warning-banner">
{{i18n "admin.config_areas.about.company_name_warning"}}
</p>
<input type="text" />
<input
{{on "input" (withEventValue (fn (mut this.companyName)))}}
type="text"
value={{this.companyName}}
/>
</div>
<div class="control-group">
<div class="control-group governing-law-input">
<label>
<span>{{i18n "admin.config_areas.about.governing_law"}}</span>
<span class="admin-config-area-card__label-optional">{{i18n
@ -37,9 +76,13 @@ export default class AdminConfigAreasAboutYourOrganization extends Component {
<p class="admin-config-area-card__additional-help">
{{i18n "admin.config_areas.about.governing_law_help"}}
</p>
<input type="text" />
<input
{{on "input" (withEventValue (fn (mut this.governingLaw)))}}
type="text"
value={{this.governingLaw}}
/>
</div>
<div class="control-group">
<div class="control-group city-for-disputes-input">
<label>
<span>{{i18n "admin.config_areas.about.city_for_disputes"}}</span>
<span class="admin-config-area-card__label-optional">{{i18n
@ -49,12 +92,17 @@ export default class AdminConfigAreasAboutYourOrganization extends Component {
<p class="admin-config-area-card__additional-help">
{{i18n "admin.config_areas.about.city_for_disputes_help"}}
</p>
<input type="text" />
<input
{{on "input" (withEventValue (fn (mut this.cityForDisputes)))}}
type="text"
value={{this.cityForDisputes}}
/>
</div>
<DButton
@label="admin.config_areas.about.update"
@action={{this.save}}
class="btn-primary"
@disabled={{@globalSavingStatus}}
class="btn-primary admin-config-area-card__btn-save"
/>
</template>
}

View File

@ -1,4 +1,6 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
import i18n from "discourse-common/helpers/i18n";
import AdminConfigAreaCard from "admin/components/admin-config-area-card";
import AdminConfigAreasAboutContactInformation from "admin/components/admin-config-area-cards/about/contact-information";
@ -6,9 +8,44 @@ import AdminConfigAreasAboutGeneralSettings from "admin/components/admin-config-
import AdminConfigAreasAboutYourOrganization from "admin/components/admin-config-area-cards/about/your-organization";
export default class AdminConfigAreasAbout extends Component {
saveCallback() {
// eslint-disable-next-line no-console
console.log("save callback");
@tracked saving = false;
get generalSettings() {
return {
title: this.#lookupSettingFromData("title"),
siteDescription: this.#lookupSettingFromData("site_description"),
extendedSiteDescription: this.#lookupSettingFromData(
"extended_site_description"
),
aboutBannerImage: this.#lookupSettingFromData("about_banner_image"),
};
}
get contactInformation() {
return {
communityOwner: this.#lookupSettingFromData("community_owner"),
contactEmail: this.#lookupSettingFromData("contact_email"),
contactURL: this.#lookupSettingFromData("contact_url"),
contactUsername: this.#lookupSettingFromData("site_contact_username"),
contactGroupName: this.#lookupSettingFromData("site_contact_group_name"),
};
}
get yourOrganization() {
return {
companyName: this.#lookupSettingFromData("company_name"),
governingLaw: this.#lookupSettingFromData("governing_law"),
cityForDisputes: this.#lookupSettingFromData("city_for_disputes"),
};
}
@action
setSavingStatus(status) {
this.saving = status;
}
#lookupSettingFromData(name) {
return this.args.data.findBy("setting", name);
}
<template>
@ -18,25 +55,34 @@ export default class AdminConfigAreasAbout extends Component {
<AdminConfigAreaCard
@heading="admin.config_areas.about.general_settings"
@primaryActionLabel="admin.config_areas.about.update"
class="admin-config-area-about__general-settings-section"
>
<AdminConfigAreasAboutGeneralSettings
@saveCallback={{this.saveCallback}}
@generalSettings={{this.generalSettings}}
@setGlobalSavingStatus={{this.setSavingStatus}}
@globalSavingStatus={{this.saving}}
/>
</AdminConfigAreaCard>
<AdminConfigAreaCard
@heading="admin.config_areas.about.contact_information"
@primaryActionLabel="admin.config_areas.about.update"
class="admin-config-area-about__contact-information-section"
>
<AdminConfigAreasAboutContactInformation
@saveCallback={{this.saveCallback}}
@contactInformation={{this.contactInformation}}
@setGlobalSavingStatus={{this.setSavingStatus}}
@globalSavingStatus={{this.saving}}
/>
</AdminConfigAreaCard>
<AdminConfigAreaCard
@heading="admin.config_areas.about.your_organization"
@primaryActionLabel="admin.config_areas.about.update"
class="admin-config-area-about__your-organization-section"
>
<AdminConfigAreasAboutYourOrganization
@saveCallback={{this.saveCallback}}
@yourOrganization={{this.yourOrganization}}
@setGlobalSavingStatus={{this.setSavingStatus}}
@globalSavingStatus={{this.saving}}
/>
</AdminConfigAreaCard>
</div>

View File

@ -0,0 +1,25 @@
import Route from "@ember/routing/route";
import { ajax } from "discourse/lib/ajax";
export default class AdminConfigAboutRoute extends Route {
model() {
return ajax("/admin/site_settings.json", {
data: {
filter_names: [
"title",
"site_description",
"extended_site_description",
"about_banner_image",
"community_owner",
"contact_email",
"contact_url",
"site_contact_username",
"site_contact_group_name",
"company_name",
"governing_law",
"city_for_disputes",
],
},
});
}
}

View File

@ -1 +1 @@
<AdminConfigAreas::About />
<AdminConfigAreas::About @data={{this.model.site_settings}} />

View File

@ -5,5 +5,49 @@ class Admin::Config::AboutController < Admin::AdminController
end
def update
settings_map = {}
if general_settings = params[:general_settings]
settings_map[:title] = general_settings[:name]
settings_map[:site_description] = general_settings[:summary]
settings_map[:about_banner_image] = general_settings[:about_banner_image]
settings_map[:extended_site_description] = general_settings[:extended_description]
if settings_map[:extended_site_description].present?
settings_map[:extended_site_description_cooked] = PrettyText.markdown(
settings_map[:extended_site_description],
)
else
settings_map[:extended_site_description_cooked] = ""
end
end
if contact_information = params[:contact_information]
settings_map[:community_owner] = contact_information[:community_owner]
settings_map[:contact_email] = contact_information[:contact_email]
settings_map[:contact_url] = contact_information[:contact_url]
settings_map[:site_contact_username] = contact_information[:contact_username]
settings_map[:site_contact_group_name] = contact_information[:contact_group_name]
end
if your_organization = params[:your_organization]
settings_map[:company_name] = your_organization[:company_name]
settings_map[:governing_law] = your_organization[:governing_law]
settings_map[:city_for_disputes] = your_organization[:city_for_disputes]
end
settings_map.each do |name, value|
with_service(
UpdateSiteSetting,
setting_name: name,
new_value: value,
allow_changing_hidden: %i[
extended_site_description
extended_site_description_cooked
about_banner_image
community_owner
].include?(name),
)
end
render json: success_json
end
end

View File

@ -5,6 +5,12 @@ class Admin::SiteSettingsController < Admin::AdminController
render_json_error e.message, status: 422
end
ADMIN_CONFIG_AREA_ALLOWLISTED_HIDDEN_SETTINGS = %i[
extended_site_description
about_banner_image
community_owner
]
def index
params.permit(:categories, :plugin)
params.permit(:filter_names, [])
@ -16,6 +22,8 @@ class Admin::SiteSettingsController < Admin::AdminController
filter_plugin: params[:plugin],
filter_names: params[:filter_names],
include_locale_setting: params[:filter_names].blank?,
include_hidden: true,
filter_allowed_hidden: ADMIN_CONFIG_AREA_ALLOWLISTED_HIDDEN_SETTINGS,
),
)
end

View File

@ -5475,6 +5475,11 @@ en:
Specify the city that will be used as the jurisdiction for resolving any disputes related to the use of this forum. This information is typically included in legal documents such as the forum's Terms of Service.
optional: "(optional)"
update: "Update"
toasts:
general_settings_saved: "General settings saved"
contact_information_saved: "Contact information saved"
your_organization_saved: "Your organization saved"
saved: "saved!"
plugins:
title: "Plugins"
installed: "Installed Plugins"

View File

@ -411,6 +411,22 @@ basic:
show_user_menu_avatars:
client: true
default: false
extended_site_description:
default: ""
max: 10_000
hidden: true
extended_site_description_cooked:
default: ""
hidden: true
max: 15_000
about_banner_image:
default: ""
type: upload
hidden: true
community_owner:
default: ""
max: 300
hidden: true
login:
invite_only:
refresh: true

View File

@ -190,7 +190,8 @@ module SiteSettingExtension
only_overridden: false,
filter_categories: nil,
filter_plugin: nil,
filter_names: nil
filter_names: nil,
filter_allowed_hidden: nil
)
locale_setting_hash = {
setting: "default_locale",
@ -211,7 +212,15 @@ module SiteSettingExtension
.reject do |setting_name, _|
plugins[name] && !Discourse.plugins_by_name[plugins[name]].configurable?
end
.reject { |setting_name, _| !include_hidden && hidden_settings.include?(setting_name) }
.select do |setting_name, _|
is_hidden = hidden_settings.include?(setting_name)
next true if !is_hidden
next false if !include_hidden
next true if filter_allowed_hidden.nil?
filter_allowed_hidden.include?(setting_name)
end
.select do |setting_name, _|
if filter_categories && filter_categories.any?
filter_categories.include?(categories[setting_name])

View File

@ -826,6 +826,45 @@ RSpec.describe SiteSettingExtension do
expect(setting[:default]).to eq(system_upload.url)
end
end
context "with the filter_allowed_hidden argument" do
it "includes the specified hidden settings only if include_hidden is true" do
result =
SiteSetting
.all_settings(include_hidden: true, filter_allowed_hidden: [:about_banner_image])
.map { |ss| ss[:setting] }
expect(result).to include(:about_banner_image)
expect(result).not_to include(:community_owner)
result =
SiteSetting
.all_settings(include_hidden: false, filter_allowed_hidden: [:about_banner_image])
.map { |ss| ss[:setting] }
expect(result).not_to include(:about_banner_image)
expect(result).not_to include(:community_owner)
result =
SiteSetting
.all_settings(include_hidden: true, filter_allowed_hidden: [:community_owner])
.map { |ss| ss[:setting] }
expect(result).not_to include(:about_banner_image)
expect(result).to include(:community_owner)
result =
SiteSetting
.all_settings(
include_hidden: true,
filter_allowed_hidden: %i[about_banner_image community_owner],
)
.map { |ss| ss[:setting] }
expect(result).to include(:about_banner_image)
expect(result).to include(:community_owner)
end
end
end
describe ".client_settings_json_uncached" do

View File

@ -0,0 +1,150 @@
# frozen_string_literal: true
describe "Admin About Config Area Page", type: :system do
fab!(:admin)
fab!(:image_upload)
let(:config_area) { PageObjects::Pages::AdminAboutConfigArea.new }
before { sign_in(admin) }
context "when all fields have existing values" do
before do
SiteSetting.title = "my forums title"
SiteSetting.site_description = "this is a description for my forums"
SiteSetting.about_banner_image = image_upload
SiteSetting.extended_site_description = "this is an extended description for my forums"
SiteSetting.community_owner = "kitty"
SiteSetting.contact_email = "kitty@litterbox.com"
SiteSetting.contact_url = "https://hello.com"
SiteSetting.site_contact_username = admin.username
SiteSetting.site_contact_group_name = admin.groups.first.name
SiteSetting.company_name = "kitty company inc."
SiteSetting.governing_law = "kitty jurisdiction"
SiteSetting.city_for_disputes = "no disputes allowed"
end
it "populates all input fields correctly" do
config_area.visit
expect(config_area.general_settings_section.community_name_input.value).to eq(
"my forums title",
)
expect(config_area.general_settings_section.community_summary_input.value).to eq(
"this is a description for my forums",
)
expect(config_area.general_settings_section.community_description_editor.value).to eq(
"this is an extended description for my forums",
)
expect(config_area.general_settings_section.banner_image_uploader).to have_uploaded_picture
expect(config_area.contact_information_section.community_owner_input.value).to eq("kitty")
expect(config_area.contact_information_section.contact_email_input.value).to eq(
"kitty@litterbox.com",
)
expect(config_area.contact_information_section.contact_url_input.value).to eq(
"https://hello.com",
)
expect(
config_area.contact_information_section.site_contact_user_selector,
).to have_selected_value(admin.username)
expect(
config_area.contact_information_section.site_contact_group_selector,
).to have_selected_value(admin.groups.first.id)
expect(config_area.your_organization_section.company_name_input.value).to eq(
"kitty company inc.",
)
expect(config_area.your_organization_section.governing_law_input.value).to eq(
"kitty jurisdiction",
)
expect(config_area.your_organization_section.city_for_disputes_input.value).to eq(
"no disputes allowed",
)
end
end
describe "the general settings card" do
it "can saves its fields to their corresponding site settings" do
config_area.visit
image_file = file_from_fixtures("logo.png", "images")
config_area.general_settings_section.community_name_input.fill_in(with: "my community name")
config_area.general_settings_section.community_summary_input.fill_in(
with: "here's a bit of a summary",
)
config_area.general_settings_section.community_description_editor.fill_in(
with: "here's an extended description for the **community**",
)
config_area.general_settings_section.banner_image_uploader.select_image(image_file.path)
config_area.general_settings_section.save_button.click
expect(config_area.general_settings_section).to have_saved_successfully
expect(SiteSetting.title).to eq("my community name")
expect(SiteSetting.site_description).to eq("here's a bit of a summary")
expect(SiteSetting.extended_site_description).to eq(
"here's an extended description for the **community**",
)
expect(SiteSetting.extended_site_description_cooked).to eq(
"<p>heres an extended description for the <strong>community</strong></p>",
)
expect(SiteSetting.about_banner_image.sha1).to eq(Upload.generate_digest(image_file))
end
end
describe "the contact information card" do
it "can saves its fields to their corresponding site settings" do
config_area.visit
config_area.contact_information_section.community_owner_input.fill_in(with: "awesome owner")
config_area.contact_information_section.contact_email_input.fill_in(
with: "owneremail@owner.com",
)
config_area.contact_information_section.contact_url_input.fill_in(
with: "https://website.owner.com/blah",
)
user_select_kit = config_area.contact_information_section.site_contact_user_selector
user_select_kit.expand
user_select_kit.search(admin.username)
user_select_kit.select_row_by_value(admin.username)
user_select_kit.collapse
group_select_kit = config_area.contact_information_section.site_contact_group_selector
group = admin.groups.first
group_select_kit.expand
group_select_kit.search(group.name)
group_select_kit.select_row_by_value(group.id)
group_select_kit.collapse
config_area.contact_information_section.save_button.click
expect(config_area.contact_information_section).to have_saved_successfully
expect(SiteSetting.community_owner).to eq("awesome owner")
expect(SiteSetting.contact_email).to eq("owneremail@owner.com")
expect(SiteSetting.contact_url).to eq("https://website.owner.com/blah")
expect(SiteSetting.site_contact_username).to eq(admin.username)
expect(SiteSetting.site_contact_group_name).to eq(group.name)
end
end
describe "the your organization card" do
it "can saves its fields to their corresponding site settings" do
config_area.visit
config_area.your_organization_section.company_name_input.fill_in(with: "lil' company")
config_area.your_organization_section.governing_law_input.fill_in(with: "wild west law")
config_area.your_organization_section.city_for_disputes_input.fill_in(with: "teeb el shouq")
config_area.your_organization_section.save_button.click
expect(config_area.your_organization_section).to have_saved_successfully
expect(SiteSetting.company_name).to eq("lil' company")
expect(SiteSetting.governing_law).to eq("wild west law")
expect(SiteSetting.city_for_disputes).to eq("teeb el shouq")
end
end
end

View File

@ -0,0 +1,45 @@
# frozen_string_literal: true
module PageObjects
module Components
class AdminAboutConfigAreaContactInformationCard < PageObjects::Components::Base
def community_owner_input
card.find(".community-owner-input input")
end
def contact_email_input
card.find(".contact-email-input input")
end
def contact_url_input
card.find(".contact-url-input input")
end
def site_contact_user_selector
PageObjects::Components::SelectKit.new(
".admin-config-area-about__contact-information-section .site-contact-username-input .user-chooser",
)
end
def site_contact_group_selector
PageObjects::Components::SelectKit.new(
".admin-config-area-about__contact-information-section .site-contact-group-input .group-chooser",
)
end
def save_button
card.find(".btn-primary.admin-config-area-card__btn-save")
end
def has_saved_successfully?
PageObjects::Components::Toasts.new.has_success?(
I18n.t("admin_js.admin.config_areas.about.toasts.contact_information_saved"),
)
end
def card
find(".admin-config-area-about__contact-information-section")
end
end
end
end

View File

@ -0,0 +1,37 @@
# frozen_string_literal: true
module PageObjects
module Components
class AdminAboutConfigAreaGeneralSettingsCard < PageObjects::Components::Base
def community_name_input
card.find(".community-name-input input")
end
def community_summary_input
card.find(".community-summary-input input")
end
def community_description_editor
card.find(".community-description-input .d-editor-input")
end
def banner_image_uploader
PageObjects::Components::UppyImageUploader.new(card.find(".image-uploader"))
end
def save_button
card.find(".btn-primary.admin-config-area-card__btn-save")
end
def has_saved_successfully?
PageObjects::Components::Toasts.new.has_success?(
I18n.t("admin_js.admin.config_areas.about.toasts.general_settings_saved"),
)
end
def card
find(".admin-config-area-about__general-settings-section")
end
end
end
end

View File

@ -0,0 +1,33 @@
# frozen_string_literal: true
module PageObjects
module Components
class AdminAboutConfigAreaYourOrganizationCard < PageObjects::Components::Base
def company_name_input
card.find(".company-name-input input")
end
def governing_law_input
card.find(".governing-law-input input")
end
def city_for_disputes_input
card.find(".city-for-disputes-input input")
end
def save_button
card.find(".btn-primary.admin-config-area-card__btn-save")
end
def has_saved_successfully?
PageObjects::Components::Toasts.new.has_success?(
I18n.t("admin_js.admin.config_areas.about.toasts.your_organization_saved"),
)
end
def card
find(".admin-config-area-about__your-organization-section")
end
end
end
end

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
module PageObjects
module Components
class UppyImageUploader < PageObjects::Components::Base
def initialize(element)
@element = element
end
def select_image(path)
attach_file(path) { @element.find("label.btn-default").click }
end
def has_uploaded_picture?
@element.has_css?(".uploaded-image-preview")
end
end
end
end

View File

@ -0,0 +1,23 @@
# frozen_string_literal: true
module PageObjects
module Pages
class AdminAboutConfigArea < PageObjects::Pages::Base
def visit
page.visit("/admin/config/about")
end
def general_settings_section
PageObjects::Components::AdminAboutConfigAreaGeneralSettingsCard.new
end
def contact_information_section
PageObjects::Components::AdminAboutConfigAreaContactInformationCard.new
end
def your_organization_section
PageObjects::Components::AdminAboutConfigAreaYourOrganizationCard.new
end
end
end
end