parcoursmob/renderer/renderer.go

253 lines
6.2 KiB
Go

package renderer
import (
"fmt"
"html/template"
"net/http"
"git.coopgo.io/coopgo-apps/parcoursmob/utils/icons"
"git.coopgo.io/coopgo-apps/parcoursmob/utils/identification"
"git.coopgo.io/coopgo-platform/emailing"
"git.coopgo.io/coopgo-platform/groups-management/storage"
"github.com/coreos/go-oidc"
"github.com/spf13/viper"
)
type Renderer struct {
TemplatesDir string
GlobalConfig *viper.Viper
ThemeConfig *viper.Viper
Mailer *emailing.Mailer
}
func NewRenderer(global *viper.Viper, templates_dir string) *Renderer {
theme := viper.New()
theme.SetConfigName("config")
theme.AddConfigPath(templates_dir)
err := theme.ReadInConfig()
if err != nil {
panic(fmt.Errorf("fatal error config file: %w", err))
}
return &Renderer{
TemplatesDir: templates_dir,
GlobalConfig: global,
ThemeConfig: theme,
}
}
func (renderer *Renderer) Render(name string, w http.ResponseWriter, r *http.Request, files []string, state RenderState) {
genericFiles := renderer.ThemeConfig.GetStringSlice("views.generic.files")
prefixed_files := []string{}
for _, f := range genericFiles {
prefixed_files = append(prefixed_files, renderer.templateFile(f))
}
for _, f := range files {
prefixed_files = append(prefixed_files, renderer.templateFile(f))
}
w.WriteHeader(http.StatusOK)
t := template.New(name).Funcs(
template.FuncMap{
"timeFrom": TimeFrom,
"timeFormat": TimeFormat,
"genderISO5218": GenderISO5218,
"dict": Dict,
"json": JSON,
"walkingLength": WalkingLength,
"divideFloat64": Divide[float64],
"divideInt": Divide[int],
},
)
t = template.Must(t.ParseFiles(prefixed_files...))
err := t.ExecuteTemplate(w, "main", state)
if err != nil {
fmt.Println(err)
}
}
func (renderer *Renderer) RenderNoLayout(name string, w http.ResponseWriter, r *http.Request, files []string, state RenderState) {
prefixed_files := []string{}
for _, f := range files {
prefixed_files = append(prefixed_files, renderer.templateFile(f))
}
w.WriteHeader(http.StatusOK)
t := template.New(name).Funcs(
template.FuncMap{
"timeFrom": TimeFrom,
"timeFormat": TimeFormat,
"genderISO5218": GenderISO5218,
"dict": Dict,
"json": JSON,
"divideFloat64": Divide[float64],
"divideInt": Divide[int],
},
)
t = template.Must(t.ParseFiles(prefixed_files...))
err := t.ExecuteTemplate(w, "main", state)
if err != nil {
fmt.Println(err)
}
}
func (r *Renderer) templateFile(file string) string {
return r.TemplatesDir + file
}
type RenderState struct {
icons.IconSet
LayoutState
UserID string
UserClaims map[string]any
Group storage.Group
Roles any
ViewState any // This is a state specific to a given view
}
func NewState(r *http.Request, themeConfig *viper.Viper, menuState string) RenderState {
iconset := themeConfig.GetStringMapString("icons.svg")
// Get State elements from Request
var userid string
var claims map[string]any
u := r.Context().Value(identification.IdtokenKey)
if u != nil {
if current_user_token, ok := u.(*oidc.IDToken); ok {
userid = current_user_token.Subject
}
c := r.Context().Value(identification.ClaimsKey)
if c != nil {
if current_user_claims, ok := c.(map[string]any); ok {
claims = current_user_claims
}
}
}
g := r.Context().Value(identification.GroupKey)
if g == nil {
return RenderState{
IconSet: icons.NewIconSet(iconset),
LayoutState: LayoutState{},
}
}
var roles map[string]any
ro, ok := r.Context().Value(identification.RolesKey).(map[string]any)
if ok {
roles = ro
}
group := g.(storage.Group)
modules := group.Data["modules"].(map[string]any)
ls := LayoutState{
AdministrationState: AdministrationState{
Display: modules["administration"] != nil && modules["administration"].(bool),
Active: menuState == administrationMenu,
},
//TODO from configuration for icons at least
MenuItems: []MenuItem{
{
Title: "Tableau de bord",
Link: "/app/",
Active: menuState == dashboardMenu,
Icon: "hero:outline/home",
},
},
}
if modules["beneficiaries"] != nil && modules["beneficiaries"].(bool) {
ls.MenuItems = append(ls.MenuItems, MenuItem{
Title: "Bénéficiaires",
Link: "/app/beneficiaries/",
Active: menuState == beneficiariesMenu,
Icon: "hero:outline/user-group",
})
}
if modules["journeys"] != nil && modules["journeys"].(bool) {
ls.MenuItems = append(ls.MenuItems, MenuItem{
Title: "Déplacements",
Link: "/app/journeys/",
Active: menuState == journeysMenu,
Icon: "hero:outline/map",
})
}
if modules["vehicles"] != nil && modules["vehicles"].(bool) {
ls.MenuItems = append(ls.MenuItems, MenuItem{
Title: "Véhicules partagés",
Link: "/app/vehicles/",
Active: menuState == vehiclesMenu,
Icon: "tabler-icons:car",
})
}
if modules["vehicles_management"] != nil && modules["vehicles_management"].(bool) {
ls.MenuItems = append(ls.MenuItems, MenuItem{
Title: "Gestion des véhicules",
Link: "/app/vehicles-management/",
Active: menuState == vehiclesmanagementMenu,
Icon: "hero:outline/briefcase",
})
}
if modules["agenda"] != nil && modules["agenda"].(bool) {
ls.MenuItems = append(ls.MenuItems, MenuItem{
Title: "Agenda dispositifs",
Link: "/app/agenda/",
Active: menuState == agendaMenu,
Icon: "hero:outline/calendar",
})
}
if modules["support"] != nil && modules["support"].(bool) {
ls.MenuItems = append(ls.MenuItems, MenuItem{
Title: "Support",
Link: "/app/support/",
Active: menuState == commentMenu,
Icon: "hero:outline/support",
})
}
if modules["group_module"] != nil && modules["group_module"].(bool) {
ls.MenuItems = append(ls.MenuItems, MenuItem{
Title: "Groupes / Communautés",
Link: "/app/group_module/",
Active: menuState == groupMenu,
Icon: "hero:outline/group_module",
})
}
if modules["directory"] != nil && modules["directory"].(bool) {
ls.MenuItems = append(ls.MenuItems, MenuItem{
Title: "Répertoire solutions",
Link: "/app/directory/",
Active: menuState == directoryMenu,
Icon: "hero:outline/document-text",
})
}
return RenderState{
IconSet: icons.NewIconSet(iconset),
Group: group,
Roles: roles,
UserID: userid,
UserClaims: claims,
LayoutState: ls,
}
}