Skip to content

Commit ea37475

Browse files
Merge pull request #3376 from hujambo-dunia/instances-routing-structure
Enhancements to Galaxy server instances on Use Page
2 parents 5d1de6d + 92426d1 commit ea37475

File tree

3 files changed

+648
-46
lines changed

3 files changed

+648
-46
lines changed

src/composables/useTableRouting.js

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
export function useTableRouting() {
2+
/**
3+
* Convert tab id to URL-friendly slug
4+
* @param {Object} tab - Tab object with id property
5+
* @returns {string} URL-friendly slug
6+
*/
7+
const getTabSlug = (tab) => {
8+
if (!tab || !tab.id) return "";
9+
10+
const slugMap = {
11+
usegalaxy: "usegalaxy",
12+
all: "all",
13+
"public-server": "public-servers",
14+
"academic-cloud": "academic-clouds",
15+
"commercial-cloud": "commercial-clouds",
16+
containers: "containers",
17+
vms: "vms",
18+
};
19+
20+
return slugMap[tab.id] || tab.id.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
21+
};
22+
23+
/**
24+
* Find tab object from URL slug
25+
* @param {Array} tabs - Array of tab objects
26+
* @param {string} slug - URL slug to match
27+
* @returns {Object|null} Matching tab object or null
28+
*/
29+
const getTabFromSlug = (tabs, slug) => {
30+
if (!slug || !tabs) return null;
31+
return tabs.find((tab) => getTabSlug(tab) === slug);
32+
};
33+
34+
/**
35+
* Get active tab index based on URL query parameter
36+
* @param {Array} tabs - Array of tab objects
37+
* @param {Object} route - Vue router route object
38+
* @returns {number} Active tab index (0-based)
39+
*/
40+
const getActiveTabIndex = (tabs, route) => {
41+
if (!route || !route.query) {
42+
return 0;
43+
}
44+
45+
const platformGroup = route.query.platform_group;
46+
47+
if (!platformGroup || !tabs || !Array.isArray(tabs)) {
48+
return 0;
49+
}
50+
51+
const tabIndex = tabs.findIndex((tab) => {
52+
const slug = getTabSlug(tab);
53+
return slug === platformGroup;
54+
});
55+
56+
return tabIndex >= 0 ? tabIndex : 0;
57+
};
58+
59+
/**
60+
* Update URL with new tab selection
61+
* @param {Object} router - Vue router instance
62+
* @param {Object} route - Current route object
63+
* @param {Object} tab - Selected tab object
64+
* @returns {void}
65+
*/
66+
const updateUrlForTab = (router, route, tab) => {
67+
if (!router || !tab) return;
68+
69+
const slug = getTabSlug(tab);
70+
const newQuery = { ...route.query };
71+
72+
if (slug) {
73+
newQuery.platform_group = slug;
74+
} else {
75+
delete newQuery.platform_group;
76+
}
77+
78+
// Update URL without page refresh, ignore navigation duplicated errors
79+
router.push({ query: newQuery }).catch((err) => {
80+
if (err.name !== "NavigationDuplicated") {
81+
console.warn("Navigation error:", err);
82+
}
83+
});
84+
};
85+
86+
/**
87+
* Initialize tab from URL query parameters and return reactive state manager
88+
* @param {Array} tabs - Array of tab objects
89+
* @param {Object} route - Current route object
90+
* @param {Object} router - Vue router instance
91+
* @returns {Object} Tab state manager with reactive activeTabIndex
92+
*/
93+
const createTabStateManager = (tabs, route, router) => {
94+
let activeTabIndex = getActiveTabIndex(tabs, route);
95+
96+
return {
97+
get activeTabIndex() {
98+
return activeTabIndex;
99+
},
100+
101+
set activeTabIndex(value) {
102+
activeTabIndex = value;
103+
},
104+
105+
onTabChange(newTabIndex) {
106+
activeTabIndex = newTabIndex;
107+
const tab = tabs[newTabIndex];
108+
updateUrlForTab(router, route, tab);
109+
},
110+
111+
initializeFromUrl() {
112+
const platformGroup = route.query.platform_group;
113+
114+
if (platformGroup) {
115+
const tabIndex = tabs.findIndex((tab) => getTabSlug(tab) === platformGroup);
116+
117+
if (tabIndex >= 0) {
118+
activeTabIndex = tabIndex;
119+
return true;
120+
}
121+
}
122+
123+
// Default to first tab if no match or no platform_group
124+
activeTabIndex = 0;
125+
return false;
126+
},
127+
128+
handleRouteChange(newPlatformType, oldPlatformType) {
129+
if (newPlatformType !== oldPlatformType) {
130+
this.initializeFromUrl();
131+
}
132+
},
133+
};
134+
};
135+
136+
/**
137+
* Initialize tab state from URL query parameters (legacy method for backwards compatibility)
138+
* @param {Array} tabs - Array of tab objects
139+
* @param {Object} route - Current route object
140+
* @returns {Object|null} Initial tab object or null
141+
*/
142+
const initializeFromUrl = (tabs, route) => {
143+
const platformGroup = route.query.platform_group;
144+
if (platformGroup && tabs) {
145+
const tab = getTabFromSlug(tabs, platformGroup);
146+
if (tab) {
147+
return tab;
148+
}
149+
}
150+
return null;
151+
};
152+
153+
return {
154+
getTabSlug,
155+
getTabFromSlug,
156+
getActiveTabIndex,
157+
updateUrlForTab,
158+
initializeFromUrl,
159+
createTabStateManager,
160+
};
161+
}

0 commit comments

Comments
 (0)