]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: shorten `Container ID` and `Container image ID` in Services page 34026/head
authorVolker Theile <vtheile@suse.com>
Tue, 31 Mar 2020 09:13:21 +0000 (11:13 +0200)
committerVolker Theile <vtheile@suse.com>
Tue, 31 Mar 2020 09:13:41 +0000 (11:13 +0200)
Fixes: https://tracker.ceph.com/issues/44539
Signed-off-by: Volker Theile <vtheile@suse.com>
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/enum/cell-template.enum.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/pipes.module.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/truncate.pipe.spec.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/truncate.pipe.ts [new file with mode: 0644]

index 82632e0607e7e4bc3eefb0f084530c0cb1441672..6683d276c6a46d1780b5b5880f60496780c1da8e 100644 (file)
@@ -18,6 +18,7 @@ import { CephServiceService } from '../../../../shared/api/ceph-service.service'
 import { HostService } from '../../../../shared/api/host.service';
 import { OrchestratorService } from '../../../../shared/api/orchestrator.service';
 import { TableComponent } from '../../../../shared/datatable/table/table.component';
+import { CellTemplate } from '../../../../shared/enum/cell-template.enum';
 import { CdTableColumn } from '../../../../shared/models/cd-table-column';
 import { CdTableFetchDataContext } from '../../../../shared/models/cd-table-fetch-data-context';
 import { Daemon } from '../../../../shared/models/daemon.interface';
@@ -76,7 +77,11 @@ export class ServiceDaemonListComponent implements OnInit, OnChanges, AfterViewI
         name: this.i18n('Container ID'),
         prop: 'container_id',
         flexGrow: 3,
