feat: improve k8s resource filtering UI

- Change namespace filter from text input to dropdown select
- Add name filtering input for all resource types
- Fix UI overlap issue with namespace dropdown label
- Add automatic namespace list loading
- Implement server-side name filtering for all resources
- Support combined namespace + name filtering

🤖 Generated with [Qoder][https://qoder.com]
This commit is contained in:
loveuer
2025-11-12 23:26:52 +08:00
parent 54ed79cea3
commit 7d2e2ab842
2 changed files with 134 additions and 10 deletions

View File

@@ -6,12 +6,14 @@ import (
"encoding/json"
"fmt"
"io"
"strings"
"gitea.loveuer.com/loveuer/cluster/internal/model"
"gitea.loveuer.com/loveuer/cluster/pkg/resp"
"gitea.loveuer.com/loveuer/cluster/pkg/store"
"github.com/gofiber/fiber/v3"
"gorm.io/gorm"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -93,6 +95,7 @@ func K8sNamespaceList(ctx context.Context, db *gorm.DB, store store.Store) fiber
func K8sDeploymentList(ctx context.Context, db *gorm.DB, store store.Store) fiber.Handler {
return func(c fiber.Ctx) error {
namespace := c.Query("namespace", "")
name := c.Query("name", "")
clientset, err := getK8sClient(db)
if err != nil {
@@ -104,8 +107,20 @@ func K8sDeploymentList(ctx context.Context, db *gorm.DB, store store.Store) fibe
return resp.R500(c, "", nil, err)
}
// Filter by name if provided
var filtered []appsv1.Deployment
if name != "" {
for _, deployment := range deployments.Items {
if strings.Contains(deployment.Name, name) {
filtered = append(filtered, deployment)
}
}
} else {
filtered = deployments.Items
}
return resp.R200(c, map[string]any{
"items": deployments.Items,
"items": filtered,
})
}
}
@@ -113,6 +128,7 @@ func K8sDeploymentList(ctx context.Context, db *gorm.DB, store store.Store) fibe
func K8sStatefulSetList(ctx context.Context, db *gorm.DB, store store.Store) fiber.Handler {
return func(c fiber.Ctx) error {
namespace := c.Query("namespace", "")
name := c.Query("name", "")
clientset, err := getK8sClient(db)
if err != nil {
@@ -124,8 +140,20 @@ func K8sStatefulSetList(ctx context.Context, db *gorm.DB, store store.Store) fib
return resp.R500(c, "", nil, err)
}
// Filter by name if provided
var filtered []appsv1.StatefulSet
if name != "" {
for _, statefulset := range statefulsets.Items {
if strings.Contains(statefulset.Name, name) {
filtered = append(filtered, statefulset)
}
}
} else {
filtered = statefulsets.Items
}
return resp.R200(c, map[string]any{
"items": statefulsets.Items,
"items": filtered,
})
}
}
@@ -133,6 +161,7 @@ func K8sStatefulSetList(ctx context.Context, db *gorm.DB, store store.Store) fib
func K8sConfigMapList(ctx context.Context, db *gorm.DB, store store.Store) fiber.Handler {
return func(c fiber.Ctx) error {
namespace := c.Query("namespace", "")
name := c.Query("name", "")
clientset, err := getK8sClient(db)
if err != nil {
@@ -144,8 +173,20 @@ func K8sConfigMapList(ctx context.Context, db *gorm.DB, store store.Store) fiber
return resp.R500(c, "", nil, err)
}
// Filter by name if provided
var filtered []corev1.ConfigMap
if name != "" {
for _, configmap := range configmaps.Items {
if strings.Contains(configmap.Name, name) {
filtered = append(filtered, configmap)
}
}
} else {
filtered = configmaps.Items
}
return resp.R200(c, map[string]any{
"items": configmaps.Items,
"items": filtered,
})
}
}
@@ -153,6 +194,7 @@ func K8sConfigMapList(ctx context.Context, db *gorm.DB, store store.Store) fiber
func K8sPodList(ctx context.Context, db *gorm.DB, store store.Store) fiber.Handler {
return func(c fiber.Ctx) error {
namespace := c.Query("namespace", "")
name := c.Query("name", "")
clientset, err := getK8sClient(db)
if err != nil {
@@ -164,8 +206,20 @@ func K8sPodList(ctx context.Context, db *gorm.DB, store store.Store) fiber.Handl
return resp.R500(c, "", nil, err)
}
// Filter by name if provided
var filtered []corev1.Pod
if name != "" {
for _, pod := range pods.Items {
if strings.Contains(pod.Name, name) {
filtered = append(filtered, pod)
}
}
} else {
filtered = pods.Items
}
return resp.R200(c, map[string]any{
"items": pods.Items,
"items": filtered,
})
}
}
@@ -191,6 +245,7 @@ func K8sPVList(ctx context.Context, db *gorm.DB, store store.Store) fiber.Handle
func K8sPVCList(ctx context.Context, db *gorm.DB, store store.Store) fiber.Handler {
return func(c fiber.Ctx) error {
namespace := c.Query("namespace", "")
name := c.Query("name", "")
clientset, err := getK8sClient(db)
if err != nil {
@@ -202,8 +257,20 @@ func K8sPVCList(ctx context.Context, db *gorm.DB, store store.Store) fiber.Handl
return resp.R500(c, "", nil, err)
}
// Filter by name if provided
var filtered []corev1.PersistentVolumeClaim
if name != "" {
for _, pvc := range pvcs.Items {
if strings.Contains(pvc.Name, name) {
filtered = append(filtered, pvc)
}
}
} else {
filtered = pvcs.Items
}
return resp.R200(c, map[string]any{
"items": pvcs.Items,
"items": filtered,
})
}
}
@@ -211,6 +278,7 @@ func K8sPVCList(ctx context.Context, db *gorm.DB, store store.Store) fiber.Handl
func K8sServiceList(ctx context.Context, db *gorm.DB, store store.Store) fiber.Handler {
return func(c fiber.Ctx) error {
namespace := c.Query("namespace", "")
name := c.Query("name", "")
clientset, err := getK8sClient(db)
if err != nil {
@@ -222,8 +290,20 @@ func K8sServiceList(ctx context.Context, db *gorm.DB, store store.Store) fiber.H
return resp.R500(c, "", nil, err)
}
// Filter by name if provided
var filtered []corev1.Service
if name != "" {
for _, service := range services.Items {
if strings.Contains(service.Name, name) {
filtered = append(filtered, service)
}
}
} else {
filtered = services.Items
}
return resp.R200(c, map[string]any{
"items": services.Items,
"items": filtered,
})
}
}