diff --git a/handlers/packages/packages.go b/handlers/packages/packages.go index 9f1efb3..fb6e270 100644 --- a/handlers/packages/packages.go +++ b/handlers/packages/packages.go @@ -4,67 +4,69 @@ import ( "brunel/domain" "brunel/fastmap" "brunel/packages" + "sort" "strings" "github.com/gofiber/fiber/v2" ) func Packages(c *fiber.Ctx) error { - pageNum := c.QueryInt("page") - pageSize := c.QueryInt("pageSize") - search := c.Query("search") + pageNum := c.QueryInt("page", 1) // Default to 1 if not provided + pageSize := c.QueryInt("pageSize", 250) // Default to 250 if not provided + search := strings.ToLower(c.Query("search")) filter := c.Query("filter") - if pageNum == 0 { - pageNum = 1 - } - if pageSize == 0 { - pageSize = 250 + + // Adjust pageNum to be 0-based for GetPage + adjustedPageNum := pageNum - 1 + if adjustedPageNum < 0 { + adjustedPageNum = 0 } + packs := packages.GetPackages() - if filter != "" { - finalReturn := fastmap.New[string, domain.SourcePackage]() - filteredPacks := fastmap.New[string, domain.SourcePackage]() - packs.Iter(func(k string, source domain.SourcePackage) bool { - source.Packages.Iter(func(key string, value domain.PackageInfo) bool { - if value.Status == domain.PackageStatus(filter) { - filteredPacks.Set(k, source) - return false - } - return true - }) - return true + // Convert map to slice for sorting + packSlice := make([]struct { + Key string + Value domain.SourcePackage + }, 0, packs.Len()) + + packs.Iter(func(k string, v domain.SourcePackage) bool { + packSlice = append(packSlice, struct { + Key string + Value domain.SourcePackage + }{k, v}) + return true + }) + + // Stable sort the slice + sort.SliceStable(packSlice, func(i, j int) bool { + return packSlice[i].Key < packSlice[j].Key + }) + + finalReturn := fastmap.New[string, domain.SourcePackage]() + + for _, item := range packSlice { + k, source := item.Key, item.Value + + matchesFilter := filter == "" + matchesSearch := search == "" || strings.Contains(strings.ToLower(k), search) + + source.Packages.Iter(func(key string, value domain.PackageInfo) bool { + if !matchesFilter && value.Status == domain.PackageStatus(filter) { + matchesFilter = true + } + if !matchesSearch && strings.Contains(strings.ToLower(key), search) { + matchesSearch = true + } + return !(matchesFilter && matchesSearch) // stop iterating if we've found matches for both }) - if search != "" { - filteredPacks.Iter(func(k string, source domain.SourcePackage) bool { - source.Packages.Iter(func(key string, value domain.PackageInfo) bool { - if strings.Contains(key, search) { - finalReturn.Set(k, source) - return false - } - return true - }) - return true - }) - } else { - finalReturn = filteredPacks + + if matchesFilter && matchesSearch { + finalReturn.Set(k, source) } - return c.Status(fiber.StatusOK).JSON(finalReturn.GetPage(pageNum, pageSize)) - } - if search != "" { - finalReturn := fastmap.New[string, domain.SourcePackage]() - packs.Iter(func(k string, source domain.SourcePackage) bool { - source.Packages.Iter(func(key string, value domain.PackageInfo) bool { - if value.Status == domain.PackageStatus(filter) { - finalReturn.Set(k, source) - return false - } - return true - }) - return true - }) - return c.Status(fiber.StatusOK).JSON(finalReturn.GetPage(pageNum, pageSize)) } - return c.Status(fiber.StatusOK).JSON(packs.GetPage(pageNum, pageSize)) + result := finalReturn.GetPage(adjustedPageNum, pageSize) + + return c.Status(fiber.StatusOK).JSON(result) }