From 41ee9cb182dd5f730c8eb21282004ce6ee4e2927 Mon Sep 17 00:00:00 2001 From: miriame Date: Mon, 4 Mar 2019 13:49:15 +0200 Subject: Add 'Req & Cap' screen for VF/PNF/Service - UI Issue-ID: SDC-2142 Change-Id: I23a2de18862e18389f801cbec3e452d7094df8e9 Signed-off-by: miriame --- .../req-and-capabilities-editable-view.html | 197 ++++++++++++ .../req-and-capabilities-view-model.ts | 355 +++++++++++++++++++-- .../req-and-capabilities/req-and-capabilities.less | 193 ++++++++++- .../view-models/workspace/workspace-view-model.ts | 8 +- 4 files changed, 721 insertions(+), 32 deletions(-) create mode 100644 catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-editable-view.html (limited to 'catalog-ui/src/app/view-models') diff --git a/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-editable-view.html b/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-editable-view.html new file mode 100644 index 0000000000..14bc49e28b --- /dev/null +++ b/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-editable-view.html @@ -0,0 +1,197 @@ + + +
+ + +
+
+
Requirements +
+
Capabilities +
+
+
+ +
+ + + {{mode === 'requirements' ? 'Add Requirement' : 'Add Capability'}} +
+
+
+ +
+
+ + +
{{mode === 'requirements' ? 'Add Requirement' : 'Add Capability'}}
+
+
+ +
+
+
+
+ {{header.title}} + +
+
+ +
+ +
+ There are no requirements to display + +
+
+
+
+ {{req.name}} +
+
+ {{req.capability && cutToscaTypePrefix(req.capability, 'capabilities.')}} +
+
+ {{req.node && cutToscaTypePrefix(req.node, "nodes.")}} +
+
+ {{req.relationship && cutToscaTypePrefix(req.relationship, "relationships.")}} +
+
+ {{req.minOccurrences}} - {{req.maxOccurrences}} +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ {{header.title}} + +
+
+ +
+ +
+ There are no capabilities to display + +
+
+ +
+ {{capability.name}} +
+
+ {{capability.type && cutToscaTypePrefix(capability.type, 'capabilities.')}} +
+ +
+
{{capability.description}} +
+
+ +
+ {{capability.validSourceTypes.join(',')}} +
+ +
+ {{capability.minOccurrences}} - {{capability.maxOccurrences}} +
+ +
+ +
+
+
+
+ +
+
+
+ diff --git a/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view-model.ts index 6eaae44eb2..165578d008 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view-model.ts +++ b/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view-model.ts @@ -23,33 +23,82 @@ */ 'use strict'; import * as _ from "lodash"; +import {ComponentRef} from '@angular/core'; import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model"; -import {ModalsHandler} from "app/utils"; -import {Capability, PropertyModel, Requirement} from "app/models"; -import {ComponentGenericResponse} from "../../../../ng2/services/responses/component-generic-response"; -import {ComponentServiceNg2} from "../../../../ng2/services/component-services/component.service"; +import {ModalsHandler, ResourceType} from "app/utils"; +import {ComponentType} from "app/utils/constants"; +import { + Capability, PropertyModel, Requirement, Resource, + RelationshipTypesMap, NodeTypesMap, CapabilityTypesMap +} from "app/models"; +import {ComponentGenericResponse} from "app/ng2/services/responses/component-generic-response"; +import {ComponentServiceNg2} from "app/ng2/services/component-services/component.service"; +import {ToscaTypesServiceNg2} from "app/ng2/services/tosca-types.service"; +import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component'; +import {ModalService} from 'app/ng2/services/modal.service'; +import {RequirementsEditorComponent} from 'app/ng2/pages/req-and-capabilities-editor/requirements-editor/requirements-editor.component'; +import {CapabilitiesEditorComponent} from 'app/ng2/pages/req-and-capabilities-editor/capabilities-editor/capabilities-editor.component'; +import {ModalService as ModalServiceSdcUI} from "sdc-ui/lib/angular/modals/modal.service"; +import {IModalConfig} from "sdc-ui/lib/angular/modals/models/modal-config"; +import {ModalButtonComponent} from "sdc-ui/lib/angular/components"; export class SortTableDefined { reverse:boolean; sortByField:string; } +class RequirementUI extends Requirement { + isCreatedManually: boolean; + + constructor(input: Requirement, componentUniqueId: string) { + super(input); + this.isCreatedManually = input.ownerId === componentUniqueId; + } +} +class CapabilityUI extends Capability { + isCreatedManually: boolean; + + constructor(input: Capability, componentUniqueId: string) { + super(input); + this.isCreatedManually = input.ownerId === componentUniqueId; + } +} + interface IReqAndCapabilitiesViewModelScope extends IWorkspaceViewModelScope { requirementsTableHeadersList:Array; + editableRequirementsTableHeadersList: Array; capabilitiesTableHeadersList:Array; + editableCapabilitiesTableHeadersList: Array; capabilityPropertiesTableHeadersList:Array; requirementsSortTableDefined:SortTableDefined; capabilitiesSortTableDefined:SortTableDefined; propertiesSortTableDefined:SortTableDefined; - requirements:Array; - capabilities:Array; + requirements: Array; + filteredRequirementsList: Array; + capabilities: Array; + filteredCapabilitiesList: Array; mode:string; filteredProperties:Array>; searchText:string; + isEditable: boolean; + modalInstance: ComponentRef; + filter: {txt: string; show: boolean}; sort(sortBy:string, sortByTableDefined:SortTableDefined):void; + sortByIsCreatedManually(arrToSort: Array): Array; updateProperty(property:PropertyModel, indexInFilteredProperties:number):void; allCapabilitiesSelected(selected:boolean):void; + onAddBtnClicked(): void; + onEditRequirement(req: RequirementUI): void; + onEditCapability(cap: CapabilityUI): void; + onDeleteReq(event, req: RequirementUI): void; + onDeleteCap(event, cap: CapabilityUI): void; + onFilter(): void; + isListEmpty(): boolean; + onSwitchTab(): void; + onSearchIconClick(): void; + cutToscaTypePrefix(valToCut: string, textToStartCut: string): string; + isReadonly(): boolean; } export class ReqAndCapabilitiesViewModel { @@ -58,33 +107,37 @@ export class ReqAndCapabilitiesViewModel { '$scope', '$filter', 'ModalsHandler', - 'ComponentServiceNg2' + 'ComponentServiceNg2', + 'ToscaTypesServiceNg2', + 'ModalServiceNg2', + 'ModalServiceSdcUI' ]; constructor(private $scope:IReqAndCapabilitiesViewModelScope, private $filter:ng.IFilterService, private ModalsHandler:ModalsHandler, - private ComponentServiceNg2: ComponentServiceNg2) { + private ComponentServiceNg2: ComponentServiceNg2, + private ToscaTypesServiceNg2: ToscaTypesServiceNg2, + private ModalServiceNg2: ModalService, + private ModalServiceSdcUI: ModalServiceSdcUI) { this.initCapabilitiesAndRequirements(); + this.fetchCapabilitiesRelatedData(); } private initCapabilitiesAndRequirements = (): void => { - if(!this.$scope.component.capabilities || !this.$scope.component.requirements) { - this.$scope.isLoading = true; - this.ComponentServiceNg2.getCapabilitiesAndRequirements(this.$scope.component.componentType, this.$scope.component.uniqueId).subscribe((response:ComponentGenericResponse) => { - this.$scope.component.capabilities = response.capabilities; - this.$scope.component.requirements = response.requirements; - this.initScope(); - this.$scope.isLoading = false; - }, () => { - this.$scope.isLoading = false; - }); - } else { + this.$scope.isEditable = this.getIsEditableByComponentType(); + this.$scope.isLoading = true; + this.ComponentServiceNg2.getCapabilitiesAndRequirements(this.$scope.component.componentType, this.$scope.component.uniqueId).subscribe((response: ComponentGenericResponse) => { + this.$scope.component.capabilities = response.capabilities; + this.$scope.component.requirements = response.requirements; this.initScope(); - } + this.$scope.isLoading = false; + }, () => { + this.$scope.isLoading = false; + }); } @@ -98,15 +151,18 @@ export class ReqAndCapabilitiesViewModel { }); }; - private initScope = ():void => { - + private initScope = (currentMode = 'requirements'): void => { + this.$scope.isReadonly = (): boolean => { + return this.$scope.isViewMode() || !this.$scope.isDesigner(); + }; + this.$scope.filter = {txt: '', show: false}; this.$scope.requirementsSortTableDefined = { reverse: false, - sortByField: 'name' + sortByField: this.$scope.isEditable ? 'other' : 'name' }; this.$scope.capabilitiesSortTableDefined = { reverse: false, - sortByField: 'name' + sortByField: this.$scope.isEditable ? 'other' : 'name' }; this.$scope.propertiesSortTableDefined = { reverse: false, @@ -129,6 +185,22 @@ export class ReqAndCapabilitiesViewModel { {title: 'Valid Source', property: ''}, {title: 'Occurrences', property: ''} ]; + this.$scope.editableRequirementsTableHeadersList = [ + {title: 'Name', property: 'name'}, + {title: 'Capability', property: 'capability'}, + {title: 'Node', property: 'node'}, + {title: 'Relationship', property: 'relationship'}, + {title: 'Occurrences', property: 'occurrences'}, + {title: '●●●', property: 'other'} + ]; + this.$scope.editableCapabilitiesTableHeadersList = [ + {title: 'Name', property: 'name'}, + {title: 'Type', property: 'type'}, + {title: 'Description', property: 'description'}, + {title: 'Valid Sources', property: 'valid-sources'}, + {title: 'Occurrences', property: 'occurrences'}, + {title: '●●●', property: 'other'} + ]; this.$scope.capabilityPropertiesTableHeadersList = [ {title: 'Name', property: 'name'}, {title: 'Type', property: 'type'}, @@ -137,17 +209,26 @@ export class ReqAndCapabilitiesViewModel { ]; this.$scope.filteredProperties = []; - this.$scope.mode = 'requirements'; + this.$scope.mode = currentMode; this.$scope.requirements = []; _.forEach(this.$scope.component.requirements, (req:Array, capName)=> { - this.$scope.requirements = this.$scope.requirements.concat(req); + let reqUIList: Array = _.map(req, reqObj => new RequirementUI(reqObj, this.$scope.component.uniqueId)); + this.$scope.requirements = this.$scope.requirements.concat(reqUIList); }); + this.$scope.filteredRequirementsList = this.$scope.requirements; this.$scope.capabilities = []; _.forEach(this.$scope.component.capabilities, (cap:Array, capName)=> { - this.$scope.capabilities = this.$scope.capabilities.concat(cap); + let capUIList: Array = _.map(cap, capObj => new CapabilityUI(capObj, this.$scope.component.uniqueId)); + this.$scope.capabilities = this.$scope.capabilities.concat(capUIList); }); + this.$scope.sortByIsCreatedManually = (arrToSort: Array): Array => { + return arrToSort.sort((elem1: RequirementUI|CapabilityUI, elem2: RequirementUI|CapabilityUI) => +elem2.isCreatedManually - (+elem1.isCreatedManually)); + }; + this.$scope.filteredCapabilitiesList = this.$scope.sortByIsCreatedManually(this.$scope.capabilities); + this.$scope.filteredRequirementsList = this.$scope.sortByIsCreatedManually(this.$scope.requirements); + this.$scope.sort = (sortBy:string, sortByTableDefined:SortTableDefined):void => { sortByTableDefined.reverse = (sortByTableDefined.sortByField === sortBy) ? !sortByTableDefined.reverse : false; sortByTableDefined.sortByField = sortBy; @@ -162,6 +243,226 @@ export class ReqAndCapabilitiesViewModel { cap.selected = selected; }); }; + this.$scope.onAddBtnClicked = (): void => { + switch (this.$scope.mode) { + case 'requirements': + this.openRequirementsModal(); + break; + case 'capabilities': + this.openCapabilitiesModal(); + break; + } + }; + this.$scope.onEditRequirement = (req: RequirementUI): void => { + this.openRequirementsModal(req); + }; + this.$scope.onEditCapability = (cap: CapabilityUI): void => { + this.openCapabilitiesModal(cap); + }; + this.$scope.onDeleteReq = (event: Event, req: RequirementUI): void => { + event.stopPropagation(); + this.ModalServiceSdcUI.openAlertModal('Delete Requirement', + `Are you sure you want to delete requirement: ${req.name}?`, 'OK', () => this.deleteRequirement(req), 'Cancel'); + }; + this.$scope.onDeleteCap = (event: Event, cap: CapabilityUI): void => { + event.stopPropagation(); + this.ModalServiceSdcUI.openAlertModal('Delete Capability', + `Are you sure you want to delete capability: ${cap.name}?`, 'OK', () => this.deleteCapability(cap), 'Cancel'); + }; + this.$scope.onSearchIconClick = (): void => { + this.$scope.filter.show = !!this.$scope.filter.txt || !this.$scope.filter.show; + }; + this.$scope.onFilter = (): void => { + switch (this.$scope.mode) { + case 'requirements': + this.$scope.filteredRequirementsList = _.filter(this.$scope.requirements, req => req.name.includes(this.$scope.filter.txt)); + break; + case 'capabilities': + this.$scope.filteredCapabilitiesList = _.filter(this.$scope.capabilities, cap => cap.name.includes(this.$scope.filter.txt)); + break; + } + }; + this.$scope.isListEmpty = (): boolean => { + switch (this.$scope.mode) { + case 'requirements': + return this.$scope.requirements.length === 0; + case 'capabilities': + return this.$scope.capabilities.length === 0; + } + }; + this.$scope.onSwitchTab = (): void => { + this.$scope.mode = this.$scope.mode === 'requirements' ? 'capabilities' : 'requirements'; + this.$scope.filter.txt = ''; + this.$scope.filter.show = false; + this.$scope.filteredRequirementsList = this.$scope.requirements; + this.$scope.filteredCapabilitiesList = this.$scope.capabilities; + }; + this.$scope.cutToscaTypePrefix = (valToCut: string, textToStartCut: string): string => { + let index = valToCut.indexOf(textToStartCut); + return index !== -1 ? valToCut.substr(index + textToStartCut.length) : valToCut; + }; + }; + + private getIsEditableByComponentType() { + if (this.$scope.componentType === ComponentType.SERVICE) { + return true; + } + if (this.$scope.component.isResource()) { + let componentAsResource: Resource = this.$scope.component; + return componentAsResource.resourceType === ResourceType.VF || + componentAsResource.resourceType === ResourceType.PNF; + } + return false; + }; + + private fetchCapabilitiesRelatedData() { + if (this.$scope.isEditable) { + this.$scope.capabilityTypesList = []; + this.ToscaTypesServiceNg2.fetchCapabilityTypes().subscribe((result: CapabilityTypesMap) => { + _.forEach(result, capabilityType => this.$scope.capabilityTypesList.push(capabilityType)); + }); + this.$scope.nodeTypesList = []; + this.ToscaTypesServiceNg2.fetchNodeTypes().subscribe((result: NodeTypesMap) => { + _.forEach(result, nodeType => this.$scope.nodeTypesList.push(nodeType)); + }); + this.$scope.relationshipTypesList = []; + this.ToscaTypesServiceNg2.fetchRelationshipTypes().subscribe((result: RelationshipTypesMap) => { + _.forEach(result, relshipType => this.$scope.relationshipTypesList.push(relshipType)); + }); + } + } + + private openRequirementsModal(req?: RequirementUI) { + let modalConfig: IModalConfig = { + size: 'md', + title: (req ? 'Update' : 'Add') + ' Requirement', + type: 'custom', + buttons: [ + { + id: 'saveButton', + text: (req ? 'Update' : 'Create'), + size: "'x-small'", + callback: () => this.createOrUpdateRequirement(), + closeModal: true + }, + {text: "Cancel", size: "'x-small'", closeModal: true}] + }; + let modalInputs = { + requirement: req, + relationshipTypesList: this.$scope.relationshipTypesList, + nodeTypesList: this.$scope.nodeTypesList, + capabilityTypesList: this.$scope.capabilityTypesList, + isReadonly: this.$scope.isViewMode() || !this.$scope.isDesigner(), + validityChangedCallback: this.getDisabled + }; + + this.ModalServiceSdcUI.openCustomModal(modalConfig, RequirementsEditorComponent, {input: modalInputs}); + } + + private openCapabilitiesModal(cap?: CapabilityUI) { + let modalConfig: IModalConfig = { + size: 'md', + title: (cap ? 'Update' : 'Add') + ' Capability', + type: 'custom', + buttons: [ + { + id: 'saveButton', + text: (cap ? 'Update' : 'Create'), + size: "'x-small'", + callback: () => this.createOrUpdateCapability(), + closeModal: true + }, + {text: "Cancel", size: "'x-small'", closeModal: true}] + }; + let modalInputs = { + capability: cap, + capabilityTypesList: this.$scope.capabilityTypesList, + isReadonly: this.$scope.isViewMode() || !this.$scope.isDesigner(), + validityChangedCallback: this.getDisabled + }; + + this.ModalServiceSdcUI.openCustomModal(modalConfig, CapabilitiesEditorComponent, {input: modalInputs}); + } + + getDisabled = (shouldEnable: boolean): void => { + let saveButton: ModalButtonComponent = this.ModalServiceSdcUI.getCurrentInstance().getButtonById('saveButton'); + saveButton.disabled = this.$scope.isViewMode() || !this.$scope.isDesigner() || !shouldEnable; + }; + + private createOrUpdateRequirement() { + let requirement = this.ModalServiceSdcUI.getCurrentInstance().innerModalContent.instance.requirementData; + this.$scope.isLoading = true; + if (!requirement.uniqueId) { + this.ComponentServiceNg2.createRequirement(this.$scope.component, requirement).subscribe(result => { + this.$scope.requirements.unshift(new RequirementUI(result[0], this.$scope.component.uniqueId)); + this.$scope.isLoading = false; + }, () => { + this.$scope.isLoading = false; + }); + } + else { + this.ComponentServiceNg2.updateRequirement(this.$scope.component, requirement).subscribe(result => { + let index = this.$scope.requirements.findIndex(req => result[0].uniqueId === req.uniqueId); + this.$scope.requirements[index] = new RequirementUI(result[0], this.$scope.component.uniqueId); + this.$scope.isLoading = false; + this.$scope.$apply(); + }, () => { + this.$scope.isLoading = false; + }); + } + } + + private createOrUpdateCapability() { + let capability = this.ModalServiceSdcUI.getCurrentInstance().innerModalContent.instance.capabilityData; + this.$scope.isLoading = true; + if (!capability.uniqueId) { + this.ComponentServiceNg2.createCapability(this.$scope.component, capability).subscribe(result => { + this.$scope.capabilities.unshift(new CapabilityUI(result[0], this.$scope.component.uniqueId)); + this.$scope.isLoading = false; + }, () => { + this.$scope.isLoading = false; + }); + } + else { + this.ComponentServiceNg2.updateCapability(this.$scope.component, capability).subscribe(result => { + let index = this.$scope.capabilities.findIndex(cap => result[0].uniqueId === cap.uniqueId); + this.$scope.capabilities[index] = new CapabilityUI(result[0], this.$scope.component.uniqueId); + this.$scope.isLoading = false; + this.$scope.$apply(); + }, () => { + this.$scope.isLoading = false; + }); + } + } + + private deleteRequirement(req) { + this.$scope.isLoading = true; + this.ComponentServiceNg2.deleteRequirement(this.$scope.component, req.uniqueId).subscribe(() => { + this.ComponentServiceNg2.getCapabilitiesAndRequirements(this.$scope.componentType, this.$scope.component.uniqueId).subscribe(response => { + this.$scope.component.requirements = response.requirements; + this.initScope('requirements'); + this.$scope.isLoading = false; + }, () => { + this.$scope.isLoading = false; + }); + }, () => { + this.$scope.isLoading = false; + }); + } + + private deleteCapability(cap) { + this.$scope.isLoading = true; + this.ComponentServiceNg2.deleteCapability(this.$scope.component, cap.uniqueId).subscribe(() => { + this.ComponentServiceNg2.getCapabilitiesAndRequirements(this.$scope.componentType, this.$scope.component.uniqueId).subscribe(response => { + this.$scope.component.capabilities = response.capabilities; + this.initScope('capabilities'); + this.$scope.isLoading = false; + }, () => { + this.$scope.isLoading = false; + }); + }, () => { + this.$scope.isLoading = false; + }); } } diff --git a/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities.less b/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities.less index 9b52fad411..fa6623f089 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities.less +++ b/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities.less @@ -65,13 +65,14 @@ } } } - .expand-collapse-buttons{ + .add-button { + color: @main_color_a; + } + .add-button, .expand-collapse-buttons { float: right; - width: 44px; margin-left: 11px; margin-top: 10px; - span{ - vertical-align: bottom; + &, span { .hand; } } @@ -108,6 +109,28 @@ white-space: nowrap; } + .editable-table-data { + max-height: 430px; + } + + .data-row { + &:not(.editable-row) { + background: @tlv_color_t; + color: @main_color_n; + } + &.editable-row { + cursor: pointer; + } + .sprite-new.delete-icon { + visibility: hidden; + } + &:hover { + .sprite-new.delete-icon { + visibility: visible; + } + } + } + &.requirements-table{ border-top: 4px solid @main_color_a; .flex-item:nth-child(1) { @@ -194,3 +217,165 @@ } } + +.workspace-req-and-cap-editable { + .tabs-header { + display: flex; + justify-content: space-between; + border-bottom: 1px solid @main_color_o; + .req-and-cap-tabs { + display: flex; + .tab { + font-family: @font-opensans-regular; + font-size: 22px; + padding: 5px; + .hand; + &:first-of-type { + margin-right: 35px; + } + &.selected { + color: @main_color_a; + border-bottom: 2px solid @main_color_a; + } + } + } + .buttons-in-right { + display: flex; + .search { + display: flex; + height: min-content; + margin-top: 10px; + padding-right: 11px; + border-right: 1px solid @main_color_o; + #search-box { + border: none; + border-bottom: 1px solid @main_color_o; + text-indent: 10px; + &:focus { + outline: none; + } + } + .search-icon-container { + margin-top: 3px; + padding-top: 4px; + } + + } + .add-button-icon-and-label { + font-size: 14px; + margin-left: 11px; + margin-top: 10px; + padding-top: 5px; + /deep/ svg-icon { + vertical-align: bottom; + } + &:hover { + &:not(.disabled) { + cursor: pointer; + color: @sdcui_color_light-blue; + } + } + } + } + } + .add-button-icon-and-label { + .icon-label-txt { + text-transform: uppercase; + font-family: @font-opensans-medium; + color: @main_color_a; + &:hover { + &:not(.disabled) { + color: @sdcui_color_light-blue; + } + } + } + } + .empty-list-container { + width: 100%; + display: flex; + justify-content: center; + + .empty-list-add-btn { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + border: 1px solid @main_color_o; + margin-top: 50px; + height: 229px; + width: 480px; + &.disabled { + pointer-events: none; + } + &:hover { + &:not(.disabled) { + border: 1px solid @main_color_a; + cursor: pointer; + } + } + .icon-label-txt { + margin-top: 15px; + font-size: 16px; + } + } + } + .table-container-flex .table .head .head-row { + text-align: left; + &.description { + flex: 2; + } + &.other { + flex: 0.25; + text-align: center; + } + &.occurrences { + flex: 0.75; + } + } + .data-row { + .ellipsis-text { + overflow: hidden; + text-overflow: ellipsis; + } + &:not(.editable-row) { + background: @tlv_color_t; + cursor: default; + color: @main_color_n; + } + &.editable-row { + cursor: pointer; + .table-col-general:hover { + color: @main_color_b; + } + } + .description-col { + flex: 2; + } + .occurrences-col { + flex: 0.75; + } + .other-col { + display: flex; + justify-content: center; + align-items: center; + flex: 0.25; + .trash-icon { + visibility: hidden; + } + } + &:hover { + .trash-icon { + visibility: visible; + } + } + .multiline-ellipsis { + line-height: 1.5em; + padding: 1px 0 1px 0; + /deep/ .ellipsis-directive-more-less { + float: none; + margin-left: 5px; + color: @main_color_a; + } + } + } +} diff --git a/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts b/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts index 676a2d38d3..9429022b48 100644 --- a/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts +++ b/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts @@ -23,7 +23,10 @@ */ 'use strict'; import * as _ from "lodash"; -import {IUserProperties, IAppMenu, Resource, Component, Plugin, PluginsConfiguration, PluginDisplayOptions} from "app/models"; +import { + IUserProperties, IAppMenu, Resource, Component, Plugin, PluginsConfiguration, PluginDisplayOptions, + RelationshipTypeModel, NodeTypeModel, CapabilityTypeModel +} from "app/models"; import { WorkspaceMode, ComponentFactory, ChangeLifecycleStateHandler, Role, ComponentState, MenuItemGroup, MenuHandler, MenuItem, ModalsHandler, States, EVENTS, CHANGE_COMPONENT_CSAR_VERSION_FLAG, ResourceType, PREVIOUS_CSAR_COMPONENT @@ -78,6 +81,9 @@ export interface IWorkspaceViewModelScope extends ng.IScope { unsavedChanges:boolean; unsavedChangesCallback:Function; unsavedFile:boolean; + capabilityTypesList: Array; + relationshipTypesList: Array; + nodeTypesList: Array; startProgress(message:string):void; -- cgit 1.2.3-korg