Refactor getting all namespaces to use a map for easier handling of pseudo namespaces
continuous-integration/drone/pr Build is failing
Details
continuous-integration/drone/pr Build is failing
Details
This commit is contained in:
parent
9895f8ad66
commit
9469f38d79
|
@ -21,6 +21,7 @@ import (
|
||||||
"code.vikunja.io/api/pkg/user"
|
"code.vikunja.io/api/pkg/user"
|
||||||
"code.vikunja.io/web"
|
"code.vikunja.io/web"
|
||||||
"github.com/imdario/mergo"
|
"github.com/imdario/mergo"
|
||||||
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
)
|
)
|
||||||
|
@ -53,8 +54,8 @@ type Namespace struct {
|
||||||
web.Rights `xorm:"-" json:"-"`
|
web.Rights `xorm:"-" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PseudoNamespace is a pseudo namespace used to hold shared lists
|
// SharedListsPseudoNamespace is a pseudo namespace used to hold shared lists
|
||||||
var PseudoNamespace = Namespace{
|
var SharedListsPseudoNamespace = Namespace{
|
||||||
ID: -1,
|
ID: -1,
|
||||||
Title: "Shared Lists",
|
Title: "Shared Lists",
|
||||||
Description: "Lists of other users shared with you via teams or directly.",
|
Description: "Lists of other users shared with you via teams or directly.",
|
||||||
|
@ -71,6 +72,15 @@ var FavoritesPseudoNamespace = Namespace{
|
||||||
Updated: time.Now(),
|
Updated: time.Now(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SavedFiltersPseudoNamespace is a pseudo namespace used to hold saved filters
|
||||||
|
var SavedFiltersPseudoNamespace = Namespace{
|
||||||
|
ID: -3,
|
||||||
|
Title: "Filters",
|
||||||
|
Description: "Saved filters.",
|
||||||
|
Created: time.Now(),
|
||||||
|
Updated: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
// TableName makes beautiful table names
|
// TableName makes beautiful table names
|
||||||
func (Namespace) TableName() string {
|
func (Namespace) TableName() string {
|
||||||
return "namespaces"
|
return "namespaces"
|
||||||
|
@ -84,7 +94,7 @@ func (n *Namespace) GetSimpleByID() (err error) {
|
||||||
|
|
||||||
// Get the namesapce with shared lists
|
// Get the namesapce with shared lists
|
||||||
if n.ID == -1 {
|
if n.ID == -1 {
|
||||||
*n = PseudoNamespace
|
*n = SharedListsPseudoNamespace
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,13 +189,18 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
|
||||||
return nil, 0, 0, ErrGenericForbidden{}
|
return nil, 0, 0, ErrGenericForbidden{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This map will hold all namespaces and their lists. The key is usually the id of the namespace.
|
||||||
|
// We're using a map here because it makes a few things like adding lists or removing pseudo namespaces easier.
|
||||||
|
namespaces := make(map[int64]*NamespaceWithLists)
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
// Lists with their namespaces
|
||||||
|
|
||||||
doer, err := user.GetFromAuth(a)
|
doer, err := user.GetFromAuth(a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, 0, err
|
return nil, 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
all := []*NamespaceWithLists{}
|
|
||||||
|
|
||||||
// Adding a 1=1 condition by default here because xorm always needs a condition and cannot handle nil conditions
|
// Adding a 1=1 condition by default here because xorm always needs a condition and cannot handle nil conditions
|
||||||
var isArchivedCond builder.Cond = builder.Eq{"1": 1}
|
var isArchivedCond builder.Cond = builder.Eq{"1": 1}
|
||||||
if !n.IsArchived {
|
if !n.IsArchived {
|
||||||
|
@ -194,26 +209,7 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create our pseudo namespace with favorite lists
|
|
||||||
// We want this one at the beginning, which is why we create it here
|
|
||||||
pseudoFavoriteNamespace := FavoritesPseudoNamespace
|
|
||||||
pseudoFavoriteNamespace.Owner = doer
|
|
||||||
all = append(all, &NamespaceWithLists{
|
|
||||||
Namespace: pseudoFavoriteNamespace,
|
|
||||||
Lists: []*List{{}},
|
|
||||||
})
|
|
||||||
*all[0].Lists[0] = FavoritesPseudoList // Copying the list to be able to modify it later
|
|
||||||
|
|
||||||
// Create our pseudo namespace to hold the shared lists
|
|
||||||
pseudonamespace := PseudoNamespace
|
|
||||||
pseudonamespace.Owner = doer
|
|
||||||
all = append(all, &NamespaceWithLists{
|
|
||||||
pseudonamespace,
|
|
||||||
[]*List{},
|
|
||||||
})
|
|
||||||
|
|
||||||
limit, start := getLimitFromPageIndex(page, perPage)
|
limit, start := getLimitFromPageIndex(page, perPage)
|
||||||
|
|
||||||
query := x.Select("namespaces.*").
|
query := x.Select("namespaces.*").
|
||||||
Table("namespaces").
|
Table("namespaces").
|
||||||
Join("LEFT", "team_namespaces", "namespaces.id = team_namespaces.namespace_id").
|
Join("LEFT", "team_namespaces", "namespaces.id = team_namespaces.namespace_id").
|
||||||
|
@ -228,15 +224,15 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
|
||||||
if limit > 0 {
|
if limit > 0 {
|
||||||
query = query.Limit(limit, start)
|
query = query.Limit(limit, start)
|
||||||
}
|
}
|
||||||
err = query.Find(&all)
|
err = query.Find(&namespaces)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return all, 0, 0, err
|
return nil, 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a list of namespace ids
|
// Make a list of namespace ids
|
||||||
var namespaceids []int64
|
var namespaceids []int64
|
||||||
var userIDs []int64
|
var userIDs []int64
|
||||||
for _, nsp := range all {
|
for _, nsp := range namespaces {
|
||||||
namespaceids = append(namespaceids, nsp.ID)
|
namespaceids = append(namespaceids, nsp.ID)
|
||||||
userIDs = append(userIDs, nsp.OwnerID)
|
userIDs = append(userIDs, nsp.OwnerID)
|
||||||
}
|
}
|
||||||
|
@ -245,7 +241,7 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
|
||||||
userMap := make(map[int64]*user.User)
|
userMap := make(map[int64]*user.User)
|
||||||
err = x.In("id", userIDs).Find(&userMap)
|
err = x.In("id", userIDs).Find(&userMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return all, 0, 0, err
|
return nil, 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all lists
|
// Get all lists
|
||||||
|
@ -258,7 +254,18 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
|
||||||
}
|
}
|
||||||
err = listQuery.Find(&lists)
|
err = listQuery.Find(&lists)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return all, 0, 0, err
|
return nil, 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
// Shared Lists
|
||||||
|
|
||||||
|
// Create our pseudo namespace to hold the shared lists
|
||||||
|
sharedListsPseudonamespace := SharedListsPseudoNamespace
|
||||||
|
sharedListsPseudonamespace.Owner = doer
|
||||||
|
namespaces[sharedListsPseudonamespace.ID] = &NamespaceWithLists{
|
||||||
|
sharedListsPseudonamespace,
|
||||||
|
[]*List{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all lists individually shared with our user (not via a namespace)
|
// Get all lists individually shared with our user (not via a namespace)
|
||||||
|
@ -287,9 +294,9 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
|
||||||
lists = append(lists, l)
|
lists = append(lists, l)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the pseudonamespace if we don't have any shared lists
|
// Remove the sharedListsPseudonamespace if we don't have any shared lists
|
||||||
if len(individualLists) == 0 {
|
if len(individualLists) == 0 {
|
||||||
all = append(all[:1], all[2:]...)
|
delete(namespaces, sharedListsPseudonamespace.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// More details for the lists
|
// More details for the lists
|
||||||
|
@ -298,22 +305,23 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
|
||||||
return nil, 0, 0, err
|
return nil, 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
nMap := make(map[int64]*NamespaceWithLists, len(all))
|
/////////////////
|
||||||
|
// Favorite lists
|
||||||
|
|
||||||
// Put objects in our namespace list
|
// Create our pseudo namespace with favorite lists
|
||||||
for _, n := range all {
|
pseudoFavoriteNamespace := FavoritesPseudoNamespace
|
||||||
|
pseudoFavoriteNamespace.Owner = doer
|
||||||
// Users
|
namespaces[pseudoFavoriteNamespace.ID] = &NamespaceWithLists{
|
||||||
n.Owner = userMap[n.OwnerID]
|
Namespace: pseudoFavoriteNamespace,
|
||||||
|
Lists: []*List{{}},
|
||||||
nMap[n.ID] = n
|
|
||||||
}
|
}
|
||||||
|
*namespaces[pseudoFavoriteNamespace.ID].Lists[0] = FavoritesPseudoList // Copying the list to be able to modify it later
|
||||||
|
|
||||||
for _, list := range lists {
|
for _, list := range lists {
|
||||||
if list.IsFavorite {
|
if list.IsFavorite {
|
||||||
nMap[pseudoFavoriteNamespace.ID].Lists = append(nMap[pseudoFavoriteNamespace.ID].Lists, list)
|
namespaces[pseudoFavoriteNamespace.ID].Lists = append(namespaces[pseudoFavoriteNamespace.ID].Lists, list)
|
||||||
}
|
}
|
||||||
nMap[list.NamespaceID].Lists = append(nMap[list.NamespaceID].Lists, list)
|
namespaces[list.NamespaceID].Lists = append(namespaces[list.NamespaceID].Lists, list)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we have any favorites or favorited lists and remove the favorites namespace from the list if not
|
// Check if we have any favorites or favorited lists and remove the favorites namespace from the list if not
|
||||||
|
@ -329,19 +337,24 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
|
||||||
|
|
||||||
// If we don't have any favorites in the favorites pseudo list, remove that pseudo list from the namespace
|
// If we don't have any favorites in the favorites pseudo list, remove that pseudo list from the namespace
|
||||||
if favoriteCount == 0 {
|
if favoriteCount == 0 {
|
||||||
for in, l := range nMap[pseudoFavoriteNamespace.ID].Lists {
|
for in, l := range namespaces[pseudoFavoriteNamespace.ID].Lists {
|
||||||
if l.ID == FavoritesPseudoList.ID {
|
if l.ID == FavoritesPseudoList.ID {
|
||||||
nMap[pseudoFavoriteNamespace.ID].Lists = append(nMap[pseudoFavoriteNamespace.ID].Lists[:in], nMap[pseudoFavoriteNamespace.ID].Lists[in+1:]...)
|
namespaces[pseudoFavoriteNamespace.ID].Lists = append(namespaces[pseudoFavoriteNamespace.ID].Lists[:in], namespaces[pseudoFavoriteNamespace.ID].Lists[in+1:]...)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we don't have any favorites in the namespace, remove it
|
// If we don't have any favorites in the namespace, remove it
|
||||||
if len(nMap[pseudoFavoriteNamespace.ID].Lists) == 0 {
|
if len(namespaces[pseudoFavoriteNamespace.ID].Lists) == 0 {
|
||||||
all = append(all[:0], all[1:]...)
|
delete(namespaces, pseudoFavoriteNamespace.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
// Saved Filters
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
numberOfTotalItems, err = x.
|
numberOfTotalItems, err = x.
|
||||||
Table("namespaces").
|
Table("namespaces").
|
||||||
Join("LEFT", "team_namespaces", "namespaces.id = team_namespaces.namespace_id").
|
Join("LEFT", "team_namespaces", "namespaces.id = team_namespaces.namespace_id").
|
||||||
|
@ -355,9 +368,20 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
|
||||||
Where("namespaces.title LIKE ?", "%"+search+"%").
|
Where("namespaces.title LIKE ?", "%"+search+"%").
|
||||||
Count(&NamespaceWithLists{})
|
Count(&NamespaceWithLists{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return all, 0, 0, err
|
return nil, 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////
|
||||||
|
// Put it all together
|
||||||
|
all := make([]*NamespaceWithLists, 0, len(namespaces))
|
||||||
|
for _, n := range namespaces {
|
||||||
|
n.Owner = userMap[n.OwnerID]
|
||||||
|
all = append(all, n)
|
||||||
|
}
|
||||||
|
sort.Slice(all, func(i, j int) bool {
|
||||||
|
return all[i].ID < all[j].ID
|
||||||
|
})
|
||||||
|
|
||||||
return all, len(all), numberOfTotalItems, nil
|
return all, len(all), numberOfTotalItems, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,13 @@ func (s *SavedFilter) Create(auth web.Auth) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSavedFilterSimpleByID(id int64) (s *SavedFilter, err error) {
|
func getSavedFilterSimpleByID(id int64) (s *SavedFilter, err error) {
|
||||||
_, err = x.Where("id = ?", id).Get(s)
|
exists, err := x.Where("id = ?", id).Get(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
return nil, ErrSavedFilterDoesNotExist{SavedFilterID: id}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ func getNamespace(c echo.Context) (namespace *models.Namespace, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if namespaceID == -1 {
|
if namespaceID == -1 {
|
||||||
namespace = &models.PseudoNamespace
|
namespace = &models.SharedListsPseudoNamespace
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue