portainer/portainer

View on GitHub
api/http/handler/endpoints/sort.go

Summary

Maintainability
A
0 mins
Test Coverage
package endpoints

import (
    "slices"

    "github.com/fvbommel/sortorder"
    portainer "github.com/portainer/portainer/api"
)

type comp[T any] func(a, b T) int

func stringComp(a, b string) int {
    if sortorder.NaturalLess(a, b) {
        return -1
    } else if sortorder.NaturalLess(b, a) {
        return 1
    } else {
        return 0
    }
}

func sortEnvironmentsByField(environments []portainer.Endpoint, environmentGroups []portainer.EndpointGroup, sortField sortKey, isSortDesc bool) {
    if sortField == "" {
        return
    }

    var less comp[portainer.Endpoint]
    switch sortField {
    case sortKeyName:
        less = func(a, b portainer.Endpoint) int {
            return stringComp(a.Name, b.Name)
        }

    case sortKeyGroup:
        environmentGroupNames := make(map[portainer.EndpointGroupID]string, 0)
        for _, group := range environmentGroups {
            environmentGroupNames[group.ID] = group.Name
        }

        // set the "unassigned" group name to be empty string
        environmentGroupNames[1] = ""

        less = func(a, b portainer.Endpoint) int {
            aGroup := environmentGroupNames[a.GroupID]
            bGroup := environmentGroupNames[b.GroupID]

            return stringComp(aGroup, bGroup)
        }

    case sortKeyStatus:
        less = func(a, b portainer.Endpoint) int {
            return int(a.Status - b.Status)
        }

    case sortKeyLastCheckInDate:
        less = func(a, b portainer.Endpoint) int {
            return int(a.LastCheckInDate - b.LastCheckInDate)
        }
    case sortKeyEdgeID:
        less = func(a, b portainer.Endpoint) int {
            return stringComp(a.EdgeID, b.EdgeID)
        }

    }

    slices.SortStableFunc(environments, func(a, b portainer.Endpoint) int {
        mul := 1
        if isSortDesc {
            mul = -1
        }

        return less(a, b) * mul
    })

}

type sortKey string

const (
    sortKeyName            sortKey = "Name"
    sortKeyGroup           sortKey = "Group"
    sortKeyStatus          sortKey = "Status"
    sortKeyLastCheckInDate sortKey = "LastCheckIn"
    sortKeyEdgeID          sortKey = "EdgeID"
)

func getSortKey(sortField string) sortKey {
    fieldAsSortKey := sortKey(sortField)
    if slices.Contains([]sortKey{sortKeyName, sortKeyGroup, sortKeyStatus, sortKeyLastCheckInDate, sortKeyEdgeID}, fieldAsSortKey) {
        return fieldAsSortKey
    }

    return ""
}