mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 09:00:10 +00:00
add preview to Announcements
This commit is contained in:
parent
2c6d08319b
commit
c0f316d049
5
api.go
5
api.go
@ -1712,6 +1712,9 @@ func (app *appContext) GetCustomEmailTemplate(gc *gin.Context) {
|
||||
}
|
||||
writeVars = func(variables []string) { app.storage.customEmails.UserExpired.Variables = variables }
|
||||
values = app.email.userExpiredValues(app, false)
|
||||
// Just send the email html
|
||||
case "Announcement":
|
||||
content = ""
|
||||
default:
|
||||
respondBool(400, false, gc)
|
||||
return
|
||||
@ -1747,7 +1750,7 @@ func (app *appContext) GetCustomEmailTemplate(gc *gin.Context) {
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
}
|
||||
email, err := app.email.constructTemplate("", "<div id=\"preview-content\"></div>", app)
|
||||
email, err := app.email.constructTemplate("", "<div class=\"preview-content\"></div>", app)
|
||||
if err != nil {
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
|
@ -156,18 +156,24 @@
|
||||
</form>
|
||||
</div>
|
||||
<div id="modal-announce" class="modal">
|
||||
<form class="modal-content card" id="form-announce" href="">
|
||||
<form class="modal-content wide card" id="form-announce" href="">
|
||||
<span class="heading"><span id="header-announce"></span> <span class="modal-close">×</span></span>
|
||||
<div class="content mt-half">
|
||||
<label class="label supra" for="announce-subject"> {{ .strings.subject }}</label>
|
||||
<input type="text" id="announce-subject" class="input ~neutral !normal mb-1 mt-half">
|
||||
<label class="label supra" for="textarea-announce">{{ .strings.message }}</label>
|
||||
<textarea id="textarea-announce" class="textarea full-width ~neutral !normal mt-half monospace"></textarea>
|
||||
<p class="support mt-half mb-1">{{ .strings.markdownSupported }}</p>
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~urge !normal full-width center supra submit">{{ .strings.submit }}</span>
|
||||
</label>
|
||||
<div class="row">
|
||||
<div class="col flex-col content mt-half">
|
||||
<label class="label supra" for="announce-subject"> {{ .strings.subject }}</label>
|
||||
<input type="text" id="announce-subject" class="input ~neutral !normal mb-1 mt-half">
|
||||
<label class="label supra" for="textarea-announce">{{ .strings.message }}</label>
|
||||
<textarea id="textarea-announce" class="textarea full-width ~neutral !normal mt-half monospace"></textarea>
|
||||
<p class="support mt-half mb-1">{{ .strings.markdownSupported }}</p>
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~urge !normal full-width center supra submit">{{ .strings.submit }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col card ~neutral !low">
|
||||
<span class="subheading supra">{{ .strings.preview }}</span>
|
||||
<div class="mt-half" id="announce-preview"></div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
13
package-lock.json
generated
13
package-lock.json
generated
@ -9,6 +9,7 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@ts-stack/markdown": "^1.3.0",
|
||||
"@types/node": "^15.0.1",
|
||||
"a17t": "^0.4.0",
|
||||
"esbuild": "^0.8.57",
|
||||
"lodash": "^4.17.19",
|
||||
@ -35,9 +36,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "14.14.16",
|
||||
"resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-14.14.16.tgz?cache=0&sync_timestamp=1608756036972&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.14.16.tgz",
|
||||
"integrity": "sha1-PMNR+NSBAd6t/tTJ5PEWBI1De0s="
|
||||
"version": "15.0.1",
|
||||
"resolved": "https://registry.nlark.com/@types/node/download/@types/node-15.0.1.tgz?cache=0&sync_timestamp=1619534647758&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-15.0.1.tgz",
|
||||
"integrity": "sha1-7zTeoIgQKNETmL5b9OhWdD49w1o="
|
||||
},
|
||||
"node_modules/a17t": {
|
||||
"version": "0.4.0",
|
||||
@ -1835,9 +1836,9 @@
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "14.14.16",
|
||||
"resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-14.14.16.tgz?cache=0&sync_timestamp=1608756036972&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.14.16.tgz",
|
||||
"integrity": "sha1-PMNR+NSBAd6t/tTJ5PEWBI1De0s="
|
||||
"version": "15.0.1",
|
||||
"resolved": "https://registry.nlark.com/@types/node/download/@types/node-15.0.1.tgz?cache=0&sync_timestamp=1619534647758&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-15.0.1.tgz",
|
||||
"integrity": "sha1-7zTeoIgQKNETmL5b9OhWdD49w1o="
|
||||
},
|
||||
"a17t": {
|
||||
"version": "0.4.0",
|
||||
|
@ -18,6 +18,7 @@
|
||||
"homepage": "https://github.com/hrfee/jfa-go#readme",
|
||||
"dependencies": {
|
||||
"@ts-stack/markdown": "^1.3.0",
|
||||
"@types/node": "^15.0.1",
|
||||
"a17t": "^0.4.0",
|
||||
"esbuild": "^0.8.57",
|
||||
"lodash": "^4.17.19",
|
||||
|
@ -1,4 +1,7 @@
|
||||
import { _get, _post, _delete, toggleLoader, toDateString } from "../modules/common.js";
|
||||
import { templateEmail } from "../modules/settings.js";
|
||||
import { Marked } from "@ts-stack/markdown";
|
||||
import { stripMarkdown } from "../modules/stripmd.js";
|
||||
|
||||
interface User {
|
||||
id: string;
|
||||
@ -193,6 +196,9 @@ export class accountsList {
|
||||
|
||||
private _addUserButton = document.getElementById("accounts-add-user") as HTMLSpanElement;
|
||||
private _announceButton = document.getElementById("accounts-announce") as HTMLSpanElement;
|
||||
private _announcePreview: HTMLElement;
|
||||
private _previewLoaded = false;
|
||||
private _announceTextarea = document.getElementById("textarea-announce") as HTMLTextAreaElement;
|
||||
private _deleteUser = document.getElementById("accounts-delete-user") as HTMLSpanElement;
|
||||
private _disableEnable = document.getElementById("accounts-disable-enable") as HTMLSpanElement;
|
||||
private _deleteNotify = document.getElementById("delete-user-notify") as HTMLInputElement;
|
||||
@ -432,7 +438,16 @@ export class accountsList {
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
loadPreview = () => {
|
||||
let content = this._announceTextarea.value;
|
||||
if (!this._previewLoaded) {
|
||||
content = stripMarkdown(content);
|
||||
this._announcePreview.textContent = content;
|
||||
} else {
|
||||
content = Marked.parse(content);
|
||||
this._announcePreview.innerHTML = content;
|
||||
}
|
||||
}
|
||||
announce = () => {
|
||||
const modalHeader = document.getElementById("header-announce");
|
||||
modalHeader.textContent = window.lang.quantity("announceTo", this._collectUsers().length);
|
||||
@ -440,16 +455,16 @@ export class accountsList {
|
||||
let list = this._collectUsers();
|
||||
const button = form.querySelector("span.submit") as HTMLSpanElement;
|
||||
const subject = document.getElementById("announce-subject") as HTMLInputElement;
|
||||
const message = document.getElementById("textarea-announce") as HTMLTextAreaElement;
|
||||
|
||||
subject.value = "";
|
||||
message.value = "";
|
||||
this._announceTextarea.value = "";
|
||||
form.onsubmit = (event: Event) => {
|
||||
event.preventDefault();
|
||||
toggleLoader(button);
|
||||
let send = {
|
||||
"users": list,
|
||||
"subject": subject.value,
|
||||
"message": message.value
|
||||
"message": this._announceTextarea.value
|
||||
}
|
||||
_post("/users/announce", send, (req: XMLHttpRequest) => {
|
||||
if (req.readyState == 4) {
|
||||
@ -463,7 +478,29 @@ export class accountsList {
|
||||
}
|
||||
});
|
||||
};
|
||||
window.modals.announce.show();
|
||||
_get("/config/emails/Announcement", null, (req: XMLHttpRequest) => {
|
||||
if (req.readyState == 4) {
|
||||
const preview = document.getElementById("announce-preview") as HTMLDivElement;
|
||||
if (req.status != 200) {
|
||||
preview.innerHTML = `<pre class="preview-content" class="monospace"></pre>`;
|
||||
window.modals.announce.show();
|
||||
this._previewLoaded = false;
|
||||
return;
|
||||
}
|
||||
|
||||
let templ = req.response as templateEmail;
|
||||
if (!templ.html) {
|
||||
preview.innerHTML = `<pre class="preview-content" class="monospace"></pre>`;
|
||||
this._previewLoaded = false;
|
||||
} else {
|
||||
preview.innerHTML = templ.html;
|
||||
this._previewLoaded = true;
|
||||
}
|
||||
this._announcePreview = preview.getElementsByClassName("preview-content")[0] as HTMLElement;
|
||||
this.loadPreview();
|
||||
window.modals.announce.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
enableDisableUsers = () => {
|
||||
@ -750,6 +787,8 @@ export class accountsList {
|
||||
}
|
||||
this._checkCheckCount();
|
||||
};
|
||||
|
||||
this._announceTextarea.onkeyup = this.loadPreview;
|
||||
}
|
||||
|
||||
reload = () => _get("/users", null, (req: XMLHttpRequest) => {
|
||||
|
@ -157,7 +157,7 @@ class DOMInvite implements Invite {
|
||||
this._createdUnix = unix;
|
||||
const el = this._middle.querySelector("strong.inv-created");
|
||||
if (unix == 0) {
|
||||
el.textContent = "n/a";
|
||||
el.textContent = window.lang.strings("unknown");
|
||||
} else {
|
||||
el.textContent = toDateString(new Date(unix*1000));
|
||||
}
|
||||
@ -479,7 +479,7 @@ export class inviteList implements inviteList {
|
||||
}
|
||||
|
||||
|
||||
function parseInvite(invite: { [f: string]: string | number | string[][] | boolean }): Invite {
|
||||
function parseInvite(invite: { [f: string]: string | number | { [name: string]: number } | boolean }): Invite {
|
||||
let parsed: Invite = {};
|
||||
parsed.code = invite["code"] as string;
|
||||
parsed.email = invite["email"] as string || "";
|
||||
@ -509,8 +509,8 @@ function parseInvite(invite: { [f: string]: string | number | string[][] | boole
|
||||
parsed.userExpiry = invite["user-expiry"] as boolean;
|
||||
parsed.userExpiryTime = userExpiryTime.slice(0, -1);
|
||||
parsed.remainingUses = invite["no-limit"] ? "∞" : String(invite["remaining-uses"])
|
||||
parsed.usedBy = invite["used-by"] as string[][] || [];
|
||||
parsed.created = invite["created"] as string || window.lang.strings("unknown");
|
||||
parsed.usedBy = invite["used-by"] as { [name: string]: number } || {} ;
|
||||
parsed.created = invite["created"] as number || 0;
|
||||
parsed.profile = invite["profile"] as string || "";
|
||||
parsed.notifyExpiry = invite["notify-expiry"] as boolean || false;
|
||||
parsed.notifyCreation = invite["notify-creation"] as boolean || false;
|
||||
|
@ -766,7 +766,7 @@ class ombiDefaults {
|
||||
}
|
||||
}
|
||||
|
||||
interface templateEmail {
|
||||
export interface templateEmail {
|
||||
content: string;
|
||||
variables: string[];
|
||||
conditionals: string[];
|
||||
@ -829,11 +829,11 @@ class EmailEditor {
|
||||
this._templ = req.response as templateEmail;
|
||||
this._textArea.value = this._templ.content;
|
||||
if (this._templ.html == "") {
|
||||
this._preview.innerHTML = `<pre id="preview-content" class="monospace"></pre>`;
|
||||
this._preview.innerHTML = `<pre class="preview-content" class="monospace"></pre>`;
|
||||
} else {
|
||||
this._preview.innerHTML = this._templ.html;
|
||||
}
|
||||
this._previewContent = document.getElementById("preview-content");
|
||||
this._previewContent = this._preview.getElementsByClassName("preview-content")[0] as HTMLElement;
|
||||
this.loadPreview();
|
||||
this._content = this._templ.content;
|
||||
const colors = ["info", "urge", "positive", "neutral"];
|
||||
|
6
views.go
6
views.go
@ -53,13 +53,15 @@ func (app *appContext) pushResources(gc *gin.Context, admin bool) {
|
||||
gc.Header("Link", cssHeader)
|
||||
}
|
||||
|
||||
type Page int
|
||||
|
||||
const (
|
||||
AdminPage = iota + 1
|
||||
AdminPage Page = iota + 1
|
||||
FormPage
|
||||
PWRPage
|
||||
)
|
||||
|
||||
func (app *appContext) getLang(gc *gin.Context, page int, chosen string) string {
|
||||
func (app *appContext) getLang(gc *gin.Context, page Page, chosen string) string {
|
||||
lang := gc.Query("lang")
|
||||
cookie, err := gc.Cookie("lang")
|
||||
if lang != "" {
|
||||
|
Loading…
Reference in New Issue
Block a user