diff options
author | vasraz <vasyl.razinkov@est.tech> | 2021-02-16 17:37:57 +0000 |
---|---|---|
committer | Christophe Closset <christophe.closset@intl.att.com> | 2021-02-17 15:57:55 +0000 |
commit | 26e5029d922779fd7e786c1a31b6b37492132388 (patch) | |
tree | 8e8e68a6913749e1405fce951bc7816d4fa35ba3 /catalog-ui/src/app/view-models | |
parent | f2c0a4118c3c0b6360b639622766543bd754b59c (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/view-models')
3 files changed, 317 insertions, 0 deletions
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/attributes/attributes.component.html b/catalog-ui/src/app/view-models/workspace/tabs/attributes/attributes.component.html new file mode 100644 index 0000000000..6d50bbe11b --- /dev/null +++ b/catalog-ui/src/app/view-models/workspace/tabs/attributes/attributes.component.html @@ -0,0 +1,93 @@ +<!-- + ~ 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/view-models/workspace/tabs/attributes/attributes.component.less b/catalog-ui/src/app/view-models/workspace/tabs/attributes/attributes.component.less new file mode 100644 index 0000000000..3e91ae4689 --- /dev/null +++ b/catalog-ui/src/app/view-models/workspace/tabs/attributes/attributes.component.less @@ -0,0 +1,36 @@ +.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/view-models/workspace/tabs/attributes/attributes.component.ts b/catalog-ui/src/app/view-models/workspace/tabs/attributes/attributes.component.ts new file mode 100644 index 0000000000..ca8d5460e8 --- /dev/null +++ b/catalog-ui/src/app/view-models/workspace/tabs/attributes/attributes.component.ts @@ -0,0 +1,188 @@ +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 '../../../../ng2/services/component-services/topology-template.service'; +import { TranslateService } from '../../../../ng2/shared/translator/translate.service'; +import { WorkspaceState } from '../../../../ng2/store/states/workspace.state'; +import { WorkspaceService } from '../../../../ng2/pages/workspace/workspace.service'; +import { AttributeModalComponent } from '../../../../ng2/pages/workspace/attributes/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); + } + +} |