Skip to content

Commit

Permalink
CCIE-1265 Added version history component
Browse files Browse the repository at this point in the history
  • Loading branch information
rmathis committed May 7, 2019
1 parent 80974d0 commit 530d0cd
Show file tree
Hide file tree
Showing 18 changed files with 393 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ export class EntityItemComponent {
@Output() toggle = new EventEmitter();
@Output() preview = new EventEmitter();
@Output() delete = new EventEmitter();
@Output() history = new EventEmitter();
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
aria-label="Review the XML of the selected service provider">
<i class="fa fa-fw fa-eye fa-2x"></i>
</button>
<button class="btn btn-link"
(click)="history.emit(entity); $event.stopPropagation()"
aria-label="Review the version history of selected provider">
<i class="fa fa-fw fa-2x fa-history"></i>
</button>
<button class="btn btn-link"
(click)="select.emit(entity); $event.stopPropagation()"
aria-label="Edit selected service provider">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
(toggle)="toggleEntity(resolver)"
(preview)="openPreviewDialog(resolver)"
(delete)="deleteResolver(resolver)"
(history)="viewMetadataHistory(resolver)"
[allowDelete]="resolver.isDraft()">
</resolver-item>
</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ export class DashboardResolversListComponent implements OnInit {
this.store.dispatch(new PreviewEntity({ id: entity.getId(), entity }));
}

viewMetadataHistory(entity: MetadataEntity): void {
this.router.navigate(['metadata', 'resolver', entity.getId(), 'versions']);
}

deleteResolver(entity: MetadataResolver): void {
this.modalService
.open(DeleteDialogComponent)
Expand Down
2 changes: 2 additions & 0 deletions ui/src/app/metadata/metadata.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { I18nModule } from '../i18n/i18n.module';
import { CustomWidgetRegistry } from '../schema-form/registry';
import { WidgetRegistry, SchemaValidatorFactory } from 'ngx-schema-form';
import { CustomSchemaValidatorFactory } from '../schema-form/service/schema-validator';
import { MetadataVersionModule } from './version/version.module';


@NgModule({
Expand All @@ -20,6 +21,7 @@ import { CustomSchemaValidatorFactory } from '../schema-form/service/schema-vali
DomainModule.forRoot(),
ManagerModule.forRoot(),
ProviderModule.forRoot(),
MetadataVersionModule.forRoot(),
MetadataRoutingModule,
I18nModule
],
Expand Down
4 changes: 3 additions & 1 deletion ui/src/app/metadata/metadata.routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { MetadataPageComponent } from './metadata.component';
import { ResolverRoutes } from './resolver/resolver.routing';
import { ProviderRoutes } from './provider/provider.routing';
import { ManagerRoutes } from './manager/manager.routing';
import { VersionRoutes } from './version/version.routing';

const routes: Routes = [
{
Expand All @@ -13,7 +14,8 @@ const routes: Routes = [
children: [
...ManagerRoutes,
...ResolverRoutes,
...ProviderRoutes
...ProviderRoutes,
...VersionRoutes
],
},
];
Expand Down
37 changes: 37 additions & 0 deletions ui/src/app/metadata/version/component/history-list.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<table class="table">
<caption class="sr-only">Metadata Version History</caption>
<thead>
<tr>
<th scope="col"><span class="sr-only">Select Version</span></th>
<th scope="col">Version</th>
<th scope="col">Save Date</th>
<th scope="col">Changed By</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let version of history.versions; index as i;">
<td>
<div class="custom-control custom-checkbox" (click)="toggleVersionSelected(version)">
<input [title]="'check-' + i" type="checkbox" class="custom-control-input" [checked]="selected.indexOf(version) > -1">
<label class="custom-control-label" [for]="'check-' + i">
<span class="sr-only">Check to select</span>
</label>
</div>
</td>
<td *ngIf="i === 0">Current (v{{ version.versionNumber }})</td>
<td *ngIf="i > 0">v{{ version.versionNumber }}</td>
<td>{{ version.saveDate | date }}</td>
<td>{{ version.changedBy }}</td>
<td>
<button class="btn btn-link" (click)="restoreVersion(version)">
<i class="fa fa-undo"></i>
Restore
</button>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-primary" (click)="compareSelected(selected)" [disabled]="!selected.length">
Compare Selected <span *ngIf="selected.length">({{ selected.length }})</span>
</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { Component, ViewChild } from '@angular/core';
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { MockI18nModule } from '../../../../testing/i18n.stub';
import { HistoryListComponent } from './history-list.component';
import { MetadataHistory } from '../model/history';
import { MetadataVersion } from '../model/version';

export const TestData = {
versions: [
{
versionNumber: 1,
saveDate: new Date(),
changedBy: 'admin',
actions: []
}
]
};

@Component({
template: `<history-list [history]="history" (compare)="compare($event)" (restore)="restore($event)"></history-list>`
})
class TestHostComponent {
@ViewChild(HistoryListComponent)
public componentUnderTest: HistoryListComponent;

history: MetadataHistory = TestData;

compare(versions: MetadataVersion[]): void {}
restore(version: MetadataVersion): void {}
}

describe('Metadata History List Component', () => {
let fixture: ComponentFixture<TestHostComponent>;
let instance: TestHostComponent;
let table: HistoryListComponent;

beforeEach(() => {
TestBed.configureTestingModule({
providers: [],
imports: [
MockI18nModule
],
declarations: [
HistoryListComponent,
TestHostComponent
],
});

fixture = TestBed.createComponent(TestHostComponent);
instance = fixture.componentInstance;
table = instance.componentUnderTest;
fixture.detectChanges();
});

it('should compile', () => {
expect(table).toBeDefined();
});

describe('compare selected', () => {
it('should allow the user to toggle selected versions for comparison', () => {
table.toggleVersionSelected(TestData.versions[0]);
expect(table.selected.length).toBe(1);
});

it('should emit an event with the selected values when the Compare Selected button is clicked', () => {
spyOn(instance, 'compare');
const selected = TestData.versions;
table.compareSelected(selected);
fixture.detectChanges();
expect(instance.compare).toHaveBeenCalledWith(selected);
});

it('should emit an event with the selected version when the Restore button is clicked', () => {
spyOn(instance, 'restore');
const selected = TestData.versions[0];
table.restoreVersion(selected);
fixture.detectChanges();
expect(instance.restore).toHaveBeenCalledWith(selected);
});
});
});
35 changes: 35 additions & 0 deletions ui/src/app/metadata/version/component/history-list.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Component, Input, EventEmitter, ChangeDetectionStrategy, Output } from '@angular/core';
import { MetadataHistory } from '../model/history';
import { MetadataVersion } from '../model/version';

@Component({
selector: 'history-list',
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: './history-list.component.html',
styleUrls: []
})
export class HistoryListComponent {
@Input() history: MetadataHistory;
@Output() compare: EventEmitter<MetadataVersion[]> = new EventEmitter();
@Output() restore: EventEmitter<MetadataVersion> = new EventEmitter();

selected: MetadataVersion[] = [];

constructor() {}

toggleVersionSelected(version: MetadataVersion): void {
if (this.selected.indexOf(version) > -1) {
this.selected = this.selected.filter(s => s !== version);
} else {
this.selected = [...this.selected, version];
}
}

compareSelected(selected: MetadataVersion[]): void {
this.compare.emit(selected);
}

restoreVersion(version: MetadataVersion): void {
this.restore.emit(version);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<div class="container-fluid p-3">
<section class="section" aria-label="View Metadata Version History"
tabindex="0">
<div class="section-header bg-info p-2 text-white">
<div class="row justify-content-between">
<div class="col-md-12">
<span class="display-6">
<i class="fa fa-fw fa-gears"></i>
Metadata resolver history
</span>
</div>
</div>
</div>
<div class="section-body p-4 border border-top-0 border-info">
<history-list [history]="history$ | async"></history-list>
</div>
</section>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Component, ViewChild, Input, EventEmitter, Output } from '@angular/core';
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { MockI18nModule } from '../../../../testing/i18n.stub';
import { VersionHistoryComponent } from './version-history.component';
import { MetadataHistory } from '../model/history';
import { MetadataVersion } from '../model/version';
import { HistoryService } from '../service/history.service';
import { of } from 'rxjs';

export const TestData = {
versions: [
{
versionNumber: 1,
saveDate: new Date(),
changedBy: 'admin',
actions: []
}
]
};

@Component({
selector: 'history-list',
template: `<span></span>`
})
class MockHistoryListComponent {
@Input() history: MetadataHistory;
@Output() compare: EventEmitter<MetadataVersion[]> = new EventEmitter();
@Output() restore: EventEmitter<MetadataVersion> = new EventEmitter();
}

const MockHistoryService = {
query: () => of(TestData)
};

describe('Metadata Version History Component', () => {
let fixture: ComponentFixture<VersionHistoryComponent>;
let instance: VersionHistoryComponent;

beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{
provide: HistoryService, useValue: MockHistoryService
}
],
imports: [
MockI18nModule
],
declarations: [
MockHistoryListComponent,
VersionHistoryComponent
],
});

fixture = TestBed.createComponent(VersionHistoryComponent);
instance = fixture.componentInstance;
fixture.detectChanges();
});

it('should compile', () => {
expect(instance).toBeDefined();
});
});
21 changes: 21 additions & 0 deletions ui/src/app/metadata/version/container/version-history.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { MetadataHistory } from '../model/history';
import { HistoryService } from '../service/history.service';
import { Observable } from 'rxjs';

