mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
🐛 Fixed missing 'duplicate a post' feature for editors (#21304)
ref https://linear.app/tryghost/issue/ENG-1647 - as per [staff user definitions](https://ghost.org/docs/staff), an editor should be able to duplicate a post - this feature was missing from the right-click menu on post/page lists for editors
This commit is contained in:
parent
d7e36cb22a
commit
d5aa77bb7f
2 changed files with 82 additions and 4 deletions
|
@ -30,7 +30,7 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if this.canFeatureSelection}}
|
{{#if this.canFeatureSelection}}
|
||||||
{{#if this.shouldFeatureSelection }}
|
{{#if this.shouldFeatureSelection}}
|
||||||
<li>
|
<li>
|
||||||
<button class="mr2" type="button" {{on "click" this.featurePosts}} data-test-button="feature">
|
<button class="mr2" type="button" {{on "click" this.featurePosts}} data-test-button="feature">
|
||||||
<span>{{svg-jar "star" class="mb1 star"}}Feature</span>
|
<span>{{svg-jar "star" class="mb1 star"}}Feature</span>
|
||||||
|
@ -44,11 +44,13 @@
|
||||||
</li>
|
</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<button class="mr2" type="button" {{on "click" this.addTagToPosts}} data-test-button="add-tag">
|
<button class="mr2" type="button" {{on "click" this.addTagToPosts}} data-test-button="add-tag">
|
||||||
<span>{{svg-jar "tag"}}Add a tag</span>
|
<span>{{svg-jar "tag"}}Add a tag</span>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{{#if this.membersUtils.isMembersEnabled}}
|
{{#if this.membersUtils.isMembersEnabled}}
|
||||||
<li>
|
<li>
|
||||||
<button class="mr2" type="button" {{on "click" this.editPostsAccess}} data-test-button="change-access">
|
<button class="mr2" type="button" {{on "click" this.editPostsAccess}} data-test-button="change-access">
|
||||||
|
@ -56,14 +58,16 @@
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if this.session.user.isAdmin}}
|
|
||||||
{{#if this.canCopySelection}}
|
{{#if this.canCopySelection}}
|
||||||
<li>
|
<li>
|
||||||
<button class="mr2" type="button" {{on "click" this.copyPosts}} data-test-button="duplicate">
|
<button class="mr2" type="button" {{on "click" this.copyPosts}} data-test-button="duplicate">
|
||||||
<span>{{svg-jar "duplicate"}}Duplicate</span>
|
<span>{{svg-jar "duplicate"}}Duplicate</span>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if this.session.user.isAdmin}}
|
||||||
<li>
|
<li>
|
||||||
<button class="mr2" type="button" {{on "click" this.deletePosts}} data-test-button="delete">
|
<button class="mr2" type="button" {{on "click" this.deletePosts}} data-test-button="delete">
|
||||||
<span class="red">{{svg-jar "trash"}}Delete</span>
|
<span class="red">{{svg-jar "trash"}}Delete</span>
|
||||||
|
|
|
@ -72,6 +72,27 @@ describe('Acceptance: Posts / Pages', function () {
|
||||||
expect(findAll('[data-test-post-id]')).to.have.length(1);
|
expect(findAll('[data-test-post-id]')).to.have.length(1);
|
||||||
expect(find('[data-test-no-posts-box]')).to.not.exist;
|
expect(find('[data-test-no-posts-box]')).to.not.exist;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('context menu', function () {
|
||||||
|
let publishedPost;
|
||||||
|
|
||||||
|
beforeEach(async function () {
|
||||||
|
publishedPost = this.server.create('post', {status: 'published'});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not render the context menu', async function () {
|
||||||
|
await visit('/posts');
|
||||||
|
|
||||||
|
// get the post
|
||||||
|
const post = find(`[data-test-post-id="${publishedPost.id}"]`);
|
||||||
|
expect(post, 'post').to.exist;
|
||||||
|
|
||||||
|
await triggerEvent(post, 'contextmenu');
|
||||||
|
|
||||||
|
let contextMenu = find('.gh-posts-context-menu');
|
||||||
|
expect(contextMenu, 'context menu').to.not.be.visible;
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('as author', function () {
|
describe('as author', function () {
|
||||||
|
@ -103,6 +124,59 @@ describe('Acceptance: Posts / Pages', function () {
|
||||||
expect(findAll('[data-test-post-id]').length, 'post count').to.equal(1);
|
expect(findAll('[data-test-post-id]').length, 'post count').to.equal(1);
|
||||||
expect(find(`[data-test-post-id="${authorPost.id}"]`), 'author post').to.exist;
|
expect(find(`[data-test-post-id="${authorPost.id}"]`), 'author post').to.exist;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('context menu', function () {
|
||||||
|
it('does not render the context menu', async function () {
|
||||||
|
await visit('/posts');
|
||||||
|
|
||||||
|
// get the post
|
||||||
|
const post = find(`[data-test-post-id="${authorPost.id}"]`);
|
||||||
|
expect(post, 'post').to.exist;
|
||||||
|
|
||||||
|
await triggerEvent(post, 'contextmenu');
|
||||||
|
|
||||||
|
let contextMenu = find('.gh-posts-context-menu');
|
||||||
|
expect(contextMenu, 'context menu').to.not.be.visible;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('as editor', function () {
|
||||||
|
let editor, editorPost;
|
||||||
|
|
||||||
|
beforeEach(async function () {
|
||||||
|
let editorRole = this.server.create('role', {name: 'Editor'});
|
||||||
|
editor = this.server.create('user', {roles: [editorRole]});
|
||||||
|
editorPost = this.server.create('post', {authors: [editor], status: 'published', title: 'Editor Post'});
|
||||||
|
|
||||||
|
await authenticateSession();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('context menu', function () {
|
||||||
|
it('renders the correct options', async function () {
|
||||||
|
await visit('/posts');
|
||||||
|
|
||||||
|
const post = find(`[data-test-post-id="${editorPost.id}"]`);
|
||||||
|
expect(post, 'post').to.exist;
|
||||||
|
|
||||||
|
await triggerEvent(post, 'contextmenu');
|
||||||
|
|
||||||
|
// Test that the context menu is rendered
|
||||||
|
const contextMenu = find('.gh-posts-context-menu');
|
||||||
|
expect(contextMenu, 'context menu').to.exist;
|
||||||
|
|
||||||
|
// Test that the context menu has the correct buttons
|
||||||
|
const buttons = contextMenu.querySelectorAll('button');
|
||||||
|
expect(buttons.length, 'context menu buttons').to.equal(5);
|
||||||
|
expect(buttons[0].innerText.trim(), 'context menu button 1').to.contain('Copy link to post');
|
||||||
|
expect(buttons[1].innerText.trim(), 'context menu button 2').to.contain('Unpublish');
|
||||||
|
expect(buttons[2].innerText.trim(), 'context menu button 3').to.contain('Feature');
|
||||||
|
expect(buttons[3].innerText.trim(), 'context menu button 4').to.contain('Add a tag');
|
||||||
|
expect(buttons[4].innerText.trim(), 'context menu button 5').to.contain('Duplicate');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Note: we cover the functionality of the context menu buttons in the 'as admin' section
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('as admin', function () {
|
describe('as admin', function () {
|
||||||
|
|
Loading…
Add table
Reference in a new issue