Merge pull request 'refs #5941 feat: when error can send email to support' (!1670) from 5941-send-to-support into dev
gitea/salix/pipeline/head This commit looks good Details

Reviewed-on: #1670
Reviewed-by: Juan Ferrer <juan@verdnatura.es>
Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
This commit is contained in:
Alex Moreno 2023-08-17 07:16:45 +00:00
commit 9fffa1601a
13 changed files with 165 additions and 13 deletions

View File

@ -0,0 +1,63 @@
const smtp = require('vn-print/core/smtp');
const config = require('vn-print/core/config');
module.exports = Self => {
Self.remoteMethodCtx('sendToSupport', {
description: 'Send mail to support',
accessType: 'WRITE',
accepts: [
{
arg: 'reason',
type: 'string',
description: 'The reason'
},
{
arg: 'additionalData',
type: 'object',
required: true,
description: 'The additional data'
}
],
returns: {
type: 'object',
root: true
},
http: {
path: `/send-to-support`,
verb: 'POST'
}
});
Self.sendToSupport = async(ctx, reason, additionalData) => {
const emailUser =
await Self.app.models.EmailUser.findById(ctx.req.accessToken.userId, {fields: ['email']});
let html = `<strong>Motivo</strong>:<br/>${reason}<br/>`;
for (const data in additionalData)
html += `<strong>${data}</strong>:<br/>${tryParse(additionalData[data])}<br/>`;
const subjectReason = JSON.parse(additionalData?.httpRequest)?.data?.error;
smtp.send({
to: config.app.reportEmail,
replyTo: emailUser.email,
subject:
'[Support-Salix] ' +
additionalData?.frontPath + ' ' +
subjectReason?.name + ':' +
subjectReason?.message,
html
});
};
function tryParse(value) {
try {
try {
value = JSON.parse(value);
} catch {}
return JSON.stringify(value, null, '&nbsp;').split('\n').join('<br>');
} catch {
return value;
}
}
};

View File

@ -1,4 +1,5 @@
module.exports = Self => {
require('../methods/osticket/osTicketReportEmail')(Self);
require('../methods/osticket/closeTicket')(Self);
require('../methods/osticket/sendToSupport')(Self);
};

View File

@ -55,3 +55,4 @@ import './datalist';
import './contextmenu';
import './rating';
import './smart-table';
import './support-dialog';

View File

@ -1 +1,5 @@
<div id="shapes"></div>
<div id="shapes"></div>
<vn-support-dialog
vn-id="support-dialog"
additional-data="$ctrl.additionalData">
</vn-support-dialog>

View File

@ -27,6 +27,18 @@ export default class Controller extends Component {
setTimeout(() => element.classList.add('shown'), 30);
shape.element = element;
if (data.additionalData) {
this.additionalData = data.additionalData;
let supportButton = document.createElement('i');
supportButton.setAttribute('class', 'material-icons clickable');
supportButton.addEventListener('click', () => this.$.supportDialog.show());
element.appendChild(supportButton);
let buttonIcon = 'support_agent';
buttonIcon = document.createTextNode(buttonIcon);
supportButton.appendChild(buttonIcon);
}
if (shape.type)
element.classList.add(shape.type);
@ -95,7 +107,7 @@ export default class Controller extends Component {
clearTimeout(shape.hideTimeout);
shape.hideTimeout = setTimeout(
() => this.hide(shape), shape.timeout || 3000);
() => this.hide(shape), shape.timeout || 5000);
this.lastShape = shape;
}

View File

@ -20,11 +20,15 @@ vn-snackbar .shape {
margin-bottom: 15px;
color: white;
padding: 12px 25px 12px 12px;
display: flex ;
flex-direction: row;
justify-content: center;
align-items: center;
& > .text {
text-align: center;
vn-chip {
vn-chip {
position: absolute;
left: -16px;
top: -16px;
@ -64,4 +68,12 @@ vn-snackbar .shape {
top: 0;
right: 0
}
}
.clickable{
background-color: $color-main;
padding: 6px;
border-radius: 50%;
cursor: pointer;
margin-right: 7px;
}
}

View File

@ -0,0 +1,22 @@
<tpl-body>
<section>
<h5 class="vn-py-sm" translate>Send cau</h5>
<vn-horizontal>
<vn-textarea vn-one
label="ExplainReason"
ng-model="$ctrl.reason"
rows="2"
required="true">
</vn-textarea>
</vn-horizontal>
<vn-horizontal>
<span>
{{'By sending this ticket, all the data related to the error, the section, the user, etc., are already sent.' | translate}}
</span>
</vn-horizontal>
</section>
</tpl-body>
<tpl-buttons>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Send</button>
</tpl-buttons>

View File

@ -0,0 +1,27 @@
import ngModule from '../../module';
import Dialog from '../dialog';
export default class Controller extends Dialog {
constructor($element, $, $transclude) {
super($element, $, $transclude);
}
responseHandler(response) {
this.$http.post('Ostickets/send-to-support', {
reason: this.reason,
additionalData: this.additionalData
})
.then(() => super.responseHandler(response))
.then(() => this.vnApp.showSuccess(this.$t('Email sended!')));
}
}
Controller.$inject = ['$element', '$scope', '$transclude'];
ngModule.vnComponent('vnSupportDialog', {
slotTemplate: require('./index.html'),
controller: Controller,
bindings: {
additionalData: '<?'
}
});

View File

@ -13,4 +13,5 @@ Finalize: Finalize
Previous: Back
Load more: Load more
Auto-scroll interrupted, please adjust the search: Auto-scroll interrupted, please adjust the search
General search: General search
General search: General search
ExplainReason: Explain the reason why this error should not occur

View File

@ -64,3 +64,6 @@ No results found: Sin resultados
No data: Sin datos
Undo changes: Deshacer cambios
Load more results: Cargar más resultados
Send cau: Enviar cau
By sending this ticket, all the data related to the error, the section, the user, etc., are already sent.: Al enviar este cau ya se envían todos los datos relacionados con el error, la sección, el usuario, etc
ExplainReason: Explique el motivo por el que no deberia aparecer este fallo

View File

@ -23,9 +23,9 @@ export default class App {
this.logger.showSuccess(message);
}
showError(message) {
showError(message, additionalData) {
if (this.logger)
this.logger.showError(message);
this.logger.showError(message, additionalData);
}
pushLoader() {

View File

@ -25,15 +25,15 @@ export default class App extends Component {
}
showMessage(message) {
this.$.snackbar.show({message: message});
this.$.snackbar.show({message});
}
showSuccess(message) {
this.$.snackbar.showSuccess({message: message});
this.$.snackbar.showSuccess({message});
}
showError(message) {
this.$.snackbar.showError({message: message});
showError(message, additionalData) {
this.$.snackbar.showError({message, additionalData});
}
}

View File

@ -148,7 +148,13 @@ function $exceptionHandler(vnApp, $window, $state, $injector) {
if (messageT)
message = $translate.instant(messageT);
vnApp.showError(message);
const additonalData = {
frontPath: $state.current.name,
httpRequest: cause?.replace('Possibly unhandled rejection: ', ''),
backError: exception
};
vnApp.showError(message, additonalData);
};
}
ngModule.factory('$exceptionHandler', $exceptionHandler);