From 6aecf4214941dce197185f862a4636db93211012 Mon Sep 17 00:00:00 2001 From: Tiago Melo Date: Thu, 30 Jul 2020 20:31:13 +0000 Subject: [PATCH] mgr/dashboard: Extract documentation link to a component Fixes: https://tracker.ceph.com/issues/36565 Fixes: https://tracker.ceph.com/issues/43375 Signed-off-by: Tiago Melo (cherry picked from commit e12702a6c71d2050fe3f3991173a60332c5d583a) Conflicts: src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.ts src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-list-helper.ts src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-501/nfs-501.component.ts src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.html src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.ts src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.spec.ts src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.ts src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/monitoring-list/monitoring-list.component.html src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/monitoring-list/monitoring-list.component.ts src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.ts src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.spec.ts --- .../iscsi-target-list.component.html | 5 +- .../iscsi-target-list.component.ts | 11 +-- .../cluster/inventory/inventory.component.ts | 1 - .../osd/osd-form/osd-form.component.ts | 1 - .../monitoring-list.component.html | 21 +++--- .../monitoring-list.component.ts | 13 +--- .../cluster/services/services.component.ts | 1 - .../ceph/nfs/nfs-501/nfs-501.component.html | 5 +- .../app/ceph/nfs/nfs-501/nfs-501.component.ts | 18 +---- .../ceph/nfs/nfs-form/nfs-form.component.html | 5 +- .../ceph/nfs/nfs-form/nfs-form.component.ts | 10 --- .../pool/pool-form/pool-form.component.html | 6 +- .../ceph/rgw/rgw-501/rgw-501.component.html | 5 +- .../app/ceph/rgw/rgw-501/rgw-501.component.ts | 17 +---- .../dashboard-help.component.html | 6 +- .../dashboard-help.component.ts | 13 ++-- .../shared/components/components.module.ts | 7 +- .../shared/components/doc/doc.component.html | 2 + .../shared/components/doc/doc.component.scss | 0 .../components/doc/doc.component.spec.ts | 27 ++++++++ .../shared/components/doc/doc.component.ts | 25 +++++++ .../components/grafana/grafana.component.html | 10 +-- .../grafana/grafana.component.spec.ts | 3 +- .../components/grafana/grafana.component.ts | 13 ---- .../orchestrator-doc-panel.component.html | 7 +- .../orchestrator-doc-panel.component.ts | 21 +----- .../app/shared/services/doc.service.spec.ts | 69 +++++++++++++++++++ .../src/app/shared/services/doc.service.ts | 57 +++++++++++++++ 28 files changed, 227 insertions(+), 152 deletions(-) create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.ts diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html index 276629cd413b2..0103c11249a1b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html @@ -4,9 +4,8 @@ *ngIf="available === false" title="iSCSI Targets not available" i18n-title> - Please consult the documentation - on how to configure and enable the iSCSI Targets management functionality. + Please consult the on + how to configure and enable the iSCSI Targets management functionality.
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts index 07976f2c2195e..fb49691f8fd80 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts @@ -18,10 +18,8 @@ import { CdTableSelection } from '../../../shared/models/cd-table-selection'; import { FinishedTask } from '../../../shared/models/finished-task'; import { Permission } from '../../../shared/models/permissions'; import { Task } from '../../../shared/models/task'; -import { CephReleaseNamePipe } from '../../../shared/pipes/ceph-release-name.pipe'; import { NotAvailablePipe } from '../../../shared/pipes/not-available.pipe'; import { AuthStorageService } from '../../../shared/services/auth-storage.service'; -import { SummaryService } from '../../../shared/services/summary.service'; import { TaskListService } from '../../../shared/services/task-list.service'; import { TaskWrapperService } from '../../../shared/services/task-wrapper.service'; import { IscsiTargetDiscoveryModalComponent } from '../iscsi-target-discovery-modal/iscsi-target-discovery-modal.component'; @@ -38,7 +36,6 @@ export class IscsiTargetListComponent extends ListWithDetails implements OnInit, available: boolean = undefined; columns: CdTableColumn[]; - docsUrl: string; modalRef: BsModalRef; permission: Permission; selection = new CdTableSelection(); @@ -63,9 +60,7 @@ export class IscsiTargetListComponent extends ListWithDetails implements OnInit, private i18n: I18n, private iscsiService: IscsiService, private taskListService: TaskListService, - private cephReleaseNamePipe: CephReleaseNamePipe, private notAvailablePipe: NotAvailablePipe, - private summaryservice: SummaryService, private modalService: BsModalService, private taskWrapper: TaskWrapperService, public actionLabels: ActionLabelsI18n @@ -146,11 +141,7 @@ export class IscsiTargetListComponent extends ListWithDetails implements OnInit, this.settings = settings; }); } else { - this.summaryservice.subscribeOnce((summary) => { - const releaseName = this.cephReleaseNamePipe.transform(summary.version); - this.docsUrl = `http://docs.ceph.com/docs/${releaseName}/mgr/dashboard/#enabling-iscsi-management`; - this.status = result.message; - }); + this.status = result.message; } }); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.ts index a529924d93e53..da0f1a541a140 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory.component.ts @@ -16,7 +16,6 @@ export class InventoryComponent implements OnChanges, OnInit { icons = Icons; hasOrchestrator = false; - docsUrl: string; devices: Array = []; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.ts index a4eddc43a263e..b38e540ddf297 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.ts @@ -61,7 +61,6 @@ export class OsdFormComponent implements OnInit { featureList: OsdFeature[] = []; hasOrchestrator = false; - docsUrl: string; constructor( public actionLabels: ActionLabelsI18n, diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/monitoring-list/monitoring-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/monitoring-list/monitoring-list.component.html index f54c1fe515f55..9bb49de583c97 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/monitoring-list/monitoring-list.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/monitoring-list/monitoring-list.component.html @@ -6,10 +6,9 @@ To see all active Prometheus alerts, please - provide the URL to the API of Prometheus' Alertmanager as described in the - documentation. + *ngIf="!isAlertmanagerConfigured">To see all active Prometheus alerts, + please provide the URL to the API of Prometheus' Alertmanager as described in + the . To see all configured Prometheus alerts, please provide the URL to - the API of Prometheus as described in the - documentation. + *ngIf="!isPrometheusConfigured">To see all configured Prometheus alerts, + please provide the URL to the API of Prometheus as described in + the . To enable Silences, please provide the URL to the API of the Prometheus' Alertmanager as - described in the - documentation. + i18n>To enable Silences, please provide the URL to the API + of the Prometheus' Alertmanager as described in + the . diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/monitoring-list/monitoring-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/monitoring-list/monitoring-list.component.ts index e08e235fe751f..9b549aca8426f 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/monitoring-list/monitoring-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/monitoring-list/monitoring-list.component.ts @@ -4,9 +4,7 @@ import { ActivatedRoute, Router } from '@angular/router'; import { TabDirective, TabsetComponent } from 'ngx-bootstrap/tabs'; import { PrometheusService } from '../../../../shared/api/prometheus.service'; -import { CephReleaseNamePipe } from '../../../../shared/pipes/ceph-release-name.pipe'; import { PrometheusAlertService } from '../../../../shared/services/prometheus-alert.service'; -import { SummaryService } from '../../../../shared/services/summary.service'; @Component({ selector: 'cd-monitoring-list', @@ -18,9 +16,7 @@ export class MonitoringListComponent implements OnInit { public prometheusAlertService: PrometheusAlertService, private prometheusService: PrometheusService, private route: ActivatedRoute, - private router: Router, - private summaryService: SummaryService, - private cephReleaseNamePipe: CephReleaseNamePipe + private router: Router ) {} @ViewChild('tabs', { static: true }) tabs: TabsetComponent; @@ -28,8 +24,6 @@ export class MonitoringListComponent implements OnInit { isPrometheusConfigured = false; isAlertmanagerConfigured = false; - docsUrl = ''; - ngOnInit() { this.prometheusService.ifAlertmanagerConfigured(() => { this.isAlertmanagerConfigured = true; @@ -38,11 +32,6 @@ export class MonitoringListComponent implements OnInit { this.isPrometheusConfigured = true; }); - this.summaryService.subscribeOnce((summary) => { - const releaseName = this.cephReleaseNamePipe.transform(summary.version); - this.docsUrl = `https://docs.ceph.com/docs/${releaseName}/mgr/dashboard/#enabling-prometheus-alerting`; - }); - // Activate tab according to given fragment if (this.route.snapshot.fragment) { const tab = this.tabs.tabs.find( diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.ts index ddb14cca189dc..8890ff5531ed1 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.ts @@ -31,7 +31,6 @@ export class ServicesComponent extends ListWithDetails implements OnChanges, OnI checkingOrchestrator = true; hasOrchestrator = false; - docsUrl: string; columns: Array = []; services: Array = []; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-501/nfs-501.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-501/nfs-501.component.html index dae183db0d6cc..bcbb88125429d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-501/nfs-501.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-501/nfs-501.component.html @@ -1,6 +1,5 @@ {{ message }}
- Please consult the documentation - on how to configure and enable the NFS Ganesha management functionality. + Please consult the on how + to configure and enable the NFS Ganesha management functionality.
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-501/nfs-501.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-501/nfs-501.component.ts index 985b3b3f531de..1b34aaf7df5d0 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-501/nfs-501.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-501/nfs-501.component.ts @@ -3,34 +3,18 @@ import { ActivatedRoute } from '@angular/router'; import { I18n } from '@ngx-translate/i18n-polyfill'; -import { CephReleaseNamePipe } from '../../../shared/pipes/ceph-release-name.pipe'; -import { SummaryService } from '../../../shared/services/summary.service'; - @Component({ selector: 'cd-nfs-501', templateUrl: './nfs-501.component.html', styleUrls: ['./nfs-501.component.scss'] }) export class Nfs501Component implements OnInit, OnDestroy { - docsUrl: string; message = this.i18n('The NFS Ganesha service is not configured.'); routeParamsSubscribe: any; - constructor( - private route: ActivatedRoute, - private summaryService: SummaryService, - private cephReleaseNamePipe: CephReleaseNamePipe, - private i18n: I18n - ) {} + constructor(private route: ActivatedRoute, private i18n: I18n) {} ngOnInit() { - this.summaryService.subscribeOnce((summary) => { - const releaseName = this.cephReleaseNamePipe.transform(summary.version); - this.docsUrl = - `http://docs.ceph.com/docs/${releaseName}/mgr/dashboard/` + - `#configuring-nfs-ganesha-in-the-dashboard`; - }); - this.routeParamsSubscribe = this.route.params.subscribe((params: { message: string }) => { this.message = params.message; }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html index 75a07e47f3be2..70d577b3456ef 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html @@ -404,9 +404,8 @@ *ngIf="nfsForm.getValue('access_type') === 'RW' && nfsForm.getValue('name') === 'RGW'" i18n>The Object Gateway NFS backend has a number of limitations which will seriously affect applications writing to - the share. Please consult the - documentation for details before enabling write access. + the share. Please consult the + for details before enabling write access. This field is required. diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts index 50616fb2d9408..8467d46e481b1 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts @@ -18,9 +18,7 @@ import { CdFormGroup } from '../../../shared/forms/cd-form-group'; import { CdValidators } from '../../../shared/forms/cd-validators'; import { FinishedTask } from '../../../shared/models/finished-task'; import { Permission } from '../../../shared/models/permissions'; -import { CephReleaseNamePipe } from '../../../shared/pipes/ceph-release-name.pipe'; import { AuthStorageService } from '../../../shared/services/auth-storage.service'; -import { SummaryService } from '../../../shared/services/summary.service'; import { TaskWrapperService } from '../../../shared/services/task-wrapper.service'; import { NfsFormClientComponent } from '../nfs-form-client/nfs-form-client.component'; @@ -59,7 +57,6 @@ export class NfsFormComponent implements OnInit { action: string; resource: string; - docsUrl: string; daemonsSelections: SelectOption[] = []; daemonsMessages = new SelectMessages( @@ -85,8 +82,6 @@ export class NfsFormComponent implements OnInit { private router: Router, private rgwUserService: RgwUserService, private formBuilder: CdFormBuilder, - private summaryservice: SummaryService, - private cephReleaseNamePipe: CephReleaseNamePipe, private taskWrapper: TaskWrapperService, private cdRef: ChangeDetectorRef, private i18n: I18n, @@ -122,11 +117,6 @@ export class NfsFormComponent implements OnInit { this.action = this.actionLabels.CREATE; this.getData(promises); } - - this.summaryservice.subscribeOnce((summary) => { - const releaseName = this.cephReleaseNamePipe.transform(summary.version); - this.docsUrl = `http://docs.ceph.com/docs/${releaseName}/radosgw/nfs/`; - }); } getData(promises: Observable[]) { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.html index 7f0b57bfbf9e5..398a535bf8c6d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.html @@ -110,9 +110,9 @@ *ngIf="form.showError('pgNum', formDir, '34')" i18n>Your cluster can't handle this many PGs. Please recalculate the PG amount needed. - Calculation help + {{ message }}
- Please consult the documentation - on how to configure and enable the Object Gateway management functionality. + Please consult the on how + to configure and enable the Object Gateway management functionality. diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-501/rgw-501.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-501/rgw-501.component.ts index 02fbc18cdc607..77bea30a6be1e 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-501/rgw-501.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-501/rgw-501.component.ts @@ -1,33 +1,18 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { CephReleaseNamePipe } from '../../../shared/pipes/ceph-release-name.pipe'; -import { SummaryService } from '../../../shared/services/summary.service'; - @Component({ selector: 'cd-rgw-501', templateUrl: './rgw-501.component.html', styleUrls: ['./rgw-501.component.scss'] }) export class Rgw501Component implements OnInit, OnDestroy { - docsUrl: string; message = 'The Object Gateway service is not configured.'; routeParamsSubscribe: any; - constructor( - private route: ActivatedRoute, - private summaryService: SummaryService, - private cephReleaseNamePipe: CephReleaseNamePipe - ) {} + constructor(private route: ActivatedRoute) {} ngOnInit() { - this.summaryService.subscribeOnce((summary) => { - const releaseName = this.cephReleaseNamePipe.transform(summary.version); - this.docsUrl = - `http://docs.ceph.com/docs/${releaseName}/mgr/dashboard/` + - `#enabling-the-object-gateway-management-frontend`; - }); - this.routeParamsSubscribe = this.route.params.subscribe((params: { message: string }) => { this.message = params.message; }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.html index 122bcfd5943d2..27dda06bc659f 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.html @@ -20,11 +20,11 @@ class="dropdown-menu dropdown-menu-right" role="menu">
  • - Documentation + target="_blank" + i18n>documentation
  • { - const releaseName = this.cephReleaseNamePipe.transform(summary.version); - this.docsUrl = `http://docs.ceph.com/docs/${releaseName}/mgr/dashboard/`; + this.docService.subscribeOnce('dashboard', (url: string) => { + this.docsUrl = url; }); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts index 3d08c56c3598d..811e411340a6b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts @@ -21,6 +21,7 @@ import { BackButtonComponent } from './back-button/back-button.component'; import { ConfigOptionComponent } from './config-option/config-option.component'; import { ConfirmationModalComponent } from './confirmation-modal/confirmation-modal.component'; import { CriticalConfirmationModalComponent } from './critical-confirmation-modal/critical-confirmation-modal.component'; +import { DocComponent } from './doc/doc.component'; import { FormModalComponent } from './form-modal/form-modal.component'; import { GrafanaComponent } from './grafana/grafana.component'; import { HelperComponent } from './helper/helper.component'; @@ -83,7 +84,8 @@ import { ViewCacheComponent } from './view-cache/view-cache.component'; PwdExpirationNotificationComponent, TelemetryNotificationComponent, OrchestratorDocPanelComponent, - OrchestratorDocModalComponent + OrchestratorDocModalComponent, + DocComponent ], providers: [], exports: [ @@ -105,7 +107,8 @@ import { ViewCacheComponent } from './view-cache/view-cache.component'; AlertPanelComponent, PwdExpirationNotificationComponent, TelemetryNotificationComponent, - OrchestratorDocPanelComponent + OrchestratorDocPanelComponent, + DocComponent ], entryComponents: [ ModalComponent, diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.html new file mode 100644 index 0000000000000..b90fedc0cf15f --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.html @@ -0,0 +1,2 @@ +{{ docText }} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.scss new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.spec.ts new file mode 100644 index 0000000000000..a0fc059044f99 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.spec.ts @@ -0,0 +1,27 @@ +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper'; +import { CephReleaseNamePipe } from '../../../shared/pipes/ceph-release-name.pipe'; +import { DocComponent } from './doc.component'; + +describe('DocComponent', () => { + let component: DocComponent; + let fixture: ComponentFixture; + + configureTestBed({ + declarations: [DocComponent], + imports: [HttpClientTestingModule], + providers: [CephReleaseNamePipe, i18nProviders] + }); + + beforeEach(() => { + fixture = TestBed.createComponent(DocComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.ts new file mode 100644 index 0000000000000..355601a8b284c --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/doc/doc.component.ts @@ -0,0 +1,25 @@ +import { Component, Input, OnInit } from '@angular/core'; + +import { I18n } from '@ngx-translate/i18n-polyfill'; + +import { DocService } from '../../../shared/services/doc.service'; + +@Component({ + selector: 'cd-doc', + templateUrl: './doc.component.html', + styleUrls: ['./doc.component.scss'] +}) +export class DocComponent implements OnInit { + @Input() section: string; + @Input() docText = this.i18n(`documentation`); + + docUrl: string; + + constructor(private docService: DocService, private i18n: I18n) {} + + ngOnInit() { + this.docService.subscribeOnce(this.section, (url: string) => { + this.docUrl = url; + }); + } +} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.html index d6ac94af42aa4..a5a29bfbee850 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.html @@ -4,17 +4,13 @@ Please consult the - documentation on how to - configure and enable the monitoring functionality. + i18n>Please consult the on + how to configure and enable the monitoring functionality. Grafana Dashboard doesn't exist. Please refer to - documentation on how to - add dashboards to Grafana. + on how to add dashboards to Grafana.
    diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.spec.ts index 409f3b8a1a312..f6bc6a42f8ac7 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.spec.ts @@ -10,6 +10,7 @@ import { SummaryService } from '../../../shared/services/summary.service'; import { SettingsService } from '../../api/settings.service'; import { CephReleaseNamePipe } from '../../pipes/ceph-release-name.pipe'; import { AlertPanelComponent } from '../alert-panel/alert-panel.component'; +import { DocComponent } from '../doc/doc.component'; import { LoadingPanelComponent } from '../loading-panel/loading-panel.component'; import { GrafanaComponent } from './grafana.component'; @@ -18,7 +19,7 @@ describe('GrafanaComponent', () => { let fixture: ComponentFixture; configureTestBed({ - declarations: [GrafanaComponent, AlertPanelComponent, LoadingPanelComponent], + declarations: [GrafanaComponent, AlertPanelComponent, LoadingPanelComponent, DocComponent], imports: [AlertModule.forRoot(), HttpClientTestingModule, RouterTestingModule, FormsModule], providers: [CephReleaseNamePipe, SettingsService, SummaryService, i18nProviders] }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.ts index afb4136189005..27d300ed93102 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.ts @@ -4,8 +4,6 @@ import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; import { I18n } from '@ngx-translate/i18n-polyfill'; import { Icons } from '../../../shared/enum/icons.enum'; -import { CephReleaseNamePipe } from '../../../shared/pipes/ceph-release-name.pipe'; -import { SummaryService } from '../../../shared/services/summary.service'; import { SettingsService } from '../../api/settings.service'; @Component({ @@ -38,13 +36,9 @@ export class GrafanaComponent implements OnInit, OnChanges { @Input() uid: string; - docsUrl: string; - constructor( - private summaryService: SummaryService, private sanitizer: DomSanitizer, private settingsService: SettingsService, - private cephReleaseNamePipe: CephReleaseNamePipe, private i18n: I18n ) { this.grafanaTimes = [ @@ -179,13 +173,6 @@ export class GrafanaComponent implements OnInit, OnChanges { three: 'grafana_three' }; - this.summaryService.subscribeOnce((summary) => { - const releaseName = this.cephReleaseNamePipe.transform(summary.version); - this.docsUrl = - `http://docs.ceph.com/docs/${releaseName}/mgr/dashboard/` + - `#enabling-the-embedding-of-grafana-dashboards`; - }); - this.settingsService.ifSettingConfigured('api/grafana/url', (url) => { this.grafanaExist = true; this.loading = false; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html index 5159177ab5062..4c7175910b068 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.html @@ -1,5 +1,4 @@ Orchestrator is not available. Please consult the - documentation on how to - configure and enable the functionality. + i18n>Orchestrator is not available. + Please consult the on how to configure and + enable the functionality. diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.ts index d4728bce70236..71c94ec7facdc 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-panel/orchestrator-doc-panel.component.ts @@ -1,25 +1,8 @@ -import { Component, OnInit } from '@angular/core'; - -import { CephReleaseNamePipe } from '../../pipes/ceph-release-name.pipe'; -import { SummaryService } from '../../services/summary.service'; +import { Component } from '@angular/core'; @Component({ selector: 'cd-orchestrator-doc-panel', templateUrl: './orchestrator-doc-panel.component.html', styleUrls: ['./orchestrator-doc-panel.component.scss'] }) -export class OrchestratorDocPanelComponent implements OnInit { - docsUrl: string; - - constructor( - private cephReleaseNamePipe: CephReleaseNamePipe, - private summaryService: SummaryService - ) {} - - ngOnInit() { - this.summaryService.subscribeOnce((summary) => { - const releaseName = this.cephReleaseNamePipe.transform(summary.version); - this.docsUrl = `http://docs.ceph.com/docs/${releaseName}/mgr/orchestrator/`; - }); - } -} +export class OrchestratorDocPanelComponent {} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.spec.ts new file mode 100644 index 0000000000000..131d3436ae4c1 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.spec.ts @@ -0,0 +1,69 @@ +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { TestBed } from '@angular/core/testing'; + +import { Subscriber } from 'rxjs'; + +import { configureTestBed } from '../../../testing/unit-test-helper'; +import { SharedModule } from '../shared.module'; +import { DocService } from './doc.service'; + +describe('DocService', () => { + let service: DocService; + + configureTestBed({ imports: [HttpClientTestingModule, SharedModule] }); + + beforeEach(() => { + service = TestBed.get(DocService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('should return full URL', () => { + expect(service.urlGenerator('foo', 'iscsi')).toBe( + 'http://docs.ceph.com/docs/foo/mgr/dashboard/#enabling-iscsi-management' + ); + }); + + describe('Name of the group', () => { + let result: string; + let i: number; + + const nextSummary = (newData: any) => service['releaseDataSource'].next(newData); + + const callback = (response: string) => { + i++; + result = response; + }; + + beforeEach(() => { + i = 0; + result = undefined; + nextSummary(undefined); + }); + + it('should call subscribeOnce without releaseName', () => { + const subscriber = service.subscribeOnce('prometheus', callback); + + expect(subscriber).toEqual(jasmine.any(Subscriber)); + expect(i).toBe(0); + expect(result).toEqual(undefined); + }); + + it('should call subscribeOnce with releaseName', () => { + const subscriber = service.subscribeOnce('prometheus', callback); + + expect(subscriber).toEqual(jasmine.any(Subscriber)); + expect(i).toBe(0); + expect(result).toEqual(undefined); + + nextSummary('foo'); + expect(result).toEqual( + 'http://docs.ceph.com/docs/foo/mgr/dashboard/#enabling-prometheus-alerting' + ); + expect(i).toBe(1); + expect(subscriber.closed).toBe(true); + }); + }); +}); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.ts new file mode 100644 index 0000000000000..4d3ab0f6fd116 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/doc.service.ts @@ -0,0 +1,57 @@ +import { Injectable } from '@angular/core'; + +import { BehaviorSubject, Subscription } from 'rxjs'; +import { filter, first, map } from 'rxjs/operators'; + +import { CephReleaseNamePipe } from '../pipes/ceph-release-name.pipe'; +import { SummaryService } from './summary.service'; + +@Injectable({ + providedIn: 'root' +}) +export class DocService { + private releaseDataSource = new BehaviorSubject(null); + releaseData$ = this.releaseDataSource.asObservable(); + + constructor( + private summaryservice: SummaryService, + private cephReleaseNamePipe: CephReleaseNamePipe + ) { + this.summaryservice.subscribeOnce((summary) => { + const releaseName = this.cephReleaseNamePipe.transform(summary.version); + this.releaseDataSource.next(releaseName); + }); + } + + urlGenerator(release: string, section: string): string { + const domain = `http://docs.ceph.com/docs/${release}/`; + + const sections = { + iscsi: `${domain}mgr/dashboard/#enabling-iscsi-management`, + prometheus: `${domain}mgr/dashboard/#enabling-prometheus-alerting`, + 'nfs-ganesha': `${domain}mgr/dashboard/#configuring-nfs-ganesha-in-the-dashboard`, + 'rgw-nfs': `${domain}radosgw/nfs`, + rgw: `${domain}mgr/dashboard/#enabling-the-object-gateway-management-frontend`, + dashboard: `${domain}mgr/dashboard`, + grafana: `${domain}mgr/dashboard/#enabling-the-embedding-of-grafana-dashboards`, + orch: `${domain}mgr/orchestrator`, + pgs: `http://ceph.com/pgcalc` + }; + + return sections[section]; + } + + subscribeOnce( + section: string, + next: (release: string) => void, + error?: (error: any) => void + ): Subscription { + return this.releaseData$ + .pipe( + filter((value) => !!value), + map((release) => this.urlGenerator(release, section)), + first() + ) + .subscribe(next, error); + } +} -- 2.47.3