148 lines
4.1 KiB
Go
148 lines
4.1 KiB
Go
package api
|
|
|
|
import (
|
|
"sort"
|
|
"strings"
|
|
|
|
apiv1 "github.com/OliveTin/OliveTin/gen/olivetin/api/v1"
|
|
config "github.com/OliveTin/OliveTin/internal/config"
|
|
"github.com/OliveTin/OliveTin/internal/entities"
|
|
)
|
|
|
|
const defaultEntityInstancesPageSize = 10
|
|
|
|
func (api *oliveTinAPI) buildEntityDefinitionsResponse(req *apiv1.GetEntitiesRequest, entityMap entities.EntitiesByClass) []*apiv1.EntityDefinition {
|
|
if req != nil && req.EntityType != "" {
|
|
return api.buildFilteredEntityDefinitions(req, entityMap)
|
|
}
|
|
|
|
return api.buildAllEntityDefinitions(entityMap)
|
|
}
|
|
|
|
func (api *oliveTinAPI) buildAllEntityDefinitions(entityMap entities.EntitiesByClass) []*apiv1.EntityDefinition {
|
|
entityNames := sortedEntityTypeNames(entityMap)
|
|
entityDefinitions := make([]*apiv1.EntityDefinition, 0, len(entityNames))
|
|
|
|
for _, name := range entityNames {
|
|
entityFile := entityFileForType(api.cfg, name)
|
|
properties := entityPropertiesFromFile(entityFile)
|
|
instances := buildSortedEntityInstances(name, entityMap[name], properties)
|
|
|
|
def := &apiv1.EntityDefinition{
|
|
Title: name,
|
|
UsedOnDashboards: findDashboardsForEntity(name, api.cfg.Dashboards),
|
|
Icon: entityTypeIcon(api.cfg, name),
|
|
Properties: entityDefinitionProperties(properties),
|
|
TotalInstances: int32(len(instances)),
|
|
}
|
|
|
|
if len(properties) == 0 {
|
|
def.Instances = instances
|
|
}
|
|
|
|
entityDefinitions = append(entityDefinitions, def)
|
|
}
|
|
|
|
return entityDefinitions
|
|
}
|
|
|
|
func (api *oliveTinAPI) buildFilteredEntityDefinitions(req *apiv1.GetEntitiesRequest, entityMap entities.EntitiesByClass) []*apiv1.EntityDefinition {
|
|
entityInstances, ok := entityMap[req.EntityType]
|
|
if !ok || len(entityInstances) == 0 {
|
|
return nil
|
|
}
|
|
|
|
entityFile := entityFileForType(api.cfg, req.EntityType)
|
|
properties := entityPropertiesFromFile(entityFile)
|
|
instances := buildSortedEntityInstances(req.EntityType, entityInstances, properties)
|
|
filtered := filterEntityInstances(instances, req.Filter)
|
|
pageSize := normalizeEntityInstancesPageSize(req.PageSize)
|
|
page := normalizeEntityInstancesPage(req.Page)
|
|
|
|
def := &apiv1.EntityDefinition{
|
|
Title: req.EntityType,
|
|
UsedOnDashboards: findDashboardsForEntity(req.EntityType, api.cfg.Dashboards),
|
|
Icon: entityTypeIcon(api.cfg, req.EntityType),
|
|
Properties: entityDefinitionProperties(properties),
|
|
TotalInstances: int32(len(filtered)),
|
|
Instances: paginateEntityInstances(filtered, page, pageSize),
|
|
}
|
|
|
|
return []*apiv1.EntityDefinition{def}
|
|
}
|
|
|
|
func sortedEntityTypeNames(entityMap entities.EntitiesByClass) []string {
|
|
entityNames := make([]string, 0, len(entityMap))
|
|
for name := range entityMap {
|
|
entityNames = append(entityNames, name)
|
|
}
|
|
sort.Strings(entityNames)
|
|
return entityNames
|
|
}
|
|
|
|
func normalizeEntityInstancesPage(page int32) int32 {
|
|
if page < 1 {
|
|
return 1
|
|
}
|
|
return page
|
|
}
|
|
|
|
func normalizeEntityInstancesPageSize(pageSize int32) int32 {
|
|
if pageSize < 1 {
|
|
return defaultEntityInstancesPageSize
|
|
}
|
|
return pageSize
|
|
}
|
|
|
|
func filterEntityInstances(instances []*apiv1.Entity, filter string) []*apiv1.Entity {
|
|
filter = strings.TrimSpace(strings.ToLower(filter))
|
|
if filter == "" {
|
|
return instances
|
|
}
|
|
|
|
filtered := make([]*apiv1.Entity, 0, len(instances))
|
|
for _, instance := range instances {
|
|
if entityInstanceMatchesFilter(instance, filter) {
|
|
filtered = append(filtered, instance)
|
|
}
|
|
}
|
|
|
|
return filtered
|
|
}
|
|
|
|
func entityInstanceMatchesFilter(instance *apiv1.Entity, filter string) bool {
|
|
if strings.Contains(strings.ToLower(instance.Title), filter) {
|
|
return true
|
|
}
|
|
|
|
for _, value := range instance.Fields {
|
|
if strings.Contains(strings.ToLower(value), filter) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func paginateEntityInstances(instances []*apiv1.Entity, page, pageSize int32) []*apiv1.Entity {
|
|
start := int((page - 1) * pageSize)
|
|
if start >= len(instances) {
|
|
return []*apiv1.Entity{}
|
|
}
|
|
|
|
end := start + int(pageSize)
|
|
if end > len(instances) {
|
|
end = len(instances)
|
|
}
|
|
|
|
return instances[start:end]
|
|
}
|
|
|
|
func entityFieldsForResponse(data any, properties []config.EntityProperty) map[string]string {
|
|
if len(properties) > 0 {
|
|
return entityListFields(data, properties)
|
|
}
|
|
|
|
return serializeEntityFields(data)
|
|
}
|