Commit fc7b42c3d6738a63905b0c02b42ee2f7681a9d1e
Committed by
Andrew Shvayka
1 parent
3feb32c0
Improvements to the templates
Showing
4 changed files
with
320 additions
and
216 deletions
application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java
@@ -297,15 +297,9 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { | @@ -297,15 +297,9 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { | ||
297 | 297 | ||
298 | if (StringUtils.isNotEmpty(email)) { | 298 | if (StringUtils.isNotEmpty(email)) { |
299 | result.forEach((apiFeature, stateValue) -> { | 299 | result.forEach((apiFeature, stateValue) -> { |
300 | - ApiUsageRecordKey[] keys = ApiUsageRecordKey.getKeys(apiFeature); | ||
301 | - ApiUsageStateMailMessage[] msgs = new ApiUsageStateMailMessage[keys.length]; | ||
302 | - for (int i = 0; i < keys.length; i++) { | ||
303 | - ApiUsageRecordKey key = keys[i]; | ||
304 | - msgs[i] = new ApiUsageStateMailMessage(key, state.getProfileThreshold(key), state.get(key)); | ||
305 | - } | ||
306 | mailExecutor.submit(() -> { | 300 | mailExecutor.submit(() -> { |
307 | try { | 301 | try { |
308 | - mailService.sendApiFeatureStateEmail(apiFeature, stateValue, email, msgs[0]); | 302 | + mailService.sendApiFeatureStateEmail(apiFeature, stateValue, email, createStateMailMessage(state, apiFeature, stateValue)); |
309 | } catch (ThingsboardException e) { | 303 | } catch (ThingsboardException e) { |
310 | log.warn("[{}] Can't send update of the API state to tenant with provided email [{}]", state.getTenantId(), email, e); | 304 | log.warn("[{}] Can't send update of the API state to tenant with provided email [{}]", state.getTenantId(), email, e); |
311 | } | 305 | } |
@@ -316,6 +310,33 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { | @@ -316,6 +310,33 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { | ||
316 | } | 310 | } |
317 | } | 311 | } |
318 | 312 | ||
313 | + private ApiUsageStateMailMessage createStateMailMessage(TenantApiUsageState state, ApiFeature apiFeature, ApiUsageStateValue stateValue) { | ||
314 | + StateChecker checker = getStateChecker(stateValue); | ||
315 | + for (ApiUsageRecordKey apiUsageRecordKey : ApiUsageRecordKey.getKeys(apiFeature)) { | ||
316 | + long threshold = state.getProfileThreshold(apiUsageRecordKey); | ||
317 | + long warnThreshold = state.getProfileWarnThreshold(apiUsageRecordKey); | ||
318 | + long value = state.get(apiUsageRecordKey); | ||
319 | + if (checker.check(threshold, warnThreshold, value)) { | ||
320 | + return new ApiUsageStateMailMessage(apiUsageRecordKey, threshold, value); | ||
321 | + } | ||
322 | + } | ||
323 | + return null; | ||
324 | + } | ||
325 | + | ||
326 | + private StateChecker getStateChecker(ApiUsageStateValue stateValue) { | ||
327 | + if (ApiUsageStateValue.ENABLED.equals(stateValue)) { | ||
328 | + return (t, wt, v) -> true; | ||
329 | + } else if (ApiUsageStateValue.WARNING.equals(stateValue)) { | ||
330 | + return (t, wt, v) -> v < t && v >= wt; | ||
331 | + } else { | ||
332 | + return (t, wt, v) -> v >= t; | ||
333 | + } | ||
334 | + } | ||
335 | + | ||
336 | + private interface StateChecker { | ||
337 | + boolean check(long threshold, long warnThreshold, long value); | ||
338 | + } | ||
339 | + | ||
319 | private void checkStartOfNextCycle() { | 340 | private void checkStartOfNextCycle() { |
320 | updateLock.lock(); | 341 | updateLock.lock(); |
321 | try { | 342 | try { |
@@ -30,6 +30,7 @@ import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; | @@ -30,6 +30,7 @@ import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; | ||
30 | import org.thingsboard.rule.engine.api.MailService; | 30 | import org.thingsboard.rule.engine.api.MailService; |
31 | import org.thingsboard.server.common.data.AdminSettings; | 31 | import org.thingsboard.server.common.data.AdminSettings; |
32 | import org.thingsboard.server.common.data.ApiFeature; | 32 | import org.thingsboard.server.common.data.ApiFeature; |
33 | +import org.thingsboard.server.common.data.ApiUsageRecordKey; | ||
33 | import org.thingsboard.server.common.data.ApiUsageStateMailMessage; | 34 | import org.thingsboard.server.common.data.ApiUsageStateMailMessage; |
34 | import org.thingsboard.server.common.data.ApiUsageStateValue; | 35 | import org.thingsboard.server.common.data.ApiUsageStateValue; |
35 | import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; | 36 | import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; |
@@ -261,19 +262,36 @@ public class DefaultMailService implements MailService { | @@ -261,19 +262,36 @@ public class DefaultMailService implements MailService { | ||
261 | 262 | ||
262 | switch (stateValue) { | 263 | switch (stateValue) { |
263 | case ENABLED: | 264 | case ENABLED: |
265 | + model.put("apiLabel", toEnabledValueLabel(apiFeature)); | ||
264 | message = mergeTemplateIntoString("state.enabled.ftl", model); | 266 | message = mergeTemplateIntoString("state.enabled.ftl", model); |
265 | break; | 267 | break; |
266 | case WARNING: | 268 | case WARNING: |
269 | + model.put("apiLimitValueLabel", toDisabledValueLabel(msg.getKey(), msg.getThreshold())); | ||
270 | + model.put("apiValueLabel", toDisabledValueLabel(apiFeature) + " " + toDisabledValueLabel(msg.getKey(), msg.getValue())); | ||
267 | message = mergeTemplateIntoString("state.warning.ftl", model); | 271 | message = mergeTemplateIntoString("state.warning.ftl", model); |
268 | break; | 272 | break; |
269 | case DISABLED: | 273 | case DISABLED: |
270 | - model.put("apiLimitValueLabel", toDisabledValueLabel(apiFeature) + " " + toDisabledValueLabel(msg)); | 274 | + model.put("apiLimitValueLabel", toDisabledValueLabel(apiFeature) + " " + toDisabledValueLabel(msg.getKey(), msg.getThreshold())); |
271 | message = mergeTemplateIntoString("state.disabled.ftl", model); | 275 | message = mergeTemplateIntoString("state.disabled.ftl", model); |
272 | break; | 276 | break; |
273 | } | 277 | } |
274 | sendMail(mailSender, mailFrom, email, subject, message); | 278 | sendMail(mailSender, mailFrom, email, subject, message); |
275 | } | 279 | } |
276 | 280 | ||
281 | + private String toEnabledValueLabel(ApiFeature apiFeature) { | ||
282 | + switch (apiFeature) { | ||
283 | + case DB: | ||
284 | + return "save"; | ||
285 | + case TRANSPORT: | ||
286 | + return "receive"; | ||
287 | + case JS: | ||
288 | + case RE: | ||
289 | + return "invoke"; | ||
290 | + default: | ||
291 | + throw new RuntimeException("Not implemented!"); | ||
292 | + } | ||
293 | + } | ||
294 | + | ||
277 | private String toDisabledValueLabel(ApiFeature apiFeature) { | 295 | private String toDisabledValueLabel(ApiFeature apiFeature) { |
278 | switch (apiFeature) { | 296 | switch (apiFeature) { |
279 | case DB: | 297 | case DB: |
@@ -288,17 +306,17 @@ public class DefaultMailService implements MailService { | @@ -288,17 +306,17 @@ public class DefaultMailService implements MailService { | ||
288 | } | 306 | } |
289 | } | 307 | } |
290 | 308 | ||
291 | - private String toDisabledValueLabel(ApiUsageStateMailMessage msg) { | ||
292 | - switch (msg.getKey()) { | 309 | + private String toDisabledValueLabel(ApiUsageRecordKey key, long value) { |
310 | + switch (key) { | ||
293 | case STORAGE_DP_COUNT: | 311 | case STORAGE_DP_COUNT: |
294 | case TRANSPORT_DP_COUNT: | 312 | case TRANSPORT_DP_COUNT: |
295 | - return (msg.getThreshold() / 1000000) + "M data points"; | 313 | + return (value / 1000000) + "M data points"; |
296 | case TRANSPORT_MSG_COUNT: | 314 | case TRANSPORT_MSG_COUNT: |
297 | - return (msg.getThreshold() / 1000000) + "M messages"; | 315 | + return (value / 1000000) + "M messages"; |
298 | case JS_EXEC_COUNT: | 316 | case JS_EXEC_COUNT: |
299 | - return (msg.getThreshold() / 1000000) + "M JavaScript functions"; | 317 | + return (value / 1000000) + "M JavaScript functions"; |
300 | case RE_EXEC_COUNT: | 318 | case RE_EXEC_COUNT: |
301 | - return (msg.getThreshold() / 1000000) + "M Rule Engine nodes"; | 319 | + return (value / 1000000) + "M Rule Engine nodes"; |
302 | default: | 320 | default: |
303 | throw new RuntimeException("Not implemented!"); | 321 | throw new RuntimeException("Not implemented!"); |
304 | } | 322 | } |
@@ -15,112 +15,141 @@ | @@ -15,112 +15,141 @@ | ||
15 | limitations under the License. | 15 | limitations under the License. |
16 | 16 | ||
17 | --> | 17 | --> |
18 | -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
19 | -<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;"> | 18 | +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" |
19 | + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
20 | +<html xmlns="http://www.w3.org/1999/xhtml" | ||
21 | + style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
20 | <head> | 22 | <head> |
21 | -<meta name="viewport" content="width=device-width" /> | ||
22 | -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | ||
23 | -<title>Thingsboard - Api Usage State</title> | ||
24 | - | ||
25 | - | ||
26 | -<style type="text/css"> | ||
27 | -img { | ||
28 | -max-width: 100%; | ||
29 | -} | ||
30 | -body { | ||
31 | --webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; | ||
32 | -} | ||
33 | -body { | ||
34 | -background-color: #f6f6f6; | ||
35 | -} | ||
36 | -@media only screen and (max-width: 640px) { | ||
37 | - body { | ||
38 | - padding: 0 !important; | ||
39 | - } | ||
40 | - h1 { | ||
41 | - font-weight: 800 !important; margin: 20px 0 5px !important; | ||
42 | - } | ||
43 | - h2 { | ||
44 | - font-weight: 800 !important; margin: 20px 0 5px !important; | ||
45 | - } | ||
46 | - h3 { | ||
47 | - font-weight: 800 !important; margin: 20px 0 5px !important; | ||
48 | - } | ||
49 | - h4 { | ||
50 | - font-weight: 800 !important; margin: 20px 0 5px !important; | ||
51 | - } | ||
52 | - h1 { | ||
53 | - font-size: 22px !important; | ||
54 | - } | ||
55 | - h2 { | ||
56 | - font-size: 18px !important; | ||
57 | - } | ||
58 | - h3 { | ||
59 | - font-size: 16px !important; | ||
60 | - } | ||
61 | - .container { | ||
62 | - padding: 0 !important; width: 100% !important; | ||
63 | - } | ||
64 | - .content { | ||
65 | - padding: 0 !important; | ||
66 | - } | ||
67 | - .content-wrap { | ||
68 | - padding: 10px !important; | ||
69 | - } | ||
70 | - .invoice { | ||
71 | - width: 100% !important; | ||
72 | - } | ||
73 | -} | ||
74 | -</style> | 23 | + <meta name="viewport" content="width=device-width"/> |
24 | + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | ||
25 | + <title>Thingsboard - Api Usage State</title> | ||
26 | + | ||
27 | + | ||
28 | + <style type="text/css"> | ||
29 | + img { | ||
30 | + max-width: 100%; | ||
31 | + } | ||
32 | + | ||
33 | + body { | ||
34 | + -webkit-font-smoothing: antialiased; | ||
35 | + -webkit-text-size-adjust: none; | ||
36 | + width: 100% !important; | ||
37 | + height: 100%; | ||
38 | + line-height: 1.6em; | ||
39 | + } | ||
40 | + | ||
41 | + body { | ||
42 | + background-color: #f6f6f6; | ||
43 | + } | ||
44 | + | ||
45 | + @media only screen and (max-width: 640px) { | ||
46 | + body { | ||
47 | + padding: 0 !important; | ||
48 | + } | ||
49 | + | ||
50 | + h1 { | ||
51 | + font-weight: 800 !important; | ||
52 | + margin: 20px 0 5px !important; | ||
53 | + } | ||
54 | + | ||
55 | + h2 { | ||
56 | + font-weight: 800 !important; | ||
57 | + margin: 20px 0 5px !important; | ||
58 | + } | ||
59 | + | ||
60 | + h3 { | ||
61 | + font-weight: 800 !important; | ||
62 | + margin: 20px 0 5px !important; | ||
63 | + } | ||
64 | + | ||
65 | + h4 { | ||
66 | + font-weight: 800 !important; | ||
67 | + margin: 20px 0 5px !important; | ||
68 | + } | ||
69 | + | ||
70 | + h1 { | ||
71 | + font-size: 22px !important; | ||
72 | + } | ||
73 | + | ||
74 | + h2 { | ||
75 | + font-size: 18px !important; | ||
76 | + } | ||
77 | + | ||
78 | + h3 { | ||
79 | + font-size: 16px !important; | ||
80 | + } | ||
81 | + | ||
82 | + .container { | ||
83 | + padding: 0 !important; | ||
84 | + width: 100% !important; | ||
85 | + } | ||
86 | + | ||
87 | + .content { | ||
88 | + padding: 0 !important; | ||
89 | + } | ||
90 | + | ||
91 | + .content-wrap { | ||
92 | + padding: 10px !important; | ||
93 | + } | ||
94 | + | ||
95 | + .invoice { | ||
96 | + width: 100% !important; | ||
97 | + } | ||
98 | + } | ||
99 | + </style> | ||
75 | </head> | 100 | </head> |
76 | 101 | ||
77 | -<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"> | ||
78 | - | ||
79 | -<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> | ||
80 | - <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"> | ||
81 | - <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;"> | ||
82 | - <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"> | ||
83 | - <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;"> | ||
84 | - <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
85 | - <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"> | ||
86 | - <h2>Thingsboard Api Usage State for tenant has been updated</h2> | ||
87 | - </td> | ||
88 | - </tr> | ||
89 | - <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0 ;"> | ||
90 | - <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"> | ||
91 | - Thingsboard Usage state ${apiFeature} was updated to status ENABLED. | ||
92 | - </td> | ||
93 | - </tr> | ||
94 | - <#list apiUsageStateMailMessages as msg> | ||
95 | - <tr> | ||
96 | - <td> | ||
97 | - ${msg.key.apiLimitKey} = ${msg.threshold} | ||
98 | - </td> | ||
99 | - </tr> | ||
100 | - <tr> | ||
101 | - <td> | ||
102 | - ${msg.key.apiCountKey} = ${msg.value} | ||
103 | - </td> | ||
104 | - </tr> | ||
105 | - </#list> | ||
106 | - <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
107 | - <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"> | ||
108 | - — The Thingsboard | ||
109 | - </td> | ||
110 | - </tr></table></td> | ||
111 | - </tr> | ||
112 | - </table> | ||
113 | - <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;"> | ||
114 | - <table width="100%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
115 | - <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
116 | - <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> | ||
117 | - </tr> | ||
118 | - </table> | ||
119 | - </div> | ||
120 | - </div> | 102 | +<body itemscope itemtype="http://schema.org/EmailMessage" |
103 | + 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;" | ||
104 | + bgcolor="#f6f6f6"> | ||
105 | + | ||
106 | +<table class="main" | ||
107 | + 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;" | ||
108 | + cellspacing="0" cellpadding="0" bgcolor="#f6f6f6"> | ||
109 | + <tbody> | ||
110 | + <tr style="box-sizing: border-box; margin: 0px;"> | ||
111 | + <td class="content-wrap" style="box-sizing: border-box; vertical-align: top; margin: 0px; padding: 20px;" | ||
112 | + align="center" valign="top"> | ||
113 | + <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;" | ||
114 | + width="600" cellspacing="0" cellpadding="0"> | ||
115 | + <tbody> | ||
116 | + <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
117 | + <td class="content-block" | ||
118 | + 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;" | ||
119 | + valign="top"> | ||
120 | + <h2>Your ThingsBoard account feature was enabled</h2> | ||
121 | + </td> | ||
122 | + </tr> | ||
123 | + <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
124 | + <td class="content-block" | ||
125 | + 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;" | ||
126 | + valign="top">We have enabled the ${apiFeature} for your account and ThingsBoard already able to ${apiLabel} messages. | ||
127 | + </td> | ||
128 | + </tr> | ||
129 | + <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
130 | + <td class="content-block" | ||
131 | + 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;" | ||
132 | + valign="top">— The ThingsBoard | ||
133 | + </td> | ||
134 | + </tr> | ||
135 | + </tbody> | ||
136 | + </table> | ||
137 | + </td> | ||
138 | + </tr> | ||
139 | + </tbody> | ||
140 | +</table> | ||
141 | +<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%;" | ||
142 | + cellpadding="0px 0px 20px"> | ||
143 | + <tbody> | ||
144 | + <tr style="box-sizing: border-box; margin: 0px;"> | ||
145 | + <td class="aligncenter content-block" | ||
146 | + style="box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px 0px 20px; width: 600px; text-align: center; vertical-align: middle;" | ||
147 | + align="center" valign="top">This email was sent to <a | ||
148 | + style="box-sizing: border-box; color: #999999; margin: 0px;" | ||
149 | + href="mailto:${targetEmail}">${targetEmail}</a> by ThingsBoard. | ||
121 | </td> | 150 | </td> |
122 | - <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> | ||
123 | </tr> | 151 | </tr> |
152 | + </tbody> | ||
124 | </table> | 153 | </table> |
125 | </body> | 154 | </body> |
126 | </html> | 155 | </html> |
@@ -15,112 +15,148 @@ | @@ -15,112 +15,148 @@ | ||
15 | limitations under the License. | 15 | limitations under the License. |
16 | 16 | ||
17 | --> | 17 | --> |
18 | -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
19 | -<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;"> | 18 | +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" |
19 | + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
20 | +<html xmlns="http://www.w3.org/1999/xhtml" | ||
21 | + style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
20 | <head> | 22 | <head> |
21 | -<meta name="viewport" content="width=device-width" /> | ||
22 | -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | ||
23 | -<title>Thingsboard - Api Usage State</title> | ||
24 | - | ||
25 | - | ||
26 | -<style type="text/css"> | ||
27 | -img { | ||
28 | -max-width: 100%; | ||
29 | -} | ||
30 | -body { | ||
31 | --webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; | ||
32 | -} | ||
33 | -body { | ||
34 | -background-color: #f6f6f6; | ||
35 | -} | ||
36 | -@media only screen and (max-width: 640px) { | ||
37 | - body { | ||
38 | - padding: 0 !important; | ||
39 | - } | ||
40 | - h1 { | ||
41 | - font-weight: 800 !important; margin: 20px 0 5px !important; | ||
42 | - } | ||
43 | - h2 { | ||
44 | - font-weight: 800 !important; margin: 20px 0 5px !important; | ||
45 | - } | ||
46 | - h3 { | ||
47 | - font-weight: 800 !important; margin: 20px 0 5px !important; | ||
48 | - } | ||
49 | - h4 { | ||
50 | - font-weight: 800 !important; margin: 20px 0 5px !important; | ||
51 | - } | ||
52 | - h1 { | ||
53 | - font-size: 22px !important; | ||
54 | - } | ||
55 | - h2 { | ||
56 | - font-size: 18px !important; | ||
57 | - } | ||
58 | - h3 { | ||
59 | - font-size: 16px !important; | ||
60 | - } | ||
61 | - .container { | ||
62 | - padding: 0 !important; width: 100% !important; | ||
63 | - } | ||
64 | - .content { | ||
65 | - padding: 0 !important; | ||
66 | - } | ||
67 | - .content-wrap { | ||
68 | - padding: 10px !important; | ||
69 | - } | ||
70 | - .invoice { | ||
71 | - width: 100% !important; | ||
72 | - } | ||
73 | -} | ||
74 | -</style> | 23 | + <meta name="viewport" content="width=device-width"/> |
24 | + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | ||
25 | + <title>Thingsboard - Api Usage State</title> | ||
26 | + | ||
27 | + | ||
28 | + <style type="text/css"> | ||
29 | + img { | ||
30 | + max-width: 100%; | ||
31 | + } | ||
32 | + | ||
33 | + body { | ||
34 | + -webkit-font-smoothing: antialiased; | ||
35 | + -webkit-text-size-adjust: none; | ||
36 | + width: 100% !important; | ||
37 | + height: 100%; | ||
38 | + line-height: 1.6em; | ||
39 | + } | ||
40 | + | ||
41 | + body { | ||
42 | + background-color: #f6f6f6; | ||
43 | + } | ||
44 | + | ||
45 | + @media only screen and (max-width: 640px) { | ||
46 | + body { | ||
47 | + padding: 0 !important; | ||
48 | + } | ||
49 | + | ||
50 | + h1 { | ||
51 | + font-weight: 800 !important; | ||
52 | + margin: 20px 0 5px !important; | ||
53 | + } | ||
54 | + | ||
55 | + h2 { | ||
56 | + font-weight: 800 !important; | ||
57 | + margin: 20px 0 5px !important; | ||
58 | + } | ||
59 | + | ||
60 | + h3 { | ||
61 | + font-weight: 800 !important; | ||
62 | + margin: 20px 0 5px !important; | ||
63 | + } | ||
64 | + | ||
65 | + h4 { | ||
66 | + font-weight: 800 !important; | ||
67 | + margin: 20px 0 5px !important; | ||
68 | + } | ||
69 | + | ||
70 | + h1 { | ||
71 | + font-size: 22px !important; | ||
72 | + } | ||
73 | + | ||
74 | + h2 { | ||
75 | + font-size: 18px !important; | ||
76 | + } | ||
77 | + | ||
78 | + h3 { | ||
79 | + font-size: 16px !important; | ||
80 | + } | ||
81 | + | ||
82 | + .container { | ||
83 | + padding: 0 !important; | ||
84 | + width: 100% !important; | ||
85 | + } | ||
86 | + | ||
87 | + .content { | ||
88 | + padding: 0 !important; | ||
89 | + } | ||
90 | + | ||
91 | + .content-wrap { | ||
92 | + padding: 10px !important; | ||
93 | + } | ||
94 | + | ||
95 | + .invoice { | ||
96 | + width: 100% !important; | ||
97 | + } | ||
98 | + } | ||
99 | + </style> | ||
75 | </head> | 100 | </head> |
76 | 101 | ||
77 | -<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"> | ||
78 | - | ||
79 | -<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> | ||
80 | - <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"> | ||
81 | - <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;"> | ||
82 | - <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"> | ||
83 | - <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;"> | ||
84 | - <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
85 | - <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"> | ||
86 | - <h2>Thingsboard Api Usage State for tenant has been updated</h2> | ||
87 | - </td> | ||
88 | - </tr> | ||
89 | - <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
90 | - <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"> | ||
91 | - Thingsboard Usage state ${apiFeature} was updated to status WARNING. | ||
92 | - </td> | ||
93 | - </tr> | ||
94 | - <#list apiUsageStateMailMessages as msg> | ||
95 | - <tr> | ||
96 | - <td> | ||
97 | - ${msg.key.apiLimitKey} = ${msg.threshold} | ||
98 | - </td> | ||
99 | - </tr> | ||
100 | - <tr> | ||
101 | - <td> | ||
102 | - ${msg.key.apiCountKey} = ${msg.value} | ||
103 | - </td> | ||
104 | - </tr> | ||
105 | - </#list> | ||
106 | - <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
107 | - <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"> | ||
108 | - — The Thingsboard | ||
109 | - </td> | ||
110 | - </tr></table></td> | ||
111 | - </tr> | ||
112 | - </table> | ||
113 | - <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;"> | ||
114 | - <table width="100%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
115 | - <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
116 | - <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> | ||
117 | - </tr> | ||
118 | - </table> | ||
119 | - </div> | ||
120 | - </div> | 102 | +<body itemscope itemtype="http://schema.org/EmailMessage" |
103 | + 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;" | ||
104 | + bgcolor="#f6f6f6"> | ||
105 | + | ||
106 | +<table class="main" | ||
107 | + 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;" | ||
108 | + cellspacing="0" cellpadding="0" bgcolor="#f6f6f6"> | ||
109 | + <tbody> | ||
110 | + <tr style="box-sizing: border-box; margin: 0px;"> | ||
111 | + <td class="content-wrap" style="box-sizing: border-box; vertical-align: top; margin: 0px; padding: 20px;" | ||
112 | + align="center" valign="top"> | ||
113 | + <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;" | ||
114 | + width="600" cellspacing="0" cellpadding="0"> | ||
115 | + <tbody> | ||
116 | + <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
117 | + <td class="content-block" | ||
118 | + 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;" | ||
119 | + valign="top"> | ||
120 | + <h2>Your ThingsBoard account feature may be disabled</h2> | ||
121 | + </td> | ||
122 | + </tr> | ||
123 | + <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
124 | + <td class="content-block" | ||
125 | + 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;" | ||
126 | + valign="top"> | ||
127 | + 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. | ||
128 | + </td> | ||
129 | + </tr> | ||
130 | + <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
131 | + <td class="content-block" | ||
132 | + 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;" | ||
133 | + valign="top">Please contact your system administrator to resolve the issue. | ||
134 | + </td> | ||
135 | + </tr> | ||
136 | + <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | ||
137 | + <td class="content-block" | ||
138 | + 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;" | ||
139 | + valign="top">— The ThingsBoard | ||
140 | + </td> | ||
141 | + </tr> | ||
142 | + </tbody> | ||
143 | + </table> | ||
144 | + </td> | ||
145 | + </tr> | ||
146 | + </tbody> | ||
147 | +</table> | ||
148 | +<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%;" | ||
149 | + cellpadding="0px 0px 20px"> | ||
150 | + <tbody> | ||
151 | + <tr style="box-sizing: border-box; margin: 0px;"> | ||
152 | + <td class="aligncenter content-block" | ||
153 | + style="box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px 0px 20px; width: 600px; text-align: center; vertical-align: middle;" | ||
154 | + align="center" valign="top">This email was sent to <a | ||
155 | + style="box-sizing: border-box; color: #999999; margin: 0px;" | ||
156 | + href="mailto:${targetEmail}">${targetEmail}</a> by ThingsBoard. | ||
121 | </td> | 157 | </td> |
122 | - <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> | ||
123 | </tr> | 158 | </tr> |
159 | + </tbody> | ||
124 | </table> | 160 | </table> |
125 | </body> | 161 | </body> |
126 | </html> | 162 | </html> |