]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: created common Card component for info shown in landing page: 22902/head
authoralfonsomthd <almartin@redhat.com>
Thu, 12 Jul 2018 07:47:47 +0000 (09:47 +0200)
committeralfonsomthd <alfonsomthd@tutanota.com>
Thu, 12 Jul 2018 13:23:47 +0000 (15:23 +0200)
Info encapsulated in cd-info-card selector:
- Overall health status, MON/OSD/MDS/MGR status

Fixes: https://tracker.ceph.com/issues/24778
Signed-off-by: Alfonso Martínez <almartin@redhat.com>
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard.module.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.scss
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.html [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.ts [new file with mode: 0644]

index 34744fc09adadc9567e41308b1a2cce6b6ff1d0d..8e4cc903938ca782279f8f8e688c640302e538ae 100644 (file)
@@ -9,6 +9,7 @@ import { SharedModule } from '../../shared/shared.module';
 import { DashboardComponent } from './dashboard/dashboard.component';
 import { HealthPieComponent } from './health-pie/health-pie.component';
 import { HealthComponent } from './health/health.component';
+import { InfoCardComponent } from './info-card/info-card.component';
 import { LogColorPipe } from './log-color.pipe';
 import { MdsSummaryPipe } from './mds-summary.pipe';
 import { MgrSummaryPipe } from './mgr-summary.pipe';
@@ -29,7 +30,8 @@ import { PgStatusPipe } from './pg-status.pipe';
     PgStatusPipe,
     MdsSummaryPipe,
     PgStatusStylePipe,
-    HealthPieComponent
+    HealthPieComponent,
+    InfoCardComponent
   ]
 })
 export class DashboardModule {}
index 4ce0feae1be38332d1cd8685241998d362147c04..bc68e2037ffcded12b84cada1c13b8f545e7e77f 100644 (file)
 <div *ngIf="contentData">
   <div class="row">
-    <!-- HEALTH -->
-    <div class="col-md-6">
-      <div class="well">
-        <fieldset>
-          <legend i18n>Health</legend>
-          <ng-container i18n>Overall status: </ng-container>
-          <span [ngStyle]="contentData.health.status | healthColor">{{ contentData.health.status }}</span>
-          <ul>
-            <li *ngFor="let check of contentData.health.checks">
-              <span [ngStyle]="check.severity | healthColor">{{ check.type }}</span>: {{ check.summary.message }}
-            </li>
-          </ul>
-        </fieldset>
-      </div>
-    </div>
+    <cd-info-card title="Health">
+      <ng-container i18n>Overall status: </ng-container>
+      <span [ngStyle]="contentData.health.status | healthColor">{{ contentData.health.status }}</span>
+      <ul>
+        <li *ngFor="let check of contentData.health.checks">
+          <span [ngStyle]="check.severity | healthColor">{{ check.type }}</span>: {{ check.summary.message }}
+        </li>
+      </ul>
+    </cd-info-card>
 
     <div class="col-md-6">
       <!--STATS -->
       <div class="row">
-        <div class="col-md-6">
-          <div class="well"
-               *ngIf="contentData.mon_status">
-            <div class="media">
-              <div class="media-left">
-                <i class="fa fa-database fa-fw"></i>
-              </div>
-              <div class="media-body">
-                <span class="media-heading"
-                      i18n="ceph monitors">
-                  <a routerLink="/monitor/">Monitors</a>
-                </span>
-                <span class="media-text">{{ contentData.mon_status | monSummary }}</span>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div class="col-md-6">
-          <div class="well"
-               *ngIf="contentData.osd_map">
-            <div class="media">
-              <div class="media-left">
-                <i class="fa fa-hdd-o fa-fw"></i>
-              </div>
-              <div class="media-body">
-                <span class="media-heading"
-                      i18n="ceph OSDs">
-                  <a routerLink="/osd/">OSDs</a>
-                </span>
-                <span class="media-text">{{ contentData.osd_map | osdSummary }}</span>
-              </div>
-            </div>
-          </div>
-        </div>
+        <cd-info-card title="MONITORS"
+                      imageClass="fa fa-database fa-fw"
+                      link="/monitor"
+                      contentClass="media-text"
+                      *ngIf="contentData.mon_status">
+          {{ contentData.mon_status | monSummary }}
+        </cd-info-card>
+
+        <cd-info-card title="OSDs"
+                      imageClass="fa fa-hdd-o fa-fw"
+                      link="/osd"
+                      contentClass="media-text"
+                      *ngIf="contentData.osd_map">
+          {{ contentData.osd_map | osdSummary }}
+        </cd-info-card>
       </div>
       <div class="row">
