diff --git a/frontend_tests/node_tests/filter.js b/frontend_tests/node_tests/filter.js index 1d7533f969..24a793a085 100644 --- a/frontend_tests/node_tests/filter.js +++ b/frontend_tests/node_tests/filter.js @@ -763,6 +763,30 @@ function make_sub(name, stream_id) { assert_term_type(term('is', 'private'), 'is-private'); assert_term_type(term('has', 'link'), 'has-link'); assert_term_type(term('has', 'attachment', true), 'not-has-attachment'); + + function assert_term_sort(in_terms, expected) { + const sorted_terms = Filter.sorted_term_types(in_terms); + assert.deepEqual(sorted_terms, expected); + } + + assert_term_sort( + ['topic', 'stream', 'sender'], + ['stream', 'topic', 'sender'] + ); + + assert_term_sort( + ['has-link', 'near', 'is-unread', 'pm-with'], + ['pm-with', 'near', 'is-unread', 'has-link'] + ); + + assert_term_sort( + ['bogus', 'stream', 'topic'], + ['stream', 'topic', 'bogus'] + ); + assert_term_sort( + ['stream', 'topic', 'stream'], + ['stream', 'stream', 'topic'] + ); }()); (function test_update_email() { diff --git a/static/js/filter.js b/static/js/filter.js index 1f211b89aa..4a4b55a392 100644 --- a/static/js/filter.js +++ b/static/js/filter.js @@ -511,6 +511,36 @@ Filter.term_type = function (term) { return result; }; +Filter.sorted_term_types = function (term_types) { + var levels = [ + 'stream', 'topic', + 'pm-with', 'group-pm-with', 'sender', + 'near', 'id', + 'is-alerted', 'is-mentioned', 'is-private', + 'is-starred', 'is-unread', + 'has-link', 'has-image', 'has-attachment', + 'search', + ]; + + function level(term_type) { + var i = levels.indexOf(term_type); + if (i === -1) { + i = 999; + } + return i; + } + + function compare(a, b) { + var diff = level(a) - level(b); + if (diff !== 0) { + return diff; + } + return util.strcmp(a, b); + } + + return _.clone(term_types).sort(compare); +}; + Filter.operator_to_prefix = function (operator, negated) { var verb;