aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities
diff options
context:
space:
mode:
Diffstat (limited to 'catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities')
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.html22
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.less9
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.ts33
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.html59
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.less16
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.ts79
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.html93
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.less38
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.ts81
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.module.ts29
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.html21
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.less19
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.spec.ts127
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.ts229
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.module.ts49
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.service.ts80
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.html91
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.less35
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.ts90
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.module.ts28
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirements.component.less4
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirments.components.html38
-rw-r--r--catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirments.components.ts103
23 files changed, 1373 insertions, 0 deletions
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.html b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.html
new file mode 100644
index 0000000000..f496e64c17
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.html
@@ -0,0 +1,22 @@
+<div class="capabilities-properties-table">
+ <ngx-datatable #componentsMetadataTable
+ columnMode="flex"
+ [headerHeight]="40"
+ [rowHeight]="35"
+ [rows]="capabilitiesProperties"
+ [sorts]="[{prop: 'name', dir: 'desc'}]">
+ <ngx-datatable-column *ngFor="let column of capabilityPropertiesColumns" [ngSwitch]="column.prop" [resizeable]="false"
+ [draggable]="false" name={{column.name}} [flexGrow]="column.flexGrow">
+ <ng-template ngx-datatable-cell-template let-row="row" *ngSwitchCase="'name'">
+ <a data-tests-id="row[column.prop]" sdc-tooltip [tooltip-text]="row[column.prop]" (click)="updateProperty(row)">{{row[column.prop]}}</a>
+ </ng-template>
+ <ng-template ngx-datatable-cell-template let-row="row" *ngSwitchCase="'schema'">
+ <span *ngIf="row[column.prop] && row[column.prop].property" data-tests-id="row[column.prop].property.type"
+ sdc-tooltip [tooltip-text]="row[column.prop].property.type">{{row[column.prop].property.type}}</span>
+ </ng-template>
+ <ng-template ngx-datatable-cell-template let-row="row" *ngSwitchDefault>
+ <span data-tests-id="row[column.prop]" sdc-tooltip [tooltip-text]="row[column.prop]" [tooltip-placement]="3">{{row[column.prop]}}</span>
+ </ng-template>
+ </ngx-datatable-column>
+ </ngx-datatable>
+</div> \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.less b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.less
new file mode 100644
index 0000000000..007f509538
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.less
@@ -0,0 +1,9 @@
+
+:host ::ng-deep {
+ .ngx-datatable {
+ > div {
+ min-height: auto !important;
+ }
+
+ }
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.ts
new file mode 100644
index 0000000000..2a1a16e265
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.ts
@@ -0,0 +1,33 @@
+
+import { ViewChild, Input, OnInit, Component } from "@angular/core";
+import {SdcUiServices} from "onap-ui-angular";
+import { ModalsHandler } from "../../../../../../utils/modals-handler";
+import { WorkspaceService } from "../../../workspace.service";
+import { PropertyModel } from "../../../../../../models/properties";
+
+
+@Component({
+ selector: 'capabilities-properties',
+ templateUrl: './capabilities-properties.html',
+ styleUrls: ['./capabilities-properties.less', '../../../../../../../assets/styles/table-style.less']
+})
+export class CapabilitiesPropertiesComponent {
+ @Input() public capabilitiesProperties: Array<PropertyModel> = [];
+
+ private capabilityPropertiesColumns = [
+ {name: 'Name', prop: 'name', flexGrow: 1},
+ {name: 'Type', prop: 'type', flexGrow: 1},
+ {name: 'Schema', prop: 'schema', flexGrow: 1},
+ {name: 'Description', prop: 'description', flexGrow: 1},
+ ];
+ constructor(private modalsHandler: ModalsHandler,
+ private workspaceService: WorkspaceService) {}
+
+ private updateProperty(property: PropertyModel): void {
+ _.forEach(this.capabilitiesProperties, (prop: PropertyModel) => {
+ prop.readonly = true;
+ });
+ this.modalsHandler.openEditPropertyModal(property, this.workspaceService.metadata, this.capabilitiesProperties, false, 'component',
+ this.workspaceService.metadata.uniqueId);
+ }
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.html b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.html
new file mode 100644
index 0000000000..819eb84849
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.html
@@ -0,0 +1,59 @@
+<div class="capabilities-table">
+ <div class="expand-collapse-all-rows">
+ <svg-icon class="selected-all-capabilities"
+ [mode]="'primary'" [clickable]="true" [name]="'expand-o'"
+ [size]="'medium'" (click)="capabilitiesTable.rowDetail.expandAllRows()">
+ </svg-icon>
+ <svg-icon class="unselected-all-capabilities"
+ [mode]="'primary'" [clickable]="true" [name]="'minimize-o'"
+ [size]="'medium'" (click)="capabilitiesTable.rowDetail.collapseAllRows()">
+ </svg-icon>
+ </div>
+ <ngx-datatable #capabilitiesTable
+ columnMode="flex"
+ [headerHeight]="40"
+ [rowHeight]="35"
+ [rows]="capabilities"
+ (select)="onSelectCapabilities($event)"
+ [selectionType]="'single'">
+ <ngx-datatable-row-detail [rowHeight]="undefiend">
+ <ng-template let-row="row" ngx-datatable-row-detail-template>
+ <div class="properties-title">Properties</div>
+ <capabilities-properties [capabilitiesProperties]="row.properties"></capabilities-properties>
+ </ng-template>
+ </ngx-datatable-row-detail>
+ <ngx-datatable-column name="Name" [flexGrow]="1" [resizeable]="false">
+ <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'" (click)="expendRow(row)"></svg-icon>
+ <span data-tests-id="row.name" sdc-tooltip [tooltip-text]="row.name" [tooltip-placement]="3" (click)="editCapability(row)">{{row.name}}</span>
+ </div>
+ </ng-template>
+ </ngx-datatable-column>
+ <ngx-datatable-column name="Type" [flexGrow]="1" [resizeable]="false">
+ <ng-template ngx-datatable-cell-template let-row="row">
+ <span data-tests-id="row.type" sdc-tooltip [tooltip-text]="row.type" [tooltip-placement]="3">{{row.type ? row.type.replace("tosca.capabilities.",""): ''}}</span>
+ </ng-template>
+ </ngx-datatable-column>
+ <ngx-datatable-column name="Description" [flexGrow]="1" [resizeable]="false">
+ <ng-template ngx-datatable-cell-template let-row="row">
+ <span data-tests-id="row.description" sdc-tooltip [tooltip-text]="row.description" [tooltip-placement]="3">{{row.description}}</span>
+ </ng-template>
+ </ngx-datatable-column>
+ <ngx-datatable-column name="Valid Source" [flexGrow]="1" [resizeable]="false">
+ <ng-template ngx-datatable-cell-template let-row="row">
+ <span data-tests-id="row.validSourceTypes.join(',')" sdc-tooltip [tooltip-text]="row.validSourceTypes ? row.validSourceTypes.join(',') : null" [tooltip-placement]="3">
+ {{row.validSourceTypes ? row.validSourceTypes.join(','): ''}}</span>
+ </ng-template>
+ </ngx-datatable-column>
+ <ngx-datatable-column name="Occurrences" [flexGrow]="1" [prop]="'minOccurrences'" [resizeable]="false">
+ <ng-template ngx-datatable-cell-template let-row="row">
+ <span data-tests-id="row.minOccurrences+','+row.maxOccurrences" sdc-tooltip
+ [tooltip-text]="row.minOccurrences+','+row.maxOccurrences" [tooltip-placement]="3">
+ {{row.minOccurrences}},{{row.maxOccurrences}}</span>
+ </ng-template>
+ </ngx-datatable-column>
+ </ngx-datatable>
+</div> \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.less b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.less
new file mode 100644
index 0000000000..0c520a8135
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.less
@@ -0,0 +1,16 @@
+:host ::ng-deep {
+ .datatable-row-detail {
+ width: 1260px;
+ }
+ .datatable-body-row {
+ cursor: pointer;
+ }
+}
+.expand-collapse-all-rows {
+ position: absolute;
+ top: 172px;
+ left: 890px;
+}
+.properties-title {
+ padding-bottom: 10px;
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.ts
new file mode 100644
index 0000000000..02db5d3aee
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.ts
@@ -0,0 +1,79 @@
+import {Capability, CapabilityUI} from "../../../../../models/capability";
+import { ViewChild, Input, OnInit, Component } from "@angular/core";
+import {SdcUiServices} from "onap-ui-angular";
+import {CapabilitiesEditorComponent} from "./capabilityEditor/capabilities-editor.component";
+import {WorkspaceService} from "../../workspace.service";
+import {TopologyTemplateService} from "../../../../services/component-services/topology-template.service";
+import {ReqAndCapabilitiesService} from "../req-and-capabilities.service";
+import {ModalComponent} from "onap-ui-angular/dist/modals/modal.component";
+import {EventListenerService} from "../../../../../services/event-listener-service";
+
+
+@Component({
+ selector: 'capabilities',
+ templateUrl: './capabilities.component.html',
+ styleUrls: ['./capabilities.component.less','../../../../../../assets/styles/table-style.less']
+})
+export class CapabilitiesComponent {
+ @Input() public capabilities: Array<Capability>;
+ @ViewChild('capabilitiesTable') capabilitiesTable: any;
+ private customModalInstance: ModalComponent;
+
+ constructor(
+ private workspaceService: WorkspaceService,
+ private loaderService: SdcUiServices.LoaderService,
+ private topologyTemplateService: TopologyTemplateService,
+ private reqAndCapabilitiesService : ReqAndCapabilitiesService,
+ private modalService: SdcUiServices.ModalService,
+ private eventListenerService: EventListenerService) {
+ }
+
+ private onSelectCapabilities({ selected }) {
+ }
+
+ editCapability(cap: CapabilityUI) {
+ let modalConfig = {
+ size: 'md',
+ title: 'Update Capability',
+ type: 'custom',
+ buttons: [
+ {
+ id: 'saveButton',
+ text: ('Update'),
+ size: "'x-small'",
+ callback: () => this.updateCapability(),
+ closeModal: true
+ },
+ {text: "Cancel", size: "'x-small'", closeModal: true}]
+ };
+ let modalInputs = {
+ capability: cap,
+ capabilityTypesList: this.reqAndCapabilitiesService.getCapabilityTypesList(),
+ };
+
+ this.customModalInstance = this.modalService.openCustomModal(modalConfig, CapabilitiesEditorComponent, {input: modalInputs});
+ this.customModalInstance.innerModalContent.instance.
+ onValidationChange.subscribe((isValid) => this.customModalInstance.getButtonById('saveButton').disabled = !isValid);
+ }
+
+ expendRow(row) {
+ this.capabilitiesTable.rowDetail.toggleExpandRow(row);
+ }
+
+ private updateCapability() {
+ const capability = this.customModalInstance.innerModalContent.instance.capabilityData;
+ this.loaderService.activate();
+ if (capability.uniqueId) {
+ this.topologyTemplateService.updateCapability(this.workspaceService.metadata.getTypeUrl(), this.workspaceService.metadata.uniqueId, capability).subscribe((result) => {
+ let index = this.capabilities.findIndex((cap) => result[0].uniqueId === cap.uniqueId);
+ this.capabilities[index] = new CapabilityUI(result[0], this.workspaceService.metadata.uniqueId);
+ this.loaderService.deactivate();
+ this.eventListenerService.notifyObservers('CAPABILITIES_UPDATED');
+ }, () => {
+ this.loaderService.deactivate();
+ });
+ }
+ }
+
+
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.html b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.html
new file mode 100644
index 0000000000..bc15d4d228
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.html
@@ -0,0 +1,93 @@
+<div class="capability-editor">
+ <form class="w-sdc-form">
+ <div class="i-sdc-form-content-capability-content">
+ <div class="content-row">
+ <div class="i-sdc-form-item">
+ <sdc-input
+ label="{{ 'CAP_NAME' | translate }}"
+ required="true"
+ class="i-sdc-form-input"
+ testId="capName"
+ [disabled]="isReadonly"
+ [(value)]="capabilityData.name"
+ (valueChange)="validityChanged()">
+ </sdc-input>
+ </div>
+ </div>
+
+ <div class="group-with-border">
+ <div class="content-row i-sdc-form-item">
+ <sdc-dropdown
+ label="{{ 'CAP_TYPE' | translate }}"
+ required="true"
+ class="i-sdc-form-select"
+ testId="capType"
+ [disabled]="isReadonly"
+ [options]="capabilityTypesMappedList"
+ selectedOption="{{ capabilityData.type }}"
+ [placeHolder] = "capabilityData.type"
+ (changed)="onSelectCapabilityType($event)">
+ </sdc-dropdown>
+ </div>
+ <div class="content-row i-sdc-form-item">
+ <label class="i-sdc-form-label"> {{ 'CAP_DESCRIPTION' | translate }} </label>
+ <textarea
+ rows="3"
+ class="i-sdc-form-input description"
+ data-tests-id="capDesc"
+ disabled
+ value="{{capabilityData.description}}">
+ </textarea>
+ </div>
+ <div class="content-row i-sdc-form-item">
+ <label class="i-sdc-form-label valid-source-label"> {{ 'CAP_VALID_SOURCE' | translate }} </label>
+ <textarea
+ rows="2"
+ class="i-sdc-form-input"
+ data-tests-id="capValidSrc"
+ disabled
+ value="{{capabilityData.validSourceTypes}}">
+ </textarea>
+ </div>
+ </div>
+
+ <label class="i-sdc-form-label occurrences-label"> {{ 'REQ_CAP_OCCURRENCES' | translate }} </label>
+ <div class="content-row occurrences-section">
+ <div class="min-occurrences-value">
+ <sdc-input
+ label="{{ 'REQ_CAP_OCCURRENCES_MIN' | translate }}"
+ class="i-sdc-form-input"
+ testId="capOccurrencesMin"
+ [disabled]="isReadonly"
+ [(value)]="capabilityData.minOccurrences"
+ (valueChange)="validityChanged()"
+ type="number">
+ </sdc-input>
+ </div>
+ <div class="sdc-input">
+ <label class="sdc-input__label"> {{ 'REQ_CAP_OCCURRENCES_MAX' | translate }} </label>
+ <div class="max-occurrences-value">
+ <sdc-checkbox
+ class="checkbox-label unbounded-value"
+ testId="capOccurrencesMaxUnbounded"
+ label="{{translatedUnboundTxt.toLowerCase()}}"
+ (checkedChange)="onUnboundedChanged()"
+ [checked]="isUnboundedChecked"
+ [disabled]="isReadonly">
+ </sdc-checkbox>
+
+ <sdc-input
+ *ngIf="!isUnboundedChecked"
+ class="i-sdc-form-input"
+ testId="capOccurrencesMax"
+ [disabled]="isReadonly"
+ [(value)]="capabilityData.maxOccurrences"
+ (valueChange)="validityChanged()"
+ type="number">
+ </sdc-input>
+ </div>
+ </div>
+ </div>
+ </div>
+ </form>
+</div> \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.less b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.less
new file mode 100644
index 0000000000..324dc6c4d2
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.less
@@ -0,0 +1,38 @@
+@import '../../../../../../../assets/styles/variables.less';
+
+.capability-editor {
+ .i-sdc-form-content-capability-content {
+ padding: 10px 25px;
+ .group-with-border {
+ margin: 25px 0;
+ padding: 15px 0;
+ border-top: 1px solid @tlv_color_u;
+ border-bottom: 1px solid @tlv_color_u;
+ .content-row:not(:last-of-type) {
+ padding-bottom: 13px;
+ }
+ }
+
+ .occurrences-label {
+ font-family: @font-opensans-bold;
+ margin-bottom: 19px;
+ }
+ .occurrences-section, /deep/ .max-occurrences-value {
+ display: flex;
+ .min-occurrences-value {
+ padding-right: 30px;
+ }
+ .unbounded-value {
+ padding-top: 7px;
+ padding-right: 20px;
+ .sdc-checkbox__label {
+ text-transform: capitalize;
+ }
+ }
+ }
+ textarea {
+ min-height: unset;
+ height: unset;
+ }
+ }
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.ts
new file mode 100644
index 0000000000..3bafa42e0f
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.ts
@@ -0,0 +1,81 @@
+import {Component} from '@angular/core';
+import {ServiceServiceNg2} from "app/ng2/services/component-services/service.service";
+import {Capability, CapabilityTypeModel} from 'app/models';
+import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component";
+import {TranslateService} from 'app/ng2/shared/translator/translate.service';
+import {Subject} from "rxjs";
+
+@Component({
+ selector: 'capabilities-editor',
+ templateUrl: './capabilities-editor.component.html',
+ styleUrls: ['./capabilities-editor.component.less'],
+ providers: [ServiceServiceNg2]
+})
+
+export class CapabilitiesEditorComponent {
+ input: {
+ test: string,
+ capability: Capability,
+ capabilityTypesList: Array<CapabilityTypeModel>,
+ isReadonly: boolean;
+ };
+ capabilityData: Capability;
+ capabilityTypesMappedList: Array<DropdownValue>;
+ isUnboundedChecked: boolean;
+ isReadonly: boolean;
+ translatedUnboundTxt: string;
+
+ public onValidationChange: Subject<boolean> = new Subject();
+
+ constructor(private translateService: TranslateService) {
+ }
+
+ ngOnInit() {
+ this.capabilityData = new Capability(this.input.capability);
+ this.translatedUnboundTxt = '';
+ this.capabilityData.minOccurrences = this.capabilityData.minOccurrences || 0;
+ this.translateService.languageChangedObservable.subscribe(lang => {
+ this.translatedUnboundTxt = this.translateService.translate('REQ_CAP_OCCURRENCES_UNBOUNDED');
+ this.capabilityData.maxOccurrences = this.capabilityData.maxOccurrences || this.translatedUnboundTxt;
+ this.isUnboundedChecked = this.capabilityData.maxOccurrences === this.translatedUnboundTxt;
+ });
+ this.capabilityTypesMappedList = _.map(this.input.capabilityTypesList, capType => new DropdownValue(capType.toscaPresentation.type, capType.toscaPresentation.type));
+ this.isReadonly = this.input.isReadonly;
+ this.validityChanged();
+ }
+
+ onUnboundedChanged() {
+ this.isUnboundedChecked = !this.isUnboundedChecked;
+ this.capabilityData.maxOccurrences = this.isUnboundedChecked ? this.translatedUnboundTxt : null;
+ this.validityChanged();
+ }
+
+ checkFormValidForSubmit() {
+ return this.capabilityData.name && this.capabilityData.name.length &&
+ this.capabilityData.type && this.capabilityData.type.length && !_.isEqual(this.capabilityData.minOccurrences, "") && this.capabilityData.minOccurrences >= 0 &&
+ (
+ this.isUnboundedChecked ||
+ (this.capabilityData.maxOccurrences && (this.capabilityData.minOccurrences <= parseInt(this.capabilityData.maxOccurrences)))
+ );
+ }
+
+ onSelectCapabilityType(selectedCapType: DropdownValue) {
+ this.capabilityData.type = selectedCapType && selectedCapType.value;
+ if (selectedCapType && selectedCapType.value) {
+ let selectedCapabilityTypeObj: CapabilityTypeModel = this.input.capabilityTypesList.find(capType => capType.toscaPresentation.type === selectedCapType.value);
+ this.capabilityData.description = selectedCapabilityTypeObj.toscaPresentation.description;
+ this.capabilityData.validSourceTypes = selectedCapabilityTypeObj.toscaPresentation.validTargetTypes;
+ this.capabilityData.properties = _.forEach(
+ _.toArray(selectedCapabilityTypeObj.properties),
+ prop => prop.uniqueId = null //a requirement for the BE
+ );
+ }
+ this.validityChanged();
+ }
+
+ validityChanged = () => {
+ let validState = this.checkFormValidForSubmit();
+ this.onValidationChange.next(validState);
+ }
+
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.module.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.module.ts
new file mode 100644
index 0000000000..38b104a0f6
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.module.ts
@@ -0,0 +1,29 @@
+import {NgModule} from '@angular/core';
+import {CommonModule} from '@angular/common';
+import {CapabilitiesEditorComponent} from './capabilities-editor.component';
+import {FormsModule} from '@angular/forms';
+import {FormElementsModule} from 'app/ng2/components/ui/form-components/form-elements.module';
+import {UiElementsModule} from 'app/ng2/components/ui/ui-elements.module';
+import {TranslateModule} from 'app/ng2/shared/translator/translate.module';
+import {SdcUiComponentsModule} from 'onap-ui-angular';
+// import {SdcUiComponentsModule} from "sdc-ui/lib/angular/index";
+
+@NgModule({
+ declarations: [
+ CapabilitiesEditorComponent
+ ],
+ imports: [CommonModule,
+ FormsModule,
+ FormElementsModule,
+ UiElementsModule,
+ TranslateModule,
+ SdcUiComponentsModule
+ ],
+ exports: [],
+ entryComponents: [
+ CapabilitiesEditorComponent
+ ],
+ providers: []
+})
+export class CapabilitiesEditorModule {
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.html b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.html
new file mode 100644
index 0000000000..73e0ae52ae
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.html
@@ -0,0 +1,21 @@
+<div class="workspace-req-and-cap">
+ <div>
+ <span class="addTitle" *ngIf="selectTabName === 'REQUIREMENTS'" (click)="addRequiremnet()">Add Requirement</span>
+ <span class="addTitle" *ngIf="selectTabName !== 'REQUIREMENTS'" (click)="addCapability()">Add Capability</span>
+ <span class="req-and-cap-filter" *ngIf="notEmptyTable">
+ <sdc-filter-bar
+ [placeHolder]="'Search'"
+ (keyup)="updateFilter($event)"
+ [testId]="'search-box'">
+ </sdc-filter-bar>
+ </span>
+ </div>
+ <sdc-tabs (selectedTab)="selectTab($event)" [tabStyle]="'sdc-table-tab'">
+ <sdc-tab [title]="'Requirements('+(requirements.length||'0')+')'" [active]="true" [testId]="'req-tab'">
+ <div #requirmentsContainer></div>
+ </sdc-tab>
+ <sdc-tab [title]="'Capabilities('+(capabilities.length||'0')+')'" [active]="false" [testId]="'cap-tab'">
+ <div #capabilitiesContainer></div>
+ </sdc-tab>
+ </sdc-tabs>
+</div> \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.less b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.less
new file mode 100644
index 0000000000..f3d39cacd6
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.less
@@ -0,0 +1,19 @@
+.req-and-cap-filter {
+ width: 336px;
+ float: right;
+ margin-right: 10px;
+}
+
+.addTitle {
+ float: right;
+ text-transform: uppercase;
+ font-family: OpenSans-Semibold, sans-serif;
+ color: #009fdb;
+ cursor: pointer;
+}
+
+:host ::ng-deep .sdc-tabs {
+ .sdc-tab-content {
+ margin-top: 0;
+ }
+}
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.spec.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.spec.ts
new file mode 100644
index 0000000000..b7fad045d3
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.spec.ts
@@ -0,0 +1,127 @@
+import {async, ComponentFixture, TestBed} from "@angular/core/testing";
+import { NO_ERRORS_SCHEMA} from "@angular/core";
+import {ConfigureFn, configureTests} from "../../../../../jest/test-config.helper";
+
+import {Observable} from "rxjs/Observable";
+import {NgxDatatableModule} from "@swimlane/ngx-datatable";
+import {SdcUiServices, SdcUiCommon} from "onap-ui-angular";
+import 'rxjs/add/observable/of';
+import {ReqAndCapabilitiesComponent} from "./req-and-capabilities.component";
+import {ReqAndCapabilitiesService} from "./req-and-capabilities.service";
+import {WorkspaceService} from "../workspace.service";
+import {
+ capabilitiesMock,
+ filterRequirmentsMock,
+ requirementMock
+} from "../../../../../jest/mocks/req-and-capabilities.mock";
+import {ComponentMetadata} from "../../../../models/component-metadata";
+import { TopologyTemplateService } from "../../../services/component-services/topology-template.service";
+import {EventListenerService} from "../../../../services/event-listener-service";
+
+describe('req and capabilities component', () => {
+
+ let fixture: ComponentFixture<ReqAndCapabilitiesComponent>;
+ let workspaceServiceMock: Partial<WorkspaceService>;
+ let loaderServiceMock: Partial<SdcUiServices.LoaderService>;
+ let topologyTemplateServiceMock: Partial<TopologyTemplateService>;
+ let createDynamicComponentServiceMock: Partial<SdcUiServices.CreateDynamicComponentService>
+ let reqAndCapabilitiesService: Partial<ReqAndCapabilitiesService>;
+ let modalService: Partial<SdcUiServices.ModalService>;
+ let eventListenerService: Partial<EventListenerService>;
+
+
+
+ beforeEach(
+ async(() => {
+
+ workspaceServiceMock = {
+ metadata: new ComponentMetadata()
+ };
+
+ topologyTemplateServiceMock = {
+ getRequirementsAndCapabilitiesWithProperties: jest.fn().mockImplementation(() =>
+ Observable.of({requirements: {'tosca.requirements.Node': requirementMock},
+ capabilities: {'tosca.capabilities.Node': capabilitiesMock}}))
+ };
+
+ loaderServiceMock = {
+ activate : jest.fn(),
+ deactivate: jest.fn()
+ }
+ createDynamicComponentServiceMock = {
+ insertComponentDynamically: jest.fn()
+ }
+
+ const configure: ConfigureFn = testBed => {
+ testBed.configureTestingModule({
+ declarations: [ReqAndCapabilitiesComponent],
+ imports: [NgxDatatableModule],
+ schemas: [NO_ERRORS_SCHEMA],
+ providers: [
+ { provide: WorkspaceService, useValue: workspaceServiceMock },
+ { provide: SdcUiServices.LoaderService, useValue: loaderServiceMock },
+ { provide: TopologyTemplateService, useValue: topologyTemplateServiceMock },
+ { provide: SdcUiServices.CreateDynamicComponentService, useValue: createDynamicComponentServiceMock },
+ { provide: ReqAndCapabilitiesService, useValue: reqAndCapabilitiesService },
+ { provide: SdcUiServices.ModalService, useValue: modalService },
+ { provide: EventListenerService, useValue: eventListenerService }
+ ],
+ });
+ };
+ configureTests(configure).then(testBed => {
+ fixture = testBed.createComponent(ReqAndCapabilitiesComponent);
+ });
+ })
+ );
+
+ it('should see exactly 2 requirement in requirements table when call initCapabilitiesAndRequirements and meta data requirements null', () => {
+ workspaceServiceMock.metadata.requirements = null;
+ fixture.componentInstance.initCapabilitiesAndRequirements();
+ expect(workspaceServiceMock.metadata.requirements["tosca.requirements.Node"].length).toBe(3);
+ });
+ it('should see exactly 2 capabilities in capabilities table when call initCapabilitiesAndRequirements and meta data capabilities null', () => {
+ workspaceServiceMock.metadata.capabilities = null;
+ fixture.componentInstance.initCapabilitiesAndRequirements();
+ expect(workspaceServiceMock.metadata.capabilities["tosca.capabilities.Node"].length).toBe(2);
+ });
+
+ it('capabilities array papulated when call populateReqOrCap with capabilities', () => {
+ workspaceServiceMock.metadata.capabilities = {"tosca.capabilities.Node": capabilitiesMock, "tosca.capabilities.Scalable": capabilitiesMock};
+ fixture.componentInstance.populateReqOrCap("capabilities");
+ expect(fixture.componentInstance.capabilities.length).toBe(4);
+ });
+
+ it('create requirements component when call loadReqOrCap with true', () => {
+ createDynamicComponentServiceMock.insertComponentDynamically.mockImplementation(() => { return {instance: {requirements: requirementMock}}});
+ fixture.componentInstance.requirements = requirementMock;
+ fixture.componentInstance.loadReqOrCap(true);
+ expect(fixture.componentInstance.instanceRef.instance.requirements.length).toEqual(3);
+ });
+
+ it('create capabilities component when call loadReqOrCap with false', () => {
+ fixture.componentInstance.instanceRef = {instance: {requirements: null}};
+ createDynamicComponentServiceMock.insertComponentDynamically.mockImplementation(() => { return {instance: {capabilities: capabilitiesMock}}});
+ fixture.componentInstance.capabilities = capabilitiesMock;
+ fixture.componentInstance.requirementsUI = filterRequirmentsMock;
+ let event = {
+ target : {
+ value : 'root'
+ }
+ }
+ fixture.componentInstance.updateFilter(event);
+ expect(fixture.componentInstance.instanceRef.instance.requirements.length).toBe(1);
+ });
+
+ it('should filter 1 capabilities when searching and call updateFilter function and instanceRef is capabilities component', () => {
+ fixture.componentInstance.instanceRef = {instance: {capabilities: null}};
+ fixture.componentInstance.capabilities = capabilitiesMock;
+ fixture.componentInstance.selectTabName = 'CAPABILITIES';
+ let event = {
+ target : {
+ value : '1source'
+ }
+ }
+ fixture.componentInstance.updateFilter(event);
+ expect(fixture.componentInstance.instanceRef.instance.capabilities[0].type).toBe("tosca.capabilities.Node");
+ });
+});
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.ts
new file mode 100644
index 0000000000..69999bfb86
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.ts
@@ -0,0 +1,229 @@
+import { Component, ComponentRef, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
+import * as _ from 'lodash';
+import { SdcUiServices } from 'onap-ui-angular';
+import { Capability, CapabilityUI } from '../../../../models/capability';
+import { Requirement, RequirementUI } from '../../../../models/requirement';
+import { TopologyTemplateService } from '../../../services/component-services/topology-template.service';
+import { ComponentGenericResponse } from '../../../services/responses/component-generic-response';
+import { WorkspaceService } from '../workspace.service';
+import { CapabilitiesComponent } from './capabilities/capabilities.component';
+import { RequirmentsComponent } from './requirements/requirments.components';
+import {ReqAndCapabilitiesService} from "./req-and-capabilities.service";
+import {CapabilitiesEditorComponent} from "./capabilities/capabilityEditor/capabilities-editor.component";
+import {ModalComponent} from "onap-ui-angular/dist/modals/modal.component";
+import {EventListenerService} from "../../../../services/event-listener-service";
+import {RequirementsEditorComponent} from "./requirements/requirementEditor/requirements-editor.component";
+
+@Component({
+ selector: 'req-and-capabilities',
+ templateUrl: './req-and-capabilities.component.html',
+ styleUrls: ['./req-and-capabilities.component.less']
+})
+export class ReqAndCapabilitiesComponent implements OnInit {
+
+ @ViewChild('requirmentsContainer', { read: ViewContainerRef }) requirmentsContainer: ViewContainerRef;
+ @ViewChild('capabilitiesContainer', { read: ViewContainerRef }) capabilitiesContainer: ViewContainerRef;
+ private requirements: Requirement[] = [];
+ private requirementsUI: RequirementUI[] = [];
+ private capabilities: Capability[] = [];
+ private selectTabName: string = 'REQUIREMENTS';
+ private notEmptyTable: boolean = true;
+ private instanceRef: ComponentRef<any>;
+ private customModalInstance: ModalComponent;
+ readonly INPUTS_FOR_CAPABILITIES: string = 'INPUTS_FOR_CAPABILITIES';
+ readonly INPUTS_FOR_REQUIREMENTS: string = 'INPUTS_FOR_REQUIREMENTS';
+
+ constructor(private workspaceService: WorkspaceService,
+ private loaderService: SdcUiServices.LoaderService,
+ private topologyTemplateService: TopologyTemplateService,
+ private createDynamicComponentService: SdcUiServices.CreateDynamicComponentService,
+ private reqAndCapabilitiesService : ReqAndCapabilitiesService,
+ private modalService: SdcUiServices.ModalService,
+ private eventListenerService: EventListenerService) {
+ }
+
+ ngOnInit(): void {
+ this.initCapabilitiesAndRequirements();
+
+ this.eventListenerService.registerObserverCallback('CAPABILITIES_UPDATED', () => {
+ this.loadReqOrCap();
+ });
+
+ this.eventListenerService.registerObserverCallback('REQUIREMENTS_UPDATED', () => {
+ this.loadReqOrCap();
+ });
+ }
+
+
+
+ private initCapabilitiesAndRequirements(): void {
+ if (!this.workspaceService.metadata.capabilities || !this.workspaceService.metadata.requirements) {
+ this.loaderService.activate();
+ this.topologyTemplateService.getRequirementsAndCapabilitiesWithProperties
+ (this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId)
+ .subscribe((response: ComponentGenericResponse) => {
+ this.workspaceService.metadata.capabilities = response.capabilities;
+ this.workspaceService.metadata.requirements = response.requirements;
+ this.initReqOrCap();
+ this.loaderService.deactivate();
+ }, (error) => {
+ this.loaderService.deactivate();
+ });
+ } else {
+ this.initReqOrCap();
+ }
+ }
+
+ private initReqOrCap() {
+ this.populateReqOrCap('requirements');
+ this.extendRequirementsToRequiremnetsUI(this.requirements);
+ this.populateReqOrCap('capabilities');
+ this.loadReqOrCap();
+ }
+
+ private populateReqOrCap(instanceName: string) {
+ _.forEach(this.workspaceService.metadata[instanceName], (concatArray: any[], name) => {
+ this[instanceName] = this[instanceName].concat(concatArray);
+ });
+ }
+
+ private updateFilter(event) {
+ const val = event.target.value.toLowerCase();
+ if (this.selectTabName === 'REQUIREMENTS') {
+ this.instanceRef.instance.requirements = this.requirementsUI.filter((req: Requirement) => {
+ return !val || this.filterRequirments(req, val);
+ });
+ } else {
+ this.instanceRef.instance.capabilities = this.capabilities.filter((cap: Capability) => {
+ return !val || this.filterCapabilities(cap, val);
+ });
+ }
+
+ }
+
+ private selectTab($event) {
+ this.selectTabName = $event.title.contains('Requirement') ? 'REQUIREMENTS' : 'CATPABILITIES';
+ this.loadReqOrCap();
+ }
+
+ private async loadReqOrCap() {
+ if (this.instanceRef) {
+ this.instanceRef.destroy();
+ }
+
+ if (this.selectTabName === 'REQUIREMENTS') {
+ this.notEmptyTable = this.requirementsUI.length !== 0;
+ this.instanceRef = this.createDynamicComponentService.
+ insertComponentDynamically(RequirmentsComponent, {requirements: this.requirementsUI}, this.requirmentsContainer);
+ // TODO - Keep the initInputs, so it will be called only for the first time - no need to wait to thse API's every time that a user switches tab
+ await this.reqAndCapabilitiesService.initInputs(this.INPUTS_FOR_REQUIREMENTS);
+ } else {
+ this.notEmptyTable = this.capabilities.length !== 0;
+ this.instanceRef = this.createDynamicComponentService.
+ insertComponentDynamically(CapabilitiesComponent, {capabilities: this.capabilities}, this.capabilitiesContainer);
+ // TODO - Keep the initInputs, so it will be called only for the first time - no need to wait to thse API's every time that a user switches tab
+ await this.reqAndCapabilitiesService.initInputs(this.INPUTS_FOR_CAPABILITIES);
+ }
+ }
+
+ private filterCapabilities(capability: Capability, val: string): boolean {
+ return _.includes([capability.name, capability.description, capability.validSourceTypes.join(),
+ capability.minOccurrences, capability.maxOccurrences].join('').toLowerCase(), val) ||
+ (capability.type && capability.type.replace('tosca.capabilities.', '').toLowerCase().indexOf(val) !== -1);
+ }
+
+ private filterRequirments(requirement: Requirement, val: string): boolean {
+ return _.includes([requirement.name, requirement.minOccurrences, requirement.maxOccurrences].join('').toLowerCase(), val) ||
+ (requirement.capability && requirement.capability.substring('tosca.capabilities.'.length).toLowerCase().indexOf(val) !== -1) ||
+ (requirement.node && requirement.node.substring('tosca.node.'.length).toLowerCase().indexOf(val) !== -1) ||
+ (requirement.relationship && requirement.relationship.substring('tosca.relationship.'.length)
+ .toLowerCase().indexOf(val) !== -1);
+ }
+
+ private addCapability() {
+ let modalConfig = {
+ size: 'md',
+ title: 'Add Capability',
+ type: 'custom',
+ buttons: [
+ {
+ id: 'saveButton',
+ text: ('Create'),
+ size: "'x-small'",
+ callback: () => this.createCapability(),
+ closeModal: true
+ },
+ {text: "Cancel", size: "'x-small'", closeModal: true}]
+ };
+ let modalInputs = {
+ capabilityTypesList: this.reqAndCapabilitiesService.getCapabilityTypesList(),
+ };
+
+ this.customModalInstance = this.modalService.openCustomModal(modalConfig, CapabilitiesEditorComponent, {input: modalInputs});
+ this.customModalInstance.innerModalContent.instance.
+ onValidationChange.subscribe((isValid) => this.customModalInstance.getButtonById('saveButton').disabled = !isValid);
+ }
+
+ private createCapability() {
+ const capability = this.customModalInstance.innerModalContent.instance.capabilityData;
+ this.loaderService.activate();
+ if (!capability.uniqueId) {
+ this.topologyTemplateService.createCapability(this.workspaceService.metadata.getTypeUrl(), this.workspaceService.metadata.uniqueId, capability).subscribe((result) => {
+ this.capabilities.unshift(new CapabilityUI(result[0], this.workspaceService.metadata.uniqueId));
+ this.loadReqOrCap();
+ this.loaderService.deactivate();
+ }, () => {
+ this.loaderService.deactivate();
+ });
+ }
+ }
+
+ private addRequiremnet () {
+ let modalConfig = {
+ size: 'md',
+ title: 'Add Requirement',
+ type: 'custom',
+ buttons: [
+ {
+ id: 'saveButton',
+ text: ('Create'),
+ size: "'x-small'",
+ callback: () => this.createRequirement(),
+ closeModal: true
+ },
+ {text: "Cancel", size: "'x-small'", closeModal: true}]
+ };
+ let modalInputs = {
+ // requirement: req,
+ relationshipTypesList: this.reqAndCapabilitiesService.getRelationsShipeTypeList(),
+ nodeTypesList: this.reqAndCapabilitiesService.getNodeTypesList(),
+ capabilityTypesList: this.reqAndCapabilitiesService.getCapabilityTypesList(),
+ // isReadonly: this.$scope.isViewMode() || !this.$scope.isDesigner(),
+ };
+
+ this.customModalInstance = this.modalService.openCustomModal(modalConfig, RequirementsEditorComponent, {input: modalInputs});
+ this.customModalInstance.innerModalContent.instance.
+ onValidationChange.subscribe((isValid) => this.customModalInstance.getButtonById('saveButton').disabled = !isValid);
+ }
+
+
+ private createRequirement() {
+ const requirement = this.customModalInstance.innerModalContent.instance.requirementData;
+ this.loaderService.activate();
+ if (!requirement.uniqueId) {
+ this.topologyTemplateService.createRequirement(this.workspaceService.metadata.getTypeUrl(), this.workspaceService.metadata.uniqueId, requirement).subscribe(result => {
+ this.requirementsUI.unshift(new RequirementUI(result[0], this.workspaceService.metadata.uniqueId));
+ this.loadReqOrCap();
+ this.loaderService.deactivate();
+ }, () => {
+ this.loaderService.deactivate();
+ });
+ }
+ }
+
+ private extendRequirementsToRequiremnetsUI(requirements: Requirement[]) {
+ this.requirements.map((requirement) => {
+ this.requirementsUI.push(new RequirementUI(requirement, this.workspaceService.metadata.uniqueId));
+ });
+ }
+}
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.module.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.module.ts
new file mode 100644
index 0000000000..aacb3a5bd1
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.module.ts
@@ -0,0 +1,49 @@
+import {NgModule} from "@angular/core";
+import {SdcUiComponentsModule} from "onap-ui-angular";
+
+import {NgxDatatableModule} from "@swimlane/ngx-datatable";
+import { ReqAndCapabilitiesComponent } from "./req-and-capabilities.component";
+import { CommonModule } from "@angular/common";
+
+import {RequirmentsComponent } from "./requirements/requirments.components";
+import { CapabilitiesComponent } from "./capabilities/capabilities.component";
+import { CapabilitiesPropertiesComponent } from "./capabilities/capabilities-properties/capabilities-properties";
+import {ReqAndCapabilitiesService} from "./req-and-capabilities.service";
+import {RequirementsEditorComponent} from "./requirements/requirementEditor/requirements-editor.component";
+import {CapabilitiesEditorComponent} from "./capabilities/capabilityEditor/capabilities-editor.component";
+import {TranslateModule} from "../../../shared/translator/translate.module";
+import {ToscaTypesServiceNg2} from "../../../services/tosca-types.service";
+
+@NgModule({
+ declarations: [
+ ReqAndCapabilitiesComponent,
+ CapabilitiesComponent,
+ RequirmentsComponent,
+ CapabilitiesPropertiesComponent,
+ RequirementsEditorComponent,
+ CapabilitiesEditorComponent
+ ],
+ imports: [
+ CommonModule,
+ SdcUiComponentsModule,
+ NgxDatatableModule,
+ TranslateModule
+ ],
+ exports: [
+ ReqAndCapabilitiesComponent,
+ CapabilitiesComponent,
+ RequirmentsComponent,
+ CapabilitiesPropertiesComponent
+ ],
+ entryComponents: [
+ ReqAndCapabilitiesComponent,
+ CapabilitiesComponent,
+ RequirmentsComponent,
+ CapabilitiesPropertiesComponent,
+ RequirementsEditorComponent,
+ CapabilitiesEditorComponent
+ ],
+ providers: [ ReqAndCapabilitiesService]
+})
+export class reqAndCapabilitiesModule {
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.service.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.service.ts
new file mode 100644
index 0000000000..470aac75a6
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.service.ts
@@ -0,0 +1,80 @@
+import { Injectable } from "@angular/core";
+import { TopologyTemplateService } from "../../../services/component-services/topology-template.service";
+import { Store } from "@ngxs/store";
+import { SdcUiServices } from "onap-ui-angular";
+import { CapabilityTypeModel } from "../../../../models/capability-types";
+import { RelationshipTypeModel } from "../../../../models/relationship-types";
+import { NodeTypeModel } from "../../../../models/node-types";
+import { WorkspaceService } from "../workspace.service";
+import { ToscaTypesServiceNg2 } from "../../../services/tosca-types.service";
+
+
+
+@Injectable()
+export class ReqAndCapabilitiesService {
+
+ private capabilityTypesList: CapabilityTypeModel[];
+ private relationshipTypesList: RelationshipTypeModel[];
+ private nodeTypesList: NodeTypeModel[];
+ private capabilitiesListUpdated: boolean = false;
+ private requirementsListUpdated: boolean = false;
+ private nodeTypeListUpdated: boolean = false;
+
+ readonly INPUTS_FOR_REQUIREMENTS: string = 'INPUTS_FOR_REQUIREMENTS';
+ readonly INPUTS_FOR_CAPABILITIES: string = 'INPUTS_FOR_CAPABILITIES';
+
+ constructor(
+ private workspaceService: WorkspaceService,
+ private modalService: SdcUiServices.ModalService,
+ private loaderService: SdcUiServices.LoaderService,
+ private topologyTemplateService: TopologyTemplateService,
+ private store: Store,
+ private toscaTypesServiceNg2: ToscaTypesServiceNg2){}
+
+ public isViewOnly = (): boolean => {
+ return this.store.selectSnapshot((state) => state.workspace.isViewOnly);
+ }
+
+ public isDesigner = (): boolean => {
+ return this.store.selectSnapshot((state) => state.workspace.isDesigner);
+ }
+
+ public async initInputs(initInputsFor: string) {
+
+ if (!this.capabilitiesListUpdated){
+ // -- COMMON for both --
+ this.capabilityTypesList = [];
+ let capabilityTypesResult = await this.toscaTypesServiceNg2.fetchCapabilityTypes();
+ Object.keys(capabilityTypesResult).forEach(key => {this.capabilityTypesList.push(capabilityTypesResult[key])})
+ this.capabilitiesListUpdated = true;
+ }
+
+ if (initInputsFor === 'INPUTS_FOR_REQUIREMENTS') {
+ if (!this.requirementsListUpdated){
+ this.relationshipTypesList = [];
+ let relationshipTypesResult = await this.toscaTypesServiceNg2.fetchRelationshipTypes();
+ Object.keys(relationshipTypesResult).forEach(key => {this.relationshipTypesList.push(relationshipTypesResult[key])});
+ this.requirementsListUpdated = true;
+ }
+
+ if (!this.nodeTypeListUpdated){
+ this.nodeTypesList = [];
+ let nodeTypesResult = await this.toscaTypesServiceNg2.fetchNodeTypes();
+ Object.keys(nodeTypesResult).forEach(key => {this.nodeTypesList.push(nodeTypesResult[key])})
+ this.nodeTypeListUpdated = true;
+ }
+ }
+ }
+
+ getCapabilityTypesList() {
+ return this.capabilityTypesList;
+ }
+
+ getRelationsShipeTypeList() {
+ return this.relationshipTypesList;
+ }
+
+ getNodeTypesList() {
+ return this.nodeTypesList;
+ }
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.html b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.html
new file mode 100644
index 0000000000..330680d3ed
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.html
@@ -0,0 +1,91 @@
+<div class="requirement-editor">
+ <form class="w-sdc-form">
+ <div class="i-sdc-form-content-requirement-content">
+ <div class="content-row">
+ <div class="i-sdc-form-item">
+ <sdc-input
+ label="{{ 'REQ_NAME' | translate}}"
+ required="true"
+ testId="reqName"
+ [disabled]="isReadonly"
+ [(value)]="requirementData.name"
+ (valueChange)="validityChanged()">
+ </sdc-input>
+ </div>
+ </div>
+
+ <div class="group-with-border">
+ <div class="content-row i-sdc-form-item">
+ <sdc-dropdown
+ label="{{ 'REQ_RELATED_CAPABILITY' | translate }}"
+ testId="reqRelatedCapability"
+ required="true"
+ [disabled]="isReadonly"
+ [options]="capabilityTypesMappedList"
+ selectedOption="{{requirementData.capability}}"
+ [placeHolder] = "requirementData.capability"
+ (changed)="onCapabilityChanged($event)">
+ </sdc-dropdown>
+ </div>
+ <div class="content-row i-sdc-form-item">
+ <sdc-dropdown
+ label="{{ 'REQ_NODE' | translate }}"
+ testId="reqNode"
+ [disabled]="isReadonly"
+ [options]="nodeTypesMappedList"
+ selectedOption="{{requirementData.node}}"
+ [placeHolder] = "requirementData.node"
+ (changed)="onNodeChanged($event)">
+ </sdc-dropdown>
+ </div>
+ <div class="content-row i-sdc-form-item">
+ <sdc-dropdown
+ label="{{ 'REQ_RELATIONSHIP' | translate }}"
+ testId="reqRelationship"
+ [disabled]="isReadonly"
+ [options]="relationshipTypesMappedList"
+ selectedOption="{{requirementData.relationship}}"
+ [placeHolder] = "requirementData.relationship"
+ (changed)="onRelationshipChanged($event)">
+ </sdc-dropdown>
+ </div>
+ </div>
+
+ <label class="i-sdc-form-label occurrences-label"> {{ 'REQ_CAP_OCCURRENCES' | translate}} </label>
+ <div class="content-row occurrences-section">
+ <div class="min-occurrences-value">
+ <sdc-input
+ label="{{ 'REQ_CAP_OCCURRENCES_MIN' | translate}}"
+ testId="reqOccurrencesMin"
+ [disabled]="isReadonly"
+ [(value)]="requirementData.minOccurrences"
+ (valueChange)="validityChanged()"
+ type="number">
+ </sdc-input>
+ </div>
+ <div class="sdc-input">
+ <label class="sdc-input__label"> {{ 'REQ_CAP_OCCURRENCES_MAX' | translate}} </label>
+ <div class="max-occurrences-value">
+ <sdc-checkbox
+ class="checkbox-label unbounded-value"
+ testId="reqOccurrencesMaxUnbounded"
+ label="{{translatedUnboundTxt.toLowerCase()}}"
+ (checkedChange)="onUnboundedChanged()"
+ [checked]="isUnboundedChecked"
+ [disabled]="isReadonly">
+ </sdc-checkbox>
+ <sdc-input
+ *ngIf="!isUnboundedChecked"
+ testId="reqOccurrencesMax"
+ [disabled]="isReadonly"
+ [(value)]="requirementData.maxOccurrences"
+ (valueChange)="validityChanged()"
+ type="number">
+ </sdc-input>
+ </div>
+
+ </div>
+ </div>
+ </div>
+ </form>
+</div> \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.less b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.less
new file mode 100644
index 0000000000..6e50eb79f5
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.less
@@ -0,0 +1,35 @@
+@import '../../../../../../../assets/styles/variables.less';
+
+.requirement-editor {
+ .i-sdc-form-content-requirement-content {
+ padding: 10px 25px;
+
+ .group-with-border {
+ margin: 25px 0;
+ padding: 15px 0;
+ border-top: 1px solid @tlv_color_u;
+ border-bottom: 1px solid @tlv_color_u;
+ .content-row:not(:last-of-type) {
+ padding-bottom: 13px;
+ }
+ }
+
+ .occurrences-label {
+ font-family: @font-opensans-bold;
+ margin-bottom: 19px;
+ }
+ .occurrences-section, /deep/ .max-occurrences-value {
+ display: flex;
+ .min-occurrences-value {
+ padding-right: 30px;
+ }
+ .unbounded-value {
+ padding-top: 7px;
+ padding-right: 20px;
+ .sdc-checkbox__label {
+ text-transform: capitalize;
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.ts
new file mode 100644
index 0000000000..2c5c96f3da
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.ts
@@ -0,0 +1,90 @@
+import {Component} from '@angular/core';
+import {ServiceServiceNg2} from "app/ng2/services/component-services/service.service";
+import {Requirement, RelationshipTypeModel, NodeTypeModel, CapabilityTypeModel} from 'app/models';
+import {TranslateService} from 'app/ng2/shared/translator/translate.service';
+import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component";
+import {Subject} from "rxjs";
+
+@Component({
+ selector: 'requirements-editor',
+ templateUrl: 'requirements-editor.component.html',
+ styleUrls: ['requirements-editor.component.less'],
+ providers: [ServiceServiceNg2, TranslateService]
+})
+
+export class RequirementsEditorComponent {
+
+ input: {
+ requirement: Requirement,
+ relationshipTypesList: Array<RelationshipTypeModel>;
+ nodeTypesList: Array<NodeTypeModel>;
+ capabilityTypesList: Array<CapabilityTypeModel>;
+ isReadonly: boolean;
+ };
+ requirementData: Requirement;
+ capabilityTypesMappedList: Array<DropdownValue>;
+ relationshipTypesMappedList: Array<DropdownValue>;
+ nodeTypesMappedList: Array<DropdownValue>;
+ isUnboundedChecked: boolean;
+ isReadonly: boolean;
+ translatedUnboundTxt: string;
+
+ public onValidationChange: Subject<boolean> = new Subject();
+
+ constructor(private translateService: TranslateService) {
+ }
+
+ ngOnInit() {
+ this.requirementData = new Requirement(this.input.requirement);
+ this.requirementData.minOccurrences = this.requirementData.minOccurrences || 0;
+ this.translatedUnboundTxt = '';
+ this.capabilityTypesMappedList = _.map(this.input.capabilityTypesList, capType => new DropdownValue(capType.toscaPresentation.type, capType.toscaPresentation.type));
+ this.relationshipTypesMappedList = _.map(this.input.relationshipTypesList, rType => new DropdownValue(rType.toscaPresentation.type, rType.toscaPresentation.type));
+ this.nodeTypesMappedList = _.map(this.input.nodeTypesList, nodeType => {
+ return new DropdownValue(
+ nodeType.componentMetadataDefinition.componentMetadataDataDefinition.toscaResourceName,
+ nodeType.componentMetadataDefinition.componentMetadataDataDefinition.toscaResourceName)
+ });
+ this.translateService.languageChangedObservable.subscribe(lang => {
+ this.translatedUnboundTxt = this.translateService.translate('REQ_CAP_OCCURRENCES_UNBOUNDED');
+ this.requirementData.maxOccurrences = this.requirementData.maxOccurrences || this.translatedUnboundTxt;
+ this.isUnboundedChecked = this.requirementData.maxOccurrences === this.translatedUnboundTxt;
+ });
+ this.isReadonly = this.input.isReadonly;
+ this.validityChanged();
+ }
+
+ onUnboundedChanged() {
+ this.isUnboundedChecked = !this.isUnboundedChecked;
+ this.requirementData.maxOccurrences = this.isUnboundedChecked ? this.translatedUnboundTxt : null;
+ this.validityChanged();
+ }
+
+ onCapabilityChanged(selectedCapability: DropdownValue) {
+ this.requirementData.capability = selectedCapability && selectedCapability.value;
+ this.validityChanged();
+ }
+
+ onNodeChanged(selectedNode: DropdownValue) {
+ this.requirementData.node = selectedNode && selectedNode.value;
+ }
+
+ onRelationshipChanged(selectedRelationship: DropdownValue) {
+ this.requirementData.relationship = selectedRelationship && selectedRelationship.value;
+ }
+
+ checkFormValidForSubmit() {
+ return this.requirementData.name && this.requirementData.name.length &&
+ this.requirementData.capability && this.requirementData.capability.length && !_.isEqual(this.requirementData.minOccurrences, "") && this.requirementData.minOccurrences >= 0 &&
+ (
+ this.isUnboundedChecked ||
+ (this.requirementData.maxOccurrences && (this.requirementData.minOccurrences <= parseInt(this.requirementData.maxOccurrences)))
+ );
+ }
+
+ validityChanged = () => {
+ let validState = this.checkFormValidForSubmit();
+ this.onValidationChange.next(validState);
+ }
+
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.module.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.module.ts
new file mode 100644
index 0000000000..b1d8db54aa
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.module.ts
@@ -0,0 +1,28 @@
+import {NgModule} from "@angular/core";
+import {CommonModule} from "@angular/common";
+import {RequirementsEditorComponent} from "./requirements-editor.component";
+import {FormsModule} from "@angular/forms";
+// import {FormElementsModule} from "../../../components/ui/form-components/form-elements.module";
+import {TranslateModule} from 'app/ng2/shared/translator/translate.module';
+import {SdcUiComponentsModule} from "onap-ui-angular/";
+import {FormElementsModule} from 'app/ng2/components/ui/form-components/form-elements.module';
+// import {SdcUiComponentsModule} from "sdc-ui/lib/angular/index";
+
+@NgModule({
+ declarations: [
+ RequirementsEditorComponent
+ ],
+ imports: [CommonModule,
+ FormsModule,
+ FormElementsModule,
+ TranslateModule,
+ SdcUiComponentsModule
+ ],
+ exports: [],
+ entryComponents: [
+ RequirementsEditorComponent
+ ],
+ providers: []
+})
+export class RequirementsEditorModule {
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirements.component.less b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirements.component.less
new file mode 100644
index 0000000000..19f1c9b55a
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirements.component.less
@@ -0,0 +1,4 @@
+/deep/ .importedFromFile {
+ background-color: #f8f8f8;
+ color: #959595;
+ } \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirments.components.html b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirments.components.html
new file mode 100644
index 0000000000..7606ed189a
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirments.components.html
@@ -0,0 +1,38 @@
+<div class="requirements-table">
+ <ngx-datatable #capabilitiesTable
+ columnMode="flex"
+ [headerHeight]="40"
+ [rowHeight]="35"
+ [rowClass]="getRowClass"
+ [rows]="requirements">
+ <ngx-datatable-column name="Name" [flexGrow]="1" [resizeable]="false" >
+ <ng-template ngx-datatable-cell-template let-row="row">
+ <span [ngStyle]="{'cursor':row.isCreatedManually ? 'pointer' : 'null' }" data-tests-id="row.name" sdc-tooltip [tooltip-text]="row.name" [tooltip-placement]="3" (click)="editRequirement(row)">{{row.name}}</span>
+ </ng-template>
+ </ngx-datatable-column>
+ <ngx-datatable-column name="Capability" [flexGrow]="1" [resizeable]="false">
+ <ng-template ngx-datatable-cell-template let-row="row">
+ <span data-tests-id="row.capability" sdc-tooltip [tooltip-text]="row.capability" [tooltip-placement]="3">{{row.capability ? row.capability.substring("tosca.capabilities.".length) : ''}}</span>
+ </ng-template>
+ </ngx-datatable-column>
+ <ngx-datatable-column name="Node" [flexGrow]="1" [resizeable]="false">
+ <ng-template ngx-datatable-cell-template let-row="row">
+ <span data-tests-id="row.node" sdc-tooltip [tooltip-text]="row.node" [tooltip-placement]="3">{{row.node ? row.node.substring("tosca.nodes.".length) : ''}}</span>
+ </ng-template>
+ </ngx-datatable-column>
+ <ngx-datatable-column name="Relationship" [flexGrow]="1" [resizeable]="false">
+ <ng-template ngx-datatable-cell-template let-row="row">
+ <span data-tests-id="row.relationship" sdc-tooltip [tooltip-text]="row.relationship" [tooltip-placement]="3">{{row.relationship ? row.relationship.substring("tosca.relationships.".length): ''}}</span>
+ </ng-template>
+ </ngx-datatable-column>
+ <ngx-datatable-column name="Connected To" [flexGrow]="1" [resizeable]="false">
+ </ngx-datatable-column>
+ <ngx-datatable-column name="Occurrences" [flexGrow]="1" [prop]="'minOccurrences'" [resizeable]="false">
+ <ng-template ngx-datatable-cell-template let-row="row">
+ <span data-tests-id="row.minOccurrences+','+row.maxOccurrences" sdc-tooltip
+ [tooltip-text]="row.minOccurrences+','+row.maxOccurrences" [tooltip-placement]="3">
+ {{row.minOccurrences}},{{row.maxOccurrences}}</span>
+ </ng-template>
+ </ngx-datatable-column>
+ </ngx-datatable>
+</div> \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirments.components.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirments.components.ts
new file mode 100644
index 0000000000..b65489ce4e
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirments.components.ts
@@ -0,0 +1,103 @@
+import {Input, Component, OnInit} from "@angular/core";
+import {Requirement, RequirementUI} from "../../../../../models/requirement";
+import {RequirementsEditorComponent} from "./requirementEditor/requirements-editor.component";
+import {WorkspaceService} from "../../workspace.service";
+import {TopologyTemplateService} from "../../../../services/component-services/topology-template.service";
+import {ReqAndCapabilitiesService} from "../req-and-capabilities.service";
+import {EventListenerService} from "../../../../../services/event-listener-service";
+import {ModalComponent} from "onap-ui-angular/dist/modals/modal.component";
+import {SdcUiServices} from "onap-ui-angular";
+import sortedIndexBy = require("lodash/sortedIndexBy");
+
+@Component({
+ selector: 'requirments',
+ templateUrl: './requirments.components.html',
+ styleUrls: ['../../../../../../assets/styles/table-style.less', './requirements.component.less']
+})
+
+
+
+export class RequirmentsComponent implements OnInit {
+ @Input() public requirements: Array<RequirementUI>;
+ private customModalInstance: ModalComponent;
+
+ constructor(
+ private workspaceService: WorkspaceService,
+ private loaderService: SdcUiServices.LoaderService,
+ private topologyTemplateService: TopologyTemplateService,
+ private reqAndCapabilitiesService : ReqAndCapabilitiesService,
+ private modalService: SdcUiServices.ModalService,
+ private eventListenerService: EventListenerService) {
+ }
+
+
+ ngOnInit(): void {
+ let isCreatedManually: RequirementUI[] = [];
+ let isImportedFromFile: RequirementUI[] = [];
+
+ isCreatedManually = this.requirements.filter((requirement) => requirement.isCreatedManually);
+ isImportedFromFile = this.requirements.filter((requirement) => !requirement.isCreatedManually);
+
+ this.requirements = [];
+
+ isCreatedManually.map((requirement) => this.requirements.push(requirement));
+ isImportedFromFile.map((requirement) => this.requirements.push(requirement));
+
+ }
+
+
+
+ editRequirement(req) {
+
+ let modalConfig = {
+ size: 'md',
+ title: 'Update Requirement',
+ type: 'custom',
+ buttons: [
+ {
+ id: 'saveButton',
+ text: ('Update'),
+ size: "'x-small'",
+ callback: () => this.updateRequirement(),
+ closeModal: true
+ },
+ {text: "Cancel", size: "'x-small'", closeModal: true}]
+ };
+ let modalInputs = {
+ requirement: req,
+ relationshipTypesList: this.reqAndCapabilitiesService.getRelationsShipeTypeList(),
+ nodeTypesList: this.reqAndCapabilitiesService.getNodeTypesList(),
+ capabilityTypesList: this.reqAndCapabilitiesService.getCapabilityTypesList(),
+ // isReadonly: this.$scope.isViewMode() || !this.$scope.isDesigner(),
+ };
+
+ this.customModalInstance = this.modalService.openCustomModal(modalConfig, RequirementsEditorComponent, {input: modalInputs});
+ this.customModalInstance.innerModalContent.instance.
+ onValidationChange.subscribe((isValid) => this.customModalInstance.getButtonById('saveButton').disabled = !isValid);
+
+ }
+
+ private updateRequirement() {
+ const requirement = this.customModalInstance.innerModalContent.instance.requirementData;
+ this.loaderService.activate();
+ if (requirement.uniqueId) {
+ this.topologyTemplateService.updateRequirement(this.workspaceService.metadata.getTypeUrl(), this.workspaceService.metadata.uniqueId, requirement).subscribe(result => {
+ let index = this.requirements.findIndex(req => result[0].uniqueId === req.uniqueId);
+ this.requirements[index] = new RequirementUI(result[0], this.workspaceService.metadata.uniqueId);
+ this.eventListenerService.notifyObservers('REQUIREMENTS_UPDATED');
+ this.loaderService.deactivate();
+ }, () => {
+ this.loaderService.deactivate();
+ });
+ }
+ }
+
+ getRowClass(row) {
+ if (!row.isCreatedManually) {
+ return {
+ 'importedFromFile': true
+ };
+ }
+ }
+
+} \ No newline at end of file