-        <div class="col-md-6">
-          <div class="well"
-               *ngIf="contentData.fs_map">
-            <div class="media">
-              <div class="media-left">
-                <i class="fa fa-folder fa-fw"></i>
-              </div>
-              <div class="media-body">
-                <span class="media-heading"
-                      i18n>Metadata servers</span>
-                <span class="media-text">{{ contentData.fs_map | mdsSummary }}</span>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div class="col-md-6">
-          <div class="well"
-               *ngIf="contentData.mgr_map">
-            <div class="media">
-              <div class="media-left">
-                <i class="fa fa-cog fa-fw"></i>
-              </div>
-              <div class="media-body">
-                <span class="media-heading"
-                      i18n>Manager daemons</span>
-                <span class="media-text">{{ contentData.mgr_map | mgrSummary }}</span>
-              </div>
-            </div>
-          </div>
-        </div>
+        <cd-info-card title="METADATA SERVERS"
+                      imageClass="fa fa-folder fa-fw"
+                      contentClass="media-text"
+                      *ngIf="contentData.fs_map">
+          {{ contentData.fs_map | mdsSummary }}
+        </cd-info-card>
+
+        <cd-info-card title="MANAGER DAEMONS"
+                      imageClass="fa fa-cog fa-fw"
+                      contentClass="media-text"
+                      *ngIf="contentData.mgr_map">
+          {{ contentData.mgr_map | mgrSummary }}
+        </cd-info-card>
       </div>
     </div>
   </div>
 
   <div class="row">
-    <!-- USAGE -->
-    <div class="col-md-6">
-      <div class="well"
-           *ngIf="contentData.df?.stats?.total_objects">
-        <fieldset class="usage">
-          <legend i18n>Usage</legend>
-
-          <table class="ceph-chartbox">
-            <tr>
-              <td>
-                <span style="font-size: 45px;">{{ contentData.df.stats.total_objects | dimless }}</span>
-              </td>
-              <td>
-                <div class="center-block pie">
-                  <cd-health-pie [data]="contentData"
-                                 (prepareFn)="prepareRawUsage($event[0], $event[1])"></cd-health-pie>
-                </div>
-              </td>
-              <td>
-                <div class="center-block pie">
-                  <cd-health-pie [data]="contentData"
-                                 (prepareFn)="preparePoolUsage($event[0], $event[1])"></cd-health-pie>
-                </div>
-              </td>
-            </tr>
-            <tr>
-              <td i18n>Objects</td>
-              <td>
-                <ng-container i18n>Raw capacity</ng-container>
-                <br>
-                <ng-container i18n="disk used">({{ contentData.df.stats.total_used_bytes | dimlessBinary }} used)</ng-container>
-              </td>
-              <td i18n>Usage by pool</td>
-            </tr>
-          </table>
-        </fieldset>
-      </div>
-    </div>
+    <cd-info-card title="Usage"
+                  *ngIf="contentData.df?.stats?.total_objects">
+      <table class="ceph-chartbox">
+        <tr>
+          <td>
+            <span style="font-size: 45px;">{{ contentData.df.stats.total_objects | dimless }}</span>
+          </td>
+          <td>
+            <div class="center-block pie">
+              <cd-health-pie [data]="contentData"
+                             (prepareFn)="prepareRawUsage($event[0], $event[1])"></cd-health-pie>
+            </div>
+          </td>
+          <td>
+            <div class="center-block pie">
+              <cd-health-pie [data]="contentData"
+                             (prepareFn)="preparePoolUsage($event[0], $event[1])"></cd-health-pie>
+            </div>
+          </td>
+        </tr>
+        <tr>
+          <td i18n>Objects</td>
+          <td>
+            <ng-container i18n>Raw capacity</ng-container>
+            <br>
+            <ng-container i18n="disk used">({{ contentData.df.stats.total_used_bytes | dimlessBinary }} used)</ng-container>
+          </td>
+          <td i18n>Usage by pool</td>
+        </tr>
+      </table>
+    </cd-info-card>
 
-    <div class="col-md-6">
-      <div class="well"
-           *ngIf="contentData.pools">
-        <fieldset>
-          <legend i18n>Pools</legend>
-          <table class="table table-condensed">
-            <thead>
-              <tr>
-                <th i18n>Name</th>
-                <th i18n>PG status</th>
-                <th i18n>Usage</th>
-                <th colspan="2"
-                    i18n>Read</th>
-                <th colspan="2"
-                    i18n>Write</th>
-              </tr>
-            </thead>
-            <tbody>
-              <tr *ngFor="let pool of contentData.pools">
-                <td>{{ pool.pool_name }}</td>
-                <td [ngStyle]="pool.pg_status | pgStatusStyle">
-                  {{ pool.pg_status | pgStatus }}
-                </td>
-                <td>
-                  <cd-usage-bar [totalBytes]="pool.stats.bytes_used.latest +  pool.stats.max_avail.latest" [usedBytes]="pool.stats.bytes_used.latest"></cd-usage-bar>
-                </td>
-                <td>
-                  {{ pool.stats.rd_bytes.rate | dimless }}
-                </td>
-                <td>
-                  {{ pool.stats.rd.rate | dimless }} ops
-                </td>
-                <td>
-                  {{ pool.stats.wr_bytes.rate | dimless }}
-                </td>
-                <td>
-                  {{ pool.stats.wr.rate | dimless }} ops
-                </td>
-              </tr>
-            </tbody>
-          </table>
-        </fieldset>
-      </div>
-    </div>
+    <cd-info-card title="Pools"
+                  *ngIf="contentData.pools">
+      <table class="table table-condensed">
+        <thead>
+        <tr>
+          <th i18n>Name</th>
+          <th i18n>PG status</th>
+          <th i18n>Usage</th>
+          <th colspan="2"
+              i18n>Read</th>
+          <th colspan="2"
+              i18n>Write</th>
+        </tr>
+        </thead>
+        <tbody>
+        <tr *ngFor="let pool of contentData.pools">
+          <td>{{ pool.pool_name }}</td>
+          <td [ngStyle]="pool.pg_status | pgStatusStyle">
+            {{ pool.pg_status | pgStatus }}
+          </td>
+          <td>
+            <cd-usage-bar [totalBytes]="pool.stats.bytes_used.latest +  pool.stats.max_avail.latest" [usedBytes]="pool.stats.bytes_used.latest"></cd-usage-bar>
+          </td>
+          <td>
+            {{ pool.stats.rd_bytes.rate | dimless }}
+          </td>
+          <td>
+            {{ pool.stats.rd.rate | dimless }} ops
+          </td>
+          <td>
+            {{ pool.stats.wr_bytes.rate | dimless }}
+          </td>
+          <td>
+            {{ pool.stats.wr.rate | dimless }} ops
+          </td>
+        </tr>
+        </tbody>
+      </table>
+    </cd-info-card>
   </div>
 
   <div class="row">
