api/pkg/models/saved_filters.go

213 lines
6.9 KiB
Go

// 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 <https://www.gnu.org/licenses/>.
package models
import (
"time"
"code.vikunja.io/api/pkg/user"
"code.vikunja.io/web"
"xorm.io/xorm"
)
// SavedFilter represents a saved bunch of filters
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" 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
Description string `xorm:"longtext null" json:"description"`
OwnerID int64 `xorm:"bigint not null INDEX" json:"-"`
// 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 projects.
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.
Updated time.Time `xorm:"updated not null" json:"updated"`
web.CRUDable `xorm:"-" json:"-"`
web.Rights `xorm:"-" json:"-"`
}
// TableName returns a better table name for saved filters
func (sf *SavedFilter) TableName() string {
return "saved_filters"
}
func (sf *SavedFilter) getTaskCollection() *TaskCollection {
// We're resetting the projectID to return tasks from all projects
sf.Filters.ProjectID = 0
return sf.Filters
}
// Returns the saved filter ID from a project ID. Will not check if the filter actually exists.
// If the returned ID is zero, means that it is probably invalid.
func getSavedFilterIDFromProjectID(projectID int64) (filterID int64) {
// We get the id of the saved filter by multiplying the ProjectID with -1 and subtracting one
filterID = projectID*-1 - 1
// FilterIDs from projectIDs are always positive
if filterID < 0 {
filterID = 0
}
return
}
func getProjectIDFromSavedFilterID(filterID int64) (projectID int64) {
projectID = filterID*-1 - 1
// ProjectIDs from saved filters are always negative
if projectID > 0 {
projectID = 0
}
return
}
func getSavedFiltersForUser(s *xorm.Session, auth web.Auth) (filters []*SavedFilter, err error) {
// Link shares can't view or modify saved filters, therefore we can error out right away
if _, is := auth.(*LinkSharing); is {
return nil, ErrSavedFilterNotAvailableForLinkShare{LinkShareID: auth.GetID()}
}
err = s.Where("owner_id = ?", auth.GetID()).Find(&filters)
return
}
func (sf *SavedFilter) toProject() *Project {
return &Project{
ID: getProjectIDFromSavedFilterID(sf.ID),
Title: sf.Title,
Description: sf.Description,
IsFavorite: sf.IsFavorite,
Created: sf.Created,
Updated: sf.Updated,
Owner: sf.Owner,
NamespaceID: SavedFiltersPseudoNamespace.ID,
}
}
// Create creates a new saved filter
// @Summary Creates a new saved filter
// @Description Creates a new saved filter
// @tags filter
// @Accept json
// @Produce json
// @Security JWTKeyAuth
// @Success 201 {object} models.SavedFilter "The Saved Filter"
// @Failure 403 {object} web.HTTPError "The user does not have access to that saved filter."
// @Failure 500 {object} models.Message "Internal error"
// @Router /filters [put]
func (sf *SavedFilter) Create(s *xorm.Session, auth web.Auth) error {
sf.OwnerID = auth.GetID()
_, err := s.Insert(sf)
return err
}
func getSavedFilterSimpleByID(s *xorm.Session, id int64) (sf *SavedFilter, err error) {
sf = &SavedFilter{}
exists, err := s.
Where("id = ?", id).
Get(sf)
if err != nil {
return nil, err
}
if !exists {
return nil, ErrSavedFilterDoesNotExist{SavedFilterID: id}
}
return
}
// ReadOne returns one saved filter
// @Summary Gets one saved filter
// @Description Returns a saved filter by its ID.
// @tags filter
// @Accept json
// @Produce json
// @Security JWTKeyAuth
// @Param id path int true "Filter ID"
// @Success 200 {object} models.SavedFilter "The Saved Filter"
// @Failure 403 {object} web.HTTPError "The user does not have access to that saved filter."
// @Failure 500 {object} models.Message "Internal error"
// @Router /filters/{id} [get]
func (sf *SavedFilter) ReadOne(s *xorm.Session, a web.Auth) error {
// s already contains almost the full saved filter from the rights check, we only need to add the user
u, err := user.GetUserByID(s, sf.OwnerID)
sf.Owner = u
return err
}
// Update updates an existing filter
// @Summary Updates a saved filter
// @Description Updates a saved filter by its ID.
// @tags filter
// @Accept json
// @Produce json
// @Security JWTKeyAuth
// @Param id path int true "Filter ID"
// @Success 200 {object} models.SavedFilter "The Saved Filter"
// @Failure 403 {object} web.HTTPError "The user does not have access to that saved filter."
// @Failure 404 {object} web.HTTPError "The saved filter does not exist."
// @Failure 500 {object} models.Message "Internal error"
// @Router /filters/{id} [post]
func (sf *SavedFilter) Update(s *xorm.Session, a web.Auth) error {
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
}
// Delete removes a saved filter
// @Summary Removes a saved filter
// @Description Removes a saved filter by its ID.
// @tags filter
// @Accept json
// @Produce json
// @Security JWTKeyAuth
// @Param id path int true "Filter ID"
// @Success 200 {object} models.SavedFilter "The Saved Filter"
// @Failure 403 {object} web.HTTPError "The user does not have access to that saved filter."
// @Failure 404 {object} web.HTTPError "The saved filter does not exist."
// @Failure 500 {object} models.Message "Internal error"
// @Router /filters/{id} [delete]
func (sf *SavedFilter) Delete(s *xorm.Session, a web.Auth) error {
_, err := s.
Where("id = ?", sf.ID).
Delete(sf)
return err
}