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)
if !app.checkInvite(req.Code, false, "") {
app.info.Printf("%s New user failed: invalid code", req.Code)
respondBool(401, false, gc)
respond(401, "errorInvalidCode", gc)
return
}
validation := app.validator.validate(req.Password)
@ -344,15 +344,15 @@ func (app *appContext) NewUser(gc *gin.Context) {
}
existingUser, _, _ := app.jf.UserByName(req.Username, false)
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)
respond(401, msg, gc)
respond(401, "errorUserExists", gc)
return
}
user, status, err := app.jf.NewUser(req.Username, req.Password)
if !(status == 200 || status == 204) || err != nil {
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
}
app.storage.loadProfiles()

View File

@ -5,6 +5,7 @@
window.invalidPassword = "{{ .strings.reEnterPasswordInvalid }}";
window.URLBase = "{{ .urlBase }}";
window.code = "{{ .code }}";
window.messages = JSON.parse({{ .notifications }});
</script>
<script src="js/form.js" type="module"></script>
{{ 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>
</div>
</div>
<div id="notification-box"></div>
<span class="dropdown" tabindex="0" id="lang-dropdown">
<span class="button ~urge dropdown-button">
<i class="ri-global-line"></i>

View File

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

View File

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

View File

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

View File

@ -7,6 +7,7 @@ interface formWindow extends Window {
invalidPassword: string;
modal: Modal;
code: string;
messages: { [key: string]: string };
}
interface pwValString {
@ -75,7 +76,8 @@ rePasswordField.addEventListener("keyup", checkPasswords);
passwordField.addEventListener("keyup", checkPasswords);
interface respDTO {
[ type: string ]: boolean;
response: boolean;
error: string;
}
interface sendDTO {
@ -96,13 +98,12 @@ const create = (event: SubmitEvent) => {
};
_post("/newUser", send, (req: XMLHttpRequest) => {
if (req.readyState == 4) {
let vals = JSON.parse(req.response) as respDTO;
let vals = req.response as respDTO;
let valid = true;
for (let type in vals) {
if (requirements[type]) { requirements[type].valid = vals[type]; }
if (!vals[type]) { valid = false; }
}
toggleLoader(submitSpan);
if (req.status == 200 && valid) {
window.modal.show();
} else {
@ -114,6 +115,21 @@ const create = (event: SubmitEvent) => {
}, 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));
};
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();
req.open("POST", window.URLBase + url, true);
if (response) {
@ -76,7 +76,8 @@ export const _post = (url: string, data: Object, onreadystatechange: (req: XMLHt
req.setRequestHeader("Authorization", "Bearer " + window.token);
req.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
req.onreadystatechange = () => {
if (req.status == 0) {
if (statusHandler) { statusHandler(req); }
else if (req.status == 0) {
window.notifications.connectionError();
return;
} 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),
"strings": app.storage.lang.Form[lang].Strings,
"validationStrings": app.storage.lang.Form[lang].validationStringsJSON,
"notifications": app.storage.lang.Form[lang].notificationsJSON,
"code": code,
})
} else {