diff --git a/src/app/shared/components/no-results/no-results.component.html b/src/app/shared/components/no-results/no-results.component.html index e65c969227..ca92c412f6 100644 --- a/src/app/shared/components/no-results/no-results.component.html +++ b/src/app/shared/components/no-results/no-results.component.html @@ -1,3 +1,3 @@
- {{ 'COMMON.NO_RESULTS' | translate }} + {{ text | translate }}
diff --git a/src/app/shared/components/no-results/no-results.component.ts b/src/app/shared/components/no-results/no-results.component.ts index 90790f39cb..28b8763d3a 100644 --- a/src/app/shared/components/no-results/no-results.component.ts +++ b/src/app/shared/components/no-results/no-results.component.ts @@ -1,8 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, Input } from '@angular/core'; + @Component({ selector: 'cs-no-results', templateUrl: 'no-results.component.html', styleUrls: ['no-results.component.scss'] }) -export class NoResultsComponent {} +export class NoResultsComponent { + @Input() public text = 'COMMON.NO_RESULTS'; +} diff --git a/src/app/shared/components/sidebar/index.ts b/src/app/shared/components/sidebar/index.ts index 075e623908..f7b0fb8b4c 100644 --- a/src/app/shared/components/sidebar/index.ts +++ b/src/app/shared/components/sidebar/index.ts @@ -1 +1 @@ -export * from './sidebar.component'; +export * from './sidebar-container/sidebar-container.component'; diff --git a/src/app/shared/components/sidebar/sidebar.component.html b/src/app/shared/components/sidebar/sidebar-container/sidebar-container.component.html similarity index 100% rename from src/app/shared/components/sidebar/sidebar.component.html rename to src/app/shared/components/sidebar/sidebar-container/sidebar-container.component.html diff --git a/src/app/shared/components/sidebar/sidebar.component.scss b/src/app/shared/components/sidebar/sidebar-container/sidebar-container.component.scss similarity index 96% rename from src/app/shared/components/sidebar/sidebar.component.scss rename to src/app/shared/components/sidebar/sidebar-container/sidebar-container.component.scss index b71c646b3a..2a150b4522 100644 --- a/src/app/shared/components/sidebar/sidebar.component.scss +++ b/src/app/shared/components/sidebar/sidebar-container/sidebar-container.component.scss @@ -1,4 +1,4 @@ -@import '../../../../style/__variables'; +@import '../../../../../style/_variables'; .sidebar { height: 100%; diff --git a/src/app/shared/components/sidebar/sidebar-container/sidebar-container.component.ts b/src/app/shared/components/sidebar/sidebar-container/sidebar-container.component.ts new file mode 100644 index 0000000000..8c77641d85 --- /dev/null +++ b/src/app/shared/components/sidebar/sidebar-container/sidebar-container.component.ts @@ -0,0 +1,23 @@ +import { Component, HostBinding, Input, } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; + + +@Component({ + selector: 'cs-sidebar', + templateUrl: 'sidebar-container.component.html', + styleUrls: ['sidebar-container.component.scss'] +}) +export class SidebarContainerComponent { + @Input() @HostBinding('class.open') public isOpen; + + constructor( + private route: ActivatedRoute, + private router: Router + ) {} + + public onDetailsHide(): void { + this.router.navigate([this.route.parent.snapshot.url], { + queryParamsHandling: 'preserve' + }); + } +} diff --git a/src/app/shared/components/sidebar/sidebar.component.ts b/src/app/shared/components/sidebar/sidebar.component.ts index c5a6b2851d..f22550903f 100644 --- a/src/app/shared/components/sidebar/sidebar.component.ts +++ b/src/app/shared/components/sidebar/sidebar.component.ts @@ -1,38 +1,50 @@ -import { - Component, Input -} from '@angular/core'; -import { DialogService } from '../../../dialog/dialog-module/dialog.service'; +import { OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; +import { Observable } from 'rxjs/Observable'; +import { BaseModel } from '../../models/base.model'; +import { BaseBackendService } from '../../services/base-backend.service'; +import { NotificationService } from '../../services/notification.service'; -@Component({ - selector: 'cs-sidebar', - templateUrl: 'sidebar.component.html', - styleUrls: ['sidebar.component.scss'] -}) -export class SidebarComponent { - @Input() public isOpen = false; - - private dialogsOpen: boolean; // true if any mdl dialog is open - private dialogWasOpen: boolean; // true if last dialog was closed +export abstract class SidebarComponent implements OnInit { + public entity: M; + public notFound: boolean; constructor( - private router: Router, - private route: ActivatedRoute, - private dialogService: DialogService - ) { - this.dialogService.onDialogsOpenChanged - .subscribe(dialogsOpen => { - this.dialogsOpen = dialogsOpen; - if (dialogsOpen) { - this.dialogWasOpen = true; + protected entityService: BaseBackendService, + protected notificationService: NotificationService, + protected route: ActivatedRoute, + protected router: Router + ) {} + + public ngOnInit(): void { + this.pluckId() + .switchMap(id => this.loadEntity(id)) + .subscribe( + entity => this.entity = entity, + error => { + if (error === 'ENTITY_DOES_NOT_EXIST') { + this.onEntityDoesNotExist(); + } else { + this.onError(error); + } } - }); + ); + } + + private pluckId(): Observable { + return this.route.params.pluck('id').filter(id => !!id) as Observable; + } + + protected loadEntity(id: string): Observable { + return this.entityService.get(id); + } + + private onEntityDoesNotExist(): void { + this.notFound = true; } - public onDetailsHide(): void { - this.router.navigate([this.route.parent.snapshot.url], { - queryParamsHandling: 'preserve' - }); + private onError(error: any): void { + this.notificationService.error(error.message); } } diff --git a/src/app/shared/models/volume.model.ts b/src/app/shared/models/volume.model.ts index 671212a446..8e99e39b7a 100644 --- a/src/app/shared/models/volume.model.ts +++ b/src/app/shared/models/volume.model.ts @@ -40,9 +40,10 @@ export class Volume extends BaseModel { public tags: Array; public type: VolumeType; public zoneId: string; - public zoneName: string; + public description: string; + constructor(json) { super(json); this.created = moment(json.created).toDate(); diff --git a/src/app/shared/services/base-backend.service.ts b/src/app/shared/services/base-backend.service.ts index acb9caa5db..e4a7912968 100644 --- a/src/app/shared/services/base-backend.service.ts +++ b/src/app/shared/services/base-backend.service.ts @@ -36,8 +36,8 @@ export abstract class BaseBackendService { throw Error('BaseBackendService.get id not specified!'); } - return this.getList({ id }) - .map(res => res[0] as M); + return this.getList() + .map(res => res.find(entity => entity.id === id)); } public getList(params?: {}, customApiFormat?: ApiFormat): Observable> { diff --git a/src/app/shared/services/volume.service.ts b/src/app/shared/services/volume.service.ts index b6da4c1812..149a658840 100644 --- a/src/app/shared/services/volume.service.ts +++ b/src/app/shared/services/volume.service.ts @@ -44,19 +44,6 @@ export class VolumeService extends BaseBackendService { this.onVolumeAttached = new Subject(); } - public get(id: string): Observable { - const snapshotsRequest = this.snapshotService.getList(id); - const volumeRequest = super.get(id); - - return Observable.forkJoin( - volumeRequest, - snapshotsRequest - ).map(([volume, snapshots]) => { - volume.snapshots = snapshots; - return volume; - }); - } - public getList(params?: {}): Observable> { const volumesRequest = super.getList(params); const snapshotsRequest = this.snapshotService.getList(); @@ -64,14 +51,15 @@ export class VolumeService extends BaseBackendService { return Observable.forkJoin( volumesRequest, snapshotsRequest - ).map(([volumes, snapshots]) => { - volumes.forEach(volume => { - volume.snapshots = snapshots.filter( - (snapshot: Snapshot) => snapshot.volumeId === volume.id - ); + ) + .map(([volumes, snapshots]) => { + volumes.forEach(volume => { + volume.snapshots = snapshots.filter( + (snapshot: Snapshot) => snapshot.volumeId === volume.id + ); + }); + return volumes; }); - return volumes; - }); } public getSpareList(params?: {}): Observable> { diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 6d820f67d4..adf61a3715 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -32,7 +32,7 @@ import { NotificationBoxComponent, NotificationBoxItemComponent, SgRulesManagerComponent, - SidebarComponent, + SidebarContainerComponent, SliderComponent, TopBarComponent, VmStatisticsComponent @@ -154,7 +154,7 @@ import { ZoneService } from './services/zone.service'; OverlayLoadingComponent, SearchComponent, SgRulesManagerComponent, - SidebarComponent, + SidebarContainerComponent, TableComponent, TopBarComponent, VmStatisticsComponent, @@ -206,7 +206,7 @@ import { ZoneService } from './services/zone.service'; ReloadComponent, SearchComponent, SgRulesManagerComponent, - SidebarComponent, + SidebarContainerComponent, TableComponent, TopBarComponent, VmStatisticsComponent, diff --git a/src/app/spare-drive/spare-drive-sidebar/spare-drive-sidebar.component.html b/src/app/spare-drive/spare-drive-sidebar/spare-drive-sidebar.component.html index c25c444982..9a7bc22d80 100644 --- a/src/app/spare-drive/spare-drive-sidebar/spare-drive-sidebar.component.html +++ b/src/app/spare-drive/spare-drive-sidebar/spare-drive-sidebar.component.html @@ -1,12 +1,12 @@ -
- +
+ - +

@@ -16,39 +16,44 @@

-
+
{{ 'SPARE_DRIVE_PAGE.DETAILS.DISK_OFFERING_NAME' | translate }}
-
{{ volume.diskOffering.name }}
+
{{ entity.diskOffering.name }}
-
+
{{ 'SPARE_DRIVE_PAGE.DETAILS.DESCRIPTION' | translate }}
-
{{ volume.diskOffering.displayText }}
+
{{ entity.diskOffering.displayText }}
-
+
{{ 'SPARE_DRIVE_PAGE.DETAILS.MIN_IO' | translate }}
-
{{ volume.diskOffering.minIops }}
+
{{ entity.diskOffering.minIops }}
-
+
{{ 'SPARE_DRIVE_PAGE.DETAILS.MAX_IO' | translate }}
-
{{ volume.diskOffering.maxIops }}
+
{{ entity.diskOffering.maxIops }}
-
+
{{ 'SPARE_DRIVE_PAGE.DETAILS.READ_RATE_MB' | translate }}
-
{{ 'UNITS.MBPS' | translate:{ value: volume.diskOffering.diskBytesReadRate | division:10:6 } }}
+
{{ 'UNITS.MBPS' | translate:{ value: entity.diskOffering.diskBytesReadRate | division:10:6 } }}
-
+
{{ 'SPARE_DRIVE_PAGE.DETAILS.WRITE_RATE_MB' | translate }}
-
{{ 'UNITS.MBPS' | translate:{ value: volume.diskOffering.diskBytesWriteRate | division:10:6 } }}
+
{{ 'UNITS.MBPS' | translate:{ value: entity.diskOffering.diskBytesWriteRate | division:10:6 } }}
-
+
{{ 'SPARE_DRIVE_PAGE.DETAILS.READ_RATE_IOPS' | translate }}
-
{{ 'UNITS.IOPS' | translate:{ value: volume.diskOffering.diskIopsReadRate } }}
+
{{ 'UNITS.IOPS' | translate:{ value: entity.diskOffering.diskIopsReadRate } }}
-
+
{{ 'SPARE_DRIVE_PAGE.DETAILS.WRITE_RATE_IOPS' | translate }}
-
{{ 'UNITS.IOPS' | translate:{ value: volume.diskOffering.diskIopsWriteRate } }}
+
{{ 'UNITS.IOPS' | translate:{ value: entity.diskOffering.diskIopsWriteRate } }}
+ + + + + diff --git a/src/app/spare-drive/spare-drive-sidebar/spare-drive-sidebar.component.ts b/src/app/spare-drive/spare-drive-sidebar/spare-drive-sidebar.component.ts index ddef7b10e0..c0ff2ef6f2 100644 --- a/src/app/spare-drive/spare-drive-sidebar/spare-drive-sidebar.component.ts +++ b/src/app/spare-drive/spare-drive-sidebar/spare-drive-sidebar.component.ts @@ -1,57 +1,61 @@ -import { Component, HostBinding, Input } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; +import { Component, HostBinding } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; import { Observable } from 'rxjs/Observable'; +import { SidebarComponent } from '../../shared/components/sidebar/sidebar.component'; import { Volume } from '../../shared/models'; import { VolumeType } from '../../shared/models/volume.model'; import { DateTimeFormatterService } from '../../shared/services/date-time-formatter.service'; import { DiskOfferingService } from '../../shared/services/disk-offering.service'; -import { VolumeTagService } from '../../shared/services/tags/volume-tag.service'; +import { NotificationService } from '../../shared/services/notification.service'; import { VolumeService } from '../../shared/services/volume.service'; +import { VolumeTagService } from '../../shared/services/tags/volume-tag.service'; @Component({ selector: 'cs-spare-drive-sidebar', templateUrl: 'spare-drive-sidebar.component.html' }) -export class SpareDriveSidebarComponent { - public description: string; - - @Input() public volume: Volume; +export class SpareDriveSidebarComponent extends SidebarComponent { @HostBinding('class.grid') public grid = true; constructor( public dateTimeFormatterService: DateTimeFormatterService, - private diskOfferingService: DiskOfferingService, - private route: ActivatedRoute, - private volumeService: VolumeService, - private volumeTagService: VolumeTagService, + protected notificationService: NotificationService, + protected route: ActivatedRoute, + protected router: Router, + protected volumeService: VolumeService, + protected volumeTagService: VolumeTagService, + private diskOfferingService: DiskOfferingService ) { - this.route.params.pluck('id') - .subscribe((id: string) => { - if (!id) { - return; - } - - Observable.forkJoin( - this.diskOfferingService.getList({ type: VolumeType.DATADISK }), - this.volumeService.get(id) - ) - .subscribe(([diskOfferings, volume]) => { - this.volumeTagService.getDescription(volume) - .subscribe(description => { - volume.diskOffering = diskOfferings.find( - offering => offering.id === volume.diskOfferingId - ); - this.volume = volume; - this.description = description; - }); - }); - }); + super(volumeService, notificationService, route, router); } public changeDescription(newDescription: string): void { - this.volumeTagService.setDescription(this.volume, newDescription) + this.volumeTagService.setDescription(this.entity, newDescription) .onErrorResumeNext() .subscribe(); } + + protected loadEntity(id: string): Observable { + return this.volumeService.get(id) + .switchMap(volume => { + if (volume) { + return Observable.of(volume); + } else { + return Observable.throw('ENTITY_DOES_NOT_EXIST'); + } + }) + .switchMap(volume => { + return Observable.forkJoin( + Observable.of(volume), + this.diskOfferingService.getList({ type: VolumeType.DATADISK }), + this.volumeTagService.getDescription(volume) + ); + }) + .map(([volume, diskOfferings, description]) => { + volume.diskOffering = diskOfferings.find(_ => _.id === volume.diskOfferingId); + volume.description = description; + return volume; + }); + } } diff --git a/src/app/template/shared/base-template.service.ts b/src/app/template/shared/base-template.service.ts index 353f2d57b4..6aa8d109d5 100644 --- a/src/app/template/shared/base-template.service.ts +++ b/src/app/template/shared/base-template.service.ts @@ -89,7 +89,8 @@ export abstract class BaseTemplateService extends BaseBackendCachedService> { return this.getListWithDuplicates(params, useCache) - .map(templates => this.distinctIds(templates)); + .map(templates => this.distinctIds(templates)) + .catch(() => Observable.of([])); } public getListWithDuplicates(params: RequestParams, useCache = true): Observable> { @@ -118,23 +119,27 @@ export abstract class BaseTemplateService extends BaseBackendCachedService Utils.convertToGB(template.size) <= maxSize); } return templates; - }); + }) + .catch(() => Observable.of([])); } public getWithGroupedZones(id: string, params?: RequestParams, useCache = true): Observable { const filter = params && params.filter ? params.filter : TemplateFilters.featured; return this.getListWithDuplicates({ id, filter }, useCache) .map(templates => { - templates[0].zones = []; - templates.forEach(template => { - templates[0].zones.push({ - created: template.created, - zoneId: template.zoneId, - zoneName: template.zoneName, - status: template.status, - isReady: template.isReady + if (templates.length) { + templates[0].zones = []; + + templates.forEach(template => { + templates[0].zones.push({ + created: template.created, + zoneId: template.zoneId, + zoneName: template.zoneName, + status: template.status, + isReady: template.isReady + }); }); - }); + } return templates[0]; }); diff --git a/src/app/template/template-sidebar/base-template-sidebar.component.html b/src/app/template/template-sidebar/base-template-sidebar.component.html index eaece3ab18..834ee685f4 100644 --- a/src/app/template/template-sidebar/base-template-sidebar.component.html +++ b/src/app/template/template-sidebar/base-template-sidebar.component.html @@ -1,4 +1,4 @@ -
+
@@ -10,7 +10,7 @@ @@ -22,49 +22,49 @@

{{ "TEMPLATE_PAGE.TEMPLATE_DETAILS.DETAILS" | tra
-
+
{{ 'TEMPLATE_PAGE.TEMPLATE_DETAILS.SIZE' | translate }}
-
{{ template.size | division:2:30:2 }} {{ 'UNITS.GB' | translate }}
+
{{ entity.size | division:2:30:2 }} {{ 'UNITS.GB' | translate }}
{{ 'TEMPLATE_PAGE.TEMPLATE_DETAILS.EXTRACTABLE' | translate }}
-
{{ template.isExtractable | viewValue | async }}
+
{{ entity.isExtractable | viewValue | async }}
{{ 'TEMPLATE_PAGE.TEMPLATE_DETAILS.PUBLIC' | translate }}
-
{{ template.isPublic | viewValue | async }}
+
{{ entity.isPublic | viewValue | async }}
{{ 'TEMPLATE_PAGE.TEMPLATE_DETAILS.RECOMMENDED' | translate }}
-
{{ template.isFeatured | viewValue | async }}
+
{{ entity.isFeatured | viewValue | async }}
-
+
{{ 'TEMPLATE_PAGE.TEMPLATE_DETAILS.PASSWORD_ENABLED' | translate }}
-
{{ template.isPasswordEnabled | viewValue | async }}
+
{{ entity.isPasswordEnabled | viewValue | async }}
-
+
{{ 'TEMPLATE_PAGE.TEMPLATE_DETAILS.DYNAMICALLY_SCALABLE' | translate }}
-
{{ template.isDynamicallyScalable | viewValue | async }}
+
{{ entity.isDynamicallyScalable | viewValue | async }}
{{ 'TEMPLATE_PAGE.TEMPLATE_DETAILS.CROSS_ZONES' | translate }}
-
{{ template.crossZones | viewValue | async }}
+
{{ entity.crossZones | viewValue | async }}
{{ 'TEMPLATE_PAGE.TEMPLATE_DETAILS.DOMAIN' | translate }}
-
{{ template.domain }}
+
{{ entity.domain }}
{{ 'TEMPLATE_PAGE.TEMPLATE_DETAILS.CREATED' | translate }}
-
{{ template.created | stringifyDate }}
+
{{ entity.created | stringifyDate }}
-
+
{{ 'TEMPLATE_PAGE.TEMPLATE_DETAILS.TYPE' | translate }}
{{ templateTypeTranslationToken | translate }}
-
+
{{ 'TEMPLATE_PAGE.TEMPLATE_DETAILS.HYPERVISOR' | translate }}
-
{{ template.hypervisor }}
+
{{ entity.hypervisor }}
@@ -112,7 +112,7 @@

{{ "TEMPLATE_PAGE.TEMPLATE_DETAILS.DETAILS" | tra
{{ 'COMMON.UPDATE' | translate }}
- +

{{ zone.zoneName }}

@@ -137,7 +137,11 @@

{{ zone.zoneName }}

local_offer

- +
+ + + + diff --git a/src/app/template/template-sidebar/base-template-sidebar.component.ts b/src/app/template/template-sidebar/base-template-sidebar.component.ts index 67b2f1cdb2..90ca06d364 100644 --- a/src/app/template/template-sidebar/base-template-sidebar.component.ts +++ b/src/app/template/template-sidebar/base-template-sidebar.component.ts @@ -1,44 +1,39 @@ -import { Input, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { BaseTemplateModel } from '../shared/base-template.model'; -import { TemplateActionsService } from '../shared/template-actions.service'; -import { ListService } from '../../shared/components/list/list.service'; -import { BaseTemplateService } from '../shared/base-template.service'; +import { OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { Observable } from 'rxjs/Observable'; import { DialogService } from '../../dialog/dialog-module/dialog.service'; -import { NotificationService } from '../../shared/services/notification.service'; +import { ListService } from '../../shared/components/list/list.service'; +import { SidebarComponent } from '../../shared/components/sidebar/sidebar.component'; import { DateTimeFormatterService } from '../../shared/services/date-time-formatter.service'; +import { NotificationService } from '../../shared/services/notification.service'; +import { BaseTemplateModel } from '../shared/base-template.model'; +import { BaseTemplateService } from '../shared/base-template.service'; +import { TemplateActionsService } from '../shared/template-actions.service'; +import { TemplateTagKeys } from '../../shared/services/tags/template-tag-keys'; -export abstract class BaseTemplateSidebarComponent implements OnInit { - @Input() public template: BaseTemplateModel; +export abstract class BaseTemplateSidebarComponent extends SidebarComponent implements OnInit { + public templateDownloadUrl: string; public readyInEveryZone: boolean; public updating: boolean; - private service: BaseTemplateService; constructor( service: BaseTemplateService, public dateTimeFormatterService: DateTimeFormatterService, - private route: ActivatedRoute, private dialogService: DialogService, - private notificationService: NotificationService, - protected templateActions: TemplateActionsService, + protected route: ActivatedRoute, + protected router: Router, protected listService: ListService, + protected notificationService: NotificationService, + protected templateActions: TemplateActionsService ) { + super(service, notificationService, route, router); this.service = service; } - public ngOnInit(): void { - this.route.params.pluck('id').filter(id => !!id).subscribe((id: string) => { - this.service.getWithGroupedZones(id).subscribe(template => { - this.template = template; - this.checkZones(); - }); - }); - } - public get templateTypeTranslationToken(): string { - const type = this.template && (this.template as any).type || ''; + const type = this.entity && (this.entity as any).type || ''; const templateTypeTranslations = { 'BUILTIN': 'Built-in', 'USER': 'User' @@ -48,30 +43,26 @@ export abstract class BaseTemplateSidebarComponent implements OnInit { } public remove(): void { - this.templateActions.removeTemplate(this.template).subscribe(() => { - this.listService.onUpdate.emit(this.template); + this.templateActions.removeTemplate(this.entity).subscribe(() => { + this.listService.onUpdate.emit(this.entity); }); } public updateStatus(): void { - if (this.template) { + if (this.entity) { this.updating = true; - this.service.getWithGroupedZones(this.template.id, null, false) + this.service.getWithGroupedZones(this.entity.id, null, false) .finally(() => this.updating = false) .subscribe( template => { - this.template = template; - this.checkZones(); + this.entity = template; + this.checkZones(template); }, error => this.dialogService.alert(error.message) ); } } - private checkZones(): void { - this.readyInEveryZone = this.template.zones.every(template => template.isReady); - } - public onCopySuccess(): void { this.notificationService.message('COPY_SUCCESS'); } @@ -79,4 +70,28 @@ export abstract class BaseTemplateSidebarComponent implements OnInit { public onCopyFail(): void { this.notificationService.message('COPY_FAIL'); } + + private checkZones(template: BaseTemplateModel): void { + this.readyInEveryZone = template && template.zones.every(_ => _.isReady); + } + + protected loadEntity(id: string): Observable { + return this.service.getWithGroupedZones(id) + .switchMap(template => { + if (template) { + return Observable.of(template); + } else { + return Observable.throw('ENTITY_DOES_NOT_EXIST'); + } + }) + .do(template => { + const downloadUrlTag = template.tags.find( + tag => tag.key === TemplateTagKeys.downloadUrl + ); + if (downloadUrlTag) { + this.templateDownloadUrl = downloadUrlTag.value; + } + this.checkZones(template); + }); + } } diff --git a/src/app/template/template-sidebar/iso-sidebar.component.ts b/src/app/template/template-sidebar/iso-sidebar.component.ts index 678fb26013..870cf8f623 100644 --- a/src/app/template/template-sidebar/iso-sidebar.component.ts +++ b/src/app/template/template-sidebar/iso-sidebar.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { ListService } from '../../shared/components/list/list.service'; import { IsoService } from '../shared'; import { TemplateActionsService } from '../shared/template-actions.service'; @@ -18,6 +18,7 @@ export class IsoSidebarComponent extends BaseTemplateSidebarComponent { isoService: IsoService, dateTimeFormatterService: DateTimeFormatterService, route: ActivatedRoute, + router: Router, templateActions: TemplateActionsService, listService: ListService, dialogService: DialogService, @@ -26,11 +27,12 @@ export class IsoSidebarComponent extends BaseTemplateSidebarComponent { super( isoService, dateTimeFormatterService, - route, dialogService, + route, + router, + listService, notificationService, - templateActions, - listService + templateActions ); } } diff --git a/src/app/template/template-sidebar/template-sidebar.component.ts b/src/app/template/template-sidebar/template-sidebar.component.ts index 21d2476c6c..11d1a35a32 100644 --- a/src/app/template/template-sidebar/template-sidebar.component.ts +++ b/src/app/template/template-sidebar/template-sidebar.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { TemplateService } from '../shared'; import { BaseTemplateSidebarComponent } from './base-template-sidebar.component'; import { TemplateActionsService } from '../shared/template-actions.service'; @@ -18,6 +18,7 @@ export class TemplateSidebarComponent extends BaseTemplateSidebarComponent { templateService: TemplateService, dateTimeFormatterService: DateTimeFormatterService, route: ActivatedRoute, + router: Router, templateActions: TemplateActionsService, listService: ListService, dialogService: DialogService, @@ -26,11 +27,12 @@ export class TemplateSidebarComponent extends BaseTemplateSidebarComponent { super( templateService, dateTimeFormatterService, - route, dialogService, + route, + router, + listService, notificationService, - templateActions, - listService + templateActions ); } } diff --git a/src/app/vm/shared/vm.service.ts b/src/app/vm/shared/vm.service.ts index 3e3980bc01..197aa7d4f9 100644 --- a/src/app/vm/shared/vm.service.ts +++ b/src/app/vm/shared/vm.service.ts @@ -71,10 +71,11 @@ export class VmService extends BaseBackendService { public getListWithDetails(params?: {}, customApiFormat?: ApiFormat, lite = false): Observable> { if (lite) { - return super.getList(params); + return this.getList(params); } + return Observable.forkJoin( - super.getList(params), + this.getList(params), this.volumeService.getList(), this.osTypesService.getList(), this.serviceOfferingService.getList(), diff --git a/src/app/vm/vm-sidebar/vm-sidebar.component.html b/src/app/vm/vm-sidebar/vm-sidebar.component.html index f074bb27f2..2e6015a687 100644 --- a/src/app/vm/vm-sidebar/vm-sidebar.component.html +++ b/src/app/vm/vm-sidebar/vm-sidebar.component.html @@ -1,39 +1,41 @@ -
-
-

{{ vm.displayName }}

- - - -
- computer -
-
- -
- - -
- storage -
-
- -
- - -
- router -
-
- -
- - -
- local_offer -
-
- -
-
-
-
+ +

{{ entity.displayName }}

+ + + +
+ computer +
+
+ +
+ + +
+ storage +
+
+ +
+ + +
+ router +
+
+ +
+ + +
+ local_offer +
+
+ +
+
+
+ + + + diff --git a/src/app/vm/vm-sidebar/vm-sidebar.component.scss b/src/app/vm/vm-sidebar/vm-sidebar.component.scss index 3112edcc1a..34e9d9e9db 100644 --- a/src/app/vm/vm-sidebar/vm-sidebar.component.scss +++ b/src/app/vm/vm-sidebar/vm-sidebar.component.scss @@ -8,4 +8,4 @@ h4.details-header { :host /deep/ .mat-tab-label { min-width: 83px !important; -} \ No newline at end of file +} diff --git a/src/app/vm/vm-sidebar/vm-sidebar.component.ts b/src/app/vm/vm-sidebar/vm-sidebar.component.ts index c1ed4dcac1..602f8b2c00 100644 --- a/src/app/vm/vm-sidebar/vm-sidebar.component.ts +++ b/src/app/vm/vm-sidebar/vm-sidebar.component.ts @@ -1,9 +1,10 @@ -import { Component, Input } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; - +import { Component } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { SidebarComponent } from '../../shared/components/sidebar/sidebar.component'; +import { NotificationService } from '../../shared/services/notification.service'; import { VirtualMachine } from '../shared/vm.model'; import { VmService } from '../shared/vm.service'; -import { NotificationService } from '../../shared/services/notification.service'; +import { Observable } from 'rxjs/Observable'; @Component({ @@ -11,20 +12,24 @@ import { NotificationService } from '../../shared/services/notification.service' templateUrl: 'vm-sidebar.component.html', styleUrls: ['vm-sidebar.component.scss'] }) -export class VmSidebarComponent { - @Input() public vm: VirtualMachine; - +export class VmSidebarComponent extends SidebarComponent { constructor( - private vmService: VmService, - private notificationService: NotificationService, - private route: ActivatedRoute + protected vmService: VmService, + protected notificationService: NotificationService, + protected route: ActivatedRoute, + protected router: Router ) { - this.route.params.pluck('id') - .filter(id => !!id) - .switchMap((id: string) => this.vmService.getWithDetails(id)) - .subscribe( - vm => this.vm = vm, - (error) => this.notificationService.error(error.message) - ); + super(vmService, notificationService, route, router); + } + + protected loadEntity(id: string): Observable { + return this.vmService.getWithDetails(id) + .switchMap(vm => { + if (vm) { + return Observable.of(vm); + } else { + return Observable.throw('ENTITY_DOES_NOT_EXIST'); + } + }); } } diff --git a/src/i18n/en.json b/src/i18n/en.json index 6700f74313..e07236941b 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -772,6 +772,10 @@ "SELECT_AN_OPTION": "Select an option" }, + "VM_NOT_FOUND": "Virtual machine not found", + "VOLUME_NOT_FOUND": "Volume not found", + "TEMPLATE_NOT_FOUND": "Template not found", + "PULSE": { "PULSE": "Pulse", "CPU_RAM": "CPU / RAM", diff --git a/src/i18n/ru.json b/src/i18n/ru.json index 5cc8ada27b..07fe132905 100644 --- a/src/i18n/ru.json +++ b/src/i18n/ru.json @@ -772,6 +772,10 @@ "SELECT_AN_OPTION": "Выберите опцию" }, + "VM_NOT_FOUND": "Виртуальная машина не найдена", + "VOLUME_NOT_FOUND": "Диск не найден", + "TEMPLATE_NOT_FOUND": "Шаблон не найден", + "PULSE": { "PULSE": "Pulse", "CPU_RAM": "ЦП / ОЗУ",