Add checkboxes to delete posts/comments

- fix tests
- rename files/directory to DeleteData to be more accurate
This commit is contained in:
Matt Rider 2019-06-12 15:07:16 -03:00
parent fc8792e7af
commit 83c7773d1b
5 changed files with 122 additions and 116 deletions

View File

@ -1,5 +1,5 @@
import { config, mount, createLocalVue } from '@vue/test-utils'
import DeleteAccount from './DeleteAccount.vue'
import { mount, createLocalVue } from '@vue/test-utils'
import DeleteData from './DeleteData.vue'
import Styleguide from '@human-connection/styleguide'
import Vuex from 'vuex'
@ -7,20 +7,18 @@ const localVue = createLocalVue()
localVue.use(Vuex)
localVue.use(Styleguide)
config.stubs['b-switch'] = '<span><slot /></span>'
config.stubs['b-checkbox'] = '<span><slot /></span>'
describe('DeleteAccount.vue', () => {
describe('DeleteData.vue', () => {
let mocks
let wrapper
let getters
let actions
let deleteAccountBtn
let enableDeletionInput
let enablePostDeletionInput
let enableCommentDeletionInput
let enableContributionDeletionCheckbox
let enableCommentDeletionCheckbox
const deleteAccountName = 'Delete MyAccount'
const deletePostsMessage = 'Delete my 2 posts'
const deleteContributionsMessage = 'Delete my 2 posts'
const deleteCommentsMessage = 'Delete my 3 comments'
beforeEach(() => {
@ -31,7 +29,7 @@ describe('DeleteAccount.vue', () => {
.fn()
.mockResolvedValueOnce({
data: {
DeleteAccount: {
DeleteData: {
id: 'u343',
},
},
@ -62,7 +60,7 @@ describe('DeleteAccount.vue', () => {
getters,
actions,
})
return mount(DeleteAccount, { mocks, localVue, store })
return mount(DeleteData, { mocks, localVue, store })
}
beforeEach(() => {
@ -111,9 +109,9 @@ describe('DeleteAccount.vue', () => {
})
it("deletes a user's posts if requested", () => {
mocks.$t.mockImplementation(() => deletePostsMessage)
enablePostDeletionInput = wrapper.find('.enable-post-deletion-input input')
enablePostDeletionInput.setValue(deletePostsMessage)
mocks.$t.mockImplementation(() => deleteContributionsMessage)
enableContributionDeletionCheckbox = wrapper.findAll('.checkbox-container input').at(0)
enableContributionDeletionCheckbox.trigger('click')
deleteAccountBtn.trigger('click')
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(
expect.objectContaining({
@ -127,8 +125,8 @@ describe('DeleteAccount.vue', () => {
it("deletes a user's comments if requested", () => {
mocks.$t.mockImplementation(() => deleteCommentsMessage)
enableCommentDeletionInput = wrapper.find('.enable-comment-deletion-input input')
enableCommentDeletionInput.setValue(deleteCommentsMessage)
enableCommentDeletionCheckbox = wrapper.findAll('.checkbox-container input').at(1)
enableCommentDeletionCheckbox.trigger('click')
deleteAccountBtn.trigger('click')
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(
expect.objectContaining({
@ -141,12 +139,12 @@ describe('DeleteAccount.vue', () => {
})
it("deletes a user's posts and comments if requested", () => {
mocks.$t.mockImplementation(() => deletePostsMessage)
enablePostDeletionInput = wrapper.find('.enable-post-deletion-input input')
enablePostDeletionInput.setValue(deletePostsMessage)
mocks.$t.mockImplementation(() => deleteContributionsMessage)
enableContributionDeletionCheckbox = wrapper.findAll('.checkbox-container input').at(0)
enableContributionDeletionCheckbox.trigger('click')
mocks.$t.mockImplementation(() => deleteCommentsMessage)
enableCommentDeletionInput = wrapper.find('.enable-comment-deletion-input input')
enableCommentDeletionInput.setValue(deleteCommentsMessage)
enableCommentDeletionCheckbox = wrapper.findAll('.checkbox-container input').at(1)
enableCommentDeletionCheckbox.trigger('click')
deleteAccountBtn.trigger('click')
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(
expect.objectContaining({
@ -163,7 +161,7 @@ describe('DeleteAccount.vue', () => {
expect(mocks.$toast.success).toHaveBeenCalledTimes(1)
})
it('updates the user in the store', async () => {
it('redirect the user to the homepage', async () => {
await deleteAccountBtn.trigger('click')
expect(mocks.$router.history.push).toHaveBeenCalledWith('/')
})

View File

@ -4,10 +4,10 @@
<ds-space />
<ds-container>
<ds-flex>
<ds-flex-item :width="{ base: '100%', sm: 0.75, md: 0.5, lg: 0.5 }">
<ds-flex-item :width="{ base: '22%', sm: '12%', md: '12%', lg: '8%' }">
<ds-icon name="warning" size="xxx-large" class="delete-warning-icon" />
</ds-flex-item>
<ds-flex-item :width="{ base: '100%', sm: 5.25, md: 2.75, lg: 5.5 }">
<ds-flex-item :width="{ base: '78%', sm: '88%', md: '88%', lg: '92%' }">
<ds-heading>{{ $t('settings.deleteUserAccount.name') }}</ds-heading>
</ds-flex-item>
<ds-space />
@ -20,62 +20,33 @@
<ds-container>
<transition name="slide-up">
<div v-if="deleteEnabled">
<div
class="delete-input-label"
v-html="
$t('settings.deleteUserAccount.pleaseConfirm', {
confirm: $t('settings.deleteUserAccount.contributionsCount', {
count: currentUser.contributionsCount,
}),
<label v-if="currentUser.contributionsCount" class="checkbox-container">
<input type="checkbox" v-model="deleteContributions" />
<span class="checkmark"></span>
{{
$t('settings.deleteUserAccount.contributionsCount', {
count: currentUser.contributionsCount,
})
"
></div>
<ds-space margin-bottom="xx-small" />
<ds-flex :gutter="{ base: 'xx-small', md: 'small', lg: 'large' }">
<ds-flex-item
v-if="currentUser.contributionsCount"
:width="{ base: '100%', sm: '100%', md: '100%', lg: '100%' }"
>
<ds-input
v-model="deleteContributionsValue"
@input="enableDeletion"
class="enable-post-deletion-input"
/>
</ds-flex-item>
</ds-flex>
<ds-space margin-bottom="xx-small" />
<div
class="delete-input-label"
v-html="
$t('settings.deleteUserAccount.pleaseConfirm', {
confirm: $t('settings.deleteUserAccount.commentsCount', {
count: currentUser.commentsCount,
}),
}}
</label>
<ds-space margin-bottom="small" />
<label v-if="currentUser.commentsCount" class="checkbox-container">
<input type="checkbox" v-model="deleteComments" />
<span class="checkmark"></span>
{{
$t('settings.deleteUserAccount.commentsCount', {
count: currentUser.commentsCount,
})
"
></div>
<ds-space margin-bottom="xx-small" />
<ds-flex :gutter="{ base: 'xx-small', md: 'small', lg: 'large' }">
<ds-flex-item
v-if="currentUser.commentsCount"
:width="{ base: '100%', sm: '100%', md: '100%', lg: '100%' }"
>
<ds-input
v-model="deleteCommentsValue"
@input="enableDeletion"
class="enable-comment-deletion-input"
/>
</ds-flex-item>
<ds-flex-item :width="{ base: '100%', sm: '100%', md: '100%', lg: '100%' }">
<ds-section id="delete-user-account-warning">
<div v-html="$t('settings.deleteUserAccount.accountWarning')"></div>
</ds-section>
</ds-flex-item>
</ds-flex>
}}
</label>
<ds-space margin-bottom="small" />
<ds-section id="delete-user-account-warning">
<div v-html="$t('settings.deleteUserAccount.accountWarning')"></div>
</ds-section>
</div>
</transition>
</ds-container>
<template slot="footer">
<template slot="footer" class="delete-data-footer">
<ds-container>
<div
class="delete-input-label"
@ -91,12 +62,7 @@
/>
</ds-flex-item>
<ds-flex-item :width="{ base: '100%', sm: '100%', md: '100%', lg: 1 }">
<ds-button
icon="trash"
danger
:disabled="isLoading || !deleteEnabled"
@click="handleSubmit"
>
<ds-button icon="trash" danger :disabled="!deleteEnabled" @click="handleSubmit">
{{ $t('settings.deleteUserAccount.name') }}
</ds-button>
</ds-flex-item>
@ -111,16 +77,12 @@ import { mapGetters, mapActions } from 'vuex'
import gql from 'graphql-tag'
export default {
name: 'DeleteAccount',
name: 'DeleteData',
data() {
return {
deleteContributions: false,
deleteComments: false,
deleteEnabled: false,
isLoading: false,
enableDeletionValue: '',
deleteContributionsValue: '',
deleteCommentsValue: '',
}
},
computed: {
@ -135,23 +97,6 @@ export default {
enableDeletion() {
if (this.enableDeletionValue === this.currentUser.name) {
this.deleteEnabled = true
this.focused = false
}
if (
this.deleteContributionsValue ===
this.$t('settings.deleteUserAccount.contributionsCount', {
count: this.currentUser.contributionsCount,
})
) {
this.deleteContributions = true
}
if (
this.deleteCommentsValue ===
this.$t('settings.deleteUserAccount.commentsCount', {
count: this.currentUser.commentsCount,
})
) {
this.deleteComments = true
}
},
handleSubmit() {
@ -190,9 +135,72 @@ export default {
color: $color-danger;
}
.enable-deletion-input input:focus,
.enable-post-deletion-input input:focus,
.enable-comment-deletion-input input:focus {
.checkbox-container {
display: block;
position: relative;
padding-left: 35px;
cursor: pointer;
font-size: $font-size-large;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.checkbox-container input {
position: absolute;
opacity: 0;
cursor: pointer;
height: 0;
width: 0;
}
.checkmark {
position: absolute;
top: 0;
left: 0;
height: 20px;
width: 20px;
border: 2px solid $background-color-inverse-softer;
background-color: $background-color-base;
border-radius: $border-radius-x-large;
}
.checkbox-container:hover input ~ .checkmark {
background-color: $background-color-softest;
}
/* When the checkbox is checked, add a blue background */
.checkbox-container input:checked ~ .checkmark {
background-color: $background-color-danger-active;
}
/* Create the checkmark/indicator (hidden when not checked) */
.checkmark:after {
content: '';
position: absolute;
display: none;
}
/* Show the checkmark when checked */
.checkbox-container input:checked ~ .checkmark:after {
display: block;
}
/* Style the checkmark/indicator */
.checkbox-container .checkmark:after {
left: 6px;
top: 3px;
width: 5px;
height: 10px;
border: solid $background-color-base;
border-width: 0 $border-size-large $border-size-large 0;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
.enable-deletion-input input:focus {
border-color: $border-color-danger;
}
@ -204,7 +212,7 @@ b.is-danger {
color: $text-color-danger;
}
.ds-card-footer {
.delete-data-footer {
border-top: $border-size-base solid $border-color-softest;
background-color: $background-color-danger-inverse;
}

View File

@ -74,13 +74,13 @@
"name": "Daten herunterladen"
},
"deleteUserAccount": {
"name": "Mein Benutzerkonto löschen",
"name": "Daten löschen",
"contributionsCount": "Meine {count} Beiträge löschen",
"commentsCount": "Meine {count} Kommentare löschen",
"accountDescription": "Seien Sie sich bewusst, dass Ihre Beiträge und Kommentare für unsere Community wichtig sind. Wenn du sie trotzdem löschen möchtest, musst du dies unten auswählen.",
"accountWarning": "Dein Benutzerkonto, die Beiträge, etc. kannst Du nach dem Löschen <b>WEDER VERWALTEN NOCH WIEDERHERSTELLEN!</b>",
"accountDescription": "Sie dir bewusst, dass deine Beiträge und Kommentare für unsere Community wichtig sind. Wenn du sie trotzdem löschen möchtest, musst du sie unten markieren.",
"accountWarning": "Dein Konto, Beiträge oder Kommentare kannst Du nach dem Löschen <b>WEDER VERWALTEN NOCH WIEDERHERSTELLEN!</b>",
"success": "Konto erfolgreich gelöscht",
"pleaseConfirm": "<b class='is-danger'>Zerstörerische Aktion!</b> Geben Sie <b>{confirm}</b> ein, um zu bestätigen."
"pleaseConfirm": "<b class='is-danger'>Zerstörerische Aktion!</b> Gib <b>{confirm}</b> ein, um zu bestätigen."
},
"organizations": {
"name": "Meine Organisationen"

View File

@ -74,11 +74,11 @@
"name": "Download Data"
},
"deleteUserAccount": {
"name": "Delete my User Account",
"name": "Delete Data",
"contributionsCount": "Delete my {count} posts",
"commentsCount": "Delete my {count} comments",
"accountDescription": "Be aware that your Post and Comments are important to our community. If you still want to delete them, you have to choose so below.",
"accountWarning": "You <b>CAN'T MANAGE</b> and <b>CAN'T RECOVER</b> your Account, Posts... after deleting your account!",
"accountDescription": "Be aware that your Post and Comments are important to our community. If you still choose to delete them, you have to mark them below.",
"accountWarning": "You <b>CAN'T MANAGE</b> and <b>CAN'T RECOVER</b> your Account, Posts, or Comments after deleting your account!",
"success": "Account successfully deleted",
"pleaseConfirm": "<b class='is-danger'>Destructive action!</b> Type <b>{confirm}</b> to confirm"
},

View File

@ -1,13 +1,13 @@
<template>
<delete-account />
<delete-data />
</template>
<script>
import DeleteAccount from '~/components/DeleteAccount/DeleteAccount.vue'
import DeleteData from '~/components/DeleteData/DeleteData.vue'
export default {
components: {
DeleteAccount,
DeleteData,
},
}
</script>