Nested folders: Refactor folder update (#60323)
* Nested folders: Refactor folder update * Apply suggestions from code review
This commit is contained in:
@@ -366,33 +366,33 @@ func (s *Service) Create(ctx context.Context, cmd *folder.CreateFolderCommand) (
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (s *Service) Update(ctx context.Context, user *user.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) (*folder.Folder, error) {
|
||||
foldr, err := s.legacyUpdate(ctx, user, orgID, existingUid, cmd)
|
||||
func (s *Service) Update(ctx context.Context, cmd *folder.UpdateFolderCommand) (*folder.Folder, error) {
|
||||
if cmd.SignedInUser == nil {
|
||||
return nil, folder.ErrBadRequest.Errorf("missing signed in user")
|
||||
}
|
||||
user := cmd.SignedInUser
|
||||
|
||||
foldr, err := s.legacyUpdate(ctx, cmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if s.features.IsEnabled(featuremgmt.FlagNestedFolders) {
|
||||
if cmd.Uid != "" {
|
||||
if !util.IsValidShortUID(cmd.Uid) {
|
||||
if cmd.NewUID != nil && *cmd.NewUID != "" {
|
||||
if !util.IsValidShortUID(*cmd.NewUID) {
|
||||
return nil, dashboards.ErrDashboardInvalidUid
|
||||
} else if util.IsShortUIDTooLong(cmd.Uid) {
|
||||
} else if util.IsShortUIDTooLong(*cmd.NewUID) {
|
||||
return nil, dashboards.ErrDashboardUidTooLong
|
||||
}
|
||||
}
|
||||
|
||||
getFolder, err := s.store.Get(ctx, folder.GetFolderQuery{
|
||||
UID: &existingUid,
|
||||
OrgID: orgID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
foldr, err := s.store.Update(ctx, folder.UpdateFolderCommand{
|
||||
Folder: getFolder,
|
||||
NewUID: &cmd.Uid,
|
||||
NewTitle: &cmd.Title,
|
||||
NewDescription: &cmd.Description,
|
||||
UID: cmd.UID,
|
||||
OrgID: cmd.OrgID,
|
||||
NewUID: cmd.NewUID,
|
||||
NewTitle: cmd.NewTitle,
|
||||
NewDescription: cmd.NewDescription,
|
||||
SignedInUser: user,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -402,10 +402,10 @@ func (s *Service) Update(ctx context.Context, user *user.SignedInUser, orgID int
|
||||
return foldr, nil
|
||||
}
|
||||
|
||||
func (s *Service) legacyUpdate(ctx context.Context, user *user.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) (*folder.Folder, error) {
|
||||
func (s *Service) legacyUpdate(ctx context.Context, cmd *folder.UpdateFolderCommand) (*folder.Folder, error) {
|
||||
logger := s.log.FromContext(ctx)
|
||||
|
||||
query := models.GetDashboardQuery{OrgId: orgID, Uid: existingUid}
|
||||
query := models.GetDashboardQuery{OrgId: cmd.OrgID, Uid: cmd.UID}
|
||||
_, err := s.dashboardStore.GetDashboard(ctx, &query)
|
||||
if err != nil {
|
||||
return nil, toFolderError(err)
|
||||
@@ -418,12 +418,17 @@ func (s *Service) legacyUpdate(ctx context.Context, user *user.SignedInUser, org
|
||||
return nil, dashboards.ErrFolderNotFound
|
||||
}
|
||||
|
||||
cmd.UpdateDashboardModel(dashFolder, orgID, user.UserID)
|
||||
if cmd.SignedInUser == nil {
|
||||
return nil, folder.ErrBadRequest.Errorf("missing signed in user")
|
||||
}
|
||||
user := cmd.SignedInUser
|
||||
|
||||
prepareForUpdate(dashFolder, cmd.OrgID, cmd.SignedInUser.UserID, cmd)
|
||||
|
||||
dto := &dashboards.SaveDashboardDTO{
|
||||
Dashboard: dashFolder,
|
||||
OrgId: orgID,
|
||||
User: user,
|
||||
OrgId: cmd.OrgID,
|
||||
User: cmd.SignedInUser,
|
||||
Overwrite: cmd.Overwrite,
|
||||
}
|
||||
|
||||
@@ -438,7 +443,7 @@ func (s *Service) legacyUpdate(ctx context.Context, user *user.SignedInUser, org
|
||||
}
|
||||
|
||||
var foldr *folder.Folder
|
||||
foldr, err = s.dashboardStore.GetFolderByID(ctx, orgID, dash.Id)
|
||||
foldr, err = s.dashboardStore.GetFolderByID(ctx, cmd.OrgID, dash.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -449,7 +454,7 @@ func (s *Service) legacyUpdate(ctx context.Context, user *user.SignedInUser, org
|
||||
Title: foldr.Title,
|
||||
ID: dash.Id,
|
||||
UID: dash.Uid,
|
||||
OrgID: orgID,
|
||||
OrgID: cmd.OrgID,
|
||||
}); err != nil {
|
||||
logger.Error("failed to publish FolderTitleUpdated event", "folder", foldr.Title, "user", user.UserID, "error", err)
|
||||
}
|
||||
@@ -457,6 +462,32 @@ func (s *Service) legacyUpdate(ctx context.Context, user *user.SignedInUser, org
|
||||
return foldr, nil
|
||||
}
|
||||
|
||||
// prepareForUpdate updates an existing dashboard model from command into model for folder update
|
||||
func prepareForUpdate(dashFolder *models.Dashboard, orgId int64, userId int64, cmd *folder.UpdateFolderCommand) {
|
||||
dashFolder.OrgId = orgId
|
||||
|
||||
title := dashFolder.Title
|
||||
if cmd.NewTitle != nil && *cmd.NewTitle != "" {
|
||||
title = *cmd.NewTitle
|
||||
}
|
||||
dashFolder.Title = strings.TrimSpace(title)
|
||||
dashFolder.Data.Set("title", dashFolder.Title)
|
||||
|
||||
if cmd.NewUID != nil && *cmd.NewUID != "" {
|
||||
dashFolder.SetUid(*cmd.NewUID)
|
||||
}
|
||||
|
||||
dashFolder.SetVersion(cmd.Version)
|
||||
dashFolder.IsFolder = true
|
||||
|
||||
if userId == 0 {
|
||||
userId = -1
|
||||
}
|
||||
|
||||
dashFolder.UpdatedBy = userId
|
||||
dashFolder.UpdateSlug()
|
||||
}
|
||||
|
||||
func (s *Service) DeleteFolder(ctx context.Context, cmd *folder.DeleteFolderCommand) error {
|
||||
logger := s.log.FromContext(ctx)
|
||||
if cmd.SignedInUser == nil {
|
||||
@@ -501,23 +532,20 @@ func (s *Service) Move(ctx context.Context, cmd *folder.MoveFolderCommand) (*fol
|
||||
return nil, folder.ErrBadRequest.Errorf("missing signed in user")
|
||||
}
|
||||
|
||||
foldr, err := s.Get(ctx, &folder.GetFolderQuery{
|
||||
UID: &cmd.UID,
|
||||
OrgID: cmd.OrgID,
|
||||
SignedInUser: cmd.SignedInUser,
|
||||
})
|
||||
g, err := guardian.NewByUID(ctx, cmd.UID, cmd.OrgID, cmd.SignedInUser)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if the new parent is the same as the current parent, we don't need to do anything
|
||||
if foldr.ParentUID == cmd.NewParentUID {
|
||||
return foldr, nil
|
||||
if canSave, err := g.CanSave(); err != nil || !canSave {
|
||||
if err != nil {
|
||||
return nil, toFolderError(err)
|
||||
}
|
||||
return nil, dashboards.ErrFolderAccessDenied
|
||||
}
|
||||
|
||||
// here we get the folder, we need to get the height of current folder
|
||||
// and the depth of the new parent folder, the sum can't bypass 8
|
||||
folderHeight, err := s.store.GetHeight(ctx, foldr.UID, cmd.OrgID, &cmd.NewParentUID)
|
||||
folderHeight, err := s.store.GetHeight(ctx, cmd.UID, cmd.OrgID, &cmd.NewParentUID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -533,13 +561,16 @@ func (s *Service) Move(ctx context.Context, cmd *folder.MoveFolderCommand) (*fol
|
||||
|
||||
// if the current folder is already a parent of newparent, we should return error
|
||||
for _, parent := range parents {
|
||||
if parent.UID == foldr.UID {
|
||||
if parent.UID == cmd.UID {
|
||||
return nil, folder.ErrCircularReference
|
||||
}
|
||||
}
|
||||
|
||||
return s.store.Update(ctx, folder.UpdateFolderCommand{
|
||||
Folder: foldr,
|
||||
UID: cmd.UID,
|
||||
OrgID: cmd.OrgID,
|
||||
NewParentUID: &cmd.NewParentUID,
|
||||
SignedInUser: cmd.SignedInUser,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user