diff --git a/app/assets/javascripts/discourse/components/date-input.js.es6 b/app/assets/javascripts/discourse/components/date-input.js.es6 index b095781b82d..7d56b964a20 100644 --- a/app/assets/javascripts/discourse/components/date-input.js.es6 +++ b/app/assets/javascripts/discourse/components/date-input.js.es6 @@ -26,6 +26,10 @@ export default Component.extend({ } else { this._loadPikadayPicker(container); } + + if (this.date && this._picker) { + this._picker.setDate(this.date, true); + } }, didUpdateAttrs() { @@ -71,6 +75,9 @@ export default Component.extend({ picker.destroy = () => { /* do nothing for native */ }; + picker.setDate = date => { + picker.value = date; + }; this._picker = picker; }, diff --git a/app/assets/javascripts/discourse/components/date-time-input-range.js.es6 b/app/assets/javascripts/discourse/components/date-time-input-range.js.es6 index ec048ec730d..52438ffd949 100644 --- a/app/assets/javascripts/discourse/components/date-time-input-range.js.es6 +++ b/app/assets/javascripts/discourse/components/date-time-input-range.js.es6 @@ -16,7 +16,7 @@ export default Component.extend({ toPanelActive: equal("currentPanel", "to"), _valid(state) { - if (state.to < state.from) { + if (state.to && state.from && state.to < state.from) { return I18n.t("date_time_picker.errors.to_before_from"); } diff --git a/app/assets/javascripts/discourse/components/date-time-input.js.es6 b/app/assets/javascripts/discourse/components/date-time-input.js.es6 index e9c7ad73975..392dc5dac0f 100644 --- a/app/assets/javascripts/discourse/components/date-time-input.js.es6 +++ b/app/assets/javascripts/discourse/components/date-time-input.js.es6 @@ -7,11 +7,11 @@ export default Component.extend({ showTime: true, _hours: computed("date", function() { - return this.date ? this.date.getHours() : null; + return this.date && this.showTime ? this.date.getHours() : null; }), _minutes: computed("date", function() { - return this.date ? this.date.getMinutes() : null; + return this.date && this.showTime ? this.date.getMinutes() : null; }), actions: { diff --git a/app/assets/javascripts/discourse/controllers/review-index.js.es6 b/app/assets/javascripts/discourse/controllers/review-index.js.es6 index df95f33cfbe..0c9f090aa43 100644 --- a/app/assets/javascripts/discourse/controllers/review-index.js.es6 +++ b/app/assets/javascripts/discourse/controllers/review-index.js.es6 @@ -9,6 +9,8 @@ export default Controller.extend({ "category_id", "topic_id", "username", + "from_date", + "to_date", "sort_order" ], type: null, @@ -19,6 +21,8 @@ export default Controller.extend({ topic_id: null, filtersExpanded: false, username: "", + from_date: null, + to_date: null, sort_order: "priority", init(...args) { @@ -79,6 +83,15 @@ export default Controller.extend({ return filtersExpanded ? "chevron-up" : "chevron-down"; }, + setRange(range) { + if (range.from) { + this.set("from", new Date(range.from).toISOString().split("T")[0]); + } + if (range.to) { + this.set("to", new Date(range.to).toISOString().split("T")[0]); + } + }, + actions: { remove(ids) { if (!ids) { @@ -103,6 +116,8 @@ export default Controller.extend({ status: this.filterStatus, category_id: this.filterCategoryId, username: this.filterUsername, + from_date: this.filterFromDate, + to_date: this.filterToDate, sort_order: this.filterSortOrder }); this.send("refreshRoute"); diff --git a/app/assets/javascripts/discourse/routes/review-index.js.es6 b/app/assets/javascripts/discourse/routes/review-index.js.es6 index d5b2fad3701..2c08fa8ed5f 100644 --- a/app/assets/javascripts/discourse/routes/review-index.js.es6 +++ b/app/assets/javascripts/discourse/routes/review-index.js.es6 @@ -23,6 +23,8 @@ export default DiscourseRoute.extend({ filterPriority: meta.priority, reviewableTypes: meta.reviewable_types, filterUsername: meta.username, + filterFromDate: meta.from_date, + filterToDate: meta.to_date, filterSortOrder: meta.sort_order }); }, diff --git a/app/assets/javascripts/discourse/templates/review-index.hbs b/app/assets/javascripts/discourse/templates/review-index.hbs index 86799229f1b..76f2fe20627 100644 --- a/app/assets/javascripts/discourse/templates/review-index.hbs +++ b/app/assets/javascripts/discourse/templates/review-index.hbs @@ -59,6 +59,10 @@ {{/if}} +
+ {{date-time-input-range showFromTime=false showToTime=false from=filterFromDate to=filterToDate onChange=setRange}} +
+
{{i18n "review.order_by"}} {{combo-box value=filterSortOrder content=sortOrders}} diff --git a/app/assets/stylesheets/common/base/reviewables.scss b/app/assets/stylesheets/common/base/reviewables.scss index 6adae41eda5..701bdf440a3 100644 --- a/app/assets/stylesheets/common/base/reviewables.scss +++ b/app/assets/stylesheets/common/base/reviewables.scss @@ -121,6 +121,17 @@ .category-chooser { width: 100%; } + + .d-date-time-input-range { + width: inherit; + border: none; + padding: 0; + + .d-date-input { + flex: 1 1 auto; + border: 1px solid $primary-medium; + } + } } } diff --git a/app/controllers/reviewables_controller.rb b/app/controllers/reviewables_controller.rb index 2e9816bab10..47d65c1efd3 100644 --- a/app/controllers/reviewables_controller.rb +++ b/app/controllers/reviewables_controller.rb @@ -26,6 +26,8 @@ class ReviewablesController < ApplicationController topic_id: topic_id, priority: params[:priority], username: params[:username], + from_date: params[:from_date], + to_date: params[:to_date], type: params[:type], sort_order: params[:sort_order] } diff --git a/app/models/reviewable.rb b/app/models/reviewable.rb index 13157fa4442..f8a0398597e 100644 --- a/app/models/reviewable.rb +++ b/app/models/reviewable.rb @@ -406,7 +406,9 @@ class Reviewable < ActiveRecord::Base offset: nil, priority: nil, username: nil, - sort_order: nil + sort_order: nil, + from_date: nil, + to_date: nil ) min_score = Reviewable.min_score_for_priority(priority) @@ -434,6 +436,8 @@ class Reviewable < ActiveRecord::Base result = result.where(category_id: category_id) if category_id result = result.where(topic_id: topic_id) if topic_id result = result.where("score >= ?", min_score) if min_score > 0 + result = result.where("created_at >= ?", from_date) if from_date + result = result.where("created_at <= ?", to_date) if to_date # If a reviewable doesn't have a target, allow us to filter on who created that reviewable. if user_id diff --git a/package.json b/package.json index 11769181f3f..f667b5f05e7 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "install-peerdeps": "^1.10.2", "lodash-cli": "https://github.com/lodash-archive/lodash-cli.git", "pretender": "^1.6", - "prettier": "1.19.1", + "prettier": "^1.18.2", "puppeteer": "1.20", "qunit": "2.8.0", "route-recognizer": "^0.3.3", diff --git a/spec/requests/reviewables_controller_spec.rb b/spec/requests/reviewables_controller_spec.rb index dba29199b01..6ae6dfae8a8 100644 --- a/spec/requests/reviewables_controller_spec.rb +++ b/spec/requests/reviewables_controller_spec.rb @@ -168,6 +168,30 @@ describe ReviewablesController do expect(json_review['id']).to eq(reviewable.id) expect(json_review['user_id']).to eq(user.id) end + + context "supports filtering by range" do + let(:from) { 3.days.ago.strftime('%F') } + let(:to) { 1.day.ago.strftime('%F') } + + let(:reviewables) { ::JSON.parse(response.body)['reviewables'] } + + it 'returns an empty array when no reviewable matches the date range' do + reviewable = Fabricate(:reviewable) + + get "/review.json?from_date=#{from}&to_date=#{to}" + + expect(reviewables).to eq([]) + end + + it 'returns reviewable content that matches the date range' do + reviewable = Fabricate(:reviewable, created_at: 2.day.ago) + + get "/review.json?from_date=#{from}&to_date=#{to}" + + json_review = reviewables.first + expect(json_review['id']).to eq(reviewable.id) + end + end end context "#show" do diff --git a/yarn.lock b/yarn.lock index 2094f01b991..aa6379bef8b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2287,7 +2287,7 @@ pretender@^1.6: fake-xml-http-request "^1.6.0" route-recognizer "^0.3.3" -prettier@1.19.1: +prettier@^1.18.2: version "1.19.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==