mgr/dashboard: shorten Container ID and Container image ID in Services page

Fixes: https://tracker.ceph.com/issues/44539

Signed-off-by: Volker Theile <vtheile@suse.com>
This commit is contained in:
Volker Theile 2020-03-31 11:13:21 +02:00
parent 558853be66
commit ed51f8039a
8 changed files with 83 additions and 7 deletions

View 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'),

View 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'),

View File

@ -290,3 +290,10 @@
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>

View 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 {

View 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'
}

View File

@ -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 {}

View File

@ -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);
});
});

View File

@ -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 });
}
}