Improvements to the templates
This commit is contained in:
parent
3feb32c0f6
commit
fc7b42c3d6
@ -297,15 +297,9 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService {
|
|||||||
|
|
||||||
if (StringUtils.isNotEmpty(email)) {
|
if (StringUtils.isNotEmpty(email)) {
|
||||||
result.forEach((apiFeature, stateValue) -> {
|
result.forEach((apiFeature, stateValue) -> {
|
||||||
ApiUsageRecordKey[] keys = ApiUsageRecordKey.getKeys(apiFeature);
|
|
||||||
ApiUsageStateMailMessage[] msgs = new ApiUsageStateMailMessage[keys.length];
|
|
||||||
for (int i = 0; i < keys.length; i++) {
|
|
||||||
ApiUsageRecordKey key = keys[i];
|
|
||||||
msgs[i] = new ApiUsageStateMailMessage(key, state.getProfileThreshold(key), state.get(key));
|
|
||||||
}
|
|
||||||
mailExecutor.submit(() -> {
|
mailExecutor.submit(() -> {
|
||||||
try {
|
try {
|
||||||
mailService.sendApiFeatureStateEmail(apiFeature, stateValue, email, msgs[0]);
|
mailService.sendApiFeatureStateEmail(apiFeature, stateValue, email, createStateMailMessage(state, apiFeature, stateValue));
|
||||||
} catch (ThingsboardException e) {
|
} catch (ThingsboardException e) {
|
||||||
log.warn("[{}] Can't send update of the API state to tenant with provided email [{}]", state.getTenantId(), email, e);
|
log.warn("[{}] Can't send update of the API state to tenant with provided email [{}]", state.getTenantId(), email, e);
|
||||||
}
|
}
|
||||||
@ -316,6 +310,33 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ApiUsageStateMailMessage createStateMailMessage(TenantApiUsageState state, ApiFeature apiFeature, ApiUsageStateValue stateValue) {
|
||||||
|
StateChecker checker = getStateChecker(stateValue);
|
||||||
|
for (ApiUsageRecordKey apiUsageRecordKey : ApiUsageRecordKey.getKeys(apiFeature)) {
|
||||||
|
long threshold = state.getProfileThreshold(apiUsageRecordKey);
|
||||||
|
long warnThreshold = state.getProfileWarnThreshold(apiUsageRecordKey);
|
||||||
|
long value = state.get(apiUsageRecordKey);
|
||||||
|
if (checker.check(threshold, warnThreshold, value)) {
|
||||||
|
return new ApiUsageStateMailMessage(apiUsageRecordKey, threshold, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private StateChecker getStateChecker(ApiUsageStateValue stateValue) {
|
||||||
|
if (ApiUsageStateValue.ENABLED.equals(stateValue)) {
|
||||||
|
return (t, wt, v) -> true;
|
||||||
|
} else if (ApiUsageStateValue.WARNING.equals(stateValue)) {
|
||||||
|
return (t, wt, v) -> v < t && v >= wt;
|
||||||
|
} else {
|
||||||
|
return (t, wt, v) -> v >= t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface StateChecker {
|
||||||
|
boolean check(long threshold, long warnThreshold, long value);
|
||||||
|
}
|
||||||
|
|
||||||
private void checkStartOfNextCycle() {
|
private void checkStartOfNextCycle() {
|
||||||
updateLock.lock();
|
updateLock.lock();
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -30,6 +30,7 @@ import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
|
|||||||
import org.thingsboard.rule.engine.api.MailService;
|
import org.thingsboard.rule.engine.api.MailService;
|
||||||
import org.thingsboard.server.common.data.AdminSettings;
|
import org.thingsboard.server.common.data.AdminSettings;
|
||||||
import org.thingsboard.server.common.data.ApiFeature;
|
import org.thingsboard.server.common.data.ApiFeature;
|
||||||
|
import org.thingsboard.server.common.data.ApiUsageRecordKey;
|
||||||
import org.thingsboard.server.common.data.ApiUsageStateMailMessage;
|
import org.thingsboard.server.common.data.ApiUsageStateMailMessage;
|
||||||
import org.thingsboard.server.common.data.ApiUsageStateValue;
|
import org.thingsboard.server.common.data.ApiUsageStateValue;
|
||||||
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
|
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
|
||||||
@ -261,19 +262,36 @@ public class DefaultMailService implements MailService {
|
|||||||
|
|
||||||
switch (stateValue) {
|
switch (stateValue) {
|
||||||
case ENABLED:
|
case ENABLED:
|
||||||
|
model.put("apiLabel", toEnabledValueLabel(apiFeature));
|
||||||
message = mergeTemplateIntoString("state.enabled.ftl", model);
|
message = mergeTemplateIntoString("state.enabled.ftl", model);
|
||||||
break;
|
break;
|
||||||
case WARNING:
|
case WARNING:
|
||||||
|
model.put("apiLimitValueLabel", toDisabledValueLabel(msg.getKey(), msg.getThreshold()));
|
||||||
|
model.put("apiValueLabel", toDisabledValueLabel(apiFeature) + " " + toDisabledValueLabel(msg.getKey(), msg.getValue()));
|
||||||
message = mergeTemplateIntoString("state.warning.ftl", model);
|
message = mergeTemplateIntoString("state.warning.ftl", model);
|
||||||
break;
|
break;
|
||||||
case DISABLED:
|
case DISABLED:
|
||||||
model.put("apiLimitValueLabel", toDisabledValueLabel(apiFeature) + " " + toDisabledValueLabel(msg));
|
model.put("apiLimitValueLabel", toDisabledValueLabel(apiFeature) + " " + toDisabledValueLabel(msg.getKey(), msg.getThreshold()));
|
||||||
message = mergeTemplateIntoString("state.disabled.ftl", model);
|
message = mergeTemplateIntoString("state.disabled.ftl", model);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sendMail(mailSender, mailFrom, email, subject, message);
|
sendMail(mailSender, mailFrom, email, subject, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String toEnabledValueLabel(ApiFeature apiFeature) {
|
||||||
|
switch (apiFeature) {
|
||||||
|
case DB:
|
||||||
|
return "save";
|
||||||
|
case TRANSPORT:
|
||||||
|
return "receive";
|
||||||
|
case JS:
|
||||||
|
case RE:
|
||||||
|
return "invoke";
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Not implemented!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String toDisabledValueLabel(ApiFeature apiFeature) {
|
private String toDisabledValueLabel(ApiFeature apiFeature) {
|
||||||
switch (apiFeature) {
|
switch (apiFeature) {
|
||||||
case DB:
|
case DB:
|
||||||
@ -288,17 +306,17 @@ public class DefaultMailService implements MailService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toDisabledValueLabel(ApiUsageStateMailMessage msg) {
|
private String toDisabledValueLabel(ApiUsageRecordKey key, long value) {
|
||||||
switch (msg.getKey()) {
|
switch (key) {
|
||||||
case STORAGE_DP_COUNT:
|
case STORAGE_DP_COUNT:
|
||||||
case TRANSPORT_DP_COUNT:
|
case TRANSPORT_DP_COUNT:
|
||||||
return (msg.getThreshold() / 1000000) + "M data points";
|
return (value / 1000000) + "M data points";
|
||||||
case TRANSPORT_MSG_COUNT:
|
case TRANSPORT_MSG_COUNT:
|
||||||
return (msg.getThreshold() / 1000000) + "M messages";
|
return (value / 1000000) + "M messages";
|
||||||
case JS_EXEC_COUNT:
|
case JS_EXEC_COUNT:
|
||||||
return (msg.getThreshold() / 1000000) + "M JavaScript functions";
|
return (value / 1000000) + "M JavaScript functions";
|
||||||
case RE_EXEC_COUNT:
|
case RE_EXEC_COUNT:
|
||||||
return (msg.getThreshold() / 1000000) + "M Rule Engine nodes";
|
return (value / 1000000) + "M Rule Engine nodes";
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Not implemented!");
|
throw new RuntimeException("Not implemented!");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,112 +15,141 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width"/>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
<title>Thingsboard - Api Usage State</title>
|
<title>Thingsboard - Api Usage State</title>
|
||||||
|
|
||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
img {
|
img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
body {
|
|
||||||
-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em;
|
body {
|
||||||
}
|
-webkit-font-smoothing: antialiased;
|
||||||
body {
|
-webkit-text-size-adjust: none;
|
||||||
background-color: #f6f6f6;
|
width: 100% !important;
|
||||||
}
|
height: 100%;
|
||||||
@media only screen and (max-width: 640px) {
|
line-height: 1.6em;
|
||||||
body {
|
}
|
||||||
padding: 0 !important;
|
|
||||||
}
|
body {
|
||||||
h1 {
|
background-color: #f6f6f6;
|
||||||
font-weight: 800 !important; margin: 20px 0 5px !important;
|
}
|
||||||
}
|
|
||||||
h2 {
|
@media only screen and (max-width: 640px) {
|
||||||
font-weight: 800 !important; margin: 20px 0 5px !important;
|
body {
|
||||||
}
|
padding: 0 !important;
|
||||||
h3 {
|
}
|
||||||
font-weight: 800 !important; margin: 20px 0 5px !important;
|
|
||||||
}
|
h1 {
|
||||||
h4 {
|
font-weight: 800 !important;
|
||||||
font-weight: 800 !important; margin: 20px 0 5px !important;
|
margin: 20px 0 5px !important;
|
||||||
}
|
}
|
||||||
h1 {
|
|
||||||
font-size: 22px !important;
|
h2 {
|
||||||
}
|
font-weight: 800 !important;
|
||||||
h2 {
|
margin: 20px 0 5px !important;
|
||||||
font-size: 18px !important;
|
}
|
||||||
}
|
|
||||||
h3 {
|
h3 {
|
||||||
font-size: 16px !important;
|
font-weight: 800 !important;
|
||||||
}
|
margin: 20px 0 5px !important;
|
||||||
.container {
|
}
|
||||||
padding: 0 !important; width: 100% !important;
|
|
||||||
}
|
h4 {
|
||||||
.content {
|
font-weight: 800 !important;
|
||||||
padding: 0 !important;
|
margin: 20px 0 5px !important;
|
||||||
}
|
}
|
||||||
.content-wrap {
|
|
||||||
padding: 10px !important;
|
h1 {
|
||||||
}
|
font-size: 22px !important;
|
||||||
.invoice {
|
}
|
||||||
width: 100% !important;
|
|
||||||
}
|
h2 {
|
||||||
}
|
font-size: 18px !important;
|
||||||
</style>
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrap {
|
||||||
|
padding: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invoice {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body itemscope itemtype="http://schema.org/EmailMessage" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;" bgcolor="#f6f6f6">
|
<body itemscope itemtype="http://schema.org/EmailMessage"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;"
|
||||||
|
bgcolor="#f6f6f6">
|
||||||
|
|
||||||
<table class="body-wrap" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; background-color: #f6f6f6; margin: 0;" bgcolor="#f6f6f6"><tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"><td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top"></td>
|
<table class="main"
|
||||||
<td class="container" width="600" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto;" valign="top">
|
style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; box-sizing: border-box; border-radius: 3px; width: 100%; background-color: #f6f6f6; margin: 0px auto;"
|
||||||
<div class="content" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; max-width: 600px; display: block; margin: 0 auto; padding: 20px;">
|
cellspacing="0" cellpadding="0" bgcolor="#f6f6f6">
|
||||||
<table class="main" width="100%" cellpadding="0" cellspacing="0" itemprop="action" itemscope itemtype="http://schema.org/ConfirmAction" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background-color: #fff; margin: 0; border: 1px solid #e9e9e9;" bgcolor="#fff"><tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"><td class="content-wrap" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 20px;" valign="top">
|
<tbody>
|
||||||
<meta itemprop="name" content="Confirm Email" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;" /><table width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
<tr style="box-sizing: border-box; margin: 0px;">
|
||||||
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
<td class="content-wrap" style="box-sizing: border-box; vertical-align: top; margin: 0px; padding: 20px;"
|
||||||
<td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; color: #348eda; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
|
align="center" valign="top">
|
||||||
<h2>Thingsboard Api Usage State for tenant has been updated</h2>
|
<table style="box-sizing: border-box; border: 1px solid #e9e9e9; border-radius: 3px; margin: 0px; height: 223px; padding: 20px; background-color: #ffffff; width: 600px; max-width: 600px !important;"
|
||||||
</td>
|
width="600" cellspacing="0" cellpadding="0">
|
||||||
</tr>
|
<tbody>
|
||||||
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0 ;">
|
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
<td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
|
<td class="content-block"
|
||||||
Thingsboard Usage state ${apiFeature} was updated to status ENABLED.
|
style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: #348eda; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0px; padding: 0px 0px 20px; height: 84px;"
|
||||||
</td>
|
valign="top">
|
||||||
</tr>
|
<h2>Your ThingsBoard account feature was enabled</h2>
|
||||||
<#list apiUsageStateMailMessages as msg>
|
</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>
|
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
${msg.key.apiLimitKey} = ${msg.threshold}
|
<td class="content-block"
|
||||||
</td>
|
style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0px; padding: 0px 0px 20px; height: 40px;"
|
||||||
</tr>
|
valign="top">We have enabled the ${apiFeature} for your account and ThingsBoard already able to ${apiLabel} messages.
|
||||||
<tr>
|
</td>
|
||||||
<td>
|
</tr>
|
||||||
${msg.key.apiCountKey} = ${msg.value}
|
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
</td>
|
<td class="content-block"
|
||||||
</tr>
|
style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0px; padding: 0px 0px 20px; height: 40px;"
|
||||||
</#list>
|
valign="top">— The ThingsBoard
|
||||||
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
</td>
|
||||||
<td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
|
</tr>
|
||||||
— The Thingsboard
|
</tbody>
|
||||||
</td>
|
</table>
|
||||||
</tr></table></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="footer" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; clear: both; color: #999; margin: 0; padding: 20px;">
|
|
||||||
<table width="100%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
|
||||||
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
|
||||||
<td class="aligncenter content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0; padding: 0 0 20px;" align="center" valign="top">This email was sent to <a href="mailto:${targetEmail}" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: underline; margin: 0;">${targetEmail}</a> by Thingsboard.</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top"></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<table style="color: #999999; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; box-sizing: border-box; margin: 0px auto; height: 64px; background-color: #f6f6f6; width: 100%;"
|
||||||
|
cellpadding="0px 0px 20px">
|
||||||
|
<tbody>
|
||||||
|
<tr style="box-sizing: border-box; margin: 0px;">
|
||||||
|
<td class="aligncenter content-block"
|
||||||
|
style="box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px 0px 20px; width: 600px; text-align: center; vertical-align: middle;"
|
||||||
|
align="center" valign="top">This email was sent to <a
|
||||||
|
style="box-sizing: border-box; color: #999999; margin: 0px;"
|
||||||
|
href="mailto:${targetEmail}">${targetEmail}</a> by ThingsBoard.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -15,112 +15,148 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width"/>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
<title>Thingsboard - Api Usage State</title>
|
<title>Thingsboard - Api Usage State</title>
|
||||||
|
|
||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
img {
|
img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
body {
|
|
||||||
-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em;
|
body {
|
||||||
}
|
-webkit-font-smoothing: antialiased;
|
||||||
body {
|
-webkit-text-size-adjust: none;
|
||||||
background-color: #f6f6f6;
|
width: 100% !important;
|
||||||
}
|
height: 100%;
|
||||||
@media only screen and (max-width: 640px) {
|
line-height: 1.6em;
|
||||||
body {
|
}
|
||||||
padding: 0 !important;
|
|
||||||
}
|
body {
|
||||||
h1 {
|
background-color: #f6f6f6;
|
||||||
font-weight: 800 !important; margin: 20px 0 5px !important;
|
}
|
||||||
}
|
|
||||||
h2 {
|
@media only screen and (max-width: 640px) {
|
||||||
font-weight: 800 !important; margin: 20px 0 5px !important;
|
body {
|
||||||
}
|
padding: 0 !important;
|
||||||
h3 {
|
}
|
||||||
font-weight: 800 !important; margin: 20px 0 5px !important;
|
|
||||||
}
|
h1 {
|
||||||
h4 {
|
font-weight: 800 !important;
|
||||||
font-weight: 800 !important; margin: 20px 0 5px !important;
|
margin: 20px 0 5px !important;
|
||||||
}
|
}
|
||||||
h1 {
|
|
||||||
font-size: 22px !important;
|
h2 {
|
||||||
}
|
font-weight: 800 !important;
|
||||||
h2 {
|
margin: 20px 0 5px !important;
|
||||||
font-size: 18px !important;
|
}
|
||||||
}
|
|
||||||
h3 {
|
h3 {
|
||||||
font-size: 16px !important;
|
font-weight: 800 !important;
|
||||||
}
|
margin: 20px 0 5px !important;
|
||||||
.container {
|
}
|
||||||
padding: 0 !important; width: 100% !important;
|
|
||||||
}
|
h4 {
|
||||||
.content {
|
font-weight: 800 !important;
|
||||||
padding: 0 !important;
|
margin: 20px 0 5px !important;
|
||||||
}
|
}
|
||||||
.content-wrap {
|
|
||||||
padding: 10px !important;
|
h1 {
|
||||||
}
|
font-size: 22px !important;
|
||||||
.invoice {
|
}
|
||||||
width: 100% !important;
|
|
||||||
}
|
h2 {
|
||||||
}
|
font-size: 18px !important;
|
||||||
</style>
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrap {
|
||||||
|
padding: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invoice {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body itemscope itemtype="http://schema.org/EmailMessage" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;" bgcolor="#f6f6f6">
|
<body itemscope itemtype="http://schema.org/EmailMessage"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;"
|
||||||
|
bgcolor="#f6f6f6">
|
||||||
|
|
||||||
<table class="body-wrap" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; background-color: #f6f6f6; margin: 0;" bgcolor="#f6f6f6"><tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"><td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top"></td>
|
<table class="main"
|
||||||
<td class="container" width="600" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto;" valign="top">
|
style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; box-sizing: border-box; border-radius: 3px; width: 100%; background-color: #f6f6f6; margin: 0px auto;"
|
||||||
<div class="content" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; max-width: 600px; display: block; margin: 0 auto; padding: 20px;">
|
cellspacing="0" cellpadding="0" bgcolor="#f6f6f6">
|
||||||
<table class="main" width="100%" cellpadding="0" cellspacing="0" itemprop="action" itemscope itemtype="http://schema.org/ConfirmAction" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background-color: #fff; margin: 0; border: 1px solid #e9e9e9;" bgcolor="#fff"><tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"><td class="content-wrap" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 20px;" valign="top">
|
<tbody>
|
||||||
<meta itemprop="name" content="Confirm Email" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;" /><table width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
<tr style="box-sizing: border-box; margin: 0px;">
|
||||||
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
<td class="content-wrap" style="box-sizing: border-box; vertical-align: top; margin: 0px; padding: 20px;"
|
||||||
<td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; color: #348eda; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
|
align="center" valign="top">
|
||||||
<h2>Thingsboard Api Usage State for tenant has been updated</h2>
|
<table style="box-sizing: border-box; border: 1px solid #e9e9e9; border-radius: 3px; margin: 0px; height: 223px; padding: 20px; background-color: #ffffff; width: 600px; max-width: 600px !important;"
|
||||||
</td>
|
width="600" cellspacing="0" cellpadding="0">
|
||||||
</tr>
|
<tbody>
|
||||||
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
<td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
|
<td class="content-block"
|
||||||
Thingsboard Usage state ${apiFeature} was updated to status WARNING.
|
style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: #348eda; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0px; padding: 0px 0px 20px; height: 84px;"
|
||||||
</td>
|
valign="top">
|
||||||
</tr>
|
<h2>Your ThingsBoard account feature may be disabled</h2>
|
||||||
<#list apiUsageStateMailMessages as msg>
|
</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>
|
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
${msg.key.apiLimitKey} = ${msg.threshold}
|
<td class="content-block"
|
||||||
</td>
|
style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0px; padding: 0px 0px 20px; height: 40px;"
|
||||||
</tr>
|
valign="top">
|
||||||
<tr>
|
Your ${apiFeature} limit (${apiLimitValueLabel}) is almost exhausted. <br>ThingsBoard has already ${apiValueLabel}.<br> ${apiFeature} will be disabled for your account when limit will be reached.
|
||||||
<td>
|
</td>
|
||||||
${msg.key.apiCountKey} = ${msg.value}
|
</tr>
|
||||||
</td>
|
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
</tr>
|
<td class="content-block"
|
||||||
</#list>
|
style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0px; padding: 0px 0px 20px; height: 59px;"
|
||||||
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
valign="top">Please contact your system administrator to resolve the issue.
|
||||||
<td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
|
</td>
|
||||||
— The Thingsboard
|
</tr>
|
||||||
</td>
|
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
</tr></table></td>
|
<td class="content-block"
|
||||||
</tr>
|
style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0px; padding: 0px 0px 20px; height: 40px;"
|
||||||
</table>
|
valign="top">— The ThingsBoard
|
||||||
<div class="footer" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; clear: both; color: #999; margin: 0; padding: 20px;">
|
</td>
|
||||||
<table width="100%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
</tr>
|
||||||
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
</tbody>
|
||||||
<td class="aligncenter content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0; padding: 0 0 20px;" align="center" valign="top">This email was sent to <a href="mailto:${targetEmail}" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: underline; margin: 0;">${targetEmail}</a> by Thingsboard.</td>
|
</table>
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top"></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<table style="color: #999999; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; box-sizing: border-box; margin: 0px auto; height: 64px; background-color: #f6f6f6; width: 100%;"
|
||||||
|
cellpadding="0px 0px 20px">
|
||||||
|
<tbody>
|
||||||
|
<tr style="box-sizing: border-box; margin: 0px;">
|
||||||
|
<td class="aligncenter content-block"
|
||||||
|
style="box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px 0px 20px; width: 600px; text-align: center; vertical-align: middle;"
|
||||||
|
align="center" valign="top">This email was sent to <a
|
||||||
|
style="box-sizing: border-box; color: #999999; margin: 0px;"
|
||||||
|
href="mailto:${targetEmail}">${targetEmail}</a> by ThingsBoard.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user