1
0
mirror of https://github.com/hrfee/jfa-go.git synced 2024-12-22 09:00:10 +00:00

use templateEmail and show conditionals in editor

This commit is contained in:
Harvey Tindall 2021-04-15 15:34:17 +01:00
parent f7d2771263
commit 8fdab39b18
Signed by: hrfee
GPG Key ID: BBC65952848FB1A2
7 changed files with 116 additions and 88 deletions

12
api.go
View File

@ -1570,6 +1570,7 @@ func (app *appContext) GetEmail(gc *gin.Context) {
var err error var err error
var msg *Email var msg *Email
var variables []string var variables []string
var conditionals []string
var values map[string]interface{} var values map[string]interface{}
var writeVars func(variables []string) var writeVars func(variables []string)
newEmail := false newEmail := false
@ -1661,16 +1662,21 @@ func (app *appContext) GetEmail(gc *gin.Context) {
// app.storage.customEmails.InviteEmail = content // app.storage.customEmails.InviteEmail = content
} else if id == "WelcomeEmail" { } else if id == "WelcomeEmail" {
content = app.storage.customEmails.WelcomeEmail.Content content = app.storage.customEmails.WelcomeEmail.Content
conditionals = []string{"{yourAccountWillExpire}"}
app.storage.customEmails.WelcomeEmail.Conditionals = conditionals
if content == "" { if content == "" {
newEmail = true newEmail = true
msg, err = app.email.constructWelcome("", time.Time{}, app, true) msg, err = app.email.constructWelcome("", time.Time{}, app, true)
content = msg.Text content = msg.Text
conditionals = []string{"{yourAccountWillExpire}"}
} else { } else {
variables = app.storage.customEmails.WelcomeEmail.Variables variables = app.storage.customEmails.WelcomeEmail.Variables
} }
writeVars = func(variables []string) { app.storage.customEmails.WelcomeEmail.Variables = variables } writeVars = func(variables []string) {
app.storage.customEmails.WelcomeEmail.Variables = variables
}
// app.storage.customEmails.WelcomeEmail = content // app.storage.customEmails.WelcomeEmail = content
values = app.email.welcomeValues(username, time.Time{}, app, false, true) values = app.email.welcomeValues(username, time.Now(), app, false, true)
} else if id == "EmailConfirmation" { } else if id == "EmailConfirmation" {
content = app.storage.customEmails.EmailConfirmation.Content content = app.storage.customEmails.EmailConfirmation.Content
if content == "" { if content == "" {
@ -1734,7 +1740,7 @@ func (app *appContext) GetEmail(gc *gin.Context) {
respondBool(500, false, gc) respondBool(500, false, gc)
return return
} }
gc.JSON(200, customEmailDTO{Content: content, Variables: variables, Values: values, HTML: email.HTML, Plaintext: email.Text}) gc.JSON(200, customEmailDTO{Content: content, Variables: variables, Conditionals: conditionals, Values: values, HTML: email.HTML, Plaintext: email.Text})
} }
// @Summary Returns whether there's a new update, and extra info if there is. // @Summary Returns whether there's a new update, and extra info if there is.

144
email.go
View File

@ -274,13 +274,12 @@ func (emailer *Emailer) constructConfirmation(code, username, key string, app *a
var err error var err error
template := emailer.confirmationValues(code, username, key, app, noSub) template := emailer.confirmationValues(code, username, key, app, noSub)
if app.storage.customEmails.EmailConfirmation.Enabled { if app.storage.customEmails.EmailConfirmation.Enabled {
content := app.storage.customEmails.EmailConfirmation.Content content := templateEmail(
for _, v := range app.storage.customEmails.EmailConfirmation.Variables { app.storage.customEmails.EmailConfirmation.Content,
replaceWith, ok := template[v[1:len(v)-1]] app.storage.customEmails.EmailConfirmation.Variables,
if ok { nil,
content = strings.ReplaceAll(content, v, replaceWith.(string)) template,
} )
}
email, err = emailer.constructTemplate(email.Subject, content, app) email, err = emailer.constructTemplate(email.Subject, content, app)
} else { } else {
email.HTML, email.Text, err = emailer.construct(app, "email_confirmation", "email_", template) email.HTML, email.Text, err = emailer.construct(app, "email_confirmation", "email_", template)
@ -346,13 +345,12 @@ func (emailer *Emailer) constructInvite(code string, invite Invite, app *appCont
template := emailer.inviteValues(code, invite, app, noSub) template := emailer.inviteValues(code, invite, app, noSub)
var err error var err error
if app.storage.customEmails.InviteEmail.Enabled { if app.storage.customEmails.InviteEmail.Enabled {
content := app.storage.customEmails.InviteEmail.Content content := templateEmail(
for _, v := range app.storage.customEmails.InviteEmail.Variables { app.storage.customEmails.InviteEmail.Content,
replaceWith, ok := template[v[1:len(v)-1]] app.storage.customEmails.InviteEmail.Variables,
if ok { nil,
content = strings.ReplaceAll(content, v, replaceWith.(string)) template,
} )
}
email, err = emailer.constructTemplate(email.Subject, content, app) email, err = emailer.constructTemplate(email.Subject, content, app)
} else { } else {
email.HTML, email.Text, err = emailer.construct(app, "invite_emails", "email_", template) email.HTML, email.Text, err = emailer.construct(app, "invite_emails", "email_", template)
@ -386,13 +384,12 @@ func (emailer *Emailer) constructExpiry(code string, invite Invite, app *appCont
var err error var err error
template := emailer.expiryValues(code, invite, app, noSub) template := emailer.expiryValues(code, invite, app, noSub)
if app.storage.customEmails.InviteExpiry.Enabled { if app.storage.customEmails.InviteExpiry.Enabled {
content := app.storage.customEmails.InviteExpiry.Content content := templateEmail(
for _, v := range app.storage.customEmails.InviteExpiry.Variables { app.storage.customEmails.InviteExpiry.Content,
replaceWith, ok := template[v[1:len(v)-1]] app.storage.customEmails.InviteExpiry.Variables,
if ok { nil,
content = strings.ReplaceAll(content, v, replaceWith.(string)) template,
} )
}
email, err = emailer.constructTemplate(email.Subject, content, app) email, err = emailer.constructTemplate(email.Subject, content, app)
} else { } else {
email.HTML, email.Text, err = emailer.construct(app, "notifications", "expiry_", template) email.HTML, email.Text, err = emailer.construct(app, "notifications", "expiry_", template)
@ -441,13 +438,12 @@ func (emailer *Emailer) constructCreated(code, username, address string, invite
template := emailer.createdValues(code, username, address, invite, app, noSub) template := emailer.createdValues(code, username, address, invite, app, noSub)
var err error var err error
if app.storage.customEmails.UserCreated.Enabled { if app.storage.customEmails.UserCreated.Enabled {
content := app.storage.customEmails.UserCreated.Content content := templateEmail(
for _, v := range app.storage.customEmails.UserCreated.Variables { app.storage.customEmails.UserCreated.Content,
replaceWith, ok := template[v[1:len(v)-1]] app.storage.customEmails.UserCreated.Variables,
if ok { nil,
content = strings.ReplaceAll(content, v, replaceWith.(string)) template,
} )
}
email, err = emailer.constructTemplate(email.Subject, content, app) email, err = emailer.constructTemplate(email.Subject, content, app)
} else { } else {
email.HTML, email.Text, err = emailer.construct(app, "notifications", "created_", template) email.HTML, email.Text, err = emailer.construct(app, "notifications", "created_", template)
@ -516,13 +512,12 @@ func (emailer *Emailer) constructReset(pwr PasswordReset, app *appContext, noSub
template := emailer.resetValues(pwr, app, noSub) template := emailer.resetValues(pwr, app, noSub)
var err error var err error
if app.storage.customEmails.PasswordReset.Enabled { if app.storage.customEmails.PasswordReset.Enabled {
content := app.storage.customEmails.PasswordReset.Content content := templateEmail(
for _, v := range app.storage.customEmails.PasswordReset.Variables { app.storage.customEmails.PasswordReset.Content,
replaceWith, ok := template[v[1:len(v)-1]] app.storage.customEmails.PasswordReset.Variables,
if ok { nil,
content = strings.ReplaceAll(content, v, replaceWith.(string)) template,
} )
}
email, err = emailer.constructTemplate(email.Subject, content, app) email, err = emailer.constructTemplate(email.Subject, content, app)
} else { } else {
email.HTML, email.Text, err = emailer.construct(app, "password_resets", "email_", template) email.HTML, email.Text, err = emailer.construct(app, "password_resets", "email_", template)
@ -558,13 +553,12 @@ func (emailer *Emailer) constructDeleted(reason string, app *appContext, noSub b
var err error var err error
template := emailer.deletedValues(reason, app, noSub) template := emailer.deletedValues(reason, app, noSub)
if app.storage.customEmails.UserDeleted.Enabled { if app.storage.customEmails.UserDeleted.Enabled {
content := app.storage.customEmails.UserDeleted.Content content := templateEmail(
for _, v := range app.storage.customEmails.UserDeleted.Variables { app.storage.customEmails.UserDeleted.Content,
replaceWith, ok := template[v[1:len(v)-1]] app.storage.customEmails.UserDeleted.Variables,
if ok { nil,
content = strings.ReplaceAll(content, v, replaceWith.(string)) template,
} )
}
email, err = emailer.constructTemplate(email.Subject, content, app) email, err = emailer.constructTemplate(email.Subject, content, app)
} else { } else {
email.HTML, email.Text, err = emailer.construct(app, "deletion", "email_", template) email.HTML, email.Text, err = emailer.construct(app, "deletion", "email_", template)
@ -600,13 +594,12 @@ func (emailer *Emailer) constructDisabled(reason string, app *appContext, noSub
var err error var err error
template := emailer.disabledValues(reason, app, noSub) template := emailer.disabledValues(reason, app, noSub)
if app.storage.customEmails.UserDisabled.Enabled { if app.storage.customEmails.UserDisabled.Enabled {
content := app.storage.customEmails.UserDisabled.Content content := templateEmail(
for _, v := range app.storage.customEmails.UserDisabled.Variables { app.storage.customEmails.UserDisabled.Content,
replaceWith, ok := template[v[1:len(v)-1]] app.storage.customEmails.UserDisabled.Variables,
if ok { nil,
content = strings.ReplaceAll(content, v, replaceWith.(string)) template,
} )
}
email, err = emailer.constructTemplate(email.Subject, content, app) email, err = emailer.constructTemplate(email.Subject, content, app)
} else { } else {
email.HTML, email.Text, err = emailer.construct(app, "disable_enable", "disabled_", template) email.HTML, email.Text, err = emailer.construct(app, "disable_enable", "disabled_", template)
@ -642,13 +635,12 @@ func (emailer *Emailer) constructEnabled(reason string, app *appContext, noSub b
var err error var err error
template := emailer.enabledValues(reason, app, noSub) template := emailer.enabledValues(reason, app, noSub)
if app.storage.customEmails.UserEnabled.Enabled { if app.storage.customEmails.UserEnabled.Enabled {
content := app.storage.customEmails.UserEnabled.Content content := templateEmail(
for _, v := range app.storage.customEmails.UserEnabled.Variables { app.storage.customEmails.UserEnabled.Content,
replaceWith, ok := template[v[1:len(v)-1]] app.storage.customEmails.UserEnabled.Variables,
if ok { nil,
content = strings.ReplaceAll(content, v, replaceWith.(string)) template,
} )
}
email, err = emailer.constructTemplate(email.Subject, content, app) email, err = emailer.constructTemplate(email.Subject, content, app)
} else { } else {
email.HTML, email.Text, err = emailer.construct(app, "disable_enable", "enabled_", template) email.HTML, email.Text, err = emailer.construct(app, "disable_enable", "enabled_", template)
@ -677,12 +669,14 @@ func (emailer *Emailer) welcomeValues(username string, expiry time.Time, app *ap
template["username"] = username template["username"] = username
template["message"] = app.config.Section("email").Key("message").String() template["message"] = app.config.Section("email").Key("message").String()
exp := app.formatDatetime(expiry) exp := app.formatDatetime(expiry)
if custom { if !expiry.IsZero() {
template["yourAccountWillExpire"] = exp if custom {
} else if !expiry.IsZero() { template["yourAccountWillExpire"] = exp
template["yourAccountWillExpire"] = emailer.lang.WelcomeEmail.template("yourAccountWillExpire", tmpl{ } else if !expiry.IsZero() {
"date": exp, template["yourAccountWillExpire"] = emailer.lang.WelcomeEmail.template("yourAccountWillExpire", tmpl{
}) "date": exp,
})
}
} }
} }
return template return template
@ -705,13 +699,12 @@ func (emailer *Emailer) constructWelcome(username string, expiry time.Time, app
}) })
} }
if app.storage.customEmails.WelcomeEmail.Enabled { if app.storage.customEmails.WelcomeEmail.Enabled {
content := app.storage.customEmails.WelcomeEmail.Content content := templateEmail(
for _, v := range app.storage.customEmails.WelcomeEmail.Variables { app.storage.customEmails.WelcomeEmail.Content,
replaceWith, ok := template[v[1:len(v)-1]] app.storage.customEmails.WelcomeEmail.Variables,
if ok { app.storage.customEmails.WelcomeEmail.Conditionals,
content = strings.ReplaceAll(content, v, replaceWith.(string)) template,
} )
}
email, err = emailer.constructTemplate(email.Subject, content, app) email, err = emailer.constructTemplate(email.Subject, content, app)
} else { } else {
email.HTML, email.Text, err = emailer.construct(app, "welcome_email", "email_", template) email.HTML, email.Text, err = emailer.construct(app, "welcome_email", "email_", template)
@ -741,13 +734,12 @@ func (emailer *Emailer) constructUserExpired(app *appContext, noSub bool) (*Emai
var err error var err error
template := emailer.userExpiredValues(app, noSub) template := emailer.userExpiredValues(app, noSub)
if app.storage.customEmails.UserExpired.Enabled { if app.storage.customEmails.UserExpired.Enabled {
content := app.storage.customEmails.UserExpired.Content content := templateEmail(
for _, v := range app.storage.customEmails.UserExpired.Variables { app.storage.customEmails.UserExpired.Content,
replaceWith, ok := template[v[1:len(v)-1]] app.storage.customEmails.UserExpired.Variables,
if ok { nil,
content = strings.ReplaceAll(content, v, replaceWith.(string)) template,
} )
}
email, err = emailer.constructTemplate(email.Subject, content, app) email, err = emailer.constructTemplate(email.Subject, content, app)
} else { } else {
email.HTML, email.Text, err = emailer.construct(app, "user_expiry", "email_", template) email.HTML, email.Text, err = emailer.construct(app, "user_expiry", "email_", template)

View File

@ -183,6 +183,8 @@
<div class="col flex-col content mt-half"> <div class="col flex-col content mt-half">
<span class="label supra" for="editor-variables" id="label-editor-variables">{{ .strings.variables }}</span> <span class="label supra" for="editor-variables" id="label-editor-variables">{{ .strings.variables }}</span>
<div id="editor-variables"></div> <div id="editor-variables"></div>
<span class="label supra" for="editor-conditionals" id="label-editor-conditionals">{{ .strings.conditionals }}</span>
<div id="editor-conditionals"></div>
<label class="label supra" for="textarea-editor">{{ .strings.message }}</label> <label class="label supra" for="textarea-editor">{{ .strings.message }}</label>
<textarea id="textarea-editor" class="textarea full-width flex-auto ~neutral !normal mt-half monospace"></textarea> <textarea id="textarea-editor" class="textarea full-width flex-auto ~neutral !normal mt-half monospace"></textarea>
<p class="support mt-half mb-1">{{ .strings.markdownSupported }}</p> <p class="support mt-half mb-1">{{ .strings.markdownSupported }}</p>

View File

@ -49,6 +49,7 @@
"subject": "Email Subject", "subject": "Email Subject",
"message": "Message", "message": "Message",
"variables": "Variables", "variables": "Variables",
"conditionals": "Conditionals",
"preview": "Preview", "preview": "Preview",
"reset": "Reset", "reset": "Reset",
"edit": "Edit", "edit": "Edit",

View File

@ -214,11 +214,12 @@ type emailTestDTO struct {
} }
type customEmailDTO struct { type customEmailDTO struct {
Content string `json:"content"` Content string `json:"content"`
Variables []string `json:"variables"` Variables []string `json:"variables"`
Values map[string]interface{} `json:"values"` Conditionals []string `json:"conditionals"`
HTML string `json:"html"` Values map[string]interface{} `json:"values"`
Plaintext string `json:"plaintext"` HTML string `json:"html"`
Plaintext string `json:"plaintext"`
} }
type extendExpiryDTO struct { type extendExpiryDTO struct {

View File

@ -43,9 +43,10 @@ type customEmails struct {
} }
type customEmail struct { type customEmail struct {
Enabled bool `json:"enabled,omitempty"` Enabled bool `json:"enabled,omitempty"`
Content string `json:"content"` Content string `json:"content"`
Variables []string `json:"variables,omitempty"` Variables []string `json:"variables,omitempty"`
Conditionals []string `json:"conditionals,omitempty"`
} }
// timePattern: %Y-%m-%dT%H:%M:%S.%f // timePattern: %Y-%m-%dT%H:%M:%S.%f

View File

@ -769,6 +769,7 @@ class ombiDefaults {
interface templateEmail { interface templateEmail {
content: string; content: string;
variables: string[]; variables: string[];
conditionals: string[];
values: { [key: string]: string }; values: { [key: string]: string };
html: string; html: string;
plaintext: string; plaintext: string;
@ -788,6 +789,8 @@ class EmailEditor {
private _header = document.getElementById("header-editor") as HTMLSpanElement; private _header = document.getElementById("header-editor") as HTMLSpanElement;
private _variables = document.getElementById("editor-variables") as HTMLDivElement; private _variables = document.getElementById("editor-variables") as HTMLDivElement;
private _variablesLabel = document.getElementById("label-editor-variables") as HTMLElement; private _variablesLabel = document.getElementById("label-editor-variables") as HTMLElement;
private _conditionals = document.getElementById("editor-conditionals") as HTMLDivElement;
private _conditionalsLabel = document.getElementById("label-editor-conditionals") as HTMLElement;
private _textArea = document.getElementById("textarea-editor") as HTMLTextAreaElement; private _textArea = document.getElementById("textarea-editor") as HTMLTextAreaElement;
private _preview = document.getElementById("editor-preview") as HTMLDivElement; private _preview = document.getElementById("editor-preview") as HTMLDivElement;
private _previewContent: HTMLElement; private _previewContent: HTMLElement;
@ -845,7 +848,7 @@ class EmailEditor {
this._variablesLabel.classList.remove("unfocused"); this._variablesLabel.classList.remove("unfocused");
} }
this._variables.innerHTML = innerHTML this._variables.innerHTML = innerHTML
const buttons = this._variables.querySelectorAll("span.button") as NodeListOf<HTMLSpanElement>; let buttons = this._variables.querySelectorAll("span.button") as NodeListOf<HTMLSpanElement>;
for (let i = 0; i < this._templ.variables.length; i++) { for (let i = 0; i < this._templ.variables.length; i++) {
buttons[i].innerHTML = `<span class="monospace">` + this._templ.variables[i] + `</span>`; buttons[i].innerHTML = `<span class="monospace">` + this._templ.variables[i] + `</span>`;
buttons[i].onclick = () => { buttons[i].onclick = () => {
@ -854,6 +857,28 @@ class EmailEditor {
// this._timeout = setTimeout(this.loadPreview, this._finishInterval); // this._timeout = setTimeout(this.loadPreview, this._finishInterval);
} }
} }
innerHTML = '';
for (let i = this._templ.conditionals.length-1; i >= 0; i--) {
let ci = i % colors.length;
innerHTML += '<span class="button ~' + colors[ci] +' !normal mb-1" style="margin-left: 0.25rem; margin-right: 0.25rem;"></span>'
}
if (this._templ.conditionals.length == 0) {
this._conditionalsLabel.classList.add("unfocused");
} else {
this._conditionalsLabel.classList.remove("unfocused");
}
this._conditionals.innerHTML = innerHTML
buttons = this._conditionals.querySelectorAll("span.button") as NodeListOf<HTMLSpanElement>;
for (let i = 0; i < this._templ.conditionals.length; i++) {
buttons[i].innerHTML = `<span class="monospace">{if ` + this._templ.conditionals[i].slice(1) + `</span>`;
buttons[i].onclick = () => {
this.insert(this._textArea, "{if " + this._templ.conditionals[i].slice(1) + "{endif}");
this.loadPreview();
// this._timeout = setTimeout(this.loadPreview, this._finishInterval);
}
}
window.modals.editor.show(); window.modals.editor.show();
} }
}) })