Implements language selector and some lang list improvements
This commit is contained in:
@@ -93,6 +93,10 @@ a:hover {
|
||||
padding: 1.25rem 0.75rem;
|
||||
}
|
||||
|
||||
select.form-control {
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
box-shadow: none;
|
||||
border-color: var(--primary);
|
||||
|
||||
@@ -61,6 +61,28 @@
|
||||
aria-label="{{ tr "profile.template.form.handle.label" }}">
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="profileFormPreferredLanguage">{{ tr "profile.template.form.preferred-language.label" }}</label>
|
||||
<select
|
||||
class="form-control"
|
||||
name="preferredLanguage"
|
||||
id="profileFormPreferredLanguage"
|
||||
aria-label="{{ tr "profile.template.form.preferred-language.label" }}"
|
||||
value="{{ .form.preferredLanguage }}"
|
||||
>
|
||||
{{ $prefLang := .form.preferredLanguage }}
|
||||
{{ range .languages }}
|
||||
<option
|
||||
value="{{ .Tag }}"
|
||||
{{ if eq $prefLang .Tag.String }}selected{{ end }}
|
||||
>
|
||||
{{ .LocalizedName }} ({{ .Name }})
|
||||
</option>
|
||||
{{ end }}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button
|
||||
type="submit"
|
||||
|
||||
@@ -2,7 +2,9 @@ package handlers
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/auth/request"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
"github.com/cortezaproject/corteza-server/system/service"
|
||||
"github.com/cortezaproject/corteza-server/system/types"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
@@ -10,14 +12,23 @@ func (h *AuthHandlers) profileForm(req *request.AuthReq) error {
|
||||
req.Template = TmplProfile
|
||||
u := req.AuthUser.User
|
||||
|
||||
req.Data["languages"] = locale.Global().LocalizedList(req.Context())
|
||||
|
||||
if form := req.PopKV(); len(form) > 0 {
|
||||
req.Data["form"] = form
|
||||
} else {
|
||||
req.Data["form"] = map[string]string{
|
||||
"email": u.Email,
|
||||
"handle": u.Handle,
|
||||
"name": u.Name,
|
||||
var preferredLanguage = locale.Global().Default().Tag.String()
|
||||
if u.Meta != nil && u.Meta.PreferredLanguage != "" {
|
||||
preferredLanguage = u.Meta.PreferredLanguage
|
||||
}
|
||||
|
||||
req.Data["form"] = map[string]string{
|
||||
"email": u.Email,
|
||||
"handle": u.Handle,
|
||||
"name": u.Name,
|
||||
"preferredLanguage": preferredLanguage,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
req.Data["emailConfirmationRequired"] = !u.EmailConfirmed && h.Settings.EmailConfirmationRequired
|
||||
@@ -32,6 +43,14 @@ func (h *AuthHandlers) profileProc(req *request.AuthReq) error {
|
||||
u.Handle = req.Request.PostFormValue("handle")
|
||||
u.Name = req.Request.PostFormValue("name")
|
||||
|
||||
if pl := req.Request.PostFormValue("preferredLanguage"); pl != "" {
|
||||
if u.Meta == nil {
|
||||
u.Meta = &types.UserMeta{}
|
||||
}
|
||||
|
||||
u.Meta.PreferredLanguage = pl
|
||||
}
|
||||
|
||||
// a little workaround to inject current user as authenticated identity into context
|
||||
// this way user service will pass us through.
|
||||
user, err := h.UserService.Update(req.Context(), u)
|
||||
|
||||
@@ -33,12 +33,13 @@ type (
|
||||
// pointer to the place we loaded files from
|
||||
fs fs.FS
|
||||
|
||||
Tag language.Tag
|
||||
Name string
|
||||
Tag language.Tag `json:"tag,string"`
|
||||
Name string `json:"name"`
|
||||
LocalizedName string `json:"localizedName"`
|
||||
|
||||
// Language (tag) that this language is extending
|
||||
// @todo
|
||||
Extends language.Tag
|
||||
Extends language.Tag `json:"-"`
|
||||
|
||||
// Points to extended language
|
||||
// @todo
|
||||
|
||||
+38
-1
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/pkg/options"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/language/display"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -205,7 +206,43 @@ func (svc *service) List() []*Language {
|
||||
|
||||
ll := make([]*Language, 0, len(svc.set))
|
||||
for _, tag := range svc.tags {
|
||||
ll = append(ll, svc.set[tag])
|
||||
if svc.set[tag] != nil {
|
||||
ll = append(ll, svc.set[tag])
|
||||
}
|
||||
}
|
||||
|
||||
return ll
|
||||
}
|
||||
|
||||
// List localized list of all languages
|
||||
func (svc *service) LocalizedList(ctx context.Context) []*Language {
|
||||
svc.l.RLock()
|
||||
defer svc.l.RUnlock()
|
||||
|
||||
var (
|
||||
l *Language
|
||||
ll = make([]*Language, 0, len(svc.set))
|
||||
reqLang = GetLanguageFromContext(ctx)
|
||||
)
|
||||
|
||||
for _, tag := range svc.tags {
|
||||
l = svc.set[tag]
|
||||
if l == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
l = &Language{
|
||||
Tag: l.Tag,
|
||||
Name: l.Name,
|
||||
LocalizedName: display.Languages(reqLang).Name(l.Tag),
|
||||
}
|
||||
|
||||
if l.Name == "" {
|
||||
// for cases when language name is not configured
|
||||
l.Name = display.Languages(l.Tag).Name(l.Tag)
|
||||
}
|
||||
|
||||
ll = append(ll, l)
|
||||
}
|
||||
|
||||
return ll
|
||||
|
||||
+1
-15
@@ -9,7 +9,6 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
"github.com/cortezaproject/corteza-server/system/rest/request"
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/language/display"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -28,20 +27,7 @@ func (Locale) New() *Locale {
|
||||
}
|
||||
|
||||
func (ctrl Locale) List(ctx context.Context, r *request.LocaleList) (interface{}, error) {
|
||||
var (
|
||||
rval = make([]*localeResponse, 0, 16)
|
||||
currentLang = locale.GetLanguageFromContext(ctx)
|
||||
)
|
||||
|
||||
for _, l := range locale.Global().List() {
|
||||
rval = append(rval, &localeResponse{
|
||||
Name: display.Languages(l.Tag).Name(l.Tag),
|
||||
Self: display.Languages(currentLang).Name(l.Tag),
|
||||
Tag: l.Tag,
|
||||
})
|
||||
}
|
||||
|
||||
return rval, nil
|
||||
return locale.Global().LocalizedList(ctx), nil
|
||||
}
|
||||
|
||||
func (ctrl Locale) Get(ctx context.Context, r *request.LocaleGet) (interface{}, error) {
|
||||
|
||||
+5
-1
@@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/api"
|
||||
"github.com/cortezaproject/corteza-server/pkg/corredor"
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
@@ -14,7 +16,6 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/system/types"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cast"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var _ = errors.Wrap
|
||||
@@ -140,6 +141,9 @@ func (ctrl User) PartialUpdate(ctx context.Context, r *request.UserPartialUpdate
|
||||
err = json.Unmarshal(p.Value, &aux)
|
||||
|
||||
switch p.Path {
|
||||
case "/meta/preferredLanguage":
|
||||
u.Meta.PreferredLanguage, err = cast.ToStringE(aux)
|
||||
|
||||
case "/meta/securityPolicy/mfa/enforcedEmailOTP":
|
||||
u.Meta.SecurityPolicy.MFA.EnforcedEmailOTP, err = cast.ToBoolE(aux)
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ type (
|
||||
// @todo remove, obsolete.
|
||||
Avatar string `json:"avatar,omitempty"`
|
||||
|
||||
PreferredLanguage string `json:"preferredLanguage"`
|
||||
|
||||
// User's security policy settings
|
||||
SecurityPolicy struct {
|
||||
// settings for multi-factor authentication
|
||||
|
||||
Reference in New Issue
Block a user