Skip to content

Commit 052d3d4

Browse files
committed
Merge branch 'catalog'
2 parents 8ac89b6 + bebb4be commit 052d3d4

File tree

3 files changed

+226
-0
lines changed

3 files changed

+226
-0
lines changed

mdl/catalog/builder.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,10 @@ func (b *Builder) Build(progress ProgressFunc) error {
328328
return fmt.Errorf("failed to build database connections: %w", err)
329329
}
330330

331+
if err := b.buildNavigation(); err != nil {
332+
return fmt.Errorf("failed to build navigation: %w", err)
333+
}
334+
331335
if err := b.buildRoleMappings(); err != nil {
332336
return fmt.Errorf("failed to build role mappings: %w", err)
333337
}

mdl/catalog/builder_navigation.go

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
package catalog
4+
5+
import (
6+
"database/sql"
7+
"fmt"
8+
9+
"github.com/mendixlabs/mxcli/sdk/mpr"
10+
)
11+
12+
func (b *Builder) buildNavigation() error {
13+
nav, err := b.reader.GetNavigation()
14+
if err != nil {
15+
return nil // Navigation may not exist
16+
}
17+
if nav == nil || len(nav.Profiles) == 0 {
18+
return nil
19+
}
20+
21+
profileStmt, err := b.tx.Prepare(`
22+
INSERT INTO navigation_profiles (ProfileName, Kind, IsNative,
23+
HomePage, HomePageType, LoginPage, NotFoundPage,
24+
MenuItemCount, RoleBasedHomeCount, OfflineEntityCount,
25+
ProjectId, ProjectName, SnapshotId, SnapshotDate, SnapshotSource,
26+
SourceId, SourceBranch, SourceRevision)
27+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
28+
`)
29+
if err != nil {
30+
return err
31+
}
32+
defer profileStmt.Close()
33+
34+
menuStmt, err := b.tx.Prepare(`
35+
INSERT INTO navigation_menu_items (ProfileName, ItemPath, Depth, Caption,
36+
ActionType, TargetPage, TargetMicroflow, SubItemCount,
37+
ProjectId, SnapshotId)
38+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
39+
`)
40+
if err != nil {
41+
return err
42+
}
43+
defer menuStmt.Close()
44+
45+
roleHomeStmt, err := b.tx.Prepare(`
46+
INSERT INTO navigation_role_homes (ProfileName, UserRole, Page, Microflow,
47+
ProjectId, SnapshotId)
48+
VALUES (?, ?, ?, ?, ?, ?)
49+
`)
50+
if err != nil {
51+
return err
52+
}
53+
defer roleHomeStmt.Close()
54+
55+
projectID, projectName, snapshotID, snapshotDate, snapshotSource, sourceID, sourceBranch, sourceRevision := b.snapshotMeta()
56+
57+
profileCount := 0
58+
menuCount := 0
59+
roleHomeCount := 0
60+
61+
for _, profile := range nav.Profiles {
62+
// Determine home page info
63+
homePage := ""
64+
homePageType := ""
65+
if profile.HomePage != nil {
66+
if profile.HomePage.Page != "" {
67+
homePage = profile.HomePage.Page
68+
homePageType = "PAGE"
69+
} else if profile.HomePage.Microflow != "" {
70+
homePage = profile.HomePage.Microflow
71+
homePageType = "MICROFLOW"
72+
}
73+
}
74+
75+
// Count menu items recursively
76+
totalMenuItems := countMenuItems(profile.MenuItems)
77+
78+
isNative := 0
79+
if profile.IsNative {
80+
isNative = 1
81+
}
82+
83+
_, err = profileStmt.Exec(
84+
profile.Name,
85+
profile.Kind,
86+
isNative,
87+
homePage,
88+
homePageType,
89+
profile.LoginPage,
90+
profile.NotFoundPage,
91+
totalMenuItems,
92+
len(profile.RoleBasedHomePages),
93+
len(profile.OfflineEntities),
94+
projectID, projectName, snapshotID, snapshotDate, snapshotSource,
95+
sourceID, sourceBranch, sourceRevision,
96+
)
97+
if err != nil {
98+
return err
99+
}
100+
profileCount++
101+
102+
// Insert menu items
103+
menuCount += insertMenuItems(menuStmt, profile.Name, profile.MenuItems, "", 0, projectID, snapshotID)
104+
105+
// Insert role-based home pages
106+
for _, rh := range profile.RoleBasedHomePages {
107+
_, err = roleHomeStmt.Exec(
108+
profile.Name,
109+
rh.UserRole,
110+
rh.Page,
111+
rh.Microflow,
112+
projectID, snapshotID,
113+
)
114+
if err == nil {
115+
roleHomeCount++
116+
}
117+
}
118+
}
119+
120+
b.report("Navigation profiles", profileCount)
121+
if menuCount > 0 {
122+
b.report("Navigation menu items", menuCount)
123+
}
124+
if roleHomeCount > 0 {
125+
b.report("Navigation role homes", roleHomeCount)
126+
}
127+
128+
return nil
129+
}
130+
131+
// countMenuItems recursively counts all menu items.
132+
func countMenuItems(items []*mpr.NavMenuItem) int {
133+
count := len(items)
134+
for _, item := range items {
135+
count += countMenuItems(item.Items)
136+
}
137+
return count
138+
}
139+
140+
// insertMenuItems recursively inserts menu items with hierarchical path encoding.
141+
func insertMenuItems(stmt *sql.Stmt, profileName string, items []*mpr.NavMenuItem, parentPath string, depth int, projectID, snapshotID string) int {
142+
count := 0
143+
for i, item := range items {
144+
itemPath := fmt.Sprintf("%d", i)
145+
if parentPath != "" {
146+
itemPath = parentPath + "." + itemPath
147+
}
148+
149+
_, err := stmt.Exec(
150+
profileName,
151+
itemPath,
152+
depth,
153+
item.Caption,
154+
item.ActionType,
155+
item.Page,
156+
item.Microflow,
157+
len(item.Items),
158+
projectID, snapshotID,
159+
)
160+
if err == nil {
161+
count++
162+
}
163+
164+
if len(item.Items) > 0 {
165+
count += insertMenuItems(stmt, profileName, item.Items, itemPath, depth+1, projectID, snapshotID)
166+
}
167+
}
168+
return count
169+
}

