0
Fork 0
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:
Kevin Ansfield 2021-07-08 22:44:52 +01:00
parent c646e78fff
commit 7ab0db9be7
14 changed files with 273 additions and 320 deletions

View file

@ -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>

View file

@ -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
});
}

View file

@ -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>

View file

@ -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');
}
});

View file

@ -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>

View file

@ -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();
}
}
}

View file

@ -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>

View file

@ -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>

View file

@ -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'});
}
});

View file

@ -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,

View file

@ -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}}

View file

@ -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'),

View file

@ -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}}

View file

@ -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">