aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-ui/src/app/ng2/pages/workspace
diff options
context:
space:
mode:
authorvasraz <vasyl.razinkov@est.tech>2021-02-16 17:37:57 +0000
committerChristophe Closset <christophe.closset@intl.att.com>2021-02-17 15:57:55 +0000
commit26e5029d922779fd7e786c1a31b6b37492132388 (patch)
tree8e8e68a6913749e1405fce951bc7816d4fa35ba3 /catalog-ui/src/app/ng2/pages/workspace
parentf2c0a4118c3c0b6360b639622766543bd754b59c (diff)
Implement Attributes/Outputs FE
Change-Id: I014bb0ebc07f3fea4266a4f295172eadee546705 Signed-off-by: Vasyl Razinkov <vasyl.razinkov@est.tech> Issue-ID: SDC-3448
Diffstat (limited to 'catalog-ui/src/app/ng2/pages/workspace')
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/attributes/attribute-modal.component.ts2
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.html93
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.less36
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.spec.ts182
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.ts188
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.module.ts2
6 files changed, 2 insertions, 501 deletions
diff --git a/catalog-ui/src/app/ng2/pages/workspace/attributes/attribute-modal.component.ts b/catalog-ui/src/app/ng2/pages/workspace/attributes/attribute-modal.component.ts
index b0a7651809..426ed4063e 100644
--- a/catalog-ui/src/app/ng2/pages/workspace/attributes/attribute-modal.component.ts
+++ b/catalog-ui/src/app/ng2/pages/workspace/attributes/attribute-modal.component.ts
@@ -11,7 +11,7 @@ import { AttributeOptions } from './attributes-options';
@Component({
selector: 'attribute-modal',
templateUrl: './attribute-modal.component.html',
- styleUrls: ['./attributes.component.less']
+ styleUrls: ['../../../../view-models/workspace/tabs/attributes/attributes.component.less']
})
export class AttributeModalComponent implements OnInit {
diff --git a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.html b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.html
deleted file mode 100644
index 6d50bbe11b..0000000000
--- a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.html
+++ /dev/null
@@ -1,93 +0,0 @@
-<!--
- ~ Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
--->
-<div class="workspace-attributes">
-
- <div class="action-bar-wrapper">
- <svg-icon-label
- *ngIf="!(this.isViewOnly$ | async)"
- class="add-attr-icon"
- [name]="'plus'"
- [mode]="'primary'"
- [size]="'medium'"
- [label]="'Add'"
- [labelPlacement]="'right'"
- [labelClassName]="'externalActionLabel'"
- (click)="onAddAttribute()">
- </svg-icon-label>
- </div>
-
- <ngx-datatable
- columnMode="flex"
- [footerHeight]="0"
- [limit]="50"
- [headerHeight]="40"
- [rowHeight]="35"
- [rows]="attributes"
- #componentAttributesTable
- (activate)="onExpandRow($event)">
-
- <ngx-datatable-row-detail [rowHeight]="80">
- <ng-template let-row="row" let-expanded="expanded" ngx-datatable-row-detail-template>
- <div>{{row.description}}</div>
- </ng-template>
- </ngx-datatable-row-detail>
-
- <ngx-datatable-column [resizeable]="false" name="Name" [flexGrow]="2">
-
- <ng-template ngx-datatable-cell-template let-row="row" let-expanded="expanded">
- <div class="expand-collapse-cell">
- <svg-icon [clickable]="true" class="expand-collapse-icon"
- [name]="expanded ? 'caret1-up-o': 'caret1-down-o'" [mode]="'primary'"
- [size]="'medium'"></svg-icon>
- <span>{{ row.name }}</span>
- </div>
- </ng-template>
-
- </ngx-datatable-column>
-
- <ngx-datatable-column [resizeable]="false" name="Type" [flexGrow]="1">
- <ng-template ngx-datatable-cell-template let-row="row">
- {{row.type}}
- </ng-template>
- </ngx-datatable-column>
-
- <ngx-datatable-column [resizeable]="false" name="Default Value" [flexGrow]="3">
- <ng-template ngx-datatable-cell-template let-row="row">
- {{row._default}}
- </ng-template>
- </ngx-datatable-column>
-
- <ngx-datatable-column *ngIf="!(this.isViewOnly$ | async)" [resizeable]="false" name="Action" [flexGrow]="1">
- <ng-template ngx-datatable-cell-template let-row="row" let-rowIndex="rowIndex">
- <div class="actionColumn">
- <svg-icon [clickable]="true"
- [mode]="'primary2'"
- [name]="'edit-o'"
- [size]="'medium'"
- (click)="onEditAttribute($event, row)">
- </svg-icon>
- <svg-icon [clickable]="true"
- [mode]="'primary2'"
- [name]="'trash-o'"
- (click)="onDeleteAttribute($event, row)"
- [size]="'medium'">
- </svg-icon>
- </div>
- </ng-template>
- </ngx-datatable-column>
-
- </ngx-datatable>
-</div>
diff --git a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.less b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.less
deleted file mode 100644
index 3e91ae4689..0000000000
--- a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.less
+++ /dev/null
@@ -1,36 +0,0 @@
-.action-bar-wrapper {
- flex: 0 0 30%;
- display: flex;
- justify-content: flex-end;
- margin-bottom: 10px;
-}
-
-.add-attr-icon{
- cursor: pointer;
-}
-
-.attr-container {
- display: flex;
- justify-content: space-between;
-
- .attr-col {
- display: flex;
- flex-direction: column;
- max-width: 275px;
- flex-grow: 1;
- }
-
-}
-
-.attributeType {
- margin-bottom: 10px;
-}
-
-sdc-checkbox {
- margin-top: 20px;
-}
-
-.actionColumn {
- text-align: center;
- padding: 5px;
-} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.spec.ts b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.spec.ts
deleted file mode 100644
index f676e2b4d9..0000000000
--- a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.spec.ts
+++ /dev/null
@@ -1,182 +0,0 @@
-import { NO_ERRORS_SCHEMA } from '@angular/core';
-import { async, ComponentFixture } from '@angular/core/testing';
-import { NgxDatatableModule } from '@swimlane/ngx-datatable';
-import { SdcUiCommon, SdcUiComponents, SdcUiServices } from 'onap-ui-angular';
-import 'rxjs/add/observable/of';
-import { Observable } from 'rxjs/Rx';
-import { ConfigureFn, configureTests } from '../../../../../jest/test-config.helper';
-import { ComponentMetadata } from '../../../../models/component-metadata';
-import { ModalsHandler } from '../../../../utils';
-import { TopologyTemplateService } from '../../../services/component-services/topology-template.service';
-import { TranslateService } from '../../../shared/translator/translate.service';
-import { WorkspaceService } from '../workspace.service';
-import { AttributesComponent } from './attributes.component';
-
-describe('attributes component', () => {
-
- let fixture: ComponentFixture<AttributesComponent>;
-
- // Mocks
- let workspaceServiceMock: Partial<WorkspaceService>;
- let topologyTemplateServiceMock: Partial<TopologyTemplateService>;
- let loaderServiceMock: Partial<SdcUiServices.LoaderService>;
- let componentMetadataMock: ComponentMetadata;
- let modalServiceMock: Partial<SdcUiServices.ModalService>;
-
- const mockAttributesList = [
- { uniqueId: '1', name: 'attr1', description: 'description1', type: 'string', hidden: false, defaultValue: 'val1', schema: null },
- { uniqueId : '2', name : 'attr2', description: 'description2', type : 'int', hidden : false, defaultValue : 1, schema : null},
- { uniqueId : '3', name : 'attr3', description: 'description3', type : 'double', hidden : false, defaultValue : 1.0, schema : null},
- { uniqueId : '4', name : 'attr4', description: 'description4', type : 'boolean', hidden : false, defaultValue : true, schema : null},
- ];
-
- const newAttribute = {
- uniqueId : '5', name : 'attr5', description: 'description5', type : 'string', hidden : false, defaultValue : 'val5', schema : null
- };
- const updatedAttribute = {
- uniqueId : '2', name : 'attr2', description: 'description_new', type : 'string', hidden : false, defaultValue : 'new_val2', schema : null
- };
- const errorAttribute = {
- uniqueId : '99', name : 'attr99', description: 'description_error', type : 'string', hidden : false, defaultValue : 'error', schema : null
- };
-
- beforeEach(
- async(() => {
-
- componentMetadataMock = new ComponentMetadata();
- componentMetadataMock.uniqueId = 'fake';
- componentMetadataMock.componentType = 'VL';
-
- topologyTemplateServiceMock = {
- getComponentAttributes: jest.fn().mockResolvedValue({ attributes : mockAttributesList }),
- addAttributeAsync: jest.fn().mockImplementation(
- (compType, cUid, attr) => {
- if (attr === errorAttribute) {
- return Observable.throwError('add_error').toPromise();
- } else {
- return Observable.of(newAttribute).toPromise();
- }
- }
- ),
- updateAttributeAsync: jest.fn().mockImplementation(
- (compType, cUid, attr) => {
- if (attr === errorAttribute) {
- return Observable.throwError('update_error').toPromise();
- } else {
- return Observable.of(updatedAttribute).toPromise();
- }
- }
- ),
- deleteAttributeAsync: jest.fn().mockImplementation((cid, ctype, attr) => Observable.of(attr))
- };
-
- workspaceServiceMock = {
- metadata: componentMetadataMock
- };
-
- const customModalInstance = { innerModalContent: { instance: { onValidationChange: { subscribe: jest.fn()}}}};
-
- modalServiceMock = {
- openInfoModal: jest.fn(),
- openCustomModal: jest.fn().mockImplementation(() => customModalInstance)
- };
-
- loaderServiceMock = {
- activate: jest.fn(),
- deactivate: jest.fn()
- };
-
- const configure: ConfigureFn = (testBed) => {
- testBed.configureTestingModule({
- declarations: [AttributesComponent],
- imports: [NgxDatatableModule],
- schemas: [NO_ERRORS_SCHEMA],
- providers: [
- {provide: WorkspaceService, useValue: workspaceServiceMock},
- {provide: TopologyTemplateService, useValue: topologyTemplateServiceMock},
- {provide: ModalsHandler, useValue: {}},
- {provide: TranslateService, useValue: { translate: jest.fn() }},
- {provide: SdcUiServices.ModalService, useValue: modalServiceMock },
- {provide: SdcUiServices.LoaderService, useValue: loaderServiceMock }
- ],
- });
- };
-
- configureTests(configure).then((testBed) => {
- fixture = testBed.createComponent(AttributesComponent);
- });
- })
- );
-
- it('should see exactly 1 attributes on init', async () => {
- await fixture.componentInstance.asyncInitComponent();
- expect(fixture.componentInstance.getAttributes().length).toEqual(4);
- });
-
- it('should see exactly 5 attributes when adding', async () => {
- await fixture.componentInstance.asyncInitComponent();
- expect(fixture.componentInstance.getAttributes().length).toEqual(4);
-
- await fixture.componentInstance.addOrUpdateAttribute(newAttribute, false);
- expect(fixture.componentInstance.getAttributes().length).toEqual(5);
- });
-
- it('should see exactly 3 attributes when deleting', async () => {
- await fixture.componentInstance.asyncInitComponent();
- expect(fixture.componentInstance.getAttributes().length).toEqual(4);
- const attrToDelete = mockAttributesList[0];
- expect(fixture.componentInstance.getAttributes().filter((attr) => attr.uniqueId === attrToDelete.uniqueId).length).toEqual(1);
- await fixture.componentInstance.deleteAttribute(attrToDelete);
- expect(fixture.componentInstance.getAttributes().length).toEqual(3);
- expect(fixture.componentInstance.getAttributes().filter((attr) => attr.uniqueId === attrToDelete.uniqueId).length).toEqual(0);
- });
-
- it('should see updated attribute', async () => {
- await fixture.componentInstance.asyncInitComponent();
-
- await fixture.componentInstance.addOrUpdateAttribute(updatedAttribute, true);
- expect(fixture.componentInstance.getAttributes().length).toEqual(4);
- const attribute = fixture.componentInstance.getAttributes().filter( (attr) => {
- return attr.uniqueId === updatedAttribute.uniqueId;
- })[0];
- expect(attribute.description).toEqual( 'description_new');
- });
-
- it('Add fails, make sure loader is deactivated and attribute is not added', async () => {
- await fixture.componentInstance.asyncInitComponent();
- const numAttributes = fixture.componentInstance.getAttributes().length;
- await fixture.componentInstance.addOrUpdateAttribute(errorAttribute, false); // Add
- expect(loaderServiceMock.deactivate).toHaveBeenCalled();
- expect(fixture.componentInstance.getAttributes().length).toEqual(numAttributes);
- });
-
- it('Update fails, make sure loader is deactivated', async () => {
- await fixture.componentInstance.asyncInitComponent();
- const numAttributes = fixture.componentInstance.getAttributes().length;
- await fixture.componentInstance.addOrUpdateAttribute(errorAttribute, true); // Add
- expect(loaderServiceMock.deactivate).toHaveBeenCalled();
- expect(fixture.componentInstance.getAttributes().length).toEqual(numAttributes);
- });
-
- it('on delete modal shell be opened', async () => {
- await fixture.componentInstance.asyncInitComponent();
- const event = { stopPropagation: jest.fn() };
- fixture.componentInstance.onDeleteAttribute(event, fixture.componentInstance.getAttributes()[0]);
- expect(event.stopPropagation).toHaveBeenCalled();
- expect(modalServiceMock.openInfoModal).toHaveBeenCalled();
- });
-
- it('on add modal shell be opened', async () => {
- await fixture.componentInstance.asyncInitComponent();
- fixture.componentInstance.onAddAttribute();
- expect(modalServiceMock.openCustomModal).toHaveBeenCalled();
- });
-
- it('on edit modal shell be opened', async () => {
- await fixture.componentInstance.asyncInitComponent();
- const event = { stopPropagation: jest.fn() };
- fixture.componentInstance.onEditAttribute(event, fixture.componentInstance.getAttributes()[0]);
- expect(event.stopPropagation).toHaveBeenCalled();
- expect(modalServiceMock.openCustomModal).toHaveBeenCalled();
- });
-});
diff --git a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.ts b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.ts
deleted file mode 100644
index bc47f1456b..0000000000
--- a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.ts
+++ /dev/null
@@ -1,188 +0,0 @@
-import { Component, OnInit, ViewChild } from '@angular/core';
-import { Select } from '@ngxs/store';
-import { IAttributeModel } from 'app/models';
-import * as _ from 'lodash';
-import { SdcUiCommon, SdcUiComponents, SdcUiServices } from 'onap-ui-angular';
-import { ModalComponent } from 'onap-ui-angular/dist/modals/modal.component';
-import { AttributeModel } from '../../../../models';
-import { Resource } from '../../../../models';
-import { ModalsHandler } from '../../../../utils';
-import { TopologyTemplateService } from '../../../services/component-services/topology-template.service';
-import { TranslateService } from '../../../shared/translator/translate.service';
-import { WorkspaceState } from '../../../store/states/workspace.state';
-import { WorkspaceService } from '../workspace.service';
-import { AttributeModalComponent } from './attribute-modal.component';
-
-@Component({
- selector: 'attributes',
- templateUrl: './attributes.component.html',
- styleUrls: ['./attributes.component.less', '../../../../../assets/styles/table-style.less']
-})
-export class AttributesComponent implements OnInit {
-
- @Select(WorkspaceState.isViewOnly)
- isViewOnly$: boolean;
-
- @ViewChild('componentAttributesTable')
- private table: any;
-
- private componentType: string;
- private componentUid: string;
-
- private attributes: IAttributeModel[] = [];
- private temp: IAttributeModel[] = [];
- private customModalInstance: ModalComponent;
-
- constructor(private workspaceService: WorkspaceService,
- private topologyTemplateService: TopologyTemplateService,
- private modalsHandler: ModalsHandler,
- private modalService: SdcUiServices.ModalService,
- private loaderService: SdcUiServices.LoaderService,
- private translateService: TranslateService) {
-
- this.componentType = this.workspaceService.metadata.componentType;
- this.componentUid = this.workspaceService.metadata.uniqueId;
- }
-
- ngOnInit(): void {
- this.asyncInitComponent();
- }
-
- async asyncInitComponent() {
- this.loaderService.activate();
- const response = await this.topologyTemplateService.getComponentAttributes(this.componentType, this.componentUid);
- this.attributes = response.attributes;
- this.temp = [...response.attributes];
- this.loaderService.deactivate();
- }
-
- getAttributes(): IAttributeModel[] {
- return this.attributes;
- }
-
- addOrUpdateAttribute = async (attribute: AttributeModel, isEdit: boolean) => {
- this.loaderService.activate();
- let attributeFromServer: AttributeModel;
- this.temp = [...this.attributes];
-
- const deactivateLoader = () => {
- this.loaderService.deactivate();
- return undefined;
- };
-
- if (isEdit) {
- attributeFromServer = await this.topologyTemplateService
- .updateAttributeAsync(this.componentType, this.componentUid, attribute)
- .catch(deactivateLoader);
- if (attributeFromServer) {
- const indexOfUpdatedAttribute = _.findIndex(this.temp, (e) => e.uniqueId === attributeFromServer.uniqueId);
- this.temp[indexOfUpdatedAttribute] = attributeFromServer;
- }
- } else {
- attributeFromServer = await this.topologyTemplateService
- .addAttributeAsync(this.componentType, this.componentUid, attribute)
- .catch(deactivateLoader);
- if (attributeFromServer) {
- this.temp.push(attributeFromServer);
- }
- }
- this.attributes = this.temp;
- this.loaderService.deactivate();
- }
-
- deleteAttribute = async (attributeToDelete: AttributeModel) => {
- this.loaderService.activate();
- this.temp = [...this.attributes];
- const res = await this.topologyTemplateService.deleteAttributeAsync(this.componentType, this.componentUid, attributeToDelete);
- _.remove(this.temp, (attr) => attr.uniqueId === attributeToDelete.uniqueId);
- this.attributes = this.temp;
- this.loaderService.deactivate();
- };
-
- openAddEditModal(selectedRow: AttributeModel, isEdit: boolean) {
- const component = new Resource(undefined, undefined, undefined);
- component.componentType = this.componentType;
- component.uniqueId = this.componentUid;
-
- const title: string = this.translateService.translate('ATTRIBUTE_DETAILS_MODAL_TITLE');
- const attributeModalConfig = {
- title,
- size: 'md',
- type: SdcUiCommon.ModalType.custom,
- buttons: [
- {
- id: 'save',
- text: 'Save',
- // spinner_position: Placement.left,
- size: 'sm',
- callback: () => this.modalCallBack(isEdit),
- closeModal: true,
- disabled: false,
- }
- ] as SdcUiCommon.IModalButtonComponent[]
- };
-
- this.customModalInstance = this.modalService.openCustomModal(attributeModalConfig, AttributeModalComponent, { attributeToEdit: selectedRow });
- this.customModalInstance.innerModalContent.instance.
- onValidationChange.subscribe((isValid) => this.customModalInstance.getButtonById('save').disabled = !isValid);
- }
-
- /***********************
- * Call Backs from UI *
- ***********************/
-
- /**
- * Called when 'Add' is clicked
- */
- onAddAttribute() {
- this.openAddEditModal(new AttributeModel(), false);
- }
-
- /**
- * Called when 'Edit' button is clicked
- */
- onEditAttribute(event, row) {
- event.stopPropagation();
-
- const attributeToEdit: AttributeModel = new AttributeModel(row);
- this.openAddEditModal(attributeToEdit, true);
- }
-
- /**
- * Called when 'Delete' button is clicked
- */
- onDeleteAttribute(event, row: AttributeModel) {
- event.stopPropagation();
- const onOk = () => {
- this.deleteAttribute(row);
- };
-
- const title: string = this.translateService.translate('ATTRIBUTE_VIEW_DELETE_MODAL_TITLE');
- const message: string = this.translateService.translate('ATTRIBUTE_VIEW_DELETE_MODAL_TEXT');
- const okButton = new SdcUiComponents.ModalButtonComponent();
- okButton.testId = 'OK';
- okButton.text = 'OK';
- okButton.type = SdcUiCommon.ButtonType.info;
- okButton.closeModal = true;
- okButton.callback = onOk;
-
- this.modalService.openInfoModal(title, message, 'delete-modal', [okButton]);
- }
-
- onExpandRow(event) {
- if (event.type === 'click') {
- this.table.rowDetail.toggleExpandRow(event.row);
- }
- }
-
- /**
- * Callback from Modal after "Save" is clicked
- *
- * @param {boolean} isEdit - Whether modal is edit or add attribute
- */
- modalCallBack = (isEdit: boolean) => {
- const attribute: AttributeModel = this.customModalInstance.innerModalContent.instance.attributeToEdit;
- this.addOrUpdateAttribute(attribute, isEdit);
- }
-
-}
diff --git a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.module.ts b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.module.ts
index 5abb952e37..f85d5298f9 100644
--- a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.module.ts
+++ b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.module.ts
@@ -2,7 +2,7 @@ import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { SdcUiComponentsModule } from 'onap-ui-angular';
import { GlobalPipesModule } from '../../../pipes/global-pipes.module';
-import { AttributesComponent } from './attributes.component';
+import { AttributesComponent } from '../../../../view-models/workspace/tabs/attributes/attributes.component';
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import { TopologyTemplateService } from '../../../services/component-services/topology-template.service';
import { AttributeModalComponent } from './attribute-modal.component';