32: MenuService — menu data model, tree builder, and app/section state #33

Open
opened 2026-07-05 00:54:47 -06:00 by ppreeper · 0 comments
Owner

Description

Build the menu data model and service layer that feeds menu data to the NavBar (AppMenu, SectionMenu, Breadcrumbs) and Sidebar. Models Odoo's menu service architecture.

Data Model

// MenuItem represents a single menu node in the hierarchy.
type MenuItem struct {
    ID          int         `json:"id"`
    Name        string      `json:"name"`
    ParentID    *int        `json:"parent_id"`      // nil for root
    ActionID    *int        `json:"action_id"`      // nil for folders
    AppID       int         `json:"app_id"`         // which app this belongs to
    XMLID       string      `json:"xmlid"`
    WebIconData string      `json:"web_icon_data"`  // data:image/png;base64,...
    Children    []*MenuItem `json:"children"`
}

// MenuStore holds the full menu tree with lookup helpers.
type MenuStore struct {
    items  map[int]*MenuItem  // flat lookup by ID
    root   *MenuItem          // virtual root, children = apps
    order  []int              // user's custom app ordering
}

Service API

type MenuService interface {
    GetApps() []*MenuItem                    // root children = installed apps
    GetAppByID(id int) *MenuItem
    GetMenu(id int) *MenuItem
    GetMenuAsTree(id int) *MenuItem          // builds childrenTree recursively
    GetCurrentApp() *MenuItem
    SelectMenu(menu *MenuItem)               // triggers action + sets current app
    SetCurrentApp(app *MenuItem)
    Reload() error                           // re-fetch menus from server
}

Events

const MenuAppChanged = "MENUS:APP-CHANGED"  // emitted when current app changes

Responsibilities

  • Parse flat menu JSON into tree structure
  • Provide apps list for AppMenu and Sidebar
  • Provide sections for SectionMenu (child of current app)
  • Track current active app
  • Provide breadcrumb trail from current location
  • Persist app order preference
  • Support async reload from server

Depends On

  • A server endpoint returning menu JSON (analogous to Odoo's /web/webclient/load_menus)
  • The action router (for SelectMenu to trigger navigation)

References

Odoo's menu_service.js:

  • Flat menusData object keyed by menu ID
  • getApps() = root.children.map(getMenu)
  • getMenuAsTree() recursively builds childrenTree by mapping child IDs
  • selectMenu() triggers action + sets current app
  • MENUS:APP-CHANGED bus event for reactive UI updates
  • localStorage caching with version hash
## Description Build the menu data model and service layer that feeds menu data to the NavBar (AppMenu, SectionMenu, Breadcrumbs) and Sidebar. Models Odoo's menu service architecture. ## Data Model ```go // MenuItem represents a single menu node in the hierarchy. type MenuItem struct { ID int `json:"id"` Name string `json:"name"` ParentID *int `json:"parent_id"` // nil for root ActionID *int `json:"action_id"` // nil for folders AppID int `json:"app_id"` // which app this belongs to XMLID string `json:"xmlid"` WebIconData string `json:"web_icon_data"` // data:image/png;base64,... Children []*MenuItem `json:"children"` } // MenuStore holds the full menu tree with lookup helpers. type MenuStore struct { items map[int]*MenuItem // flat lookup by ID root *MenuItem // virtual root, children = apps order []int // user's custom app ordering } ``` ## Service API ```go type MenuService interface { GetApps() []*MenuItem // root children = installed apps GetAppByID(id int) *MenuItem GetMenu(id int) *MenuItem GetMenuAsTree(id int) *MenuItem // builds childrenTree recursively GetCurrentApp() *MenuItem SelectMenu(menu *MenuItem) // triggers action + sets current app SetCurrentApp(app *MenuItem) Reload() error // re-fetch menus from server } ``` ## Events ```go const MenuAppChanged = "MENUS:APP-CHANGED" // emitted when current app changes ``` ## Responsibilities - Parse flat menu JSON into tree structure - Provide apps list for AppMenu and Sidebar - Provide sections for SectionMenu (child of current app) - Track current active app - Provide breadcrumb trail from current location - Persist app order preference - Support async reload from server ## Depends On - A server endpoint returning menu JSON (analogous to Odoo's `/web/webclient/load_menus`) - The action router (for `SelectMenu` to trigger navigation) ## References Odoo's menu_service.js: - Flat `menusData` object keyed by menu ID - `getApps()` = root.children.map(getMenu) - `getMenuAsTree()` recursively builds childrenTree by mapping child IDs - `selectMenu()` triggers action + sets current app - `MENUS:APP-CHANGED` bus event for reactive UI updates - localStorage caching with version hash
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ppreeper/webtemplate#33
No description provided.