@Component({
selector: 'version-history',
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: './version-history.component.html',
styleUrls: []
})
export class VersionHistoryComponent {

history$: Observable<MetadataHistory>;

constructor(
private historyService: HistoryService
) {
this.history$ = this.historyService.query();
}
}
5 changes: 5 additions & 0 deletions ui/src/app/metadata/version/model/history.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { MetadataVersion } from './version';

export interface MetadataHistory {
versions: MetadataVersion[];
}
6 changes: 6 additions & 0 deletions ui/src/app/metadata/version/model/version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface MetadataVersion {
versionNumber: Number;
saveDate: Date;
changedBy: String;
actions: string[];
}
28 changes: 28 additions & 0 deletions ui/src/app/metadata/version/service/history.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { TestBed, async, inject } from '@angular/core/testing';
import { HttpClientModule } from '@angular/common/http';
import { HttpTestingController, HttpClientTestingModule } from '@angular/common/http/testing';
import { HistoryService } from './history.service';

describe(`Attributes Service`, () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientModule,
HttpClientTestingModule
],
providers: [
HistoryService
]
});
});

describe('query method', () => {
it(`should return a MetadataHistory`, async(inject([HistoryService, HttpTestingController],
(service: HistoryService) => {
service.query().subscribe(history => {
expect(history).toBeDefined();
});
}
)));
});
});
Loading

0 comments on commit 530d0cd

Please sign in to comment.