From 2080dac0f82d36d3fe89e10e4d348a172c23184f Mon Sep 17 00:00:00 2001 From: Kevin Ngo Date: Wed, 4 Mar 2015 18:22:36 -0800 Subject: [PATCH] device filtering persist site-wide, don't persist between session (bug 1127080) --- src/dev.html | 2 +- ...mpat-filtering.styl => compat-filter.styl} | 0 src/media/js/compat_filter.js | 147 ++++++++ src/media/js/compatibility_filtering.js | 164 -------- .../js/compatibility_filtering_select.js | 19 - src/media/js/helpers_local.js | 8 +- src/media/js/init.js | 25 +- src/media/js/main.js | 1 - src/media/js/reviews.js | 2 +- src/media/js/route_api_args.js | 13 - src/media/js/routes.js | 5 +- src/media/js/views/category.js | 3 +- src/media/js/views/debug.js | 8 +- src/media/js/views/debug_features.js | 8 +- src/media/js/views/feedback.js | 6 +- src/media/js/views/new.js | 2 +- src/media/js/views/popular.js | 2 +- src/templates/_includes/app_list_filters.html | 2 +- src/templates/compat_filter.html | 18 + src/templates/compatibility_filtering.html | 29 -- src/templates/langpacks.html | 2 +- src/templates/tests.html | 2 +- tests/ui/app_list.js | 8 +- tests/ui/compat_filter.js | 109 ++++++ tests/ui/search.js | 4 +- tests/unit/compat_filter.js | 117 ++++++ tests/unit/compatibility_filtering.js | 354 ------------------ tests/unit/rewriters.js | 10 +- 28 files changed, 439 insertions(+), 631 deletions(-) rename src/media/css/{compat-filtering.styl => compat-filter.styl} (100%) create mode 100644 src/media/js/compat_filter.js delete mode 100644 src/media/js/compatibility_filtering.js delete mode 100644 src/media/js/compatibility_filtering_select.js delete mode 100644 src/media/js/route_api_args.js create mode 100644 src/templates/compat_filter.html delete mode 100644 src/templates/compatibility_filtering.html create mode 100644 tests/ui/compat_filter.js create mode 100644 tests/unit/compat_filter.js delete mode 100644 tests/unit/compatibility_filtering.js diff --git a/src/dev.html b/src/dev.html index dc501f694a..d325978d11 100644 --- a/src/dev.html +++ b/src/dev.html @@ -38,7 +38,7 @@ - + diff --git a/src/media/css/compat-filtering.styl b/src/media/css/compat-filter.styl similarity index 100% rename from src/media/css/compat-filtering.styl rename to src/media/css/compat-filter.styl diff --git a/src/media/js/compat_filter.js b/src/media/js/compat_filter.js new file mode 100644 index 0000000000..aaa1626180 --- /dev/null +++ b/src/media/js/compat_filter.js @@ -0,0 +1,147 @@ +/* + Compatibility filtering and device filtering. Mainly used to add arguments + to the API router's processor. It also handles `limit` since that can be + affected by the device or form factor. + + Device filtering is affected by a dropdown found above app lists. When the + dropdown is changed, we will persist the new device filtering preference + globally and across sessions. + + For desktop, device filtering is off by default at the moment. + + For feature profiles, if not in querystring, we default to a feature + profile sig that is specially crafted. Includes all features except more + recent ones to hide apps using more recent features from older Marketplaces + that have not been updated yet. Generated in Zamboni with: + f = FeatureProfile.from_signature('fffffffffffffffffffffffffff') + f.update({'mobileid': False, 'precompile_asmjs': False, + 'hardware_512mb_ram': False, 'hardware_1gb_ram': False}) + f.to_signature() +*/ +define('compat_filter', + ['core/capabilities', 'core/l10n', 'core/log', 'core/storage', + 'core/utils', 'core/views', 'core/z', 'underscore'], + function(caps, l10n, log, storage, + utils, views, z, _) { + 'use strict'; + var logger = log('compat_filter'); + var gettext = l10n.gettext; + + var limit = 24; + + // Endpoints where feat. profile enabled if conditions met. See apiArgs(). + var ENDPOINTS_WITH_FEATURE_PROFILE = [ + 'category', 'feed', 'feed-app', 'feed-brand', 'feed-collection', + 'feed-items', 'feed-shelf', 'installed', 'recommended', 'search' + ]; + var feature_profile = utils.getVars().pro || '7fffffffffff0.51.6'; + + var DEVICE_CHOICES = { + 'android-mobile': gettext('Android Mobile'), + 'android-tablet': gettext('Android Tablet'), + 'desktop': gettext('Desktop'), + 'firefoxos': gettext('Firefox OS'), + }; + var DEVICE_FILTER_CHOICES = [ + ['all', gettext('All Apps')], + ['desktop', gettext('Desktop Apps')], + ['firefoxos', gettext('Firefox OS Apps')], + ['android-mobile', gettext('Android Mobile Apps')], + ['android-tablet', gettext('Android Tablet Apps')] + ]; + var actual_platform = caps.device_platform(); + var actual_formfactor = caps.device_formfactor(); + var filterDevice = caps.device_type(); + + z.body.on('change', '#compat-filter', function() { + // Update stored preferences and reload view to refresh changes. + filterDevice = this[this.selectedIndex].value; + logger.log('Filtering: ' + filterDevice); + views.reload(); + }); + + // Add "Apps for my Device" option on mobile. + if (caps.firefoxOS || caps.firefoxAndroid) { + DEVICE_FILTER_CHOICES.splice( + 1, 0, [caps.device_type(), gettext('Apps for My Device')]); + } + + // On desktop, the default is no filtering. + if (actual_platform == 'desktop') { + actual_platform = ''; + filterDevice = ''; + } + + // For mobile, set limit to 10. + if (actual_formfactor == 'mobile' || actual_platform == 'firefoxos') { + limit = 10; + } + + function isDeviceSelected(value) { + // Return whether value should be currently selected. + if (value == 'all' && !filterDevice) { + // Special case: on desktop, where filterDevice is empty. + // 'all' is default behaviour -> 'follow default filtering'. + value = ''; + } + + var deviceOverride = utils.getVars().device_override; + if (deviceOverride) { + return deviceOverride == value; + } else { + return filterDevice == value; + } + } + + function apiArgs(endpoint) { + // Return API args to use for API router's processor. + var args = {}; + var pref; + + pref = utils.getVars().device_override || filterDevice; + if (pref) { + // If have device filter preference or override in query string + // extract it. + pref = pref.split('-'); + if (pref.length > 1) { + args.dev = pref[0]; + args.device = pref[1]; + } else if (pref[0] != 'all') { + args.dev = pref[0]; + args.device = ''; + } else { + // 'all' means no dev/device filtering at all. + args.dev = ''; + args.device = ''; + } + } else { + // If filterDevice does not exist or is empty value, use default + // filtering according to actual_platform and actual_formfactor. + args.dev = actual_platform; + args.device = actual_formfactor; + } + args.limit = limit; + if (actual_platform === 'firefoxos' && + actual_platform === args.dev && + actual_formfactor === args.device && + _.indexOf(ENDPOINTS_WITH_FEATURE_PROFILE, endpoint) >= 0) { + /* + Include feature profile, but only if we: + Are using a Firefox OS device. + Aren't showing 'all apps'. + Are dealing with endpoint that can handle feature profile. + */ + args.pro = feature_profile; + } + return args; + } + + return { + DEVICE_CHOICES: DEVICE_CHOICES, + DEVICE_FILTER_CHOICES: DEVICE_FILTER_CHOICES, + apiArgs: apiArgs, + feature_profile: feature_profile, + isDeviceSelected: isDeviceSelected, + limit: limit, + }; +}); diff --git a/src/media/js/compatibility_filtering.js b/src/media/js/compatibility_filtering.js deleted file mode 100644 index d9bc02280c..0000000000 --- a/src/media/js/compatibility_filtering.js +++ /dev/null @@ -1,164 +0,0 @@ -/* - Compatibility filtering. Also sets some default API arguments. - - Note that endpoint_name must be passed to views looking to use - compatiibility filtering since the `select`s need an endpoint_name. -*/ -define('compatibility_filtering', - ['core/capabilities', 'core/l10n', 'core/log', 'core/storage', 'underscore', 'core/utils', 'core/z'], - function(capabilities, l10n, log, storage, _, utils, z) { - 'use strict'; - var logger = log('compatibility_filtering'); - var gettext = l10n.gettext; - - var DEVICE_CHOICES = { - 'android-mobile': gettext('Android Mobile'), - 'android-tablet': gettext('Android Tablet'), - 'desktop': gettext('Desktop'), - 'firefoxos': gettext('Firefox OS'), - }; - - // API endpoints where feature profile is enabled, if all conditions met. - // See api_args() below. - var ENDPOINTS_WITH_FEATURE_PROFILE = [ - 'category_landing', 'feed', 'feed-app', 'feed-brand', 'feed-collection', - 'feed-items', 'feed-shelf', 'installed', 'recommended', - 'new_popular_search', 'search' - ]; - - var actual_platform = ''; - var actual_formfactor = ''; - var limit = 24; - var device_filter_name; - var key = 'device_filtering_preferences'; - var device_override; - var device_filtering_preferences; - - // Default feature profile signature. - // a specially crafted signature that includes all features except the more - // recent ones, to hide apps using more recent features from older - // Marketplaces that have not been updated yet. Generated in Zamboni with: - // f = FeatureProfile.from_signature('fffffffffffffffffffffffffff') - // f.update({'mobileid': False, - // 'precompile_asmjs': False, - // 'hardware_512mb_ram': False, - // 'hardware_1gb_ram': False}) - // f.to_signature() - var default_feature_profile = '7fffffffffff0.51.6'; - // Get feature profile from query string (yulelog sets this), or fall back - // to the default. - var feature_profile = utils.getVars().pro || default_feature_profile; - - refresh_params(); - z.win.on('navigating', refresh_params); - - // By default, filter by platform and form factor. - actual_platform = capabilities.device_platform(); - actual_formfactor = capabilities.device_formfactor(); - - // For mobile phones, set limit to 10, otherwise use the default, 24. - if (actual_formfactor == 'mobile' || actual_platform == 'firefoxos') { - limit = 10; - } - - // Build the name of the filter combination we are currently using. - device_filter_name = capabilities.device_type(); - - // On desktop, the default is no filtering. - if (actual_platform == 'desktop') { - actual_platform = ''; - device_filter_name = ''; - } - - // Filtering preferences per page group. The default is to follow the - // default filter combination we just built above. - device_filtering_preferences = { - 'category_landing': device_filter_name, - 'new_popular_search': device_filter_name, - 'recommended': device_filter_name, - 'search': device_filter_name, - }; - device_filtering_preferences = _.extend(device_filtering_preferences, - storage.getItem(key) || {}); - - /* Refresh query string parameter override. Called when navigating. */ - function refresh_params(e) { - device_override = utils.getVars().device_override; - } - - /* Return whether the value passed in argument should be selected for the - * seecified endpoint. */ - function is_preference_selected(endpoint_name, value) { - if (value == 'all' && !device_filter_name) { - // Special case: On desktop, where device_filter_name is empty, - // 'all' is the default behaviour. So in this case, treat 'all' - // as '', which is the value for 'follow the default filtering'. - value = ''; - } - if (device_override) { - return device_override == value; - } else { - return device_filtering_preferences[endpoint_name] == value; - } - } - - /* Set a new filtering preference value for the specified endpoint. */ - function set_preference(endpoint_name, value) { - logger.log('Filtering for ' + endpoint_name + ' changed to ' + value); - device_filtering_preferences[endpoint_name] = value; - storage.setItem(key, device_filtering_preferences); - } - - /* Return base API args to use for the specified endpoint. routes_api_args - * adds a couple generic ones on top of these. */ - function api_args(endpoint_name) { - var args = {}, pref; - - pref = device_override || device_filtering_preferences[endpoint_name]; - if (pref) { - // If we have a device filtering preference for that endpoint, - // or an override was given in the query string, extract it. - pref = pref.split('-'); - if (pref.length > 1) { - args.dev = pref[0]; - args.device = pref[1]; - } else if (pref[0] != 'all') { - args.dev = pref[0]; - args.device = ''; - } else { - // 'all' means no dev/device filtering at all. - args.dev = ''; - args.device = ''; - } - } else { - // If device_filtering_preferences[endpoint_name] does not exist or - // is an 'empty' value, then we use the default filtering behaviour - // with whatever actual_platform and actual_formfactor are. - args.dev = actual_platform; - args.device = actual_formfactor; - } - args.limit = limit; - if (actual_platform === 'firefoxos' && - actual_platform === args.dev && - actual_formfactor === args.device && - _.indexOf(ENDPOINTS_WITH_FEATURE_PROFILE, endpoint_name) >= 0) { - // Include feature profile, but only if specific conditions are met: - // - We are using a Firefox OS device - // - We aren't showing 'all apps' - // - We are dealing with an endpoint that knows how to handle feature profiles - args.pro = feature_profile; - } - return args; - } - - return { - api_args: api_args, - default_feature_profile: default_feature_profile, - DEVICE_CHOICES: DEVICE_CHOICES, - device_filter_name: device_filter_name, - feature_profile: feature_profile, - limit: limit, - is_preference_selected: is_preference_selected, - set_preference: set_preference - }; -}); diff --git a/src/media/js/compatibility_filtering_select.js b/src/media/js/compatibility_filtering_select.js deleted file mode 100644 index fbc104575e..0000000000 --- a/src/media/js/compatibility_filtering_select.js +++ /dev/null @@ -1,19 +0,0 @@ -define('compatibility_filtering_select', - ['compatibility_filtering', 'jquery', 'core/log', 'core/views', 'core/z'], - function(compatibility_filtering, $, log, views, z) { - var logger = log('compatibility_filtering_select'); - - z.body.on('change', '#compatibility_filtering', function() { - var value = $(this[this.selectedIndex]).val(); - var endpoint_name = $('#compatibility_filtering_endpoint_name').val(); - - if (endpoint_name) { - // Override stored preferences with the new ones and reload the - // view to take changes into account. - compatibility_filtering.set_preference(endpoint_name, value); - views.reload(); - } else { - logger.error('Tried to change filtering preferences w/o endpoint'); - } - }); -}); diff --git a/src/media/js/helpers_local.js b/src/media/js/helpers_local.js index 03be26d282..c70b357f14 100644 --- a/src/media/js/helpers_local.js +++ b/src/media/js/helpers_local.js @@ -1,9 +1,9 @@ define('helpers_local', - ['apps', 'categories', 'compatibility_filtering', 'content-ratings', + ['apps', 'categories', 'compat_filter', 'content-ratings', 'core/format', 'core/helpers', 'core/models', 'core/nunjucks', 'core/settings', 'core/urls', 'core/utils', 'core/z', 'feed', 'regions', 'user_helpers', 'utils_local'], - function(apps, categories, compatibility_filtering, iarc, + function(apps, categories, compat_filter, iarc, format, base_helpers, models, nunjucks, settings, urls, utils, z, feed, regions, user_helpers, utils_local) { @@ -94,14 +94,14 @@ define('helpers_local', /* Global variables, provided in default context. */ globals.CATEGORIES = categories; - globals.DEVICE_CHOICES = compatibility_filtering.DEVICE_CHOICES; + globals.DEVICE_CHOICES = compat_filter.DEVICE_CHOICES; globals.feed = feed; globals.iarc_names = iarc.names; globals.NEWSLETTER_LANGUAGES = settings.NEWSLETTER_LANGUAGES; globals.REGIONS = regions.REGION_CHOICES_SLUG; globals.user_helpers = user_helpers; globals.PLACEHOLDER_ICON = urls.media('fireplace/img/icons/placeholder.svg'); - globals.compatibility_filtering = compatibility_filtering; + globals.compat_filter = compat_filter; /* Helpers functions, provided in the default context. */ function indexOf(arr, val) { diff --git a/src/media/js/init.js b/src/media/js/init.js index 989d175279..ba71e94ecb 100644 --- a/src/media/js/init.js +++ b/src/media/js/init.js @@ -1,19 +1,20 @@ define('init', - ['compatibility_filtering', 'core/cache', 'core/init', 'core/log', - 'core/router', 'document-register-element', 'helpers_local', 'rewriters', - 'route_api_args', 'user_helpers'], - function(compatibility_filtering, cache, init, log, - router, documentRegisterElement, helpers_local, rewriters, - user_helpers) { - - log('init').log('dependencies loaded'); + ['compat_filter', 'core/cache', 'core/init', 'core/router', + 'document-register-element', 'helpers_local', 'rewriters', + 'user_helpers'], + function(compatFilter, cache, init, router, + documentRegisterElement, helpers_local, rewriters, + userHelpers) { rewriters.forEach(function(rewriter) { cache.addRewriter(rewriter); }); - // Put any code that needs to run to initialize the app here or in the - // dependencies. - - log('init').log('done'); + // Put code to initialize the app either here or in the dependencies. + router.api.addProcessor(function(endpoint) { + var args = compatFilter.apiArgs(endpoint); + args.region = userHelpers.region(undefined, true); + args.carrier = userHelpers.carrier(); + return args; + }); }); diff --git a/src/media/js/main.js b/src/media/js/main.js index 53808e946d..f7081bfbc1 100644 --- a/src/media/js/main.js +++ b/src/media/js/main.js @@ -18,7 +18,6 @@ require([ 'core/cache', 'core/capabilities', 'consumer_info', - 'compatibility_filtering_select', 'content-ratings', 'flipsnap', 'core/forms', diff --git a/src/media/js/reviews.js b/src/media/js/reviews.js index d48bd284dd..03af4e2283 100644 --- a/src/media/js/reviews.js +++ b/src/media/js/reviews.js @@ -1,5 +1,5 @@ define('reviews', - ['compatibility_filtering', 'core/cache', 'core/capabilities', + ['compat_filter', 'core/cache', 'core/capabilities', 'core/forms', 'jquery', 'core/l10n', 'core/login', 'core/models', 'core/notification', 'core/nunjucks', 'ratingwidget', 'core/requests', 'core/settings', 'underscore', 'core/utils', 'core/urls', 'core/user', 'core/z'], diff --git a/src/media/js/route_api_args.js b/src/media/js/route_api_args.js deleted file mode 100644 index c52bfff17e..0000000000 --- a/src/media/js/route_api_args.js +++ /dev/null @@ -1,13 +0,0 @@ -define('route_api_args', - ['compatibility_filtering', 'core/router', 'user_helpers'], - function(compatibility_filtering, router, user_helpers) { - - router.api.addProcessor(function(endpoint) { - // Ask compatibility_filtering module for the base args to use, then - // add a few extra generic ones. - var args = compatibility_filtering.api_args(endpoint); - args.region = user_helpers.region(undefined, true); - args.carrier = user_helpers.carrier(); - return args; - }); -}); diff --git a/src/media/js/routes.js b/src/media/js/routes.js index 0e92372fa9..7f9a0fec70 100644 --- a/src/media/js/routes.js +++ b/src/media/js/routes.js @@ -41,7 +41,7 @@ define('routes', 'app': '/api/v2/fireplace/app/{0}/?cache=1&vary=0', 'app/privacy': '/api/v2/apps/app/{0}/privacy/?cache=1&vary=0', 'app_abuse': '/api/v2/abuse/app/', - 'category_landing': '/api/v2/fireplace/search/?cat={0}&cache=1&vary=0', + 'category': '/api/v2/fireplace/search/?cat={0}&cache=1&vary=0', // consumer_info should be cached by the browser, never served by the // CDN, we can keep the Vary header. 'consumer_info': '/api/v2/fireplace/consumer-info/?cache=1', @@ -56,9 +56,6 @@ define('routes', 'langpacks': '/api/v2/langpacks/?cache=1&vary=0', 'login': '/api/v2/account/login/', 'logout': '/api/v2/account/logout/', - // New / Popular pages use a regular search API call, but we need - // device filtering depending on the page group, so we need an alias. - 'new_popular_search': '/api/v2/fireplace/search/?cache=1&vary=0', 'newsletter': '/api/v2/account/newsletter/', 'payments_status': '/api/v2/webpay/status/{0}/', 'prepare_nav_pay': '/api/v2/webpay/prepare/', diff --git a/src/media/js/views/category.js b/src/media/js/views/category.js index 38bb75d13a..fa9a792eee 100644 --- a/src/media/js/views/category.js +++ b/src/media/js/views/category.js @@ -23,8 +23,7 @@ define('views/category', builder.start('category.html', { category: slug, category_name: name, - endpoint: urls.api.unsigned.url('category_landing', [slug], params), - endpoint_name: 'category_landing', + endpoint: urls.api.unsigned.url('category', [slug], params), sort: params.sort, }); diff --git a/src/media/js/views/debug.js b/src/media/js/views/debug.js index e304c83fdf..9c7ae951c9 100644 --- a/src/media/js/views/debug.js +++ b/src/media/js/views/debug.js @@ -1,8 +1,8 @@ define('views/debug', - ['core/cache', 'core/capabilities', 'compatibility_filtering', 'core/log', + ['core/cache', 'core/capabilities', 'compat_filter', 'core/log', 'core/models', 'core/notification', 'core/requests', 'core/settings', 'core/storage', 'core/user', 'core/utils', 'core/z', 'regions'], - function(cache, capabilities, compatibility_filtering, log, + function(cache, capabilities, compatFilter, log, models, notification, requests, settings, storage, user, utils, z, regions) { 'use strict'; @@ -73,7 +73,7 @@ define('views/debug', capabilities: capabilities, settings: settings, report_version: 1.0, - profile: compatibility_filtering.feature_profile + profile: compat_filter.feature_profile })}; var ashesUrl = 'https://ashes.paas.allizom.org/post_report'; @@ -126,7 +126,7 @@ define('views/debug', carriers: require('mobilenetwork').carriers, filter: log.filter, persistent_logs: log.persistent.all, - profile: compatibility_filtering.feature_profile, + profile: compatFilter.feature_profile, recent_logs: log.get_recent(100), request_cache: storage.getItem('request_cache') || {} }); diff --git a/src/media/js/views/debug_features.js b/src/media/js/views/debug_features.js index 30e37a7473..4197a56191 100644 --- a/src/media/js/views/debug_features.js +++ b/src/media/js/views/debug_features.js @@ -1,17 +1,17 @@ define('views/debug_features', - ['compatibility_filtering', 'core/settings', 'core/urls'], - function(compatibility_filtering, settings, urls) { + ['compat_filter', 'core/settings', 'core/urls'], + function(compat_filter, settings, urls) { 'use strict'; return function(builder, args, params) { params = params || {}; // Force feature profile to be sent even if it's blacklisted. - params.pro = compatibility_filtering.feature_profile; + params.pro = compat_filter.feature_profile; builder.start('debug_features.html', { endpoint: urls.api.unsigned.url('features', [], params), - profile: compatibility_filtering.feature_profile + profile: compat_filter.feature_profile }); }; }); diff --git a/src/media/js/views/feedback.js b/src/media/js/views/feedback.js index ed77476b03..1048b9e49b 100644 --- a/src/media/js/views/feedback.js +++ b/src/media/js/views/feedback.js @@ -1,7 +1,7 @@ define('views/feedback', - ['core/capabilities', 'compatibility_filtering', 'core/forms', 'core/l10n', 'linefit', + ['core/capabilities', 'compat_filter', 'core/forms', 'core/l10n', 'linefit', 'core/notification', 'core/requests', 'templates', 'core/urls', 'core/utils', 'core/z'], - function(caps, compatibility_filtering, forms, l10n, linefit, + function(caps, compat_filter, forms, l10n, linefit, notification, requests, nunjucks, urls, utils, z) { var gettext = l10n.gettext; var notify = notification.notification; @@ -13,7 +13,7 @@ define('views/feedback', chromeless: caps.chromeless ? 'Yes' : 'No', feedback: $this.find('[name="feedback"]').val(), from_url: window.location.pathname, - profile: compatibility_filtering.feature_profile + profile: compat_filter.feature_profile }); forms.toggleSubmitFormState($this); diff --git a/src/media/js/views/new.js b/src/media/js/views/new.js index e0879d09a9..9d1f2424c7 100644 --- a/src/media/js/views/new.js +++ b/src/media/js/views/new.js @@ -12,7 +12,7 @@ define('views/new', builder.z('title', title); builder.start('app_list.html', { - endpoint_name: 'new_popular_search', + endpoint_name: 'search', sort: 'reviewed', source: 'new', title: title diff --git a/src/media/js/views/popular.js b/src/media/js/views/popular.js index 82e339d7ad..44b889b428 100644 --- a/src/media/js/views/popular.js +++ b/src/media/js/views/popular.js @@ -12,7 +12,7 @@ define('views/popular', builder.z('title', title); builder.start('app_list.html', { - endpoint_name: 'new_popular_search', + endpoint_name: 'search', source: 'popular', title: title }); diff --git a/src/templates/_includes/app_list_filters.html b/src/templates/_includes/app_list_filters.html index 47605ac9ec..0aeef86e6b 100644 --- a/src/templates/_includes/app_list_filters.html +++ b/src/templates/_includes/app_list_filters.html @@ -11,7 +11,7 @@ {{ _('New') }} - {% include "compatibility_filtering.html" %} + {% include "compat_filter.html" %}
{{ _('Display as') }} diff --git a/src/templates/compat_filter.html b/src/templates/compat_filter.html new file mode 100644 index 0000000000..5369645a0a --- /dev/null +++ b/src/templates/compat_filter.html @@ -0,0 +1,18 @@ +
+
+
+ +
+ +
+
+
+
diff --git a/src/templates/compatibility_filtering.html b/src/templates/compatibility_filtering.html deleted file mode 100644 index 69de10b8b3..0000000000 --- a/src/templates/compatibility_filtering.html +++ /dev/null @@ -1,29 +0,0 @@ -
-
-
- - -
- -
-
-
-
diff --git a/src/templates/langpacks.html b/src/templates/langpacks.html index 26bde2b4eb..a8e4d67547 100644 --- a/src/templates/langpacks.html +++ b/src/templates/langpacks.html @@ -11,7 +11,7 @@

{{ title }}

{{ subtitle }}

- {% defer (url=anonApiParams(endpoint_name, params), pluck='objects', paginate='.app-list') %} + {% defer (url=anonApiParams('langpacks', params), pluck='objects', paginate='.app-list') %}