Skip to content

Commit 4526cfa

Browse files
committed
Refactor mcp.
1 parent 99addc4 commit 4526cfa

File tree

2 files changed

+13
-73
lines changed

2 files changed

+13
-73
lines changed

gravitee-apim-portal-webui-next/src/app/documentation/components/documentation-folder/documentation-folder.component.html

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
}
2727
</button>
2828
@if (subscribeApiHasMcp()) {
29-
<button mat-stroked-button type="button" (click)="onMcp()" data-testid="mcp-button">
29+
<button mat-stroked-button type="button" (click)="this.mcpDrawerOpen.set(true)" data-testid="mcp-button">
3030
<span i18n="@@documentationMcpButton">MCP</span>
3131
</button>
3232
}
@@ -55,7 +55,7 @@
5555
role="presentation"
5656
tabindex="-1"
5757
@documentationFolderMcpBackdrop
58-
(click)="closeMcpDrawer()"
58+
(click)="this.mcpDrawerOpen.set(false)"
5959
></div>
6060
<div
6161
class="documentation-folder__mcp-panel"
@@ -68,11 +68,7 @@
6868
>
6969
<div class="documentation-folder__mcp-panel__inner">
7070
<div class="documentation-folder__mcp-panel__body">
71-
@if (mcpDrawerLoadError()) {
72-
<div class="m3-body-medium" i18n="@@documentationMcpDrawerLoadError">Could not load MCP tools. Try again.</div>
73-
} @else if (mcpDrawerLoading()) {
74-
<div class="m3-body-medium" i18n="@@documentationMcpDrawerLoading">Loading…</div>
75-
} @else if (mcpDrawerApi(); as apiForTools) {
71+
@if (api.value(); as apiForTools) {
7672
<app-api-tab-tools [api]="apiForTools" />
7773
}
7874
</div>

gravitee-apim-portal-webui-next/src/app/documentation/components/documentation-folder/documentation-folder.component.ts

Lines changed: 10 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
*/
1616
import { animate, style, transition, trigger } from '@angular/animations';
1717
import { AsyncPipe } from '@angular/common';
18-
import { Component, effect, inject, input, signal, untracked } from '@angular/core';
19-
import { toObservable, toSignal } from '@angular/core/rxjs-interop';
18+
import { Component, computed, effect, inject, input, signal, untracked } from '@angular/core';
19+
import { rxResource, toObservable, toSignal } from '@angular/core/rxjs-interop';
2020
import { MatButtonModule } from '@angular/material/button';
2121
import { MatIconModule } from '@angular/material/icon';
2222
import { ActivatedRoute, Router } from '@angular/router';
@@ -89,6 +89,9 @@ const MCP_OVERLAY_DURATION_MS = 400;
8989
],
9090
})
9191
export class DocumentationFolderComponent {
92+
private readonly apiService = inject(ApiService);
93+
readonly currentUser = inject(CurrentUserService).isUserAuthenticated;
94+
9295
navItem = input.required<PortalNavigationItem>();
9396
navId$ = toObservable(this.navItem).pipe(map(({ id }) => id));
9497
selectedId$ = this.activatedRoute.queryParams.pipe(map(({ selectedId }) => selectedId));
@@ -97,51 +100,20 @@ export class DocumentationFolderComponent {
97100
tree = signal<TreeNode[]>([]);
98101
breadcrumbs = signal<Breadcrumb[]>([]);
99102
subscribeApiId = signal<string | null>(null);
100-
readonly currentUser = inject(CurrentUserService).isUserAuthenticated;
101-
private readonly apiService = inject(ApiService);
102-
103-
subscribeApiHasMcp = toSignal(
104-
toObservable(this.subscribeApiId).pipe(
105-
switchMap((id: string | null) =>
106-
id
107-
? this.apiService.details(id).pipe(
108-
map((api: Api) => !!api.mcp),
109-
catchError(() => of(false)),
110-
)
111-
: of(false),
112-
),
113-
),
114-
{ initialValue: false },
115-
);
116103

104+
api = rxResource({
105+
params: this.subscribeApiId,
106+
stream: ({ params }) => params ? this.apiService.details(params).pipe(map(api => api)) : of(undefined),
107+
});
108+
subscribeApiHasMcp = computed(() => !!this.api.value()?.mcp);
117109
mcpDrawerOpen = signal(false);
118-
mcpDrawerApi = signal<Api | undefined>(undefined);
119-
mcpDrawerLoading = signal(false);
120-
mcpDrawerLoadError = signal(false);
121-
122-
private lastSubscribeApiIdWhenMcpContext: string | null = null;
123110

124111
constructor(
125112
private readonly router: Router,
126113
private readonly activatedRoute: ActivatedRoute,
127114
private readonly itemsService: PortalNavigationItemsService,
128115
private readonly treeService: TreeService,
129116
) {
130-
effect(() => {
131-
const id = this.subscribeApiId();
132-
if (
133-
this.mcpDrawerOpen() &&
134-
this.lastSubscribeApiIdWhenMcpContext !== null &&
135-
id !== this.lastSubscribeApiIdWhenMcpContext
136-
) {
137-
untracked(() => {
138-
this.mcpDrawerOpen.set(false);
139-
this.mcpDrawerApi.set(undefined);
140-
this.mcpDrawerLoadError.set(false);
141-
});
142-
}
143-
this.lastSubscribeApiIdWhenMcpContext = id;
144-
});
145117
}
146118

147119
onSelect(selectedPageId: string) {
@@ -158,34 +130,6 @@ export class DocumentationFolderComponent {
158130
}
159131
}
160132

161-
onMcp() {
162-
const apiId = this.subscribeApiId();
163-
if (!apiId) {
164-
return;
165-
}
166-
this.mcpDrawerOpen.set(true);
167-
if (this.mcpDrawerApi()?.id === apiId) {
168-
return;
169-
}
170-
this.mcpDrawerLoading.set(true);
171-
this.mcpDrawerLoadError.set(false);
172-
this.apiService
173-
.details(apiId)
174-
.pipe(
175-
take(1),
176-
finalize(() => this.mcpDrawerLoading.set(false)),
177-
)
178-
.subscribe({
179-
next: (api: Api) => this.mcpDrawerApi.set(api),
180-
error: () => this.mcpDrawerLoadError.set(true),
181-
});
182-
}
183-
184-
closeMcpDrawer() {
185-
this.mcpDrawerOpen.set(false);
186-
this.mcpDrawerLoadError.set(false);
187-
}
188-
189133
private loadFolderData(): Observable<FolderData | undefined> {
190134
return merge(this.navId$.pipe(map(() => NavParamsChange.NAV_ID)), this.selectedId$.pipe(map(() => NavParamsChange.PAGE_ID))).pipe(
191135
debounceTime(0), // merge simultaneous change of navId and selectedId

0 commit comments

Comments
 (0)