fix(web-app): update dashboard navigation to use the router directly and refresh admin tabs on login changes

This commit is contained in:
2026-03-20 16:44:44 +00:00
parent aacf30e582
commit b9a3d79b5f
5 changed files with 19 additions and 16 deletions

View File

@@ -1,5 +1,12 @@
# Changelog
## 2026-03-20 - 1.5.1 - fix(web-app)
update dashboard navigation to use the router directly and refresh admin tabs on login changes
- removes the global router workaround in the dashboard and imports appRouter directly
- re-filters resolved view tabs when login state changes so the Admin tab matches system admin access
- adds dashboard navigation support for the organizations view
## 2026-03-20 - 1.5.0 - feat(opsserver,web)
replace the Angular UI and REST management layer with a TypedRequest-based ops server and bundled web frontend

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@stack.gallery/registry',
version: '1.5.0',
version: '1.5.1',
description: 'Enterprise-grade multi-protocol package registry'
}

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@stack.gallery/registry',
version: '1.5.0',
version: '1.5.1',
description: 'Enterprise-grade multi-protocol package registry'
}

View File

@@ -72,19 +72,23 @@ export class SgAppShell extends DeesElement {
},
];
private allResolvedViewTabs: Array<{ name: string; iconName?: string; element: any }> = [];
private resolvedViewTabs: Array<{ name: string; iconName?: string; element: any }> = [];
constructor() {
super();
document.title = 'Stack.Gallery Registry';
// Make appRouter globally accessible for view elements
(globalThis as any).__sgAppRouter = appRouter;
const loginSubscription = appstate.loginStatePart
.select((s) => s)
.subscribe((loginState) => {
this.loginState = loginState;
// Re-filter tabs when login state changes
if (loginState.isLoggedIn && this.allResolvedViewTabs.length > 0) {
this.resolvedViewTabs = loginState.identity?.isSystemAdmin
? this.allResolvedViewTabs
: this.allResolvedViewTabs.filter((t) => t.name !== 'Admin');
}
});
this.rxSubscriptions.push(loginSubscription);

View File

@@ -1,5 +1,6 @@
import * as appstate from '../appstate.js';
import * as shared from './shared/index.js';
import { appRouter } from '../router.js';
import {
css,
cssManager,
@@ -77,24 +78,15 @@ export class SgViewDashboard extends DeesElement {
private handleNavigate(e: CustomEvent) {
const { type, id } = e.detail;
if (type === 'org' && id) {
const { appRouter } = await_import_router();
appRouter.navigateToEntity('organizations', id);
} else if (type === 'package' && id) {
const { appRouter } = await_import_router();
appRouter.navigateToEntity('packages', id);
} else if (type === 'packages') {
const { appRouter } = await_import_router();
appRouter.navigateToView('packages');
} else if (type === 'tokens') {
const { appRouter } = await_import_router();
appRouter.navigateToView('tokens');
} else if (type === 'organizations') {
appRouter.navigateToView('organizations');
}
}
}
// Lazy import to avoid circular dependency
function await_import_router() {
// Dynamic import not needed here since router is a separate module
// We use a workaround by importing at the module level
return { appRouter: (globalThis as any).__sgAppRouter };
}