index 919b41d10fc60e125b085d21f8de53afee667653..e7728ce5762437e90709ff2c887583a6e31319e5 100644 (file)
@@ -15,48 +15,3 @@ table.ceph-chartbox {
   height: 120px;
   width: 120px;
 }
-
-.media {
-  display: block;
-  min-height: 60px;
-  width: 100%;
-
-  .media-left {
-    border-top-left-radius: 2px;
-    border-top-right-radius: 0;
-    border-bottom-right-radius: 0;
-    border-bottom-left-radius: 2px;
-    display: block;
-    float: left;
-    height: 60px;
-    width: 60px;
-    text-align: center;
-    font-size: 40px;
-    line-height: 60px;
-    padding-right: 0;
-
-    .fa {
-      font-size: 45px;
-    }
-  }
-
-  .media-body {
-    padding: 5px 10px;
-    margin-left: 60px;
-
-    .media-heading {
-      text-transform: uppercase;
-      display: block;
-      font-size: 14px;
-      white-space: nowrap;
-      overflow: hidden;
-      text-overflow: ellipsis;
-    }
-
-    .media-text {
-      display: block;
-      font-weight: bold;
-      font-size: 18px;
-    }
-  }
-}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.html
new file mode 100644 (file)
index 0000000..0941eaa
--- /dev/null
@@ -0,0 +1,21 @@
+<div [ngClass]="cardClass">
+  <div class="well">
+    <div class="media">
+      <div *ngIf="imageClass" class="media-left">
+        <i [ngClass]="imageClass"></i>
+      </div>
+      <div class="media-body">
+        <span class="media-heading" i18n>
+          <a *ngIf="link; else noLinkTitle" [routerLink]="link">{{ title }}</a>
+          <ng-template #noLinkTitle>
+            {{ title }}
+            <hr *ngIf="!imageClass" class="underline" />
+          </ng-template>
+        </span>
+        <span [ngClass]="contentClass">
+          <ng-content></ng-content>
+        </span>
+      </div>
+    </div>
+  </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss
new file mode 100644 (file)
index 0000000..728f16d
--- /dev/null
@@ -0,0 +1,50 @@
+.media {
+  display: block;
+  min-height: 60px;
+  width: 100%;
+
+  .media-left {
+    border-top-left-radius: 2px;
+    border-top-right-radius: 0;
+    border-bottom-right-radius: 0;
+    border-bottom-left-radius: 2px;
+    display: block;
+    float: left;
+    height: 60px;
+    width: 60px;
+    text-align: center;
+    font-size: 40px;
+    line-height: 60px;
+    padding-right: 0;
+
+    .fa {
+      font-size: 45px;
+    }
+  }
+
+  .media-body {
+    padding: 5px 10px;
+    margin-left: 60px;
+
+    .media-heading {
+      display: block;
+      font-size: 20px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+
+      .underline {
+        border-bottom: 1px solid #e5e5e5;
+        margin-top: 0px;
+        margin-bottom: 18px;
+        padding: 0px;
+      }
+    }
+
+    .media-text {
+      display: block;
+      font-weight: bold;
+      font-size: 18px;
+    }
+  }
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.ts
new file mode 100644 (file)
index 0000000..c01b5ca
--- /dev/null
@@ -0,0 +1,14 @@
+import { Component, Input } from '@angular/core';
+
+@Component({
+  selector: 'cd-info-card',
+  templateUrl: './info-card.component.html',
+  styleUrls: ['./info-card.component.scss']
+})
+export class InfoCardComponent {
+  @Input() title: string;
+  @Input() link: string;
+  @Input() cardClass = 'col-md-6';
+  @Input() imageClass: string;
+  @Input() contentClass: string;
+}