mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
FEATURE: add language picker for theme translations in admin UI (#26150)
Allows editing translations of a theme in locales other than the current localy.
This commit is contained in:
@@ -17,7 +17,7 @@ export default class ThemeTranslation extends SiteSettingComponent {
|
||||
|
||||
return ajax(this.updateUrl, {
|
||||
type: "PUT",
|
||||
data: { theme: { translations } },
|
||||
data: { theme: { translations, locale: this.get("model.locale") } },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
readOnly,
|
||||
} from "@ember/object/computed";
|
||||
import { service } from "@ember/service";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import { url } from "discourse/lib/computed";
|
||||
import { makeArray } from "discourse-common/lib/helpers";
|
||||
@@ -24,12 +25,15 @@ const THEME_UPLOAD_VAR = 2;
|
||||
export default class AdminCustomizeThemesShowController extends Controller {
|
||||
@service dialog;
|
||||
@service router;
|
||||
@service siteSettings;
|
||||
@service modal;
|
||||
|
||||
editRouteName = "adminCustomizeThemes.edit";
|
||||
|
||||
@url("model.id", "/admin/customize/themes/%@/export") downloadUrl;
|
||||
@url("model.id", "/admin/themes/%@/preview") previewUrl;
|
||||
@url("model.id", "model.locale", "/admin/themes/%@/translations/%@")
|
||||
getTranslationsUrl;
|
||||
@empty("selectedChildThemeId") addButtonDisabled;
|
||||
@mapBy("model.parentThemes", "name") parentThemesNames;
|
||||
@filterBy("allThemes", "component", false) availableParentThemes;
|
||||
@@ -293,6 +297,22 @@ export default class AdminCustomizeThemesShowController extends Controller {
|
||||
model.saveChanges("theme_fields").catch((e) => popupAjaxError(e));
|
||||
}
|
||||
|
||||
get availableLocales() {
|
||||
return JSON.parse(this.siteSettings.available_locales);
|
||||
}
|
||||
|
||||
get locale() {
|
||||
return this.get("model.locale") || this.siteSettings.default_locale;
|
||||
}
|
||||
|
||||
@action
|
||||
updateLocale(value) {
|
||||
this.set("model.locale", value);
|
||||
ajax(this.getTranslationsUrl).then(({ translations }) =>
|
||||
this.set("model.translations", translations)
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
cancelChangeScheme() {
|
||||
this.set("colorSchemeId", this.get("model.color_scheme_id"));
|
||||
|
||||
@@ -460,12 +460,23 @@
|
||||
|
||||
{{#if this.hasTranslations}}
|
||||
<div class="control-unit">
|
||||
<div class="mini-title">{{i18n
|
||||
"admin.customize.theme.theme_translations"
|
||||
}}</div>
|
||||
<div class="translation-selector-container">
|
||||
<span class="mini-title">
|
||||
{{i18n "admin.customize.theme.theme_translations"}}
|
||||
</span>
|
||||
<ComboBox
|
||||
@valueProperty="value"
|
||||
@content={{this.availableLocales}}
|
||||
@value={{this.locale}}
|
||||
@onChange={{this.updateLocale}}
|
||||
@options={{hash filterable=true}}
|
||||
class="translation-selector"
|
||||
/>
|
||||
</div>
|
||||
<section
|
||||
class="form-horizontal theme settings translations control-unit"
|
||||
>
|
||||
|
||||
{{#each this.translations as |translation|}}
|
||||
<ThemeTranslation
|
||||
@translation={{translation}}
|
||||
|
||||
@@ -168,6 +168,25 @@
|
||||
.control-unit {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 2em;
|
||||
|
||||
.translation-selector-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 79.7%;
|
||||
|
||||
@media screen and (max-width: 700px) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 700px) and (max-width: 768px) {
|
||||
width: 73%;
|
||||
}
|
||||
|
||||
.translation-selector {
|
||||
width: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
.control {
|
||||
margin-bottom: 10px;
|
||||
|
||||
@@ -311,6 +311,25 @@ class Admin::ThemesController < Admin::AdminController
|
||||
exporter.cleanup!
|
||||
end
|
||||
|
||||
def get_translations
|
||||
params.require(:locale)
|
||||
unless I18n.available_locales.include?(params[:locale].to_sym)
|
||||
raise Discourse::InvalidParameters.new(:locale)
|
||||
end
|
||||
|
||||
I18n.locale = params[:locale]
|
||||
|
||||
@theme = Theme.find_by(id: params[:id])
|
||||
raise Discourse::InvalidParameters.new(:id) unless @theme
|
||||
|
||||
translations =
|
||||
@theme.translations.map do |translation|
|
||||
{ key: translation.key, value: translation.value, default: translation.default }
|
||||
end
|
||||
|
||||
render json: { translations: translations }, status: :ok
|
||||
end
|
||||
|
||||
def update_single_setting
|
||||
params.require("name")
|
||||
@theme = Theme.find_by(id: params[:id])
|
||||
@@ -369,6 +388,7 @@ class Admin::ThemesController < Admin::AdminController
|
||||
:component,
|
||||
:enabled,
|
||||
:auto_update,
|
||||
:locale,
|
||||
settings: {
|
||||
},
|
||||
translations: {
|
||||
@@ -408,6 +428,14 @@ class Admin::ThemesController < Admin::AdminController
|
||||
def update_translations
|
||||
return unless target_translations = theme_params[:translations]
|
||||
|
||||
locale = theme_params[:locale].presence
|
||||
if locale
|
||||
unless I18n.available_locales.include?(locale.to_sym)
|
||||
raise Discourse::InvalidParameters.new(:locale)
|
||||
end
|
||||
I18n.locale = locale
|
||||
end
|
||||
|
||||
target_translations.each_pair do |translation_key, new_value|
|
||||
@theme.update_translation(translation_key, new_value)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user