From ee8b9452a5c2debe5b8057924675130eb57c6f1f Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Thu, 3 Mar 2022 19:38:28 +0000 Subject: [PATCH] Added "Subscription start date" members filter no issue - added datepicker based filter for the start date of paid subscriptions - updated table to add "Start date" column when filtered, showing the paid subscription's start date --- .../gh-members-list-item-column.hbs | 10 +++ .../app/components/members/filter-value.hbs | 7 ++ ghost/admin/app/components/members/filter.js | 11 +++ .../tests/acceptance/members/filter-test.js | 79 +++++++++++++++++++ 4 files changed, 107 insertions(+) diff --git a/ghost/admin/app/components/gh-members-list-item-column.hbs b/ghost/admin/app/components/gh-members-list-item-column.hbs index cf1e5f91e8..db6395a1b8 100644 --- a/ghost/admin/app/components/gh-members-list-item-column.hbs +++ b/ghost/admin/app/components/gh-members-list-item-column.hbs @@ -71,4 +71,14 @@ - {{/if}} + +{{else if (eq @filterColumn 'subscriptions.start_date')}} + + {{#if (not (is-empty @member.subscriptions.firstObject.start_date))}} + {{moment-format (moment-site-tz @member.subscriptions.firstObject.start_date) "D MMM YYYY"}} +
{{moment-from-now @member.subscriptions.firstObject.start_date}}
+ {{else}} + - + {{/if}} +
{{/if}} diff --git a/ghost/admin/app/components/members/filter-value.hbs b/ghost/admin/app/components/members/filter-value.hbs index 871208f087..19ec0375b7 100644 --- a/ghost/admin/app/components/members/filter-value.hbs +++ b/ghost/admin/app/components/members/filter-value.hbs @@ -136,6 +136,13 @@ {{svg-jar "arrow-down-small"}} +{{else if (eq @filter.type 'subscriptions.start_date')}} + + {{else}} ='2022-03-02 00:00'+created_at:<'2022-03-03 00:00' + // {label: 'on', name: 'is'}, + // {label: 'not on', name: 'is-not'}, + {label: 'after', name: 'is-greater'}, + {label: 'on or after', name: 'is-or-greater'} + ], email_count: [ {label: 'is', name: 'is'}, {label: 'is greater than', name: 'is-greater'}, diff --git a/ghost/admin/tests/acceptance/members/filter-test.js b/ghost/admin/tests/acceptance/members/filter-test.js index 886edc0a15..338fcde369 100644 --- a/ghost/admin/tests/acceptance/members/filter-test.js +++ b/ghost/admin/tests/acceptance/members/filter-test.js @@ -764,6 +764,85 @@ describe('Acceptance: Members filtering', function () { expect(find(valueInput)).to.have.value('2022-02-28'); }); + it('can filter by paid subscription start date', async function () { + clock = sinon.useFakeTimers({ + now: moment('2022-03-01 09:00:00.000Z').toDate(), + shouldAdvanceTime: true + }); + + // add some members to filter + this.server.createList('member', 3, {subscriptions: [{start_date: moment('2022-02-01 12:00:00').format('YYYY-MM-DD HH:mm:ss')}]}); + this.server.createList('member', 4, {subscriptions: [{start_date: moment('2022-02-05 12:00:00').format('YYYY-MM-DD HH:mm:ss')}]}); + this.server.createList('member', 2, {subscriptions: []}); + + await visit('/members'); + + expect(findAll('[data-test-list="members-list-item"]').length, '# of initial member rows') + .to.equal(9); + + await click('[data-test-button="members-filter-actions"]'); + + const filterSelect = `[data-test-members-filter="0"]`; + const typeSelect = `${filterSelect} [data-test-select="members-filter"]`; + const operatorSelect = `${filterSelect} [data-test-select="members-filter-operator"]`; + + expect(find(`${filterSelect} [data-test-select="members-filter"] option[value="subscriptions.start_date"]`), 'subscriptions.start_date filter option').to.exist; + + await fillIn(typeSelect, 'subscriptions.start_date'); + + // has the right operators + const operatorOptions = findAll(`${operatorSelect} option`); + expect(operatorOptions).to.have.length(4); + expect(operatorOptions[0]).to.have.value('is-less'); + expect(operatorOptions[1]).to.have.value('is-or-less'); + // expect(operatorOptions[2]).to.have.value('is'); + // expect(operatorOptions[3]).to.have.value('is-not'); + expect(operatorOptions[2]).to.have.value('is-greater'); + expect(operatorOptions[3]).to.have.value('is-or-greater'); + + const valueDateInput = `${filterSelect} [data-test-input="members-filter-value"] [data-test-date-picker-input]`; + const valueDatePicker = `${filterSelect} [data-test-input="members-filter-value"]`; + + // operator defaults to "on or before" + expect(find(operatorSelect)).to.have.value('is-or-less'); + + // value defaults to today's date + expect(find(valueDateInput)).to.have.value('2022-03-01'); + expect(findAll('[data-test-list="members-list-item"]').length, '# of filtered member rows - default') + .to.equal(7); + + // can change date + await datepickerSelect(valueDatePicker, moment.utc('2022-02-03').toDate()); + expect(findAll('[data-test-list="members-list-item"]').length, '# of filtered member rows - 2022-02-03') + .to.equal(3); + + // can change operator + await fillIn(operatorSelect, 'is-greater'); + expect(findAll('[data-test-list="members-list-item"]').length, '# of filtered member rows - is-greater') + .to.equal(4); + + // can populate filter from URL + // TODO: leaving screen is needed, suggests component is not fully reactive and needs to be torn down. + // - see constructor + await visit(`/`); + const filter = encodeURIComponent(`subscriptions.start_date:<='2022-02-01 23:59:59'`); + await visit(`/members?filter=${filter}`); + await click('[data-test-button="members-filter-actions"]'); + + expect(find(typeSelect), 'type select - from URL').to.have.value('subscriptions.start_date'); + expect(find(operatorSelect), 'operator select - from URL').to.have.value('is-or-less'); + expect(find(valueDateInput), 'date input - from URL').to.have.value('2022-02-01'); + + expect(findAll('[data-test-list="members-list-item"]').length, '# of filtered member rows - from URL') + .to.equal(3); + + // it adds extra column to table + expect(find('[data-test-table-column="subscriptions.start_date"]')).to.exist; + expect(findAll('[data-test-table-data="subscriptions.start_date"]').length).to.equal(3); + expect(find('[data-test-table-data="subscriptions.start_date"]')).to.contain.text('1 Feb 2022'); + expect(find('[data-test-table-data="subscriptions.start_date"]')).to.contain.text('a month ago'); + }); + it('can handle multiple filters', async function () { // add some members to filter this.server.createList('member', 1, {subscriptions: [{status: 'active'}]});