From 664bd2573be246b88cfac44a83d9a0542feeee35 Mon Sep 17 00:00:00 2001 From: Lars Karlslund Date: Thu, 12 Dec 2024 10:15:49 +0100 Subject: [PATCH] Redesigned UI preference backend storage --- modules/frontend/html/preferences.js | 17 +++----- modules/frontend/preferences.go | 64 ++++++++++++++++++++++++++++ modules/frontend/webservicefuncs.go | 35 --------------- modules/persistence/database.go | 19 +++++---- modules/settings/settings.go | 63 --------------------------- 5 files changed, 79 insertions(+), 119 deletions(-) create mode 100644 modules/frontend/preferences.go delete mode 100644 modules/settings/settings.go diff --git a/modules/frontend/html/preferences.js b/modules/frontend/html/preferences.js index 8fe16f0..b42f4a4 100644 --- a/modules/frontend/html/preferences.js +++ b/modules/frontend/html/preferences.js @@ -1,7 +1,7 @@ let prefs = {}; function loadprefs() { - $.ajax({ + return $.ajax({ url: "/api/preferences", dataType: "json", success: function (data) { @@ -34,16 +34,6 @@ function onchangepreference(ele) { } else { setpref(ele.attr("preference"), ele.val()) } - saveprefs() -} - -function saveprefs() { - $.ajax({ - method: "POST", - url: "/api/preferences", - dataType: "json", - data: JSON.stringify(prefs), - }); } function getpref(key, defvalue) { @@ -59,7 +49,10 @@ function getpref(key, defvalue) { function setpref(key, value) { prefs[key] = value; - saveprefs(); + $.ajax({ + method: "GET", + url: `/api/preferences/${key}/${value}`, + }); } $(function () { diff --git a/modules/frontend/preferences.go b/modules/frontend/preferences.go new file mode 100644 index 0000000..517c281 --- /dev/null +++ b/modules/frontend/preferences.go @@ -0,0 +1,64 @@ +package frontend + +import ( + "encoding/json" + "maps" + + "github.com/gin-gonic/gin" + "github.com/lkarlslund/adalanche/modules/persistence" +) + +type Preference struct { + Name string `json:"name"` + Value any `json:"value"` +} + +func (p Preference) ID() string { + return p.Name +} + +func AddPreferencesEndpoints(ws *WebService) { + // Saved preferences + sb := persistence.GetStorage[Preference]("preferences", false) + + preferences := ws.API.Group("preferences") + + preferences.GET("", func(c *gin.Context) { + prefs, err := sb.List() + if err != nil { + return + } + prefsmap := maps.Collect[string, any](func(yield func(string, any) bool) { + for _, pref := range prefs { + if !yield(pref.Name, pref.Value) { + break + } + } + }) + c.JSON(200, prefsmap) + }) + preferences.POST("", func(c *gin.Context) { + var prefsmap = make(map[string]any) + err := c.BindJSON(&prefsmap) + if err != nil { + c.String(500, err.Error()) + } + for key, value := range prefsmap { + sb.Put(Preference{Name: key, Value: value}) + } + }) + preferences.GET(":key", func(c *gin.Context) { + key := c.Param("key") + pref, found := sb.Get(key) + if !found { + return + } + out, _ := json.Marshal(pref.Value) + c.Writer.Write(out) + }) + preferences.GET(":key/:value", func(c *gin.Context) { + key := c.Param("key") + value := c.Param("value") + sb.Put(Preference{Name: key, Value: value}) + }) +} diff --git a/modules/frontend/webservicefuncs.go b/modules/frontend/webservicefuncs.go index 877a898..943de64 100644 --- a/modules/frontend/webservicefuncs.go +++ b/modules/frontend/webservicefuncs.go @@ -1,7 +1,6 @@ package frontend import ( - "encoding/json" "fmt" "reflect" "slices" @@ -16,7 +15,6 @@ import ( "github.com/lkarlslund/adalanche/modules/engine" "github.com/lkarlslund/adalanche/modules/integrations/activedirectory" "github.com/lkarlslund/adalanche/modules/query" - "github.com/lkarlslund/adalanche/modules/settings" "github.com/lkarlslund/adalanche/modules/ui" "github.com/lkarlslund/adalanche/modules/util" "github.com/lkarlslund/adalanche/modules/version" @@ -173,39 +171,6 @@ func AddUIEndpoints(ws *WebService) { ws.quit <- true }) } -func AddPreferencesEndpoints(ws *WebService) { - // Saved preferences - err := settings.Load() - if err != nil { - ui.Warn().Msgf("Problem loading preferences: %v", err) - } - preferences := ws.API.Group("preferences") - preferences.GET("", func(c *gin.Context) { - c.JSON(200, settings.All()) - }) - preferences.POST("", func(c *gin.Context) { - var prefsmap = make(map[string]any) - err := c.BindJSON(&prefsmap) - if err != nil { - c.String(500, err.Error()) - } - for key, value := range prefsmap { - settings.Set(key, value) - } - settings.Save() - }) - preferences.GET(":key", func(c *gin.Context) { - key := c.Param("key") - out, _ := json.Marshal(settings.Get(key)) - c.Writer.Write(out) - }) - preferences.GET(":key/:value", func(c *gin.Context) { - key := c.Param("key") - value := c.Param("value") - settings.Set(key, value) - settings.Save() - }) -} func AddDataEndpoints(ws *WebService) { api := ws.API // Returns JSON describing an object located by distinguishedName, sid or guid diff --git a/modules/persistence/database.go b/modules/persistence/database.go index 244a410..d5f37ea 100644 --- a/modules/persistence/database.go +++ b/modules/persistence/database.go @@ -3,12 +3,13 @@ package persistence import ( "errors" "fmt" + "os" + "path/filepath" + "github.com/lkarlslund/adalanche/modules/cli" "github.com/spf13/cobra" "github.com/ugorji/go/codec" "go.etcd.io/bbolt" - "os" - "path/filepath" ) var ( @@ -62,18 +63,18 @@ type Identifiable interface { type Defaulter interface { Default() } -type storage[i Identifiable] struct { +type Store[i Identifiable] struct { db *bbolt.DB cache map[string]i bucketname []byte } -func GetStorage[i Identifiable](bucketname string, cached bool) storage[i] { +func GetStorage[i Identifiable](bucketname string, cached bool) Store[i] { db, err := getDB() if err != nil { panic(err) // FIXME } - s := storage[i]{ + s := Store[i]{ db: db, bucketname: []byte(bucketname), // cache: make(map[string]i), @@ -83,7 +84,7 @@ func GetStorage[i Identifiable](bucketname string, cached bool) storage[i] { } return s } -func (s storage[p]) Get(id string) (*p, bool) { +func (s Store[p]) Get(id string) (*p, bool) { var result p if s.cache != nil { if rv, found := s.cache[string(id)]; found { @@ -111,7 +112,7 @@ func (s storage[p]) Get(id string) (*p, bool) { } return nil, false } -func (s storage[p]) Put(saveme p) error { +func (s Store[p]) Put(saveme p) error { var output []byte enc := codec.NewEncoderBytes(&output, &mh) err := enc.Encode(saveme) @@ -141,7 +142,7 @@ func (s storage[p]) Put(saveme p) error { } return nil } -func (s storage[p]) Delete(id string) error { +func (s Store[p]) Delete(id string) error { return s.db.Update(func(tx *bbolt.Tx) error { b := tx.Bucket([]byte(s.bucketname)) if b == nil { @@ -158,7 +159,7 @@ func (s storage[p]) Delete(id string) error { return nil }) } -func (s storage[p]) List() ([]p, error) { +func (s Store[p]) List() ([]p, error) { var result []p return result, s.db.View(func(tx *bbolt.Tx) error { b := tx.Bucket([]byte(s.bucketname)) diff --git a/modules/settings/settings.go b/modules/settings/settings.go deleted file mode 100644 index 77c9655..0000000 --- a/modules/settings/settings.go +++ /dev/null @@ -1,63 +0,0 @@ -package settings - -import ( - "encoding/json" - "errors" - "os" - "sync" -) - -type prefs struct { - data map[string]any -} - -var loaded prefs - -var prefmutex sync.Mutex - -func init() { - Load() -} - -func Load() error { - prefmutex.Lock() - defer prefmutex.Unlock() - loaded.data = make(map[string]any) - - rawprefs, err := os.ReadFile("preferences.json") - if errors.Is(err, os.ErrNotExist) { - return nil - } - if err != nil { - return err - } - err = json.Unmarshal(rawprefs, &loaded.data) - return err -} - -func Save() error { - prefmutex.Lock() - defer prefmutex.Unlock() - rawprefs, err := json.Marshal(loaded.data) - if err != nil { - return err - } - err = os.WriteFile("preferences.json", rawprefs, 0600) - return err -} - -func Set(key string, val any) { - prefmutex.Lock() - defer prefmutex.Unlock() - loaded.data[key] = val -} - -func Get(key string) any { - prefmutex.Lock() - defer prefmutex.Unlock() - return loaded.data[key] -} - -func All() map[string]any { - return loaded.data -}