+

Filter deprecations by version range

- To: - {{#x-select data-test-select-to=true value=selectedTo action=(action (mut to)) as |xs|}} - {{#each toVersions as |version|}} - {{#xs.option value=version}} - {{version}} - {{/xs.option}} - {{/each}} - {{/x-select}} + + From: + {{#x-select data-test-select-from=true value=selectedFrom action=(action (mut from)) as |xs|}} + {{#each fromVersions as |version|}} + {{#xs.option value=version}} + {{version}} + {{/xs.option}} + {{/each}} + {{/x-select}} + - Number of deprecations: {{filteredDeprecations.length}} + + To: + {{#x-select data-test-select-to=true value=selectedTo action=(action (mut to)) as |xs|}} + {{#each toVersions as |version|}} + {{#xs.option value=version}} + {{version}} + {{/xs.option}} + {{/each}} + {{/x-select}} + {{#each filteredDeprecations as |deprecation|}} {{deprecation-article From af5e821724daa350679da5f93e025361d225bae3 Mon Sep 17 00:00:00 2001 From: Chris Freeman Date: Thu, 27 Sep 2018 15:14:33 -0500 Subject: [PATCH 08/10] comments and cleanup --- app/controllers/filters.js | 37 +++++++++++++------ app/routes/filters.js | 8 ++++ .../acceptance/filtering-by-versions-test.js | 2 +- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/app/controllers/filters.js b/app/controllers/filters.js index 9d87f0c9..c70a223a 100644 --- a/app/controllers/filters.js +++ b/app/controllers/filters.js @@ -8,6 +8,8 @@ export default Controller.extend({ from: null, to: null, + // The model is initially an array of arrays, one for each project/version pair + // (e.g. `ember-data-2.x`), so we need to flatten it to make filtering easier flattenedDeprecations: computed('model.[]', function() { return this.model.reduce((acc, elem) => { let rawArray = elem.toArray(); @@ -15,6 +17,8 @@ export default Controller.extend({ }, []); }), + // Create a deduped list of semver-coerced versions from all the deprecations that were loaded. + // We'll use this as the basis for our filter dropdowns versions: computed('flattenedDeprecations.@each.since', function() { let versionsList = this.flattenedDeprecations.reduce((acc, elem) => { let coerced = semver.coerce(elem.since); @@ -30,40 +34,49 @@ export default Controller.extend({ return versionsList.sort(); }), + // `fromVersions` is the list of versions that the `from` dropdown uses. It's restricted so that + // you can't select a `from` version that is higher than your `to` version. fromVersions: computed('versions.[]', 'to', function() { return this.to ? this.versions.filter(version => semver.lt(version, this.to)) : this.versions; }), + // `toVersions` is the list of versions that the `to` dropdown uses. It's restricted so that + // you can't select a `to` version that is lower than your `from` version. toVersions: computed('versions.[]', 'from', function() { return this.from ? this.versions.filter(version => semver.gt(version, this.from)) : this.versions; }), + // This will usually just mirror the `from` query param, but in case that param is empty, + // this lets us just use the lowest possible version as a default selectedFrom: computed('from', function() { - if (!this.from) { - return this.get('versions.firstObject'); - } - - return this.from; + return this.from || this.get('versions.firstObject'); }), + // This will usually just mirror the `to` query param, but in case that param is empty, + // this lets us just use the highest possible version as a default selectedTo: computed('to', function() { - if(!this.to) { - return this.get('versions.lastObject'); - } - - return this.to; + return this.to || this.get('versions.lastObject'); }), - filteredDeprecations: computed('flattenedDeprecations', 'from', 'to', function() { let deprecations = this.flattenedDeprecations; return deprecations.filter(deprecation => { - return (deprecation.since >= this.selectedFrom) && (deprecation.since <= this.selectedTo); + let coerced = semver.coerce(deprecation.since); + let version = coerced && coerced.version; + + // In case we're not able to get an actual semver version (like, if the version is a bunch + // of words or something) we just return false immediately rather than trying to pass it + // into the `semver` functions. + if (!version) { + return false; + } + + return semver.gte(version, this.selectedFrom) && semver.lte(version, this.selectedTo); }); }), }); diff --git a/app/routes/filters.js b/app/routes/filters.js index 25b77d4f..fa02c28c 100644 --- a/app/routes/filters.js +++ b/app/routes/filters.js @@ -4,6 +4,12 @@ import { all } from 'rsvp'; export default Route.extend({ model() { + // Since we currently load the deprecation files in project/version buckets + // (e.g. ember-data-2.x), we need to instead get ahold of all of the deprecations at once + // so we can do more fine-grained filtering. + + // Read the `contentFolders` config used to serve all the markdown files as static JSON assets + // and transform them in `store.query` param objects let contentFolders = config.contentFolders.map(folder => { let [ path, version ] = folder.split('/'); @@ -13,6 +19,8 @@ export default Route.extend({ }; }); + // Fire off queries for all the different project/version combinations. + // These will be flattened and filtered in the controller. let queryObjectPromises = contentFolders.map(version => { return this.store.query('content', version); }); diff --git a/tests/acceptance/filtering-by-versions-test.js b/tests/acceptance/filtering-by-versions-test.js index 53bc5072..f5bc440c 100644 --- a/tests/acceptance/filtering-by-versions-test.js +++ b/tests/acceptance/filtering-by-versions-test.js @@ -1,5 +1,5 @@ import { module, test } from 'qunit'; -import { visit, currentURL, findAll, pauseTest } from '@ember/test-helpers'; +import { visit, currentURL, findAll } from '@ember/test-helpers'; import { setupApplicationTest } from 'ember-qunit'; import { select } from 'deprecation-app/tests/helpers/x-select'; From 7bfe3f688364ee6fb1c839303b2dce6d7368ca6e Mon Sep 17 00:00:00 2001 From: NullVoxPopuli Date: Tue, 4 Jun 2019 10:42:48 -0400 Subject: [PATCH 09/10] address deprecation --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index a9a02e7a..7f10af81 100644 --- a/package.json +++ b/package.json @@ -61,14 +61,14 @@ "ember-set-body-class": "^0.4.2", "ember-source": "~3.9.1", "ember-styleguide": "2.5.0", + "ember-test-selectors": "^1.0.0", "ember-tether": "^1.0.0", + "emberx-select": "^3.1.1", "eslint-plugin-ember": "^6.5.1", "loader.js": "^4.7.0", "prember": "^1.0.2", "qunit-dom": "^0.8.5", "sass": "^1.20.3", - "emberx-select": "^3.1.1", - "ember-test-selectors": "^1.0.0", "semver": "^5.5.1", "semver-compare": "^1.0.0" }, From d7832094c841bf7caf74643fbfc83f895a875ef2 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli Date: Tue, 4 Jun 2019 10:50:33 -0400 Subject: [PATCH 10/10] cleanup --- .eslintrc.js | 3 +-- config/environment.js | 8 +++++--- ember-cli-build.js | 10 +++++++-- lib/content-docs-generator/index.js | 32 +++++++++++------------------ 4 files changed, 26 insertions(+), 27 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 5c0021ad..5397fb76 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -27,8 +27,7 @@ module.exports = { 'testem.js', 'blueprints/*/index.js', 'config/**/*.js', - 'lib/*/index.js', - 'content-folder-list.js' + 'lib/*/index.js' ], parserOptions: { sourceType: 'script', diff --git a/config/environment.js b/config/environment.js index 4f238316..ae661d80 100644 --- a/config/environment.js +++ b/config/environment.js @@ -1,5 +1,4 @@ "use strict"; -const contentFolders = require('../content-folder-list'); module.exports = function(environment) { let ENV = { @@ -25,10 +24,13 @@ module.exports = function(environment) { }, fastboot: { - hostWhitelist: ["localhost:4200"] + hostWhitelist: [/localhost:\d+/] }, - contentFolders, + algolia: { + algoliaId: 'Y1OMR4C7MF', + algoliaKey: '5d01c83734dc36754d9e94cbf6f8964d' + }, }; if (environment === 'development') { diff --git a/ember-cli-build.js b/ember-cli-build.js index 6a420b21..779a324c 100644 --- a/ember-cli-build.js +++ b/ember-cli-build.js @@ -1,7 +1,6 @@ "use strict"; const EmberApp = require("ember-cli/lib/broccoli/ember-app"); -const contentFolders = require('./content-folder-list'); module.exports = function(defaults) { let prepend = ""; @@ -42,7 +41,14 @@ module.exports = function(defaults) { importBootstrapCSS: false }, - contentFolders + // TODO: remove once this issue is fixed https://github.com/ember-cli/ember-cli/issues/8075 + 'ember-cli-uglify': { + uglify: { + compress: { + collapse_vars: false + } + } + }, }); app.import("node_modules/semver-compare/index.js", { diff --git a/lib/content-docs-generator/index.js b/lib/content-docs-generator/index.js index 72048a20..d5946da4 100644 --- a/lib/content-docs-generator/index.js +++ b/lib/content-docs-generator/index.js @@ -3,34 +3,26 @@ const StaticSiteJson = require('broccoli-static-site-json'); const BroccoliMergeTrees = require('broccoli-merge-trees'); -module.exports = { - name: 'content-docs-generator', +const contentFolders = ['ember/v1', 'ember/v2', 'ember/v3', 'ember-data/v2', 'ember-cli/v2']; - included(parent) { - this._super.included && this._super.included.apply(this, arguments); +const jsonTrees = contentFolders.map((type) => new StaticSiteJson(`content/${type}`, { + attributes: ['title', 'since', 'until'], + type: 'contents', + collections: [{ + src: `content/${type}`, + output: `${type.replace(/\//, '-')}.x.json`, + }] +})); - if (parent.options && parent.options.contentFolders) { - this.contentFolders = parent.options.contentFolders; - } - }, +module.exports = { + name: 'content-docs-generator', isDevelopingAddon() { return true; }, treeForPublic() { - let jsonTrees = this._createJsonTrees(); return new BroccoliMergeTrees([...jsonTrees]) - }, - - _createJsonTrees() { - return this.contentFolders.map((type) => new StaticSiteJson(`content/${type}`, { - attributes: ['title', 'since', 'until'], - type: 'contents', - collections: [{ - src: `content/${type}`, - output: `${type.replace(/\//, '-')}.x.json`, - }] - })); } }; +