UX: Prioritize categories autocomplete with new rules.

This commit is contained in:
Guo Xiang Tan 2016-01-05 12:50:26 +08:00
parent 294f0e6491
commit d6b5b9436c
3 changed files with 93 additions and 15 deletions

View file

@ -258,21 +258,7 @@ export default Ember.Component.extend({
return category.get('slug'); return category.get('slug');
}, },
dataSource(term) { dataSource(term) {
const limit = 5; return Category.search(term);
const regexp = new RegExp(term, 'i');
var count = 0;
var data = [];
Category.listByActivity().some(category => {
if (category.get('name').match(regexp)) {
count++;
data.push(category);
}
return count === limit;
});
return data;
}, },
triggerRule(textarea, opts) { triggerRule(textarea, opts) {
const result = Discourse.Utilities.caretRowCol(textarea); const result = Discourse.Utilities.caretRowCol(textarea);

View file

@ -285,6 +285,51 @@ Category.reopenClass({
reloadById(id) { reloadById(id) {
return Discourse.ajax(`/c/${id}/show.json`); return Discourse.ajax(`/c/${id}/show.json`);
},
search(term, opts) {
var limit = 5;
if (opts) {
if (opts.limit === 0) {
return [];
} else if (opts.limit) {
limit = opts.limit;
}
}
const emptyTerm = (term === "");
const categories = Category.listByActivity();
const length = categories.length;
var i;
var count = 0;
var data = [];
const done = () => {
return data.length === limit;
}
for (i = 0; i < length && !done(); i++) {
const category = categories[i];
if ((emptyTerm) ||
(!emptyTerm && category.get('name').indexOf(term) === 0)) {
data.push(category);
}
}
if (!done()) {
for (i = 0; i < length && !done(); i++) {
const category = categories[i];
if ((!emptyTerm && category.get('name').indexOf(term) > 0)) {
if (data.indexOf(category) === -1) data.push(category);
}
}
}
return _.sortBy(data, (category) => {
return category.get('read_restricted');
});
} }
}); });

View file

@ -1,4 +1,5 @@
import createStore from 'helpers/create-store'; import createStore from 'helpers/create-store';
import Category from 'discourse/models/category';
module("model:category"); module("model:category");
@ -50,6 +51,8 @@ test('findBySlug', function() {
deepEqual(Discourse.Category.findBySlug('뉴스피드', '熱帶風暴畫眉'), newsFeed, 'we can find a category with CJK slug whose parent slug is also CJK'); deepEqual(Discourse.Category.findBySlug('뉴스피드', '熱帶風暴畫眉'), newsFeed, 'we can find a category with CJK slug whose parent slug is also CJK');
deepEqual(Discourse.Category.findBySlug('时间', 'darth'), time, 'we can find a category with CJK slug whose parent slug is english'); deepEqual(Discourse.Category.findBySlug('时间', 'darth'), time, 'we can find a category with CJK slug whose parent slug is english');
deepEqual(Discourse.Category.findBySlug('bah', '熱帶風暴畫眉'), bah, 'we can find a category with english slug whose parent slug is CJK'); deepEqual(Discourse.Category.findBySlug('bah', '熱帶風暴畫眉'), bah, 'we can find a category with english slug whose parent slug is CJK');
sandbox.restore();
}); });
test('findSingleBySlug', function() { test('findSingleBySlug', function() {
@ -122,3 +125,47 @@ test('postCountStats', function() {
result = category5.get('postCountStats'); result = category5.get('postCountStats');
equal(result.length, 0, "should show nothing"); equal(result.length, 0, "should show nothing");
}); });
test('search', () => {
const result = (term, opts) => {
return Category.search(term, opts).map((category) => category.get('id'));
}
const store = createStore(),
category1 = store.createRecord('category', { id: 1, name: 'middle term' }),
category2 = store.createRecord('category', { id: 2, name: 'middle term' });
sandbox.stub(Category, "listByActivity").returns([category1, category2]);
deepEqual(result('term', { limit: 0 }), [], "returns an empty array when limit is 0");
deepEqual(result(''), [category1.get('id'), category2.get('id')], "orders by activity if no term is matched");
deepEqual(result('term'), [category1.get('id'), category2.get('id')], "orders by activity");
category2.set('name', 'term start');
deepEqual(result('term'), [category2.get('id'), category1.get('id')], "orders matching begin with and then contains");
sandbox.restore();
const category3 = store.createRecord('category', { id: 3, name: 'term start', parent_category_id: category1.get('id') }),
category4 = store.createRecord('category', { id: 4, name: 'some term', read_restricted: true });
sandbox.stub(Category, "listByActivity").returns([category4, category1, category3, category2]);
deepEqual(result(''),
[category1.get('id'), category3.get('id'), category2.get('id'), category4.get('id')],
"prioritize non read_restricted categories when term is blank");
deepEqual(result('', { limit: 3 }),
[category1.get('id'), category3.get('id'), category4.get('id')],
"prioritize non read_restricted categories when term is blank with limit");
deepEqual(result('term'),
[category3.get('id'), category2.get('id'), category1.get('id'), category4.get('id')],
"prioritize non read_restricted");
deepEqual(result('term', { limit: 3 }),
[category3.get('id'), category2.get('id'), category4.get('id')],
"prioritize non read_restricted with limit");
sandbox.restore();
});