2022-10-26 09:15:14 -05:00
|
|
|
package folder
|
|
|
|
|
|
|
|
import (
|
|
|
|
"time"
|
2022-10-28 08:35:49 -05:00
|
|
|
|
2022-11-30 10:12:56 -06:00
|
|
|
"github.com/grafana/grafana/pkg/infra/slugify"
|
2022-11-10 03:41:03 -06:00
|
|
|
"github.com/grafana/grafana/pkg/models"
|
2022-11-23 03:13:47 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/user"
|
2022-10-28 08:35:49 -05:00
|
|
|
"github.com/grafana/grafana/pkg/util/errutil"
|
2022-10-26 09:15:14 -05:00
|
|
|
)
|
|
|
|
|
2022-11-03 08:21:41 -05:00
|
|
|
var ErrMaximumDepthReached = errutil.NewBase(errutil.StatusBadRequest, "folder.maximum-depth-reached", errutil.WithPublicMessage("Maximum nested folder depth reached"))
|
|
|
|
var ErrBadRequest = errutil.NewBase(errutil.StatusBadRequest, "folder.bad-request")
|
|
|
|
var ErrDatabaseError = errutil.NewBase(errutil.StatusInternal, "folder.database-error")
|
|
|
|
var ErrInternal = errutil.NewBase(errutil.StatusInternal, "folder.internal")
|
2022-11-08 13:53:05 -06:00
|
|
|
var ErrFolderTooDeep = errutil.NewBase(errutil.StatusInternal, "folder.too-deep")
|
2022-12-08 07:49:17 -06:00
|
|
|
var ErrCircularReference = errutil.NewBase(errutil.StatusBadRequest, "folder.circular-reference", errutil.WithPublicMessage("Circular reference detected"))
|
2022-11-03 08:21:41 -05:00
|
|
|
|
2022-10-26 09:15:14 -05:00
|
|
|
const (
|
|
|
|
GeneralFolderUID = "general"
|
2022-11-08 07:59:55 -06:00
|
|
|
RootFolderUID = ""
|
2022-10-26 09:15:14 -05:00
|
|
|
MaxNestedFolderDepth = 8
|
|
|
|
)
|
|
|
|
|
2022-10-28 08:35:49 -05:00
|
|
|
var ErrFolderNotFound = errutil.NewBase(errutil.StatusNotFound, "folder.notFound")
|
|
|
|
|
2022-10-26 09:15:14 -05:00
|
|
|
type Folder struct {
|
2022-11-03 08:21:41 -05:00
|
|
|
ID int64 `xorm:"pk autoincr 'id'"`
|
|
|
|
OrgID int64 `xorm:"org_id"`
|
|
|
|
UID string `xorm:"uid"`
|
|
|
|
ParentUID string `xorm:"parent_uid"`
|
2022-10-26 09:15:14 -05:00
|
|
|
Title string
|
|
|
|
Description string
|
|
|
|
|
|
|
|
Created time.Time
|
|
|
|
Updated time.Time
|
|
|
|
|
2022-10-28 07:23:39 -05:00
|
|
|
// TODO: validate if this field is required/relevant to folders.
|
2022-11-03 08:21:41 -05:00
|
|
|
// currently there is no such column
|
2022-11-15 04:58:12 -06:00
|
|
|
Version int
|
|
|
|
Url string
|
|
|
|
UpdatedBy int64
|
|
|
|
CreatedBy int64
|
|
|
|
HasACL bool
|
2022-11-10 03:41:03 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
type FolderDTO struct {
|
|
|
|
Folder
|
|
|
|
|
|
|
|
Children []FolderDTO
|
2022-10-26 09:15:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewFolder tales a title and returns a Folder with the Created and Updated
|
|
|
|
// fields set to the current time.
|
|
|
|
func NewFolder(title string, description string) *Folder {
|
|
|
|
return &Folder{
|
|
|
|
Title: title,
|
|
|
|
Description: description,
|
|
|
|
Created: time.Now(),
|
|
|
|
Updated: time.Now(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CreateFolderCommand captures the information required by the folder service
|
|
|
|
// to create a folder.
|
|
|
|
type CreateFolderCommand struct {
|
2022-11-03 08:21:41 -05:00
|
|
|
UID string `json:"uid"`
|
2022-11-10 03:41:03 -06:00
|
|
|
OrgID int64 `json:"-"`
|
2022-10-26 09:15:14 -05:00
|
|
|
Title string `json:"title"`
|
|
|
|
Description string `json:"description"`
|
2022-11-24 12:28:53 -06:00
|
|
|
ParentUID string `json:"parentUid"`
|
2022-11-23 03:13:47 -06:00
|
|
|
|
|
|
|
SignedInUser *user.SignedInUser `json:"-"`
|
2022-10-26 09:15:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// UpdateFolderCommand captures the information required by the folder service
|
|
|
|
// to update a folder. Use Move to update a folder's parent folder.
|
|
|
|
type UpdateFolderCommand struct {
|
|
|
|
Folder *Folder `json:"folder"` // The extant folder
|
2022-10-28 13:07:25 -05:00
|
|
|
NewUID *string `json:"uid" xorm:"uid"`
|
2022-10-26 09:15:14 -05:00
|
|
|
NewTitle *string `json:"title"`
|
|
|
|
NewDescription *string `json:"description"`
|
2022-11-23 03:13:47 -06:00
|
|
|
|
|
|
|
SignedInUser *user.SignedInUser `json:"-"`
|
2022-10-26 09:15:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// MoveFolderCommand captures the information required by the folder service
|
|
|
|
// to move a folder.
|
|
|
|
type MoveFolderCommand struct {
|
|
|
|
UID string `json:"uid"`
|
2022-11-24 12:28:53 -06:00
|
|
|
NewParentUID string `json:"newParentUid"`
|
2022-11-10 03:41:03 -06:00
|
|
|
OrgID int64 `json:"-"`
|
2022-11-23 03:13:47 -06:00
|
|
|
|
|
|
|
SignedInUser *user.SignedInUser `json:"-"`
|
2022-10-26 09:15:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// DeleteFolderCommand captures the information required by the folder service
|
|
|
|
// to delete a folder.
|
|
|
|
type DeleteFolderCommand struct {
|
2022-11-10 02:42:32 -06:00
|
|
|
UID string `json:"uid" xorm:"uid"`
|
|
|
|
OrgID int64 `json:"orgId" xorm:"org_id"`
|
|
|
|
ForceDeleteRules bool `json:"forceDeleteRules"`
|
2022-11-23 03:13:47 -06:00
|
|
|
|
|
|
|
SignedInUser *user.SignedInUser `json:"-"`
|
2022-10-26 09:15:14 -05:00
|
|
|
}
|
|
|
|
|
2022-10-26 10:52:01 -05:00
|
|
|
// GetFolderQuery is used for all folder Get requests. Only one of UID, ID, or
|
2022-10-26 09:15:14 -05:00
|
|
|
// Title should be set; if multilpe fields are set by the caller the dashboard
|
|
|
|
// service will select the field with the most specificity, in order: ID, UID,
|
|
|
|
// Title.
|
2022-10-26 10:52:01 -05:00
|
|
|
type GetFolderQuery struct {
|
2022-10-26 09:15:14 -05:00
|
|
|
UID *string
|
2022-11-03 08:21:41 -05:00
|
|
|
ID *int64
|
2022-10-26 09:15:14 -05:00
|
|
|
Title *string
|
2022-11-03 08:21:41 -05:00
|
|
|
OrgID int64
|
2022-11-23 03:13:47 -06:00
|
|
|
|
|
|
|
SignedInUser *user.SignedInUser `json:"-"`
|
2022-10-26 09:15:14 -05:00
|
|
|
}
|
|
|
|
|
2022-10-26 10:52:01 -05:00
|
|
|
// GetParentsQuery captures the information required by the folder service to
|
2022-10-26 09:15:14 -05:00
|
|
|
// return a list of all parent folders of a given folder.
|
2022-10-26 10:52:01 -05:00
|
|
|
type GetParentsQuery struct {
|
2022-11-03 08:21:41 -05:00
|
|
|
UID string `xorm:"uid"`
|
|
|
|
OrgID int64 `xorm:"org_id"`
|
2022-10-26 09:15:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetTreeCommand captures the information required by the folder service to
|
|
|
|
// return a list of child folders of the given folder.
|
|
|
|
|
2022-10-26 10:52:01 -05:00
|
|
|
type GetTreeQuery struct {
|
2022-10-28 13:07:25 -05:00
|
|
|
UID string `xorm:"uid"`
|
|
|
|
OrgID int64 `xorm:"org_id"`
|
2022-10-26 09:15:14 -05:00
|
|
|
Depth int64
|
|
|
|
|
|
|
|
// Pagination options
|
|
|
|
Limit int64
|
|
|
|
Page int64
|
|
|
|
}
|
2022-11-10 03:41:03 -06:00
|
|
|
|
|
|
|
// ToLegacyModel is temporary until the two folder services are merged
|
|
|
|
func (f *Folder) ToLegacyModel() *models.Folder {
|
|
|
|
return &models.Folder{
|
|
|
|
Id: f.ID,
|
|
|
|
Uid: f.UID,
|
|
|
|
Title: f.Title,
|
2022-11-30 10:12:56 -06:00
|
|
|
Url: models.GetFolderUrl(f.UID, slugify.Slugify(f.Title)),
|
2022-11-10 03:41:03 -06:00
|
|
|
Version: 0,
|
|
|
|
Created: f.Created,
|
|
|
|
Updated: f.Updated,
|
|
|
|
UpdatedBy: 0,
|
|
|
|
CreatedBy: 0,
|
|
|
|
HasACL: false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func FromDashboard(dash *models.Dashboard) *Folder {
|
|
|
|
return &Folder{
|
2022-11-15 04:58:12 -06:00
|
|
|
ID: dash.Id,
|
|
|
|
UID: dash.Uid,
|
|
|
|
Title: dash.Title,
|
|
|
|
HasACL: dash.HasACL,
|
|
|
|
Url: models.GetFolderUrl(dash.Uid, dash.Slug),
|
|
|
|
Version: dash.Version,
|
|
|
|
Created: dash.Created,
|
|
|
|
CreatedBy: dash.CreatedBy,
|
|
|
|
Updated: dash.Updated,
|
|
|
|
UpdatedBy: dash.UpdatedBy,
|
2022-11-10 03:41:03 -06:00
|
|
|
}
|
|
|
|
}
|