fix(frontend): add navigation context for cross-view linking and fix double-load bug
Projects "View Secrets"/"View Pipelines" and Groups "View Secrets" now pass connection/scope/entity context so the target view opens with filters pre-filled. Fixed double-load bug where dees-simple-appdash's view-select event re-dispatched setActiveViewAction without context.
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -34,10 +34,18 @@ export interface IActionLogState {
|
|||||||
total: number;
|
total: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface INavigationContext {
|
||||||
|
connectionId?: string;
|
||||||
|
scope?: 'project' | 'group';
|
||||||
|
scopeId?: string;
|
||||||
|
projectId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IUiState {
|
export interface IUiState {
|
||||||
activeView: string;
|
activeView: string;
|
||||||
autoRefresh: boolean;
|
autoRefresh: boolean;
|
||||||
refreshInterval: number;
|
refreshInterval: number;
|
||||||
|
navigationContext?: INavigationContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -664,9 +672,22 @@ export const fetchActionLogAction = actionLogStatePart.createAction<{
|
|||||||
// UI Actions
|
// UI Actions
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
export const setActiveViewAction = uiStatePart.createAction<{ view: string }>(
|
export const setActiveViewAction = uiStatePart.createAction<{
|
||||||
|
view: string;
|
||||||
|
navigationContext?: INavigationContext;
|
||||||
|
}>(
|
||||||
async (statePartArg, dataArg) => {
|
async (statePartArg, dataArg) => {
|
||||||
return { ...statePartArg.getState(), activeView: dataArg.view };
|
return {
|
||||||
|
...statePartArg.getState(),
|
||||||
|
activeView: dataArg.view,
|
||||||
|
navigationContext: dataArg.navigationContext,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const clearNavigationContextAction = uiStatePart.createAction(
|
||||||
|
async (statePartArg) => {
|
||||||
|
return { ...statePartArg.getState(), navigationContext: undefined };
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -174,6 +174,7 @@ export class GitopsDashboard extends DeesElement {
|
|||||||
if (appDash) {
|
if (appDash) {
|
||||||
appDash.addEventListener('view-select', (e: CustomEvent) => {
|
appDash.addEventListener('view-select', (e: CustomEvent) => {
|
||||||
const viewName = e.detail.view.name.toLowerCase();
|
const viewName = e.detail.view.name.toLowerCase();
|
||||||
|
if (this.uiState.activeView === viewName) return;
|
||||||
appstate.uiStatePart.dispatchAction(appstate.setActiveViewAction, { view: viewName });
|
appstate.uiStatePart.dispatchAction(appstate.setActiveViewAction, { view: viewName });
|
||||||
});
|
});
|
||||||
appDash.addEventListener('logout', async () => {
|
appDash.addEventListener('logout', async () => {
|
||||||
@@ -338,6 +339,7 @@ export class GitopsDashboard extends DeesElement {
|
|||||||
if (!appDash || this.resolvedViewTabs.length === 0) return;
|
if (!appDash || this.resolvedViewTabs.length === 0) return;
|
||||||
const targetTab = this.resolvedViewTabs.find((t) => t.name.toLowerCase() === viewName);
|
const targetTab = this.resolvedViewTabs.find((t) => t.name.toLowerCase() === viewName);
|
||||||
if (!targetTab) return;
|
if (!targetTab) return;
|
||||||
|
if (appDash.selectedView === targetTab) return;
|
||||||
appDash.loadView(targetTab);
|
appDash.loadView(targetTab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,14 @@ export class GitopsViewGroups extends DeesElement {
|
|||||||
iconName: 'lucide:key',
|
iconName: 'lucide:key',
|
||||||
type: ['inRow', 'contextmenu'],
|
type: ['inRow', 'contextmenu'],
|
||||||
actionFunc: async ({ item }: any) => {
|
actionFunc: async ({ item }: any) => {
|
||||||
appstate.uiStatePart.dispatchAction(appstate.setActiveViewAction, { view: 'secrets' });
|
appstate.uiStatePart.dispatchAction(appstate.setActiveViewAction, {
|
||||||
|
view: 'secrets',
|
||||||
|
navigationContext: {
|
||||||
|
connectionId: this.selectedConnectionId,
|
||||||
|
scope: 'group',
|
||||||
|
scopeId: item.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
|||||||
@@ -167,6 +167,18 @@ export class GitopsViewPipelines extends DeesElement {
|
|||||||
|
|
||||||
async firstUpdated() {
|
async firstUpdated() {
|
||||||
await appstate.connectionsStatePart.dispatchAction(appstate.fetchConnectionsAction, null);
|
await appstate.connectionsStatePart.dispatchAction(appstate.fetchConnectionsAction, null);
|
||||||
|
|
||||||
|
// Check for navigation context from projects view
|
||||||
|
const navCtx = appstate.uiStatePart.getState().navigationContext;
|
||||||
|
if (navCtx?.connectionId && navCtx?.projectId) {
|
||||||
|
this.selectedConnectionId = navCtx.connectionId;
|
||||||
|
this.selectedProjectId = navCtx.projectId;
|
||||||
|
appstate.uiStatePart.dispatchAction(appstate.clearNavigationContextAction, null);
|
||||||
|
await this.loadProjects();
|
||||||
|
await this.loadPipelines();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const conns = appstate.connectionsStatePart.getState().connections;
|
const conns = appstate.connectionsStatePart.getState().connections;
|
||||||
if (conns.length > 0 && !this.selectedConnectionId) {
|
if (conns.length > 0 && !this.selectedConnectionId) {
|
||||||
this.selectedConnectionId = conns[0].id;
|
this.selectedConnectionId = conns[0].id;
|
||||||
|
|||||||
@@ -102,7 +102,14 @@ export class GitopsViewProjects extends DeesElement {
|
|||||||
iconName: 'lucide:key',
|
iconName: 'lucide:key',
|
||||||
type: ['inRow', 'contextmenu'],
|
type: ['inRow', 'contextmenu'],
|
||||||
actionFunc: async ({ item }: any) => {
|
actionFunc: async ({ item }: any) => {
|
||||||
appstate.uiStatePart.dispatchAction(appstate.setActiveViewAction, { view: 'secrets' });
|
appstate.uiStatePart.dispatchAction(appstate.setActiveViewAction, {
|
||||||
|
view: 'secrets',
|
||||||
|
navigationContext: {
|
||||||
|
connectionId: this.selectedConnectionId,
|
||||||
|
scope: 'project',
|
||||||
|
scopeId: item.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -110,7 +117,13 @@ export class GitopsViewProjects extends DeesElement {
|
|||||||
iconName: 'lucide:play',
|
iconName: 'lucide:play',
|
||||||
type: ['inRow', 'contextmenu'],
|
type: ['inRow', 'contextmenu'],
|
||||||
actionFunc: async ({ item }: any) => {
|
actionFunc: async ({ item }: any) => {
|
||||||
appstate.uiStatePart.dispatchAction(appstate.setActiveViewAction, { view: 'pipelines' });
|
appstate.uiStatePart.dispatchAction(appstate.setActiveViewAction, {
|
||||||
|
view: 'pipelines',
|
||||||
|
navigationContext: {
|
||||||
|
connectionId: this.selectedConnectionId,
|
||||||
|
projectId: item.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
|||||||
@@ -201,6 +201,19 @@ export class GitopsViewSecrets extends DeesElement {
|
|||||||
|
|
||||||
async firstUpdated() {
|
async firstUpdated() {
|
||||||
await appstate.connectionsStatePart.dispatchAction(appstate.fetchConnectionsAction, null);
|
await appstate.connectionsStatePart.dispatchAction(appstate.fetchConnectionsAction, null);
|
||||||
|
|
||||||
|
// Check for navigation context from projects/groups view
|
||||||
|
const navCtx = appstate.uiStatePart.getState().navigationContext;
|
||||||
|
if (navCtx?.connectionId && navCtx?.scope && navCtx?.scopeId) {
|
||||||
|
this.selectedConnectionId = navCtx.connectionId;
|
||||||
|
this.selectedScope = navCtx.scope;
|
||||||
|
this.selectedScopeId = navCtx.scopeId;
|
||||||
|
appstate.uiStatePart.dispatchAction(appstate.clearNavigationContextAction, null);
|
||||||
|
await this.loadEntities();
|
||||||
|
await this.loadSecrets();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const conns = appstate.connectionsStatePart.getState().connections;
|
const conns = appstate.connectionsStatePart.getState().connections;
|
||||||
if (conns.length > 0 && !this.selectedConnectionId) {
|
if (conns.length > 0 && !this.selectedConnectionId) {
|
||||||
this.selectedConnectionId = conns[0].id;
|
this.selectedConnectionId = conns[0].id;
|
||||||
|
|||||||
Reference in New Issue
Block a user