diff options
author | Michael Lando <ml636r@att.com> | 2018-07-29 16:13:45 +0300 |
---|---|---|
committer | Michael Lando <ml636r@att.com> | 2018-07-29 16:20:34 +0300 |
commit | 5b593496b8f1b8e8be8d7d2dbcc223332e65a49b (patch) | |
tree | 2f9dfc45191e723da69cf74be7829784e9741b94 /catalog-ui/src/app/ng2/components | |
parent | 9200382f2ce7b4bb729aa287d0878004b2d2b4f9 (diff) |
re base code
Change-Id: I12a5ca14a6d8a87e9316b9ff362eb131105f98a5
Issue-ID: SDC-1566
Signed-off-by: Michael Lando <ml636r@att.com>
Diffstat (limited to 'catalog-ui/src/app/ng2/components')
53 files changed, 870 insertions, 166 deletions
diff --git a/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.html b/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.html index 55c4bf0460..78f311112e 100644 --- a/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.html +++ b/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.html @@ -20,7 +20,7 @@ <li [ngClass]="{'selected': $last }"> <a (click)="menuItemClick(groupItem, groupItem.menuItems[groupItem.selectedIndex])" [attr.data-tests-id]="'breadcrumbs-button-' + $index"> - {{groupItem.menuItems[groupItem.selectedIndex].text}} + {{groupItem.menuItems[groupItem.selectedIndex]?.text}} </a> </li> <li class="triangle-dropdown" diff --git a/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.ts b/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.ts index a0b6b2b543..881a91613d 100644 --- a/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.ts +++ b/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.ts @@ -41,6 +41,8 @@ export class TopNavComponent { @Input() public hideSearch:boolean; @Input() public searchTerm:string; @Input() public notificationIconCallback:Function; + @Input() public unsavedChanges: boolean; + @Input() public unsavedChangesCallback: (completeCallback:Function)=> Promise<any>; @Output() public searchTermChange:EventEmitter<string> = new EventEmitter<string>(); emitSearchTerm(event:string) { this.searchTermChange.emit(event); @@ -80,17 +82,21 @@ export class TopNavComponent { return true; }); - //if it's a different state , checking previous state param + //if it's a different state if (result === -1) { - this.topLvlMenu.menuItems.forEach((item:MenuItem, index:number)=> { - if (item.state === this.$state.params['previousState']) { - result = index; - } - }); - } + //if in 'workspace' - checking previous state param + if (this.$state.includes('workspace')) { + // if previous state is 'dashboard' or 'catalog', then select it - otherwise, use 'catalog' as default for 'workspace' + const selectedStateName = (['dashboard', 'catalog'].indexOf(this.$state.params['previousState']) !== -1) + ? this.$state.params['previousState'] + : 'catalog'; + result = this.topLvlMenu.menuItems.findIndex((item:MenuItem) => item.state === selectedStateName); + } - if (result === -1) { - result = 0; + //if yet, none is selected, then select the first as default + if (result === -1) { + result = 0; + } } return result; @@ -151,8 +157,21 @@ export class TopNavComponent { } menuItemClick(itemGroup:MenuItemGroup, item:MenuItem) { - itemGroup.itemClick = false; + let onSuccessFunction = () => { + this.navigate(itemGroup, item); + } + if (this.unsavedChanges && this.unsavedChangesCallback){ + this.unsavedChangesCallback(onSuccessFunction).then((onSuccess)=> { + this.navigate(itemGroup, item); + }, (onReject) => {}); + } else { + this.navigate(itemGroup, item); + } + } + + navigate(itemGroup:MenuItemGroup, item:MenuItem) { + itemGroup.itemClick = false; let onSuccess = ():void => { itemGroup.selectedIndex = itemGroup.menuItems.indexOf(item); }; @@ -165,4 +184,5 @@ export class TopNavComponent { this[item.action](item.state, item.params).then(onSuccess, onFailed); } } + } diff --git a/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-display-options.ts b/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-display-options.ts index c8d4566653..36257ca94e 100644 --- a/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-display-options.ts +++ b/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-display-options.ts @@ -23,10 +23,16 @@ export class HierarchyDisplayOptions { valueProperty: string; childrenProperty: string; searchText:string; - constructor(idProperty:string, valueProperty:string, childrenProperty?:string, searchText?:string) { + archived:boolean; + + iconProperty: string; + constructor(idProperty:string, valueProperty:string, childrenProperty?:string, searchText?:string, iconProperty?:string, archived?:boolean) { + this.idProperty = idProperty; this.valueProperty = valueProperty; this.childrenProperty = childrenProperty; this.searchText = searchText; + this.archived = archived; + this.iconProperty = iconProperty; } } diff --git a/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.html b/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.html index c3f9e5ac74..aa60337f84 100644 --- a/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.html +++ b/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.html @@ -1,7 +1,12 @@ <div class="navigation-wrapper"> <div class="node-item" *ngFor="let item of displayData" (click)="onClick($event, item)"> <div class="node-data-wrapper" [ngClass]="{'selected': selectedItem && selectedItem === item[displayOptions.idProperty]}"> - <span class="node-data" [ngClass]="{'mark':item[displayOptions.valueProperty] === displayOptions.searchText}" [attr.data-tests-id]="item[displayOptions.valueProperty]">{{item[displayOptions.valueProperty]}}</span> + <span class="node-data" [ngClass]="{'mark':item[displayOptions.valueProperty] === displayOptions.searchText}" [attr.data-tests-id]="item[displayOptions.valueProperty]"> + + <span *ngIf="displayOptions.iconProperty" [ngClass]="['node-data-icon', item[displayOptions.iconProperty], 'small']"></span> + {{item[displayOptions.valueProperty]}} + <span class="sprite-new archive-label" *ngIf="item.originArchived"></span> + </span> </div> <div class="children-node" *ngIf="item[displayOptions.childrenProperty]"> <hierarchy-navigation class="children-hierarchy" [displayData]="item[displayOptions.childrenProperty]" diff --git a/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.less b/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.less index 4befa2c797..33ffb49537 100644 --- a/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.less +++ b/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.less @@ -1,3 +1,5 @@ +@import './../../../../../assets/styles/mixins.less'; + .navigation-wrapper { text-align: left; } @@ -30,6 +32,25 @@ .node-data { margin-left: 10px; margin-right: 10px; + align-items: center; + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 300px; + .archive-label{ + margin-left: 5px; + } +} + +.node-data-icon { + vertical-align: middle; + margin-right: 7px; + + &.defaulticon.small { + background-color: #999; + border-radius: 14px; + } } .node-data-wrapper.selected { @@ -50,3 +71,20 @@ +.icon-group { + .square-icon(); + background-color: @main_color_a; + + &::before { + content: "G"; + } +} +.icon-policy { + .square-icon(); + background-color: @main_color_r; + + &::before { + content: "P"; + } +} + diff --git a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html index b7cde7eb23..daffc9efea 100644 --- a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html +++ b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html @@ -17,8 +17,8 @@ tooltip="{{input.description}}" tooltipDelay="0"></span> </div> <div class="table-cell col3"> - <div class="inner-cell-div" tooltip="{{instanceNamesMap[input.instanceUniqueId]}}"> - <span>{{instanceNamesMap[input.instanceUniqueId]}}</span> + <div class="inner-cell-div" tooltip="{{instanceNamesMap[input.instanceUniqueId]?.name}}"> + <span>{{instanceNamesMap[input.instanceUniqueId]?.name}}</span> </div> </div> <div class="table-cell col2"> @@ -34,7 +34,8 @@ [type]="input.type" [name]="input.name" (elementChanged)="onInputChanged(input, $event)" - [readonly]="readonly"> + [readonly]="readonly" + [testId]="'input-' + input.name"> </dynamic-element> <div class="delete-button-container"> <span *ngIf="input.instanceUniqueId && !readonly" class="sprite-new delete-btn" (click)="openDeleteModal(input)" data-tests-id="delete-input-button"></span> diff --git a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less index d709f3f0c5..5fbb62f7fb 100644 --- a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less +++ b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less @@ -85,8 +85,8 @@ border-right:#d2d2d2 solid 1px; } &.col1 { - flex: 1 0 210px; - max-width:210px; + flex: 1 0 120px; + max-width:120px; display: flex; justify-content: space-between; @@ -112,14 +112,7 @@ } &.valueCol { - flex: 1 0 auto; - min-width: 350px; - display: flex; - justify-content: flex-end; - padding: 0px; - align-items: center; - - .value-input { + .value-input { flex: 1; border: none; background-color: inherit; @@ -142,7 +135,7 @@ padding: 0px; .delete-button-container { - padding: 3px 5px 0 0 ; + padding: 0 8px 0 0 ; } } } diff --git a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts index ebecbc9390..0c7fc2a24c 100644 --- a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts @@ -24,6 +24,7 @@ import {Component, Input, Output, EventEmitter} from "@angular/core"; import {InputFEModel} from "app/models"; import {ModalService} from "../../../services/modal.service"; +import { InstanceFeDetails } from "app/models/instance-fe-details"; @Component({ selector: 'inputs-table', @@ -33,7 +34,7 @@ import {ModalService} from "../../../services/modal.service"; export class InputsTableComponent { @Input() inputs: Array<InputFEModel>; - @Input() instanceNamesMap: Map<string, string>; + @Input() instanceNamesMap: Map<string, InstanceFeDetails>; @Input() readonly:boolean; @Input() isLoading:boolean; @Output() inputChanged: EventEmitter<any> = new EventEmitter<any>(); diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html index 4805875d83..b5ae7a8f66 100644 --- a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html +++ b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html @@ -19,6 +19,7 @@ [name]="property.name" (elementChanged)="mapKeyChanged.emit($event.value)" [readonly]="readonly" + [testId]="'prop-key-' + propertyTestsId" ></dynamic-element> </div> </ng-container> @@ -27,12 +28,13 @@ <div class="table-cell"> <dynamic-element class="value-input" pattern="validationUtils.getValidationPattern(property.type)" - [value]="property.valueObj" + [value]="property.isDeclared ? property.value : property.valueObj" [type]="property.isDeclared ? 'string' : property.type" [name]="property.name" [path]="property.propertiesName" (elementChanged)="onElementChanged($event)" [readonly]="readonly || property.isDeclared || property.isDisabled" + [testId]="'prop-' + propertyTestsId" ></dynamic-element> </div> </ng-container> @@ -45,9 +47,9 @@ </ng-container> <!-- ICONS: add, delete, and expand --> <ng-container *ngIf="!property.isDeclared"> - <a *ngIf="(propType == derivedPropertyTypes.LIST || propType == derivedPropertyTypes.MAP) && !property.isChildOfListOrMap" class="property-icon add-item" (click)="createNewChildProperty();" [ngClass]="{'disabled':readonly || preventInsertItem(property)}">Add value to list</a> - <span *ngIf="property.isChildOfListOrMap" (click)="deleteItem.emit(property);" class="property-icon sprite-new delete-item-icon" [ngClass]="{'disabled':readonly}"></span> - <span *ngIf="!isPropertyFEModel && (propType == derivedPropertyTypes.COMPLEX || ((propType == derivedPropertyTypes.LIST || propType == derivedPropertyTypes.MAP) && hasChildren))" (click)="expandChildById(propPath)" class="property-icon sprite-new round-expand-icon" [class.open]="expandedChildId.indexOf(propPath) == 0"></span> + <a *ngIf="(propType == derivedPropertyTypes.LIST || propType == derivedPropertyTypes.MAP) && !property.isChildOfListOrMap" class="property-icon add-item" (click)="createNewChildProperty();" [ngClass]="{'disabled':readonly || preventInsertItem(property)}" [attr.data-tests-id]="'add-to-list-' + propertyTestsId">Add value to list</a> + <span *ngIf="property.isChildOfListOrMap" (click)="deleteItem.emit(property);" class="property-icon sprite-new delete-item-icon" [ngClass]="{'disabled':readonly}" [attr.data-tests-id]="'delete-from-list-' + propertyTestsId"></span> + <span *ngIf="!isPropertyFEModel && (propType == derivedPropertyTypes.COMPLEX || ((propType == derivedPropertyTypes.LIST || propType == derivedPropertyTypes.MAP) && hasChildren))" (click)="expandChildById(propPath)" class="property-icon sprite-new round-expand-icon" [class.open]="expandedChildId.indexOf(propPath) == 0" [attr.data-tests-id]="'expand-' + propertyTestsId"></span> </ng-container> </div> @@ -59,6 +61,7 @@ [hasDeclareOption]="hasDeclareOption" [canBeDeclared]="hasDeclareOption && prop.canBeDeclared" [property]="prop" + [rootProperty]="rootProperty || property" [expandedChildId]="expandedChildId" [propertyNameSearchText]="propertyNameSearchText" [readonly]="readonly" diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts index 6f7e57b643..6e19c95003 100644 --- a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts @@ -41,6 +41,7 @@ export class DynamicPropertyComponent { propPath: string; isPropertyFEModel: boolean; nestedLevel: number; + propertyTestsId: string; @Input() canBeDeclared: boolean; @Input() property: PropertyFEModel | DerivedFEProperty; @@ -50,6 +51,7 @@ export class DynamicPropertyComponent { @Input() readonly: boolean; @Input() hasChildren: boolean; @Input() hasDeclareOption:boolean; + @Input() rootProperty: PropertyFEModel; @Output('propertyChanged') emitter: EventEmitter<void> = new EventEmitter<void>(); @Output() expandChild: EventEmitter<string> = new EventEmitter<string>(); @@ -69,6 +71,8 @@ export class DynamicPropertyComponent { this.propType = this.property.derivedDataType; this.propPath = (this.property instanceof PropertyFEModel) ? this.property.name : this.property.propertiesName; this.nestedLevel = (this.property.propertiesName.match(/#/g) || []).length; + this.rootProperty = (this.rootProperty) ? this.rootProperty : <PropertyFEModel>this.property; + this.propertyTestsId = this.getPropertyTestsId(); } ngDoCheck() { @@ -105,6 +109,10 @@ export class DynamicPropertyComponent { }).length > 1; } + getPropertyTestsId = () => { + return [this.rootProperty.name].concat(this.rootProperty.getParentNamesArray(this.property.propertiesName, [], true)).join('.'); + }; + onElementChanged = (event: IUiElementChangeEvent) => { this.property.updateValueObj(event.value, event.isValid); this.emitter.emit(); diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html index ecfa7e7c5e..b574b552ae 100644 --- a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html +++ b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html @@ -9,8 +9,14 @@ <div class="table-body" [ngClass]="{'view-mode': readonly}"> <div class="no-data" *ngIf="!fePropertiesMap || !(fePropertiesMap | keys).length">No data to display</div> - <ng-container *ngFor="let instanceId of fePropertiesMap | keys; trackBy:instanceId"> - <div class="table-rows-header white-sub-header" *ngIf="feInstanceNamesMap">{{feInstanceNamesMap[instanceId]}}</div> + <ng-container *ngFor="let instanceId of fePropertiesMap | keys; trackBy:vspId"> + <div class="table-rows-header white-sub-header" *ngIf="feInstanceNamesMap"> + + + <span [ngClass]="['prop-instance-icon', feInstanceNamesMap[instanceId].iconClass, 'small']"></span> + {{feInstanceNamesMap[instanceId].name}} + <div class="sprite-new archive-label" *ngIf="feInstanceNamesMap[instanceId].originArchived == true" ></div> + </div> <div class="table-row" *ngFor="let property of fePropertiesMap[instanceId] | searchFilter:'name':searchTerm; trackBy:property?.name" @@ -22,8 +28,8 @@ <checkbox *ngIf="hasDeclareOption" [(checked)]="property.isSelected" [disabled]="property.isDisabled || property.isDeclared || readonly" (checkedChange)="propertyChecked(property)" [attr.data-tests-id]="property.name"></checkbox> - <div class="inner-cell-div" tooltip="{{property.name}}"> - <span>{{property.name}}</span> + <div class="inner-cell-div-multiline" tooltip="{{property.name}}"> + <multiline-ellipsis className="table-cell-multiline-ellipsis" [lines]="2">{{property.name}}</multiline-ellipsis> </div> </div> <span *ngIf="property.description" class="property-description-icon sprite-new show-desc" tooltip="{{property.description}}" tooltipDelay="0"></span> diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.less b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.less index 20da0b6ec2..72f67e434e 100644 --- a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.less +++ b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.less @@ -1,4 +1,4 @@ -@import './../../../../../assets/styles/variables.less'; +@import './../../../../../assets/styles/mixins.less'; @import '../../../../../assets/styles/sprite'; @smaller-screen: ~"only screen and (max-width: 1580px)"; @@ -12,13 +12,16 @@ text-align:left; - .inner-cell-div{ - max-width: 100%; + .inner-cell-div { text-overflow: ellipsis; overflow: hidden; height: 20px; } + .inner-cell-div-multiline { + max-width: 100%; + } + .table-header { display: flex; flex-direction:row; @@ -36,6 +39,11 @@ .table-rows-header { border: #d2d2d2 solid 1px; border-top:none; + display: flex; + align-items: center; + .archive-label{ + margin-left: 10px; + } } .table-body { @@ -120,7 +128,7 @@ .property-description-icon { float: right; margin-top: 4px; - margin-left: 5px; + margin-left: 15px; flex: 0 0 auto; } } @@ -177,4 +185,53 @@ } } + .table-row { + /deep/ .table-cell-multiline-ellipsis .multiline-ellipsis-dots { + background: linear-gradient(to right, transparent 0%, #ffffff 80%); + padding-left: 1em; + } + + &.selected /deep/ .table-cell-multiline-ellipsis .multiline-ellipsis-dots { + background: linear-gradient(to right, transparent 0%, #e6f6fb 80%); + padding-left: 1em; + } + + &.readonly /deep/ .table-cell-multiline-ellipsis .multiline-ellipsis-dots { + background: linear-gradient(to right, transparent 0%, #f8f8f8 80%); + padding-left: 1em; + } + + &:hover:not(.selected) /deep/ .table-cell-multiline-ellipsis .multiline-ellipsis-dots { + background: linear-gradient(to right, transparent 0%, #f8f8f8 80%); + padding-left: 1em; + } + } + + .prop-instance-icon { + vertical-align: middle; + margin-right: 7px; + &.defaulticon.small { + background-color: @main_color_q; + border-radius:14px; + } + // square icons + + &.icon-group { + .square-icon(); + background-color: @main_color_a; + + &::before { + content: "G"; + } + } + &.icon-policy { + .square-icon(); + background-color: @main_color_r; + + &::before { + content: "P"; + } + } + + } } diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts index 093fae1684..da1fb82ba0 100644 --- a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts @@ -21,6 +21,7 @@ import { Component, Input, Output, EventEmitter} from "@angular/core"; import {PropertyFEModel, DerivedFEProperty, InstanceFePropertiesMap} from "app/models"; import {PropertiesService} from "../../../services/properties.service"; +import { InstanceFeDetails } from "../../../../models/instance-fe-details"; @Component({ selector: 'properties-table', @@ -30,7 +31,7 @@ import {PropertiesService} from "../../../services/properties.service"; export class PropertiesTableComponent { @Input() fePropertiesMap: InstanceFePropertiesMap; - @Input() feInstanceNamesMap: Map<string, string>; + @Input() feInstanceNamesMap: Map<string, InstanceFeDetails>; @Input() selectedPropertyId: string; @Input() propertyNameSearchText:string; @Input() searchTerm:string; diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/property-table.module.ts b/catalog-ui/src/app/ng2/components/logic/properties-table/property-table.module.ts index 91f33485a9..91baaf1bc1 100644 --- a/catalog-ui/src/app/ng2/components/logic/properties-table/property-table.module.ts +++ b/catalog-ui/src/app/ng2/components/logic/properties-table/property-table.module.ts @@ -8,6 +8,7 @@ import {HttpModule} from "@angular/http"; import {FilterChildPropertiesPipe} from "./pipes/filterChildProperties.pipe"; import {GlobalPipesModule} from "../../../pipes/global-pipes.module"; import {PropertiesService} from "../../../services/properties.service"; +import {MultilineEllipsisModule} from "../../../shared/multiline-ellipsis/multiline-ellipsis.module"; @NgModule({ imports: [ @@ -15,7 +16,8 @@ import {PropertiesService} from "../../../services/properties.service"; HttpModule, CommonModule, GlobalPipesModule, - UiElementsModule + UiElementsModule, + MultilineEllipsisModule ], declarations: [ FilterChildPropertiesPipe, diff --git a/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.component.html b/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.component.html index 6e0f93f750..9d570f036a 100644 --- a/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.component.html +++ b/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.component.html @@ -9,7 +9,7 @@ </radio-buttons> <label class="select-type-label">Select type:</label> <div class="select-type"> - <ui-element-dropdown [values]="types" [(value)]="selectedType" (valueChange)="onTypeSelected($event)"></ui-element-dropdown> + <ui-element-dropdown [values]="types" [(value)]="selectedType" (valueChange)="onTypeSelected($event)" testId="select"></ui-element-dropdown> </div> <div class="table-and-list-container"> diff --git a/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.html b/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.html index 72e083534c..af7a470495 100644 --- a/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.html +++ b/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.html @@ -1,5 +1,5 @@ <div class="service-path-selector"> - <label>Service Paths:</label> + <label>Service Flows:</label> <ui-element-dropdown class="path-dropdown" data-tests-id="service-path-selector" diff --git a/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.ts b/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.ts index be9966acef..e09001fc6c 100644 --- a/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.ts @@ -1,4 +1,3 @@ -import * as _ from "lodash"; import {Component, Input, KeyValueDiffer, IterableDiffers, KeyValueDiffers, DoCheck} from '@angular/core'; import {Service} from "app/models/components/service"; import {TranslateService} from "app/ng2/shared/translator/translate.service"; diff --git a/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.html b/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.html index ff7902e2b9..75f064230c 100644 --- a/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.html +++ b/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.html @@ -1,22 +1,15 @@ <div class='service-path'> <button class='zoom-icons create-path-button' data-tests-id="pathsMenuBtn" (click)="showServicePathMenu = !showServicePathMenu">...</button> - <div class="service-path-menu" - *ngIf="showServicePathMenu" > + <div class="service-path-menu" *ngIf="showServicePathMenu"> <div > <ul> - <li><div class="hand" (click)="onCreateServicePath()" data-tests-id="createPathMenuItem"> - Create Service Path + <li *ngIf='!isViewOnly'><div class="hand" (click)="onCreateServicePath()" data-tests-id="createPathMenuItem"> + Create Service Flow </div></li> <li><div class="hand" (click)="onListServicePath()" data-tests-id="pathsListMenuItem"> - Service Paths List + Service Flows List </div></li> </ul> </div> </div> - <!-- TODO - ask Orit about positioning issues and styling issues --> - <!-- - <menu-list [open]="showServicePathMenu" [position]="menuPos" > - <menu-item [action]="onCreateServicePath">Create Path</menu-item> - <menu-item [action]="onListServicePath">Paths' List</menu-item> - </menu-list> --> </div>
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.ts b/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.ts index 4a6209fb6f..d66c5f0132 100644 --- a/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.ts @@ -39,6 +39,7 @@ export class ServicePathComponent { @Input() service: Service; @Input() onCreate: Function; @Input() onSave: Function; + @Input() isViewOnly:boolean; constructor(private ModalServiceNg2: ModalService) {} @@ -46,7 +47,7 @@ export class ServicePathComponent { this.showServicePathMenu = false; let cancelButton: ButtonModel = new ButtonModel('Cancel', 'outline white', this.ModalServiceNg2.closeCurrentModal); let saveButton: ButtonModel = new ButtonModel('Create', 'blue', this.createPath, this.getDisabled ); - let modalModel: ModalModel = new ModalModel('l', 'Create Service Path', '', [saveButton, cancelButton], 'standard', true); + let modalModel: ModalModel = new ModalModel('l', 'Create Service Flow', '', [saveButton, cancelButton], 'standard', true); this.modalInstance = this.ModalServiceNg2.createCustomModal(modalModel); this.ModalServiceNg2.addDynamicContentToModal(this.modalInstance, ServicePathCreatorComponent, {service: this.service}); this.modalInstance.instance.open(); @@ -55,10 +56,10 @@ export class ServicePathComponent { onListServicePath = ():void => { this.showServicePathMenu = false; let cancelButton: ButtonModel = new ButtonModel('Close', 'outline white', this.ModalServiceNg2.closeCurrentModal); - let modalModel: ModalModel = new ModalModel('md', 'Service Paths List','', [cancelButton], 'standard', true); + let modalModel: ModalModel = new ModalModel('md', 'Service Flows List','', [cancelButton], 'standard', true); this.modalInstance = this.ModalServiceNg2.createCustomModal(modalModel); this.ModalServiceNg2.addDynamicContentToModal(this.modalInstance, ServicePathsListComponent, {service: this.service, - onCreateServicePath: this.onCreateServicePath, onEditServicePath: this.onEditServicePath}); + onCreateServicePath: this.onCreateServicePath, onEditServicePath: this.onEditServicePath, isViewOnly: this.isViewOnly}); this.modalInstance.instance.open(); }; @@ -70,14 +71,14 @@ export class ServicePathComponent { onEditServicePath = (id:string):void => { let cancelButton: ButtonModel = new ButtonModel('Cancel', 'outline white', this.ModalServiceNg2.closeCurrentModal); let saveButton: ButtonModel = new ButtonModel('Save', 'blue', this.createPath, this.getDisabled ); - let modalModel: ModalModel = new ModalModel('l', 'Edit Path', '', [saveButton, cancelButton]); + let modalModel: ModalModel = new ModalModel('l', 'Edit Path', '', [saveButton, cancelButton], 'standard', true); this.modalInstance = this.ModalServiceNg2.createCustomModal(modalModel); this.ModalServiceNg2.addDynamicContentToModal(this.modalInstance, ServicePathCreatorComponent, {service: this.service, pathId: id}); this.modalInstance.instance.open(); }; getDisabled = ():boolean => { - return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit(); + return this.isViewOnly || !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit(); }; } diff --git a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.html b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.html index e279e3f704..981efbb58e 100644 --- a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.html +++ b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.html @@ -1,11 +1,11 @@ -<div class="sdc-canvas-zone {{class}}-zone" [class.minimized]="minifyZone" [class.hidden]="!showZone"> - <div class="sdc-canvas-zone__header" (click)="unminifyZone()" > +<div class="sdc-canvas-zone {{class}}-zone" [class.minimized]="minimized" [class.hidden]="!visible" (click)="backgroundClicked()"> + <div class="sdc-canvas-zone__header" (click)="unminifyZone(); $event.stopPropagation();" > <div class="sdc-canvas-zone__title">{{title}} <span class="sdc-canvas-zone__counter">{{count}}</span> </div> <span class="sdc-canvas-zone__state-button">–</span> </div> - <div class="sdc-canvas-zone__container"> + <div class="sdc-canvas-zone__container" #scrollDiv > <ng-content></ng-content> </div> </div>
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.less b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.less index 3e77c5ca3b..02880a9202 100644 --- a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.less +++ b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.less @@ -1,5 +1,5 @@ .sdc-canvas-zone { - width: 280px; + width: 285px; max-height:186px; display:flex; flex-direction:column; diff --git a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.ts b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.ts index 7e60cb37a6..4059ad6cae 100644 --- a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.ts +++ b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.ts @@ -1,6 +1,5 @@ -import { Component, Input, Output, ViewEncapsulation, EventEmitter } from '@angular/core'; -import { EventListenerService } from 'app/services'; -import { GRAPH_EVENTS } from 'app/utils'; +import { Component, Input, Output, ViewEncapsulation, EventEmitter, OnInit } from '@angular/core'; +import { ZoneInstanceType } from '../../../../models/graph/zones/zone-instance'; @Component({ selector: 'zone-container', @@ -9,17 +8,28 @@ import { GRAPH_EVENTS } from 'app/utils'; encapsulation: ViewEncapsulation.None }) -export class ZoneContainerComponent { +export class ZoneContainerComponent implements OnInit { @Input() title:string; - @Input() class:string; - @Input() count:number; - @Input() showZone:boolean; - @Input() minifyZone:boolean; - constructor(private eventListenerService:EventListenerService) {} + @Input() type:ZoneInstanceType; + @Input() count:number; + @Input() visible:boolean; + @Input() minimized:boolean; + @Output() minimize: EventEmitter<any> = new EventEmitter<any>(); + @Output() backgroundClick: EventEmitter<void> = new EventEmitter<void>(); + private class:string; + + constructor() {} + + ngOnInit() { + this.class = ZoneInstanceType[this.type].toLowerCase(); + } private unminifyZone = () => { - this.minifyZone = !this.minifyZone; - this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_ZONE_SIZE_CHANGE); + this.minimize.emit(); + } + + private backgroundClicked = () => { + this.backgroundClick.emit(); } }
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.html b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.html index d36b7aec6f..031b081323 100644 --- a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.html +++ b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.html @@ -1,8 +1,10 @@ -<div class="zone-child mode-{{config.mode}}" [class.locked]="activeInstanceMode > MODE.HOVER" - (mouseenter)="setMode(MODE.HOVER)" (mouseleave)="setMode(MODE.NONE)" (click)="setMode(MODE.SELECTED)"> - <div class="zone-child__handle" (click)="setMode(MODE.TAG, $event)">+</div> - <div class="zone-child__body"> - <div class="zone-child__body-content">{{config.count || defaultIconText}}</div> +<div tooltip="{{zoneInstance.instanceData.name}}" #currentComponent + class="zone-instance mode-{{zoneInstance.mode}}" [class.locked]="activeInstanceMode > MODE.HOVER" [class.hiding]="hidden" + (mouseenter)="setMode(MODE.HOVER)" (mouseleave)="setMode(MODE.NONE)" (click)="setMode(MODE.SELECTED, $event)"> + <div *ngIf="zoneInstance.handle" class="target-handle {{zoneInstance.handle}}" (click)="tagHandleClicked($event)"></div> + <div *ngIf="!isViewOnly" class="zone-instance__handle" (click)="setMode(MODE.TAG, $event)">+</div> + <div class="zone-instance__body"> + <div class="zone-instance__body-content">{{zoneInstance.assignments.length || defaultIconText}}</div> </div> - <div class="zone-child__name">{{config.name}}</div> + <div class="zone-instance__name">{{zoneInstance.instanceData.name}}</div> </div>
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.less b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.less index a1d56df96e..b562c08514 100644 --- a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.less +++ b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.less @@ -1,9 +1,12 @@ -.zone-child { +@import '../../../../../../assets/styles/variables'; + +.zone-instance { position:relative; width:76px; margin:5px; + opacity:1; - .zone-child__handle { + .zone-instance__handle { display:none; position:absolute; right:4px; @@ -11,33 +14,34 @@ width:22px; height:22px; cursor:pointer; - border: solid white 1px; + border: solid @main_color_p 1px; border-radius: 2px; text-align: center; font-weight:bold; } - .zone-child__body { + .zone-instance__body { margin:0 auto; width:43px; height:43px; display:flex; padding:3px; - } - .zone-child__body-content { + .zone-instance__body-content { border-radius: 2px; flex:1; - color:white; - font-size:18px; + color:@main_color_p; + font-size:16px; text-align:center; display:flex; align-items: center; justify-content: center; + box-shadow:none; + transition:box-shadow 5s; } - .zone-child__name { + .zone-instance__name { text-overflow: ellipsis; overflow: hidden; white-space: nowrap; @@ -45,66 +49,86 @@ } /* Dynamic classes below */ + .target-handle { + position:absolute; + width:18px; + height:18px; + display:block; + top: -4px; + right: 10px; + background-size: 100% 100%; + cursor: url("../../../../../../assets/styles/images/canvas-tagging-icons/policy_2.svg"), pointer; + + &.tagged-policy { + background-image: url('../../../../../../assets/styles/images/canvas-tagging-icons/policy_added.svg'); + } + + &.tag-available { + background-image: url('../../../../../../assets/styles/images/canvas-tagging-icons/indication.svg'); + } + } + + &.mode-1, &.mode-2, &.mode-3 { //hover, selected, tag - .zone-child__body { + .zone-instance__body { border:solid 2px; border-radius: 2px; padding:2px; cursor:pointer; } - .zone-child__handle{ + } + + &.mode-1, &.mode-2:hover{ + .zone-instance__handle{ display:block; - cursor:pointer; } } &.locked { - cursor: default; + cursor: inherit; } - - // &:not(.locked):hover .zone-child__handle{ - // display:block; - // } - .zone-child__body { - cursor: default; + + &.hiding { + opacity:0; + .zone-instance__body-content { + box-shadow: #CCC 0px 0px 15px; + } } - &.mode-3 .zone-child__handle { + + + &.mode-3 .zone-instance__handle { width:24px; height:24px; right:3px; top:9px; display:block; background-image: linear-gradient(-140deg, #009E98 0%, #97D648 100%); - border: 2px solid #FFFFFF; + border: 2px solid @main_color_p; border-radius: 2px; box-shadow: inset 2px -2px 3px 0 #007A3E; - cursor: pointer; } } .sdc-canvas-zone.group-zone { - .zone-child__handle { - background-color:#009FDB; - } - .zone-child__body { - border-color:#009FDB; + .zone-instance__handle { + background-color:@main_color_a; } - .zone-child__body-content { - background: #009FDB; + .zone-instance__body { + border-color:@main_color_a; + .zone-instance__body-content { + background: @main_color_a; + } } } .sdc-canvas-zone.policy-zone { - .zone-child__handle { - background-color:#0568AE; + .zone-instance__handle { + background-color:@main_color_r; } - .zone-child__body { - border-color:#1287D9; - .zone-child__body-content { - background: #1287D9; + .zone-instance__body { + border-color:@main_color_r; + .zone-instance__body-content { + background: @main_color_r; } } - .zone-child__body-content { - background: #0568AE; - } }
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.ts b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.ts index 8057ae908a..3c2dd45db5 100644 --- a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.ts +++ b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.ts @@ -1,5 +1,14 @@ -import { Component, Input, Output, EventEmitter, ViewEncapsulation } from '@angular/core'; -import { ZoneInstanceConfig, ZoneInstanceMode } from 'app/models/graph/zones/zone-child'; +import { Component, Input, Output, EventEmitter, ViewEncapsulation, OnInit, SimpleChange, ElementRef, ViewChild, SimpleChanges } from '@angular/core'; +import { + ZoneInstance, ZoneInstanceMode, ZoneInstanceType, + IZoneInstanceAssignment +} from 'app/models/graph/zones/zone-instance'; +import { PoliciesService } from '../../../../services/policies.service'; +import { GroupsService } from '../../../../services/groups.service'; +import { IZoneService } from "../../../../../models/graph/zones/zone"; +import { EventListenerService } from 'app/services'; +import { GRAPH_EVENTS } from '../../../../../utils'; +import { Subject, Observable } from 'rxjs'; @Component({ selector: 'zone-instance', @@ -7,22 +16,95 @@ import { ZoneInstanceConfig, ZoneInstanceMode } from 'app/models/graph/zones/zon styleUrls: ['./zone-instance.component.less'], encapsulation: ViewEncapsulation.None }) -export class ZoneInstanceComponent { +export class ZoneInstanceComponent implements OnInit { - @Input() config:ZoneInstanceConfig; + @Input() zoneInstance:ZoneInstance; @Input() defaultIconText:string; @Input() isActive:boolean; + @Input() isViewOnly:boolean; @Input() activeInstanceMode: ZoneInstanceMode; + @Input() hidden:boolean; + @Input() forceSave:Subject<Function>; @Output() modeChange: EventEmitter<any> = new EventEmitter<any>(); + @Output() assignmentSaveStart: EventEmitter<void> = new EventEmitter<void>(); + @Output() assignmentSaveComplete: EventEmitter<boolean> = new EventEmitter<boolean>(); + @Output() tagHandleClick: EventEmitter<ZoneInstance> = new EventEmitter<ZoneInstance>(); + @ViewChild('currentComponent') currentComponent: ElementRef; private MODE = ZoneInstanceMode; + private zoneService:IZoneService; - private setMode = (mode:ZoneInstanceMode, event?:any):void => { - if(!this.isActive || this.isActive && mode == ZoneInstanceMode.TAG){ //when active, do not allow hover/select mode toggling - this.modeChange.emit({newMode: mode, instance: this.config}); + constructor(private policiesService:PoliciesService, private groupsService:GroupsService, private eventListenerService:EventListenerService){} + + ngOnInit(){ + if(this.zoneInstance.type == ZoneInstanceType.POLICY){ + this.zoneService = this.policiesService; + } else { + this.zoneService = this.groupsService; } - if(event){ - event.stopPropagation(); + this.forceSave.subscribe((afterSaveFunction:Function) => { + this.setMode(ZoneInstanceMode.TAG, null, afterSaveFunction); + }) + } + + ngOnChanges(changes:SimpleChanges) { + if(changes.hidden){ + this.currentComponent.nativeElement.scrollIntoView({behavior: "smooth", block: "nearest", inline:"end"}); } } + ngOnDestroy() { + this.forceSave.unsubscribe(); + } + + private setMode = (mode:ZoneInstanceMode, event?:any, afterSaveCallback?:Function):void => { + + if(event){ //prevent event from handle and then repeat event from zone instance + event.stopPropagation(); + } + + if(!this.isActive && this.activeInstanceMode === ZoneInstanceMode.TAG) { + return; //someone else is tagging. No events allowed + } + + if(this.isActive && this.zoneInstance.mode === ZoneInstanceMode.TAG){ + if(mode !== ZoneInstanceMode.TAG) { + return; //ignore all other events. The only valid option is saving changes. + } + + let oldAssignments:Array<IZoneInstanceAssignment> = this.zoneInstance.instanceData.getSavedAssignments(); + if(this.zoneInstance.isZoneAssignmentChanged(oldAssignments, this.zoneInstance.assignments)) { + + this.assignmentSaveStart.emit(); + + this.zoneService.updateZoneInstanceAssignments(this.zoneInstance.parentComponentType, this.zoneInstance.parentComponentID, this.zoneInstance.instanceData.uniqueId, this.zoneInstance.assignments).subscribe( + (success) => { + this.zoneInstance.instanceData.setSavedAssignments(this.zoneInstance.assignments); + if(this.zoneInstance.type === ZoneInstanceType.POLICY){ + this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_POLICY_INSTANCE_UPDATE, this.zoneInstance.instanceData); + } else { + this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_GROUP_INSTANCE_UPDATE, this.zoneInstance.instanceData); + } + this.assignmentSaveComplete.emit(true); + if(afterSaveCallback) afterSaveCallback(); + }, (error) => { + this.zoneInstance.assignments = oldAssignments; + this.assignmentSaveComplete.emit(false); + }); + } else { + if(afterSaveCallback) afterSaveCallback(); + } + this.modeChange.emit({newMode: ZoneInstanceMode.NONE, instance: this.zoneInstance}); + + } else { + this.modeChange.emit({newMode: mode, instance: this.zoneInstance}); + } + + + } + + private tagHandleClicked = (event:Event) => { + this.tagHandleClick.emit(this.zoneInstance); + event.stopPropagation(); + }; + }
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts b/catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts index d1e68f3088..c15f92ccb8 100644 --- a/catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts +++ b/catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts @@ -53,6 +53,7 @@ export class DynamicElementComponent { @ViewChild('target', { read: ViewContainerRef }) target: any; @Input() type: any; @Input() name: string; + @Input() testId: string; @Input() readonly:boolean; @Input() path:string;//optional param. used only for for subnetpoolid type @@ -111,6 +112,7 @@ export class DynamicElementComponent { if (this.cmpRef) { this.cmpRef.instance.name = this.name; this.cmpRef.instance.type = this.type; + this.cmpRef.instance.testId = this.testId; this.cmpRef.instance.value = this.value; this.cmpRef.instance.readonly = this.readonly; } @@ -133,7 +135,7 @@ export class DynamicElementComponent { case DynamicElementComponentCreatorIdentifier.FLOAT: this.createComponent(UiElementIntegerInputComponent); - this.cmpRef.instance.pattern = /^[-+]?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?$/; + this.cmpRef.instance.pattern = /^[-+]?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?$/.source; break; case DynamicElementComponentCreatorIdentifier.STRING: @@ -156,10 +158,10 @@ export class DynamicElementComponent { case DynamicElementComponentCreatorIdentifier.DEFAULT: default: this.createComponent(UiElementInputComponent); - console.log("ERROR: No ui component to handle type: " + this.type); + console.log("ERROR: No ui-models component to handle type: " + this.type); } - // Subscribe to change event of of ui-element-basic and fire event to change the value + // Subscribe to change event of of ui-models-element-basic and fire event to change the value this.cmpRef.instance.baseEmitter.subscribe((event) => { this.emitter.emit(event); }); this.cmpRef.instance.valueChange.subscribe((event) => { this.valueChange.emit(event); }); } diff --git a/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.html b/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.html new file mode 100644 index 0000000000..83daca2ae5 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.html @@ -0,0 +1,13 @@ +<h1 class="w-sdc-designer-sidebar-section-title" + tooltip="{{titleTooltip}}" + [ngClass]="{'expanded': state == 0, 'collapsed': state == 1}" + (click)="toggleState()"> + {{caption}}<span class="w-sdc-designer-sidebar-section-title-icon"></span> + <ng-content select="header"></ng-content> + <span class="w-sdc-designer-sidebar-section-title-icon"></span> +</h1> + +<div class="expand-collapse-content" [ngClass]="{'visible': state === 0, 'hidden': state === 1}"> + <ng-content></ng-content> + <ng-content select="content"></ng-content> +</div> diff --git a/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.less b/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.less new file mode 100644 index 0000000000..e5dd2527c1 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.less @@ -0,0 +1,7 @@ +.ellipsis-directive-more-less { + float: right; + margin-right: 10px; + line-height: 23px; + text-decoration: underline; + text-align: left; +} diff --git a/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.ts b/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.ts new file mode 100644 index 0000000000..0fa0d33de9 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.ts @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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. + * ============LICENSE_END========================================================= + */ + +import { Component, Input, Output, ViewEncapsulation, AfterViewInit } from '@angular/core'; + +export enum ExpandState { + EXPANDED, + COLLAPSED +} + +@Component({ + selector: 'ng2-expand-collapse', + templateUrl: './expand-collapse.component.html', + styleUrls: ['./expand-collapse.component.less'], + encapsulation: ViewEncapsulation.None +}) + +export class ExpandCollapseComponent implements AfterViewInit { + @Input() caption: String; + @Input() state: ExpandState; + @Input() titleTooltip: String; + + constructor() { + + } + + toggleState():void { + if (this.state == ExpandState.EXPANDED) { + this.state = ExpandState.COLLAPSED; + } else { + this.state = ExpandState.EXPANDED; + } + } + + ngAfterViewInit(): void { + + } + +} diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component.html b/catalog-ui/src/app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component.html index 805e5ac295..c564abc092 100644 --- a/catalog-ui/src/app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component.html +++ b/catalog-ui/src/app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component.html @@ -1,3 +1,3 @@ -<select name='{{name}}' [(ngModel)]="value" (change)="onChange()" [ngClass]="{'disabled':readonly}" data-tests-id="SelectType"> +<select name='{{name}}' [(ngModel)]="value" (change)="onChange()" [ngClass]="{'disabled':readonly}" [attr.data-tests-id]="'value-' + testId"> <option *ngFor="let ddvalue of values" [ngValue]="ddvalue.label != undefined ? ddvalue.value : ddvalue">{{ddvalue.label||ddvalue}}</option> </select> diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/input/ui-element-input.component.html b/catalog-ui/src/app/ng2/components/ui/form-components/input/ui-element-input.component.html index 057e731ada..fdba850e93 100644 --- a/catalog-ui/src/app/ng2/components/ui/form-components/input/ui-element-input.component.html +++ b/catalog-ui/src/app/ng2/components/ui/form-components/input/ui-element-input.component.html @@ -11,4 +11,5 @@ [formControl]="control" tooltip="{{value}}" [readonly]="readonly" + [attr.data-tests-id]="'value-' + testId" /> diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/integer-input/ui-element-integer-input.component.html b/catalog-ui/src/app/ng2/components/ui/form-components/integer-input/ui-element-integer-input.component.html index e1555e87fd..04307e4c2d 100644 --- a/catalog-ui/src/app/ng2/components/ui/form-components/integer-input/ui-element-integer-input.component.html +++ b/catalog-ui/src/app/ng2/components/ui/form-components/integer-input/ui-element-integer-input.component.html @@ -11,4 +11,5 @@ [formControl]="control" tooltip="{{value}}" [readonly]="readonly" + [attr.data-tests-id]="'value-' + testId" /> diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/popover-input/ui-element-popover-input.component.html b/catalog-ui/src/app/ng2/components/ui/form-components/popover-input/ui-element-popover-input.component.html index 3bd51b4e36..3bc94de1e4 100644 --- a/catalog-ui/src/app/ng2/components/ui/form-components/popover-input/ui-element-popover-input.component.html +++ b/catalog-ui/src/app/ng2/components/ui/form-components/popover-input/ui-element-popover-input.component.html @@ -7,7 +7,7 @@ [value]="value!=undefined?value:''" disabled /> - <button [popover]="popoverForm" [ngClass]="{'disabled':readonly}">Edit</button> + <button [popover]="popoverForm" (onShown)="setEditValue()" [ngClass]="{'disabled':readonly}" [attr.data-tests-id] ="'edit-button-' + testId">Edit</button> </div> <popover-content #popoverForm [title]="name" [buttons]="buttonsArray" [placement]="'top'" [closeOnClickOutside]="true"> @@ -16,11 +16,12 @@ #textArea class="subnet-value" [ngClass]="{'error': control.invalid}" - [(ngModel)]="value" + [(ngModel)]="editValue" [attr.maxlength]="validation.propertyValue.max" [attr.minlength]="validation.propertyValue.min" [pattern]="pattern" [formControl]="control" + [attr.data-tests-id]="'value-' + testId" ></textarea> </div> </popover-content> diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/popover-input/ui-element-popover-input.component.ts b/catalog-ui/src/app/ng2/components/ui/form-components/popover-input/ui-element-popover-input.component.ts index 525cd1742c..f485d270fa 100644 --- a/catalog-ui/src/app/ng2/components/ui/form-components/popover-input/ui-element-popover-input.component.ts +++ b/catalog-ui/src/app/ng2/components/ui/form-components/popover-input/ui-element-popover-input.component.ts @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -import {Component, ViewChild, ElementRef, Input} from '@angular/core'; +import {Component, ViewChild, ElementRef} from '@angular/core'; import {ButtonsModelMap, ButtonModel} from "app/models"; import {PopoverContentComponent} from "../../popover/popover-content.component"; import {UiElementBase, UiElementBaseInterface} from "../ui-element-base.component"; @@ -32,13 +32,14 @@ export class UiElementPopoverInputComponent extends UiElementBase implements UiE @ViewChild('textArea') textArea: ElementRef; @ViewChild('popoverForm') popoverContentComponent: PopoverContentComponent; + editValue: any; saveButton: ButtonModel; buttonsArray: ButtonsModelMap; constructor() { super(); // Create Save button and insert to buttons map - this.saveButton = new ButtonModel('save', 'blue', this.onChange); + this.saveButton = new ButtonModel('Set', 'blue', this.onChange.bind(this)); this.buttonsArray = { 'test': this.saveButton }; // Define the regex pattern for this controller @@ -47,4 +48,15 @@ export class UiElementPopoverInputComponent extends UiElementBase implements UiE // Disable / Enable button according to validation //this.control.valueChanges.subscribe(data => this.saveButton.disabled = this.control.invalid); } + + public setEditValue() { + // copy value to edit + this.editValue = angular.copy(this.value); + } + + public onChange() { + this.popoverContentComponent.hide(); + this.value = this.editValue; + super.onChange(); + } } diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/ui-element-base.component.ts b/catalog-ui/src/app/ng2/components/ui/form-components/ui-element-base.component.ts index b4e9e7d36a..31fa7c3442 100644 --- a/catalog-ui/src/app/ng2/components/ui/form-components/ui-element-base.component.ts +++ b/catalog-ui/src/app/ng2/components/ui/form-components/ui-element-base.component.ts @@ -46,9 +46,12 @@ export class UiElementBase { @Input() name: string; @Input() type: string; + @Input() path: string; @Input() pattern: any; @Input() readonly:boolean; + @Input() testId:string; + constructor() { //this.control = new FormControl('', [Validators.required]); this.control = new FormControl('', []); diff --git a/catalog-ui/src/app/ng2/components/ui/forms/modal-forms.module.ts b/catalog-ui/src/app/ng2/components/ui/forms/modal-forms.module.ts new file mode 100644 index 0000000000..34404e50a5 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/forms/modal-forms.module.ts @@ -0,0 +1,27 @@ +import { NgModule } from "@angular/core"; +import { CommonModule } from '@angular/common'; +import { SdcUiComponentsModule } from "sdc-ui/lib/angular"; +import { ValueEditComponent } from './value-edit/value-edit.component'; +import { UnsavedChangesComponent } from "./unsaved-changes/unsaved-changes.component"; +import { UiElementsModule } from "../ui-elements.module"; + + + +@NgModule({ + declarations: [ + ValueEditComponent, + UnsavedChangesComponent + ], + imports: [ + CommonModule, + SdcUiComponentsModule, + UiElementsModule + ], + exports: [ValueEditComponent, UnsavedChangesComponent], + entryComponents: [ UnsavedChangesComponent + ], + providers: [] +}) +export class ModalFormsModule { + +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component.html b/catalog-ui/src/app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component.html new file mode 100644 index 0000000000..bdf21dec62 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component.html @@ -0,0 +1,6 @@ +<div class="unsaved-changes-modal"> + <div class="message"> + <p>Your changes {{isValidChangedData ? '' : '(invalid)'}} have not been saved.</p> + <p>Do you want to {{isValidChangedData ? 'save' : 'discard'}} them?</p> + </div> +</div>
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component.ts b/catalog-ui/src/app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component.ts new file mode 100644 index 0000000000..b8fdeaf659 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component.ts @@ -0,0 +1,17 @@ +import { Component, Input } from "@angular/core"; + +@Component({ + selector: 'unsaved-changes', + templateUrl: './unsaved-changes.component.html', + styleUrls: [] +}) +export class UnsavedChangesComponent { + + @Input() isValidChangedData:boolean; + + constructor(){ + } + + + +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.html b/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.html new file mode 100644 index 0000000000..464b756a3f --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.html @@ -0,0 +1,12 @@ +<div class="name-update-container"> + <sdc-input #updateNameInput + label="Instance Name" + required="true" + [maxLength]="50" + [(value)]="name" + testId="instanceName"></sdc-input> + <sdc-validation [validateElement]="updateNameInput" (validityChanged)="validityChanged($event)"> + <sdc-required-validator message="Name is required."></sdc-required-validator> + <sdc-regex-validator message="Special characters not allowed." [pattern]="pattern"></sdc-regex-validator> + </sdc-validation> +</div>
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.less b/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.less new file mode 100644 index 0000000000..b958ca17b7 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.less @@ -0,0 +1,3 @@ +.name-update-container { + min-height: 90px; +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.ts b/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.ts new file mode 100644 index 0000000000..08bc0586c7 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.ts @@ -0,0 +1,25 @@ +import { Component, Input } from "@angular/core"; + +@Component({ + selector: 'value-edit', + templateUrl: './value-edit.component.html', + styleUrls: ['./value-edit.component.less'] +}) +export class ValueEditComponent { + + @Input() name:String; + @Input() validityChangedCallback: Function; + + private pattern:string = "^[\\s\\w\&_.:-]{1,1024}$" + constructor(){ + } + + private validityChanged = (value):void => { + if(this.validityChangedCallback) { + this.validityChangedCallback(value); + } + } + + + +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.html b/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.html new file mode 100644 index 0000000000..ba897198d6 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.html @@ -0,0 +1,30 @@ +<div class="component-add-element"> + <div class="add-element-selection-container"> + <sdc-dropdown class="add-element-selection" selectedOption="selectedElement" placeHolder="Please choose option" + (changed)="onElementSelected($event)" [options]="dropdownOptions"></sdc-dropdown> + <svg-icon-label class="add-element-button" [class.disabled]="!selectedElement" + name="plus-circle-o" + mode="primary" + size="medium" + label="ADD" + labelPlacement="right" + clickable="{{!!selectedElement}}" + (click)="addElement()"> + </svg-icon-label> + </div> + + <div class="elements-list"> + <ul> + <li *ngFor="let element of existingElements" class="elements-list-item"> + <span>{{element.name}}</span> + <svg-icon-label name="trash-o" clickable="true" size="small" class="elements-list-item-delete" + data-tests-id="delete_target" (click)="removeElement(element)"></svg-icon-label> + </li> + </ul> + <div *ngIf="existingElements.length===0" class="add-element-no-data"> + <div class="add-element-no-data-title">No {{elementName}} have been added yet.</div> + <div class="add-element-no-data-content">Begin typing or select {{elementName}} above</div> + </div> + </div> + +</div>
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.less b/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.less new file mode 100644 index 0000000000..522483dfb7 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.less @@ -0,0 +1,61 @@ +@import "./../../../../../../assets/styles/variables-old"; + +.component-add-element { + + .add-element-selection-container { + + display: flex; + flex-direction: row; + .add-element-selection { + flex: 2; + } + + .add-element-button { + padding: 0px 0px 0px 15px; + &:not(.disabled) { + cursor:pointer; + } + } + + } + + .elements-list { + border: 1px solid #d2d2d2; + margin-top: 10px; + height: 300px; + overflow: auto; + + .elements-list-item { + padding: 10px 20px 10px 20px; + + &:first-child { + padding-top: 15px; + } + + &:hover { + background-color: #f8f8f8; + .elements-list-item-delete { + visibility: visible; + } + } + } + } + + .elements-list-item-delete { + float:right; + cursor: pointer; + visibility: hidden; + } + + + .add-element-no-data { + margin: 0 auto; + padding-top: 30px; + text-align: center; + + .add-element-no-data-title { + font-family: @font-opensans-bold; + } + + } +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.ts b/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.ts new file mode 100644 index 0000000000..1d05b27d68 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.ts @@ -0,0 +1,65 @@ +/** + * Created by ob0695 on 11.04.2018. + */ +import {Component, Input} from "@angular/core"; +import {UiBaseObject} from "../../../../../models/ui-models/ui-base-object"; +import {IDropDownOption} from "sdc-ui/lib/angular/form-elements/dropdown/dropdown-models"; + +@Component({ + selector: 'add-elements', + templateUrl: './add-elements.component.html', + styleUrls: ['./add-elements.component.less'] +}) + +export class AddElementsComponent { + + @Input() elementsToAdd:Array<UiBaseObject>; + @Input() elementName: string; + + private existingElements:Array<UiBaseObject>; + private dropdownOptions:Array<IDropDownOption>; + private selectedElement:IDropDownOption; + + ngOnInit() { + this.existingElements = []; + this.convertElementToDropdownDisplay(); + + } + + private convertElementToDropdownDisplay = () => { + this.dropdownOptions = []; + _.forEach(this.elementsToAdd, (elementToAdd:UiBaseObject) =>{ + this.dropdownOptions.push({label:elementToAdd.name, value: elementToAdd.uniqueId }) + }); + } + + onElementSelected(selectedElement:IDropDownOption):void { + this.selectedElement = selectedElement + } + + addElement():void { + + if(this.selectedElement){ + this.dropdownOptions = _.reject(this.dropdownOptions, (option: IDropDownOption) => { // remove from dropDown + return option.value === this.selectedElement.value; + }); + + let selected = _.find(this.elementsToAdd, (element:UiBaseObject) => { + return this.selectedElement.value === element.uniqueId; + }); + + this.elementsToAdd =_.without(this.elementsToAdd, selected); // remove from optional elements to add + this.existingElements.push(selected); // add to existing element list + this.selectedElement = undefined; + } else { + console.log("no element selected"); //TODO:show error? + } + } + + removeElement(element:UiBaseObject):void { + + this.existingElements =_.without(this.existingElements, element); // remove from optional elements to add + this.dropdownOptions.push({label:element.name, value: element.uniqueId }); + this.elementsToAdd.push(element); + } +} diff --git a/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.module.ts b/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.module.ts new file mode 100644 index 0000000000..a1c34f5686 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.module.ts @@ -0,0 +1,30 @@ +/** + * Created by ob0695 on 11.04.2018. + */ +import {NgModule} from "@angular/core"; +import {SdcUiComponentsModule} from "sdc-ui/lib/angular/index"; +import {AddElementsComponent} from "./add-elements.component"; +import {CommonModule} from "@angular/common"; + +/** + * Created by ob0695 on 9.04.2018. + */ +@NgModule({ + declarations: [ + AddElementsComponent + ], + + imports: [ + CommonModule, + SdcUiComponentsModule + ], + + entryComponents: [ + AddElementsComponent + ], + exports: [], + providers: [] +}) +export class AddElementsModule { + +} diff --git a/catalog-ui/src/app/ng2/components/ui/modal/modal.component.html b/catalog-ui/src/app/ng2/components/ui/modal/modal.component.html index 6fc55d19e7..1708fc4c23 100644 --- a/catalog-ui/src/app/ng2/components/ui/modal/modal.component.html +++ b/catalog-ui/src/app/ng2/components/ui/modal/modal.component.html @@ -1,6 +1,5 @@ <div class="custom-modal {{input.size}}"> <div class="ng2-modal-content" - ngDraggable [ngDraggable]="input.isMovable" [handle]="ModalHandle" [bounds]="ModalBounds" diff --git a/catalog-ui/src/app/ng2/components/ui/palette-animation/palette-animation.component.ts b/catalog-ui/src/app/ng2/components/ui/palette-animation/palette-animation.component.ts index 609a1fc5e1..7e45b9e55b 100644 --- a/catalog-ui/src/app/ng2/components/ui/palette-animation/palette-animation.component.ts +++ b/catalog-ui/src/app/ng2/components/ui/palette-animation/palette-animation.component.ts @@ -24,6 +24,7 @@ import { setTimeout } from 'core-js/library/web/timers'; import { EventListenerService } from 'app/services'; import { GRAPH_EVENTS } from 'app/utils'; import { Point } from 'app/models'; +import { ZoneInstanceType, ZoneInstance } from '../../../../models/graph/zones/zone-instance'; @@ -37,8 +38,9 @@ export class PaletteAnimationComponent { @Input() from : Point; @Input() to : Point; + @Input() type: ZoneInstanceType; @Input() iconName : string; - @Input() data : any; + @Input() zoneInstance : ZoneInstance; public animation; private visible:boolean = false; @@ -47,6 +49,11 @@ export class PaletteAnimationComponent { constructor(private eventListenerService:EventListenerService) {} + + ngOnDestroy(){ + this.zoneInstance.hidden = false; //if animation component is destroyed before animation is complete + } + public runAnimation() { this.visible = true; let positionDiff:Point = new Point(this.to.x - this.from.x, this.to.y - this.from.y); @@ -57,7 +64,7 @@ export class PaletteAnimationComponent { public animationComplete = (e) => { this.visible = false; - this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_FINISH_ANIMATION_ZONE); + this.zoneInstance.hidden = false; }; diff --git a/catalog-ui/src/app/ng2/components/ui/palette-popup-panel/palette-popup-panel.component.ts b/catalog-ui/src/app/ng2/components/ui/palette-popup-panel/palette-popup-panel.component.ts index d30d5f6178..a10ca7dc81 100644 --- a/catalog-ui/src/app/ng2/components/ui/palette-popup-panel/palette-popup-panel.component.ts +++ b/catalog-ui/src/app/ng2/components/ui/palette-popup-panel/palette-popup-panel.component.ts @@ -35,7 +35,8 @@ export class PalettePopupPanelComponent implements OnInit { public addZoneInstance(): void { if(this.displayComponent) { - this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_ADD_COMPONENT_INSTANCE_ZONE_START, this.component, this.displayComponent, this.popupPanelPosition); + this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_ADD_ZONE_INSTANCE_FROM_PALETTE, this.component, this.displayComponent, this.popupPanelPosition); + this.hidePopupPanel(); } } diff --git a/catalog-ui/src/app/ng2/components/ui/tile/tile.component.html b/catalog-ui/src/app/ng2/components/ui/tile/tile.component.html new file mode 100644 index 0000000000..a7a7b2c5b5 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/tile/tile.component.html @@ -0,0 +1,28 @@ +<div class="sdc-tile sdc-tile-fix-width"> + + <div class='sdc-tile-header' [ngClass]="{'purple': component.isResource(), 'blue': !component.isResource()}"> + <div *ngIf="component.isResource()" data-tests-id="asset-type">{{component.getComponentSubType()}}</div> + <div *ngIf="component.isService()">S</div> + </div> + + <div class='sdc-tile-content' data-tests-id="dashboard-Elements" (click)="tileClicked()"> + <div class='sdc-tile-content-icon'> + <div [ngClass]="[component.iconSprite, component.icon]" [ngClass]="{'sprite-resource-icons': component.isResource(), 'sprite-services-icons': component.isService()}" + [attr.data-tests-id]="component.name"></div> + </div> + + <div class='sdc-tile-content-info'> + <div class="sdc-tile-info-line title" [attr.data-tests-id]="component.name | resourceName" [tooltip]="component.name | resourceName" [tooltipDisabled]="!hasEllipsis"> + <multiline-ellipsis className="w-sdc-tile-multiline-ellipsis" [lines]="3" (hasEllipsisChanged)="hasEllipsis = $event">{{component.name | resourceName}}</multiline-ellipsis> + </div> + <div class="sdc-tile-info-line subtitle" [attr.data-tests-id]="component.name+'Version'">V {{component.version}}</div> + </div> + </div> + + <div class='sdc-tile-footer'> + <div class="sdc-tile-footer-content"> + <div class='sdc-tile-footer-text'>{{component.getStatus(sdcMenu)}}</div> + </div> + </div> + +</div> diff --git a/catalog-ui/src/app/ng2/components/ui/tile/tile.component.less b/catalog-ui/src/app/ng2/components/ui/tile/tile.component.less new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/tile/tile.component.less diff --git a/catalog-ui/src/app/ng2/components/ui/tile/tile.component.ts b/catalog-ui/src/app/ng2/components/ui/tile/tile.component.ts new file mode 100644 index 0000000000..b6f63584be --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/tile/tile.component.ts @@ -0,0 +1,24 @@ +import {Component, Input, Output, Inject, EventEmitter} from '@angular/core'; +import {Component as ComponentModel} from 'app/models'; +import {SdcMenuToken, IAppMenu} from "../../../config/sdc-menu.config"; + +@Component({ + selector: 'ui-tile', + templateUrl: './tile.component.html', + styleUrls: ['./tile.component.less'] +}) +export class TileComponent { + @Input() public component: ComponentModel; + @Output() public onTileClick: EventEmitter<ComponentModel>; + + public hasEllipsis: boolean; + + constructor(@Inject(SdcMenuToken) public sdcMenu:IAppMenu) { + this.onTileClick = new EventEmitter<ComponentModel>(); + this.hasEllipsis = false; + } + + public tileClicked() { + this.onTileClick.emit(this.component); + } +} diff --git a/catalog-ui/src/app/ng2/components/ui/tile/tile.module.ts b/catalog-ui/src/app/ng2/components/ui/tile/tile.module.ts new file mode 100644 index 0000000000..55b34400d6 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/ui/tile/tile.module.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { TileComponent } from './tile.component'; +import { GlobalPipesModule } from "../../../pipes/global-pipes.module"; +import { TooltipModule } from "../tooltip/tooltip.module"; +import {MultilineEllipsisModule} from "../../../shared/multiline-ellipsis/multiline-ellipsis.module"; + + +@NgModule({ + imports: [BrowserModule, GlobalPipesModule, TooltipModule, MultilineEllipsisModule], + declarations: [TileComponent], + exports: [TileComponent], + entryComponents: [TileComponent] +}) +export class TileModule { } diff --git a/catalog-ui/src/app/ng2/components/ui/ui-elements.module.ts b/catalog-ui/src/app/ng2/components/ui/ui-elements.module.ts index 44314734c3..e905db73a6 100644 --- a/catalog-ui/src/app/ng2/components/ui/ui-elements.module.ts +++ b/catalog-ui/src/app/ng2/components/ui/ui-elements.module.ts @@ -20,26 +20,28 @@ import { NgModule } from '@angular/core'; import { NavbarModule } from "./navbar/navbar.module"; -import {DynamicElementModule} from "./dynamic-element/dynamic-element.module"; -import {FormElementsModule} from "./form-components/form-elements.module"; -import {LoaderComponent} from "./loader/loader.component"; -import {ModalModule} from "./modal/modal.module"; -import {PopoverModule} from "./popover/popover.module"; -import {SearchBarComponent} from "./search-bar/search-bar.component"; -import {SearchWithAutoCompleteComponent} from "./search-with-autocomplete/search-with-autocomplete.component"; -import {PalettePopupPanelComponent} from "./palette-popup-panel/palette-popup-panel.component"; -import {ZoneContainerComponent} from "./canvas-zone/zone-container.component"; -import {ZoneInstanceComponent } from "./canvas-zone/zone-instance/zone-instance.component"; -import {PaletteAnimationComponent} from "./palette-animation/palette-animation.component" -import {TabModule} from "./tabs/tabs.module"; -import {TooltipModule} from "./tooltip/tooltip.module"; -import {CommonModule} from "@angular/common"; -import {FormsModule} from "@angular/forms"; -import {BrowserModule} from "@angular/platform-browser"; -import {MultiStepsWizardModule} from "./multi-steps-wizard/multi-steps-wizard.module"; -import {MenuListModule} from "./menu/menu-list.module"; -import {MenuListNg2Module} from "../downgrade-wrappers/menu-list-ng2/menu-list-ng2.module"; -//import {SdcUiComponentsModule} from "sdc-ui/lib/angular"; +import { DynamicElementModule } from "./dynamic-element/dynamic-element.module"; +import { FormElementsModule } from "./form-components/form-elements.module"; +import { LoaderComponent } from "./loader/loader.component"; +import { ModalModule } from "./modal/modal.module"; +import { PopoverModule } from "./popover/popover.module"; +import { SearchBarComponent } from "./search-bar/search-bar.component"; +import { SearchWithAutoCompleteComponent } from "./search-with-autocomplete/search-with-autocomplete.component"; +import { PalettePopupPanelComponent } from "./palette-popup-panel/palette-popup-panel.component"; +import { ZoneContainerComponent } from "./canvas-zone/zone-container.component"; +import { ZoneInstanceComponent } from "./canvas-zone/zone-instance/zone-instance.component"; +import { PaletteAnimationComponent } from "./palette-animation/palette-animation.component" +import { TabModule } from "./tabs/tabs.module"; +import { TooltipModule } from "./tooltip/tooltip.module"; +import { CommonModule } from "@angular/common"; +import { FormsModule } from "@angular/forms"; +import { BrowserModule } from "@angular/platform-browser"; +import { MultiStepsWizardModule } from "./multi-steps-wizard/multi-steps-wizard.module"; +import { MenuListModule } from "./menu/menu-list.module"; +import { MenuListNg2Module } from "../downgrade-wrappers/menu-list-ng2/menu-list-ng2.module"; +import { ExpandCollapseComponent } from './expand-collapse/expand-collapse.component'; +import { SdcUiComponentsModule } from "sdc-ui/lib/angular"; +import { TileModule } from "./tile/tile.module"; @NgModule({ declarations: [ @@ -49,11 +51,12 @@ import {MenuListNg2Module} from "../downgrade-wrappers/menu-list-ng2/menu-list-n PalettePopupPanelComponent, ZoneContainerComponent, ZoneInstanceComponent, - PaletteAnimationComponent + PaletteAnimationComponent, + ExpandCollapseComponent ], - + imports: [ - //SdcUiComponentsModule, + SdcUiComponentsModule, BrowserModule, FormsModule, CommonModule, @@ -66,7 +69,8 @@ import {MenuListNg2Module} from "../downgrade-wrappers/menu-list-ng2/menu-list-n TooltipModule, MultiStepsWizardModule, MenuListModule, - MenuListNg2Module + MenuListNg2Module, + TileModule ], exports: [ LoaderComponent, @@ -85,7 +89,9 @@ import {MenuListNg2Module} from "../downgrade-wrappers/menu-list-ng2/menu-list-n TooltipModule, MenuListModule, MenuListNg2Module, - PaletteAnimationComponent + PaletteAnimationComponent, + ExpandCollapseComponent, + TileModule ], entryComponents: [SearchWithAutoCompleteComponent, PalettePopupPanelComponent, ZoneContainerComponent, ZoneInstanceComponent, PaletteAnimationComponent] }) |