-        filterable: true
+        filterable: true,
+        cellTransformation: CellTemplate.truncate,
+        customTemplateConfig: {
+          length: 12
+        }
       },
       {
         name: this.i18n('Container Image name'),
@@ -88,7 +93,11 @@ export class ServiceDaemonListComponent implements OnInit, OnChanges, AfterViewI
         name: this.i18n('Container Image ID'),
         prop: 'container_image_id',
         flexGrow: 3,
-        filterable: true
+        filterable: true,
+        cellTransformation: CellTemplate.truncate,
+        customTemplateConfig: {
+          length: 12
+        }
       },
       {
         name: this.i18n('Version'),
index 74f059f5e600589ab6cf3a55141941619d07dbee..a691ff5c61ebda2bf005c510ea1d6bf44f2038cd 100644 (file)
@@ -4,6 +4,7 @@ import { I18n } from '@ngx-translate/i18n-polyfill';
 import { CephServiceService } from '../../../shared/api/ceph-service.service';
 import { OrchestratorService } from '../../../shared/api/orchestrator.service';
 import { TableComponent } from '../../../shared/datatable/table/table.component';
+import { CellTemplate } from '../../../shared/enum/cell-template.enum';
 import { CdTableColumn } from '../../../shared/models/cd-table-column';
 import { CdTableFetchDataContext } from '../../../shared/models/cd-table-fetch-data-context';
 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
@@ -60,7 +61,11 @@ export class ServicesComponent implements OnChanges, OnInit {
       {
         name: this.i18n('Container image ID'),
         prop: 'status.container_image_id',
-        flexGrow: 3
+        flexGrow: 3,
+        cellTransformation: CellTemplate.truncate,
+        customTemplateConfig: {
+          length: 12
+        }
       },
       {
         name: this.i18n('Running'),
index ceef88337ab8fd442815e0d7457b88d401a9d768..82eeef2f4df653150f2dd210565f9121a1c4f7db 100644 (file)
              let-value="value">
   <span>{{ value | map:column?.customTemplateConfig }}</span>
 </ng-template>
+
+<ng-template #truncateTpl
+             let-column="column"
+             let-value="value">
+  <span data-toggle="tooltip"
+        [title]="value">{{ value | truncate:column?.customTemplateConfig?.length:column?.customTemplateConfig?.omission }}</span>
+</ng-template>
index 4433326cebbe2cccd09755e4444e0e2c1cbb77cd..1eb859e18f1617536257434990e3b7eca7bec6ec 100644 (file)
@@ -61,6 +61,8 @@ export class TableComponent implements AfterContentChecked, OnInit, OnChanges, O
   badgeTpl: TemplateRef<any>;
   @ViewChild('mapTpl', { static: true })
   mapTpl: TemplateRef<any>;
+  @ViewChild('truncateTpl', { static: true })
+  truncateTpl: TemplateRef<any>;
 
   // This is the array with the items to be shown.
   @Input()
@@ -513,6 +515,7 @@ export class TableComponent implements AfterContentChecked, OnInit, OnChanges, O
     this.cellTemplates.classAdding = this.classAddingTpl;
     this.cellTemplates.badge = this.badgeTpl;
     this.cellTemplates.map = this.mapTpl;
+    this.cellTemplates.truncate = this.truncateTpl;
   }
 
   useCustomClass(value: any): string {
index 47f180bc5a90109b0c80fbb967b3c9187f7e4870..586f4376f04bd5593babf48bfb1c3c36d1a55ff3 100644 (file)
@@ -29,5 +29,16 @@ export enum CellTemplate {
   //     [key: any]: any
   //   }
   // }
-  map = 'map'
+  map = 'map',
+  // Truncates string if it's longer than the given maximum
+  // string length.
+  // {
+  //   ...
+  //   cellTransformation: CellTemplate.truncate,
+  //   customTemplateConfig: {
+  //     length?: number;   // Defaults to 30.
+  //     omission?: string; // Defaults to empty string.
+  //   }
+  // }
+  truncate = 'truncate'
 }
index 5a70d512ff6f8492c68b2288d3b7c99ff21383fc..3deb535929d3c5509bdb15039e2ac22174f60dba 100755 (executable)
@@ -26,6 +26,7 @@ import { OrdinalPipe } from './ordinal.pipe';
 import { RbdConfigurationSourcePipe } from './rbd-configuration-source.pipe';
 import { RelativeDatePipe } from './relative-date.pipe';
 import { RoundPipe } from './round.pipe';
+import { TruncatePipe } from './truncate.pipe';
 import { UpperFirstPipe } from './upper-first.pipe';
 
 @NgModule({
@@ -56,7 +57,8 @@ import { UpperFirstPipe } from './upper-first.pipe';
     UpperFirstPipe,
     RbdConfigurationSourcePipe,
     DurationPipe,
-    MapPipe
+    MapPipe,
+    TruncatePipe
   ],
   exports: [
     ArrayPipe,
@@ -84,7 +86,8 @@ import { UpperFirstPipe } from './upper-first.pipe';
     UpperFirstPipe,
     RbdConfigurationSourcePipe,
     DurationPipe,
-    MapPipe
+    MapPipe,
+    TruncatePipe
   ],
   providers: [
     ArrayPipe,
@@ -108,7 +111,8 @@ import { UpperFirstPipe } from './upper-first.pipe';
     MillisecondsPipe,
     NotAvailablePipe,
     UpperFirstPipe,
-    MapPipe
+    MapPipe,
+    TruncatePipe
   ]
 })
 export class PipesModule {}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/truncate.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/truncate.pipe.spec.ts
new file mode 100644 (file)
index 0000000..cc0b2fc
--- /dev/null
@@ -0,0 +1,21 @@
+import { TruncatePipe } from './truncate.pipe';
+
+describe('TruncatePipe', () => {
+  const pipe = new TruncatePipe();
+
+  it('create an instance', () => {
+    expect(pipe).toBeTruthy();
+  });
+
+  it('should truncate string (1)', () => {
+    expect(pipe.transform('fsdfdsfs asdasd', 5, '')).toEqual('fsdfd');
+  });
+
+  it('should truncate string (2)', () => {
+    expect(pipe.transform('fsdfdsfs asdasd', 10, '...')).toEqual('fsdfdsf...');
+  });
+
+  it('should not truncate number', () => {
+    expect(pipe.transform(2, 6, '...')).toBe(2);
+  });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/truncate.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/truncate.pipe.ts
new file mode 100644 (file)
index 0000000..d825832
--- /dev/null
@@ -0,0 +1,16 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import * as _ from 'lodash';
+
+@Pipe({
+  name: 'truncate'
+})
+export class TruncatePipe implements PipeTransform {
+  transform(value: any, length: number, omission?: string): any {
+    if (!_.isString(value)) {
+      return value;
+    }
+    omission = _.defaultTo(omission, '');
+    return _.truncate(value, { length, omission });
+  }
+}