mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
feat: ability to filter by project labels
This commit is contained in:
parent
a279548c89
commit
d80c1a4c4b
@ -104,7 +104,6 @@ func (f *Filters) Hash() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *Filters) Match(h *Heartbeat) bool {
|
func (f *Filters) Match(h *Heartbeat) bool {
|
||||||
// TODO: labels?
|
|
||||||
return (f.Project == nil || f.Project.MatchAny(h.Project)) &&
|
return (f.Project == nil || f.Project.MatchAny(h.Project)) &&
|
||||||
(f.OS == nil || f.OS.MatchAny(h.OperatingSystem)) &&
|
(f.OS == nil || f.OS.MatchAny(h.OperatingSystem)) &&
|
||||||
(f.Language == nil || f.Language.MatchAny(h.Language)) &&
|
(f.Language == nil || f.Language.MatchAny(h.Language)) &&
|
||||||
@ -113,12 +112,12 @@ func (f *Filters) Match(h *Heartbeat) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WithAliases adds OR-conditions for every alias of a filter key as additional filter keys
|
// WithAliases adds OR-conditions for every alias of a filter key as additional filter keys
|
||||||
func (f *Filters) WithAliases(resolver AliasReverseResolver) *Filters {
|
func (f *Filters) WithAliases(resolve AliasReverseResolver) *Filters {
|
||||||
if f.Project != nil {
|
if f.Project != nil {
|
||||||
updated := OrFilter(make([]string, 0, len(f.Project)))
|
updated := OrFilter(make([]string, 0, len(f.Project)))
|
||||||
for _, e := range f.Project {
|
for _, e := range f.Project {
|
||||||
updated = append(updated, e)
|
updated = append(updated, e)
|
||||||
updated = append(updated, resolver(SummaryProject, e)...)
|
updated = append(updated, resolve(SummaryProject, e)...)
|
||||||
}
|
}
|
||||||
f.Project = updated
|
f.Project = updated
|
||||||
}
|
}
|
||||||
@ -126,7 +125,7 @@ func (f *Filters) WithAliases(resolver AliasReverseResolver) *Filters {
|
|||||||
updated := OrFilter(make([]string, 0, len(f.OS)))
|
updated := OrFilter(make([]string, 0, len(f.OS)))
|
||||||
for _, e := range f.OS {
|
for _, e := range f.OS {
|
||||||
updated = append(updated, e)
|
updated = append(updated, e)
|
||||||
updated = append(updated, resolver(SummaryOS, e)...)
|
updated = append(updated, resolve(SummaryOS, e)...)
|
||||||
}
|
}
|
||||||
f.OS = updated
|
f.OS = updated
|
||||||
}
|
}
|
||||||
@ -134,7 +133,7 @@ func (f *Filters) WithAliases(resolver AliasReverseResolver) *Filters {
|
|||||||
updated := OrFilter(make([]string, 0, len(f.Language)))
|
updated := OrFilter(make([]string, 0, len(f.Language)))
|
||||||
for _, e := range f.Language {
|
for _, e := range f.Language {
|
||||||
updated = append(updated, e)
|
updated = append(updated, e)
|
||||||
updated = append(updated, resolver(SummaryLanguage, e)...)
|
updated = append(updated, resolve(SummaryLanguage, e)...)
|
||||||
}
|
}
|
||||||
f.Language = updated
|
f.Language = updated
|
||||||
}
|
}
|
||||||
@ -142,7 +141,7 @@ func (f *Filters) WithAliases(resolver AliasReverseResolver) *Filters {
|
|||||||
updated := OrFilter(make([]string, 0, len(f.Editor)))
|
updated := OrFilter(make([]string, 0, len(f.Editor)))
|
||||||
for _, e := range f.Editor {
|
for _, e := range f.Editor {
|
||||||
updated = append(updated, e)
|
updated = append(updated, e)
|
||||||
updated = append(updated, resolver(SummaryEditor, e)...)
|
updated = append(updated, resolve(SummaryEditor, e)...)
|
||||||
}
|
}
|
||||||
f.Editor = updated
|
f.Editor = updated
|
||||||
}
|
}
|
||||||
@ -150,9 +149,19 @@ func (f *Filters) WithAliases(resolver AliasReverseResolver) *Filters {
|
|||||||
updated := OrFilter(make([]string, 0, len(f.Machine)))
|
updated := OrFilter(make([]string, 0, len(f.Machine)))
|
||||||
for _, e := range f.Machine {
|
for _, e := range f.Machine {
|
||||||
updated = append(updated, e)
|
updated = append(updated, e)
|
||||||
updated = append(updated, resolver(SummaryMachine, e)...)
|
updated = append(updated, resolve(SummaryMachine, e)...)
|
||||||
}
|
}
|
||||||
f.Machine = updated
|
f.Machine = updated
|
||||||
}
|
}
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *Filters) WithProjectLabels(resolve ProjectLabelReverseResolver) *Filters {
|
||||||
|
if f.Label == nil || !f.Label.Exists() {
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
for _, l := range f.Label {
|
||||||
|
f.Project = append(f.Project, resolve(l)...)
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
|
// ProjectLabelReverseResolver returns all projects for a given label
|
||||||
|
type ProjectLabelReverseResolver func(l string) []string
|
||||||
|
|
||||||
type ProjectLabel struct {
|
type ProjectLabel struct {
|
||||||
ID uint `json:"id" gorm:"primary_key"`
|
ID uint `json:"id" gorm:"primary_key"`
|
||||||
User *User `json:"-" gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
|
User *User `json:"-" gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
|
||||||
|
@ -43,6 +43,7 @@ func (srv *ProjectLabelService) GetByUser(userId string) ([]*models.ProjectLabel
|
|||||||
return labels, nil
|
return labels, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetByUserGrouped returns lists of project labels, grouped by their project key
|
||||||
func (srv *ProjectLabelService) GetByUserGrouped(userId string) (map[string][]*models.ProjectLabel, error) {
|
func (srv *ProjectLabelService) GetByUserGrouped(userId string) (map[string][]*models.ProjectLabel, error) {
|
||||||
labelsByProject := make(map[string][]*models.ProjectLabel)
|
labelsByProject := make(map[string][]*models.ProjectLabel)
|
||||||
userLabels, err := srv.GetByUser(userId)
|
userLabels, err := srv.GetByUser(userId)
|
||||||
@ -60,6 +61,7 @@ func (srv *ProjectLabelService) GetByUserGrouped(userId string) (map[string][]*m
|
|||||||
return labelsByProject, nil
|
return labelsByProject, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetByUserGroupedInverted returns lists of project labels, grouped by their label key
|
||||||
func (srv *ProjectLabelService) GetByUserGroupedInverted(userId string) (map[string][]*models.ProjectLabel, error) {
|
func (srv *ProjectLabelService) GetByUserGroupedInverted(userId string) (map[string][]*models.ProjectLabel, error) {
|
||||||
projectsByLabel := make(map[string][]*models.ProjectLabel)
|
projectsByLabel := make(map[string][]*models.ProjectLabel)
|
||||||
userLabels, err := srv.GetByUser(userId)
|
userLabels, err := srv.GetByUser(userId)
|
||||||
|
@ -62,23 +62,15 @@ func (srv *SummaryService) Aliased(from, to time.Time, user *models.User, f Summ
|
|||||||
return cacheResult.(*models.Summary), nil
|
return cacheResult.(*models.Summary), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap alias resolution
|
// Resolver functions
|
||||||
resolve := func(t uint8, k string) string {
|
resolveAliases := srv.getAliasResolver(user)
|
||||||
s, _ := srv.aliasService.GetAliasOrDefault(user.ID, t, k)
|
resolveAliasesReverse := srv.getAliasReverseResolver(user)
|
||||||
return s
|
resolveProjectLabelsReverse := srv.getProjectLabelsReverseResolver(user)
|
||||||
}
|
|
||||||
resolveReverse := func(t uint8, k string) []string {
|
|
||||||
aliases, _ := srv.aliasService.GetByUserAndKeyAndType(user.ID, k, t)
|
|
||||||
aliasStrings := make([]string, 0, len(aliases))
|
|
||||||
for _, a := range aliases {
|
|
||||||
aliasStrings = append(aliasStrings, a.Value)
|
|
||||||
}
|
|
||||||
return aliasStrings
|
|
||||||
}
|
|
||||||
|
|
||||||
// Post-process filters
|
// Post-process filters
|
||||||
if filters != nil {
|
if filters != nil {
|
||||||
filters = filters.WithAliases(resolveReverse)
|
filters = filters.WithAliases(resolveAliasesReverse)
|
||||||
|
filters = filters.WithProjectLabels(resolveProjectLabelsReverse)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize alias resolver service
|
// Initialize alias resolver service
|
||||||
@ -93,7 +85,7 @@ func (srv *SummaryService) Aliased(from, to time.Time, user *models.User, f Summ
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Post-process summary and cache it
|
// Post-process summary and cache it
|
||||||
summary := s.WithResolvedAliases(resolve)
|
summary := s.WithResolvedAliases(resolveAliases)
|
||||||
summary = srv.withProjectLabels(summary)
|
summary = srv.withProjectLabels(summary)
|
||||||
summary.FillBy(models.SummaryProject, models.SummaryLabel) // first fill up labels from projects
|
summary.FillBy(models.SummaryProject, models.SummaryLabel) // first fill up labels from projects
|
||||||
summary.FillMissing() // then, full up types which are entirely missing
|
summary.FillMissing() // then, full up types which are entirely missing
|
||||||
@ -419,3 +411,41 @@ func (srv *SummaryService) invalidateUserCache(userId string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (srv *SummaryService) getAliasResolver(user *models.User) models.AliasResolver {
|
||||||
|
return func(t uint8, k string) string {
|
||||||
|
s, _ := srv.aliasService.GetAliasOrDefault(user.ID, t, k)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (srv *SummaryService) getAliasReverseResolver(user *models.User) models.AliasReverseResolver {
|
||||||
|
return func(t uint8, k string) []string {
|
||||||
|
aliases, err := srv.aliasService.GetByUserAndKeyAndType(user.ID, k, t)
|
||||||
|
if err != nil {
|
||||||
|
aliases = []*models.Alias{}
|
||||||
|
}
|
||||||
|
aliasStrings := make([]string, 0, len(aliases))
|
||||||
|
for _, a := range aliases {
|
||||||
|
aliasStrings = append(aliasStrings, a.Value)
|
||||||
|
}
|
||||||
|
return aliasStrings
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (srv *SummaryService) getProjectLabelsReverseResolver(user *models.User) models.ProjectLabelReverseResolver {
|
||||||
|
return func(k string) []string {
|
||||||
|
var labels []*models.ProjectLabel
|
||||||
|
allLabels, err := srv.projectLabelService.GetByUserGroupedInverted(user.ID)
|
||||||
|
if err == nil {
|
||||||
|
if l, ok := allLabels[k]; ok {
|
||||||
|
labels = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
projectStrings := make([]string, 0, len(labels))
|
||||||
|
for _, l := range labels {
|
||||||
|
projectStrings = append(projectStrings, l.ProjectKey)
|
||||||
|
}
|
||||||
|
return projectStrings
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user