diff options
author | Yoav Schneiderman <yoav.schneiderman@intl.att.com> | 2019-12-03 12:55:39 +0200 |
---|---|---|
committer | Ittay Stern <ittay.stern@att.com> | 2019-12-04 17:24:17 +0200 |
commit | 2603481cc6487b0932458ebc7eb4e53202d3f24e (patch) | |
tree | ebd3d1b6178adfddaf53e6d10f3237768062ce75 /vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal | |
parent | ce1a30dd1159eb31c2662cf93daee52c90d272d9 (diff) |
Adding Template button to new service instance + cypress test + filter
Issue-ID: VID-724
Change-Id: Ie69a32dd6b74de57fd747a92935c1ce5edb86351
Signed-off-by: Yoav Schneiderman <yoav.schneiderman@intl.att.com>
Signed-off-by: Ittay Stern <ittay.stern@att.com>
Diffstat (limited to 'vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal')
6 files changed, 607 insertions, 0 deletions
diff --git a/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.modal.component.html b/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.modal.component.html new file mode 100644 index 000000000..c231c6081 --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.modal.component.html @@ -0,0 +1,161 @@ +<div id="template-popup" class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" + class="close" + (click)="closeModal()">× + </button> + <span [attr.data-tests-id]="'template-modal-title'" + class="modal-title">Templates + </span> + </div> + <div class="modal-body templateModalBody"> + <div class="row description-section"> + <div class="col-md-6"> + <div [attr.data-tests-id]="'description-part-1'">The following list presents previous instantiations done for + this model in this version. + </div> + <div [attr.data-tests-id]="'description-part-2'">You may use one of them as a baseline for your instantiation + or start from scratch. + </div> + <div [attr.data-tests-id]="'description-part-3'">Once you selecting one allows you to change the data before + start instantiating. + </div> + </div> + <div class="col-md-6"> + <input + (keypress)="onFilterKeypress($event)" + class="filter-input form-control input-text" + placeholder="Filter..."> + </div> + + </div> + <div class="row" style="margin-left: 0;margin-right: 0;padding: 20px;"> + <table id="member-table" class="table table-bordered" style="table-layout: fixed"> + <thead class="thead-dark"> + <tr> + <th class="header-title" id="header-userId">User ID</th> + <th class="header-title" id="header-createDate" style="width: 21ch;">Date</th> + <th class="header-title" id="header-instanceName" style="max-width: 50ch;">Instance Name</th> + <th class="header-title" id="header-instantiationStatus">Instantiation Status</th> + <th class="header-title" id="header-summary">Summary</th> + <th class="header-title" id="header-region">Region</th> + <th class="header-title" id="header-tenant">Tenant</th> + <th class="header-title" id="header-aicZone">AIC Zone</th> + </tr> + </thead> + <tbody> + <tr class="member-table-row" + *ngFor="let item of filterTableData;" + (click)="selectedJobId = item.jobId" + [ngClass]="{'selected' : selectedJobId === item.jobId}" + [attr.data-tests-id]="'row-' + item.jobId"> + <td> + <div> + <custom-ellipsis + [dataTestId]="'userId-' + item.jobId" + [id]="item.userId" + [value]="item.userId" + [breakWord]="true"> + </custom-ellipsis> + </div> + </td> + <td style="width: 21ch;"> + <div> + <custom-ellipsis + [dataTestId]="'createDate-' + item.jobId" + [id]="item.createDate" + [value]="item.createDate" + [breakWord]="true"> + </custom-ellipsis> + </div> + </td> + <td style="max-width: 50ch;"> + <div> + <custom-ellipsis + [showDots]="true" + [dataTestId]="'instanceName-' + item.jobId" + [id]="item.instanceName" + [value]="item.instanceName" + [breakWord]="true"> + </custom-ellipsis> + </div> + </td> + <td> + <div> + <custom-ellipsis + [showDots]="true" + [dataTestId]="'instantiationStatus-' + item.jobId" + [id]="item.instantiationStatus" + [value]="item.instantiationStatus" + [breakWord]="true"> + </custom-ellipsis> + </div> + </td> + <td> + <div> + <custom-ellipsis + [dataTestId]="'summary-' + item.jobId" + [id]="item.summary" + [value]="item.summary" + [breakWord]="true"> + </custom-ellipsis> + </div> + </td> + <td> + <div> + <custom-ellipsis + [showDots]="true" + [dataTestId]="'region-' + item.jobId" + [id]="item.region" + [value]="item.region" + [breakWord]="true"> + </custom-ellipsis> + </div> + </td> + <td> + <div> + <custom-ellipsis + [showDots]="true" + [dataTestId]="'tenant-' + item.jobId" + [id]="item.tenant" + [value]="item.tenant" + [breakWord]="true"> + </custom-ellipsis> + </div> + </td> + <td> + <div> + <custom-ellipsis + [dataTestId]="'aicZone-' + item.jobId" + [id]="item.aicZone" + [value]="item.aicZone" + [breakWord]="true"> + </custom-ellipsis> + </div> + </td> + </tr> + </tbody> + </table> + </div> + + </div> + <div class="modal-footer row" style="padding: 0"> + <div class="col-md-6"> + </div> + <div class="col-md-6" style="padding: 15px;padding-right: 35px;"> + <button + [disabled]="selectedJobId === null" + [attr.data-tests-id]="'LoadTemplateButton'" + type="button" class="btn btn-primary submit" + (click)="loadTemplate()"><span>Load Template</span> + </button> + <button + [attr.data-tests-id]="'startFromScratchButton'" + type="button" class="btn btn-success submit startFromScratchButton" + (click)="closeModal()"><span>Start from Scratch</span> + </button> + </div> + </div> + </div> +</div> diff --git a/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.modal.component.scss b/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.modal.component.scss new file mode 100644 index 000000000..23c950c33 --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.modal.component.scss @@ -0,0 +1,192 @@ +$grid-border: 1px #d2d2d2 solid; + +#template-popup { + color: #191919; + + thead { + background: #F8F8F8; + } + .left-panel { + background: #f2f2f2; + border-right: $grid-border; + } + + .header-common { + height: 100%; + align-items: center; + display: flex; + font-family: OpenSans-Semibold; + font-size: 12px; + } + + .header-text { + padding-left: 30px; + @extend .header-common; + } + + .header-left { + grid-area: header-left; + @extend .header-text; + @extend .left-panel; + border-bottom: $grid-border; + + span { + font-family: OpenSans-Regular; + font-size: 14px; + } + ; + } + + .header-right { + grid-area: header-right; + + @extend .header-text; + } + + .quantity-label { + grid-area: quantity-label; + @extend .header-common; + height: 100%; + font-family: OpenSans-Regular; + } + + input[type="number"]:hover::-webkit-inner-spin-button { + height: 20px; + } + + .popup-content { + display: grid; + grid-template-columns: 400px auto 30px 93px; + grid-template-rows: 50px calc(100vh - 180px); + grid-template-areas: "header-left header-right quantity-label quantity" "model-information instance-form instance-form instance-form"; + padding: 0; + } +} + +.modal { + background-color: #191919; + opacity: 0.8; +} + +.modal-dialog { + position: relative; + width: auto; + margin: 0; +} + +@media (min-width: 1150px) { + .popup-content { + grid-template-rows: 30px 680px; + } +} + +.modal-content { + border-radius: 0; + box-shadow: none; + border: none; + min-height: calc(100vh); + +} + +.modal-footer { + padding: 0; + position: absolute; + bottom: 0; + width: 100%; + + .cancel { + width: 120px; + height: 36px; + background: #ffffff; + border: 1px solid #009fdb; + border-radius: 2px; + + span { + font-family: OpenSans-Regular; + font-size: 14px; + color: #009fdb; + line-height: 16px; + } + } + + .startFromScratchButton { + width: 150px !important; + } + + .submit { + width: 120px; + height: 36px; + background: #009fdb; + border-radius: 2px; + border-color: #009fdb; + + + span { + font-family: OpenSans-Regular; + font-size: 14px; + color: #FFFFFF; + line-height: 16px; + } + } +} + +.modal-header { + background-color: #009fdb; + + padding-bottom: 13px; + padding-top: 13px; + padding-left: 29px; + padding-right: 21px; + + .close { + font-size: 32px; + font-weight: 200; + color: #d8d8d8; + text-shadow: none; + filter: none; + opacity: 1; + } + + .modal-title { + font-family: OpenSans-Regular; + font-size: 24px; + color: #fff; + line-height: 34px; + } +} + +.modal-body { + padding: 0; + height: calc(85vh); + + .description-section { + padding: 20px; + font-size: 20px; + } + + .filter-input { + float: right; + width: 25%; + } + + + td.loadTemplateButton { + text-align: center; + vertical-align: middle; + } + + td { + text-align: center; + vertical-align: middle; + padding-left: 5px; + padding-right: 5px; + } + + .member-table-row:hover { + background: #80808033 !important; + } + + .member-table-row.selected { + background: #009fdbb5 !important; + } +} diff --git a/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.modal.component.ts b/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.modal.component.ts new file mode 100644 index 000000000..56abe5b4c --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.modal.component.ts @@ -0,0 +1,55 @@ +import {Component, OnDestroy, OnInit} from "@angular/core"; +import {DialogComponent, DialogService} from "ng2-bootstrap-modal"; +import {IframeService} from "../../../utils/iframe.service"; +import {ActivatedRoute} from "@angular/router"; +import {ServiceInfoService} from "../../../server/serviceInfo/serviceInfo.service"; +import {InstantiationTemplatesModalService} from "./instantiation.templates.modal.service"; +import {InstantiationTemplatesRowModel} from "./instantiation.templates.row.model"; + +@Component({ + selector: 'template-modal', + templateUrl: 'instantiation.templates.modal.component.html', + styleUrls: ['instantiation.templates.modal.component.scss'] +}) + +export class InstantiationTemplatesModalComponent extends DialogComponent<string, boolean> implements OnInit, OnDestroy { + + selectedJobId : string = null; + templateModalComponentService: InstantiationTemplatesModalService; + originalTableData: InstantiationTemplatesRowModel[] = []; + filterTableData : InstantiationTemplatesRowModel[] = []; + + constructor(dialogService: DialogService, + private _iframeService: IframeService, + private _serviceInfoService: ServiceInfoService, + private _templateModalComponentService: InstantiationTemplatesModalService, + private _route: ActivatedRoute) { + super(dialogService); + this.templateModalComponentService = _templateModalComponentService; + } + + ngOnInit(): void { + this._route + .queryParams + .subscribe(params => { + this._serviceInfoService.getServicesJobInfo(true, params['serviceModelId']).subscribe((jobs) => { + this.originalTableData = this._templateModalComponentService.convertResponseToUI(jobs); + this.filterTableData = this.originalTableData; + }); + }); + } + + loadTemplate = () => { + + }; + + + onFilterKeypress = (event : KeyboardEvent) => { + //event.target.value + console.log(event.altKey); + }; + + closeModal(): void { + this.dialogService.removeDialog(this); + } +} diff --git a/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.modal.service.spec.ts b/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.modal.service.spec.ts new file mode 100644 index 000000000..f3bd9152e --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.modal.service.spec.ts @@ -0,0 +1,133 @@ +import {getTestBed, TestBed} from '@angular/core/testing'; +import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing'; +import {InstantiationTemplatesModalService} from "./instantiation.templates.modal.service"; +import {AaiService} from "../../../services/aaiService/aai.service"; +import {ActivatedRoute} from "@angular/router"; +import {IframeService} from "../../../utils/iframe.service"; +import {NgRedux} from "@angular-redux/store"; +import {FeatureFlagsService} from "../../../services/featureFlag/feature-flags.service"; +import {InstantiationTemplatesRowModel} from "./instantiation.templates.row.model"; + + +class ActivatedRouteMock<T> { + queryParams() { + return { + serviceModelId: '6e59c5de-f052-46fa-aa7e-2fca9d674c44' + } + } +} + +class MockAppStore { + +} + +describe('instantiation templates modal service', () => { + let injector; + let service: InstantiationTemplatesModalService; + let httpMock: HttpTestingController; + let _aaiService: AaiService; + let _activatedRoute: ActivatedRoute; + + beforeAll(done => (async () => { + TestBed.configureTestingModule({ + imports: [HttpClientTestingModule], + providers: [InstantiationTemplatesModalService, + IframeService, + AaiService, + FeatureFlagsService, + {provide: ActivatedRoute, useClass: ActivatedRouteMock}, + {provide: NgRedux, useClass: MockAppStore} + ] + }); + await TestBed.compileComponents(); + + injector = getTestBed(); + service = injector.get(InstantiationTemplatesModalService); + httpMock = injector.get(HttpTestingController); + _aaiService = injector.get(AaiService); + _activatedRoute = injector.get(ActivatedRoute); + + })().then(done).catch(done.fail)); + + + test('service should be defined', () => { + expect(service).toBeDefined(); + }); + + + test('convertResponseToUI - should return table data', () => { + const jobs = [{ + "id": 5, + "created": 1524995555000, + "modified": 1524995556000, + "action": "INSTANTIATE", + "createdId": null, + "modifiedId": null, + "rowNum": null, + "auditUserId": null, + "auditTrail": null, + "jobId": "9f88fdb5-bb47-4bf3-8c5f-98f1ad0ec87c", + "templateId": "ce4ec177-cfc8-483e-8a2c-b7aea53fd740", + "userId": "16807000", + "msoRequestId": "c0011670-0e1a-4b74-945d-8bf5aede1d91", + "requestId": null, + "jobStatus": "FAILED", + "statusModifiedDate": 1524995555000, + "hidden": false, + "pause": false, + "owningEntityId": "aaa1", + "owningEntityName": "aaa1", + "project": "WATKINS", + "aicZoneId": "BAN1", + "aicZoneName": "VSDKYUTP-BAN1", + "tenantId": "1178612d2b394be4834ad77f567c0af2", + "tenantName": "AIN Web Tool-15-D-SSPtestcustome", + "regionId": "hvf6", + "regionName": null, + "serviceType": "TYLER SILVIA", + "subscriberName": "e433710f-9217-458d-a79d-1c7aff376d89", + "serviceInstanceId": null, + "serviceInstanceName": 'serviceInstanceName', + "serviceModelId": "e49fbd11-e60c-4a8e-b4bf-30fbe8f4fcc0", + "serviceModelName": "ComplexService", + "serviceModelVersion": "1.0", + "createdBulkDate": 1524995555000, + "isRetryEnabled": false + }]; + const tableRows: InstantiationTemplatesRowModel[] = service.convertResponseToUI(jobs); + expect(tableRows).toHaveLength(1); + expect(tableRows[0].userId).toEqual('16807000'); + expect(tableRows[0].createDate).toEqual('2018-04-29 12:52:35'); + expect(tableRows[0].instanceName).toEqual('serviceInstanceName'); + expect(tableRows[0].instantiationStatus).toEqual('FAILED'); + expect(tableRows[0].region).toEqual('hvf6 (AAA1)'); + expect(tableRows[0].tenant).toEqual('AIN Web Tool-15-D-SSPtestcustome'); + expect(tableRows[0].aicZone).toEqual('VSDKYUTP-BAN1'); + expect(tableRows[0].jobId).toEqual('9f88fdb5-bb47-4bf3-8c5f-98f1ad0ec87c'); + }); + + + test('getCloudOwner should remove "-att" from owningEntityName : "att-owner', () => { + let result: InstantiationTemplatesRowModel = new InstantiationTemplatesRowModel({ + owningEntityName: 'att-owner', + regionId: 'regionId' + }); + expect(result.region).toEqual('regionId (OWNER)'); + }); + + test('getCloudOwner should not return owningEntityName if not exist', () => { + let result: InstantiationTemplatesRowModel = new InstantiationTemplatesRowModel({owningEntityName: null, regionId: 'regionId'}); + expect(result.region).toEqual('regionId'); + }); + + test('getInstanceName should return instance name id exist if not exist', () => { + let result: InstantiationTemplatesRowModel = new InstantiationTemplatesRowModel({serviceInstanceName: 'instanceName'}); + expect(result.instanceName).toEqual('instanceName'); + }); + + test('getInstanceName should return <Automatically generated> if instance name not exist', () => { + let result: InstantiationTemplatesRowModel = new InstantiationTemplatesRowModel({}); + expect(result.instanceName).toEqual('<Automatically generated>'); + }); + +}); diff --git a/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.modal.service.ts b/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.modal.service.ts new file mode 100644 index 000000000..7126da36a --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.modal.service.ts @@ -0,0 +1,15 @@ +import {Injectable} from "@angular/core"; +import {InstantiationTemplatesRowModel} from "./instantiation.templates.row.model"; + +@Injectable() +export class InstantiationTemplatesModalService { + convertResponseToUI = (jobsResponse: any[]): InstantiationTemplatesRowModel[] => { + let tableRows: InstantiationTemplatesRowModel[] = []; + + jobsResponse.forEach((job) => { + tableRows.push(new InstantiationTemplatesRowModel(job)); + }); + + return tableRows; + }; +} diff --git a/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.row.model.ts b/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.row.model.ts new file mode 100644 index 000000000..08982cc67 --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/genericFormPopup/instantiationTemplatesModal/instantiation.templates.row.model.ts @@ -0,0 +1,51 @@ +import * as moment from 'moment'; +import * as _ from 'lodash'; + +export class InstantiationTemplatesRowModel { + readonly jobId: string; + readonly userId ?: string; + readonly createDate ?: string; + readonly instanceName ?: string; + readonly instantiationStatus?: string; + readonly summary?: string; + readonly region?: string; + readonly tenant?: string; + readonly aicZone?: string; + + constructor(data) { + this.jobId = data.jobId; + this.userId = !_.isNil(data.created) ? data.userId : null; + this.createDate = !_.isNil(data.created) ? moment(data.created).format("YYYY-MM-DD HH:mm:ss") : null; + this.instanceName = this.getInstanceName(data.serviceInstanceName); + this.instantiationStatus = !_.isNil(data.jobStatus) ? data.jobStatus : null; + this.summary = null; + this.region = this.getRegion(data.regionId, data.owningEntityName); + this.tenant = !_.isNil(data.tenantName) ? data.tenantName : null; + this.aicZone = !_.isNil(data.aicZoneName) ? data.aicZoneName : null; + + } + + + /************************************************************************************************** + return the LCP region and in brackets the cloud owner removing the “att-“ with capital letters. + **************************************************************************************************/ + getCloudOwner = (owningEntityName: string): string => { + const splitByAtt: string[] = owningEntityName.split('att-'); + let owning: string = splitByAtt[splitByAtt.length - 1]; + return owning.toUpperCase(); + }; + + getRegion = (regionId: string, owningEntityName: string): string => { + const convertOwning = !_.isNil(owningEntityName) ? `(${this.getCloudOwner(owningEntityName)})` : ''; + return `${regionId} ${convertOwning}`.trim(); + }; + + + getInstanceName = (instanceName?: string): string => { + if (_.isNil(instanceName)) { + return '<Automatically generated>'; + } + return instanceName; + } +} + |