diff --git a/app/assets/javascripts/admin/addon/components/admin-config-area-empty-list.gjs b/app/assets/javascripts/admin/addon/components/admin-config-area-empty-list.gjs
index bb4b8a2c1e9..f6bd0d6c761 100644
--- a/app/assets/javascripts/admin/addon/components/admin-config-area-empty-list.gjs
+++ b/app/assets/javascripts/admin/addon/components/admin-config-area-empty-list.gjs
@@ -26,6 +26,7 @@ export default class AdminConfigAreaEmptyList extends Component {
}}
@action={{@ctaAction}}
@route={{@ctaRoute}}
+ @routeModels={{@ctaRouteModels}}
/>
{{/if}}
{{yield}}
diff --git a/app/assets/javascripts/admin/addon/components/admin-config-areas/themes.gjs b/app/assets/javascripts/admin/addon/components/admin-config-areas/themes.gjs
index ffef0bf9593..a49b730d82a 100644
--- a/app/assets/javascripts/admin/addon/components/admin-config-areas/themes.gjs
+++ b/app/assets/javascripts/admin/addon/components/admin-config-areas/themes.gjs
@@ -5,6 +5,7 @@ import { service } from "@ember/service";
import { isPresent } from "@ember/utils";
import DPageSubheader from "discourse/components/d-page-subheader";
import PluginOutlet from "discourse/components/plugin-outlet";
+import getURL from "discourse/helpers/get-url";
import lazyHash from "discourse/helpers/lazy-hash";
import { i18n } from "discourse-i18n";
import InstallThemeModal from "admin/components/modal/install-theme";
@@ -90,6 +91,7 @@ export default class AdminConfigAreasThemes extends Component {
}}
@descriptionLabel={{i18n
"admin.config_areas.themes_and_components.themes.description"
+ themeSiteSettingsUrl=(getURL "/admin/config/theme-site-settings")
}}
>
<:actions as |actions|>
diff --git a/app/assets/javascripts/admin/addon/components/theme-setting-editor.js b/app/assets/javascripts/admin/addon/components/theme-setting-editor.js
index a6aabc6c5a9..d4052840ff6 100644
--- a/app/assets/javascripts/admin/addon/components/theme-setting-editor.js
+++ b/app/assets/javascripts/admin/addon/components/theme-setting-editor.js
@@ -1,10 +1,20 @@
+import { service } from "@ember/service";
+import { i18n } from "discourse-i18n";
import SiteSettingComponent from "./site-setting";
-export default class extends SiteSettingComponent {
+export default class ThemeSettingEditor extends SiteSettingComponent {
+ @service toasts;
+
_save() {
- return this.setting.updateSetting(
- this.args.model.id,
- this.buffered.get("value")
- );
+ return this.setting
+ .updateSetting(this.args.model.id, this.buffered.get("value"))
+ .then(() => {
+ this.toasts.success({
+ data: {
+ message: i18n("admin.customize.theme.theme_setting_saved"),
+ },
+ duration: "short",
+ });
+ });
}
}
diff --git a/app/assets/javascripts/admin/addon/components/theme-site-setting-editor.gjs b/app/assets/javascripts/admin/addon/components/theme-site-setting-editor.gjs
new file mode 100644
index 00000000000..c2170c1b66b
--- /dev/null
+++ b/app/assets/javascripts/admin/addon/components/theme-site-setting-editor.gjs
@@ -0,0 +1,20 @@
+import { service } from "@ember/service";
+import { i18n } from "discourse-i18n";
+import SiteSettingComponent from "./site-setting";
+
+export default class ThemeSiteSettingEditor extends SiteSettingComponent {
+ @service toasts;
+
+ _save() {
+ return this.setting
+ .updateSetting(this.args.model.id, this.buffered.get("value"))
+ .then(() => {
+ this.toasts.success({
+ data: {
+ message: i18n("admin.customize.theme.theme_site_setting_saved"),
+ },
+ duration: "short",
+ });
+ });
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/components/theme-site-settings.gjs b/app/assets/javascripts/admin/addon/components/theme-site-settings.gjs
new file mode 100644
index 00000000000..60806fa04d2
--- /dev/null
+++ b/app/assets/javascripts/admin/addon/components/theme-site-settings.gjs
@@ -0,0 +1,133 @@
+import Component from "@glimmer/component";
+import { tracked } from "@glimmer/tracking";
+import { array } from "@ember/helper";
+import { action } from "@ember/object";
+import { LinkTo } from "@ember/routing";
+import { service } from "@ember/service";
+import { eq } from "truth-helpers";
+import AsyncContent from "discourse/components/async-content";
+import DPageSubheader from "discourse/components/d-page-subheader";
+import basePath from "discourse/helpers/base-path";
+import { ajax } from "discourse/lib/ajax";
+import { currentThemeId, listThemes } from "discourse/lib/theme-selector";
+import { i18n } from "discourse-i18n";
+import DTooltip from "float-kit/components/d-tooltip";
+
+export default class ThemeSiteSettings extends Component {
+ @service site;
+ @service router;
+
+ @tracked themesWithSiteSettingOverrides = null;
+ @tracked themeableSiteSettings = null;
+
+ get themes() {
+ return listThemes(this.site);
+ }
+
+ get currentThemeIdValue() {
+ return currentThemeId();
+ }
+
+ get currentTheme() {
+ return this.themes.find((theme) => {
+ return eq(theme.id, this.currentThemeIdValue);
+ });
+ }
+
+ isLastThemeSettingOverride(overrides, theme) {
+ return theme === overrides.themes.at(-1);
+ }
+
+ @action
+ async loadThemeSiteSettings() {
+ let url = "/admin/config/theme-site-settings.json";
+ const response = await ajax(url, {
+ method: "GET",
+ });
+ this.themeableSiteSettings = response.themeable_site_settings.map(
+ (setting) => {
+ return {
+ name: setting.humanized_name,
+ value: setting,
+ };
+ }
+ );
+ this.themesWithSiteSettingOverrides =
+ response.themes_with_site_setting_overrides;
+ return this.themesWithSiteSettingOverrides;
+ }
+
+
+ {{overrides.humanized_name}}
+
+
+
+ <:empty>
+
+
+
+
+
+ {{#each-in content as |settingName overrides|}}
+ {{i18n "admin.theme_site_settings.setting"}}
+ {{i18n "admin.theme_site_settings.default_value"}}
+ {{i18n "admin.theme_site_settings.overridden_by"}}
+
+
+ {{/each-in}}
+
+
+
+
+ {{overrides.default}}
+
+
+ {{#each overrides.themes as |theme|}}
+
+
{{htmlSafe + (i18n + "admin.customize.theme.overriden_site_settings_explanation" + themeSiteSettingsConfigUrl=(getURL + "/admin/config/theme-site-settings" + ) + ) + }}
+