Add sorting capability to property assignment 11/63011/8
authorAnjali walsatwar <anjali.walsatwar@huawei.com>
Fri, 17 Aug 2018 05:33:43 +0000 (11:03 +0530)
committerIdan Amit <ia096e@intl.att.com>
Wed, 12 Sep 2018 11:53:10 +0000 (11:53 +0000)
Change-Id: I74cbebac6cfe76f4334fcb46813c98686de55822
Issue-ID: SDC-1516
Signed-off-by: Anjali walsatwar <anjali.walsatwar@huawei.com>
catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html
catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less
catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts
catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html
catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.less
catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts
catalog-ui/src/app/ng2/pipes/global-pipes.module.ts
catalog-ui/src/app/ng2/pipes/orderBy.pipe.ts [new file with mode: 0644]

index daffc9e..8a263c0 100644 (file)
@@ -1,9 +1,39 @@
+<!--
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2018 Huawei 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=========================================================
+-->
+
 <div class="properties-table">
     <loader [display]="isLoading" [size]="'large'" [relative]="true"></loader>
     <div class="table-header">
-        <div class="table-cell col1">Property Name</div>
-        <div class="table-cell col3">From Instance</div>
-        <div class="table-cell col2">Type</div>
+        <div class="table-cell col1" (click)="sort('name')">Property Name
+            <span *ngIf="sortBy === 'name'" class="table-header-sort-arrow" [ngClass]="{'down': reverse, 'up':!reverse}">
+            </span>
+        </div>
+        <div class="table-cell col3" (click)="sort('instanceUniqueId')">From Instance
+            <span *ngIf="sortBy === 'instanceUniqueId'" class="table-header-sort-arrow" [ngClass]="{'down': reverse, 'up':!reverse}">
+            </span>
+        </div>
+        <div class="table-cell col2" (click)="sort('type')">Type
+            <span *ngIf="sortBy === 'type'" class="table-header-sort-arrow" [ngClass]="{'down': reverse, 'up':!reverse}">
+            </span>
+        </div>
         <div class="table-cell valueCol">Value</div>
     </div>
     <div class="table-body">
