Skip to content

Commit

Permalink
Merge pull request #3110 from nextcloud/fix/confirmation-mails
Browse files Browse the repository at this point in the history
Fix confirmation mails and move CTAs
  • Loading branch information
dartcafe committed Oct 15, 2023
2 parents 691f51c + c68569e commit 27f5fcb
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 156 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ All notable changes to this project will be documented in this file.
- Fixed granting admin rights to shares
- Fixed a bug, where exports were prevented
- Fixed a visually bug when using Nextcloud's Dark Mode
- Fixed result reporting about sent and failed confirmation mails
### New
- Reveal hidden voters if hidden in case of performance concerns
- Support better readability of vote page
- Added locking of shares
- Shares can now be locked which works as a read only share mechanism. Locked shares can still enter the poll, but every interaction (voting and commenting) is disabled.
- Deletion of locked shares deletes the users votes as well
- Moved request for option proposals to a card on top of the vote page
- Moved CTA for confirmation mails to card on top of the vote page
- Added a card with a more prominent hint for closed polls

### Changes
- Improved username check for public polls with a large number of groups in the backend
## [5.3.2] - 2023-09-11
Expand Down
22 changes: 5 additions & 17 deletions lib/Service/MailService.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,14 @@ public function sendConfirmations(int $pollId): SentResult {

foreach ($participants as $participant) {
try {
$this->sendConfirmationMail($sentResult, $participant, $pollId);
$this->sendConfirmationMail($participant, $pollId);
$sentResult->AddSentMail($participant);
} catch (InvalidEmailAddress $e) {
$sentResult->AddAbortedMail($participant, SentResult::INVALID_EMAIL_ADDRESS);
$this->logger->warning('Invalid or no email address for confirmation: ' . json_encode($participant));
$sentResult->AddAbortedMail($participant, SentResult::INVALID_EMAIL_ADDRESS);
} catch (\Exception $e) {
$sentResult->AddAbortedMail($participant);
$this->logger->error('Error sending confirmation to ' . json_encode($participant));
$sentResult->AddAbortedMail($participant);
}
}

Expand All @@ -179,21 +179,9 @@ private function processSharesForAutoReminder(Poll $poll): void {
}
}

