Skip to content

Instantly share code, notes, and snippets.

@mathjazz
Created October 14, 2016 23:50
Show Gist options
  • Save mathjazz/5cd6b4f9858a3e443ea4a041a3beba90 to your computer and use it in GitHub Desktop.
Save mathjazz/5cd6b4f9858a3e443ea4a041a3beba90 to your computer and use it in GitHub Desktop.
Improvements over PR #463
diff --git a/pontoon/base/models.py b/pontoon/base/models.py
index 27a997d..48184cb 100644
--- a/pontoon/base/models.py
+++ b/pontoon/base/models.py
@@ -1323,7 +1323,7 @@ class Entity(DirtyFieldsMixin, models.Model):
@classmethod
def for_project_locale(self, project, locale, paths=None, status=None,
- search=None, exclude=None, smart=None, author=None, time=None):
+ search=None, exclude=None, extra=None, author=None, time=None):
"""Get project entities with locale translations."""
entities = Entity.objects.all()
@@ -1355,14 +1355,14 @@ class Entity(DirtyFieldsMixin, models.Model):
if query:
entities = EntityQuerySet.with_status_counts(entities, locale).filter(query);
- if smart:
+ if extra:
query = None
- if ',' in smart:
- smart = smart.split(',')
+ if ',' in extra:
+ extra = extra.split(',')
else:
- smart = [smart]
+ extra = [extra]
- for s in smart:
+ for s in extra:
if s == 'untranslated':
q = (~Q(approved_count=F('expected_count')))
diff --git a/pontoon/base/static/css/translate.css b/pontoon/base/static/css/translate.css
index c4d48f7..84a117f 100644
--- a/pontoon/base/static/css/translate.css
+++ b/pontoon/base/static/css/translate.css
@@ -328,7 +328,7 @@ body > header .locale.select {
content: "";
}
-.by-author .status:before {
+#filter .button.author .status:before {
color: #AAAAAA;
content: "";
}
@@ -733,6 +733,10 @@ body > header aside p {
background: transparent;
}
+#filter .menu li.time-range .title {
+ display: none;
+}
+
#filter .menu li.time-range label {
color: #FFFFFF;
float: left;
@@ -887,10 +891,15 @@ body > header aside p {
}
#filter .menu li.author {
+ height: 48px;
padding-left: 4px;
white-space: nowrap;
}
+#filter .menu li.author figure {
+ height: 100%;
+}
+
#filter .menu li.author img {
vertical-align: top;
}
@@ -912,45 +921,63 @@ body > header aside p {
#filter .menu li.author .sel {
position: absolute;
- display: inline-block;
}
#filter .menu li.author .status {
display: none;
- position: absolute;
- line-height: 48px;
- left: 17px;
- top: auto;
+ height: 100%;
+ left: 0;
+ margin: 0;
+ padding: 16px 0 0;
+ text-align: center;
+ top: 0;
+ width: 100%;
z-index: 1;
+
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
}
#filter .menu li.author .status:before {
color: #AAAAAA;
}
-#filter .menu li.author.selected .status, #filter .menu li.author:hover .status {
+
+#filter .menu li.author.selected .status,
+#filter .menu li.author .sel:hover .status {
display: block;
}
-#filter .menu li.author.selected img, #filter .menu li.author:hover img {
+#filter .menu li.author.selected img,
+#filter .menu li.author .sel:hover img {
opacity: 0.3;
}
-#filter .apply-selected {
+#filter .toolbar {
display: none;
- background: #272A2F;
- border-bottom: 1px solid #5E6475;
- height: 44px;
- left: 0;
- padding: 12px;
- position: absolute;
- text-align: right;
+ border-top: 1px solid #5E6475;
+ margin-top: 12px;
+ padding: 12px 0 0;
text-transform: uppercase;
- width: 350px;
+ width: 100%;
+
-moz-box-sizing: border-box;
box-sizing: border-box;
}
+#filter .clear-selection {
+ float: left;
+}
+
+#filter .apply-selected {
+ float: right;
+ text-align: right;
+}
+
+#filter .toolbar .fa {
+ vertical-align: top;
+}
+
#filter .apply-selected:hover, #filter .apply-selected .applied-count {
color: #7BC876;
}
@@ -974,10 +1001,14 @@ body > header aside p {
top: 2px;
}
-#filter .menu li.unchanged .status {
+#filter .menu li.unchanged:not(.selected) .status {
left: 3px;
}
+#filter .menu li.unchanged:not(.selected) .status:hover {
+ left: 4px;
+}
+
/* Make selection area bigger and fit the entire row for easier use */
#filter .menu li .status {
margin: -3px -13px -3px -16px;
diff --git a/pontoon/base/static/css/user.css b/pontoon/base/static/css/user.css
index 4f03862..b5c1e60 100644
--- a/pontoon/base/static/css/user.css
+++ b/pontoon/base/static/css/user.css
@@ -30,11 +30,6 @@
opacity: 0.3;
}
-#title a img {
- transition: opacity 0.4s;
- -webkit-transition: opacity 0.4s;
-}
-
#subtitle .uneditable {
letter-spacing: normal;
padding: 8px 0 20px;
diff --git a/pontoon/base/static/js/main.js b/pontoon/base/static/js/main.js
index 86ef9a2..5fb1d39 100755
--- a/pontoon/base/static/js/main.js
+++ b/pontoon/base/static/js/main.js
@@ -441,7 +441,6 @@ $(function() {
.parents('.select').addClass('opened');
$('#iframe-cover:not(".hidden")').show(); // iframe fix
$('body:not(".admin-project") .menu:visible input[type=search]').focus().trigger('input');
- $('.apply-selected').show();
}
});
diff --git a/pontoon/base/static/js/translate.js b/pontoon/base/static/js/translate.js
index 133ad92..c5f6bec 100644
--- a/pontoon/base/static/js/translate.js
+++ b/pontoon/base/static/js/translate.js
@@ -15,18 +15,18 @@ var Pontoon = (function (my) {
/*
* Set filter widget
*
- * filter - object with properties 'status', 'smart', 'author', 'time' for each filter type
+ * filter - object with properties 'status', 'extra', 'author', 'time' for each filter type
*/
- setFilters: function (filter) {
+ setFilter: function (filter) {
filter = filter || {
status: [],
- smart: [],
- author: [],
- time: ''
+ extra: [],
+ time: '',
+ author: []
};
- var node = $('#filter .menu [data-type="' + (filter.smart || filter.status) + '"]'),
- selectorType = filter.smart || filter.status;
+ var selectorType = filter.extra.length ? filter.extra : filter.status,
+ node = $('#filter .menu [data-type="' + selectorType + '"]');
function defaultFilter() {
selectorType = 'all';
@@ -36,25 +36,25 @@ var Pontoon = (function (my) {
// Validate filter
if (node.length === 0) {
- var t = filter.time;
+ var time = filter.time;
// Special case: filter by time range
- if (/^[0-9]{12}-[0-9]{12}$/.test(t)) {
+ if (/^[0-9]{12}-[0-9]{12}$/.test(time)) {
// Populate from/to inputs (needed if filter specified in URL)
var from = new Date(
- t.substring(0, 4) + '/' +
- t.substring(4, 6) + '/' +
- t.substring(6, 8) + ' ' +
- t.substring(8, 10) + ':' +
- t.substring(10, 12) + ' UTC'
+ time.substring(0, 4) + '/' +
+ time.substring(4, 6) + '/' +
+ time.substring(6, 8) + ' ' +
+ time.substring(8, 10) + ':' +
+ time.substring(10, 12) + ' UTC'
);
var to = new Date(
- t.substring(13, 17) + '/' +
- t.substring(17, 19) + '/' +
- t.substring(19, 21) + ' ' +
- t.substring(21, 23) + ':' +
- t.substring(23, 25) + ' UTC'
+ time.substring(13, 17) + '/' +
+ time.substring(17, 19) + '/' +
+ time.substring(19, 21) + ' ' +
+ time.substring(21, 23) + ':' +
+ time.substring(23, 25) + ' UTC'
);
if (from != 'Invalid Date' && to != 'Invalid Date') {
@@ -72,6 +72,7 @@ var Pontoon = (function (my) {
this.resetTimeRange();
}
+ // If filter invalid, fallback to default
} else {
defaultFilter();
}
@@ -80,13 +81,9 @@ var Pontoon = (function (my) {
var title = node.find('.title').text();
// Special case: filter by one author
- if (filter.author.length == 1) {
- title = $('#filter .menu [data-type="' + filter.author[0] + '"]').find('.name').text() + '\'s translations';
- selectorType = 'by-author';
- }
-
- if (selectorType == 'time-range'){
- title = 'Time Range';
+ if (filter.author.length === 1) {
+ title = $('#filter .menu [data-type="' + filter.author[0] + '"]').find('.name').text() + "'s translations";
+ selectorType = 'author';
}
$('#search').attr('placeholder', 'Search in ' + title);
@@ -1044,94 +1041,103 @@ var Pontoon = (function (my) {
/*
- * Turns on/off .selected class and changes placeholder & icon of multiple filters search
+ * Mark selected filters
*/
- applySelectedFilters: function(){
- var f = this.getFilter(),
- applied = 0,
- types = 0,
- l = 0,
- title = '',
- type = 'all';
+ updateMultipleFilterSelection: function() {
+ var filter = this.getFilter(),
+ typeFilterCount = 0,
+ placeholder = [],
+ selectorType = 'all';
- $('#filter .selected').removeClass('selected');
- for (var i in f) {
- if (f[i]) {
- if (f[i] == 'untranslated') {
- $('#filter .menu [data-type="missing"], #filter .menu [data-type="fuzzy"], #filter .menu [data-type="suggested"]').addClass("selected");
+ // Reset all filters
+ this.clearSelectedFilters();
+
+ function markSelectedFilters(type) {
+ for (var i=0; i < typeFilterCount; i++) {
+ var node = $('#filter .menu [data-type="' + filter[type][i] + '"]'),
+ title = node.find('.title').text();
+
+ node.addClass('selected');
+
+ if (type === 'author') {
+ title = node.find('.name').text() + "'s translations";
}
+ placeholder.push(title);
+ }
+ }
- if (i == 'status') {
- l = f.status.length;
- if (l > 0) types++;
- if (l > 1) title = 'Search in ' + f.status.join(', ') + ' strings';
- for (var a = 0; a < l; a++) {
- $('#filter .menu [data-type="' +f.status[a] + '"]').addClass("selected");
- applied++;
- }
+ for (var type in filter) {
+ if (filter[type] && filter[type] !== []) {
+ typeFilterCount = filter[type].length;
- } else if (i == 'smart') {
- l = f.smart.length;
- if (l > 0) types++;
- if (l > 1) title = 'Search ' + f.smart.map(function(v){
- return v == 'has-suggestions' ? 'having suggestions' : v;
- }).join(', ') + ' strings';
- for (var a = 0; a < l; a++) {
- $('#filter .menu [data-type="' +f.smart[a] + '"]').addClass("selected");
- applied++;
- }
+ if (type === 'status' || type === 'extra' || type === 'author') {
+ markSelectedFilters(type);
- } else if (i == 'author') {
- l = f.author.length;
- if (l > 0) types++;
- if (l > 1){
- title = 'Search translations of ' + f.author.join(', ');
- type = 'by-author';
- }
- for (var a = 0; a < l; a++) {
- $('#filter .menu [data-type="' + f.author[a] + '"]').addClass("selected");
- applied++;
- }
+ } else if (type === 'time') {
+ var node = $('#filter .menu [data-type="time-range"]');
+ node.addClass('selected');
+ placeholder.push(node.find('.title').text());
- } else {
- $('#filter .menu [data-type="time-range"]').addClass("selected");
- applied++;
- types++;
}
}
}
- if (types > 1) {
- title = 'Search using ' + types + ' combined filters';
- type = 'all';
- }
+ var selectedCount = $('#filter .selected').length;
- if (title) {
- $('#search').attr('placeholder', title);
- $('#filter .button').attr('class', 'button selector ' + type);
+ // If only one filter selected, use it's own icon in the filter selector
+ if (selectedCount === 1) {
+ selectorType = $('#filter .selected').data('type');
+ if (selectorType.indexOf('@') !== -1) {
+ selectorType = 'author';
+ }
}
- $('.apply-selected')
- .find('.variant').toggleClass('plural', applied > 1).parent()
- .find('.applied-count').html(applied);
+ // Update placeholder and filter selector icon
+ $('#search').attr('placeholder', 'Search in ' + (placeholder.join(', ') || 'All'));
+ $('#filter .button').attr('class', 'button selector ' + selectorType);
- return applied;
+ // Update count (N) in Apply N filters button
+ $('#filter .toolbar')
+ .toggle(selectedCount > 0)
+ .find('.variant').toggleClass('plural', selectedCount > 1).end()
+ .find('.applied-count').html(selectedCount);
},
- validateDate: function() {
+
+ /*
+ * Validate Time range filter
+ */
+ validateTimeRange: function() {
var from = this.local2server($('#from').val());
to = this.local2server($('#to').val());
- // Validate Time range filter
if (from && to) {
- return from + '-' + to;
+ return from + '-' + to;
} else {
- $('#from').toggleClass('error', !from);
- $('#to').toggleClass('error', !to);
- return '';
+ $('#from').toggleClass('error', !from);
+ $('#to').toggleClass('error', !to);
+ return false;
}
},
+
+ /*
+ * Clear selected filters
+ */
+ clearSelectedFilters: function() {
+ $('#filter .selected').removeClass('selected');
+ },
+
+
+ /*
+ * Apply selected filters
+ */
+ applySelectedFilters: function() {
+ this.searchEntities();
+ $('#filter .selector').click();
+ },
+
+
attachEntityListHandlers: function() {
var self = this;
@@ -1139,77 +1145,80 @@ var Pontoon = (function (my) {
$('#filter').on('click', 'li[data-type]:not(".editing"):not(".all") .status', function(e) {
e.stopPropagation();
- var filter = self.getFilter(),
- el = $(this).parent(),
- el = el.data('type') ? el : el.parent().parent(),
+ var el = $(this).parents('li'),
value = el.data('type'),
- applied = 0;
+ filter = self.getFilter(),
+ num = null;
+
+ function updateFilterValue(type) {
+ num = $.inArray(value, filter[type]);
+ if (num === -1) {
+ filter[type].push(value);
+ } else {
+ filter[type].splice(num, 1);
+ }
+ }
if (el.hasClass('time-range')) {
- filter.time = el.hasClass('selected') ? '' : self.validateDate();
+ filter.time = el.hasClass('selected') ? '' : self.validateTimeRange() || '';
} else if (el.hasClass('author')) {
- var num = $.inArray(value, filter.author);
- (num == -1) ? filter.author.push(value) : filter.author.splice(num, 1);
+ updateFilterValue('author');
} else if (el.hasClass('untranslated') || el.hasClass('unchanged') || el.hasClass('has-suggestions')) {
- var num = $.inArray(value, filter.smart);
- (num == -1) ? filter.smart.push(value) : filter.smart.splice(num, 1);
- if (filter.smart == 'untranslated') filter.status = [];
+ updateFilterValue('extra');
} else {
- var num = $.inArray('untranslated', filter.smart);
- if ((num !=- 1) && (value == 'missing' || value == 'fuzzy' || value == 'suggested')) {
- var a = ['missing', 'fuzzy', 'suggested'];
- a.splice($.inArray(value, a), 1);
- filter.status.push(a[0], a[1]);
- filter.smart.splice(num, 1);
-
- } else {
- var num = $.inArray(value, filter.status);
- (num == -1) ? filter.status.push(value) : filter.status.splice(num, 1);
-
- }
+ updateFilterValue('status');
}
- self.setFilters(filter);
- self.applySelectedFilters();
+ self.updateMultipleFilterSelection();
});
- // Use ONLY ONE filter for entities
+ // Filter entities by a single filter
$('#filter').on('click', 'li[data-type]:not(".editing")', function(e) {
var el = $(this),
value = el.data('type'),
filter = {
status: [],
- smart: [],
- author: [],
- time: ''
+ extra: [],
+ time: '',
+ author: []
};
if (el.hasClass('time-range')) {
- filter.time = self.validateDate();
+ filter.time = self.validateTimeRange();
+ if (!filter.time) {
+ return;
+ }
} else if (el.hasClass('author')) {
filter.author.push(value);
} else if (el.hasClass('untranslated') || el.hasClass('unchanged') || el.hasClass('has-suggestions')) {
- filter.smart.push(value);
+ filter.extra.push(value);
- } else if(!el.hasClass('all')) {
+ } else if (!el.hasClass('all')) {
filter.status.push(value);
}
- self.setFilters(filter);
+ self.clearSelectedFilters();
+ self.setFilter(filter);
self.applySelectedFilters();
- self.searchEntities();
- $('#filter .selector').click();
+ });
+
+ // Clear selected filters
+ $('#filter .clear-selected').click(function(e) {
+ e.preventDefault();
+
+ self.clearSelectedFilters();
+ self.setFilter();
+ $('#filter .toolbar').hide();
});
// Apply selected filters
$('#filter .apply-selected').click(function(e) {
- self.searchEntities();
- $('#filter .selector').click();
+ self.applySelectedFilters();
});
// Time range editing toggle
@@ -1833,7 +1842,7 @@ var Pontoon = (function (my) {
self.updateCachedTranslation();
self.updateAuthors();
self.updateRangePicker();
- self.applySelectedFilters();
+ self.updateMultipleFilterSelection();
}
});
},
@@ -1958,7 +1967,7 @@ var Pontoon = (function (my) {
self.updateAuthors();
self.countsPerMinute = entitiesData.counts_per_minute;
self.updateRangePicker();
- self.applySelectedFilters();
+ self.updateMultipleFilterSelection();
entitiesMap = {};
$.each(entitiesData.entities, function() {
@@ -2263,7 +2272,7 @@ var Pontoon = (function (my) {
self.updateAuthors();
self.updateInPlaceTranslation(data.translation.string);
self.updateRangePicker();
- self.applySelectedFilters();
+ self.updateMultipleFilterSelection();
// Update translation, including in place if possible
if (entity.body && (self.user.isTranslator || !entity.translation[pf].approved)) {
@@ -2462,7 +2471,6 @@ var Pontoon = (function (my) {
// Hide menus on click outside
$('body').bind("click.main", function (e) {
$('.menu').hide();
- $('.apply-selected').hide();
$('#iframe-cover').hide(); // iframe fix
$('.select').removeClass('opened');
$('.menu li').removeClass('hover');
@@ -2588,7 +2596,7 @@ var Pontoon = (function (my) {
self.updateCurrentPart(self.getSelectedPart());
// Reset optional state parameters and update state
- self.setFilters();
+ self.setFilter();
self.setSearch('');
var state = self.getState('selected');
@@ -2640,7 +2648,7 @@ var Pontoon = (function (my) {
*/
updateAuthors: function () {
var authors = $('#filter').find('.for-authors').toggle(this.authors.length > 0);
- $('#filter .author').remove();
+ $('#filter .menu li.author').remove();
$.each(this.authors, function() {
authors.after('<li class="author" data-type="' + this.email + '">' +
@@ -2774,7 +2782,7 @@ var Pontoon = (function (my) {
self.resetTimeRange();
self.updateAuthors();
self.updateRangePicker();
- self.applySelectedFilters();
+ self.updateMultipleFilterSelection();
self.renderEntityList();
self.updateProgress();
@@ -2806,7 +2814,7 @@ var Pontoon = (function (my) {
entity = this.state.entity;
// No optional state parameters
- if (!filter.status && !filter.smart && !filter.author && !filter.time && !search && !entity) {
+ if (!filter.status && !filter.extra && !filter.author && !filter.time && !search && !entity) {
this.showDefaultView();
return;
}
@@ -3261,7 +3269,7 @@ var Pontoon = (function (my) {
'paths': self.getPartPaths(self.currentPart),
'search': self.getSearch(),
'status': self.getFilter('status').join(','),
- 'smart': self.getFilter('smart').join(','),
+ 'extra': self.getFilter('extra').join(','),
'author': self.getFilter('author').join(','),
'time': self.getFilter('time'),
'inplaceEditor': self.requiresInplaceEditor()
@@ -3313,7 +3321,7 @@ var Pontoon = (function (my) {
self.updateProgress();
self.updateAuthors();
self.updateRangePicker();
- self.applySelectedFilters();
+ self.updateMultipleFilterSelection();
self.createObject(true);
return;
}
@@ -3609,8 +3617,8 @@ var Pontoon = (function (my) {
queryParams.status = state.filter.status.join(',');
}
- if (state.filter.smart.length > 0) {
- queryParams.smart = state.filter.smart.join(',');
+ if (state.filter.extra.length > 0) {
+ queryParams.extra = state.filter.extra.join(',');
}
if (state.filter.author.length > 0) {
@@ -3679,18 +3687,18 @@ var Pontoon = (function (my) {
updateInitialState: function() {
var state = this.getState('selected');
state.filter = {
- status: this.getQueryParam('status') ? this.getQueryParam('status').split(',') : [],
- smart: this.getQueryParam('smart') ? this.getQueryParam('smart').split(',') : [],
- author: this.getQueryParam('author') ? this.getQueryParam('author').split(',') : [],
- time: this.getQueryParam('time')
+ status: this.getQueryParam('status') ? this.getQueryParam('status').split(',') : [],
+ extra: this.getQueryParam('extra') ? this.getQueryParam('extra').split(',') : [],
+ time: this.getQueryParam('time'),
+ author: this.getQueryParam('author') ? this.getQueryParam('author').split(',') : []
};
state.search = this.getQueryParam('search');
state.entity = this.getQueryParam('string');
// Update search and filter
this.setSearch(state.search);
- this.setFilters(state.filter);
- this.applySelectedFilters();
+ this.setFilter(state.filter);
+ this.updateMultipleFilterSelection();
// Fallback to first available part if no matches found (mistyped URL)
var paths = requestedPaths = this.getSelectedPart();
@@ -3729,8 +3737,8 @@ window.onpopstate = function(e) {
// Update search and filter
Pontoon.setSearch(Pontoon.state.search);
- Pontoon.setFilters(Pontoon.state.filter);
- Pontoon.applySelectedFilters();
+ Pontoon.setFilter(Pontoon.state.filter);
+ Pontoon.updateMultipleFilterSelection();
Pontoon.initializePart(true);
}
@@ -3751,9 +3759,10 @@ Pontoon.attachBatchEditorHandlers();
Pontoon.authors = $('#server').data('authors');
Pontoon.updateAuthors();
+
Pontoon.countsPerMinute = $('#server').data('counts-per-minute');
Pontoon.updateRangePicker();
-Pontoon.applySelectedFilters();
+Pontoon.updateMultipleFilterSelection();
Pontoon.updateInitialState();
Pontoon.initializePart();
diff --git a/pontoon/base/templates/translate.html b/pontoon/base/templates/translate.html
index c41938c..e108428 100755
--- a/pontoon/base/templates/translate.html
+++ b/pontoon/base/templates/translate.html
@@ -146,20 +146,11 @@
<div id="entitylist">
<div class="search-wrapper clearfix">
<div class="icon fa fa-search"></div>
- <input id="search" type="search" autocomplete="off" placeholder="Search All" title="Search Strings (Ctrl + Shift + F)">
+ <input id="search" type="search" autocomplete="off" placeholder="Search in All" title="Search Strings (Ctrl + Shift + F)">
<div id="filter" class="select" data-current-filter="all">
<div class="button selector all">
<span class="status fa"></span>
</div>
- <a class="apply-selected" href="#apply-selected" title="Apply Selected Filters">
- <span class="fa fa-check fa-lg"></span>
- Apply
- <span class="applied-count"></span>
- <span class="variant">
- <span class="singular">filter</span>
- <span class="plural">filters</span>
- </span>
- </a>
<div class="menu">
<ul>
<li class="horizontal-separator">Translation Status</li>
@@ -170,7 +161,7 @@
{{ Filter.item('suggested', 'Suggested', count=True) }}
{{ Filter.item('translated', 'Translated', count=True) }}
- <li class="horizontal-separator">Smart Filters</li>
+ <li class="horizontal-separator">Extra Filters</li>
{{ Filter.item('untranslated', 'Untranslated') }}
{{ Filter.item('unchanged', 'Unchanged') }}
@@ -180,7 +171,8 @@
<li class="time-range clearfix" data-type="time-range">
<span class="status fa"></span>
- <div class="title clearfix">
+ <span class="title">Time Range</span>
+ <div class="clearfix">
<label for="from">From<input type="datetime" id="from" disabled></label>
<label for="to">To<input type="datetime" id="to" disabled></label>
</div>
@@ -189,6 +181,21 @@
<li class="horizontal-separator for-authors">Translation Authors</li>
</ul>
+ <div class="toolbar clearfix">
+ <a class="clear-selected" href="#clear-filters" title="Uncheck selected filters">
+ <span class="fa fa-remove fa-lg"></span>
+ Clear selection
+ </a>
+ <a class="apply-selected" href="#apply-filters" title="Apply Selected Filters">
+ <span class="fa fa-check fa-lg"></span>
+ Apply
+ <span class="applied-count"></span>
+ <span class="variant">
+ <span class="singular">filter</span>
+ <span class="plural">filters</span>
+ </span>
+ </a>
+ </div>
</div>
</div>
</div>
diff --git a/pontoon/base/views.py b/pontoon/base/views.py
index d51d255..8c5e65e 100755
--- a/pontoon/base/views.py
+++ b/pontoon/base/views.py
@@ -412,7 +412,7 @@ def entities(request):
locale = get_object_or_404(Locale, code__iexact=locale)
status = request.POST.get('status', '')
- smart = request.POST.get('smart', '')
+ extra = request.POST.get('extra', '')
author = request.POST.get('author', '')
time = request.POST.get('time', '')
search = request.POST.get('search', '')
@@ -437,7 +437,7 @@ def entities(request):
}, safe=False)
entities = Entity.for_project_locale(
- project, locale, paths, status, search, exclude_entities, smart, author, time
+ project, locale, paths, status, search, exclude_entities, extra, author, time
)
# Only return a list of entity PKs (batch editing: select all)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment