Support for "Only show overridden" in site text customization
This commit is contained in:
parent
04593b8fef
commit
de88be2fbc
|
@ -2,6 +2,7 @@ import { on } from 'ember-addons/ember-computed-decorators';
|
|||
|
||||
export default Ember.Component.extend({
|
||||
classNames: ['site-text'],
|
||||
classNameBindings: ['siteText.overridden'],
|
||||
|
||||
@on('didInsertElement')
|
||||
highlightTerm() {
|
||||
|
|
|
@ -5,8 +5,20 @@ export default Ember.Controller.extend({
|
|||
searching: false,
|
||||
siteTexts: null,
|
||||
preferred: false,
|
||||
_overridden: null,
|
||||
queryParams: ['q', 'overridden'],
|
||||
|
||||
queryParams: ['q'],
|
||||
@computed
|
||||
overridden: {
|
||||
set(value) {
|
||||
if (!value || value === "false") { value = false; }
|
||||
this._overridden = value;
|
||||
return value;
|
||||
},
|
||||
get() {
|
||||
return this._overridden;
|
||||
}
|
||||
},
|
||||
|
||||
@computed
|
||||
q: {
|
||||
|
@ -21,8 +33,7 @@ export default Ember.Controller.extend({
|
|||
},
|
||||
|
||||
_performSearch() {
|
||||
const q = this.get('q');
|
||||
this.store.find('site-text', { q }).then(results => {
|
||||
this.store.find('site-text', this.getProperties('q', 'overridden')).then(results => {
|
||||
this.set('siteTexts', results);
|
||||
}).finally(() => this.set('searching', false));
|
||||
},
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
export default Ember.Route.extend({
|
||||
queryParams: {
|
||||
q: { replace: true }
|
||||
q: { replace: true },
|
||||
overridden: { replace: true }
|
||||
},
|
||||
|
||||
model(params) {
|
||||
return this.store.find('site-text', { q: params.q });
|
||||
return this.store.find('site-text', Ember.getProperties(params, 'q', 'overridden'));
|
||||
},
|
||||
|
||||
setupController(controller, model) {
|
||||
|
|
|
@ -5,13 +5,17 @@
|
|||
placeholderKey="admin.site_text.search"
|
||||
class="no-blur site-text-search"
|
||||
autofocus="true"
|
||||
keyUpAction="search"}}
|
||||
key-up="search"}}
|
||||
|
||||
<div class='extra-options'>
|
||||
{{d-checkbox label="admin.site_text.show_overriden" checked=overridden change="search"}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#conditional-loading-spinner condition=searching}}
|
||||
{{#unless siteTexts.findArgs.q}}
|
||||
{{#if siteTexts.extras.recommended}}
|
||||
<p><b>{{i18n "admin.site_text.recommended"}}</b></p>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
|
||||
{{#each siteTexts as |siteText|}}
|
||||
{{site-text-summary siteText=siteText editAction="edit" term=q}}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import { on } from "ember-addons/ember-computed-decorators";
|
||||
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'label',
|
||||
|
||||
@on('didInsertElement')
|
||||
_watchChanges() {
|
||||
// In Ember 13.3 we can use action on the checkbox `{{input}}` but not in 1.11
|
||||
this.$('input').on('click.d-checkbox', () => {
|
||||
Ember.run.scheduleOnce('afterRender', () => this.sendAction('change'));
|
||||
});
|
||||
},
|
||||
|
||||
@on('willDestroyElement')
|
||||
_stopWatching() {
|
||||
this.$('input').off('click.d-checkbox');
|
||||
}
|
||||
});
|
|
@ -6,12 +6,5 @@ export default Ember.TextField.extend({
|
|||
@computed("placeholderKey")
|
||||
placeholder(placeholderKey) {
|
||||
return placeholderKey ? I18n.t(placeholderKey) : "";
|
||||
},
|
||||
|
||||
keyUp() {
|
||||
const act = this.get('keyUpAction');
|
||||
if (act) {
|
||||
this.sendAction('keyUpAction');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -88,9 +88,9 @@ export default Ember.Object.extend({
|
|||
|
||||
refreshResults(resultSet, type, url) {
|
||||
const self = this;
|
||||
return Discourse.ajax(url).then(function(result) {
|
||||
const typeName = Ember.String.underscore(self.pluralize(type)),
|
||||
content = result[typeName].map(obj => self._hydrate(type, obj, result));
|
||||
return Discourse.ajax(url).then(result => {
|
||||
const typeName = Ember.String.underscore(self.pluralize(type));
|
||||
const content = result[typeName].map(obj => self._hydrate(type, obj, result));
|
||||
resultSet.set('content', content);
|
||||
});
|
||||
},
|
||||
|
@ -143,13 +143,24 @@ export default Ember.Object.extend({
|
|||
},
|
||||
|
||||
_resultSet(type, result, findArgs) {
|
||||
const typeName = Ember.String.underscore(this.pluralize(type)),
|
||||
content = result[typeName].map(obj => this._hydrate(type, obj, result)),
|
||||
totalRows = result["total_rows_" + typeName] || content.length,
|
||||
loadMoreUrl = result["load_more_" + typeName],
|
||||
refreshUrl = result['refresh_' + typeName];
|
||||
const typeName = Ember.String.underscore(this.pluralize(type));
|
||||
const content = result[typeName].map(obj => this._hydrate(type, obj, result));
|
||||
|
||||
return ResultSet.create({ content, totalRows, loadMoreUrl, refreshUrl, findArgs, store: this, __type: type });
|
||||
const createArgs = {
|
||||
content,
|
||||
findArgs,
|
||||
totalRows: result["total_rows_" + typeName] || content.length,
|
||||
loadMoreUrl: result["load_more_" + typeName],
|
||||
refreshUrl: result['refresh_' + typeName],
|
||||
store: this,
|
||||
__type: type
|
||||
};
|
||||
|
||||
if (result.extras) {
|
||||
createArgs.extras = result.extras;
|
||||
}
|
||||
|
||||
return ResultSet.create(createArgs);
|
||||
},
|
||||
|
||||
_build(type, obj) {
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
{{input type="checkbox" checked=checked}}
|
||||
{{i18n label}}
|
|
@ -50,11 +50,19 @@ td.flaggers td {
|
|||
margin-top: 0;
|
||||
}
|
||||
|
||||
input {
|
||||
.site-text-search {
|
||||
padding: 0.5em;
|
||||
font-size: 1em;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.extra-options {
|
||||
float: right;
|
||||
input[type=checkbox] {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.text-highlight {
|
||||
font-weight: bold;
|
||||
|
@ -65,6 +73,10 @@ td.flaggers td {
|
|||
border-bottom: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
|
||||
margin-bottom: 0.5em;
|
||||
|
||||
&.overridden {
|
||||
background-color: dark-light-diff($highlight, $secondary, 50%, -60%);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: normal;
|
||||
font-size: 1.1em;
|
||||
|
|
|
@ -8,11 +8,15 @@ class Admin::SiteTextsController < Admin::AdminController
|
|||
end
|
||||
|
||||
def index
|
||||
if params[:q].blank?
|
||||
overridden = params[:overridden] == 'true'
|
||||
extras = {}
|
||||
|
||||
if params[:q].blank? && !overridden
|
||||
extras[:recommended] = true
|
||||
results = self.class.preferred_keys.map {|k| {id: k, value: I18n.t(k) }}
|
||||
else
|
||||
results = []
|
||||
translations = I18n.search(params[:q])
|
||||
translations = I18n.search(params[:q], overridden: overridden)
|
||||
translations.each do |k, v|
|
||||
results << {id: k, value: v}
|
||||
end
|
||||
|
@ -21,7 +25,7 @@ class Admin::SiteTextsController < Admin::AdminController
|
|||
end
|
||||
end
|
||||
|
||||
render_serialized(results[0..50], SiteTextSerializer, root: 'site_texts', rest_serializer: true)
|
||||
render_serialized(results[0..50], SiteTextSerializer, root: 'site_texts', rest_serializer: true, extras: extras)
|
||||
end
|
||||
|
||||
def show
|
||||
|
|
|
@ -229,6 +229,8 @@ class ApplicationController < ActionController::Base
|
|||
opts.each do |k, v|
|
||||
obj[k] = v if k.to_s.start_with?("refresh_")
|
||||
end
|
||||
|
||||
obj['extras'] = opts[:extras] if opts[:extras]
|
||||
end
|
||||
|
||||
render json: MultiJson.dump(obj), status: opts[:status] || 200
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class SiteTextSerializer < ApplicationSerializer
|
||||
attributes :id, :value, :can_revert?
|
||||
attributes :id, :value, :overridden?, :can_revert?
|
||||
|
||||
def id
|
||||
object[:id]
|
||||
|
@ -9,12 +9,14 @@ class SiteTextSerializer < ApplicationSerializer
|
|||
object[:value]
|
||||
end
|
||||
|
||||
def can_revert?
|
||||
def overridden?
|
||||
current_val = value
|
||||
|
||||
I18n.overrides_disabled do
|
||||
return I18n.t(object[:id]) != current_val
|
||||
end
|
||||
end
|
||||
|
||||
alias_method :can_revert?, :overridden?
|
||||
end
|
||||
|
||||
|
|
|
@ -2492,6 +2492,7 @@ en:
|
|||
revert_confirm: "Are you sure you want to revert your changes?"
|
||||
go_back: "Back to Search"
|
||||
recommended: "We recommend customizing the following text to suit your needs:"
|
||||
show_overriden: 'Only show overridden'
|
||||
|
||||
site_settings:
|
||||
show_overriden: 'Only show overridden'
|
||||
|
|
|
@ -56,7 +56,7 @@ module I18n
|
|||
opts ||= {}
|
||||
|
||||
target = opts[:backend] || backend
|
||||
results = target.search(config.locale, query)
|
||||
results = opts[:overridden] ? {} : target.search(config.locale, query)
|
||||
|
||||
regexp = /#{query}/i
|
||||
(overrides_by_locale || {}).each do |k, v|
|
||||
|
|
|
@ -6,9 +6,22 @@ test("search for a key", () => {
|
|||
visit("/admin/customize/site_texts");
|
||||
|
||||
fillIn('.site-text-search', 'Test');
|
||||
andThen(() => ok(exists('.site-text')));
|
||||
andThen(() => {
|
||||
ok(exists('.site-text'));
|
||||
ok(exists(".site-text:not(.overridden)"));
|
||||
ok(exists('.site-text.overridden'));
|
||||
});
|
||||
|
||||
|
||||
// Only show overridden
|
||||
click('.extra-options input');
|
||||
andThen(() => {
|
||||
ok(!exists(".site-text:not(.overridden)"));
|
||||
ok(exists('.site-text.overridden'));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test("edit and revert a site text by key", () => {
|
||||
visit("/admin/customize/site_texts/site.test");
|
||||
andThen(() => {
|
||||
|
|
|
@ -210,7 +210,7 @@ export default function() {
|
|||
});
|
||||
|
||||
this.get('/fruits', function() {
|
||||
return response({ __rest_serializer: "1", fruits, farmers, colors });
|
||||
return response({ __rest_serializer: "1", fruits, farmers, colors, extras: {hello: 'world'} });
|
||||
});
|
||||
|
||||
this.get('/widgets/:widget_id', function(request) {
|
||||
|
@ -262,7 +262,16 @@ export default function() {
|
|||
this.post('/topics/timings', () => response(200, {}));
|
||||
|
||||
const siteText = {id: 'site.test', value: 'Test McTest'};
|
||||
this.get('/admin/customize/site_texts', () => response(200, {site_texts: [siteText] }));
|
||||
const overridden = {id: 'site.overridden', value: 'Overridden', overridden: true };
|
||||
this.get('/admin/customize/site_texts', request => {
|
||||
|
||||
if (request.queryParams.overridden) {
|
||||
return response(200, {site_texts: [overridden] })
|
||||
} else {
|
||||
return response(200, {site_texts: [siteText, overridden] })
|
||||
}
|
||||
});
|
||||
|
||||
this.get('/admin/customize/site_texts/:key', () => response(200, {site_text: siteText }));
|
||||
this.delete('/admin/customize/site_texts/:key', () => response(200, {site_text: siteText }));
|
||||
|
||||
|
|
|
@ -116,7 +116,6 @@ test('destroyRecord when new', function(assert) {
|
|||
});
|
||||
});
|
||||
|
||||
|
||||
test('find embedded', function(assert) {
|
||||
const store = createStore();
|
||||
return store.find('fruit', 2).then(function(f) {
|
||||
|
@ -136,6 +135,7 @@ test('findAll embedded', function(assert) {
|
|||
return store.findAll('fruit').then(function(fruits) {
|
||||
assert.equal(fruits.objectAt(0).get('farmer.name'), 'Old MacDonald');
|
||||
assert.equal(fruits.objectAt(0).get('farmer'), fruits.objectAt(1).get('farmer'), 'points at the same object');
|
||||
assert.equal(fruits.get('extras.hello'), 'world', 'it can supply extra information');
|
||||
|
||||
const fruitCols = fruits.objectAt(0).get('colors');
|
||||
assert.equal(fruitCols.length, 2);
|
||||
|
|
Loading…
Reference in New Issue