Apply i18n to the more complex Compose resources
This commit is contained in:
parent
f457ee6c12
commit
e8e998293d
@ -12,6 +12,7 @@ endpoints:
|
||||
authentication: []
|
||||
imports:
|
||||
- github.com/cortezaproject/corteza-server/pkg/label
|
||||
- github.com/cortezaproject/corteza-server/pkg/locale
|
||||
- sqlxTypes github.com/jmoiron/sqlx/types
|
||||
- time
|
||||
apis:
|
||||
@ -148,6 +149,32 @@ endpoints:
|
||||
type: string
|
||||
title: Script to execute
|
||||
required: true
|
||||
- name: list resource
|
||||
method: GET
|
||||
title: List resource translations
|
||||
path: "/{namespaceID}/locale"
|
||||
parameters:
|
||||
path:
|
||||
- type: uint64
|
||||
name: namespaceID
|
||||
required: true
|
||||
title: ID
|
||||
- name: update resource
|
||||
method: PATCH
|
||||
title: Update resource translations
|
||||
path: "/{namespaceID}/locale"
|
||||
parameters:
|
||||
path:
|
||||
- type: uint64
|
||||
name: namespaceID
|
||||
required: true
|
||||
title: ID
|
||||
post:
|
||||
- name: locale
|
||||
type: locale.ResourceTranslationSet
|
||||
title: Resource translations to upsert
|
||||
required: true
|
||||
|
||||
- title: Pages
|
||||
description: Compose pages
|
||||
entrypoint: page
|
||||
@ -155,6 +182,7 @@ endpoints:
|
||||
authentication: []
|
||||
imports:
|
||||
- sqlxTypes github.com/jmoiron/sqlx/types
|
||||
- github.com/cortezaproject/corteza-server/pkg/locale
|
||||
- github.com/cortezaproject/corteza-server/pkg/label
|
||||
parameters:
|
||||
path:
|
||||
@ -357,6 +385,33 @@ endpoints:
|
||||
type: string
|
||||
title: Script to execute
|
||||
required: true
|
||||
|
||||
- name: list resource
|
||||
method: GET
|
||||
title: List resource translations
|
||||
path: "/{pageID}/locale"
|
||||
parameters:
|
||||
path:
|
||||
- type: uint64
|
||||
name: pageID
|
||||
required: true
|
||||
title: ID
|
||||
- name: update resource
|
||||
method: PATCH
|
||||
title: Update resource translations
|
||||
path: "/{pageID}/locale"
|
||||
parameters:
|
||||
path:
|
||||
- type: uint64
|
||||
name: pageID
|
||||
required: true
|
||||
title: ID
|
||||
post:
|
||||
- name: locale
|
||||
type: locale.ResourceTranslationSet
|
||||
title: Resource translations to upsert
|
||||
required: true
|
||||
|
||||
- title: Modules
|
||||
description: Compose module definitions
|
||||
entrypoint: module
|
||||
@ -371,6 +426,7 @@ endpoints:
|
||||
imports:
|
||||
- sqlxTypes github.com/jmoiron/sqlx/types
|
||||
- github.com/cortezaproject/corteza-server/compose/types
|
||||
- github.com/cortezaproject/corteza-server/pkg/locale
|
||||
- github.com/cortezaproject/corteza-server/pkg/label
|
||||
- time
|
||||
apis:
|
||||
@ -501,6 +557,32 @@ endpoints:
|
||||
type: string
|
||||
title: Script to execute
|
||||
required: true
|
||||
- name: list resource
|
||||
method: GET
|
||||
title: List resource translations
|
||||
path: "/{moduleID}/locale"
|
||||
parameters:
|
||||
path:
|
||||
- type: uint64
|
||||
name: moduleID
|
||||
required: true
|
||||
title: ID
|
||||
- name: update resource
|
||||
method: PATCH
|
||||
title: Update resource translations
|
||||
path: "/{moduleID}/locale"
|
||||
parameters:
|
||||
path:
|
||||
- type: uint64
|
||||
name: moduleID
|
||||
required: true
|
||||
title: ID
|
||||
post:
|
||||
- name: locale
|
||||
type: locale.ResourceTranslationSet
|
||||
title: Resource translations to upsert
|
||||
required: true
|
||||
|
||||
- title: Records
|
||||
description: Compose records
|
||||
entrypoint: record
|
||||
|
||||
@ -25,6 +25,8 @@ type (
|
||||
Update(context.Context, *request.ModuleUpdate) (interface{}, error)
|
||||
Delete(context.Context, *request.ModuleDelete) (interface{}, error)
|
||||
TriggerScript(context.Context, *request.ModuleTriggerScript) (interface{}, error)
|
||||
ListLocale(context.Context, *request.ModuleListLocale) (interface{}, error)
|
||||
UpdateLocale(context.Context, *request.ModuleUpdateLocale) (interface{}, error)
|
||||
}
|
||||
|
||||
// HTTP API interface
|
||||
@ -35,6 +37,8 @@ type (
|
||||
Update func(http.ResponseWriter, *http.Request)
|
||||
Delete func(http.ResponseWriter, *http.Request)
|
||||
TriggerScript func(http.ResponseWriter, *http.Request)
|
||||
ListLocale func(http.ResponseWriter, *http.Request)
|
||||
UpdateLocale func(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
)
|
||||
|
||||
@ -134,6 +138,38 @@ func NewModule(h ModuleAPI) *Module {
|
||||
return
|
||||
}
|
||||
|
||||
api.Send(w, r, value)
|
||||
},
|
||||
ListLocale: func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
params := request.NewModuleListLocale()
|
||||
if err := params.Fill(r); err != nil {
|
||||
api.Send(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
value, err := h.ListLocale(r.Context(), params)
|
||||
if err != nil {
|
||||
api.Send(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
api.Send(w, r, value)
|
||||
},
|
||||
UpdateLocale: func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
params := request.NewModuleUpdateLocale()
|
||||
if err := params.Fill(r); err != nil {
|
||||
api.Send(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
value, err := h.UpdateLocale(r.Context(), params)
|
||||
if err != nil {
|
||||
api.Send(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
api.Send(w, r, value)
|
||||
},
|
||||
}
|
||||
@ -148,5 +184,7 @@ func (h Module) MountRoutes(r chi.Router, middlewares ...func(http.Handler) http
|
||||
r.Post("/namespace/{namespaceID}/module/{moduleID}", h.Update)
|
||||
r.Delete("/namespace/{namespaceID}/module/{moduleID}", h.Delete)
|
||||
r.Post("/namespace/{namespaceID}/module/{moduleID}/trigger", h.TriggerScript)
|
||||
r.Get("/namespace/{namespaceID}/module/{moduleID}/locale", h.ListLocale)
|
||||
r.Patch("/namespace/{namespaceID}/module/{moduleID}/locale", h.UpdateLocale)
|
||||
})
|
||||
}
|
||||
|
||||
@ -26,6 +26,8 @@ type (
|
||||
Delete(context.Context, *request.NamespaceDelete) (interface{}, error)
|
||||
Upload(context.Context, *request.NamespaceUpload) (interface{}, error)
|
||||
TriggerScript(context.Context, *request.NamespaceTriggerScript) (interface{}, error)
|
||||
ListLocale(context.Context, *request.NamespaceListLocale) (interface{}, error)
|
||||
UpdateLocale(context.Context, *request.NamespaceUpdateLocale) (interface{}, error)
|
||||
}
|
||||
|
||||
// HTTP API interface
|
||||
@ -37,6 +39,8 @@ type (
|
||||
Delete func(http.ResponseWriter, *http.Request)
|
||||
Upload func(http.ResponseWriter, *http.Request)
|
||||
TriggerScript func(http.ResponseWriter, *http.Request)
|
||||
ListLocale func(http.ResponseWriter, *http.Request)
|
||||
UpdateLocale func(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
)
|
||||
|
||||
@ -152,6 +156,38 @@ func NewNamespace(h NamespaceAPI) *Namespace {
|
||||
return
|
||||
}
|
||||
|
||||
api.Send(w, r, value)
|
||||
},
|
||||
ListLocale: func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
params := request.NewNamespaceListLocale()
|
||||
if err := params.Fill(r); err != nil {
|
||||
api.Send(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
value, err := h.ListLocale(r.Context(), params)
|
||||
if err != nil {
|
||||
api.Send(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
api.Send(w, r, value)
|
||||
},
|
||||
UpdateLocale: func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
params := request.NewNamespaceUpdateLocale()
|
||||
if err := params.Fill(r); err != nil {
|
||||
api.Send(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
value, err := h.UpdateLocale(r.Context(), params)
|
||||
if err != nil {
|
||||
api.Send(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
api.Send(w, r, value)
|
||||
},
|
||||
}
|
||||
@ -167,5 +203,7 @@ func (h Namespace) MountRoutes(r chi.Router, middlewares ...func(http.Handler) h
|
||||
r.Delete("/namespace/{namespaceID}", h.Delete)
|
||||
r.Post("/namespace/upload", h.Upload)
|
||||
r.Post("/namespace/{namespaceID}/trigger", h.TriggerScript)
|
||||
r.Get("/namespace/{namespaceID}/locale", h.ListLocale)
|
||||
r.Patch("/namespace/{namespaceID}/locale", h.UpdateLocale)
|
||||
})
|
||||
}
|
||||
|
||||
@ -28,6 +28,8 @@ type (
|
||||
Delete(context.Context, *request.PageDelete) (interface{}, error)
|
||||
Upload(context.Context, *request.PageUpload) (interface{}, error)
|
||||
TriggerScript(context.Context, *request.PageTriggerScript) (interface{}, error)
|
||||
ListLocale(context.Context, *request.PageListLocale) (interface{}, error)
|
||||
UpdateLocale(context.Context, *request.PageUpdateLocale) (interface{}, error)
|
||||
}
|
||||
|
||||
// HTTP API interface
|
||||
@ -41,6 +43,8 @@ type (
|
||||
Delete func(http.ResponseWriter, *http.Request)
|
||||
Upload func(http.ResponseWriter, *http.Request)
|
||||
TriggerScript func(http.ResponseWriter, *http.Request)
|
||||
ListLocale func(http.ResponseWriter, *http.Request)
|
||||
UpdateLocale func(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
)
|
||||
|
||||
@ -188,6 +192,38 @@ func NewPage(h PageAPI) *Page {
|
||||
return
|
||||
}
|
||||
|
||||
api.Send(w, r, value)
|
||||
},
|
||||
ListLocale: func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
params := request.NewPageListLocale()
|
||||
if err := params.Fill(r); err != nil {
|
||||
api.Send(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
value, err := h.ListLocale(r.Context(), params)
|
||||
if err != nil {
|
||||
api.Send(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
api.Send(w, r, value)
|
||||
},
|
||||
UpdateLocale: func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
params := request.NewPageUpdateLocale()
|
||||
if err := params.Fill(r); err != nil {
|
||||
api.Send(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
value, err := h.UpdateLocale(r.Context(), params)
|
||||
if err != nil {
|
||||
api.Send(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
api.Send(w, r, value)
|
||||
},
|
||||
}
|
||||
@ -205,5 +241,7 @@ func (h Page) MountRoutes(r chi.Router, middlewares ...func(http.Handler) http.H
|
||||
r.Delete("/namespace/{namespaceID}/page/{pageID}", h.Delete)
|
||||
r.Post("/namespace/{namespaceID}/page/{pageID}/attachment", h.Upload)
|
||||
r.Post("/namespace/{namespaceID}/page/{pageID}/trigger", h.TriggerScript)
|
||||
r.Get("/namespace/{namespaceID}/page/{pageID}/locale", h.ListLocale)
|
||||
r.Patch("/namespace/{namespaceID}/page/{pageID}/locale", h.UpdateLocale)
|
||||
})
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@ type (
|
||||
|
||||
Module struct {
|
||||
module service.ModuleService
|
||||
locale service.ResourceTranslationService
|
||||
namespace service.NamespaceService
|
||||
ac moduleAccessController
|
||||
}
|
||||
@ -60,6 +61,7 @@ func (Module) New() *Module {
|
||||
module: service.DefaultModule,
|
||||
namespace: service.DefaultNamespace,
|
||||
ac: service.DefaultAccessControl,
|
||||
locale: service.DefaultResourceTranslation,
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,6 +94,14 @@ func (ctrl *Module) Read(ctx context.Context, r *request.ModuleRead) (interface{
|
||||
return ctrl.makePayload(ctx, mod, err)
|
||||
}
|
||||
|
||||
func (ctrl *Module) ListLocale(ctx context.Context, r *request.ModuleListLocale) (interface{}, error) {
|
||||
return ctrl.locale.Module(ctx, r.NamespaceID, r.ModuleID)
|
||||
}
|
||||
|
||||
func (ctrl *Module) UpdateLocale(ctx context.Context, r *request.ModuleUpdateLocale) (interface{}, error) {
|
||||
return api.OK(), ctrl.locale.Upsert(ctx, r.Locale)
|
||||
}
|
||||
|
||||
func (ctrl *Module) Create(ctx context.Context, r *request.ModuleCreate) (interface{}, error) {
|
||||
var (
|
||||
err error
|
||||
|
||||
@ -32,6 +32,7 @@ type (
|
||||
|
||||
Namespace struct {
|
||||
namespace service.NamespaceService
|
||||
locale service.ResourceTranslationService
|
||||
attachment service.AttachmentService
|
||||
ac namespaceAccessController
|
||||
}
|
||||
@ -52,6 +53,7 @@ type (
|
||||
func (Namespace) New() *Namespace {
|
||||
return &Namespace{
|
||||
namespace: service.DefaultNamespace,
|
||||
locale: service.DefaultResourceTranslation,
|
||||
attachment: service.DefaultAttachment,
|
||||
ac: service.DefaultAccessControl,
|
||||
}
|
||||
@ -103,6 +105,14 @@ func (ctrl Namespace) Read(ctx context.Context, r *request.NamespaceRead) (inter
|
||||
return ctrl.makePayload(ctx, ns, err)
|
||||
}
|
||||
|
||||
func (ctrl Namespace) ListLocale(ctx context.Context, r *request.NamespaceListLocale) (interface{}, error) {
|
||||
return ctrl.locale.Namespace(ctx, r.NamespaceID)
|
||||
}
|
||||
|
||||
func (ctrl Namespace) UpdateLocale(ctx context.Context, r *request.NamespaceUpdateLocale) (interface{}, error) {
|
||||
return api.OK(), ctrl.locale.Upsert(ctx, r.Locale)
|
||||
}
|
||||
|
||||
func (ctrl Namespace) Update(ctx context.Context, r *request.NamespaceUpdate) (interface{}, error) {
|
||||
var (
|
||||
err error
|
||||
|
||||
@ -44,6 +44,7 @@ type (
|
||||
|
||||
Reorder(ctx context.Context, namespaceID, selfID uint64, pageIDs []uint64) error
|
||||
}
|
||||
locale service.ResourceTranslationService
|
||||
namespace service.NamespaceService
|
||||
attachment service.AttachmentService
|
||||
ac pageAccessController
|
||||
@ -60,6 +61,7 @@ type (
|
||||
func (Page) New() *Page {
|
||||
return &Page{
|
||||
page: service.DefaultPage,
|
||||
locale: service.DefaultResourceTranslation,
|
||||
namespace: service.DefaultNamespace,
|
||||
attachment: service.DefaultAttachment,
|
||||
ac: service.DefaultAccessControl,
|
||||
@ -125,7 +127,14 @@ func (ctrl *Page) Create(ctx context.Context, r *request.PageCreate) (interface{
|
||||
func (ctrl *Page) Read(ctx context.Context, r *request.PageRead) (interface{}, error) {
|
||||
mod, err := ctrl.page.FindByID(ctx, r.NamespaceID, r.PageID)
|
||||
return ctrl.makePayload(ctx, mod, err)
|
||||
}
|
||||
|
||||
func (ctrl *Page) ListLocale(ctx context.Context, r *request.PageListLocale) (interface{}, error) {
|
||||
return ctrl.locale.Page(ctx, r.NamespaceID, r.PageID)
|
||||
}
|
||||
|
||||
func (ctrl *Page) UpdateLocale(ctx context.Context, r *request.PageUpdateLocale) (interface{}, error) {
|
||||
return api.OK(), ctrl.locale.Upsert(ctx, r.Locale)
|
||||
}
|
||||
|
||||
func (ctrl *Page) Reorder(ctx context.Context, r *request.PageReorder) (interface{}, error) {
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/cortezaproject/corteza-server/compose/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/label"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
"github.com/cortezaproject/corteza-server/pkg/payload"
|
||||
"github.com/go-chi/chi"
|
||||
sqlxTypes "github.com/jmoiron/sqlx/types"
|
||||
@ -193,6 +194,35 @@ type (
|
||||
// Script to execute
|
||||
Script string
|
||||
}
|
||||
|
||||
ModuleListLocale struct {
|
||||
// NamespaceID PATH parameter
|
||||
//
|
||||
// Namespace ID
|
||||
NamespaceID uint64 `json:",string"`
|
||||
|
||||
// ModuleID PATH parameter
|
||||
//
|
||||
// ID
|
||||
ModuleID uint64 `json:",string"`
|
||||
}
|
||||
|
||||
ModuleUpdateLocale struct {
|
||||
// NamespaceID PATH parameter
|
||||
//
|
||||
// Namespace ID
|
||||
NamespaceID uint64 `json:",string"`
|
||||
|
||||
// ModuleID PATH parameter
|
||||
//
|
||||
// ID
|
||||
ModuleID uint64 `json:",string"`
|
||||
|
||||
// Locale POST parameter
|
||||
//
|
||||
// ...
|
||||
Locale locale.ResourceTranslationSet
|
||||
}
|
||||
)
|
||||
|
||||
// NewModuleList request
|
||||
@ -770,3 +800,129 @@ func (r *ModuleTriggerScript) Fill(req *http.Request) (err error) {
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// NewModuleListLocale request
|
||||
func NewModuleListLocale() *ModuleListLocale {
|
||||
return &ModuleListLocale{}
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleListLocale) Auditable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"namespaceID": r.NamespaceID,
|
||||
"moduleID": r.ModuleID,
|
||||
}
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleListLocale) GetNamespaceID() uint64 {
|
||||
return r.NamespaceID
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleListLocale) GetModuleID() uint64 {
|
||||
return r.ModuleID
|
||||
}
|
||||
|
||||
// Fill processes request and fills internal variables
|
||||
func (r *ModuleListLocale) Fill(req *http.Request) (err error) {
|
||||
|
||||
{
|
||||
var val string
|
||||
// path params
|
||||
|
||||
val = chi.URLParam(req, "namespaceID")
|
||||
r.NamespaceID, err = payload.ParseUint64(val), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val = chi.URLParam(req, "moduleID")
|
||||
r.ModuleID, err = payload.ParseUint64(val), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// NewModuleUpdateLocale request
|
||||
func NewModuleUpdateLocale() *ModuleUpdateLocale {
|
||||
return &ModuleUpdateLocale{}
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleUpdateLocale) Auditable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"namespaceID": r.NamespaceID,
|
||||
"moduleID": r.ModuleID,
|
||||
"locale": r.Locale,
|
||||
}
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleUpdateLocale) GetNamespaceID() uint64 {
|
||||
return r.NamespaceID
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleUpdateLocale) GetModuleID() uint64 {
|
||||
return r.ModuleID
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleUpdateLocale) GetLocale() locale.ResourceTranslationSet {
|
||||
return r.Locale
|
||||
}
|
||||
|
||||
// Fill processes request and fills internal variables
|
||||
func (r *ModuleUpdateLocale) Fill(req *http.Request) (err error) {
|
||||
|
||||
if strings.ToLower(req.Header.Get("content-type")) == "application/json" {
|
||||
err = json.NewDecoder(req.Body).Decode(r)
|
||||
|
||||
switch {
|
||||
case err == io.EOF:
|
||||
err = nil
|
||||
case err != nil:
|
||||
return fmt.Errorf("error parsing http request body: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if err = req.ParseForm(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// POST params
|
||||
|
||||
//if val, ok := req.Form["locale[]"]; ok && len(val) > 0 {
|
||||
// r.Locale, err = locale.ResourceTranslationSet(val), nil
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
{
|
||||
var val string
|
||||
// path params
|
||||
|
||||
val = chi.URLParam(req, "namespaceID")
|
||||
r.NamespaceID, err = payload.ParseUint64(val), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val = chi.URLParam(req, "moduleID")
|
||||
r.ModuleID, err = payload.ParseUint64(val), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/cortezaproject/corteza-server/pkg/label"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
"github.com/cortezaproject/corteza-server/pkg/payload"
|
||||
"github.com/go-chi/chi"
|
||||
sqlxTypes "github.com/jmoiron/sqlx/types"
|
||||
@ -164,6 +165,25 @@ type (
|
||||
// Script to execute
|
||||
Script string
|
||||
}
|
||||
|
||||
NamespaceListLocale struct {
|
||||
// NamespaceID PATH parameter
|
||||
//
|
||||
// ID
|
||||
NamespaceID uint64 `json:",string"`
|
||||
}
|
||||
|
||||
NamespaceUpdateLocale struct {
|
||||
// NamespaceID PATH parameter
|
||||
//
|
||||
// ID
|
||||
NamespaceID uint64 `json:",string"`
|
||||
|
||||
// Locale POST parameter
|
||||
//
|
||||
// ...
|
||||
Locale locale.ResourceTranslationSet
|
||||
}
|
||||
)
|
||||
|
||||
// NewNamespaceList request
|
||||
@ -692,3 +712,105 @@ func (r *NamespaceTriggerScript) Fill(req *http.Request) (err error) {
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// NewNamespaceListLocale request
|
||||
func NewNamespaceListLocale() *NamespaceListLocale {
|
||||
return &NamespaceListLocale{}
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r NamespaceListLocale) Auditable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"namespaceID": r.NamespaceID,
|
||||
}
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r NamespaceListLocale) GetNamespaceID() uint64 {
|
||||
return r.NamespaceID
|
||||
}
|
||||
|
||||
// Fill processes request and fills internal variables
|
||||
func (r *NamespaceListLocale) Fill(req *http.Request) (err error) {
|
||||
|
||||
{
|
||||
var val string
|
||||
// path params
|
||||
|
||||
val = chi.URLParam(req, "namespaceID")
|
||||
r.NamespaceID, err = payload.ParseUint64(val), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// NewNamespaceUpdateLocale request
|
||||
func NewNamespaceUpdateLocale() *NamespaceUpdateLocale {
|
||||
return &NamespaceUpdateLocale{}
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r NamespaceUpdateLocale) Auditable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"namespaceID": r.NamespaceID,
|
||||
"locale": r.Locale,
|
||||
}
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r NamespaceUpdateLocale) GetNamespaceID() uint64 {
|
||||
return r.NamespaceID
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r NamespaceUpdateLocale) GetLocale() locale.ResourceTranslationSet {
|
||||
return r.Locale
|
||||
}
|
||||
|
||||
// Fill processes request and fills internal variables
|
||||
func (r *NamespaceUpdateLocale) Fill(req *http.Request) (err error) {
|
||||
|
||||
if strings.ToLower(req.Header.Get("content-type")) == "application/json" {
|
||||
err = json.NewDecoder(req.Body).Decode(r)
|
||||
|
||||
switch {
|
||||
case err == io.EOF:
|
||||
err = nil
|
||||
case err != nil:
|
||||
return fmt.Errorf("error parsing http request body: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if err = req.ParseForm(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// POST params
|
||||
|
||||
//if val, ok := req.Form["locale[]"]; ok && len(val) > 0 {
|
||||
// r.Locale, err = locale.ResourceTranslationSet(val), nil
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
{
|
||||
var val string
|
||||
// path params
|
||||
|
||||
val = chi.URLParam(req, "namespaceID")
|
||||
r.NamespaceID, err = payload.ParseUint64(val), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/cortezaproject/corteza-server/pkg/label"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
"github.com/cortezaproject/corteza-server/pkg/payload"
|
||||
"github.com/go-chi/chi"
|
||||
sqlxTypes "github.com/jmoiron/sqlx/types"
|
||||
@ -272,6 +273,35 @@ type (
|
||||
// Script to execute
|
||||
Script string
|
||||
}
|
||||
|
||||
PageListLocale struct {
|
||||
// NamespaceID PATH parameter
|
||||
//
|
||||
// Namespace ID
|
||||
NamespaceID uint64 `json:",string"`
|
||||
|
||||
// PageID PATH parameter
|
||||
//
|
||||
// ID
|
||||
PageID uint64 `json:",string"`
|
||||
}
|
||||
|
||||
PageUpdateLocale struct {
|
||||
// NamespaceID PATH parameter
|
||||
//
|
||||
// Namespace ID
|
||||
NamespaceID uint64 `json:",string"`
|
||||
|
||||
// PageID PATH parameter
|
||||
//
|
||||
// ID
|
||||
PageID uint64 `json:",string"`
|
||||
|
||||
// Locale POST parameter
|
||||
//
|
||||
// ...
|
||||
Locale locale.ResourceTranslationSet
|
||||
}
|
||||
)
|
||||
|
||||
// NewPageList request
|
||||
@ -1143,3 +1173,129 @@ func (r *PageTriggerScript) Fill(req *http.Request) (err error) {
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// NewPageListLocale request
|
||||
func NewPageListLocale() *PageListLocale {
|
||||
return &PageListLocale{}
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r PageListLocale) Auditable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"namespaceID": r.NamespaceID,
|
||||
"pageID": r.PageID,
|
||||
}
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r PageListLocale) GetNamespaceID() uint64 {
|
||||
return r.NamespaceID
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r PageListLocale) GetPageID() uint64 {
|
||||
return r.PageID
|
||||
}
|
||||
|
||||
// Fill processes request and fills internal variables
|
||||
func (r *PageListLocale) Fill(req *http.Request) (err error) {
|
||||
|
||||
{
|
||||
var val string
|
||||
// path params
|
||||
|
||||
val = chi.URLParam(req, "namespaceID")
|
||||
r.NamespaceID, err = payload.ParseUint64(val), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val = chi.URLParam(req, "pageID")
|
||||
r.PageID, err = payload.ParseUint64(val), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// NewPageUpdateLocale request
|
||||
func NewPageUpdateLocale() *PageUpdateLocale {
|
||||
return &PageUpdateLocale{}
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r PageUpdateLocale) Auditable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"namespaceID": r.NamespaceID,
|
||||
"pageID": r.PageID,
|
||||
"locale": r.Locale,
|
||||
}
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r PageUpdateLocale) GetNamespaceID() uint64 {
|
||||
return r.NamespaceID
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r PageUpdateLocale) GetPageID() uint64 {
|
||||
return r.PageID
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r PageUpdateLocale) GetLocale() locale.ResourceTranslationSet {
|
||||
return r.Locale
|
||||
}
|
||||
|
||||
// Fill processes request and fills internal variables
|
||||
func (r *PageUpdateLocale) Fill(req *http.Request) (err error) {
|
||||
|
||||
if strings.ToLower(req.Header.Get("content-type")) == "application/json" {
|
||||
err = json.NewDecoder(req.Body).Decode(r)
|
||||
|
||||
switch {
|
||||
case err == io.EOF:
|
||||
err = nil
|
||||
case err != nil:
|
||||
return fmt.Errorf("error parsing http request body: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if err = req.ParseForm(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// POST params
|
||||
|
||||
//if val, ok := req.Form["locale[]"]; ok && len(val) > 0 {
|
||||
// r.Locale, err = locale.ResourceTranslationSet(val), nil
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
{
|
||||
var val string
|
||||
// path params
|
||||
|
||||
val = chi.URLParam(req, "namespaceID")
|
||||
r.NamespaceID, err = payload.ParseUint64(val), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val = chi.URLParam(req, "pageID")
|
||||
r.PageID, err = payload.ParseUint64(val), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
213
compose/service/locale.gen.go
generated
Normal file
213
compose/service/locale.gen.go
generated
Normal file
@ -0,0 +1,213 @@
|
||||
package service
|
||||
|
||||
// This file is auto-generated.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
//
|
||||
|
||||
// Definitions file that controls how this file is generated:
|
||||
// - compose.module.yaml
|
||||
// - compose.namespace.yaml
|
||||
// - compose.page.yaml
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/compose/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/actionlog"
|
||||
"github.com/cortezaproject/corteza-server/pkg/auth"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
"github.com/cortezaproject/corteza-server/store"
|
||||
systemTypes "github.com/cortezaproject/corteza-server/system/types"
|
||||
)
|
||||
|
||||
type (
|
||||
resourceTranslation struct {
|
||||
actionlog actionlog.Recorder
|
||||
locale locale.Resource
|
||||
store store.Storer
|
||||
ac localeAccessController
|
||||
}
|
||||
|
||||
localeAccessController interface {
|
||||
// CanManageResourceTranslation(context.Context) bool
|
||||
}
|
||||
|
||||
ResourceTranslationService interface {
|
||||
Module(ctx context.Context, namespaceID uint64, ID uint64) (locale.ResourceTranslationSet, error)
|
||||
Namespace(ctx context.Context, ID uint64) (locale.ResourceTranslationSet, error)
|
||||
Page(ctx context.Context, namespaceID uint64, ID uint64) (locale.ResourceTranslationSet, error)
|
||||
|
||||
Upsert(context.Context, locale.ResourceTranslationSet) error
|
||||
Locale() locale.Resource
|
||||
}
|
||||
)
|
||||
|
||||
func ResourceTranslation(ls locale.Resource) *resourceTranslation {
|
||||
return &resourceTranslation{
|
||||
actionlog: DefaultActionlog,
|
||||
store: DefaultStore,
|
||||
locale: ls,
|
||||
}
|
||||
}
|
||||
|
||||
func (svc resourceTranslation) Upsert(ctx context.Context, rr locale.ResourceTranslationSet) (err error) {
|
||||
// @todo AC
|
||||
// @todo validation
|
||||
|
||||
defer locale.Global().ReloadResourceTranslations(ctx)
|
||||
me := auth.GetIdentityFromContext(ctx)
|
||||
|
||||
// - group by resource
|
||||
localeByRes := make(map[string]locale.ResourceTranslationSet)
|
||||
for _, r := range rr {
|
||||
localeByRes[r.Resource] = append(localeByRes[r.Resource], r)
|
||||
}
|
||||
|
||||
// - for each resource, fetch the current state
|
||||
sysLocale := make(systemTypes.ResourceTranslationSet, 0, len(rr))
|
||||
for res, rr := range localeByRes {
|
||||
current, _, err := store.SearchResourceTranslations(ctx, svc.store, systemTypes.ResourceTranslationFilter{
|
||||
Resource: res,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// get deltas and prepare upsert accordingly
|
||||
aux := current.New(rr)
|
||||
aux.Walk(func(cc *systemTypes.ResourceTranslation) error {
|
||||
cc.ID = nextID()
|
||||
cc.CreatedAt = *now()
|
||||
cc.CreatedBy = me.Identity()
|
||||
|
||||
return nil
|
||||
})
|
||||
sysLocale = append(sysLocale, aux...)
|
||||
|
||||
aux = current.Old(rr)
|
||||
aux.Walk(func(cc *systemTypes.ResourceTranslation) error {
|
||||
cc.UpdatedAt = now()
|
||||
cc.UpdatedBy = me.Identity()
|
||||
return nil
|
||||
})
|
||||
sysLocale = append(sysLocale, aux...)
|
||||
}
|
||||
|
||||
err = store.UpsertResourceTranslation(ctx, svc.store, sysLocale...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (svc resourceTranslation) Locale() locale.Resource {
|
||||
return svc.locale
|
||||
}
|
||||
|
||||
func (svc resourceTranslation) Module(ctx context.Context, namespaceID uint64, ID uint64) (locale.ResourceTranslationSet, error) {
|
||||
var (
|
||||
err error
|
||||
out locale.ResourceTranslationSet
|
||||
res *types.Module
|
||||
k types.LocaleKey
|
||||
)
|
||||
|
||||
res, err = svc.loadModule(ctx, svc.store, namespaceID, ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, tag := range svc.locale.Tags() {
|
||||
k = types.LocaleKeyModuleName
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: res.ResourceTranslation(),
|
||||
Lang: tag.String(),
|
||||
Key: k.Path,
|
||||
Msg: svc.locale.TRFor(tag, res.ResourceTranslation(), k.Path),
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
tmp, err := svc.moduleExtended(ctx, res)
|
||||
return append(out, tmp...), err
|
||||
}
|
||||
|
||||
func (svc resourceTranslation) Namespace(ctx context.Context, ID uint64) (locale.ResourceTranslationSet, error) {
|
||||
var (
|
||||
err error
|
||||
out locale.ResourceTranslationSet
|
||||
res *types.Namespace
|
||||
k types.LocaleKey
|
||||
)
|
||||
|
||||
res, err = svc.loadNamespace(ctx, svc.store, ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, tag := range svc.locale.Tags() {
|
||||
k = types.LocaleKeyNamespaceName
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: res.ResourceTranslation(),
|
||||
Lang: tag.String(),
|
||||
Key: k.Path,
|
||||
Msg: svc.locale.TRFor(tag, res.ResourceTranslation(), k.Path),
|
||||
})
|
||||
|
||||
k = types.LocaleKeyNamespaceSubtitle
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: res.ResourceTranslation(),
|
||||
Lang: tag.String(),
|
||||
Key: k.Path,
|
||||
Msg: svc.locale.TRFor(tag, res.ResourceTranslation(), k.Path),
|
||||
})
|
||||
|
||||
k = types.LocaleKeyNamespaceDescription
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: res.ResourceTranslation(),
|
||||
Lang: tag.String(),
|
||||
Key: k.Path,
|
||||
Msg: svc.locale.TRFor(tag, res.ResourceTranslation(), k.Path),
|
||||
})
|
||||
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (svc resourceTranslation) Page(ctx context.Context, namespaceID uint64, ID uint64) (locale.ResourceTranslationSet, error) {
|
||||
var (
|
||||
err error
|
||||
out locale.ResourceTranslationSet
|
||||
res *types.Page
|
||||
k types.LocaleKey
|
||||
)
|
||||
|
||||
res, err = svc.loadPage(ctx, svc.store, namespaceID, ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, tag := range svc.locale.Tags() {
|
||||
k = types.LocaleKeyPageTitle
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: res.ResourceTranslation(),
|
||||
Lang: tag.String(),
|
||||
Key: k.Path,
|
||||
Msg: svc.locale.TRFor(tag, res.ResourceTranslation(), k.Path),
|
||||
})
|
||||
|
||||
k = types.LocaleKeyPageDescription
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: res.ResourceTranslation(),
|
||||
Lang: tag.String(),
|
||||
Key: k.Path,
|
||||
Msg: svc.locale.TRFor(tag, res.ResourceTranslation(), k.Path),
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
tmp, err := svc.pageExtended(ctx, res)
|
||||
return append(out, tmp...), err
|
||||
}
|
||||
150
compose/service/locale.go
Normal file
150
compose/service/locale.go
Normal file
@ -0,0 +1,150 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/compose/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
"github.com/cortezaproject/corteza-server/store"
|
||||
"github.com/spf13/cast"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func (svc resourceTranslation) moduleExtended(ctx context.Context, res *types.Module) (out locale.ResourceTranslationSet, err error) {
|
||||
var (
|
||||
k types.LocaleKey
|
||||
)
|
||||
|
||||
for _, tag := range svc.locale.Tags() {
|
||||
for _, f := range res.Fields {
|
||||
k = types.LocaleKeyModuleFieldLabel
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: res.ResourceTranslation(),
|
||||
Lang: tag.String(),
|
||||
Key: k.Path,
|
||||
Msg: svc.locale.TRFor(tag, res.ResourceTranslation(), k.Path),
|
||||
})
|
||||
|
||||
// Extra field bits
|
||||
converted, err := svc.moduleFieldValidatorErrorHandler(ctx, tag, f, k.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, converted...)
|
||||
}
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (svc resourceTranslation) moduleFieldValidatorErrorHandler(ctx context.Context, tag language.Tag, f *types.ModuleField, k string) (locale.ResourceTranslationSet, error) {
|
||||
out := make(locale.ResourceTranslationSet, 0, 10)
|
||||
|
||||
for i, v := range f.Expressions.Validators {
|
||||
vContentID := locale.ContentID(v.ValidatorID, i)
|
||||
rpl := strings.NewReplacer(
|
||||
"{{validatorID}}", strconv.FormatUint(vContentID, 10),
|
||||
)
|
||||
tKey := rpl.Replace(k)
|
||||
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: f.ResourceTranslation(),
|
||||
Lang: tag.String(),
|
||||
Key: tKey,
|
||||
Msg: svc.locale.TRFor(tag, f.ResourceTranslation(), tKey),
|
||||
})
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (svc resourceTranslation) pageExtended(ctx context.Context, res *types.Page) (out locale.ResourceTranslationSet, err error) {
|
||||
var (
|
||||
k types.LocaleKey
|
||||
)
|
||||
|
||||
for _, tag := range svc.locale.Tags() {
|
||||
for i, block := range res.Blocks {
|
||||
pbContentID := locale.ContentID(block.BlockID, i)
|
||||
rpl := strings.NewReplacer(
|
||||
"{{blockID}}", strconv.FormatUint(pbContentID, 10),
|
||||
)
|
||||
|
||||
// base stuff
|
||||
k = types.LocaleKeyPageBlockTitle
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: res.ResourceTranslation(),
|
||||
Lang: tag.String(),
|
||||
Key: rpl.Replace(k.Path),
|
||||
Msg: svc.locale.TRFor(tag, res.ResourceTranslation(), rpl.Replace(k.Path)),
|
||||
})
|
||||
|
||||
k = types.LocaleKeyPageBlockDescription
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: res.ResourceTranslation(),
|
||||
Lang: tag.String(),
|
||||
Key: rpl.Replace(k.Path),
|
||||
Msg: svc.locale.TRFor(tag, res.ResourceTranslation(), rpl.Replace(k.Path)),
|
||||
})
|
||||
|
||||
switch block.Kind {
|
||||
case "Automation":
|
||||
aux, err := svc.pageExtendedAutomatinBlock(tag, res, block, pbContentID, k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out = append(out, aux...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (svc resourceTranslation) pageExtendedAutomatinBlock(tag language.Tag, res *types.Page, block types.PageBlock, blockID uint64, k types.LocaleKey) (locale.ResourceTranslationSet, error) {
|
||||
out := make(locale.ResourceTranslationSet, 0, 10)
|
||||
|
||||
bb, _ := block.Options["buttons"].([]interface{})
|
||||
for j, auxBtn := range bb {
|
||||
btn := auxBtn.(map[string]interface{})
|
||||
|
||||
bContentID := uint64(0)
|
||||
if aux, ok := btn["buttonID"]; ok {
|
||||
bContentID = cast.ToUint64(aux)
|
||||
}
|
||||
|
||||
bContentID = locale.ContentID(bContentID, j)
|
||||
|
||||
rpl := strings.NewReplacer(
|
||||
"{{blockID}}", strconv.FormatUint(blockID, 10),
|
||||
"{{buttonID}}", strconv.FormatUint(bContentID, 10),
|
||||
)
|
||||
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: res.ResourceTranslation(),
|
||||
Lang: tag.String(),
|
||||
Key: rpl.Replace(k.Path),
|
||||
Msg: svc.locale.TRFor(tag, res.ResourceTranslation(), rpl.Replace(k.Path)),
|
||||
})
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Helper loaders
|
||||
|
||||
func (svc resourceTranslation) loadModule(ctx context.Context, s store.Storer, namespaceID, moduleID uint64) (m *types.Module, err error) {
|
||||
return loadModule(ctx, s, moduleID)
|
||||
}
|
||||
|
||||
func (svc resourceTranslation) loadNamespace(ctx context.Context, s store.Storer, namespaceID uint64) (m *types.Namespace, err error) {
|
||||
return loadNamespace(ctx, s, namespaceID)
|
||||
}
|
||||
|
||||
func (svc resourceTranslation) loadPage(ctx context.Context, s store.Storer, namespaceID, pageID uint64) (m *types.Page, err error) {
|
||||
_, m, err = loadPage(ctx, s, namespaceID, pageID)
|
||||
return m, err
|
||||
}
|
||||
@ -16,6 +16,7 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/handle"
|
||||
"github.com/cortezaproject/corteza-server/pkg/label"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
"github.com/cortezaproject/corteza-server/store"
|
||||
)
|
||||
|
||||
@ -25,6 +26,7 @@ type (
|
||||
ac moduleAccessController
|
||||
eventbus eventDispatcher
|
||||
store store.Storer
|
||||
locale ResourceTranslationService
|
||||
}
|
||||
|
||||
moduleAccessController interface {
|
||||
@ -66,6 +68,7 @@ func Module() *module {
|
||||
eventbus: eventbus.Service(),
|
||||
actionlog: DefaultActionlog,
|
||||
store: DefaultStore,
|
||||
locale: DefaultResourceTranslation,
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,7 +125,23 @@ func (svc module) Find(ctx context.Context, filter types.ModuleFilter) (set type
|
||||
return err
|
||||
}
|
||||
|
||||
return loadModuleFields(ctx, svc.store, set...)
|
||||
err = loadModuleFields(ctx, svc.store, set...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// i18n
|
||||
tag := locale.GetLanguageFromContext(ctx)
|
||||
set.Walk(func(m *types.Module) error {
|
||||
m.DecodeTranslations(svc.locale.Locale().ResourceTranslations(tag, m.ResourceTranslation()))
|
||||
|
||||
m.Fields.Walk(func(mf *types.ModuleField) error {
|
||||
mf.DecodeTranslations(svc.locale.Locale().ResourceTranslations(tag, mf.ResourceTranslation()))
|
||||
return nil
|
||||
})
|
||||
return nil
|
||||
})
|
||||
return nil
|
||||
}()
|
||||
|
||||
return set, f, svc.recordAction(ctx, aProps, ModuleActionSearch, err)
|
||||
@ -328,6 +347,18 @@ func (svc module) updater(ctx context.Context, namespaceID, moduleID uint64, act
|
||||
}
|
||||
}
|
||||
|
||||
// i18n
|
||||
tt := m.EncodeTranslations()
|
||||
for _, f := range m.Fields {
|
||||
tt = append(tt, f.EncodeTranslations()...)
|
||||
}
|
||||
|
||||
tt.SetLanguage(locale.GetLanguageFromContext(ctx))
|
||||
err = svc.locale.Upsert(ctx, tt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if changes&moduleLabelsChanged > 0 {
|
||||
if err = label.Update(ctx, s, m); err != nil {
|
||||
return
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/pkg/eventbus"
|
||||
"github.com/cortezaproject/corteza-server/pkg/handle"
|
||||
"github.com/cortezaproject/corteza-server/pkg/label"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
"github.com/cortezaproject/corteza-server/store"
|
||||
)
|
||||
@ -22,6 +23,7 @@ type (
|
||||
ac namespaceAccessController
|
||||
eventbus eventDispatcher
|
||||
store store.Storer
|
||||
locale ResourceTranslationService
|
||||
}
|
||||
|
||||
namespaceAccessController interface {
|
||||
@ -61,6 +63,7 @@ func Namespace() *namespace {
|
||||
eventbus: eventbus.Service(),
|
||||
actionlog: DefaultActionlog,
|
||||
store: DefaultStore,
|
||||
locale: DefaultResourceTranslation,
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,6 +109,13 @@ func (svc namespace) Find(ctx context.Context, filter types.NamespaceFilter) (se
|
||||
return err
|
||||
}
|
||||
|
||||
// i18n
|
||||
tag := locale.GetLanguageFromContext(ctx)
|
||||
set.Walk(func(n *types.Namespace) error {
|
||||
n.DecodeTranslations(svc.locale.Locale().ResourceTranslations(tag, n.ResourceTranslation()))
|
||||
return nil
|
||||
})
|
||||
|
||||
if err = label.Load(ctx, svc.store, toLabeledNamespaces(set)...); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -265,6 +275,14 @@ func (svc namespace) updater(ctx context.Context, namespaceID uint64, action fun
|
||||
}
|
||||
}
|
||||
|
||||
// i18n
|
||||
tt := ns.EncodeTranslations()
|
||||
tt.SetLanguage(locale.GetLanguageFromContext(ctx))
|
||||
err = DefaultResourceTranslation.Upsert(ctx, tt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if changes&namespaceLabelsChanged > 0 {
|
||||
if err = label.Update(ctx, s, ns); err != nil {
|
||||
return
|
||||
|
||||
@ -11,6 +11,7 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/pkg/eventbus"
|
||||
"github.com/cortezaproject/corteza-server/pkg/handle"
|
||||
"github.com/cortezaproject/corteza-server/pkg/label"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
"github.com/cortezaproject/corteza-server/store"
|
||||
)
|
||||
|
||||
@ -20,6 +21,7 @@ type (
|
||||
ac pageAccessController
|
||||
eventbus eventDispatcher
|
||||
store store.Storer
|
||||
locale ResourceTranslationService
|
||||
}
|
||||
|
||||
pageAccessController interface {
|
||||
@ -47,6 +49,7 @@ func Page() *page {
|
||||
ac: DefaultAccessControl,
|
||||
eventbus: eventbus.Service(),
|
||||
store: DefaultStore,
|
||||
locale: DefaultResourceTranslation,
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,6 +143,13 @@ func (svc page) search(ctx context.Context, filter types.PageFilter) (set types.
|
||||
return err
|
||||
}
|
||||
|
||||
// i18n
|
||||
tag := locale.GetLanguageFromContext(ctx)
|
||||
set.Walk(func(p *types.Page) error {
|
||||
p.DecodeTranslations(svc.locale.Locale().ResourceTranslations(tag, p.ResourceTranslation()))
|
||||
return nil
|
||||
})
|
||||
|
||||
return nil
|
||||
}()
|
||||
|
||||
@ -350,6 +360,14 @@ func (svc page) updater(ctx context.Context, namespaceID, pageID uint64, action
|
||||
}
|
||||
}
|
||||
|
||||
// i18n
|
||||
tt := p.EncodeTranslations()
|
||||
tt.SetLanguage(locale.GetLanguageFromContext(ctx))
|
||||
err = svc.locale.Upsert(ctx, tt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if changes&pageLabelsChanged > 0 {
|
||||
if err = label.Update(ctx, s, p); err != nil {
|
||||
return
|
||||
@ -385,6 +403,8 @@ func (svc page) lookup(ctx context.Context, namespaceID uint64, lookup func(*pag
|
||||
return err
|
||||
}
|
||||
|
||||
p.DecodeTranslations(svc.locale.Locale().ResourceTranslations(locale.GetLanguageFromContext(ctx), p.ResourceTranslation()))
|
||||
|
||||
aProps.setPage(p)
|
||||
|
||||
if !svc.ac.CanReadPage(ctx, p) {
|
||||
|
||||
@ -15,6 +15,7 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/healthcheck"
|
||||
"github.com/cortezaproject/corteza-server/pkg/id"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
"github.com/cortezaproject/corteza-server/pkg/logger"
|
||||
"github.com/cortezaproject/corteza-server/pkg/objstore"
|
||||
"github.com/cortezaproject/corteza-server/pkg/objstore/minio"
|
||||
@ -52,14 +53,15 @@ var (
|
||||
// DefaultAccessControl Access control checking
|
||||
DefaultAccessControl *accessControl
|
||||
|
||||
DefaultNamespace NamespaceService
|
||||
DefaultImportSession ImportSessionService
|
||||
DefaultRecord RecordService
|
||||
DefaultModule ModuleService
|
||||
DefaultChart *chart
|
||||
DefaultPage *page
|
||||
DefaultAttachment AttachmentService
|
||||
DefaultNotification *notification
|
||||
DefaultNamespace NamespaceService
|
||||
DefaultImportSession ImportSessionService
|
||||
DefaultRecord RecordService
|
||||
DefaultModule ModuleService
|
||||
DefaultChart *chart
|
||||
DefaultPage *page
|
||||
DefaultAttachment AttachmentService
|
||||
DefaultNotification *notification
|
||||
DefaultResourceTranslation ResourceTranslationService
|
||||
|
||||
// wrapper around time.Now() that will aid service testing
|
||||
now = func() *time.Time {
|
||||
@ -97,6 +99,7 @@ func Initialize(ctx context.Context, log *zap.Logger, s store.Storer, c Config)
|
||||
DefaultActionlog = actionlog.NewService(DefaultStore, log, tee, policy)
|
||||
}
|
||||
|
||||
DefaultResourceTranslation = ResourceTranslation(locale.Global())
|
||||
DefaultAccessControl = AccessControl()
|
||||
|
||||
if DefaultObjectStore == nil {
|
||||
|
||||
310
compose/types/locale.gen.go
generated
Normal file
310
compose/types/locale.gen.go
generated
Normal file
@ -0,0 +1,310 @@
|
||||
package types
|
||||
|
||||
// This file is auto-generated.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
//
|
||||
|
||||
// Definitions file that controls how this file is generated:
|
||||
// - compose.module-field.yaml
|
||||
// - compose.module.yaml
|
||||
// - compose.namespace.yaml
|
||||
// - compose.page.yaml
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type (
|
||||
LocaleKey struct {
|
||||
Name string
|
||||
Resource string
|
||||
Path string
|
||||
CustomHandler string
|
||||
}
|
||||
)
|
||||
|
||||
// Types and stuff
|
||||
const (
|
||||
ModuleFieldResourceTranslationType = "compose:module-field"
|
||||
ModuleResourceTranslationType = "compose:module"
|
||||
NamespaceResourceTranslationType = "compose:namespace"
|
||||
PageResourceTranslationType = "compose:page"
|
||||
)
|
||||
|
||||
var (
|
||||
LocaleKeyModuleFieldLabel = LocaleKey{
|
||||
Name: "label",
|
||||
Resource: ModuleFieldResourceTranslationType,
|
||||
Path: "label",
|
||||
}
|
||||
LocaleKeyModuleFieldValidatorError = LocaleKey{
|
||||
Name: "validatorError",
|
||||
Resource: ModuleFieldResourceTranslationType,
|
||||
Path: "expression.validator.{{validatorID}}.error",
|
||||
CustomHandler: "validatorError",
|
||||
}
|
||||
LocaleKeyModuleName = LocaleKey{
|
||||
Name: "name",
|
||||
Resource: ModuleResourceTranslationType,
|
||||
Path: "name",
|
||||
}
|
||||
LocaleKeyNamespaceName = LocaleKey{
|
||||
Name: "name",
|
||||
Resource: NamespaceResourceTranslationType,
|
||||
Path: "name",
|
||||
}
|
||||
LocaleKeyNamespaceSubtitle = LocaleKey{
|
||||
Name: "subtitle",
|
||||
Resource: NamespaceResourceTranslationType,
|
||||
Path: "subtitle",
|
||||
}
|
||||
LocaleKeyNamespaceDescription = LocaleKey{
|
||||
Name: "description",
|
||||
Resource: NamespaceResourceTranslationType,
|
||||
Path: "description",
|
||||
}
|
||||
LocaleKeyPageTitle = LocaleKey{
|
||||
Name: "title",
|
||||
Resource: PageResourceTranslationType,
|
||||
Path: "title",
|
||||
}
|
||||
LocaleKeyPageDescription = LocaleKey{
|
||||
Name: "description",
|
||||
Resource: PageResourceTranslationType,
|
||||
Path: "description",
|
||||
}
|
||||
LocaleKeyPageBlockTitle = LocaleKey{
|
||||
Name: "blockTitle",
|
||||
Resource: PageResourceTranslationType,
|
||||
Path: "pageBlock.{{blockID}}.title",
|
||||
}
|
||||
LocaleKeyPageBlockDescription = LocaleKey{
|
||||
Name: "blockDescription",
|
||||
Resource: PageResourceTranslationType,
|
||||
Path: "pageBlock.{{blockID}}.description",
|
||||
}
|
||||
LocaleKeyPageBlockAutomationButtonlabel = LocaleKey{
|
||||
Name: "blockAutomationButtonlabel",
|
||||
Resource: PageResourceTranslationType,
|
||||
Path: "pageBlock.{{blockID}}.automation.{{buttonID}}.label",
|
||||
}
|
||||
)
|
||||
|
||||
// ResourceTranslation returns string representation of Locale resource for ModuleField by calling ModuleFieldResourceTranslation fn
|
||||
//
|
||||
// Locale resource is in the compose:module-field/... format
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (r ModuleField) ResourceTranslation() string {
|
||||
return ModuleFieldResourceTranslation(r.NamespaceID, r.ModuleID, r.ID)
|
||||
}
|
||||
|
||||
// ModuleFieldResourceTranslation returns string representation of Locale resource for ModuleField
|
||||
//
|
||||
// Locale resource is in the compose:module-field/... format
|
||||
//
|
||||
// This function is auto-generated
|
||||
func ModuleFieldResourceTranslation(namespaceID uint64, moduleID uint64, id uint64) string {
|
||||
cpts := []interface{}{ModuleFieldResourceTranslationType}
|
||||
cpts = append(cpts, strconv.FormatUint(namespaceID, 10), strconv.FormatUint(moduleID, 10), strconv.FormatUint(id, 10))
|
||||
|
||||
return fmt.Sprintf(ModuleFieldResourceTranslationTpl(), cpts...)
|
||||
}
|
||||
|
||||
// @todo template
|
||||
func ModuleFieldResourceTranslationTpl() string {
|
||||
return "%s/%s/%s/%s"
|
||||
}
|
||||
|
||||
func (r *ModuleField) DecodeTranslations(tt locale.ResourceTranslationIndex) {
|
||||
var aux *locale.ResourceTranslation
|
||||
if aux = tt.FindByKey(LocaleKeyModuleFieldLabel.Path); aux != nil {
|
||||
r.Label = aux.Msg
|
||||
}
|
||||
r.decodeTranslationsValidatorError(tt)
|
||||
}
|
||||
|
||||
func (r *ModuleField) EncodeTranslations() (out locale.ResourceTranslationSet) {
|
||||
out = locale.ResourceTranslationSet{
|
||||
{
|
||||
Resource: r.ResourceTranslation(),
|
||||
Key: LocaleKeyModuleFieldLabel.Path,
|
||||
Msg: r.Label,
|
||||
},
|
||||
}
|
||||
|
||||
out = append(out, r.encodeTranslationsValidatorError()...)
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// ResourceTranslation returns string representation of Locale resource for Module by calling ModuleResourceTranslation fn
|
||||
//
|
||||
// Locale resource is in the compose:module/... format
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (r Module) ResourceTranslation() string {
|
||||
return ModuleResourceTranslation(r.NamespaceID, r.ID)
|
||||
}
|
||||
|
||||
// ModuleResourceTranslation returns string representation of Locale resource for Module
|
||||
//
|
||||
// Locale resource is in the compose:module/... format
|
||||
//
|
||||
// This function is auto-generated
|
||||
func ModuleResourceTranslation(namespaceID uint64, id uint64) string {
|
||||
cpts := []interface{}{ModuleResourceTranslationType}
|
||||
cpts = append(cpts, strconv.FormatUint(namespaceID, 10), strconv.FormatUint(id, 10))
|
||||
|
||||
return fmt.Sprintf(ModuleResourceTranslationTpl(), cpts...)
|
||||
}
|
||||
|
||||
// @todo template
|
||||
func ModuleResourceTranslationTpl() string {
|
||||
return "%s/%s/%s"
|
||||
}
|
||||
|
||||
func (r *Module) DecodeTranslations(tt locale.ResourceTranslationIndex) {
|
||||
var aux *locale.ResourceTranslation
|
||||
if aux = tt.FindByKey(LocaleKeyModuleName.Path); aux != nil {
|
||||
r.Name = aux.Msg
|
||||
}
|
||||
|
||||
r.decodeTranslations(tt)
|
||||
}
|
||||
|
||||
func (r *Module) EncodeTranslations() (out locale.ResourceTranslationSet) {
|
||||
out = locale.ResourceTranslationSet{
|
||||
{
|
||||
Resource: r.ResourceTranslation(),
|
||||
Key: LocaleKeyModuleName.Path,
|
||||
Msg: r.Name,
|
||||
},
|
||||
}
|
||||
|
||||
out = append(out, r.encodeTranslations()...)
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// ResourceTranslation returns string representation of Locale resource for Namespace by calling NamespaceResourceTranslation fn
|
||||
//
|
||||
// Locale resource is in the compose:namespace/... format
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (r Namespace) ResourceTranslation() string {
|
||||
return NamespaceResourceTranslation(r.ID)
|
||||
}
|
||||
|
||||
// NamespaceResourceTranslation returns string representation of Locale resource for Namespace
|
||||
//
|
||||
// Locale resource is in the compose:namespace/... format
|
||||
//
|
||||
// This function is auto-generated
|
||||
func NamespaceResourceTranslation(id uint64) string {
|
||||
cpts := []interface{}{NamespaceResourceTranslationType}
|
||||
cpts = append(cpts, strconv.FormatUint(id, 10))
|
||||
|
||||
return fmt.Sprintf(NamespaceResourceTranslationTpl(), cpts...)
|
||||
}
|
||||
|
||||
// @todo template
|
||||
func NamespaceResourceTranslationTpl() string {
|
||||
return "%s/%s"
|
||||
}
|
||||
|
||||
func (r *Namespace) DecodeTranslations(tt locale.ResourceTranslationIndex) {
|
||||
var aux *locale.ResourceTranslation
|
||||
if aux = tt.FindByKey(LocaleKeyNamespaceName.Path); aux != nil {
|
||||
r.Name = aux.Msg
|
||||
}
|
||||
if aux = tt.FindByKey(LocaleKeyNamespaceSubtitle.Path); aux != nil {
|
||||
r.Meta.Subtitle = aux.Msg
|
||||
}
|
||||
if aux = tt.FindByKey(LocaleKeyNamespaceDescription.Path); aux != nil {
|
||||
r.Meta.Description = aux.Msg
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Namespace) EncodeTranslations() (out locale.ResourceTranslationSet) {
|
||||
out = locale.ResourceTranslationSet{
|
||||
{
|
||||
Resource: r.ResourceTranslation(),
|
||||
Key: LocaleKeyNamespaceName.Path,
|
||||
Msg: r.Name,
|
||||
},
|
||||
{
|
||||
Resource: r.ResourceTranslation(),
|
||||
Key: LocaleKeyNamespaceSubtitle.Path,
|
||||
Msg: r.Meta.Subtitle,
|
||||
},
|
||||
{
|
||||
Resource: r.ResourceTranslation(),
|
||||
Key: LocaleKeyNamespaceDescription.Path,
|
||||
Msg: r.Meta.Description,
|
||||
},
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// ResourceTranslation returns string representation of Locale resource for Page by calling PageResourceTranslation fn
|
||||
//
|
||||
// Locale resource is in the compose:page/... format
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (r Page) ResourceTranslation() string {
|
||||
return PageResourceTranslation(r.NamespaceID, r.ID)
|
||||
}
|
||||
|
||||
// PageResourceTranslation returns string representation of Locale resource for Page
|
||||
//
|
||||
// Locale resource is in the compose:page/... format
|
||||
//
|
||||
// This function is auto-generated
|
||||
func PageResourceTranslation(namespaceID uint64, id uint64) string {
|
||||
cpts := []interface{}{PageResourceTranslationType}
|
||||
cpts = append(cpts, strconv.FormatUint(namespaceID, 10), strconv.FormatUint(id, 10))
|
||||
|
||||
return fmt.Sprintf(PageResourceTranslationTpl(), cpts...)
|
||||
}
|
||||
|
||||
// @todo template
|
||||
func PageResourceTranslationTpl() string {
|
||||
return "%s/%s/%s"
|
||||
}
|
||||
|
||||
func (r *Page) DecodeTranslations(tt locale.ResourceTranslationIndex) {
|
||||
var aux *locale.ResourceTranslation
|
||||
if aux = tt.FindByKey(LocaleKeyPageTitle.Path); aux != nil {
|
||||
r.Title = aux.Msg
|
||||
}
|
||||
if aux = tt.FindByKey(LocaleKeyPageDescription.Path); aux != nil {
|
||||
r.Description = aux.Msg
|
||||
}
|
||||
|
||||
r.decodeTranslations(tt)
|
||||
}
|
||||
|
||||
func (r *Page) EncodeTranslations() (out locale.ResourceTranslationSet) {
|
||||
out = locale.ResourceTranslationSet{
|
||||
{
|
||||
Resource: r.ResourceTranslation(),
|
||||
Key: LocaleKeyPageTitle.Path,
|
||||
Msg: r.Title,
|
||||
},
|
||||
{
|
||||
Resource: r.ResourceTranslation(),
|
||||
Key: LocaleKeyPageDescription.Path,
|
||||
Msg: r.Description,
|
||||
},
|
||||
}
|
||||
|
||||
out = append(out, r.encodeTranslations()...)
|
||||
|
||||
return out
|
||||
}
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
"github.com/jmoiron/sqlx/types"
|
||||
)
|
||||
|
||||
@ -54,6 +55,16 @@ func (m Module) Clone() *Module {
|
||||
return c
|
||||
}
|
||||
|
||||
// We won't worry about fields at this point
|
||||
func (m *Module) decodeTranslations(tt locale.ResourceTranslationIndex) {
|
||||
return
|
||||
}
|
||||
|
||||
// We won't worry about fields at this point
|
||||
func (m *Module) encodeTranslations() (out locale.ResourceTranslationSet) {
|
||||
return
|
||||
}
|
||||
|
||||
// FindByHandle finds module by it's handle
|
||||
func (set ModuleSet) FindByHandle(handle string) *Module {
|
||||
for i := range set {
|
||||
|
||||
@ -3,9 +3,13 @@ package types
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
)
|
||||
|
||||
type (
|
||||
@ -47,6 +51,41 @@ var (
|
||||
_ sort.Interface = &ModuleFieldSet{}
|
||||
)
|
||||
|
||||
func (f *ModuleField) decodeTranslationsValidatorError(tt locale.ResourceTranslationIndex) {
|
||||
var aux *locale.ResourceTranslation
|
||||
|
||||
for i, e := range f.Expressions.Validators {
|
||||
validatorID := locale.ContentID(e.ValidatorID, i)
|
||||
rpl := strings.NewReplacer(
|
||||
"{{validatorID}}", strconv.FormatUint(validatorID, 10),
|
||||
)
|
||||
|
||||
if aux = tt.FindByKey(rpl.Replace(LocaleKeyModuleFieldValidatorError.Path)); aux != nil {
|
||||
f.Expressions.Validators[i].Error = aux.Msg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *ModuleField) encodeTranslationsValidatorError() (out locale.ResourceTranslationSet) {
|
||||
out = make(locale.ResourceTranslationSet, 0, 3)
|
||||
|
||||
// Module field expressions
|
||||
for i, e := range m.Expressions.Validators {
|
||||
validatorID := locale.ContentID(e.ValidatorID, i)
|
||||
rpl := strings.NewReplacer(
|
||||
"{{validatorID}}", strconv.FormatUint(validatorID, 10),
|
||||
)
|
||||
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: m.ResourceTranslation(),
|
||||
Key: rpl.Replace(LocaleKeyModuleFieldValidatorError.Path),
|
||||
Msg: e.Error,
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (m ModuleField) Clone() *ModuleField {
|
||||
return &m
|
||||
}
|
||||
|
||||
@ -20,8 +20,9 @@ type (
|
||||
}
|
||||
|
||||
ModuleFieldValidator struct {
|
||||
Test string `json:"test,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
ValidatorID uint64 `json:"validatorID,string,omitempty"`
|
||||
Test string `json:"test,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@ -3,9 +3,13 @@ package types
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@ -41,6 +45,7 @@ type (
|
||||
PageBlocks []PageBlock
|
||||
|
||||
PageBlock struct {
|
||||
BlockID uint64 `json:"blockID,string,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Options map[string]interface{} `json:"options,omitempty"`
|
||||
@ -84,6 +89,104 @@ func (m Page) Clone() *Page {
|
||||
return c
|
||||
}
|
||||
|
||||
func (p *Page) decodeTranslations(tt locale.ResourceTranslationIndex) {
|
||||
var aux *locale.ResourceTranslation
|
||||
|
||||
for i, block := range p.Blocks {
|
||||
blockID := locale.ContentID(block.BlockID, i)
|
||||
rpl := strings.NewReplacer(
|
||||
"{{blockID}}", strconv.FormatUint(blockID, 10),
|
||||
)
|
||||
|
||||
// - generic page block stuff
|
||||
if aux = tt.FindByKey(rpl.Replace(LocaleKeyPageBlockTitle.Path)); aux != nil {
|
||||
p.Blocks[i].Title = aux.Msg
|
||||
}
|
||||
if aux = tt.FindByKey(rpl.Replace(LocaleKeyPageBlockDescription.Path)); aux != nil {
|
||||
p.Blocks[i].Description = aux.Msg
|
||||
}
|
||||
|
||||
// - automation page block stuff
|
||||
if block.Kind == "Automation" {
|
||||
bb, _ := block.Options["buttons"].([]interface{})
|
||||
for j, auxBtn := range bb {
|
||||
btn := auxBtn.(map[string]interface{})
|
||||
|
||||
buttonID := uint64(0)
|
||||
if aux, ok := btn["buttonID"]; ok {
|
||||
buttonID = cast.ToUint64(aux)
|
||||
}
|
||||
buttonID = locale.ContentID(buttonID, j)
|
||||
|
||||
rpl := strings.NewReplacer(
|
||||
"{{blockID}}", strconv.FormatUint(blockID, 10),
|
||||
"{{buttonID}}", strconv.FormatUint(buttonID, 10),
|
||||
)
|
||||
|
||||
if aux = tt.FindByKey(rpl.Replace(LocaleKeyPageBlockAutomationButtonlabel.Path)); aux != nil {
|
||||
btn["label"] = aux.Msg
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Page) encodeTranslations() (out locale.ResourceTranslationSet) {
|
||||
out = make(locale.ResourceTranslationSet, 0, 3)
|
||||
|
||||
// Page blocks
|
||||
for i, block := range p.Blocks {
|
||||
blockID := locale.ContentID(block.BlockID, i)
|
||||
rpl := strings.NewReplacer(
|
||||
"{{blockID}}", strconv.FormatUint(uint64(blockID), 10),
|
||||
)
|
||||
|
||||
// - generic page block stuff
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: p.ResourceTranslation(),
|
||||
Key: rpl.Replace(LocaleKeyPageBlockTitle.Path),
|
||||
Msg: block.Title,
|
||||
})
|
||||
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: p.ResourceTranslation(),
|
||||
Key: rpl.Replace(LocaleKeyPageBlockDescription.Path),
|
||||
Msg: block.Description,
|
||||
})
|
||||
|
||||
// - automation page block stuff
|
||||
if block.Kind == "Automation" {
|
||||
bb, _ := block.Options["buttons"].([]interface{})
|
||||
for j, auxBtn := range bb {
|
||||
btn := auxBtn.(map[string]interface{})
|
||||
|
||||
if _, ok := btn["label"]; !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
buttonID := uint64(0)
|
||||
if aux, ok := btn["buttonID"]; ok {
|
||||
buttonID = cast.ToUint64(aux)
|
||||
}
|
||||
buttonID = locale.ContentID(buttonID, j)
|
||||
|
||||
rpl := strings.NewReplacer(
|
||||
"{{blockID}}", strconv.FormatUint(blockID, 10),
|
||||
"{{buttonID}}", strconv.FormatUint(buttonID, 10),
|
||||
)
|
||||
|
||||
out = append(out, &locale.ResourceTranslation{
|
||||
Resource: p.ResourceTranslation(),
|
||||
Key: rpl.Replace(LocaleKeyPageBlockAutomationButtonlabel.Path),
|
||||
Msg: btn["label"].(string),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FindByHandle finds page by it's handle
|
||||
func (set PageSet) FindByHandle(handle string) *Page {
|
||||
for i := range set {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user