mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-25 09:03:12 +03:00
Wired email alert settings for staff users on admin (#15313)
refs TryGhost/Team#1826 - allows staff users to manage their email alert settings behind the flag - only owner and admin users are able to toggle their email alerts
This commit is contained in:
parent
b51d81843b
commit
da62355e18
@ -21,6 +21,7 @@ export default Controller.extend({
|
|||||||
session: service(),
|
session: service(),
|
||||||
slugGenerator: service(),
|
slugGenerator: service(),
|
||||||
utils: service(),
|
utils: service(),
|
||||||
|
membersUtils: service(),
|
||||||
|
|
||||||
personalToken: null,
|
personalToken: null,
|
||||||
limitErrorMessage: null,
|
limitErrorMessage: null,
|
||||||
@ -47,6 +48,8 @@ export default Controller.extend({
|
|||||||
|
|
||||||
canChangeEmail: not('isAdminUserOnOwnerProfile'),
|
canChangeEmail: not('isAdminUserOnOwnerProfile'),
|
||||||
canChangePassword: not('isAdminUserOnOwnerProfile'),
|
canChangePassword: not('isAdminUserOnOwnerProfile'),
|
||||||
|
canToggleMemberAlerts: or('currentUser.isOwnerOnly', 'isAdminUserOnOwnProfile'),
|
||||||
|
isAdminUserOnOwnProfile: and('currentUser.isAdminOnly', 'isOwnProfile'),
|
||||||
canMakeOwner: and('currentUser.isOwnerOnly', 'isNotOwnProfile', 'user.isAdminOnly', 'isNotSuspended'),
|
canMakeOwner: and('currentUser.isOwnerOnly', 'isNotOwnProfile', 'user.isAdminOnly', 'isNotSuspended'),
|
||||||
isAdminUserOnOwnerProfile: and('currentUser.isAdminOnly', 'user.isOwnerOnly'),
|
isAdminUserOnOwnerProfile: and('currentUser.isAdminOnly', 'user.isOwnerOnly'),
|
||||||
isNotOwnersProfile: not('user.isOwnerOnly'),
|
isNotOwnersProfile: not('user.isOwnerOnly'),
|
||||||
@ -385,6 +388,16 @@ export default Controller.extend({
|
|||||||
this.user.commentNotifications = event.target.checked;
|
this.user.commentNotifications = event.target.checked;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
toggleMemberEmailAlerts: action(function (type, event) {
|
||||||
|
if (type === 'free-signup') {
|
||||||
|
this.user.freeMemberSignupNotification = event.target.checked;
|
||||||
|
} else if (type === 'paid-started') {
|
||||||
|
this.user.paidSubscriptionStartedNotification = event.target.checked;
|
||||||
|
} else if (type === 'paid-canceled') {
|
||||||
|
this.user.paidSubscriptionCanceledNotification = event.target.checked;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
deleteUser: task(function *() {
|
deleteUser: task(function *() {
|
||||||
try {
|
try {
|
||||||
yield this.user.destroyRecord();
|
yield this.user.destroyRecord();
|
||||||
|
@ -36,6 +36,9 @@ export default BaseModel.extend(ValidationEngine, {
|
|||||||
twitter: attr('twitter-url-user'),
|
twitter: attr('twitter-url-user'),
|
||||||
tour: attr('json-string'),
|
tour: attr('json-string'),
|
||||||
commentNotifications: attr(),
|
commentNotifications: attr(),
|
||||||
|
freeMemberSignupNotification: attr(),
|
||||||
|
paidSubscriptionStartedNotification: attr(),
|
||||||
|
paidSubscriptionCanceledNotification: attr(),
|
||||||
|
|
||||||
ghostPaths: service(),
|
ghostPaths: service(),
|
||||||
ajax: service(),
|
ajax: service(),
|
||||||
|
@ -196,7 +196,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: 12px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-setting-toggle label {
|
.user-setting-toggle label {
|
||||||
@ -205,4 +205,8 @@
|
|||||||
|
|
||||||
.user-setting-toggle p {
|
.user-setting-toggle p {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-settings-subgroup .for-switch {
|
||||||
|
width: 38px !important;
|
||||||
}
|
}
|
@ -306,16 +306,16 @@
|
|||||||
You've used {{gh-count-down-characters this.user.bio 200}}
|
You've used {{gh-count-down-characters this.user.bio 200}}
|
||||||
</p>
|
</p>
|
||||||
</GhFormGroup>
|
</GhFormGroup>
|
||||||
|
{{#if this.membersUtils.isMembersEnabled}}
|
||||||
<div class="user-settings-subgroup">
|
<div class="user-settings-subgroup">
|
||||||
<h4 class="user-settings-heading">Email notifications</h4>
|
<h4 class="user-settings-heading">Email notifications</h4>
|
||||||
<GhFormGroup @errors={{this.user.errors}} @hasValidated={{this.user.hasValidated}} @property="email">
|
<GhFormGroup @errors={{this.user.errors}} @hasValidated={{this.user.hasValidated}} @property="email">
|
||||||
<div class="user-setting-toggle">
|
<div class="user-setting-toggle">
|
||||||
<div>
|
<div>
|
||||||
<label for="user-email">Comments</label>
|
<label for="user-email">Comments</label>
|
||||||
<p>Receive notifications when members comment on one of your posts</p>
|
<p>Every time a member comments on one of your posts</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="for-switch">
|
<div class="for-switch small">
|
||||||
<label class="switch" for="comment-notifications">
|
<label class="switch" for="comment-notifications">
|
||||||
<input
|
<input
|
||||||
id="comment-notifications"
|
id="comment-notifications"
|
||||||
@ -329,8 +329,70 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{#if (and this.canToggleMemberAlerts (feature 'emailAlerts'))}}
|
||||||
|
<div class="user-setting-toggle">
|
||||||
|
<div>
|
||||||
|
<label for="user-email">New signups</label>
|
||||||
|
<p>Every time a new free member signs up</p>
|
||||||
|
</div>
|
||||||
|
<div class="for-switch small">
|
||||||
|
<label class="switch" for="free-signup-notifications" data-test-label="free-signup-notifications">
|
||||||
|
<input
|
||||||
|
id="free-signup-notifications"
|
||||||
|
type="checkbox"
|
||||||
|
checked={{this.user.freeMemberSignupNotification}}
|
||||||
|
class="gh-input"
|
||||||
|
{{on "change" (fn this.toggleMemberEmailAlerts 'free-signup')}}
|
||||||
|
data-test-checkbox="free-signup-notifications"
|
||||||
|
>
|
||||||
|
<span class="input-toggle-component"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{#if this.membersUtils.paidMembersEnabled}}
|
||||||
|
<div class="user-setting-toggle">
|
||||||
|
<div>
|
||||||
|
<label for="user-email">New paid members</label>
|
||||||
|
<p>Every time a member starts a new paid subscription</p>
|
||||||
|
</div>
|
||||||
|
<div class="for-switch small">
|
||||||
|
<label class="switch" for="paid-started-notifications" data-test-label="paid-started-notifications">
|
||||||
|
<input
|
||||||
|
id="paid-started-notifications"
|
||||||
|
type="checkbox"
|
||||||
|
checked={{this.user.paidSubscriptionStartedNotification}}
|
||||||
|
class="gh-input"
|
||||||
|
{{on "change" (fn this.toggleMemberEmailAlerts 'paid-started')}}
|
||||||
|
data-test-checkbox="paid-started-notifications"
|
||||||
|
>
|
||||||
|
<span class="input-toggle-component"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="user-setting-toggle">
|
||||||
|
<div>
|
||||||
|
<label for="user-email">Paid member cancellations</label>
|
||||||
|
<p>Every time a member cancels their paid subscription</p>
|
||||||
|
</div>
|
||||||
|
<div class="for-switch small">
|
||||||
|
<label class="switch" for="paid-canceled-notifications" data-test-label="paid-canceled-notifications">
|
||||||
|
<input
|
||||||
|
id="paid-canceled-notifications"
|
||||||
|
type="checkbox"
|
||||||
|
checked={{this.user.paidSubscriptionCanceledNotification}}
|
||||||
|
class="gh-input"
|
||||||
|
{{on "change" (fn this.toggleMemberEmailAlerts 'paid-canceled')}}
|
||||||
|
data-test-checkbox="paid-canceled-notifications"
|
||||||
|
>
|
||||||
|
<span class="input-toggle-component"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
</GhFormGroup>
|
</GhFormGroup>
|
||||||
</div>
|
</div>
|
||||||
|
{{/if}}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -4,6 +4,10 @@ import windowProxy from 'ghost-admin/utils/window-proxy';
|
|||||||
import {Response} from 'miragejs';
|
import {Response} from 'miragejs';
|
||||||
import {afterEach, beforeEach, describe, it} from 'mocha';
|
import {afterEach, beforeEach, describe, it} from 'mocha';
|
||||||
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
||||||
|
import {enableLabsFlag} from '../helpers/labs-flag';
|
||||||
|
import {enableMembers} from '../helpers/members';
|
||||||
|
import {enableStripe} from '../helpers/stripe';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
blur,
|
blur,
|
||||||
click,
|
click,
|
||||||
@ -73,7 +77,11 @@ describe('Acceptance: Staff', function () {
|
|||||||
|
|
||||||
beforeEach(async function () {
|
beforeEach(async function () {
|
||||||
this.server.loadFixtures('roles');
|
this.server.loadFixtures('roles');
|
||||||
|
this.server.loadFixtures('settings');
|
||||||
adminRole = this.server.schema.roles.find(1);
|
adminRole = this.server.schema.roles.find(1);
|
||||||
|
enableMembers(this.server);
|
||||||
|
enableStripe(this.server);
|
||||||
|
enableLabsFlag(this.server, 'emailAlerts');
|
||||||
|
|
||||||
admin = this.server.create('user', {email: 'admin@example.com', roles: [adminRole]});
|
admin = this.server.create('user', {email: 'admin@example.com', roles: [adminRole]});
|
||||||
|
|
||||||
@ -816,6 +824,13 @@ describe('Acceptance: Staff', function () {
|
|||||||
expect(find('[data-test-slug-input]').value).to.be.equal('test-1');
|
expect(find('[data-test-slug-input]').value).to.be.equal('test-1');
|
||||||
expect(find('[data-test-facebook-input]').value).to.be.equal('https://www.facebook.com/test');
|
expect(find('[data-test-facebook-input]').value).to.be.equal('https://www.facebook.com/test');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('cannot see email alerts for other user', async function () {
|
||||||
|
await visit('/settings/staff/test-1');
|
||||||
|
expect(find('[data-test-checkbox="free-signup-notifications"]'), 'free signup alert').to.not.exist;
|
||||||
|
expect(find('[data-test-checkbox="paid-started-notifications"]'), 'paid start alert').to.not.exist;
|
||||||
|
expect(find('[data-test-checkbox="paid-canceled-notifications"]'), 'paid cancel alert').to.not.exist;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('own user', function () {
|
describe('own user', function () {
|
||||||
@ -856,6 +871,24 @@ describe('Acceptance: Staff', function () {
|
|||||||
'old password validation is in error state after typing'
|
'old password validation is in error state after typing'
|
||||||
).to.not.have.class('error');
|
).to.not.have.class('error');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can toggle email alerts for own user', async function () {
|
||||||
|
await visit(`/settings/staff/${admin.slug}`);
|
||||||
|
expect(find('[data-test-checkbox="free-signup-notifications"]')).to.not.be.checked;
|
||||||
|
expect(find('[data-test-checkbox="paid-started-notifications"]')).to.not.be.checked;
|
||||||
|
expect(find('[data-test-checkbox="paid-canceled-notifications"]')).to.not.be.checked;
|
||||||
|
|
||||||
|
await click('[data-test-label="free-signup-notifications"]');
|
||||||
|
await click('[data-test-label="paid-started-notifications"]');
|
||||||
|
await click('[data-test-label="paid-canceled-notifications"]');
|
||||||
|
|
||||||
|
await click('[data-test-save-button]');
|
||||||
|
await visit(`/settings/staff/${admin.slug}`);
|
||||||
|
|
||||||
|
expect(find('[data-test-checkbox="free-signup-notifications"]')).to.be.checked;
|
||||||
|
expect(find('[data-test-checkbox="paid-started-notifications"]')).to.be.checked;
|
||||||
|
expect(find('[data-test-checkbox="paid-canceled-notifications"]')).to.be.checked;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('redirects to 404 when user does not exist', async function () {
|
it('redirects to 404 when user does not exist', async function () {
|
||||||
|
@ -2,6 +2,10 @@ export function enableMembers(server) {
|
|||||||
server.db.settings.find({key: 'members_signup_access'})
|
server.db.settings.find({key: 'members_signup_access'})
|
||||||
? server.db.settings.update({key: 'members_signup_access'}, {value: 'all'})
|
? server.db.settings.update({key: 'members_signup_access'}, {value: 'all'})
|
||||||
: server.create('setting', {key: 'members_signup_access', value: 'all', group: 'members'});
|
: server.create('setting', {key: 'members_signup_access', value: 'all', group: 'members'});
|
||||||
|
|
||||||
|
server.db.settings.find({key: 'members_enabled'})
|
||||||
|
? server.db.settings.update({key: 'members_enabled'}, {value: true})
|
||||||
|
: server.create('setting', {key: 'members_enabled', value: true, group: 'members'});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function disableMembers(server) {
|
export function disableMembers(server) {
|
||||||
|
Loading…
Reference in New Issue
Block a user