Add projects table controls and sync status tab with app version
This commit is contained in:
@@ -17,14 +17,16 @@ import (
|
||||
|
||||
// SyncHandler handles sync API endpoints
|
||||
type SyncHandler struct {
|
||||
localDB *localdb.LocalDB
|
||||
syncService *sync.Service
|
||||
connMgr *db.ConnectionManager
|
||||
tmpl *template.Template
|
||||
localDB *localdb.LocalDB
|
||||
syncService *sync.Service
|
||||
connMgr *db.ConnectionManager
|
||||
autoSyncInterval time.Duration
|
||||
onlineGraceFactor float64
|
||||
tmpl *template.Template
|
||||
}
|
||||
|
||||
// NewSyncHandler creates a new sync handler
|
||||
func NewSyncHandler(localDB *localdb.LocalDB, syncService *sync.Service, connMgr *db.ConnectionManager, templatesPath string) (*SyncHandler, error) {
|
||||
func NewSyncHandler(localDB *localdb.LocalDB, syncService *sync.Service, connMgr *db.ConnectionManager, templatesPath string, autoSyncInterval time.Duration) (*SyncHandler, error) {
|
||||
// Load sync_status partial template
|
||||
partialPath := filepath.Join(templatesPath, "partials", "sync_status.html")
|
||||
var tmpl *template.Template
|
||||
@@ -39,10 +41,12 @@ func NewSyncHandler(localDB *localdb.LocalDB, syncService *sync.Service, connMgr
|
||||
}
|
||||
|
||||
return &SyncHandler{
|
||||
localDB: localDB,
|
||||
syncService: syncService,
|
||||
connMgr: connMgr,
|
||||
tmpl: tmpl,
|
||||
localDB: localDB,
|
||||
syncService: syncService,
|
||||
connMgr: connMgr,
|
||||
autoSyncInterval: autoSyncInterval,
|
||||
onlineGraceFactor: 1.10,
|
||||
tmpl: tmpl,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -173,6 +177,7 @@ func (h *SyncHandler) SyncPricelists(c *gin.Context) {
|
||||
Synced: synced,
|
||||
Duration: time.Since(startTime).String(),
|
||||
})
|
||||
h.syncService.RecordSyncHeartbeat()
|
||||
}
|
||||
|
||||
// SyncAllResponse represents result of full sync
|
||||
@@ -238,6 +243,7 @@ func (h *SyncHandler) SyncAll(c *gin.Context) {
|
||||
PricelistsSynced: pricelistsSynced,
|
||||
Duration: time.Since(startTime).String(),
|
||||
})
|
||||
h.syncService.RecordSyncHeartbeat()
|
||||
}
|
||||
|
||||
// checkOnline checks if MariaDB is accessible
|
||||
@@ -273,6 +279,7 @@ func (h *SyncHandler) PushPendingChanges(c *gin.Context) {
|
||||
Synced: pushed,
|
||||
Duration: time.Since(startTime).String(),
|
||||
})
|
||||
h.syncService.RecordSyncHeartbeat()
|
||||
}
|
||||
|
||||
// GetPendingCount returns the number of pending changes
|
||||
@@ -308,6 +315,14 @@ type SyncInfoResponse struct {
|
||||
Errors []SyncError `json:"errors,omitempty"`
|
||||
}
|
||||
|
||||
type SyncUsersStatusResponse struct {
|
||||
IsOnline bool `json:"is_online"`
|
||||
AutoSyncIntervalSeconds int64 `json:"auto_sync_interval_seconds"`
|
||||
OnlineThresholdSeconds int64 `json:"online_threshold_seconds"`
|
||||
GeneratedAt time.Time `json:"generated_at"`
|
||||
Users []sync.UserSyncStatus `json:"users"`
|
||||
}
|
||||
|
||||
// SyncError represents a sync error
|
||||
type SyncError struct {
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
@@ -364,6 +379,40 @@ func (h *SyncHandler) GetInfo(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// GetUsersStatus returns last sync timestamps for users with sync heartbeats.
|
||||
// GET /api/sync/users-status
|
||||
func (h *SyncHandler) GetUsersStatus(c *gin.Context) {
|
||||
threshold := time.Duration(float64(h.autoSyncInterval) * h.onlineGraceFactor)
|
||||
isOnline := h.checkOnline()
|
||||
|
||||
if !isOnline {
|
||||
c.JSON(http.StatusOK, SyncUsersStatusResponse{
|
||||
IsOnline: false,
|
||||
AutoSyncIntervalSeconds: int64(h.autoSyncInterval.Seconds()),
|
||||
OnlineThresholdSeconds: int64(threshold.Seconds()),
|
||||
GeneratedAt: time.Now().UTC(),
|
||||
Users: []sync.UserSyncStatus{},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
users, err := h.syncService.ListUserSyncStatuses(threshold)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, SyncUsersStatusResponse{
|
||||
IsOnline: true,
|
||||
AutoSyncIntervalSeconds: int64(h.autoSyncInterval.Seconds()),
|
||||
OnlineThresholdSeconds: int64(threshold.Seconds()),
|
||||
GeneratedAt: time.Now().UTC(),
|
||||
Users: users,
|
||||
})
|
||||
}
|
||||
|
||||
// SyncStatusPartial renders the sync status partial for htmx
|
||||
// GET /partials/sync-status
|
||||
func (h *SyncHandler) SyncStatusPartial(c *gin.Context) {
|
||||
|
||||
Reference in New Issue
Block a user