package cabana import ( "context" "sort" "git.golem15.com/golem15/summercms/modules/bouncer" "git.golem15.com/golem15/summercms/modules/pact" "git.golem15.com/golem15/summercms/modules/phrasebook" ) // NavigationEntry is one permission-filtered backend navigation item. type NavigationEntry struct { Code string `json:"code"` Label string `json:"label"` Icon string `json:"icon"` Order int `json:"order"` Controller string `json:"controller"` SideMenu []NavigationEntry `json:"sideMenu"` } // SettingsEntry is one permission-filtered settings-list item. type SettingsEntry struct { Code string `json:"code"` Label string `json:"label"` Description string `json:"description"` Category string `json:"category"` Icon string `json:"icon"` Order int `json:"order"` Keywords []string `json:"keywords"` Model string `json:"model"` } // Metadata returns only entries the backend principal may open. Denied // entries are removed before any response value is constructed. func (r *Registry) Metadata(ctx context.Context, principal *bouncer.Principal, tr *phrasebook.Translator) ([]NavigationEntry, []SettingsEntry) { navigation := make([]NavigationEntry, 0) settings := make([]SettingsEntry, 0) if r == nil || principal == nil || !principal.Backend { return navigation, settings } for _, item := range r.navigation { children := make([]NavigationEntry, 0) for _, child := range item.SideMenu { if !Allows(principal, child.Permissions) { continue } children = append(children, navigationView(ctx, tr, child, nil)) } if !Allows(principal, item.Permissions) && len(children) == 0 { continue } navigation = append(navigation, navigationView(ctx, tr, item, children)) } sort.SliceStable(navigation, func(i, j int) bool { if navigation[i].Order == navigation[j].Order { return navigation[i].Code < navigation[j].Code } return navigation[i].Order < navigation[j].Order }) for _, compiled := range r.settings { item := compiled.Item if !Allows(principal, item.Permissions) { continue } keywords := append([]string(nil), item.Keywords...) if keywords == nil { keywords = []string{} } settings = append(settings, SettingsEntry{ Code: item.Code, Label: translateKey(ctx, tr, item.Label), Description: translateKey(ctx, tr, item.Description), Category: translateKey(ctx, tr, item.Category), Icon: item.Icon, Order: item.Order, Keywords: keywords, Model: item.Model, }) } sort.SliceStable(settings, func(i, j int) bool { if settings[i].Order == settings[j].Order { return settings[i].Code < settings[j].Code } return settings[i].Order < settings[j].Order }) return navigation, settings } func navigationView(ctx context.Context, tr *phrasebook.Translator, item pact.NavigationItem, children []NavigationEntry) NavigationEntry { if children == nil { children = []NavigationEntry{} } return NavigationEntry{ Code: item.Code, Label: translateKey(ctx, tr, item.Label), Icon: item.Icon, Order: item.Order, Controller: item.Controller, SideMenu: children, } }