mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
🐛 Fixed unexpected "unsaved changes" modal when deleting a member
closes https://github.com/TryGhost/Team/issues/2275 When deleting a member, after confirming deletion another "unsaved changes" modal popped up. From that point, if you clicked to stay you remained on the member screen with stale data (the member was still deleted) resulting in further errors when any attempt to make changes was made. - prevented the unsaved changes check running for a deleted member because it would always return `true` in that case - ensured the data setup for the unsaved changes check still occurs when a member is accessed directly via the URL - previously it was skipped because the data setup only occurred inside `fetchMemberTask` but that isn't called when the route already loaded the model via it's `model()` hook
This commit is contained in:
parent
879aad263d
commit
3817f583fa
5 changed files with 84 additions and 5 deletions
|
@ -31,7 +31,20 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="gh-btn" type="button" {{on "click" (fn @close false)}}><span>Cancel</span></button>
|
||||
<GhTaskButton @buttonText={{if this.shouldCancelSubscriptions "Delete member + Cancel subscription" "Delete member"}} @successText="Deleted" @task={{this.deleteMemberTask}} @class="gh-btn gh-btn-red gh-btn-icon" />
|
||||
<button
|
||||
type="button"
|
||||
class="gh-btn"
|
||||
{{on "click" (fn @close false)}}
|
||||
data-test-button="cancel"
|
||||
>
|
||||
<span>Cancel</span>
|
||||
</button>
|
||||
<GhTaskButton
|
||||
@buttonText={{if this.shouldCancelSubscriptions "Delete member + Cancel subscription" "Delete member"}}
|
||||
@successText="Deleted"
|
||||
@task={{this.deleteMemberTask}}
|
||||
@class="gh-btn gh-btn-red gh-btn-icon"
|
||||
data-test-button="confirm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
|
@ -222,7 +222,7 @@ export default class MemberController extends Controller {
|
|||
_hasDirtyAttributes() {
|
||||
let member = this.member;
|
||||
|
||||
if (!member) {
|
||||
if (!member || member.isDeleted || member.isDeleting) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,9 @@ export default class MembersRoute extends AdminRoute {
|
|||
|
||||
setupController(controller, member, transition) {
|
||||
super.setupController(...arguments);
|
||||
|
||||
controller.setInitialRelationshipValues();
|
||||
|
||||
if (this._requiresBackgroundRefresh) {
|
||||
controller.fetchMemberTask.perform(member.id);
|
||||
}
|
||||
|
@ -38,7 +41,7 @@ export default class MembersRoute extends AdminRoute {
|
|||
if (transition.from?.name === 'posts.analytics') {
|
||||
// Sadly transition.from.params is not reliable to use (not populated on transitions)
|
||||
const oldParams = transition.router?.oldState?.params['posts.analytics'] ?? {};
|
||||
|
||||
|
||||
// We need to store analytics in 'this' to have it accessible for the member route
|
||||
this.fromAnalytics = Object.values(oldParams);
|
||||
controller.fromAnalytics = this.fromAnalytics;
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
@dropdownName="members-actions-menu"
|
||||
@classNames="gh-btn gh-btn-icon icon-only gh-btn-action-icon"
|
||||
@title="Members Actions"
|
||||
data-test-button="member-actions"
|
||||
>
|
||||
<span>
|
||||
{{svg-jar "settings"}}
|
||||
|
@ -58,7 +59,11 @@
|
|||
>
|
||||
<li>
|
||||
<button
|
||||
class="mr2" type="button" {{on "click" this.toggleImpersonateMemberModal}}>
|
||||
class="mr2"
|
||||
type="button"
|
||||
{{on "click" this.toggleImpersonateMemberModal}}
|
||||
data-test-button="impersonate"
|
||||
>
|
||||
<span>Impersonate</span>
|
||||
</button>
|
||||
</li>
|
||||
|
|
|
@ -205,5 +205,63 @@ describe('Acceptance: Members', function () {
|
|||
|
||||
expect(find('[data-test-modal="delete-members"]')).to.not.exist;
|
||||
});
|
||||
|
||||
it('can delete a member (via list)', async function () {
|
||||
const newsletter = this.server.create('newsletter');
|
||||
const label = this.server.create('label');
|
||||
this.server.createList('member', 2, {newsletters: [newsletter], labels: [label]});
|
||||
|
||||
await visit('/members');
|
||||
|
||||
expect(findAll('[data-test-member]').length).to.equal(2);
|
||||
|
||||
await click('[data-test-member] a');
|
||||
|
||||
expect(currentURL()).to.match(/members\/\d+/);
|
||||
|
||||
await click('[data-test-button="member-actions"]');
|
||||
await click('[data-test-button="delete-member"]');
|
||||
|
||||
expect(find('[data-test-modal="delete-member"]')).to.exist;
|
||||
|
||||
await click('[data-test-modal="delete-member"] [data-test-button="cancel"]');
|
||||
|
||||
expect(currentURL()).to.match(/members\/\d+/);
|
||||
expect(find('[data-test-modal="delete-member"]')).to.not.exist;
|
||||
|
||||
await click('[data-test-button="member-actions"]');
|
||||
await click('[data-test-button="delete-member"]');
|
||||
await click('[data-test-modal="delete-member"] [data-test-button="confirm"]');
|
||||
|
||||
expect(currentURL()).to.equal('/members');
|
||||
expect(findAll('[data-test-modal]')).to.have.length(0);
|
||||
expect(findAll('[data-test-member]')).to.have.length(1);
|
||||
});
|
||||
|
||||
it('can delete a member (via url)', async function () {
|
||||
const newsletter = this.server.create('newsletter');
|
||||
const label = this.server.create('label');
|
||||
const [memberOne] = this.server.createList('member', 2, {newsletters: [newsletter], labels: [label]});
|
||||
|
||||
await visit(`/members/${memberOne.id}`);
|
||||
|
||||
await click('[data-test-button="member-actions"]');
|
||||
await click('[data-test-button="delete-member"]');
|
||||
|
||||
expect(find('[data-test-modal="delete-member"]')).to.exist;
|
||||
|
||||
await click('[data-test-modal="delete-member"] [data-test-button="cancel"]');
|
||||
|
||||
expect(currentURL()).to.match(/members\/\d+/);
|
||||
expect(find('[data-test-modal="delete-member"]')).to.not.exist;
|
||||
|
||||
await click('[data-test-button="member-actions"]');
|
||||
await click('[data-test-button="delete-member"]');
|
||||
await click('[data-test-modal="delete-member"] [data-test-button="confirm"]');
|
||||
|
||||
expect(currentURL()).to.equal('/members');
|
||||
expect(findAll('[data-test-modal]')).to.have.length(0);
|
||||
expect(findAll('[data-test-member]')).to.have.length(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue