-<ng-container
- *ngIf="{
+@if (
+ {
ftMap: featureToggleMap$ | async,
daemons: rgwDaemonService.daemons$ | async,
selectedDaemon: rgwDaemonService.selectedDaemon$ | async
- } as data"
->
- <ng-container
- *ngIf="
- data.ftMap && data.ftMap.rgw && permissions.rgw.read && isRgwRoute && data.daemons.length > 1
- "
- >
- <div class="cd-context-bar pt-3 pb-3">
+ };
+ as data
+) {
+ @if (
+ data.ftMap && data.ftMap.rgw && permissions.rgw.read && isRgwRoute && data.daemons.length > 1
+ ) {
+ <div
+ class="cd-context-bar cds-pt-5 cds-pb-5"
+ [class.cds-pl-5]="isRgwResourcePage"
+ >
<span
- class="me-1"
+ class="cds-mr-2"
i18n
>Object gateway:</span
>
- <div
- ngbDropdown
- placement="bottom-left"
- class="d-inline-block ms-2"
- >
+
+ @if (!isRgwResourcePage) {
+ <div
+ ngbDropdown
+ placement="bottom-left"
+ class="cds-ml-3"
+ style="display: inline-block"
+ >
+ <button
+ ngbDropdownToggle
+ class="btn btn-outline-info ctx-bar-selected-rgw-daemon"
+ i18n-title
+ title="Object gateway"
+ type="button"
+ >
+ {{ data.selectedDaemon.id }}
+ <cds-tag
+ type="blue"
+ size="sm"
+ >{{ data.selectedDaemon.zonegroup_name }}</cds-tag
+ >
+ </button>
+ <div ngbDropdownMenu>
+ @for (daemon of data.daemons; track daemon.id) {
+ <button
+ ngbDropdownItem
+ class="ctx-bar-available-rgw-daemon"
+ (click)="onDaemonSelection(daemon)"
+ type="button"
+ >
+ {{ daemon.id }}
+ <cds-tag
+ type="blue"
+ size="sm"
+ >{{ daemon.zonegroup_name }}</cds-tag
+ >
+ </button>
+ }
+ </div>
+ </div>
+ } @else {
<button
- ngbDropdownToggle
class="btn btn-outline-info ctx-bar-selected-rgw-daemon"
i18n-title
title="Object gateway"
type="button"
+ disabled
>
{{ data.selectedDaemon.id }}
<cds-tag
>{{ data.selectedDaemon.zonegroup_name }}</cds-tag
>
</button>
- <div ngbDropdownMenu>
- <ng-container *ngFor="let daemon of data.daemons">
- <button
- ngbDropdownItem
- class="ctx-bar-available-rgw-daemon"
- (click)="onDaemonSelection(daemon)"
- type="button"
- >
- {{ daemon.id }}
- <cds-tag
- type="blue"
- size="sm"
- >{{ daemon.zonegroup_name }}</cds-tag
- >
- </button>
- </ng-container>
- </div>
- </div>
+ }
</div>
- </ng-container>
-</ng-container>
+ }
+}
expect(selectedDaemon.textContent).toEqual(' daemon3 zonegroup3');
component.ngOnDestroy();
}));
+
+ it('should show a read-only selected daemon on RGW resource page', fakeAsync(() => {
+ component.isRgwRoute = true;
+ component.isRgwResourcePage = true;
+ fixture.detectChanges();
+ tick();
+ const req = httpTesting.expectOne('api/rgw/daemon');
+ req.flush(daemonList);
+ fixture.detectChanges();
+
+ const selectedDaemon = fixture.debugElement.nativeElement.querySelector(
+ '.ctx-bar-selected-rgw-daemon'
+ );
+ const availableDaemons = fixture.debugElement.nativeElement.querySelectorAll(
+ '.ctx-bar-available-rgw-daemon'
+ );
+
+ expect(selectedDaemon.disabled).toBe(true);
+ expect(availableDaemons.length).toEqual(0);
+ component.ngOnDestroy();
+ }));
+
+ it('should detect a RGW resource page from a hash route on reload', () => {
+ expect(component['getRoutePath']('http://localhost/#/rgw/accounts/test-account/overview')).toBe(
+ '/rgw/accounts/test-account/overview'
+ );
+ expect(
+ component['isRgwAccountsResourcePage'](
+ component['getRoutePath']('http://localhost/#/rgw/accounts/test-account/overview')
+ )
+ ).toBe(true);
+ });
});
private rgwUserUrlPrefix = '/rgw/user';
private rgwBuckerUrlPrefix = '/rgw/bucket';
private rgwAccountsUrlPrefix = '/rgw/accounts';
+ private rgwAccountsResourcePagePattern = /^\/rgw\/accounts\/[^/]+\/(overview|roles)(?:$|[?#])/;
private rgwMultisiteSyncPolicyPrefix = '/rgw/multisite/sync-policy';
permissions: Permissions;
featureToggleMap$: FeatureTogglesMap$;
+ isRgwResourcePage = this.isRgwAccountsResourcePage(this.getRoutePath(document.location.href));
isRgwRoute =
document.location.href.includes(this.rgwUserUrlPrefix) ||
document.location.href.includes(this.rgwBuckerUrlPrefix) ||
this.subs.add(
this.router.events
.pipe(filter((event: Event) => event instanceof NavigationEnd))
- .subscribe(
- () =>
- (this.isRgwRoute = [
- this.rgwBuckerUrlPrefix,
- this.rgwUserUrlPrefix,
- this.rgwAccountsUrlPrefix,
- this.rgwMultisiteSyncPolicyPrefix
- ].some((urlPrefix) => this.router.url.startsWith(urlPrefix)))
- )
+ .subscribe(() => {
+ const currentRoute = this.getRoutePath(this.router.url);
+ this.isRgwRoute = [
+ this.rgwBuckerUrlPrefix,
+ this.rgwUserUrlPrefix,
+ this.rgwAccountsUrlPrefix,
+ this.rgwMultisiteSyncPolicyPrefix
+ ].some((urlPrefix) => this.router.url.startsWith(urlPrefix));
+ this.isRgwResourcePage = this.isRgwAccountsResourcePage(currentRoute);
+ })
);
// Set daemon list polling only when in RGW route:
this.subs.add(
this.router.navigate([currentUrl]);
});
}
+
+ private isRgwAccountsResourcePage(url: string): boolean {
+ return this.rgwAccountsResourcePagePattern.test(url);
+ }
+
+ private getRoutePath(url: string): string {
+ const hashIndex = url.indexOf('#');
+ return hashIndex === -1 ? url : url.slice(hashIndex + 1);
+ }
}
padding-left: layout.$spacing-06;
}
+.cds-pl-5 {
+ padding-left: layout.$spacing-05;
+}
+
.cds-pl-4 {
padding-left: layout.$spacing-04;
}
padding-top: layout.$spacing-05;
}
+.cds-pb-5 {
+ padding-bottom: layout.$spacing-05;
+}
+
.cds-pr-4 {
padding-right: layout.$spacing-04;
}