mdl/catalog/tables.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,54 @@ func (c *Catalog) createTables() error {
400400
SourceRevision TEXT
401401
)`,
402402

403+
// Navigation profiles table
404+
`CREATE TABLE IF NOT EXISTS navigation_profiles (
405+
ProfileName TEXT PRIMARY KEY,
406+
Kind TEXT,
407+
IsNative INTEGER DEFAULT 0,
408+
HomePage TEXT,
409+
HomePageType TEXT,
410+
LoginPage TEXT,
411+
NotFoundPage TEXT,
412+
MenuItemCount INTEGER DEFAULT 0,
413+
RoleBasedHomeCount INTEGER DEFAULT 0,
414+
OfflineEntityCount INTEGER DEFAULT 0,
415+
ProjectId TEXT,
416+
ProjectName TEXT,
417+
SnapshotId TEXT,
418+
SnapshotDate TEXT,
419+
SnapshotSource TEXT,
420+
SourceId TEXT,
421+
SourceBranch TEXT,
422+
SourceRevision TEXT
423+
)`,
424+
425+
// Navigation menu items table
426+
`CREATE TABLE IF NOT EXISTS navigation_menu_items (
427+
Id INTEGER PRIMARY KEY AUTOINCREMENT,
428+
ProfileName TEXT NOT NULL,
429+
ItemPath TEXT NOT NULL,
430+
Depth INTEGER DEFAULT 0,
431+
Caption TEXT,
432+
ActionType TEXT,
433+
TargetPage TEXT,
434+
TargetMicroflow TEXT,
435+
SubItemCount INTEGER DEFAULT 0,
436+
ProjectId TEXT,
437+
SnapshotId TEXT
438+
)`,
439+
440+
// Navigation role-based home pages table
441+
`CREATE TABLE IF NOT EXISTS navigation_role_homes (
442+
Id INTEGER PRIMARY KEY AUTOINCREMENT,
443+
ProfileName TEXT NOT NULL,
444+
UserRole TEXT NOT NULL,
445+
Page TEXT,
446+
Microflow TEXT,
447+
ProjectId TEXT,
448+
SnapshotId TEXT
449+
)`,
450+
403451
`CREATE TABLE IF NOT EXISTS database_connections (
404452
Id TEXT PRIMARY KEY,
405453
Name TEXT,
@@ -569,6 +617,11 @@ func (c *Catalog) createTables() error {
569617
`CREATE INDEX IF NOT EXISTS idx_permissions_element ON permissions(ElementType, ElementName)`,
570618
`CREATE INDEX IF NOT EXISTS idx_permissions_access ON permissions(AccessType)`,
571619
`CREATE INDEX IF NOT EXISTS idx_permissions_module ON permissions(ModuleName)`,
620+
`CREATE INDEX IF NOT EXISTS idx_nav_menu_items_profile ON navigation_menu_items(ProfileName)`,
621+
`CREATE INDEX IF NOT EXISTS idx_nav_menu_items_target_page ON navigation_menu_items(TargetPage)`,
622+
`CREATE INDEX IF NOT EXISTS idx_nav_menu_items_target_mf ON navigation_menu_items(TargetMicroflow)`,
623+
`CREATE INDEX IF NOT EXISTS idx_nav_role_homes_profile ON navigation_role_homes(ProfileName)`,
624+
`CREATE INDEX IF NOT EXISTS idx_nav_role_homes_role ON navigation_role_homes(UserRole)`,
572625
}
573626

574627
for _, schema := range schemas {

0 commit comments

Comments
 (0)