diff options
Diffstat (limited to 'src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about')
4 files changed, 220 insertions, 0 deletions
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.html new file mode 100644 index 000000000..fdf4d95cf --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.html @@ -0,0 +1,47 @@ +<div class="about-container"> + <div class="modal-header"> + <button type="button" + class="close float-right" + aria-label="Close" + (click)="activeModal.close()"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body"> + <img src="assets/Ceph_Ceph_Logo_with_text_red_white.svg" + class="ceph-logo" + alt="{{ projectConstants.organization }}"> + <h3> + <strong>{{ projectConstants.projectName }}</strong> + </h3> + <div class="product-versions"> + <strong>Version</strong> + <br> + {{ versionNumber }} + {{ versionHash }} + <br> + {{ versionName }} + </div> + <br> + <dl> + <dt>Ceph Manager</dt> + <dd>{{ hostAddr }}</dd> + <dt>User</dt> + <dd>{{ modalVariables.user }}</dd> + <dt>User Role</dt> + <dd>{{ modalVariables.role }}</dd> + <dt>Browser</dt> + <dd>{{ modalVariables.browserName }}</dd> + <dt>Browser Version</dt> + <dd>{{ modalVariables.browserVersion }}</dd> + <dt>Browser OS</dt> + <dd>{{ modalVariables.browserOS }}</dd> + </dl> + </div> + <div class="modal-footer"> + <div class="text-left"> + {{ projectConstants.copyright }} + {{ projectConstants.license }} + </div> + </div> +</div> diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.scss new file mode 100644 index 000000000..78c7fe550 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.scss @@ -0,0 +1,43 @@ +@use './src/styles/vendor/variables' as vv; + +.about-container { + background-color: vv.$secondary; + background-image: url('../../../../assets/ceph_background.gif'); + background-position: right bottom; + background-repeat: no-repeat; + color: vv.$white; + text-shadow: 1px 1px vv.$secondary; +} + +.product-versions { + margin-top: 30px; +} + +.product-versions strong { + margin-right: 10px; +} + +.modal-header { + border-bottom: 0; +} + +.modal-header .close { + color: vv.$white; + font-size: 2em; +} + +.modal-body { + padding-left: 80px; + padding-right: 80px; +} + +.ceph-logo { + margin-bottom: 30px; + width: 25%; +} + +.modal-footer { + border-top: 0; + display: block; + padding: 15px 80px 35px; +} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.spec.ts new file mode 100644 index 000000000..74ca78434 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.spec.ts @@ -0,0 +1,60 @@ +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; +import { BehaviorSubject } from 'rxjs'; + +import { SummaryService } from '~/app/shared/services/summary.service'; +import { SharedModule } from '~/app/shared/shared.module'; +import { environment } from '~/environments/environment'; +import { configureTestBed } from '~/testing/unit-test-helper'; +import { AboutComponent } from './about.component'; + +export class SummaryServiceMock { + summaryDataSource = new BehaviorSubject({ + version: + 'ceph version 14.0.0-855-gb8193bb4cd ' + + '(b8193bb4cda16ccc5b028c3e1df62bc72350a15d) nautilus (dev)', + mgr_host: 'http://localhost:11000/' + }); + summaryData$ = this.summaryDataSource.asObservable(); + + subscribe(call: any) { + return this.summaryData$.subscribe(call); + } +} + +describe('AboutComponent', () => { + let component: AboutComponent; + let fixture: ComponentFixture<AboutComponent>; + + configureTestBed({ + imports: [SharedModule, HttpClientTestingModule], + declarations: [AboutComponent], + providers: [NgbActiveModal, { provide: SummaryService, useClass: SummaryServiceMock }] + }); + + beforeEach(() => { + fixture = TestBed.createComponent(AboutComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should parse version', () => { + expect(component.versionNumber).toBe('14.0.0-855-gb8193bb4cd'); + expect(component.versionHash).toBe('(b8193bb4cda16ccc5b028c3e1df62bc72350a15d)'); + expect(component.versionName).toBe('nautilus (dev)'); + }); + + it('should get host', () => { + expect(component.hostAddr).toBe('localhost:11000'); + }); + + it('should display copyright', () => { + expect(component.projectConstants.copyright).toContain(environment.year); + }); +}); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.ts new file mode 100644 index 000000000..64b26bfc6 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.ts @@ -0,0 +1,70 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; + +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; +import { detect } from 'detect-browser'; +import { Subscription } from 'rxjs'; + +import { UserService } from '~/app/shared/api/user.service'; +import { AppConstants } from '~/app/shared/constants/app.constants'; +import { Permission } from '~/app/shared/models/permissions'; +import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; +import { SummaryService } from '~/app/shared/services/summary.service'; + +@Component({ + selector: 'cd-about', + templateUrl: './about.component.html', + styleUrls: ['./about.component.scss'] +}) +export class AboutComponent implements OnInit, OnDestroy { + modalVariables: any; + versionNumber: string; + versionHash: string; + versionName: string; + subs: Subscription; + userPermission: Permission; + projectConstants: typeof AppConstants; + hostAddr: string; + copyright: string; + + constructor( + public activeModal: NgbActiveModal, + private summaryService: SummaryService, + private userService: UserService, + private authStorageService: AuthStorageService + ) { + this.userPermission = this.authStorageService.getPermissions().user; + } + + ngOnInit() { + this.projectConstants = AppConstants; + this.hostAddr = window.location.hostname; + this.modalVariables = this.setVariables(); + this.subs = this.summaryService.subscribe((summary) => { + const version = summary.version.replace('ceph version ', '').split(' '); + this.hostAddr = summary.mgr_host.replace(/(^\w+:|^)\/\//, '').replace(/\/$/, ''); + this.versionNumber = version[0]; + this.versionHash = version[1]; + this.versionName = version.slice(2, version.length).join(' '); + }); + } + + ngOnDestroy(): void { + this.subs.unsubscribe(); + } + + setVariables() { + const project = {} as any; + project.user = localStorage.getItem('dashboard_username'); + project.role = 'user'; + if (this.userPermission.read) { + this.userService.get(project.user).subscribe((data: any) => { + project.role = data.roles; + }); + } + const browser = detect(); + project.browserName = browser && browser.name ? browser.name : 'Not detected'; + project.browserVersion = browser && browser.version ? browser.version : 'Not detected'; + project.browserOS = browser && browser.os ? browser.os : 'Not detected'; + return project; + } +} |