diff --git a/compose/service/locale.gen.go b/compose/service/locale.gen.go index 4c0ef2550..388540180 100644 --- a/compose/service/locale.gen.go +++ b/compose/service/locale.gen.go @@ -48,15 +48,19 @@ func ResourceTranslation(ls locale.Resource) *resourceTranslation { return &resourceTranslation{ actionlog: DefaultActionlog, store: DefaultStore, + ac: DefaultAccessControl, locale: ls, } } func (svc resourceTranslation) Upsert(ctx context.Context, rr locale.ResourceTranslationSet) (err error) { // @todo AC + //if (!svc.ac.CanManageResourceTranslation(ctx)) { + // return *****ErrNotAllowedToCreate() + //} + // @todo validation - defer locale.Global().ReloadResourceTranslations(ctx) me := auth.GetIdentityFromContext(ctx) // - group by resource @@ -99,6 +103,11 @@ func (svc resourceTranslation) Upsert(ctx context.Context, rr locale.ResourceTra if err != nil { return err } + + // Reload ALL resource translations + // @todo we could probably do this more selectively and refresh only updated resources? + _ = locale.Global().ReloadResourceTranslations(ctx) + return nil } diff --git a/pkg/codegen-v3/assets/templates/gocode/locale/service.go.tpl b/pkg/codegen-v3/assets/templates/gocode/locale/service.go.tpl index 9200440ea..d06f17c6b 100644 --- a/pkg/codegen-v3/assets/templates/gocode/locale/service.go.tpl +++ b/pkg/codegen-v3/assets/templates/gocode/locale/service.go.tpl @@ -40,15 +40,19 @@ func ResourceTranslation(ls locale.Resource) *resourceTranslation { return &resourceTranslation{ actionlog: DefaultActionlog, store: DefaultStore, + ac: DefaultAccessControl, locale: ls, } } func (svc resourceTranslation) Upsert(ctx context.Context, rr locale.ResourceTranslationSet) (err error) { // @todo AC + //if (!svc.ac.CanManageResourceTranslation(ctx)) { + // return *****ErrNotAllowedToCreate() + //} + // @todo validation - defer locale.Global().ReloadResourceTranslations(ctx) me := auth.GetIdentityFromContext(ctx) // - group by resource @@ -91,6 +95,11 @@ func (svc resourceTranslation) Upsert(ctx context.Context, rr locale.ResourceTra if err != nil { return err } + + // Reload ALL resource translations + // @todo we could probably do this more selectively and refresh only updated resources? + _ = locale.Global().ReloadResourceTranslations(ctx) + return nil } diff --git a/pkg/locale/locale.go b/pkg/locale/locale.go index f0de41d04..557a9b912 100644 --- a/pkg/locale/locale.go +++ b/pkg/locale/locale.go @@ -104,6 +104,9 @@ func (l *Language) tResource(ns, key string, rr ...string) string { // resourceTranslations returns all resource translations for the specified resource func (l *Language) resourceTranslations(resource string) ResourceTranslationIndex { + l.l.RLock() + defer l.l.RUnlock() + out := make(ResourceTranslationIndex) if l.resources == nil { return out diff --git a/pkg/locale/service.go b/pkg/locale/service.go index c143875e6..d07ecddc0 100644 --- a/pkg/locale/service.go +++ b/pkg/locale/service.go @@ -228,6 +228,10 @@ func (svc *service) ReloadStatic() (err error) { // ReloadResourceTranslations all language configurations (as configured via path options) and // all translation files func (svc *service) ReloadResourceTranslations(ctx context.Context) (err error) { + if svc.s == nil { + return fmt.Errorf("store for locale service not set") + } + svc.l.RLock() defer svc.l.RUnlock() @@ -235,11 +239,13 @@ func (svc *service) ReloadResourceTranslations(ctx context.Context) (err error) zap.Strings("tags", tagsToStrings(svc.tags)), ) - for i, tag := range svc.tags { + for _, tag := range svc.tags { lang, ok := svc.set[tag] if !ok { lang = &Language{ Tag: tag, + // @todo find a better name for this, because it's not the + // language that it's loaded from the store, the resource translations are src: "store", } @@ -251,29 +257,11 @@ func (svc *service) ReloadResourceTranslations(ctx context.Context) (err error) } svc.log.Info( - "language loaded", + "resource translations loaded", zap.Stringer("tag", lang.Tag), zap.String("src", lang.src), - zap.Stringer("extends", lang.Extends), + zap.Int("translations", len(lang.resources)), ) - - if i == 0 && svc.def == nil { - // set first one as default - svc.def = lang - } - } - - // Do another pass and link all extended languages - for _, lang := range svc.set { - if lang.Extends.IsRoot() { - continue - } - - if svc.set[lang.Extends] == nil { - return fmt.Errorf("could not extend langage %q from an unknown language %q", lang.Tag, lang.Extends) - } - - lang.extends = svc.set[lang.Extends] } return nil @@ -365,11 +353,11 @@ func (svc *service) EncodeExternal(w io.Writer, app string, ll ...language.Tag) // Language is picked from the context func (svc *service) NS(ctx context.Context, ns string) func(key string, rr ...string) string { var ( - code = GetLanguageFromContext(ctx) + tag = GetLanguageFromContext(ctx) ) return func(key string, rr ...string) string { - return svc.t(code, ns, key, rr...) + return svc.t(tag, ns, key, rr...) } } @@ -391,6 +379,7 @@ func (svc *service) TFor(tag language.Tag, ns, key string, rr ...string) string // // Language is picked from the context func (svc *service) TResource(ctx context.Context, ns, key string, rr ...string) string { + return svc.tResource(GetLanguageFromContext(ctx), ns, key, rr...) } @@ -405,11 +394,11 @@ func (svc *service) TResourceFor(tag language.Tag, ns, key string, rr ...string) // given resource. // // The response is indexed by translation key for nicer lookups. -func (svc *service) ResourceTranslations(code language.Tag, resource string) ResourceTranslationIndex { +func (svc *service) ResourceTranslations(tag language.Tag, resource string) ResourceTranslationIndex { out := make(ResourceTranslationIndex) if svc != nil && svc.set != nil { - if l, has := svc.set[code]; has { + if l, has := svc.set[tag]; has { return l.resourceTranslations(resource) } } @@ -418,9 +407,9 @@ func (svc *service) ResourceTranslations(code language.Tag, resource string) Res } // Finds language and uses it to translate the given key -func (svc *service) t(code language.Tag, ns, key string, rr ...string) string { +func (svc *service) t(tag language.Tag, ns, key string, rr ...string) string { if svc != nil && svc.set != nil { - if l, has := svc.set[code]; has { + if l, has := svc.set[tag]; has { return l.t(ns, key, rr...) } } @@ -429,9 +418,9 @@ func (svc *service) t(code language.Tag, ns, key string, rr ...string) string { } // Finds language and uses it to translate the given key for resource -func (svc *service) tResource(code language.Tag, ns, key string, rr ...string) string { +func (svc *service) tResource(tag language.Tag, ns, key string, rr ...string) string { if svc != nil && svc.set != nil { - if l, has := svc.set[code]; has { + if l, has := svc.set[tag]; has { return l.tResource(ns, key, rr...) } } diff --git a/store/rdbms/resource_translation.go b/store/rdbms/resource_translation.go index 518d6722a..67096f494 100644 --- a/store/rdbms/resource_translation.go +++ b/store/rdbms/resource_translation.go @@ -36,6 +36,8 @@ func (s Store) convertResourceTranslationFilter(f types.ResourceTranslationFilte // TransformResource converts raw resource translations into the format used by // the locale package. +// +// @todo this function knows too much (locale pkg), move it out of store func (s *Store) TransformResource(ctx context.Context, lang language.Tag) (out map[string]map[string]*locale.ResourceTranslation, err error) { out = make(map[string]map[string]*locale.ResourceTranslation) var cc types.ResourceTranslationSet