feat(unified-storage): fetch full path if needed (#99747)
This commit is contained in:
@@ -352,6 +352,14 @@ func (ss *FolderUnifiedStoreImpl) GetFolders(ctx context.Context, q folder.GetFo
|
|||||||
if f == nil {
|
if f == nil {
|
||||||
return nil, fmt.Errorf("unable to convert unstructured item to legacy folder %w", err)
|
return nil, fmt.Errorf("unable to convert unstructured item to legacy folder %w", err)
|
||||||
}
|
}
|
||||||
|
if q.WithFullpath || q.WithFullpathUIDs {
|
||||||
|
parents, err := ss.GetParents(ctx, folder.GetParentsQuery{UID: f.UID, OrgID: q.OrgID})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get parents for folder %s: %w", f.UID, err)
|
||||||
|
}
|
||||||
|
// If we don't have a parent, we just return the current folder as the full path
|
||||||
|
f.Fullpath, f.FullpathUIDs = computeFullPath(append(parents, f))
|
||||||
|
}
|
||||||
|
|
||||||
m[f.UID] = f
|
m[f.UID] = f
|
||||||
}
|
}
|
||||||
@@ -529,3 +537,13 @@ func (ss *FolderUnifiedStoreImpl) getK8sContext(ctx context.Context) (context.Co
|
|||||||
|
|
||||||
return newCtx, nil, nil
|
return newCtx, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func computeFullPath(parents []*folder.Folder) (string, string) {
|
||||||
|
fullpath := make([]string, len(parents))
|
||||||
|
fullpathUIDs := make([]string, len(parents))
|
||||||
|
for i, p := range parents {
|
||||||
|
fullpath[i] = p.Title
|
||||||
|
fullpathUIDs[i] = p.UID
|
||||||
|
}
|
||||||
|
return strings.Join(fullpath, "/"), strings.Join(fullpathUIDs, "/")
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package folderimpl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/folder"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestComputeFullPath(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
parents []*folder.Folder
|
||||||
|
wantPath string
|
||||||
|
wantPathUIDs string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty slice should return empty paths",
|
||||||
|
parents: []*folder.Folder{},
|
||||||
|
wantPath: "",
|
||||||
|
wantPathUIDs: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single element should return single path",
|
||||||
|
parents: []*folder.Folder{
|
||||||
|
{
|
||||||
|
Title: "Element",
|
||||||
|
UID: "Element-uid",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantPath: "Element",
|
||||||
|
wantPathUIDs: "Element-uid",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple parents should return hierarchical path",
|
||||||
|
parents: []*folder.Folder{
|
||||||
|
{
|
||||||
|
Title: "Grandparent",
|
||||||
|
UID: "grandparent-uid",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Title: "Parent",
|
||||||
|
UID: "parent-uid",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Title: "Element",
|
||||||
|
UID: "Element-uid",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantPath: "Grandparent/Parent/Element",
|
||||||
|
wantPathUIDs: "grandparent-uid/parent-uid/Element-uid",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "should handle special characters in titles",
|
||||||
|
parents: []*folder.Folder{
|
||||||
|
{
|
||||||
|
Title: "Parent/With/Slashes",
|
||||||
|
UID: "parent-uid",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Title: "Element With Spaces",
|
||||||
|
UID: "Element-uid",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantPath: "Parent/With/Slashes/Element With Spaces",
|
||||||
|
wantPathUIDs: "parent-uid/Element-uid",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
gotPath, gotPathUIDs := computeFullPath(tc.parents)
|
||||||
|
require.Equal(t, tc.wantPath, gotPath)
|
||||||
|
require.Equal(t, tc.wantPathUIDs, gotPathUIDs)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user