From 0b8173c1c3c35acc2f60954cd6de3f35695ecb62 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 3 Apr 2021 16:49:20 +0200 Subject: [PATCH] Fix not able to make saved filters favorite --- .gitignore | 1 + pkg/migration/20210403145503.go | 43 +++++++++++++++++++++++++++++++++ pkg/models/list.go | 19 +++++++++++++++ pkg/models/list_rights.go | 11 +++++++++ pkg/models/namespace.go | 41 +++++++++++++++---------------- pkg/models/saved_filters.go | 29 ++++++++++++++++++++-- pkg/swagger/docs.go | 4 +++ pkg/swagger/swagger.json | 4 +++ pkg/swagger/swagger.yaml | 3 +++ 9 files changed, 131 insertions(+), 24 deletions(-) create mode 100644 pkg/migration/20210403145503.go diff --git a/.gitignore b/.gitignore index 8862180fb..7cf9e4a85 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ files/ vikunja-dump* vendor/ os-packages/ +mage_output_file.go diff --git a/pkg/migration/20210403145503.go b/pkg/migration/20210403145503.go new file mode 100644 index 000000000..9cd4b116c --- /dev/null +++ b/pkg/migration/20210403145503.go @@ -0,0 +1,43 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-2021 Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public Licensee as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public Licensee for more details. +// +// You should have received a copy of the GNU Affero General Public Licensee +// along with this program. If not, see . + +package migration + +import ( + "src.techknowlogick.com/xormigrate" + "xorm.io/xorm" +) + +type savedFilters20210403145503 struct { + IsFavorite bool `xorm:"default false" json:"is_favorite"` +} + +func (savedFilters20210403145503) TableName() string { + return "saved_filters" +} + +func init() { + migrations = append(migrations, &xormigrate.Migration{ + ID: "20210403145503", + Description: "", + Migrate: func(tx *xorm.Engine) error { + return tx.Sync2(savedFilters20210403145503{}) + }, + Rollback: func(tx *xorm.Engine) error { + return nil + }, + }) +} diff --git a/pkg/models/list.go b/pkg/models/list.go index 6156df8a9..ebcd54ed8 100644 --- a/pkg/models/list.go +++ b/pkg/models/list.go @@ -586,6 +586,25 @@ func CreateOrUpdateList(s *xorm.Session, list *List, auth web.Auth) (err error) // @Failure 500 {object} models.Message "Internal error" // @Router /lists/{id} [post] func (l *List) Update(s *xorm.Session, a web.Auth) (err error) { + fid := getSavedFilterIDFromListID(l.ID) + if fid > 0 { + f, err := getSavedFilterSimpleByID(s, fid) + if err != nil { + return err + } + + f.IsFavorite = l.IsFavorite + f.Title = l.Title + f.Description = l.Description + err = f.Update(s, a) + if err != nil { + return err + } + + *l = *f.toList() + return nil + } + err = CreateOrUpdateList(s, l, a) if err != nil { return err diff --git a/pkg/models/list_rights.go b/pkg/models/list_rights.go index f263ab7fd..5b4144f77 100644 --- a/pkg/models/list_rights.go +++ b/pkg/models/list_rights.go @@ -115,6 +115,17 @@ func (l *List) CanUpdate(s *xorm.Session, a web.Auth) (canUpdate bool, err error if l.ID == FavoritesPseudoList.ID { return false, nil } + + fid := getSavedFilterIDFromListID(l.ID) + if fid > 0 { + sf, err := getSavedFilterSimpleByID(s, fid) + if err != nil { + return false, err + } + + return sf.CanUpdate(s, a) + } + canUpdate, err = l.CanWrite(s, a) // If the list is archived and the user tries to un-archive it, let the request through if IsErrListIsArchived(err) && !l.IsArchived { diff --git a/pkg/models/namespace.go b/pkg/models/namespace.go index 044be2bcf..ebe5cd142 100644 --- a/pkg/models/namespace.go +++ b/pkg/models/namespace.go @@ -434,14 +434,10 @@ func getSavedFilters(s *xorm.Session, doer *user.User) (savedFiltersNamespace *N } for _, filter := range savedFilters { - savedFiltersNamespace.Lists = append(savedFiltersNamespace.Lists, &List{ - ID: getListIDFromSavedFilterID(filter.ID), - Title: filter.Title, - Description: filter.Description, - Created: filter.Created, - Updated: filter.Updated, - Owner: doer, - }) + filterList := filter.toList() + filterList.NamespaceID = savedFiltersNamespace.ID + filterList.Owner = doer + savedFiltersNamespace.Lists = append(savedFiltersNamespace.Lists, filterList) } return @@ -521,6 +517,19 @@ func (n *Namespace) ReadAll(s *xorm.Session, a web.Auth, search string, page int lists = append(lists, sharedListsNamespace.Lists...) } + ///////////////// + // Saved Filters + + savedFiltersNamespace, err := getSavedFilters(s, doer) + if err != nil { + return nil, 0, 0, err + } + + if savedFiltersNamespace != nil { + namespaces[savedFiltersNamespace.ID] = savedFiltersNamespace + lists = append(lists, savedFiltersNamespace.Lists...) + } + ///////////////// // Favorite lists @@ -533,18 +542,6 @@ func (n *Namespace) ReadAll(s *xorm.Session, a web.Auth, search string, page int namespaces[favoritesNamespace.ID] = favoritesNamespace } - ///////////////// - // Saved Filters - - savedFiltersNamespace, err := getSavedFilters(s, doer) - if err != nil { - return nil, 0, 0, err - } - - if savedFiltersNamespace != nil { - namespaces[savedFiltersNamespace.ID] = savedFiltersNamespace - } - ////////////////////// // Put it all together @@ -554,8 +551,8 @@ func (n *Namespace) ReadAll(s *xorm.Session, a web.Auth, search string, page int } for _, list := range lists { - if list.NamespaceID == SharedListsPseudoNamespace.ID { - // Shared lists are already in the namespace + if list.NamespaceID == SharedListsPseudoNamespace.ID || list.NamespaceID == SavedFiltersPseudoNamespace.ID { + // Shared lists and filtered lists are already in the namespace continue } namespaces[list.NamespaceID].Lists = append(namespaces[list.NamespaceID].Lists, list) diff --git a/pkg/models/saved_filters.go b/pkg/models/saved_filters.go index 1d93a5290..819d1937e 100644 --- a/pkg/models/saved_filters.go +++ b/pkg/models/saved_filters.go @@ -29,7 +29,7 @@ type SavedFilter struct { // The unique numeric id of this saved filter ID int64 `xorm:"autoincr not null unique pk" json:"id" param:"filter"` // The actual filters this filter contains - Filters *TaskCollection `xorm:"JSON not null" json:"filters"` + Filters *TaskCollection `xorm:"JSON not null" json:"filters" valid:"required"` // The title of the filter. Title string `xorm:"varchar(250) not null" json:"title" valid:"required,runelength(1|250)" minLength:"1" maxLength:"250"` // The description of the filter @@ -39,6 +39,9 @@ type SavedFilter struct { // The user who owns this filter Owner *user.User `xorm:"-" json:"owner" valid:"-"` + // True if the filter is a favorite. Favorite filters show up in a separate namespace together with favorite lists. + IsFavorite bool `xorm:"default false" json:"is_favorite"` + // A timestamp when this filter was created. You cannot change this value. Created time.Time `xorm:"created not null" json:"created"` // A timestamp when this filter was last updated. You cannot change this value. @@ -90,6 +93,18 @@ func getSavedFiltersForUser(s *xorm.Session, auth web.Auth) (filters []*SavedFil return } +func (sf *SavedFilter) toList() *List { + return &List{ + ID: getListIDFromSavedFilterID(sf.ID), + Title: sf.Title, + Description: sf.Description, + IsFavorite: sf.IsFavorite, + Created: sf.Created, + Updated: sf.Updated, + Owner: sf.Owner, + } +} + // Create creates a new saved filter // @Summary Creates a new saved filter // @Description Creates a new saved filter @@ -154,12 +169,22 @@ func (sf *SavedFilter) ReadOne(s *xorm.Session, a web.Auth) error { // @Failure 500 {object} models.Message "Internal error" // @Router /filters/{id} [post] func (sf *SavedFilter) Update(s *xorm.Session, a web.Auth) error { - _, err := s. + origFilter, err := getSavedFilterSimpleByID(s, sf.ID) + if err != nil { + return err + } + + if sf.Filters == nil { + sf.Filters = origFilter.Filters + } + + _, err = s. Where("id = ?", sf.ID). Cols( "title", "description", "filters", + "is_favorite", ). Update(sf) return err diff --git a/pkg/swagger/docs.go b/pkg/swagger/docs.go index 3dad52f1d..4d3d7b1f0 100644 --- a/pkg/swagger/docs.go +++ b/pkg/swagger/docs.go @@ -7770,6 +7770,10 @@ var doc = `{ "description": "The unique numeric id of this saved filter", "type": "integer" }, + "is_favorite": { + "description": "True if the filter is a favorite. Favorite filters show up in a separate namespace together with favorite lists.", + "type": "boolean" + }, "owner": { "description": "The user who owns this filter", "$ref": "#/definitions/user.User" diff --git a/pkg/swagger/swagger.json b/pkg/swagger/swagger.json index 218bb867b..d75e776ce 100644 --- a/pkg/swagger/swagger.json +++ b/pkg/swagger/swagger.json @@ -7753,6 +7753,10 @@ "description": "The unique numeric id of this saved filter", "type": "integer" }, + "is_favorite": { + "description": "True if the filter is a favorite. Favorite filters show up in a separate namespace together with favorite lists.", + "type": "boolean" + }, "owner": { "description": "The user who owns this filter", "$ref": "#/definitions/user.User" diff --git a/pkg/swagger/swagger.yaml b/pkg/swagger/swagger.yaml index f55d98cbf..b0240baac 100644 --- a/pkg/swagger/swagger.yaml +++ b/pkg/swagger/swagger.yaml @@ -524,6 +524,9 @@ definitions: id: description: The unique numeric id of this saved filter type: integer + is_favorite: + description: True if the filter is a favorite. Favorite filters show up in a separate namespace together with favorite lists. + type: boolean owner: $ref: '#/definitions/user.User' description: The user who owns this filter