Skip to content

Commit

Permalink
add preview to Announcements
Browse files Browse the repository at this point in the history
  • Loading branch information
hrfee committed May 3, 2021
1 parent 2c6d083 commit c0f316d
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 32 deletions.
5 changes: 4 additions & 1 deletion api.go
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
28 changes: 17 additions & 11 deletions html/admin.html
Expand Up @@ -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">&times;</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>
Expand Down
13 changes: 7 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -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",
Expand Down
49 changes: 44 additions & 5 deletions ts/modules/accounts.ts
@@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -432,24 +438,33 @@ 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);
const form = document.getElementById("form-announce") as HTMLFormElement;
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) {
Expand All @@ -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 = () => {
Expand Down Expand Up @@ -750,6 +787,8 @@ export class accountsList {
}
this._checkCheckCount();
};

this._announceTextarea.onkeyup = this.loadPreview;
}

reload = () => _get("/users", null, (req: XMLHttpRequest) => {
Expand Down
8 changes: 4 additions & 4 deletions ts/modules/invites.ts
Expand Up @@ -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));
}
Expand Down Expand Up @@ -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 || "";
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions ts/modules/settings.ts
Expand Up @@ -766,7 +766,7 @@ class ombiDefaults {
}
}

interface templateEmail {
export interface templateEmail {
content: string;
variables: string[];
conditionals: string[];
Expand Down Expand Up @@ -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"];
Expand Down
6 changes: 4 additions & 2 deletions views.go
Expand Up @@ -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 != "" {
Expand Down

0 comments on commit c0f316d

Please sign in to comment.