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

Display error messages on form

two new strings need translating in lang/form.
This commit is contained in:
Harvey Tindall 2021-01-25 18:01:18 +00:00
parent 061945218a
commit 8af1c13d7e
Signed by: hrfee
GPG Key ID: BBC65952848FB1A2
9 changed files with 42 additions and 12 deletions

8
api.go
View File

@ -325,7 +325,7 @@ func (app *appContext) NewUser(gc *gin.Context) {
app.debug.Printf("%s: New user attempt", req.Code) app.debug.Printf("%s: New user attempt", req.Code)
if !app.checkInvite(req.Code, false, "") { if !app.checkInvite(req.Code, false, "") {
app.info.Printf("%s New user failed: invalid code", req.Code) app.info.Printf("%s New user failed: invalid code", req.Code)
respondBool(401, false, gc) respond(401, "errorInvalidCode", gc)
return return
} }
validation := app.validator.validate(req.Password) validation := app.validator.validate(req.Password)
@ -344,15 +344,15 @@ func (app *appContext) NewUser(gc *gin.Context) {
} }
existingUser, _, _ := app.jf.UserByName(req.Username, false) existingUser, _, _ := app.jf.UserByName(req.Username, false)
if existingUser != nil { if existingUser != nil {
msg := fmt.Sprintf("User already exists named %s", req.Username) msg := fmt.Sprintf("User %s", req.Username)
app.info.Printf("%s New user failed: %s", req.Code, msg) app.info.Printf("%s New user failed: %s", req.Code, msg)
respond(401, msg, gc) respond(401, "errorUserExists", gc)
return return
} }
user, status, err := app.jf.NewUser(req.Username, req.Password) user, status, err := app.jf.NewUser(req.Username, req.Password)
if !(status == 200 || status == 204) || err != nil { if !(status == 200 || status == 204) || err != nil {
app.err.Printf("%s New user failed: Jellyfin responded with %d", req.Code, status) app.err.Printf("%s New user failed: Jellyfin responded with %d", req.Code, status)
respond(401, "Unknown error", gc) respond(401, app.storage.lang.Admin[app.storage.lang.chosenAdminLang].Notifications.get("errorUnknown"), gc)
return return
} }
app.storage.loadProfiles() app.storage.loadProfiles()

View File

@ -5,6 +5,7 @@
window.invalidPassword = "{{ .strings.reEnterPasswordInvalid }}"; window.invalidPassword = "{{ .strings.reEnterPasswordInvalid }}";
window.URLBase = "{{ .urlBase }}"; window.URLBase = "{{ .urlBase }}";
window.code = "{{ .code }}"; window.code = "{{ .code }}";
window.messages = JSON.parse({{ .notifications }});
</script> </script>
<script src="js/form.js" type="module"></script> <script src="js/form.js" type="module"></script>
{{ end }} {{ end }}

View File

@ -13,7 +13,6 @@
<a class="button ~urge !normal full-width center supra submit" href="{{ .jfLink }}" id="create-success-button">{{ .strings.successContinueButton }}</a> <a class="button ~urge !normal full-width center supra submit" href="{{ .jfLink }}" id="create-success-button">{{ .strings.successContinueButton }}</a>
</div> </div>
</div> </div>
<div id="notification-box"></div>
<span class="dropdown" tabindex="0" id="lang-dropdown"> <span class="dropdown" tabindex="0" id="lang-dropdown">
<span class="button ~urge dropdown-button"> <span class="button ~urge dropdown-button">
<i class="ri-global-line"></i> <i class="ri-global-line"></i>

View File

