Ghost/ghost/admin/app/components/gh-publishmenu-draft.js
Kevin Ansfield 89f9516f04 Added "created at" members filters
refs https://github.com/TryGhost/Team/issues/1390

- added `membersTimeFilters` feature flag and labs toggle
- added `<GhDatePicker>` component that lifts functionality from the `<GhDateTimePicker>` component
  - `<GhDateTimePicker>` has not yet been refactored to use the new component internally as there are some odd/complex interactions with error handling with it's existing use-cases and they are in critical publishing paths so the refactor doesn't belong as part of this change
- added "Created at" filter type to members filters
  - uses new date picker component for input value
  - has "before", "on or before", "after", "on or after" operators
  - "on" and "not on" operators were skipped as they require two NQL statements to represent, breaking the current 1:1 statement:filter approach used in the NQL-based query param parsing
2022-03-02 21:59:48 +00:00

124 lines
3.7 KiB
JavaScript

import Component from '@glimmer/component';
import moment from 'moment';
import {action} from '@ember/object';
import {isEmpty} from '@ember/utils';
import {inject as service} from '@ember/service';
import {task} from 'ember-concurrency';
import {tracked} from '@glimmer/tracking';
export default class GhPublishMenuDraftComponent extends Component {
@service config;
@service feature;
@service session;
@service settings;
@service store;
@tracked totalMemberCount = 0;
// used to set minDate in datepicker
_minDate = null;
_publishedAtBlogTZ = null;
get disableEmailOption() {
// TODO: remove owner or admin check when editors can count members
return this.session.user.isAdmin && (this.totalMemberCount === 0 || this.countTotalMembersTask.isRunning);
}
get showEmailSection() {
return this.args.canSendEmail && this.args.distributionAction !== 'publish';
}
constructor() {
super(...arguments);
this.args.post.set('publishedAtBlogTZ', this.args.post.publishedAtUTC);
this._updateDatesForSaveType(this.args.saveType);
}
@action
setSaveType(type) {
if (this.args.saveType !== type) {
this._updateDatesForSaveType(type);
this.args.setSaveType(type);
this.args.post.validate();
}
}
@action
setDistributionAction(type) {
this.args.setDistributionAction(type);
}
@action
setDate(date) {
let post = this.args.post;
let dateString = moment(date).format('YYYY-MM-DD');
post.set('publishedAtBlogDate', dateString);
return post.validate();
}
@action
setTime(time) {
let post = this.args.post;
post.set('publishedAtBlogTime', time);
return post.validate();
}
// the date-time-picker component has it's own error handling for
// invalid date and times but in this case we want the values to make it
// to the model to make that invalid
@action
dateInputDidError(date) {
this.setDate(date);
}
@action
timeInputDidError(time) {
this.setTime(time);
}
@task
*countTotalMembersTask() {
const user = yield this.session.user;
if (user.isAdmin) {
const result = yield this.store.query('member', {limit: 1, filter: 'subscribed:true'});
this.totalMemberCount = result.meta.pagination.total;
}
}
_updateDatesForSaveType(type) {
let hasDateError = !isEmpty(this.args.post.errors.errorsFor('publishedAtBlogDate'));
let hasTimeError = !isEmpty(this.args.post.errors.errorsFor('publishedAtBlogTime'));
let minDate = this._getMinDate();
this._minDate = minDate;
// when publish: switch to now to avoid validation errors
// when schedule: switch to last valid or new minimum scheduled date
if (type === 'publish') {
if (!hasDateError && !hasTimeError) {
this._publishedAtBlogTZ = this.args.post.publishedAtBlogTZ;
} else {
this._publishedAtBlogTZ = this.args.post.publishedAtUTC;
}
this.args.post.set('publishedAtBlogTZ', this.args.post.publishedAtUTC);
} else {
if (!this._publishedAtBlogTZ || moment(this._publishedAtBlogTZ).isBefore(minDate)) {
this.args.post.set('publishedAtBlogTZ', minDate);
} else {
this.args.post.set('publishedAtBlogTZ', this._publishedAtBlogTZ);
}
}
}
// API only accepts dates at least 2 mins in the future, default the
// scheduled date 5 mins in the future to avoid immediate validation errors
_getMinDate() {
return moment.utc().add(5, 'minutes');
}
}