Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(bans): minor corrections #12739

Merged
merged 4 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions src/components/ConversationSettings/BanSettings/BannedItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<template>
<li :key="ban.id" class="ban-item">
<div class="ban-item__header">
<span class="ban-item__caption">{{ ban.bannedId }}</span>
<span class="ban-item__caption">{{ ban.bannedDisplayName }}</span>
<div class="ban-item__buttons">
<NcButton type="tertiary" @click="showDetails = !showDetails">
{{ showDetails ? t('spreed', 'Hide details') : t('spreed', 'Show details') }}
Expand All @@ -17,8 +17,10 @@
</div>
</div>
<ul v-if="showDetails" class="ban-item__hint">
<!-- eslint-disable-next-line vue/no-v-html -->
<li v-for="(item, index) in banInfo" :key="index" v-html="item" />
<li v-for="(item, index) in banInfo" :key="index">
<strong>{{ item.label }}</strong>
<span>{{ item.value }}</span>
</li>
</ul>
</li>
</template>
Expand Down Expand Up @@ -54,12 +56,12 @@ export default {
computed: {
banInfo() {
return [
t('spreed', '<strong>Banned by:</strong> {actor}', { actor: this.ban.actorId },
undefined, { escape: false, sanitize: false }),
t('spreed', '<strong>Date:</strong> {date}', { date: moment(this.ban.bannedTime * 1000).format('lll') },
undefined, { escape: false, sanitize: false }),
t('spreed', '<strong>Note:</strong> {note}', { note: this.ban.internalNote },
undefined, { escape: false, sanitize: false }),
// TRANSLATORS name of a moderator who banned a participant
{ label: t('spreed', 'Banned by:'), value: this.ban.moderatorDisplayName },
// TRANSLATORS Date and time of ban creation
{ label: t('spreed', 'Date:'), value: moment(this.ban.bannedTime * 1000).format('lll') },
// TRANSLATORS Internal note for moderators, usually a reason for this ban
{ label: t('spreed', 'Note:'), value: this.ban.internalNote },
]
},
},
Expand Down
21 changes: 14 additions & 7 deletions src/components/RightSidebar/Participants/Participant.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
import NcDialog from '@nextcloud/vue/dist/Components/NcDialog.js'
import NcInputField from '@nextcloud/vue/dist/Components/NcInputField.js'
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
import NcTextArea from '@nextcloud/vue/dist/Components/NcTextArea.js'

import Participant from './Participant.vue'
import AvatarWrapper from '../../AvatarWrapper/AvatarWrapper.vue'
Expand Down Expand Up @@ -113,7 +113,7 @@ describe('Participant.vue', () => {
NcCheckboxRadioSwitch,
NcDialog,
NcInputField,
NcTextField,
NcTextArea,
},
directives: {
tooltip: tooltipMock,
Expand Down Expand Up @@ -676,10 +676,10 @@ describe('Participant.vue', () => {
const checkbox = dialog.findComponent(NcCheckboxRadioSwitch)
await checkbox.find('input').trigger('change')

const input = dialog.findComponent(NcTextField)
expect(input.exists()).toBeTruthy()
input.find('input').setValue(internalNote)
await input.find('input').trigger('change')
const textarea = dialog.findComponent(NcTextArea)
expect(textarea.exists()).toBeTruthy()
textarea.find('textarea').setValue(internalNote)
await textarea.find('textarea').trigger('change')

const button = findNcButton(dialog, 'Remove')
await button.find('button').trigger('click')
Expand Down Expand Up @@ -766,12 +766,19 @@ describe('Participant.vue', () => {
await testCannotRemove()
})

test('allows a moderator to ban a moderator', async () => {
test('allows a moderator to ban a user', async () => {
conversation.participantType = PARTICIPANT.TYPE.MODERATOR
participant.participantType = PARTICIPANT.TYPE.USER
await testCanBan()
})

test('allows a moderator to ban a federated user', async () => {
conversation.participantType = PARTICIPANT.TYPE.MODERATOR
participant.actorType = ATTENDEE.ACTOR_TYPE.FEDERATED_USERS
participant.participantType = PARTICIPANT.TYPE.USER
await testCanBan()
})

test('allows a moderator to ban a guest', async () => {
conversation.participantType = PARTICIPANT.TYPE.MODERATOR
participant.participantType = PARTICIPANT.TYPE.GUEST
Expand Down
50 changes: 36 additions & 14 deletions src/components/RightSidebar/Participants/Participant.vue
Original file line number Diff line number Diff line change
Expand Up @@ -318,17 +318,20 @@
{{ t('spreed', 'Also ban from this conversation') }}
</NcCheckboxRadioSwitch>
<template v-if="isBanParticipant">
<NcTextField v-if="isBanParticipant"
<NcTextArea v-if="isBanParticipant"
class="participant-dialog__input"
resize="vertical"
:label="t('spreed', 'Internal note (reason to ban)')"
:error="!!maxLengthWarning"
:helper-text="maxLengthWarning"
:value.sync="internalNote" />
</template>
</template>
<template #actions>
<NcButton type="tertiary" @click="isRemoveDialogOpen = false">
<NcButton type="tertiary" :disabled="isLoading" @click="isRemoveDialogOpen = false">
{{ t('spreed', 'Dismiss') }}
</NcButton>
<NcButton type="error" @click="removeParticipant">
<NcButton type="error" :disabled="isLoading || !!maxLengthWarning" @click="removeParticipant">
{{ t('spreed', 'Remove') }}
</NcButton>
</template>
Expand Down Expand Up @@ -376,7 +379,7 @@ import NcActionText from '@nextcloud/vue/dist/Components/NcActionText.js'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
import NcDialog from '@nextcloud/vue/dist/Components/NcDialog.js'
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
import NcTextArea from '@nextcloud/vue/dist/Components/NcTextArea.js'
import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip.js'

import ParticipantPermissionsEditor from './ParticipantPermissionsEditor.vue'
Expand Down Expand Up @@ -411,7 +414,7 @@ export default {
NcButton,
NcCheckboxRadioSwitch,
NcDialog,
NcTextField,
NcTextArea,
ParticipantPermissionsEditor,
// Icons
Account,
Expand Down Expand Up @@ -488,6 +491,7 @@ export default {
isBanParticipant: false,
internalNote: '',
disabled: false,
isLoading: false,
}
},

Expand Down Expand Up @@ -796,10 +800,21 @@ export default {
return this.canBeModerated
&& !this.isModerator
&& (this.participant.actorType === ATTENDEE.ACTOR_TYPE.USERS
|| this.participant.actorType === ATTENDEE.ACTOR_TYPE.FEDERATED_USERS
|| this.participant.actorType === ATTENDEE.ACTOR_TYPE.GUESTS
|| this.participant.actorType === ATTENDEE.ACTOR_TYPE.EMAILS)
},

maxLengthWarning() {
if (this.internalNote.length <= 4000) {
return ''
}
return t('spreed', 'The text must be less than or equal to {maxLength} characters long. Your current text is {charactersCount} characters long.', {
maxLength: 4000,
charactersCount: this.internalNote.length,
Antreesy marked this conversation as resolved.
Show resolved Hide resolved
})
},

removeParticipantLabel() {
switch (this.participant.actorType) {
case ATTENDEE.ACTOR_TYPE.GROUPS:
Expand Down Expand Up @@ -995,15 +1010,22 @@ export default {
},

async removeParticipant() {
await this.$store.dispatch('removeParticipant', {
token: this.token,
attendeeId: this.attendeeId,
banParticipant: this.isBanParticipant,
internalNote: this.internalNote,
})
this.isBanParticipant = false
this.internalNote = ''
this.isRemoveDialogOpen = false
this.isLoading = true
try {
await this.$store.dispatch('removeParticipant', {
token: this.token,
attendeeId: this.attendeeId,
banParticipant: this.isBanParticipant,
internalNote: this.internalNote,
})
this.isBanParticipant = false
this.internalNote = ''
this.isRemoveDialogOpen = false
} catch (error) {
console.error('Error while removing the participant: ', error)
} finally {
this.isLoading = false
}
},

grantAllPermissions() {
Expand Down
2 changes: 1 addition & 1 deletion src/store/participantsStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ const actions = {
showSuccess(t('spreed', 'Participant is banned successfully'))
} catch (error) {
showError(t('spreed', 'Error while banning the participant'))
console.error('Error while banning the participant: ', error)
throw error
}
}
await removeAttendeeFromConversation(token, attendeeId)
Expand Down
2 changes: 1 addition & 1 deletion src/views/ForbiddenView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<template>
<EmptyView :name="t('spreed', 'You do not have permissions to access this conversation.')"
:description="t('spreed', 'Join a conversation or start a new one!')">
:description="t('spreed', 'Join a different conversation or start a new one.')">
<template #icon>
<Octagon />
</template>
Expand Down
Loading