index 5fbb62f..72e19f3 100644 (file)
 
         .table-cell {
             font-size: 13px;
+            .table-header-sort-arrow {
+                display: inline-block;
+                background-color: transparent;
+                border: none;
+                color: #AAA;
+                margin: 8px 0 0 5px;
+                &.up {
+                    border-left: 5px solid transparent;
+                    border-right: 5px solid transparent;
+                    border-bottom: 5px solid;
+                }
+                &.down {
+                    border-left: 5px solid transparent;
+                    border-right: 5px solid transparent;
+                    border-top: 5px solid;
+                }
+            }
         }
         .valueCol {
             justify-content: flex-start;
             border-right:#d2d2d2 solid 1px;
         }
         &.col1 {
-            flex: 1 0 120px;
-            max-width:120px;
-            display: flex;
+            flex: 1 0 130px;
+            max-width:130px;
+
             justify-content: space-between;
 
             .property-name {
             }
         }
         &.col2 {
-            flex: 0 0 150px;
-            max-width:150px;
+            flex: 0 0 140px;
+            max-width:140px;
         }
 
         &.col3 {
index 0c7fc2a..d95198f 100644 (file)
@@ -3,6 +3,7 @@
  * SDC
  * ================================================================================
  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2018 Huawei 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.
@@ -21,9 +22,9 @@
 /**
  * Created by rc2122 on 5/4/2017.
  */
-import {Component, Input, Output, EventEmitter} from "@angular/core";
-import {InputFEModel} from "app/models";
-import {ModalService} from "../../../services/modal.service";
+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({
@@ -35,16 +36,48 @@ export class InputsTableComponent {
 
     @Input() inputs: Array<InputFEModel>;
     @Input() instanceNamesMap: Map<string, InstanceFeDetails>;
-    @Input() readonly:boolean;
-    @Input() isLoading:boolean;
+    @Input() readonly: boolean;
+    @Input() isLoading: boolean;
     @Output() inputChanged: EventEmitter<any> = new EventEmitter<any>();
     @Output() deleteInput: EventEmitter<any> = new EventEmitter<any>();
 
-    selectedInputToDelete:InputFEModel;
+    sortBy: String;
+    reverse: boolean;
+    selectedInputToDelete: InputFEModel;    
 
-    constructor(private modalService: ModalService){
+    sort = (sortBy) => {
+        this.reverse = (this.sortBy === sortBy) ? !this.reverse : true;
+        let reverse = this.reverse ? 1 : -1;
+        this.sortBy = sortBy;
+        let instanceNameMapTemp = this.instanceNamesMap;
+        let itemIdx1Val = "";
+        let itemIdx2Val = "";
+        this.inputs.sort(function (itemIdx1, itemIdx2) {
+            if (sortBy == 'instanceUniqueId') {
+                itemIdx1Val = (itemIdx1[sortBy] && instanceNameMapTemp[itemIdx1[sortBy]] !== undefined) ? instanceNameMapTemp[itemIdx1[sortBy]].name : "";
+                itemIdx2Val = (itemIdx2[sortBy] && instanceNameMapTemp[itemIdx2[sortBy]] !== undefined) ? instanceNameMapTemp[itemIdx2[sortBy]].name : "";
+            }
+            else {
+                itemIdx1Val = itemIdx1[sortBy];
+                itemIdx2Val = itemIdx2[sortBy];
+            }            
+            if (itemIdx1Val < itemIdx2Val) {
+                return -1 * reverse;
+            }
+            else if (itemIdx1Val > itemIdx2Val) {
+                return 1 * reverse;
+            }
+            else {
+                return 0;
+            }
+        });
+    };
+
+
+    constructor(private modalService: ModalService) {
     }
 
+
     onInputChanged = (input, event) => {
         input.updateDefaultValueObj(event.value, event.isValid);
         this.inputChanged.emit(input);
@@ -55,7 +88,7 @@ export class InputsTableComponent {
         this.modalService.closeCurrentModal();
     };
 
-    openDeleteModal = (input:InputFEModel) => {
+    openDeleteModal = (input: InputFEModel) => {
         this.selectedInputToDelete = input;
         this.modalService.createActionModal("Delete Input", "Are you sure you want to delete this input?", "Delete", this.onDeleteInput, "Close").instance.open();
     }
index b574b55..91f9b98 100644 (file)
@@ -1,9 +1,39 @@
+<!--
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2018 Huawei Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2018 Huawei 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=========================================================
+ -->
+
 <div class="properties-table">
     <loader [display]="isLoading" [size]="'large'" [relative]="true" [loaderDelay]="500"></loader>
     <div class="table-header">
-        <div class="table-cell col1">Property Name</div>
-        <div class="table-cell col2" *ngIf="!hidePropertyType">Type</div>
-        <div class="table-cell col3" *ngIf="!hidePropertyType">ES</div>
+        <div class="table-cell col1" (click)="sort('name')">Property Name
+            <span *ngIf="sortBy === 'name'" class="table-header-sort-arrow" [ngClass]="{'down': reverse, 'up':!reverse}">
+            </span>
+        </div>
+        <div class="table-cell col2" (click)="sort('type')" *ngIf="!hidePropertyType">Type
+            <span *ngIf="sortBy === 'type'" class="table-header-sort-arrow" [ngClass]="{'down': reverse, 'up':!reverse}">
+            </span>
+        </div>
+        <div class="table-cell col3" (click)="sort('schema.property.type')" *ngIf="!hidePropertyType">ES
+            <span *ngIf="sortBy === 'schema.property.type'" class="table-header-sort-arrow" [ngClass]="{'down': reverse, 'up':!reverse}">
+            </span>
+        </div>
         <div class="table-cell valueCol">Value</div>
     </div>
     <div class="table-body" [ngClass]="{'view-mode': readonly}">
 
         <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 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"
-                (click)="onClickPropertyRow(property, instanceId, $event)"
-                [ngClass]="{'selected': selectedPropertyId && selectedPropertyId === property.name, 'readonly': property.isDisabled || property.isDeclared}">
+            <div class="table-row" *ngFor="let property of fePropertiesMap[instanceId] | searchFilter:'name':searchTerm | orderBy:{path: path, direction: direction}; trackBy:property?.name "
+                (click)="onClickPropertyRow(property, instanceId, $event)" [ngClass]="{'selected': selectedPropertyId && selectedPropertyId === property.name, 'readonly': property.isDisabled || property.isDeclared}">
 
                 <div class="table-cell col1" [ngClass]="{'filtered':property.name === propertyNameSearchText}" [class.round-checkbox]="property.isDeclared">
-                <div class="property-name">
-                    <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-multiline" tooltip="{{property.name}}">
-                        <multiline-ellipsis className="table-cell-multiline-ellipsis" [lines]="2">{{property.name}}</multiline-ellipsis>
+                    <div class="property-name">
+                        <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-multiline" tooltip="{{property.name}}">
+                            <multiline-ellipsis className="table-cell-multiline-ellipsis" [lines]="2">{{property.name}}</multiline-ellipsis>
+                        </div>
                     </div>
-                </div>
-                <span *ngIf="property.description" class="property-description-icon sprite-new show-desc" tooltip="{{property.description}}" tooltipDelay="0"></span>
+                    <span *ngIf="property.description" class="property-description-icon sprite-new show-desc" tooltip="{{property.description}}"
+                        tooltipDelay="0"></span>
                 </div>
                 <div class="table-cell col2" *ngIf="!hidePropertyType">
                     <div class="inner-cell-div" tooltip="{{property.type | contentAfterLastDot}}">
@@ -66,4 +94,4 @@
         </ng-container>
 
     </div>
-</div>
+</div>
\ No newline at end of file
index 72f67e4..0f6dd51 100644 (file)
         .table-cell {
             color:#191919;
             font-size:13px;
+            .table-header-sort-arrow {
+                display: inline-block;
+                background-color: transparent;
+                border: none;
+                color: #AAA;
+                margin: 8px 0 0 5px;
+                &.up {
+                    border-left: 5px solid transparent;
+                    border-right: 5px solid transparent;
+                    border-bottom: 5px solid;
+                    height:5px;
+                }
+                &.down {
+                    border-left: 5px solid transparent;
+                    border-right: 5px solid transparent;
+                    border-top: 5px solid;                    
+                }
+            }
         }
     }
 
         &.col1 {
             flex: 1 0 210px;
             max-width:300px;
-            display: flex;
-            justify-content: space-between;
+            display: flex;            
             @media @smaller-screen { flex: 0 0 25%;}
 
             .property-name {
index da1fb82..b11bc02 100644 (file)
@@ -3,6 +3,7 @@
  * SDC
  * ================================================================================
  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2017 Huawei 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.
@@ -44,6 +45,18 @@ export class PropertiesTableComponent {
     @Output() selectPropertyRow: EventEmitter<PropertyRowSelectedEvent> = new EventEmitter<PropertyRowSelectedEvent>();
     @Output() updateCheckedPropertyCount: EventEmitter<boolean> = new EventEmitter<boolean>();//only for hasDeclareOption
 
+    sortBy: String;
+    reverse: boolean;
+    direction: number;
+    path:string[];
+
+    sort(sortBy){
+        this.reverse = (this.sortBy === sortBy) ? !this.reverse : true;
+        this.direction = this.reverse ? 1 : -1;
+        this.sortBy = sortBy;
+        this.path = sortBy.split('.');
+    }
+
     constructor (private propertiesService:PropertiesService ){
     }
     
index 758a7e8..c44d71b 100644 (file)
@@ -1,3 +1,24 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2018 Huawei 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 {ContentAfterLastDotPipe} from "./contentAfterLastDot.pipe";
 import {SearchFilterPipe} from "./searchFilter.pipe";
 import {KeysPipe} from "./keys.pipe";
@@ -5,6 +26,7 @@ import {GroupByPipe} from "./groupBy.pipe";
 import {ResourceNamePipe} from "./resource-name.pipe";
 import {NgModule} from "@angular/core";
 import {SafeUrlSanitizerPipe} from "./safeUrlSanitizer.pipe";
+import {OrderByPipe} from "./orderBy.pipe";
 
 @NgModule({
     declarations: [
@@ -13,7 +35,8 @@ import {SafeUrlSanitizerPipe} from "./safeUrlSanitizer.pipe";
         KeysPipe,
         SafeUrlSanitizerPipe,
         SearchFilterPipe,
-        ResourceNamePipe
+        ResourceNamePipe,
+        OrderByPipe
     ],
     exports: [
         ContentAfterLastDotPipe,
@@ -21,7 +44,8 @@ import {SafeUrlSanitizerPipe} from "./safeUrlSanitizer.pipe";
         KeysPipe,
         SafeUrlSanitizerPipe,
         SearchFilterPipe,
-        ResourceNamePipe
+        ResourceNamePipe,
+        OrderByPipe
     ]
 })
 
diff --git a/catalog-ui/src/app/ng2/pipes/orderBy.pipe.ts b/catalog-ui/src/app/ng2/pipes/orderBy.pipe.ts
new file mode 100644 (file)
index 0000000..4edbd60
--- /dev/null
@@ -0,0 +1,35 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 Huawei 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 { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({ name: 'orderBy' })
+export class OrderByPipe implements PipeTransform {
+    transform(records: Array<any>, args?: any): any {
+        if (!records || !args.path) return records;
+        let len = args.path.length;
+        return records.sort((itemIdx1, itemIdx2) => {
+            var i = 0;
+            while (i < len) { itemIdx1 = itemIdx1[args.path[i]]; itemIdx2 = itemIdx2[args.path[i]]; i++; }
+            // Order * (-1): We change our order
+            return itemIdx1 + "" > itemIdx2 + "" ? args.direction : args.direction * (- 1);
+        })
+    };
+}