feat(v0.2.0): config UI panel + folder picker + S3 bucket lister/tester

- Panel Reglages dans l'UI (modal)
- Folder picker natif Wails pour dossier local
- ListS3Buckets via aws-cli (profile-aware)
- TestS3Access pour verifier acces bucket
- Config persistee user config dir (cross-OS): %APPDATA%/field-sync ou ~/.config/field-sync
- Header affiche bucket + dest visibles
- Auto-open modal si bucket vide au premier run

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Poulpe
2026-04-28 22:08:22 +00:00
parent dcaf5ac020
commit 610ec13b19
3 changed files with 302 additions and 15 deletions

View File

@@ -1,7 +1,9 @@
package config
import (
"encoding/json"
"os"
"path/filepath"
"strconv"
"github.com/joho/godotenv"
@@ -15,7 +17,52 @@ type Config struct {
Concurrency int `json:"concurrency"`
}
// Load reads config from ENV (with optional .env file)
// Path returns the cross-OS config file path
func Path() string {
dir, _ := os.UserConfigDir()
return filepath.Join(dir, "field-sync", "config.json")
}
// Save writes config to disk (atomic)
func Save(cfg Config) error {
p := Path()
if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil {
return err
}
data, _ := json.MarshalIndent(cfg, "", " ")
tmp := p + ".tmp"
if err := os.WriteFile(tmp, data, 0644); err != nil {
return err
}
return os.Rename(tmp, p)
}
// LoadFromFile reads from JSON config file (no .env)
func LoadFromFile() Config {
data, err := os.ReadFile(Path())
if err != nil {
return Config{AWSProfile: "cosma", Concurrency: 4, LocalDest: defaultLocalDest()}
}
var c Config
json.Unmarshal(data, &c)
if c.Concurrency == 0 {
c.Concurrency = 4
}
if c.AWSProfile == "" {
c.AWSProfile = "cosma"
}
if c.LocalDest == "" {
c.LocalDest = defaultLocalDest()
}
return c
}
func defaultLocalDest() string {
home, _ := os.UserHomeDir()
return filepath.Join(home, "field-sync-data")
}
// Load reads config from ENV (with optional .env file) — kept for compat
func Load(envFile string) Config {
_ = godotenv.Load(envFile) // ignore if missing