diff --git a/service/internal/api/api_test.go b/service/internal/api/api_test.go index 270106e..c6ee915 100644 --- a/service/internal/api/api_test.go +++ b/service/internal/api/api_test.go @@ -553,7 +553,7 @@ func TestOrderTopLevelDashboardComponents_RegularFieldsetsPreserveConfigOrder(t root := &apiv1.DashboardComponent{Title: "Actions", Type: "fieldset", EntityType: ""} components := []*apiv1.DashboardComponent{zebra, alpha, root} - out := orderTopLevelDashboardComponents(components) + out := orderTopLevelDashboardComponents(components, root) require.Len(t, out, 3) assert.Same(t, zebra, out[0], "first must be Zebra (config order)") @@ -566,7 +566,7 @@ func TestOrderTopLevelDashboardComponents_SortablesSorted(t *testing.T) { entityAlpha := &apiv1.DashboardComponent{Title: "Alpha", Type: "fieldset", EntityType: "server"} components := []*apiv1.DashboardComponent{entityBeta, entityAlpha} - out := orderTopLevelDashboardComponents(components) + out := orderTopLevelDashboardComponents(components, nil) require.Len(t, out, 2) assert.Equal(t, "Alpha", out[0].Title, "sortables ordered by title") diff --git a/service/internal/api/dashboards.go b/service/internal/api/dashboards.go index bf7e9cb..99d7407 100644 --- a/service/internal/api/dashboards.go +++ b/service/internal/api/dashboards.go @@ -112,9 +112,10 @@ func buildDashboardFromConfig(dashboard *config.DashboardComponent, rr *Dashboar } func buildDashboardFromConfigWithEntity(dashboard *config.DashboardComponent, rr *DashboardRenderRequest, entity *entities.Entity) *apiv1.Dashboard { + contents, root := getDashboardComponentContentsWithEntity(dashboard, rr, entity) return &apiv1.Dashboard{ Title: dashboard.Title, - Contents: orderTopLevelDashboardComponents(removeNulls(getDashboardComponentContentsWithEntity(dashboard, rr, entity))), + Contents: orderTopLevelDashboardComponents(removeNulls(contents), root), } } @@ -216,19 +217,23 @@ func removeNulls(components []*apiv1.DashboardComponent) []*apiv1.DashboardCompo return ret } -func isRegularFieldset(component *apiv1.DashboardComponent, index int, totalLen int) bool { - if component == nil || component.Type != "fieldset" || component.EntityType != "" { - return false - } - return index != totalLen-1 +func isNonEntityFieldset(component *apiv1.DashboardComponent) bool { + return component != nil && component.Type == "fieldset" && component.EntityType == "" } -func partitionTopLevelComponents(components []*apiv1.DashboardComponent) (regular, sortables []*apiv1.DashboardComponent, isRegular []bool) { +func isRegularFieldset(component *apiv1.DashboardComponent, root *apiv1.DashboardComponent) bool { + if !isNonEntityFieldset(component) { + return false + } + return root == nil || component != root +} + +func partitionTopLevelComponents(components []*apiv1.DashboardComponent, root *apiv1.DashboardComponent) (regular, sortables []*apiv1.DashboardComponent, isRegular []bool) { regular = make([]*apiv1.DashboardComponent, 0) sortables = make([]*apiv1.DashboardComponent, 0) isRegular = make([]bool, len(components)) for i, c := range components { - anchor := isRegularFieldset(c, i, len(components)) + anchor := isRegularFieldset(c, root) isRegular[i] = anchor if anchor { regular = append(regular, c) @@ -254,16 +259,16 @@ func mergeOrderedTopLevelComponents(regular, sortables []*apiv1.DashboardCompone return out } -func orderTopLevelDashboardComponents(components []*apiv1.DashboardComponent) []*apiv1.DashboardComponent { +func orderTopLevelDashboardComponents(components []*apiv1.DashboardComponent, root *apiv1.DashboardComponent) []*apiv1.DashboardComponent { if len(components) == 0 { return components } - regular, sortables, isRegular := partitionTopLevelComponents(components) + regular, sortables, isRegular := partitionTopLevelComponents(components, root) sortDashboardComponents(sortables) return mergeOrderedTopLevelComponents(regular, sortables, isRegular) } -func getDashboardComponentContentsWithEntity(dashboard *config.DashboardComponent, rr *DashboardRenderRequest, entity *entities.Entity) []*apiv1.DashboardComponent { +func getDashboardComponentContentsWithEntity(dashboard *config.DashboardComponent, rr *DashboardRenderRequest, entity *entities.Entity) ([]*apiv1.DashboardComponent, *apiv1.DashboardComponent) { ret := make([]*apiv1.DashboardComponent, 0) rootFieldset := createRootFieldset() @@ -271,7 +276,11 @@ func getDashboardComponentContentsWithEntity(dashboard *config.DashboardComponen processDashboardSubitemWithEntity(subitem, rr, &ret, rootFieldset, entity) } - return appendRootFieldsetIfNeeded(ret, rootFieldset) + if len(rootFieldset.Contents) > 0 { + ret = append(ret, rootFieldset) + return ret, rootFieldset + } + return ret, nil } func createRootFieldset() *apiv1.DashboardComponent { @@ -310,18 +319,11 @@ func processDashboardSubitemWithEntity(subitem *config.DashboardComponent, rr *D } } -func appendRootFieldsetIfNeeded(ret []*apiv1.DashboardComponent, rootFieldset *apiv1.DashboardComponent) []*apiv1.DashboardComponent { - if len(rootFieldset.Contents) > 0 { - ret = append(ret, rootFieldset) - } - return ret -} - func buildDashboardComponentSimpleWithEntity(subitem *config.DashboardComponent, rr *DashboardRenderRequest, entity *entities.Entity) *apiv1.DashboardComponent { var contents []*apiv1.DashboardComponent if len(subitem.Contents) > 0 { - contents = getDashboardComponentContentsWithEntity(subitem, rr, entity) + contents, _ = getDashboardComponentContentsWithEntity(subitem, rr, entity) } action := rr.findActionForEntity(subitem.Title, entity)