mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
Fixed ember-test-selectors bound attributes deprecations
no issue - converted publish menu and `gh-tags-list-item` components to glimmer syntax so data attributes can be passed in via `...attributes` - added explicit `data-test-button` bound attribute to `gh-task-button` component - moved `modal-theme-warnings` auto-bound data attribute from JS file to explicit html attribute in template
This commit is contained in:
parent
c646e78fff
commit
7ab0db9be7
14 changed files with 273 additions and 320 deletions
|
@ -1,54 +1,55 @@
|
|||
<header class="gh-publishmenu-heading">Ready to publish your {{this.post.displayName}}?</header>
|
||||
<section class="gh-publishmenu-content">
|
||||
<div class="gh-publishmenu-section">
|
||||
<div class="gh-publishmenu-radio {{if (eq this.saveType "publish") "active"}}" {{action "setSaveType" "publish" on="click"}}>
|
||||
<div class="gh-publishmenu-radio-button" data-test-publishmenu-published-option></div>
|
||||
<div class="gh-publishmenu-radio-content">
|
||||
<div class="gh-publishmenu-radio-label">Set it live now</div>
|
||||
<div class="gh-publishmenu-radio-desc">Publish this {{this.post.displayName}} immediately</div>
|
||||
<div {{did-insert (fn this.setSaveType "publish")}} ...attributes>
|
||||
<header class="gh-publishmenu-heading">Ready to publish your {{@post.displayName}}?</header>
|
||||
<section class="gh-publishmenu-content">
|
||||
<div class="gh-publishmenu-section">
|
||||
<div class="gh-publishmenu-radio {{if (eq @saveType "publish") "active"}}" {{on "click" (fn this.setSaveType "publish")}}>
|
||||
<div class="gh-publishmenu-radio-button" data-test-publishmenu-published-option></div>
|
||||
<div class="gh-publishmenu-radio-content">
|
||||
<div class="gh-publishmenu-radio-label">Set it live now</div>
|
||||
<div class="gh-publishmenu-radio-desc">Publish this {{@post.displayName}} immediately</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gh-publishmenu-radio {{if (eq @saveType "schedule") "active"}}" {{on "click" (fn this.setSaveType "schedule")}}>
|
||||
<div class="gh-publishmenu-radio-button" data-test-publishmenu-scheduled-option></div>
|
||||
<div class="gh-publishmenu-radio-content">
|
||||
<div class="gh-publishmenu-radio-label">Schedule it for later</div>
|
||||
<GhDateTimePicker
|
||||
@date={{@post.publishedAtBlogDate}}
|
||||
@time={{@post.publishedAtBlogTime}}
|
||||
@setDate={{this.setDate}}
|
||||
@setTime={{this.setTime}}
|
||||
@setTypedDateError={{@setTypedDateError}}
|
||||
@errors={{@post.errors}}
|
||||
@dateErrorProperty="publishedAtBlogDate"
|
||||
@timeErrorProperty="publishedAtBlogTime"
|
||||
@minDate={{this._minDate}}
|
||||
@isActive={{eq @saveType "schedule"}}
|
||||
/>
|
||||
<div class="gh-publishmenu-radio-desc">Set automatic future publish date</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gh-publishmenu-radio {{if (eq this.saveType "schedule") "active"}}" {{action "setSaveType" "schedule" on="click"}}>
|
||||
<div class="gh-publishmenu-radio-button" data-test-publishmenu-scheduled-option></div>
|
||||
<div class="gh-publishmenu-radio-content">
|
||||
<div class="gh-publishmenu-radio-label">Schedule it for later</div>
|
||||
<GhDateTimePicker
|
||||
@date={{this.post.publishedAtBlogDate}}
|
||||
@time={{this.post.publishedAtBlogTime}}
|
||||
@setDate={{action "setDate"}}
|
||||
@setTime={{action "setTime"}}
|
||||
@setTypedDateError={{this.setTypedDateError}}
|
||||
@errors={{this.post.errors}}
|
||||
@dateErrorProperty="publishedAtBlogDate"
|
||||
@timeErrorProperty="publishedAtBlogTime"
|
||||
@minDate={{this._minDate}}
|
||||
@isActive={{eq this.saveType "schedule"}}
|
||||
/>
|
||||
<div class="gh-publishmenu-radio-desc">Set automatic future publish date</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if this.canSendEmail}}
|
||||
<div class="gh-publishmenu-section" {{did-insert (perform this.countTotalMembersTask)}}>
|
||||
<div class="gh-publishmenu-email">
|
||||
{{#if this.isSendingEmailLimited}}
|
||||
<p class="gh-box gh-box-alert">{{html-safe this.sendingEmailLimitError}}</p>
|
||||
{{else}}
|
||||
<div class="gh-publishmenu-email-label {{if this.disableEmailOption "pe-none"}}">
|
||||
<label class="gh-publishmenu-radio-label mb3 {{if this.disableEmailOption "midgrey"}}">Send by email to</label>
|
||||
{{#if @canSendEmail}}
|
||||
<div class="gh-publishmenu-section" {{did-insert (perform this.countTotalMembersTask)}}>
|
||||
<div class="gh-publishmenu-email">
|
||||
{{#if @isSendingEmailLimited}}
|
||||
<p class="gh-box gh-box-alert">{{html-safe @sendingEmailLimitError}}</p>
|
||||
{{else}}
|
||||
<div class="gh-publishmenu-email-label {{if this.disableEmailOption "pe-none"}}">
|
||||
<label class="gh-publishmenu-radio-label mb3 {{if this.disableEmailOption "midgrey"}}">Send by email to</label>
|
||||
|
||||
<div class="form-group">
|
||||
<GhMembersRecipientSelect
|
||||
@filter={{this.recipientsFilter}}
|
||||
@onChange={{this.setSendEmailWhenPublished}}
|
||||
@disabled={{this.disableEmailOption}}
|
||||
/>
|
||||
<div class="form-group">
|
||||
<GhMembersRecipientSelect
|
||||
@filter={{@recipientsFilter}}
|
||||
@onChange={{@setSendEmailWhenPublished}}
|
||||
@disabled={{this.disableEmailOption}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</section>
|
||||
|
||||
{{/if}}
|
||||
</section>
|
||||
</div>
|
|
@ -1,96 +1,96 @@
|
|||
import Component from '@ember/component';
|
||||
import Component from '@glimmer/component';
|
||||
import moment from 'moment';
|
||||
import {computed} from '@ember/object';
|
||||
import {action} from '@ember/object';
|
||||
import {isEmpty} from '@ember/utils';
|
||||
import {inject as service} from '@ember/service';
|
||||
import {task} from 'ember-concurrency';
|
||||
import {task} from 'ember-concurrency-decorators';
|
||||
import {tracked} from '@glimmer/tracking';
|
||||
|
||||
export default Component.extend({
|
||||
config: service(),
|
||||
feature: service(),
|
||||
session: service(),
|
||||
settings: service(),
|
||||
store: service(),
|
||||
export default class GhPublishMenuDraftComponent extends Component {
|
||||
@service config;
|
||||
@service feature;
|
||||
@service session;
|
||||
@service settings;
|
||||
@service store;
|
||||
|
||||
post: null,
|
||||
saveType: null,
|
||||
@tracked totalMemberCount = 0;
|
||||
|
||||
// used to set minDate in datepicker
|
||||
_minDate: null,
|
||||
_publishedAtBlogTZ: null,
|
||||
_minDate = null;
|
||||
_publishedAtBlogTZ = null;
|
||||
|
||||
'data-test-publishmenu-draft': true,
|
||||
get disableEmailOption() {
|
||||
// TODO: remove owner or admin check when editors can count members
|
||||
return this.session.user.isOwnerOrAdmin && (this.totalMemberCount === 0 || this.countTotalMembersTask.isRunning);
|
||||
}
|
||||
|
||||
// TODO: remove owner or admin check when editors can count members
|
||||
disableEmailOption: computed('totalMemberCount', 'countTotalMembersTask.isRunning', function () {
|
||||
return this.get('session.user.isOwnerOrAdmin') && (this.totalMemberCount === 0 || this.countTotalMembersTask.isRunning);
|
||||
}),
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.args.post.set('publishedAtBlogTZ', this.args.post.publishedAtUTC);
|
||||
}
|
||||
|
||||
didInsertElement() {
|
||||
this.post.set('publishedAtBlogTZ', this.get('post.publishedAtUTC'));
|
||||
this.send('setSaveType', 'publish');
|
||||
},
|
||||
@action
|
||||
setSaveType(type) {
|
||||
if (this.args.saveType !== type) {
|
||||
let hasDateError = !isEmpty(this.args.post.errors.errorsFor('publishedAtBlogDate'));
|
||||
let hasTimeError = !isEmpty(this.args.post.errors.errorsFor('publishedAtBlogTime'));
|
||||
let minDate = this._getMinDate();
|
||||
|
||||
actions: {
|
||||
setSaveType(type) {
|
||||
if (this.saveType !== type) {
|
||||
let hasDateError = !isEmpty(this.get('post.errors').errorsFor('publishedAtBlogDate'));
|
||||
let hasTimeError = !isEmpty(this.get('post.errors').errorsFor('publishedAtBlogTime'));
|
||||
let minDate = this._getMinDate();
|
||||
this._minDate = minDate;
|
||||
this.args.setSaveType(type);
|
||||
|
||||
this.set('_minDate', minDate);
|
||||
this.setSaveType(type);
|
||||
|
||||
// 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.get('post.publishedAtBlogTZ');
|
||||
} else {
|
||||
this._publishedAtBlogTZ = this.get('post.publishedAtUTC');
|
||||
}
|
||||
|
||||
this.post.set('publishedAtBlogTZ', this.get('post.publishedAtUTC'));
|
||||
// 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 {
|
||||
if (!this._publishedAtBlogTZ || moment(this._publishedAtBlogTZ).isBefore(minDate)) {
|
||||
this.post.set('publishedAtBlogTZ', minDate);
|
||||
} else {
|
||||
this.post.set('publishedAtBlogTZ', this._publishedAtBlogTZ);
|
||||
}
|
||||
this._publishedAtBlogTZ = this.args.post.publishedAtUTC;
|
||||
}
|
||||
|
||||
this.post.validate();
|
||||
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);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
setDate(date) {
|
||||
let post = this.post;
|
||||
let dateString = moment(date).format('YYYY-MM-DD');
|
||||
|
||||
post.set('publishedAtBlogDate', dateString);
|
||||
return post.validate();
|
||||
},
|
||||
|
||||
setTime(time) {
|
||||
let post = this.post;
|
||||
|
||||
post.set('publishedAtBlogTime', time);
|
||||
return post.validate();
|
||||
this.args.post.validate();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
countTotalMembersTask: task(function*() {
|
||||
@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();
|
||||
}
|
||||
|
||||
@task
|
||||
*countTotalMembersTask() {
|
||||
const user = yield this.session.user;
|
||||
|
||||
if (user.isOwnerOrAdmin) {
|
||||
const result = yield this.store.query('member', {limit: 1, filter: 'subscribed:true'});
|
||||
this.set('totalMemberCount', result.meta.pagination.total);
|
||||
this.totalMemberCount = result.meta.pagination.total;
|
||||
}
|
||||
}),
|
||||
}
|
||||
|
||||
// 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');
|
||||
}
|
||||
// API only accepts dates at least 2 mins in the future, default the
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
<header class="gh-publishmenu-heading">Update {{post.displayName}} status</header>
|
||||
<section class="gh-publishmenu-content gh-publishmenu-section">
|
||||
<div class="gh-publishmenu-radio {{if (eq this.saveType "draft") "active"}}" {{action this.setSaveType "draft" on="click"}}>
|
||||
<div class="gh-publishmenu-radio-button" data-test-publishmenu-unpublished-option></div>
|
||||
<div class="gh-publishmenu-radio-content">
|
||||
<div class="gh-publishmenu-radio-label">Unpublished</div>
|
||||
<div class="gh-publishmenu-radio-desc">Revert this {{post.displayName}} to a private draft</div>
|
||||
<div {{did-insert (fn @setSaveType "publish")}} data-test-publishmenu-published="true" ...attributes>
|
||||
<header class="gh-publishmenu-heading">Update {{@post.displayName}} status</header>
|
||||
<section class="gh-publishmenu-content gh-publishmenu-section">
|
||||
<div class="gh-publishmenu-radio {{if (eq @saveType "draft") "active"}}" {{on "click" (fn @setSaveType "draft")}}>
|
||||
<div class="gh-publishmenu-radio-button" data-test-publishmenu-unpublished-option></div>
|
||||
<div class="gh-publishmenu-radio-content">
|
||||
<div class="gh-publishmenu-radio-label">Unpublished</div>
|
||||
<div class="gh-publishmenu-radio-desc">Revert this {{@post.displayName}} to a private draft</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gh-publishmenu-radio {{if (eq this.saveType "publish") "active"}}" {{action this.setSaveType "publish" on="click"}}>
|
||||
<div class="gh-publishmenu-radio-button" data-test-publishmenu-published-option></div>
|
||||
<div class="gh-publishmenu-radio-content">
|
||||
<div class="gh-publishmenu-radio-label">Published</div>
|
||||
<div class="gh-publishmenu-radio-desc">Display this {{post.displayName}} publicly</div>
|
||||
<div class="gh-publishmenu-radio {{if (eq @saveType "publish") "active"}}" {{on "click" (fn @setSaveType "publish")}}>
|
||||
<div class="gh-publishmenu-radio-button" data-test-publishmenu-published-option></div>
|
||||
<div class="gh-publishmenu-radio-content">
|
||||
<div class="gh-publishmenu-radio-label">Published</div>
|
||||
<div class="gh-publishmenu-radio-desc">Display this {{@post.displayName}} publicly</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
|
@ -1,12 +0,0 @@
|
|||
import Component from '@ember/component';
|
||||
import {inject as service} from '@ember/service';
|
||||
|
||||
export default Component.extend({
|
||||
feature: service(),
|
||||
|
||||
'data-test-publishmenu-published': true,
|
||||
|
||||
didInsertElement() {
|
||||
this.setSaveType('publish');
|
||||
}
|
||||
});
|
|
@ -1,51 +1,53 @@
|
|||
<header class="gh-publishmenu-heading">Will be published in {{this.timeToPublished}}</header>
|
||||
<div class="gh-publishmenu-content">
|
||||
<section class="gh-publishmenu-section">
|
||||
<div class="gh-publishmenu-radio {{if (eq this.saveType "draft") "active"}}" {{action "setSaveType" "draft" on="click"}}>
|
||||
<div class="gh-publishmenu-radio-button" data-test-publishmenu-draft-option></div>
|
||||
<div class="gh-publishmenu-radio-content">
|
||||
<div class="gh-publishmenu-radio-label">Revert to draft</div>
|
||||
<div class="gh-publishmenu-radio-desc">Do not publish</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gh-publishmenu-radio {{if (eq this.saveType "schedule") "active"}}" {{action "setSaveType" "schedule" on="click"}}>
|
||||
<div class="gh-publishmenu-radio-button" data-test-publishmenu-scheduled-option></div>
|
||||
<div class="gh-publishmenu-radio-content">
|
||||
<div class="gh-publishmenu-radio-label">Schedule for later</div>
|
||||
<GhDateTimePicker
|
||||
@date={{this.post.publishedAtBlogDate}}
|
||||
@time={{this.post.publishedAtBlogTime}}
|
||||
@setDate={{action "setDate"}}
|
||||
@setTime={{action "setTime"}}
|
||||
@setTypedDateError={{this.setTypedDateError}}
|
||||
@errors={{this.post.errors}}
|
||||
@dateErrorProperty="publishedAtBlogDate"
|
||||
@timeErrorProperty="publishedAtBlogTime"
|
||||
@minDate={{this._minDate}}
|
||||
@isActive={{eq this.saveType "schedule"}}
|
||||
/>
|
||||
<div class="gh-publishmenu-radio-desc">Set automatic future publish date</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{#if this.canSendEmail}}
|
||||
<div {{did-insert (fn this.setSaveType "schedule")}} data-test-publishmenu-scheduled="true" ...attributes>
|
||||
<header class="gh-publishmenu-heading">Will be published in {{this.timeToPublished}}</header>
|
||||
<div class="gh-publishmenu-content">
|
||||
<section class="gh-publishmenu-section">
|
||||
<div class="gh-publishmenu-email">
|
||||
{{#if this.isSendingEmailLimited}}
|
||||
<p>{{html-safe this.sendingEmailLimitError}}</p>
|
||||
{{else}}
|
||||
<div class="gh-publishmenu-email-label {{if this.disableEmailOption "pe-none"}}">
|
||||
<label class="gh-publishmenu-radio-label mb3 {{if this.disableEmailOption "midgrey"}}">Send by email to</label>
|
||||
|
||||
<div class="form-group">
|
||||
<GhMembersRecipientSelect
|
||||
@filter={{this.recipientsFilter}}
|
||||
@disabled={{true}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="gh-publishmenu-radio {{if (eq @saveType "draft") "active"}}" {{on "click" (fn this.setSaveType "draft")}}>
|
||||
<div class="gh-publishmenu-radio-button" data-test-publishmenu-draft-option></div>
|
||||
<div class="gh-publishmenu-radio-content">
|
||||
<div class="gh-publishmenu-radio-label">Revert to draft</div>
|
||||
<div class="gh-publishmenu-radio-desc">Do not publish</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gh-publishmenu-radio {{if (eq @saveType "schedule") "active"}}" {{on "click" (fn this.setSaveType "schedule")}}>
|
||||
<div class="gh-publishmenu-radio-button" data-test-publishmenu-scheduled-option></div>
|
||||
<div class="gh-publishmenu-radio-content">
|
||||
<div class="gh-publishmenu-radio-label">Schedule for later</div>
|
||||
<GhDateTimePicker
|
||||
@date={{@post.publishedAtBlogDate}}
|
||||
@time={{@post.publishedAtBlogTime}}
|
||||
@setDate={{this.setDate}}
|
||||
@setTime={{this.setTime}}
|
||||
@setTypedDateError={{@setTypedDateError}}
|
||||
@errors={{@post.errors}}
|
||||
@dateErrorProperty="publishedAtBlogDate"
|
||||
@timeErrorProperty="publishedAtBlogTime"
|
||||
@minDate={{this.minDate}}
|
||||
@isActive={{eq @saveType "schedule"}}
|
||||
/>
|
||||
<div class="gh-publishmenu-radio-desc">Set automatic future publish date</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#if @canSendEmail}}
|
||||
<section class="gh-publishmenu-section">
|
||||
<div class="gh-publishmenu-email">
|
||||
{{#if @isSendingEmailLimited}}
|
||||
<p>{{html-safe @sendingEmailLimitError}}</p>
|
||||
{{else}}
|
||||
<div class="gh-publishmenu-email-label pe-none">
|
||||
<label class="gh-publishmenu-radio-label mb3 midgrey">Send by email to</label>
|
||||
|
||||
<div class="form-group">
|
||||
<GhMembersRecipientSelect
|
||||
@filter={{@recipientsFilter}}
|
||||
@disabled={{true}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</section>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
|
@ -1,74 +1,70 @@
|
|||
import Component from '@ember/component';
|
||||
import Component from '@glimmer/component';
|
||||
import moment from 'moment';
|
||||
import {computed} from '@ember/object';
|
||||
import {action} from '@ember/object';
|
||||
import {inject as service} from '@ember/service';
|
||||
import {tracked} from '@glimmer/tracking';
|
||||
|
||||
export default Component.extend({
|
||||
clock: service(),
|
||||
session: service(),
|
||||
feature: service(),
|
||||
settings: service(),
|
||||
config: service(),
|
||||
|
||||
post: null,
|
||||
saveType: null,
|
||||
isClosing: null,
|
||||
export default class GhPublishmenuScheduledComponent extends Component {
|
||||
@service clock;
|
||||
@service session;
|
||||
@service feature;
|
||||
@service settings;
|
||||
@service config;
|
||||
|
||||
// used to set minDate in datepicker
|
||||
_minDate: null,
|
||||
@tracked minDate = null;
|
||||
|
||||
'data-test-publishmenu-scheduled': true,
|
||||
|
||||
timeToPublished: computed('post.publishedAtUTC', 'clock.second', function () {
|
||||
let publishedAtUTC = this.get('post.publishedAtUTC');
|
||||
get timeToPublished() {
|
||||
let publishedAtUTC = this.args.post.publishedAtUTC;
|
||||
|
||||
if (!publishedAtUTC) {
|
||||
return null;
|
||||
}
|
||||
|
||||
this.get('clock.second');
|
||||
this.clock.get('second');
|
||||
|
||||
return publishedAtUTC.toNow(true);
|
||||
}),
|
||||
}
|
||||
|
||||
didInsertElement() {
|
||||
this.set('_minDate', new Date());
|
||||
this.setSaveType('schedule');
|
||||
},
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.minDate = new Date();
|
||||
}
|
||||
|
||||
actions: {
|
||||
setSaveType(type) {
|
||||
if (this.saveType !== type) {
|
||||
this.set('_minDate', new Date());
|
||||
this.setSaveType(type);
|
||||
@action
|
||||
setSaveType(type) {
|
||||
if (this.saveType !== type) {
|
||||
this.minDate = new Date();
|
||||
this.args.setSaveType(type);
|
||||
|
||||
// when draft switch to now to avoid validation errors
|
||||
// when schedule switch back to saved date to avoid unnecessary re-scheduling
|
||||
if (type === 'draft') {
|
||||
this.post.set('publishedAtBlogTZ', new Date());
|
||||
} else {
|
||||
this.post.set('publishedAtBlogTZ', this.get('post.publishedAtUTC'));
|
||||
}
|
||||
|
||||
this.post.validate();
|
||||
// when draft switch to now to avoid validation errors
|
||||
// when schedule switch back to saved date to avoid unnecessary re-scheduling
|
||||
if (type === 'draft') {
|
||||
this.args.post.set('publishedAtBlogTZ', new Date());
|
||||
} else {
|
||||
this.args.post.set('publishedAtBlogTZ', this.args.post.publishedAtUTC);
|
||||
}
|
||||
},
|
||||
|
||||
setDate(date) {
|
||||
let post = this.post;
|
||||
let dateString = moment(date).format('YYYY-MM-DD');
|
||||
|
||||
post.set('publishedAtBlogDate', dateString);
|
||||
return post.validate();
|
||||
},
|
||||
|
||||
setTime(time) {
|
||||
let post = this.post;
|
||||
|
||||
if (!this.isClosing) {
|
||||
post.set('publishedAtBlogTime', time);
|
||||
return post.validate();
|
||||
}
|
||||
this.args.post.validate();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@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;
|
||||
|
||||
if (!this.args.isClosing) {
|
||||
post.set('publishedAtBlogTime', time);
|
||||
return post.validate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
<GhPublishmenuPublished
|
||||
@post={{this.post}}
|
||||
@saveType={{this.saveType}}
|
||||
@setSaveType={{action "setSaveType"}} />
|
||||
@setSaveType={{action "setSaveType"}}
|
||||
data-test-publishmenu-published="true" />
|
||||
|
||||
{{else if (eq this.displayState "scheduled")}}
|
||||
<GhPublishmenuScheduled
|
||||
|
@ -20,7 +21,8 @@
|
|||
@setSaveType={{action "setSaveType"}}
|
||||
@setTypedDateError={{action (mut this.typedDateError)}}
|
||||
@isSendingEmailLimited={{this.isSendingEmailLimited}}
|
||||
@sendingEmailLimitError={{this.sendingEmailLimitError}} />
|
||||
@sendingEmailLimitError={{this.sendingEmailLimitError}}
|
||||
data-test-publishmenu-scheduled="true" />
|
||||
|
||||
{{else}}
|
||||
<GhPublishmenuDraft
|
||||
|
@ -30,10 +32,10 @@
|
|||
@setTypedDateError={{action (mut this.typedDateError)}}
|
||||
@canSendEmail={{this.canSendEmail}}
|
||||
@recipientsFilter={{this.sendEmailWhenPublished}}
|
||||
@updateMemberCount={{action "updateMemberCount"}}
|
||||
@setSendEmailWhenPublished={{action "setSendEmailWhenPublished"}}
|
||||
@isSendingEmailLimited={{this.isSendingEmailLimited}}
|
||||
@sendingEmailLimitError={{this.sendingEmailLimitError}} />
|
||||
@sendingEmailLimitError={{this.sendingEmailLimitError}}
|
||||
data-test-publishmenu-draft="true" />
|
||||
{{/if}}
|
||||
|
||||
{{!--
|
||||
|
@ -51,7 +53,7 @@
|
|||
@successText={{this.successText}}
|
||||
@runningText={{this.runningText}}
|
||||
@class="gh-btn gh-btn-black gh-publishmenu-button gh-btn-icon"
|
||||
data-test-publishmenu-save=true
|
||||
data-test-publishmenu-save="true"
|
||||
/>
|
||||
</footer>
|
||||
</dd.Content>
|
||||
|
|
|
@ -1,30 +1,32 @@
|
|||
<LinkTo @route="tag" @model={{tag}} class="gh-list-data gh-tag-list-title gh-list-cellwidth-70" @title="Edit tag">
|
||||
<h3 class="gh-tag-list-name">
|
||||
{{this.tag.name}}
|
||||
</h3>
|
||||
{{#if this.description}}
|
||||
<p class="ma0 pa0 f8 midgrey gh-tag-list-description">
|
||||
{{this.description}}
|
||||
</p>
|
||||
<li class="gh-list-row gh-tags-list-item" ...attributes>
|
||||
<LinkTo @route="tag" @model={{@tag}} class="gh-list-data gh-tag-list-title gh-list-cellwidth-70" @title="Edit tag">
|
||||
<h3 class="gh-tag-list-name">
|
||||
{{@tag.name}}
|
||||
</h3>
|
||||
{{#if @tag.description}}
|
||||
<p class="ma0 pa0 f8 midgrey gh-tag-list-description">
|
||||
{{@tag.description}}
|
||||
</p>
|
||||
{{/if}}
|
||||
</LinkTo>
|
||||
|
||||
<LinkTo @route="tag" @model={{@tag}} class="gh-list-data middarkgrey f8 gh-tag-list-slug gh-list-cellwidth-10" @title="Edit tag">
|
||||
<span title="{{@slug}}">{{@slug}}</span>
|
||||
</LinkTo>
|
||||
|
||||
{{#if @tag.count.posts}}
|
||||
<LinkTo @route="posts" @query={{hash type=null author=null tag=@tag.slug order=null}} class="gh-list-data blue gh-tag-list-posts-count gh-list-cellwidth-10 f8" @title={{concat "List posts tagged with '" @tag.name "'"}}>
|
||||
<span class="nowrap">{{gh-pluralize @tag.count.posts "post"}}</span>
|
||||
</LinkTo>
|
||||
{{else}}
|
||||
<LinkTo @route="tag" @model={{@tag}} class="gh-list-data gh-tag-list-posts-count gh-list-cellwidth-10" @title="Edit tag">
|
||||
<span class="nowrap f8 midlightgrey">{{gh-pluralize @tag.count.posts "post"}}</span>
|
||||
</LinkTo>
|
||||
{{/if}}
|
||||
</LinkTo>
|
||||
|
||||
<LinkTo @route="tag" @model={{tag}} class="gh-list-data middarkgrey f8 gh-tag-list-slug gh-list-cellwidth-10" @title="Edit tag">
|
||||
<span title="{{this.slug}}">{{this.slug}}</span>
|
||||
</LinkTo>
|
||||
|
||||
{{#if this.postsCount}}
|
||||
<LinkTo @route="posts" @query={{hash type=null author=null tag=tag.slug order=null}} class="gh-list-data blue gh-tag-list-posts-count gh-list-cellwidth-10 f8" @title={{concat "List posts tagged with '" this.tag.name "'"}}>
|
||||
<span class="nowrap">{{this.postsLabel}}</span>
|
||||
<LinkTo @route="tag" @model={{@tag}} class="gh-list-data gh-list-cellwidth-10 gh-tag-list-chevron" @title="Edit tag">
|
||||
<div class="flex items-center justify-end w-100 h-100">
|
||||
<span class="nr2">{{svg-jar "arrow-right" class="w6 h6 fill-midgrey pa1"}}</span>
|
||||
</div>
|
||||
</LinkTo>
|
||||
{{else}}
|
||||
<LinkTo @route="tag" @model={{tag}} class="gh-list-data gh-tag-list-posts-count gh-list-cellwidth-10" @title="Edit tag">
|
||||
<span class="nowrap f8 midlightgrey">{{this.postsLabel}}</span>
|
||||
</LinkTo>
|
||||
{{/if}}
|
||||
|
||||
<LinkTo @route="tag" @model={{tag}} class="gh-list-data gh-list-cellwidth-10 gh-tag-list-chevron" @title="Edit tag">
|
||||
<div class="flex items-center justify-end w-100 h-100">
|
||||
<span class="nr2">{{svg-jar "arrow-right" class="w6 h6 fill-midgrey pa1"}}</span>
|
||||
</div>
|
||||
</LinkTo>
|
||||
</li>
|
|
@ -1,38 +0,0 @@
|
|||
import Component from '@ember/component';
|
||||
import {alias} from '@ember/object/computed';
|
||||
import {computed} from '@ember/object';
|
||||
import {inject as service} from '@ember/service';
|
||||
|
||||
export default Component.extend({
|
||||
ghostPaths: service(),
|
||||
notifications: service(),
|
||||
router: service(),
|
||||
|
||||
tagName: 'li',
|
||||
classNames: ['gh-list-row', 'gh-tags-list-item'],
|
||||
|
||||
active: false,
|
||||
|
||||
id: alias('tag.id'),
|
||||
slug: alias('tag.slug'),
|
||||
name: alias('tag.name'),
|
||||
isInternal: alias('tag.isInternal'),
|
||||
description: alias('tag.description'),
|
||||
postsCount: alias('tag.count.posts'),
|
||||
postsLabel: computed('tag.count.posts', function () {
|
||||
let noOfPosts = this.postsCount || 0;
|
||||
return (noOfPosts === 1) ? `${noOfPosts} post` : `${noOfPosts} posts`;
|
||||
}),
|
||||
|
||||
_deleteTag() {
|
||||
let tag = this.tag;
|
||||
|
||||
return tag.destroyRecord().then(() => {}, (error) => {
|
||||
this._deleteTagFailure(error);
|
||||
});
|
||||
},
|
||||
|
||||
_deleteTagFailure(error) {
|
||||
this.notifications.showAPIError(error, {key: 'tag.delete'});
|
||||
}
|
||||
});
|
|
@ -25,7 +25,7 @@ const GhTaskButton = Component.extend({
|
|||
'isSuccessClass',
|
||||
'isFailureClass'
|
||||
],
|
||||
attributeBindings: ['disabled', 'form', 'type', 'tabindex'],
|
||||
attributeBindings: ['disabled', 'form', 'type', 'tabindex', 'data-test-button'],
|
||||
|
||||
task: null,
|
||||
taskArgs: undefined,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="theme-validation-container">
|
||||
<div class="theme-validation-container" data-test-theme-warnings-modal="true">
|
||||
<header class="modal-header">
|
||||
<h1 data-test-theme-warnings-title>
|
||||
{{#unless this.canActivate}}
|
||||
|
|
|
@ -2,8 +2,6 @@ import ModalComponent from 'ghost-admin/components/modal-base';
|
|||
import {reads} from '@ember/object/computed';
|
||||
|
||||
export default ModalComponent.extend({
|
||||
'data-test-theme-warnings-modal': true,
|
||||
|
||||
title: reads('model.title'),
|
||||
message: reads('model.message'),
|
||||
warnings: reads('model.warnings'),
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
<VerticalCollection @items={{this.members}} @key="id" @containerSelector=".gh-main" @estimateHeight={{69}} @staticHeight={{true}} @bufferSize={{20}} as |member|>
|
||||
<GhMembersListItem
|
||||
@member={{member}}
|
||||
@data-test-member={{member.id}}
|
||||
data-test-member={{member.id}}
|
||||
/>
|
||||
</VerticalCollection>
|
||||
{{else}}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<div class="gh-list-header gh-list-cellwidth-10"></div>
|
||||
</li>
|
||||
<VerticalCollection @items={{this.sortedTags}} @key="id" @containerSelector=".gh-main" @estimateHeight={{60}} @bufferSize={{20}} as |tag|>
|
||||
<GhTagsListItem @tag={{tag}} @data-test-tag-id={{tag.id}} />
|
||||
<GhTagsListItem @tag={{tag}} data-test-tag-id={{tag.id}} />
|
||||
</VerticalCollection>
|
||||
{{else}}
|
||||
<li class="no-posts-box">
|
||||
|
|
Loading…
Add table
Reference in a new issue