mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-20 13:34:37 +01:00
Email Rules: Add default texts and document placeholders (#5314)
Applies default subject and body text on editing to simplify email rule setup. Once the text is edited manually, the defaus aren't applied on switching the rule type. Also documents the placeholders that can be used.
This commit is contained in:
parent
17d1832dad
commit
7873f94848
2 changed files with 75 additions and 33 deletions
|
@ -1,27 +0,0 @@
|
|||
@using Microsoft.AspNetCore.Server.Kestrel.Core
|
||||
@model BTCPayServer.Models.ServerViewModels.EmailsViewModel
|
||||
@{
|
||||
Layout = "../Shared/_NavLayout.cshtml";
|
||||
ViewData.SetActivePage(StoreNavPages.Emails, "Emails", Context.GetStoreData().Id);
|
||||
}
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col-xl-10 col-xxl-constrain">
|
||||
<div class="d-flex flex-wrap gap-3 align-items-center justify-content-between mt-n1 mb-4">
|
||||
<h3 class="mb-0">Email Rules</h3>
|
||||
<a class="btn btn-secondary" asp-action="StoreEmails" asp-controller="UIStores" asp-route-storeId="@Context.GetStoreData().Id" id="ConfigureEmailRules">
|
||||
Configure
|
||||
</a>
|
||||
</div>
|
||||
<p>
|
||||
<a asp-action="StoreEmails" asp-controller="UIStores" asp-route-storeId="@Context.GetStoreData().Id">Email rules</a>
|
||||
allow BTCPay Server to send customized emails from your store based on events.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<partial name="EmailsBody" model="Model" />
|
||||
|
||||
@section PageFootContent {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
}
|
|
@ -41,7 +41,7 @@
|
|||
<ul class="list-group list-group-flush">
|
||||
@for (var index = 0; index < Model.Rules.Count; index++)
|
||||
{
|
||||
<li class="list-group-item py-4 px-0">
|
||||
<li class="list-group-item py-4 px-0 email-rule">
|
||||
<div class="form-group">
|
||||
<div class="d-flex align-items-center justify-content-between gap-3">
|
||||
<label asp-for="Rules[index].Trigger" class="form-label" data-required></label>
|
||||
|
@ -55,30 +55,42 @@
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<select asp-for="Rules[index].Trigger" asp-items="@Html.GetEnumSelectList<WebhookEventType>()" class="form-select" required></select>
|
||||
<select asp-for="Rules[index].Trigger" asp-items="@Html.GetEnumSelectList<WebhookEventType>()" class="form-select email-rule-trigger" required></select>
|
||||
<span asp-validation-for="Rules[index].Trigger" class="text-danger"></span>
|
||||
<div class="form-text">Choose what event sends the email.</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Rules[index].To" class="form-label" data-required>Recipients</label>
|
||||
<input type="text" asp-for="Rules[index].To" class="form-control" />
|
||||
<input type="text" asp-for="Rules[index].To" class="form-control email-rule-to" />
|
||||
<span asp-validation-for="Rules[index].To" class="text-danger"></span>
|
||||
<div class="form-text">Who to send the email to. For multiple emails, separate with a comma.</div>
|
||||
</div>
|
||||
<div class="form-check mb-4">
|
||||
<input asp-for="Rules[index].CustomerEmail" type="checkbox" class="form-check-input" />
|
||||
<input asp-for="Rules[index].CustomerEmail" type="checkbox" class="form-check-input email-rule-customer-email" />
|
||||
<label asp-for="Rules[index].CustomerEmail" class="form-check-label">Send the email to the buyer, if email was provided to the invoice</label>
|
||||
<span asp-validation-for="Rules[index].CustomerEmail" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Rules[index].Subject" class="form-label" data-required></label>
|
||||
<input type="text" asp-for="Rules[index].Subject" class="form-control" />
|
||||
<input type="text" asp-for="Rules[index].Subject" class="form-control email-rule-subject" />
|
||||
<span asp-validation-for="Rules[index].Subject" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Rules[index].Body" class="form-label" data-required></label>
|
||||
<textarea asp-for="Rules[index].Body" class="form-control richtext" rows="4"></textarea>
|
||||
<textarea asp-for="Rules[index].Body" class="form-control richtext email-rule-body" rows="4"></textarea>
|
||||
<span asp-validation-for="Rules[index].Body" class="text-danger"></span>
|
||||
<div class="form-text d-flex gap-2">
|
||||
<div>Placeholders:</div>
|
||||
<div>
|
||||
<code>{Invoice.Id}</code>,
|
||||
<code>{Invoice.StoreId}</code>,
|
||||
<code>{Invoice.Price}</code>,
|
||||
<code>{Invoice.Currency}</code>,
|
||||
<code>{Invoice.Status}</code>,
|
||||
<code>{Invoice.AdditionalStatus}</code>,
|
||||
<code>{Invoice.OrderId}</code>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
|
@ -96,4 +108,61 @@
|
|||
@section PageFootContent {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
<script src="~/vendor/summernote/summernote-bs5.js" asp-append-version="true"></script>
|
||||
<script>
|
||||
(function () {
|
||||
const templates = {
|
||||
InvoiceCreated: {
|
||||
subject: 'Invoice {Invoice.Id} created',
|
||||
body: 'Invoice {Invoice.Id} (Order Id: {Invoice.OrderId}) created.'
|
||||
},
|
||||
InvoiceReceivedPayment: {
|
||||
subject: 'Invoice {Invoice.Id} received payment',
|
||||
body: 'Invoice {Invoice.Id} (Order Id: {Invoice.OrderId}) received payment.'
|
||||
},
|
||||
InvoiceProcessing: {
|
||||
subject: 'Invoice {Invoice.Id} processing',
|
||||
body: 'Invoice {Invoice.Id} (Order Id: {Invoice.OrderId}) is processing.'
|
||||
},
|
||||
InvoiceExpired: {
|
||||
subject: 'Invoice {Invoice.Id} expired',
|
||||
body: 'Invoice {Invoice.Id} (Order Id: {Invoice.OrderId}) expired.'
|
||||
},
|
||||
InvoiceSettled: {
|
||||
subject: 'Invoice {Invoice.Id} settled',
|
||||
body: 'Invoice {Invoice.Id} (Order Id: {Invoice.OrderId}) is settled.'
|
||||
},
|
||||
InvoiceInvalid: {
|
||||
subject: 'Invoice {Invoice.Id} invalid',
|
||||
body: 'Invoice {Invoice.Id} (Order Id: {Invoice.OrderId}) invalid.'
|
||||
},
|
||||
InvoicePaymentSettled: {
|
||||
subject: 'Invoice {Invoice.Id} payment settled',
|
||||
body: 'Invoice {Invoice.Id} (Order Id: {Invoice.OrderId}) payment settled.'
|
||||
},
|
||||
};
|
||||
const isEmptyOrDefault = (value, type) => {
|
||||
const val = value.replace(/<.*?>/gi, '').trim()
|
||||
if (!val) return true;
|
||||
return Object.values(templates).find(t => t[type] === val) != null;
|
||||
}
|
||||
const applyDefault = $trigger => {
|
||||
const $emailRule = $trigger.closest('.email-rule');
|
||||
const $subject = $emailRule.querySelector('.email-rule-subject');
|
||||
const $body = $emailRule.querySelector('.email-rule-body');
|
||||
const rule = $trigger.querySelector(`option[value='${$trigger.value}']`).innerText;
|
||||
const { subject, body } = templates[rule];
|
||||
if (isEmptyOrDefault($subject.value, 'subject') && subject) {
|
||||
$subject.value = subject;
|
||||
}
|
||||
if (isEmptyOrDefault($body.value, 'body') && body) {
|
||||
$($body).summernote('reset');
|
||||
$($body).summernote('insertText', body);
|
||||
}
|
||||
}
|
||||
delegate('change', '.email-rule-trigger', (e) => { applyDefault(e.target); })
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.querySelectorAll('.email-rule-trigger').forEach(applyDefault);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue