Folders: Migrate getFolder API to app platform (#107617)

* Add /children endpoint

* Update folder client

* Add comment

* Add feature toggle

* Add new version of useFoldersQuery

* Error handling

* Format

* Rename feature toggle

* Remove options and move root folder constant

* Fix feature toggle merge

* Add feature toggle again

* Rename useFoldersQuery files

* Update API spec

* Fix test

* Add test

* Migrate delete folder button

* useGetFolderQueryFacade

* Use getFolder facade hook

* Recreate legacy getFolder from the APIs

* Fix imports

* Add comment

* Rename function

* Simulate virtual folders in the API client

* Translations

* Update test

* Move the hook out of the index file

* Fix undefined in test

* Better status combining

* Use real access api for virtual folders

* Add basic test for the hook

* Remove commented import

* Remove the access control api and use legacy api for it

* Update tests

* Moved delete folder into facade hook

* Remove namespace attribute from virtual folders

* go lint

---------

Co-authored-by: Clarity-89 <homes89@ukr.net>
This commit is contained in:
Andrej Ocenas
2025-08-06 13:39:35 +02:00
committed by GitHub
co-authored by Clarity-89
parent 102d230321
commit 85e9bcaa2e
17 changed files with 502 additions and 33 deletions
+2 -2
View File
@@ -4,15 +4,15 @@ import (
"context"
"net/http"
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
"github.com/grafana/grafana/pkg/services/folder"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/registry/rest"
folders "github.com/grafana/grafana/apps/folder/pkg/apis/folder/v1beta1"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/folder"
)
type subAccessREST struct {
+24 -10
View File
@@ -6,6 +6,9 @@ import (
"net/http"
"slices"
"github.com/grafana/grafana/pkg/services/folder"
"k8s.io/apiserver/pkg/storage"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/registry/rest"
@@ -44,17 +47,28 @@ func (r *subParentsREST) NewConnectOptions() (runtime.Object, bool, string) {
}
func (r *subParentsREST) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) {
obj, err := r.getter.Get(ctx, name, &metav1.GetOptions{})
if err != nil {
return nil, err
}
folder, ok := obj.(*folders.Folder)
if !ok {
return nil, fmt.Errorf("expecting folder, found: %T", folder)
}
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
info := r.parents(ctx, folder)
if name == folder.GeneralFolderUID || name == folder.SharedWithMeFolderUID {
responder.Object(http.StatusOK, &folders.FolderInfoList{
Items: []folders.FolderInfo{},
})
return
}
obj, err := r.getter.Get(ctx, name, &metav1.GetOptions{})
if storage.IsNotFound(err) {
responder.Object(http.StatusNotFound, nil)
}
if err != nil {
responder.Error(err)
}
folderObj, ok := obj.(*folders.Folder)
if !ok {
responder.Error(fmt.Errorf("expecting folder, found: %T", folderObj))
}
info := r.parents(ctx, folderObj)
// Start from the root
slices.Reverse(info.Items)
responder.Object(http.StatusOK, info)