@ -50,6 +50,8 @@ func (ls *formLangs) getOptions(chosen string) (string, []string) {
type formLang struct { type formLang struct {
Meta langMeta `json:"meta"` Meta langMeta `json:"meta"`
Strings langSection `json:"strings"` Strings langSection `json:"strings"`
Notifications langSection `json:"notifications"`
notificationsJSON string
ValidationStrings map[string]quantityString `json:"validationStrings"` ValidationStrings map[string]quantityString `json:"validationStrings"`
validationStringsJSON string validationStringsJSON string
} }

View File

@ -16,6 +16,10 @@
"successHeader": "Success!", "successHeader": "Success!",
"successContinueButton": "Continue" "successContinueButton": "Continue"
}, },
"notifications": {
"errorUserExists": "User already exists.",
"errorInvalidCode": "Invalid invite code."
},
"validationStrings": { "validationStrings": {
"length": { "length": {
"singular": "Must have at least {n} character", "singular": "Must have at least {n} character",

View File

@ -166,12 +166,18 @@ func (st *Storage) loadLangForm() error {
} }
if fname != "en-us.json" { if fname != "en-us.json" {
patchLang(&english.Strings, &lang.Strings) patchLang(&english.Strings, &lang.Strings)
patchLang(&english.Notifications, &lang.Notifications)
patchQuantityStrings(&english.ValidationStrings, &lang.ValidationStrings) patchQuantityStrings(&english.ValidationStrings, &lang.ValidationStrings)
} }
notifications, err := json.Marshal(lang.Notifications)
if err != nil {
return err
}
validationStrings, err := json.Marshal(lang.ValidationStrings) validationStrings, err := json.Marshal(lang.ValidationStrings)
if err != nil { if err != nil {
return err return err
} }
lang.notificationsJSON = string(notifications)
lang.validationStringsJSON = string(validationStrings) lang.validationStringsJSON = string(validationStrings)
st.lang.Form[index] = lang st.lang.Form[index] = lang
return nil return nil

View File

@ -7,6 +7,7 @@ interface formWindow extends Window {
invalidPassword: string; invalidPassword: string;
modal: Modal; modal: Modal;
code: string; code: string;
messages: { [key: string]: string };
} }
interface pwValString { interface pwValString {
@ -75,7 +76,8 @@ rePasswordField.addEventListener("keyup", checkPasswords);
passwordField.addEventListener("keyup", checkPasswords); passwordField.addEventListener("keyup", checkPasswords);
interface respDTO { interface respDTO {
[ type: string ]: boolean; response: boolean;
error: string;
} }
interface sendDTO { interface sendDTO {
@ -96,13 +98,12 @@ const create = (event: SubmitEvent) => {
}; };
_post("/newUser", send, (req: XMLHttpRequest) => { _post("/newUser", send, (req: XMLHttpRequest) => {
if (req.readyState == 4) { if (req.readyState == 4) {
let vals = JSON.parse(req.response) as respDTO; let vals = req.response as respDTO;
let valid = true; let valid = true;
for (let type in vals) { for (let type in vals) {
if (requirements[type]) { requirements[type].valid = vals[type]; } if (requirements[type]) { requirements[type].valid = vals[type]; }
if (!vals[type]) { valid = false; } if (!vals[type]) { valid = false; }
} }
toggleLoader(submitSpan);
if (req.status == 200 && valid) { if (req.status == 200 && valid) {
window.modal.show(); window.modal.show();
} else { } else {
@ -114,6 +115,21 @@ const create = (event: SubmitEvent) => {
}, 1000); }, 1000);
} }
} }
}, true, (req: XMLHttpRequest) => {
if (req.readyState == 4) {
toggleLoader(submitSpan);
if (req.status == 401) {
if (req.response["error"] as string) {
const old = submitSpan.textContent;
if (req.response["error"] in window.messages) {
submitSpan.textContent = window.messages[req.response["error"]];
} else {
submitSpan.textContent = req.response["error"];
}
setTimeout(() => { submitSpan.textContent = old; }, 1000);
}
}
}
}); });
}; };

View File

@ -67,7 +67,7 @@ export const _get = (url: string, data: Object, onreadystatechange: (req: XMLHtt
req.send(JSON.stringify(data)); req.send(JSON.stringify(data));
}; };
export const _post = (url: string, data: Object, onreadystatechange: (req: XMLHttpRequest) => void, response?: boolean): void => { export const _post = (url: string, data: Object, onreadystatechange: (req: XMLHttpRequest) => void, response?: boolean, statusHandler?: (req: XMLHttpRequest) => void): void => {
let req = new XMLHttpRequest(); let req = new XMLHttpRequest();
req.open("POST", window.URLBase + url, true); req.open("POST", window.URLBase + url, true);
if (response) { if (response) {
@ -76,7 +76,8 @@ export const _post = (url: string, data: Object, onreadystatechange: (req: XMLHt
req.setRequestHeader("Authorization", "Bearer " + window.token); req.setRequestHeader("Authorization", "Bearer " + window.token);
req.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); req.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
req.onreadystatechange = () => { req.onreadystatechange = () => {
if (req.status == 0) { if (statusHandler) { statusHandler(req); }
else if (req.status == 0) {
window.notifications.connectionError(); window.notifications.connectionError();
return; return;
} else if (req.status == 401) { } else if (req.status == 401) {

View File

@ -96,6 +96,7 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
"username": !app.config.Section("email").Key("no_username").MustBool(false), "username": !app.config.Section("email").Key("no_username").MustBool(false),
"strings": app.storage.lang.Form[lang].Strings, "strings": app.storage.lang.Form[lang].Strings,
"validationStrings": app.storage.lang.Form[lang].validationStringsJSON, "validationStrings": app.storage.lang.Form[lang].validationStringsJSON,
"notifications": app.storage.lang.Form[lang].notificationsJSON,
"code": code, "code": code,
}) })
} else { } else {