mirror of
https://github.com/discourse/discourse.git
synced 2025-06-16 18:28:15 +08:00
DEV: Modernize admin-site-text route/controller (#23581)
- Switch to `@tracked` and native getters - Remove queryParam defaults which are awkward to work with. Instead, add `resolvedBlah` getters - Add 'no results found' text - Use standard 'model' key instead of a custom `setupController` method - Remove use of `route-action` - Remove `{{action` helper Default queryParams in ember controllers are tricky to work with, especially when combined with the new router service. Instead, we can handle defaults ourselves
This commit is contained in:
@ -1,51 +1,65 @@
|
|||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import Controller from "@ember/controller";
|
import Controller from "@ember/controller";
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
|
||||||
import discourseDebounce from "discourse-common/lib/debounce";
|
import discourseDebounce from "discourse-common/lib/debounce";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
import { disableImplicitInjections } from "discourse/lib/implicit-injections";
|
||||||
|
import ReseedModal from "admin/components/modal/reseed";
|
||||||
|
|
||||||
let lastSearch;
|
let lastSearch;
|
||||||
|
|
||||||
|
@disableImplicitInjections
|
||||||
export default class AdminSiteTextIndexController extends Controller {
|
export default class AdminSiteTextIndexController extends Controller {
|
||||||
@service router;
|
@service router;
|
||||||
@service siteSettings;
|
@service siteSettings;
|
||||||
|
@service modal;
|
||||||
|
@service store;
|
||||||
|
|
||||||
|
@tracked locale;
|
||||||
|
@tracked q;
|
||||||
|
@tracked overridden;
|
||||||
|
@tracked outdated;
|
||||||
|
|
||||||
|
@tracked model;
|
||||||
|
|
||||||
|
@tracked searching = false;
|
||||||
|
@tracked preferred = false;
|
||||||
|
|
||||||
searching = false;
|
|
||||||
siteTexts = null;
|
|
||||||
preferred = false;
|
|
||||||
queryParams = ["q", "overridden", "outdated", "locale"];
|
queryParams = ["q", "overridden", "outdated", "locale"];
|
||||||
locale = null;
|
|
||||||
q = null;
|
|
||||||
overridden = false;
|
|
||||||
outdated = false;
|
|
||||||
|
|
||||||
init() {
|
get resolvedOverridden() {
|
||||||
super.init(...arguments);
|
return [true, "true"].includes(this.overridden) ?? false;
|
||||||
|
|
||||||
this.set("locale", this.siteSettings.default_locale);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_performSearch() {
|
get resolvedOutdated() {
|
||||||
this.store
|
return [true, "true"].includes(this.outdated) ?? false;
|
||||||
.find(
|
|
||||||
"site-text",
|
|
||||||
this.getProperties("q", "overridden", "outdated", "locale")
|
|
||||||
)
|
|
||||||
.then((results) => {
|
|
||||||
this.set("siteTexts", results);
|
|
||||||
})
|
|
||||||
.finally(() => this.set("searching", false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@discourseComputed()
|
get resolvedLocale() {
|
||||||
availableLocales() {
|
return this.locale ?? this.siteSettings.default_locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
async _performSearch() {
|
||||||
|
try {
|
||||||
|
this.model = await this.store.find("site-text", {
|
||||||
|
q: this.q,
|
||||||
|
overridden: this.resolvedOverridden,
|
||||||
|
outdated: this.resolvedOutdated,
|
||||||
|
locale: this.resolvedLocale,
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
this.searching = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get availableLocales() {
|
||||||
return JSON.parse(this.siteSettings.available_locales);
|
return JSON.parse(this.siteSettings.available_locales);
|
||||||
}
|
}
|
||||||
|
|
||||||
@discourseComputed("locale")
|
get fallbackLocaleFullName() {
|
||||||
fallbackLocaleFullName() {
|
if (this.model.extras.fallback_locale) {
|
||||||
if (this.siteTexts.extras.fallback_locale) {
|
|
||||||
return this.availableLocales.find((l) => {
|
return this.availableLocales.find((l) => {
|
||||||
return l.value === this.siteTexts.extras.fallback_locale;
|
return l.value === this.model.extras.fallback_locale;
|
||||||
}).name;
|
}).name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,22 +68,30 @@ export default class AdminSiteTextIndexController extends Controller {
|
|||||||
edit(siteText) {
|
edit(siteText) {
|
||||||
this.router.transitionTo("adminSiteText.edit", siteText.get("id"), {
|
this.router.transitionTo("adminSiteText.edit", siteText.get("id"), {
|
||||||
queryParams: {
|
queryParams: {
|
||||||
locale: this.locale,
|
locale: this.resolvedLocale,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
toggleOverridden() {
|
toggleOverridden() {
|
||||||
this.toggleProperty("overridden");
|
if (this.resolvedOverridden) {
|
||||||
this.set("searching", true);
|
this.overridden = null;
|
||||||
|
} else {
|
||||||
|
this.overridden = true;
|
||||||
|
}
|
||||||
|
this.searching = true;
|
||||||
discourseDebounce(this, this._performSearch, 400);
|
discourseDebounce(this, this._performSearch, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
toggleOutdated() {
|
toggleOutdated() {
|
||||||
this.toggleProperty("outdated");
|
if (this.resolvedOutdated) {
|
||||||
this.set("searching", true);
|
this.outdated = null;
|
||||||
|
} else {
|
||||||
|
this.outdated = true;
|
||||||
|
}
|
||||||
|
this.searching = true;
|
||||||
discourseDebounce(this, this._performSearch, 400);
|
discourseDebounce(this, this._performSearch, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +99,7 @@ export default class AdminSiteTextIndexController extends Controller {
|
|||||||
search() {
|
search() {
|
||||||
const q = this.q;
|
const q = this.q;
|
||||||
if (q !== lastSearch) {
|
if (q !== lastSearch) {
|
||||||
this.set("searching", true);
|
this.searching = true;
|
||||||
discourseDebounce(this, this._performSearch, 400);
|
discourseDebounce(this, this._performSearch, 400);
|
||||||
lastSearch = q;
|
lastSearch = q;
|
||||||
}
|
}
|
||||||
@ -85,11 +107,14 @@ export default class AdminSiteTextIndexController extends Controller {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
updateLocale(value) {
|
updateLocale(value) {
|
||||||
this.setProperties({
|
this.searching = true;
|
||||||
searching: true,
|
this.locale = value;
|
||||||
locale: value,
|
|
||||||
});
|
|
||||||
|
|
||||||
discourseDebounce(this, this._performSearch, 400);
|
discourseDebounce(this, this._performSearch, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
showReseedModal() {
|
||||||
|
this.modal.show(ReseedModal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import Route from "@ember/routing/route";
|
import Route from "@ember/routing/route";
|
||||||
import { action, getProperties } from "@ember/object";
|
import { disableImplicitInjections } from "discourse/lib/implicit-injections";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
import ReseedModal from "admin/components/modal/reseed";
|
|
||||||
|
|
||||||
|
@disableImplicitInjections
|
||||||
export default class AdminSiteTextIndexRoute extends Route {
|
export default class AdminSiteTextIndexRoute extends Route {
|
||||||
@service modal;
|
@service siteSettings;
|
||||||
|
@service store;
|
||||||
|
|
||||||
queryParams = {
|
queryParams = {
|
||||||
q: { replace: true },
|
q: { replace: true },
|
||||||
@ -14,18 +15,11 @@ export default class AdminSiteTextIndexRoute extends Route {
|
|||||||
};
|
};
|
||||||
|
|
||||||
model(params) {
|
model(params) {
|
||||||
return this.store.find(
|
return this.store.find("site-text", {
|
||||||
"site-text",
|
q: params.q,
|
||||||
getProperties(params, "q", "overridden", "outdated", "locale")
|
overridden: params.overridden ?? false,
|
||||||
);
|
outdated: params.outdated ?? false,
|
||||||
}
|
locale: params.locale ?? this.siteSettings.default_locale,
|
||||||
|
});
|
||||||
setupController(controller, model) {
|
|
||||||
controller.set("siteTexts", model);
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
|
||||||
showReseedModal() {
|
|
||||||
this.modal.show(ReseedModal);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
@placeholderKey="admin.site_text.search"
|
@placeholderKey="admin.site_text.search"
|
||||||
@class="no-blur site-text-search"
|
@class="no-blur site-text-search"
|
||||||
@autofocus="true"
|
@autofocus="true"
|
||||||
@key-up={{action "search"}}
|
@key-up={{this.search}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="reseed">
|
<div class="reseed">
|
||||||
<DButton
|
<DButton
|
||||||
@action={{route-action "showReseedModal"}}
|
@action={{this.showReseedModal}}
|
||||||
@label="admin.reseed.action.label"
|
@label="admin.reseed.action.label"
|
||||||
@title="admin.reseed.action.title"
|
@title="admin.reseed.action.title"
|
||||||
@icon="sync"
|
@icon="sync"
|
||||||
@ -26,27 +26,27 @@
|
|||||||
@valueProperty="value"
|
@valueProperty="value"
|
||||||
@content={{this.availableLocales}}
|
@content={{this.availableLocales}}
|
||||||
@value={{this.locale}}
|
@value={{this.locale}}
|
||||||
@onChange={{action "updateLocale"}}
|
@onChange={{this.updateLocale}}
|
||||||
@class="locale-search"
|
@class="locale-search"
|
||||||
@options={{hash filterable=true}}
|
@options={{hash filterable=true}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<Input
|
<input
|
||||||
id="toggle-overridden"
|
id="toggle-overridden"
|
||||||
@type="checkbox"
|
type="checkbox"
|
||||||
@checked={{this.overridden}}
|
checked={{this.resolvedOverridden}}
|
||||||
{{on "click" (action "toggleOverridden")}}
|
{{on "click" this.toggleOverridden}}
|
||||||
/>
|
/>
|
||||||
{{i18n "admin.site_text.show_overriden"}}
|
{{i18n "admin.site_text.show_overriden"}}
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<Input
|
<input
|
||||||
id="toggle-outdated"
|
id="toggle-outdated"
|
||||||
@type="checkbox"
|
type="checkbox"
|
||||||
@checked={{this.outdated}}
|
checked={{this.resolvedOutdated}}
|
||||||
{{on "click" this.toggleOutdated}}
|
{{on "click" this.toggleOutdated}}
|
||||||
/>
|
/>
|
||||||
{{i18n "admin.site_text.show_outdated"}}
|
{{i18n "admin.site_text.show_outdated"}}
|
||||||
@ -55,20 +55,22 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ConditionalLoadingSpinner @condition={{this.searching}}>
|
<ConditionalLoadingSpinner @condition={{this.searching}}>
|
||||||
{{#if this.siteTexts.extras.recommended}}
|
{{#if this.model.extras.recommended}}
|
||||||
<p><b>{{i18n "admin.site_text.recommended"}}</b></p>
|
<p><b>{{i18n "admin.site_text.recommended"}}</b></p>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#each this.siteTexts as |siteText|}}
|
{{#each this.model as |siteText|}}
|
||||||
<SiteTextSummary
|
<SiteTextSummary
|
||||||
@siteText={{siteText}}
|
@siteText={{siteText}}
|
||||||
@editAction={{action "edit"}}
|
@editAction={{this.edit}}
|
||||||
@term={{this.q}}
|
@term={{this.q}}
|
||||||
@searchRegex={{this.siteTexts.extras.regex}}
|
@searchRegex={{this.model.extras.regex}}
|
||||||
/>
|
/>
|
||||||
|
{{else}}
|
||||||
|
{{i18n "admin.site_text.no_results"}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
{{#if this.siteTexts.extras.has_more}}
|
{{#if this.model.extras.has_more}}
|
||||||
<p class="warning">{{i18n "admin.site_text.more_than_50_results"}}</p>
|
<p class="warning">{{i18n "admin.site_text.more_than_50_results"}}</p>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</ConditionalLoadingSpinner>
|
</ConditionalLoadingSpinner>
|
@ -6143,6 +6143,7 @@ en:
|
|||||||
show_outdated: "Only show outdated/invalid"
|
show_outdated: "Only show outdated/invalid"
|
||||||
locale: "Language:"
|
locale: "Language:"
|
||||||
more_than_50_results: "There are more than 50 results. Please refine your search."
|
more_than_50_results: "There are more than 50 results. Please refine your search."
|
||||||
|
no_results: "No matching site texts found"
|
||||||
interpolation_keys: "Available interpolation keys:"
|
interpolation_keys: "Available interpolation keys:"
|
||||||
outdated:
|
outdated:
|
||||||
title: "This translation is outdated"
|
title: "This translation is outdated"
|
||||||
|
Reference in New Issue
Block a user