private function sendConfirmationMail(SentResult &$sentResult, UserBase $participant, int $pollId) : SentResult {
private function sendConfirmationMail(UserBase $participant, int $pollId): void {
$confirmation = new ConfirmationMail($participant->getId(), $pollId);

try {
$confirmation->send();
$sentResult->AddSentMail($participant);
} catch (InvalidEmailAddress $e) {
$sentResult->AddAbortedMail($participant, SentResult::INVALID_EMAIL_ADDRESS);
$this->logger->warning('Invalid or no email address for confirmation: ' . json_encode($participant));
} catch (\Exception $e) {
$sentResult->AddAbortedMail($participant);
$this->logger->error('Error sending confirmation to ' . json_encode($participant));
}

return $sentResult;
$confirmation->send();
}

private function sendAutoReminderToRecipients(Share $share, Poll $poll): void {
Expand Down
2 changes: 1 addition & 1 deletion src/js/components/Actions/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export { default as ActionChangeView } from './modules/ActionChangeView.vue'
export { default as ActionDelete } from './modules/ActionDelete.vue'
export { default as ActionSendConfirmedOptions } from './modules/ActionSendConfirmedOptions.vue'
export { default as ActionSendConfirmed } from './modules/ActionSendConfirmed.vue'
export { default as ActionSortOptions } from './modules/ActionSortOptions.vue'
export { default as ActionToggleSidebar } from './modules/ActionToggleSidebar.vue'
113 changes: 113 additions & 0 deletions src/js/components/Actions/modules/ActionSendConfirmed.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<!--
- @copyright Copyright (c) 2021 René Gieling <github@dartcafe.de>
-
- @author René Gieling <github@dartcafe.de>
-
- @license GNU AGPL version 3 or any later version
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-->

<template>
<div class="action send-confirmations">
<NcButton v-tooltip="sendButtonCaption"
type="primary"
:aria-label="sendButtonCaption"
:disabled="disableButton"
@click="clickAction()">
<template #icon>
<EmailCheckIcon />
</template>
<template #default>
{{ t('polls', 'Send confirmation emails') }}
</template>
</NcButton>

<NcModal :show.sync="showModal"
:title="t('polls', 'Result of sent confirmation mails')"
size="small">
<div class="modal-confirmation-result">
<div v-if="confirmations?.countSentMails > 0" class="sent-confirmations">
<h2>{{ n('polls', '%n confirmation has been sent', '%n confirmations have been sent', confirmations.countSentMails) }}</h2>
<ul>
<li v-for="(item) in confirmations.sentMails" :key="item.displayName">
{{ item.displayName }} &lt;{{ item.emailAddress }}&gt;
</li>
</ul>
</div>
<div v-if="confirmations?.countAbortedMails > 0" class="error-confirmations">
<h2>{{ n('polls', '%n confirmation could not be sent', '%n confirmations could not be sent:', confirmations.countAbortedMails) }}</h2>
<ul>
<li v-for="(item) in confirmations.abortedMails" :key="item.displayName">
{{ item.displayName }} ({{ item.reason === 'InvalidMail' ? t('polls', 'No valid email address') : t('polls', 'Unknown error') }})
</li>
</ul>
</div>
</div>
</NcModal>
</div>
</template>
<script>
import { NcButton, NcModal } from '@nextcloud/vue'
import EmailCheckIcon from 'vue-material-design-icons/EmailCheck.vue' // view-comfy-outline
import { PollsAPI } from '../../../Api/index.js'
export default {
name: 'ActionSendConfirmed',
components: {
EmailCheckIcon,
NcButton,
NcModal,
},
data() {
return {
showModal: false,
sendButtonCaption: t('polls', 'Send information about confirmed options by email'),
confirmations: null,
disableButton: false,
}
},
methods: {
async clickAction() {
try {
this.disableButton = true
const result = await PollsAPI.sendConfirmation(this.$route.params.id)
this.disableButton = false
this.confirmations = result.data.confirmations
this.showModal = true
} catch (e) {
console.error(e)
}
},
},
}
</script>
<style lang="scss">
.modal-confirmation-result {
padding: 24px;
ul {
list-style: initial;
}
.sent-confirmations, .error-confirmations {
padding: 12px;
}
}
</style>
128 changes: 0 additions & 128 deletions src/js/components/Actions/modules/ActionSendConfirmedOptions.vue

This file was deleted.

33 changes: 23 additions & 10 deletions src/js/views/Vote.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,28 @@
</template>
</CardDiv>

<CardDiv v-if="closed" type="warning">
<CardDiv v-if="acl.allowAddOptions && proposalsOpen && !closed" type="success">
{{ t('polls', 'You are asked to propose more options. ') }}
<p v-if="proposalsExpirySet && !proposalsExpired">
{{ t('polls', 'The proposal period ends {timeRelative}.', { timeRelative: proposalsExpireRelative }) }}
</p>
<OptionProposals v-if="poll.type === 'textPoll'" />
<template #button>
<OptionProposals v-if="poll.type === 'datePoll'" />
</template>
</CardDiv>

<CardDiv v-if="closed && !showConfirmationMail" type="warning">
{{ t('polls', 'This poll is closed. No further action is possible.') }}
</CardDiv>

<CardDiv v-else-if="showConfirmationMail" type="success">
{{ t('polls', 'You have confirmed options. Inform your participants about the result via email.') }}
<template #button>
<ActionSendConfirmed />
</template>
</CardDiv>

<CardDiv v-else-if="share.locked" type="warning">
{{ lockedShareCardCaption }}
</CardDiv>
Expand All @@ -55,13 +73,6 @@
<MarkUpDescription />
</div>

<div v-if="acl.allowAddOptions && proposalsOpen && !closed" class="area__proposal">
<OptionProposals />
</div>
<div v-if="showConfirmationMail" class="area__confirmation">
<ActionSendConfirmedOptions />
</div>

<div class="area__main" :class="viewMode">
<VoteTable v-show="options.length" :view-mode="viewMode" />

Expand Down Expand Up @@ -115,12 +126,12 @@ import PollHeaderButtons from '../components/Poll/PollHeaderButtons.vue'
import { CardDiv, HeaderBar } from '../components/Base/index.js'
import DatePollIcon from 'vue-material-design-icons/CalendarBlank.vue'
import TextPollIcon from 'vue-material-design-icons/FormatListBulletedSquare.vue'
import { ActionSendConfirmedOptions } from '../components/Actions/index.js'
import { ActionSendConfirmed } from '../components/Actions/index.js'
export default {
name: 'Vote',
components: {
ActionSendConfirmedOptions,
ActionSendConfirmed,
NcAppContent,
NcButton,
NcEmptyContent,
Expand Down Expand Up @@ -159,6 +170,8 @@ export default {
viewMode: 'poll/viewMode',
proposalsAllowed: 'poll/proposalsAllowed',
proposalsOpen: 'poll/proposalsOpen',
proposalsExpirySet: 'poll/proposalsExpirySet',
proposalsExpireRelative: 'poll/proposalsExpireRelative',
countHiddenParticipants: 'poll/countHiddenParticipants',
safeTable: 'poll/safeTable',
confirmedOptions: 'options/confirmed',
Expand Down

0 comments on commit 27f5fcb

Please sign in to comment.