From 94cb8123d5f21b780bfa19695c0748d81d69756f Mon Sep 17 00:00:00 2001 From: Marek Goc Date: Thu, 26 Mar 2026 13:51:38 +0100 Subject: [PATCH] fix top menu --- app/model/topMenu.go | 16 +- app/service/menuService/menuService.go | 40 +++-- i18n/migrations/20260302163100_routes.sql | 200 ++-------------------- 3 files changed, 50 insertions(+), 206 deletions(-) diff --git a/app/model/topMenu.go b/app/model/topMenu.go index 700a673..9e82e9f 100644 --- a/app/model/topMenu.go +++ b/app/model/topMenu.go @@ -1,15 +1,15 @@ package model type B2BTopMenu struct { - MenuID int `gorm:"column:menu_id;primaryKey;autoIncrement"` - Label string `gorm:"column:label;type:longtext;not null;default:'{}'"` - ParentID *int `gorm:"column:parent_id;index:FK_b2b_top_menu_parent_id"` - Params string `gorm:"column:params;type:longtext;not null;default:'{}'"` - Active int8 `gorm:"column:active;type:tinyint;not null;default:1"` - Position int `gorm:"column:position;not null;default:1"` + MenuID int `gorm:"column:menu_id;primaryKey;autoIncrement" json:"menu_id"` + Label string `gorm:"column:label;type:longtext;not null;default:'{}'" json:"label"` + ParentID *int `gorm:"column:parent_id;index:FK_b2b_top_menu_parent_id" json:"parent_id,omitempty"` + Params string `gorm:"column:params;type:longtext;not null;default:'{}'" json:"params"` + Active int8 `gorm:"column:active;type:tinyint;not null;default:1" json:"active"` + Position int `gorm:"column:position;not null;default:1" json:"position"` - Parent *B2BTopMenu `gorm:"foreignKey:ParentID;references:MenuID;constraint:OnDelete:RESTRICT,OnUpdate:RESTRICT"` - Children []B2BTopMenu `gorm:"foreignKey:ParentID"` + Parent *B2BTopMenu `gorm:"foreignKey:ParentID;references:MenuID;constraint:OnDelete:RESTRICT,OnUpdate:RESTRICT" json:"parent,omitempty"` + Children []B2BTopMenu `gorm:"foreignKey:ParentID" json:"children,omitempty"` } func (B2BTopMenu) TableName() string { diff --git a/app/service/menuService/menuService.go b/app/service/menuService/menuService.go index b78156f..c21a660 100644 --- a/app/service/menuService/menuService.go +++ b/app/service/menuService/menuService.go @@ -99,32 +99,40 @@ func (a ByPosition) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByPosition) Less(i, j int) bool { return a[i].Position < a[j].Position } func (s *MenuService) GetTopMenu(id uint) ([]model.B2BTopMenu, error) { - menuMap := make(map[int]*model.B2BTopMenu) - var roots []model.B2BTopMenu - items, err := s.routesRepo.GetTopMenu(id) if err != nil { return nil, err } - // Build the map first - for i := range items { - items[i].Children = []model.B2BTopMenu{} - menuMap[items[i].MenuID] = &items[i] + if len(items) == 0 { + return []model.B2BTopMenu{}, nil } - // Then link children to parents - for _, item := range menuMap { - if item.ParentID != nil && *item.ParentID != 0 { - parent, exists := menuMap[*item.ParentID] - if exists { - parent.Children = append(parent.Children, *item) - } + // Build a map with empty children slices + itemMap := make(map[int]model.B2BTopMenu, len(items)) + for i := range items { + items[i].Children = []model.B2BTopMenu{} + itemMap[items[i].MenuID] = items[i] + } + + // Build the tree + var roots []model.B2BTopMenu + for _, item := range itemMap { + if item.ParentID == nil || *item.ParentID == 0 { + roots = append(roots, itemMap[item.MenuID]) } else { - // This is a root item - roots = append(roots, *item) + parentID := *item.ParentID + if parent, exists := itemMap[parentID]; exists { + parent.Children = append(parent.Children, item) + itemMap[parentID] = parent + } } } + // Update roots with children + for i := range roots { + roots[i] = itemMap[roots[i].MenuID] + } + return roots, nil } diff --git a/i18n/migrations/20260302163100_routes.sql b/i18n/migrations/20260302163100_routes.sql index 9104ad7..7414d85 100644 --- a/i18n/migrations/20260302163100_routes.sql +++ b/i18n/migrations/20260302163100_routes.sql @@ -46,192 +46,28 @@ CREATE TABLE IF NOT EXISTS b2b_top_menu ( INSERT IGNORE INTO `b2b_top_menu` (`menu_id`, `label`, `parent_id`, `params`) VALUES -- ROOT - ( - 1, - '{ - "name": "root", - "trans": { - "pl": "Menu główne", - "en": "Main Menu", - "de": "Hauptmenü" - } -}', - NULL, - '{}' - ), + (1, JSON_COMPACT('{"name":"root","trans":{"pl":"Menu główne","en":"Main Menu","de":"Hauptmenü"}}'), NULL, '{}'), + -- LEVEL 1 - ( - 2, - '{ - "name": "dashboard", - "trans": { - "pl": "Panel", - "en": "Dashboard", - "de": "Dashboard" - } -}', - 1, - '{}' - ), - ( - 3, - '{ - "name": "orders", - "trans": { - "pl": "Zamówienia", - "en": "Orders", - "de": "Bestellungen" - } -}', - 1, - '{}' - ), - ( - 4, - '{ - "name": "customers", - "trans": { - "pl": "Klienci", - "en": "Customers", - "de": "Kunden" - } -}', - 1, - '{}' - ), - ( - 5, - '{ - "name": "products", - "trans": { - "pl": "Produkty", - "en": "Products", - "de": "Produkte" - } -}', - 1, - '{}' - ), - ( - 6, - '{ - "name": "reports", - "trans": { - "pl": "Raporty", - "en": "Reports", - "de": "Berichte" - } -}', - 1, - '{}' - ), + (2, JSON_COMPACT('{"name":"dashboard","trans":{"pl":"Panel","en":"Dashboard","de":"Dashboard"}}'), 1, '{}'), + (3, JSON_COMPACT('{"name":"orders","trans":{"pl":"Zamówienia","en":"Orders","de":"Bestellungen"}}'), 1, '{}'), + (4, JSON_COMPACT('{"name":"customers","trans":{"pl":"Klienci","en":"Customers","de":"Kunden"}}'), 1, '{}'), + (5, JSON_COMPACT('{"name":"products","trans":{"pl":"Produkty","en":"Products","de":"Produkte"}}'), 1, '{}'), + (6, JSON_COMPACT('{"name":"reports","trans":{"pl":"Raporty","en":"Reports","de":"Berichte"}}'), 1, '{}'), + -- LEVEL 2 (Orders) - ( - 7, - '{ - "name": "order_list", - "trans": { - "pl": "Lista zamówień", - "en": "Order List", - "de": "Bestellliste" - } -}', - 3, - '{}' - ), - ( - 8, - '{ - "name": "pending_orders", - "trans": { - "pl": "Oczekujące zamówienia", - "en": "Pending Orders", - "de": "Ausstehende Bestellungen" - } -}', - 3, - '{}' - ), - ( - 9, - '{ - "name": "carts", - "trans": { - "pl": "Koszyki", - "en": "Carts", - "de": "Warenkörbe" - } -}', - 3, - '{}' - ), + (7, JSON_COMPACT('{"name":"order_list","trans":{"pl":"Lista zamówień","en":"Order List","de":"Bestellliste"}}'), 3, '{}'), + (8, JSON_COMPACT('{"name":"pending_orders","trans":{"pl":"Oczekujące zamówienia","en":"Pending Orders","de":"Ausstehende Bestellungen"}}'), 3, '{}'), + (9, JSON_COMPACT('{"name":"carts","trans":{"pl":"Koszyki","en":"Carts","de":"Warenkörbe"}}'), 3, '{}'), + -- LEVEL 2 (Products) - ( - 10, - '{ - "name": "product_list", - "trans": { - "pl": "Lista produktów", - "en": "Product List", - "de": "Produktliste" - } -}', - 5, - '{}' - ), - ( - 11, - '{ - "name": "categories", - "trans": { - "pl": "Kategorie", - "en": "Categories", - "de": "Kategorien" - } -}', - 5, - '{}' - ), - ( - 12, - '{ - "name": "inventory", - "trans": { - "pl": "Magazyn", - "en": "Inventory", - "de": "Lagerbestand" - } -}', - 5, - '{}' - ), + (10, JSON_COMPACT('{"name":"product_list","trans":{"pl":"Lista produktów","en":"Product List","de":"Produktliste"}}'), 5, '{}'), + (11, JSON_COMPACT('{"name":"categories","trans":{"pl":"Kategorie","en":"Categories","de":"Kategorien"}}'), 5, '{}'), + (12, JSON_COMPACT('{"name":"inventory","trans":{"pl":"Magazyn","en":"Inventory","de":"Lagerbestand"}}'), 5, '{}'), + -- LEVEL 2 (Customers) - ( - 13, - '{ - "name": "customer_list", - "trans": { - "pl": "Lista klientów", - "en": "Customer List", - "de": "Kundenliste" - } -}', - 4, - '{}' - ), - ( - 14, - '{ - "name": "customer_groups", - "trans": { - "pl": "Grupy klientów", - "en": "Customer Groups", - "de": "Kundengruppen" - } -}', - 4, - '{}' - ); + (13, JSON_COMPACT('{"name":"customer_list","trans":{"pl":"Lista klientów","en":"Customer List","de":"Kundenliste"}}'), 4, '{}'), + (14, JSON_COMPACT('{"name":"customer_groups","trans":{"pl":"Grupy klientów","en":"Customer Groups","de":"Kundengruppen"}}'), 4, '{}'); -- +goose Down DROP TABLE IF EXISTS b2b_routes; -- 2.49.1