From ea8b5c18db4f47e7beebb3d80cbddaf6134b10af Mon Sep 17 00:00:00 2001 From: Roman Rizzi Date: Mon, 18 Jan 2021 14:53:45 -0300 Subject: [PATCH] UX: Text customization for different languages. (#11729) Admins can now edit translations in different languages without having to change their locale. We display a warning when there's a fallback language set. --- .../addon/controllers/admin-site-text-edit.js | 10 +- .../controllers/admin-site-text-index.js | 42 ++++++- .../admin/addon/models/site-text.js | 6 +- .../addon/routes/admin-site-text-edit.js | 24 +++- .../addon/routes/admin-site-text-index.js | 3 +- .../admin/addon/templates/site-text-edit.hbs | 7 +- .../admin/addon/templates/site-text-index.hbs | 22 ++++ .../tests/acceptance/admin-site-text-test.js | 6 +- .../tests/helpers/create-pretender.js | 10 +- .../stylesheets/common/admin/admin_base.scss | 6 + .../admin/site_texts_controller.rb | 103 +++++++++++------ config/locales/client.en.yml | 2 + lib/freedom_patches/translate_accelerator.rb | 2 +- .../admin/site_texts_controller_spec.rb | 108 +++++++++++------- 14 files changed, 255 insertions(+), 96 deletions(-) diff --git a/app/assets/javascripts/admin/addon/controllers/admin-site-text-edit.js b/app/assets/javascripts/admin/addon/controllers/admin-site-text-edit.js index 99e1c19af34..cc7bac32675 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-site-text-edit.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-site-text-edit.js @@ -7,6 +7,7 @@ import { popupAjaxError } from "discourse/lib/ajax-error"; export default Controller.extend(bufferedProperty("siteText"), { saved: false, + queryParams: ["locale"], @discourseComputed("buffered.value") saveDisabled(value) { @@ -15,9 +16,11 @@ export default Controller.extend(bufferedProperty("siteText"), { actions: { saveChanges() { - const buffered = this.buffered; + const attrs = this.buffered.getProperties("value"); + attrs.locale = this.locale; + this.siteText - .save(buffered.getProperties("value")) + .save(attrs) .then(() => { this.commitBuffer(); this.set("saved", true); @@ -27,10 +30,11 @@ export default Controller.extend(bufferedProperty("siteText"), { revertChanges() { this.set("saved", false); + bootbox.confirm(I18n.t("admin.site_text.revert_confirm"), (result) => { if (result) { this.siteText - .revert() + .revert(this.locale) .then((props) => { const buffered = this.buffered; buffered.setProperties(props); diff --git a/app/assets/javascripts/admin/addon/controllers/admin-site-text-index.js b/app/assets/javascripts/admin/addon/controllers/admin-site-text-index.js index 289c49da87f..3c0dc9c3b0a 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-site-text-index.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-site-text-index.js @@ -1,4 +1,5 @@ import Controller from "@ember/controller"; +import discourseComputed from "discourse-common/utils/decorators"; import discourseDebounce from "discourse-common/lib/debounce"; let lastSearch; @@ -6,23 +7,49 @@ export default Controller.extend({ searching: false, siteTexts: null, preferred: false, - queryParams: ["q", "overridden"], + queryParams: ["q", "overridden", "locale"], + locale: null, q: null, overridden: false, + init() { + this._super(...arguments); + + this.set("locale", this.siteSettings.default_locale); + }, + _performSearch() { this.store - .find("site-text", this.getProperties("q", "overridden")) + .find("site-text", this.getProperties("q", "overridden", "locale")) .then((results) => { this.set("siteTexts", results); }) .finally(() => this.set("searching", false)); }, + @discourseComputed() + availableLocales() { + return JSON.parse(this.siteSettings.available_locales); + }, + + @discourseComputed("locale") + fallbackLocaleFullName() { + if (this.siteTexts.extras.fallback_locale) { + return this.availableLocales.find((l) => { + return l.value === this.siteTexts.extras.fallback_locale; + }).name; + } + }, + actions: { edit(siteText) { - this.transitionToRoute("adminSiteText.edit", siteText.get("id")); + this.transitionToRoute("adminSiteText.edit", siteText.get("id"), { + queryParams: { + locale: this.locale, + localeFullName: this.availableLocales[this.locale], + }, + }); }, toggleOverridden() { @@ -39,5 +66,14 @@ export default Controller.extend({ lastSearch = q; } }, + + updateLocale(value) { + this.setProperties({ + searching: true, + locale: value, + }); + + discourseDebounce(this, this._performSearch, 400); + }, }, }); diff --git a/app/assets/javascripts/admin/addon/models/site-text.js b/app/assets/javascripts/admin/addon/models/site-text.js index d6c4c4d1300..c25a5b30a00 100644 --- a/app/assets/javascripts/admin/addon/models/site-text.js +++ b/app/assets/javascripts/admin/addon/models/site-text.js @@ -1,10 +1,10 @@ import RestModel from "discourse/models/rest"; import { ajax } from "discourse/lib/ajax"; -const { getProperties } = Ember; +import { getProperties } from "@ember/object"; export default RestModel.extend({ - revert() { - return ajax(`/admin/customize/site_texts/${this.id}`, { + revert(locale) { + return ajax(`/admin/customize/site_texts/${this.id}?locale=${locale}`, { type: "DELETE", }).then((result) => getProperties(result.site_text, "value", "can_revert")); }, diff --git a/app/assets/javascripts/admin/addon/routes/admin-site-text-edit.js b/app/assets/javascripts/admin/addon/routes/admin-site-text-edit.js index fe720907c7c..40c74fced34 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-site-text-edit.js +++ b/app/assets/javascripts/admin/addon/routes/admin-site-text-edit.js @@ -1,10 +1,30 @@ import Route from "@ember/routing/route"; +import { ajax } from "discourse/lib/ajax"; + export default Route.extend({ + queryParams: { + locale: { replace: true }, + }, + model(params) { - return this.store.find("site-text", params.id); + return ajax( + `/admin/customize/site_texts/${params.id}?locale=${params.locale}` + ).then((result) => { + return this.store.createRecord("site-text", result.site_text); + }); }, setupController(controller, siteText) { - controller.setProperties({ siteText, saved: false }); + const locales = JSON.parse(this.siteSettings.available_locales); + + const localeFullName = locales.find((locale) => { + return locale.value === controller.locale; + }).name; + + controller.setProperties({ + siteText, + saved: false, + localeFullName: localeFullName, + }); }, }); diff --git a/app/assets/javascripts/admin/addon/routes/admin-site-text-index.js b/app/assets/javascripts/admin/addon/routes/admin-site-text-index.js index 85dfe8e8c1b..255315a8469 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-site-text-index.js +++ b/app/assets/javascripts/admin/addon/routes/admin-site-text-index.js @@ -6,12 +6,13 @@ export default Route.extend({ queryParams: { q: { replace: true }, overridden: { replace: true }, + locale: { replace: true }, }, model(params) { return this.store.find( "site-text", - getProperties(params, "q", "overridden") + getProperties(params, "q", "overridden", "locale") ); }, diff --git a/app/assets/javascripts/admin/addon/templates/site-text-edit.hbs b/app/assets/javascripts/admin/addon/templates/site-text-edit.hbs index 279a5a5acb8..2bf960c24bc 100644 --- a/app/assets/javascripts/admin/addon/templates/site-text-edit.hbs +++ b/app/assets/javascripts/admin/addon/templates/site-text-edit.hbs @@ -1,9 +1,12 @@
-

{{siteText.id}}

+
+

{{i18n "admin.site_text.locale"}} {{localeFullName}}

+
+ {{expanding-text-area value=buffered.value rows="1" class="site-text-value"}} {{#save-controls model=siteText action=(action "saveChanges") saved=saved saveDisabled=saveDisabled}} @@ -12,7 +15,7 @@ {{/if}} {{/save-controls}} - {{#link-to "adminSiteText.index" class="go-back"}} + {{#link-to "adminSiteText.index" (query-params locale=locale) class="go-back"}} {{d-icon "arrow-left"}} {{i18n "admin.site_text.go_back"}} {{/link-to}} diff --git a/app/assets/javascripts/admin/addon/templates/site-text-index.hbs b/app/assets/javascripts/admin/addon/templates/site-text-index.hbs index fa72cc36f45..16e835d2709 100644 --- a/app/assets/javascripts/admin/addon/templates/site-text-index.hbs +++ b/app/assets/javascripts/admin/addon/templates/site-text-index.hbs @@ -16,6 +16,21 @@

+

+ + {{combo-box + valueProperty="value" + content=availableLocales + value=locale + onChange=(action "updateLocale") + class="locale-search" + options=(hash + filterable=true + none="user.locale.default" + ) + }} +
+