diff --git a/ui/controllers/components.go b/ui/controllers/components.go index 5b588d1..6267450 100644 --- a/ui/controllers/components.go +++ b/ui/controllers/components.go @@ -3,6 +3,8 @@ package controllers import ( "git.preston-baxter.com/Preston_PLB/capstone/frontend-service/templates" "github.com/gin-gonic/gin" + "golang.org/x/text/language" + "golang.org/x/text/message" ) func GetAddActionForm(c *gin.Context) { @@ -22,3 +24,81 @@ func GetAddActionForm(c *gin.Context) { renderTempl(c, templates.DashboardActionModal(accounts)) } + +type DashboardMetric struct { + Title string + PrimaryValue string + SecondaryValue string + Subtitle string +} + +type dashboardMetricFunc func(c *gin.Context) *DashboardMetric + +var metricFuncMap = map[string]dashboardMetricFunc{"default": defaultMetricFunction, "events_received": eventsRecievedMetricFunction, "streams_scheduled": streamsScheduledMetricFunction} + +func GetMetricCard(c *gin.Context) { + user := getUserFromContext(c) + if user == nil { + log.Warnf("Could not find user in context. Trying to redner Action form") + badRequest(c, "No user available in context") + return + } + + if metric, ok := c.GetQuery("metric"); ok { + if metricFunc, mok := metricFuncMap[metric]; mok { + renderDashboardMetric(c, &metricFunc) + return + } + } + + //send default metric function + log.Warn("Failed to find metricfunc") + defaultFunc := metricFuncMap["default"] + renderDashboardMetric(c, &defaultFunc) +} + +func defaultMetricFunction(c *gin.Context) *DashboardMetric { + return &DashboardMetric{ + Title: "Err", + PrimaryValue: "0.00", + SecondaryValue: "0.00", + Subtitle: "something went wrong", + } +} + +func renderDashboardMetric(c *gin.Context, metricFunc *dashboardMetricFunc) { + metric := (*metricFunc)(c) + renderTempl(c, templates.DashboardCard(metric.Title, metric.PrimaryValue, metric.SecondaryValue, metric.Subtitle)) +} + +func eventsRecievedMetricFunction(c *gin.Context) *DashboardMetric { + user := getUserFromContext(c) + + events, err := mongo.AggregateVendorEventReport(user.Id) + if err != nil { + log.WithError(err).Errorf("Failed to find events for user: %s", user.Id.Hex()) + return defaultMetricFunction(c) + } + + totalEvents := 0 + biggestVendor := 0 + for index, event := range events { + totalEvents += event.Count + if events[biggestVendor].Count < event.Count { + biggestVendor = index + } + + } + + p := message.NewPrinter(language.English) + return &DashboardMetric{ + Title: "Events Recieved", + PrimaryValue: p.Sprintf("%d", totalEvents), + SecondaryValue: p.Sprintf("Most events came from: %s", events[biggestVendor].Name), + Subtitle: "thats a lot of events", + } +} + +func streamsScheduledMetricFunction(c *gin.Context) *DashboardMetric { + return defaultMetricFunction(c) +} diff --git a/ui/controllers/controllers.go b/ui/controllers/controllers.go index 4ef1dfb..793eef1 100644 --- a/ui/controllers/controllers.go +++ b/ui/controllers/controllers.go @@ -48,6 +48,9 @@ func BuildRouter(r *gin.Engine) { //Dashboard Forms dashboardForms := dashboard.Group("/forms") dashboardForms.GET("/addAction", GetAddActionForm) + //Dashboard Components + dashboardComponents := dashboard.Group("/components") + dashboardComponents.GET("/metric_card", GetMetricCard) //Vendor stuff vendor := r.Group("/vendor") diff --git a/ui/db/audit.go b/ui/db/audit.go index 45fd905..68b8a2d 100644 --- a/ui/db/audit.go +++ b/ui/db/audit.go @@ -76,6 +76,61 @@ func (db *DB) FindAuditTrailForUser(userId primitive.ObjectID) ([]models.EventRe return events, actions, nil } -func (db *DB) FindEventRecievedByVendorId(id string) []models.EventRecieved { - return []models.EventRecieved{} +func (db *DB) FindEventsRecievedByUserId(userId primitive.ObjectID) ([]models.EventRecieved, error) { + conf := config.Config() + opts := options.Find() + res, err := db.client.Database(conf.Mongo.EntDb).Collection(conf.Mongo.EntCol).Find(context.Background(), bson.M{"user_id": userId, "obj_info.ent": models.EVENT_RECIEVED_TYPE}, opts) + if err != nil { + if err == mongo.ErrNoDocuments { + return nil, nil + } + return nil, err + } + + events := []models.EventRecieved{} + err = res.All(context.Background(), &events) + if err != nil { + return nil, err + } + + return events, nil +} + +type VendorEventReport struct { + Count int `bson:"count"` + Name string `bson:"_id"` +} + +func (db *DB) AggregateVendorEventReport(userId primitive.ObjectID) ([]VendorEventReport, error) { + conf := config.Config() + opts := options.Aggregate().SetAllowDiskUse(false) + + aggregation := bson.A{ + bson.D{{Key: "$match", Value: bson.D{{Key: "obj_info.ent", Value: "audit_event_recieved"}}}}, + bson.D{ + {Key: "$group", + Value: bson.D{ + {Key: "_id", Value: "$vendor_name"}, + {Key: "count", Value: bson.D{{Key: "$sum", Value: 1}}}, + }, + }, + }, + } + + res, err := db.client.Database(conf.Mongo.EntDb).Collection(conf.Mongo.EntCol).Aggregate(context.Background(), aggregation, opts) + + if err != nil { + if err == mongo.ErrNoDocuments { + return nil, nil + } + return nil, err + } + + events := []VendorEventReport{} + err = res.All(context.Background(), &events) + if err != nil { + return nil, err + } + + return events, nil } diff --git a/ui/templates/dashboard_page.templ b/ui/templates/dashboard_page.templ index beebb11..038fad8 100644 --- a/ui/templates/dashboard_page.templ +++ b/ui/templates/dashboard_page.templ @@ -57,7 +57,7 @@ templ DashboardNav(user *models.User) { @@ -87,7 +87,7 @@ templ DashboardNav(user *models.User) { @@ -167,7 +167,7 @@ templ DashboardContentNav(user *models.User) {