Dynamic columns in GAB table 27/84727/4
authorTomasz Golabek <tomasz.golabek@nokia.com>
Tue, 9 Apr 2019 10:39:08 +0000 (12:39 +0200)
committerOfir Sonsino <ofir.sonsino@intl.att.com>
Tue, 30 Apr 2019 10:16:37 +0000 (10:16 +0000)
Possibility to add and remove new columns in GAB table.
Currently additional columns are not stored anywhere.

Change-Id: Idc204ef3da5be8f9509289461165e22d4c0068bf
Issue-ID: SDC-2229
Signed-off-by: Tomasz Golabek <tomasz.golabek@nokia.com>
catalog-ui/src/app/modules/directive-module.ts
catalog-ui/src/app/modules/view-model-module.ts
catalog-ui/src/app/ng2/components/logic/generic-artifact-browser/generic-artifact-browser-column-provider.component.html [new file with mode: 0644]
catalog-ui/src/app/ng2/components/logic/generic-artifact-browser/generic-artifact-browser-column-provider.component.less [new file with mode: 0644]
catalog-ui/src/app/ng2/components/logic/generic-artifact-browser/generic-artifact-browser-column-provider.component.ts [new file with mode: 0644]
catalog-ui/src/app/ng2/components/logic/generic-artifact-browser/generic-artifact-browser.component.html
catalog-ui/src/app/ng2/components/logic/generic-artifact-browser/generic-artifact-browser.component.less
catalog-ui/src/app/ng2/components/logic/generic-artifact-browser/generic-artifact-browser.component.ts
catalog-ui/src/app/ng2/components/logic/generic-artifact-browser/generic-artifact-browser.module.ts
catalog-ui/src/app/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts-view-model.ts

index 7e66443..126f99f 100644 (file)
@@ -178,7 +178,6 @@ import { TopNavComponent } from "../ng2/components/layout/top-nav/top-nav.compon
 import { ZoneContainerComponent } from "../ng2/components/ui/canvas-zone/zone-container.component";
 import { ZoneInstanceComponent } from "../ng2/components/ui/canvas-zone/zone-instance/zone-instance.component";
 import { CompositionPanelComponent } from 'app/ng2/pages/composition/panel/panel.component';
-import { CompositionPanelHeaderComponent } from 'app/ng2/pages/composition/panel/panel-header/panel-header.component';
 import { PropertiesAssignmentComponent } from "../ng2/pages/properties-assignment/properties-assignment.page.component";
 import { SearchWithAutoCompleteComponent } from "../ng2/components/ui/search-with-autocomplete/search-with-autocomplete.component";
 import { PalettePopupPanelComponent } from "../ng2/components/ui/palette-popup-panel/palette-popup-panel.component";
@@ -190,7 +189,6 @@ import { MultilineEllipsisComponent } from "../ng2/shared/multiline-ellipsis/mul
 import { InterfaceOperationComponent } from '../ng2/pages/interface-operation/interface-operation.page.component';
 import { PluginFrameComponent } from "../ng2/components/ui/plugin/plugin-frame.component";
 import { TileComponent } from "../ng2/components/ui/tile/tile.component";
-import {GenericArtifactBrowserComponent} from "../ng2/components/logic/generic-artifact-browser/generic-artifact-browser.component";
 
 
 directiveModule.directive('menuListNg2', downgradeComponent({
@@ -204,12 +202,6 @@ directiveModule.directive('topNav', downgradeComponent({
     outputs: ['searchTermChange']
 }) as ng.IDirectiveFactory);
 
-directiveModule.directive('gab', downgradeComponent({
-    component: GenericArtifactBrowserComponent,
-    inputs: ['pathsandnames', 'artifactid', 'resourceid'],
-    outputs: []
-}) as ng.IDirectiveFactory);
-
 directiveModule.directive('ng2ZoneContainer', downgradeComponent({
     component: ZoneContainerComponent,
         inputs: ['title', 'count', 'type', 'visible', 'minimized'],
index ce7d079..c633201 100644 (file)
@@ -73,7 +73,6 @@ import {DeploymentViewModel} from "../view-models/workspace/tabs/deployment/depl
 import {ReqAndCapabilitiesViewModel} from "../view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view-model";
 import {InputFormViewModel} from "../view-models/forms/input-form/input-form-view-modal";
 import {HierarchyViewModel} from "../view-models/tabs/hierarchy/hierarchy-view-model";
-import {downgradeComponent} from "@angular/upgrade/static";
 import {ConformanceLevelModalViewModel} from "../view-models/modals/conformance-level-modal/conformance-level-modal-view-model";
 import {PluginsTabViewModel} from "../view-models/plugins/plugins-tab-view-model";
 import {PluginsContextViewModel} from "../view-models/workspace/tabs/plugins/plugins-context-view-model";
diff --git a/catalog-ui/src/app/ng2/components/logic/generic-artifact-browser/generic-artifact-browser-column-provider.component.html b/catalog-ui/src/app/ng2/components/logic/generic-artifact-browser/generic-artifact-browser-column-provider.component.html
new file mode 100644 (file)
index 0000000..d5fa96a
--- /dev/null
@@ -0,0 +1,35 @@
+<!--
+  ~ Copyright (C) 2019 Nokia. All rights reserved.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<div>
+  <form class="gab-column-provider-form" #generalForm="ngForm">
+    <input type="text" name="name" (keyup)='checkNameDuplications($event)'
+           ng-maxlength="50"
+           [(ngModel)]="name"
+           class="gab-column-provider-input"
+           required>
+    <label placeholder="Column name" alt="Column name"></label>
+
+    <input type="text" name="path" (keyup)='checkPathDuplications($event)'
+           [(ngModel)]="path"
+           class="gab-column-provider-input"
+           required>
+    <label placeholder="Json path" alt="Json path"></label>
+
+    <button [disabled]="generalForm.invalid" class="tlv-btn blue" data-tests-id="Add" (click)="addColumn()">Add</button>
+    <button class="tlv-btn blue" data-tests-id="Close" (click)="cancelAddingNewColumn()">Cancel</button>
+  </form>
+</div>
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/logic/generic-artifact-browser/generic-artifact-browser-column-provider.component.less b/catalog-ui/src/app/ng2/components/logic/generic-artifact-browser/generic-artifact-browser-column-provider.component.less
new file mode 100644 (file)
index 0000000..07241a8
--- /dev/null
@@ -0,0 +1,92 @@
+.adaptive_placeholder(@height, @radius, @margin: 0em, @border: 1px) {
+  @borders: (@border * 2);
+  box-sizing: border-box;
+  width: 80%;
+  height: ~"calc(@{height} + @{borders})";
+  margin: @margin;
+  padding: @margin;
+  border: @border solid #00bafa;
+  border-radius: @radius;
+  background: #fff;
+  resize: none;
+  outline: none;
+  &[required] {
+    &:focus {
+      border-color: #00bafa;
+      + label {
+        &[placeholder] {
+          &:before {
+            margin: 0;
+            color: #00bafa;
+          }
+        }
+      }
+    }
+    &:focus,
+    &:valid {
+      + label {
+        &[placeholder] {
+          &:before {
+            transform: translate(0, (-1em)) scale(.9, .9);
+          }
+        }
+      }
+    }
+    &:invalid {
+      + label {
+        &[placeholder] {
+          &[alt] {
+            &:before {
+              content: attr(alt);
+            }
+          }
+        }
+      }
+    }
+    + label {
+      &[placeholder] {
+        display: block;
+        pointer-events: none;
+        line-height: @margin * 1.25;
+        margin-top: ~"calc(-1em - @{borders})";
+        margin-bottom: ~"calc((@{height} - @{margin}) + @{borders})";
+        &:before {
+          content: attr(placeholder);
+          display: inline-block;
+          margin: 0 ~"calc(@{margin} + @{borders})";
+          padding: 0 2px;
+          color: #00bafa;
+          font-size: small;
+          white-space: nowrap;
+          transition: .3s ease-in-out;
+
+          background-image: linear-gradient(to bottom, #fff, #fff);
+          background-size: 100% 5px;
+          background-repeat: no-repeat;
+          background-position: center;
+        }
+      }
+    }
+  }
+}
+
+.gab-column-provider-form {
+  margin: 5px
+}
+
+.gab-column-provider-input {
+  @height: 2em;
+  &[type="text"] {
+    .adaptive_placeholder(@height, (@height / 2));
+  }
+}
+
+.gab-column-provider-input.ng-valid[required], .gab-column-provider-input.ng-valid.required  {
+  border-left: 5px solid #42bb48;
+  border-right: 5px solid #42bb48;
+}
+
+.gab-column-provider-input.ng-invalid:not(form)  {
+  border-left: 5px solid #ff0511;
+  border-right: 5px solid #ff0511;
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/logic/generic-artifact-browser/generic-artifact-browser-column-provider.component.ts b/catalog-ui/src/app/ng2/components/logic/generic-artifact-browser/generic-artifact-browser-column-provider.component.ts
new file mode 100644 (file)
index 0000000..570f428
--- /dev/null
@@ -0,0 +1,94 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2019 Nokia. 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, EventEmitter, Input, Output, ViewChild, ViewEncapsulation} from "@angular/core";
+import {PathsAndNamesDefinition} from "../../../../models/paths-and-names";
+
+@Component({
+  selector: 'gab-column-provider',
+  templateUrl: './generic-artifact-browser-column-provider.component.html',
+  styleUrls: ['./generic-artifact-browser-column-provider.component.less'],
+  encapsulation: ViewEncapsulation.None
+})
+export class GenericArtifactBrowserColumnProviderComponent {
+  @Input()
+  pathsAndNames: PathsAndNamesDefinition[];
+
+  @Output()
+  onCancel = new EventEmitter();
+  @Output()
+  onSave = new EventEmitter();
+
+  @ViewChild('generalForm') generalForm;
+  name: string;
+  path: string;
+
+  constructor() {}
+
+  checkNameDuplications(event) {
+    const tmp = event.target.value;
+    if (tmp && !this.columnsContainsName(tmp)) {
+      this.name = tmp;
+      this.generalForm.form.controls['name'].setErrors(null);
+    } else {
+      this.generalForm.form.controls['name'].setErrors({incorrect: true});
+    }
+  }
+
+  checkPathDuplications(event) {
+    const tmp = event.target.value;
+    if (tmp && !this.columnsContainsPath(tmp)) {
+      this.path = tmp;
+      this.generalForm.form.controls['path'].setErrors(null);
+    } else {
+      this.generalForm.form.controls['path'].setErrors({incorrect: true});
+    }
+  }
+
+  cancelAddingNewColumn() {
+    this.onCancel.emit();
+  }
+
+  saveNewColumn() {
+    this.onSave.emit();
+  }
+
+  addColumn() {
+    this.updateColumnFilter(this.name, this.path);
+    this.saveNewColumn();
+  }
+
+  private updateColumnFilter = (name: string, prop: string): void => {
+    this.pathsAndNames.push(new PathsAndNamesDefinition(prop, name));
+    this.generalForm.form.controls['name'].setValue("");
+    this.generalForm.form.controls['path'].setValue("");
+  }
+
+  private columnsContainsName = (name: string): boolean => {
+    const columnDefinitions = this.pathsAndNames.filter(column => column.friendlyName.toLowerCase() === name.toLowerCase());
+    return columnDefinitions.length > 0;
+  }
+
+  private columnsContainsPath = (path: string): boolean => {
+    const columnDefinitions = this.pathsAndNames.filter(column => column.path.toLowerCase() === path.toLowerCase());
+    return columnDefinitions.length > 0;
+  }
+
+}
index 1abd68d..ad1ebcb 100644 (file)
   -->
 
 <div>
-    <ngx-datatable
-        class="material"
-        *ngIf="ready"
-        [rows]="rows"
-        [columns]="columns"
-        [columnMode]="'force'"
-        [headerHeight]="50"
-        [scrollbarV]="true"
-        [scrollbarH]="true"
-        [footerHeight]="0"
-        [loadingIndicator]="isLoading"
-        [rowHeight]="200"
-        [reorderable]="false"
-        [selected]="selectedRows"
-        [selectionType]="'cell'"
-        >
-        <ngx-datatable-column [prop]="col.prop" *ngFor="let col of columns">
-            <template let-column="column" ngx-datatable-header-template>
-            <span style="height:10px">
+  <ngx-datatable
+      class="material"
+      *ngIf="ready"
+      [rows]="rows"
+      [columns]="columns"
+      [columnMode]="'force'"
+      [headerHeight]="125"
+      [scrollbarV]="true"
+      [scrollbarH]="true"
+      [footerHeight]="0"
+      [loadingIndicator]="isLoading"
+      [rowHeight]="200"
+      [reorderable]="false"
+  >
+    <ngx-datatable-column prop="{{col.prop}}" [minWidth]="100" *ngFor="let col of columns">
+      <template let-column="column" height="100" ngx-datatable-header-template>
+            <span class="datatable-column-span">
               <b>{{col.name}}</b>
+              <div *ngIf="canBeDeleted(col.name)" style="width: 45px !important; color: red; "
+                   class="delete-icon" (click)="deleteColumn(col)">⛌</div>
             </span>
-                <br/>
-                <input
-                    type='text'
-                    class="datatable-input-filter"
-                    placeholder='Filter column...'
-                    (keyup)='updateColumnFilter($event, col.prop)'
-                />
-            </template>
-        </ngx-datatable-column>
+        <br/>
+        <input
+            type='text'
+            class="datattable-input-filter"
+            placeholder='Filter column...'
+            (keyup)='updateColumnFilter($event, col.prop)'
+        />
+      </template>
+    </ngx-datatable-column>
 
-    </ngx-datatable>
+    <ngx-datatable-column *ngIf="addNewColumn" class="datatable-white-body-cell" [minWidth]="220" [maxWidth]="220" [width]="220" >
+      <template ngx-datatable-header-template>
+        <gab-column-provider [pathsAndNames]="pathsandnames" (onCancel)="hideAddNewColumn()" (onSave)="refresh()"></gab-column-provider>
+      </template>
+      <template class="datatable-white-body-cell" ngx-datatable-cell-template>
+      </template>
+    </ngx-datatable-column>
+
+    <ngx-datatable-column class="datatable-white-body-cell" [minWidth]="50" [maxWidth]="50" [width]="50" >
+      <template ngx-datatable-header-template>
+        <div data-tests-id="gab-add-btn" class="add-btn add-btn-div" (click)="showAddNewColumn()">Add</div>
+      </template>
+      <template class="datatable-white-body-cell" ngx-datatable-cell-template>
+      </template>
+    </ngx-datatable-column>
+  </ngx-datatable>
 </div>
\ No newline at end of file
index 57da199..b237a12 100644 (file)
@@ -18,7 +18,9 @@
         border-bottom: 6px solid white;
 
         .selectable();
-
+        :last-of-type {
+          background-color: white;
+        }
         span {
           display: inline-block;
           line-height: 15pt;
   }
 }
 
+.datatable-column-span {
+  height: 10px;
+}
+
+.add-btn-div {
+  width: 45px;
+}
+
+.datattable-input-filter{
+  height: 23px;
+  margin: 2px auto;
+  border: none;
+  border-bottom: solid 3px #009fdb;
+  border-radius: 15px;
+  width: 75% !important;
+  padding: 0 15px 0 15px !important;
+  color: #009fdb;
+  outline: none;
+}
+
+.datattable-input-filter::placeholder {
+  color: #009fdb;
+  font-style: italic;
+}
+
 .datatable-row-group {
   padding-bottom: 6px;
   padding-top: 6px;
   }
 }
 
-.datatable-header span.datatable-header-cell-label {
-  .break-all-words();
+.datatable-header {
+  span.datatable-header-cell-label {
+    .break-all-words();
+  }
 }
 
 .datatable-input-filter{
@@ -68,6 +97,9 @@
   font-weight: bold;
   font-size: 14px;
   text-align: center;
+  div {
+    display: inline-block;
+  }
 }
 
 .break-all-words {
index 695d782..7e704e1 100644 (file)
@@ -25,49 +25,85 @@ import {PathsAndNamesDefinition} from "../../../../models/paths-and-names";
 const COLUMN_PREFIX: string = 'col';
 
 @Component({
-    selector: 'gab',
-    templateUrl: './generic-artifact-browser.component.html',
-    styleUrls:['./generic-artifact-browser.component.less'],
-    encapsulation: ViewEncapsulation.None
+  selector: 'gab',
+  templateUrl: './generic-artifact-browser.component.html',
+  styleUrls: ['./generic-artifact-browser.component.less'],
+  encapsulation: ViewEncapsulation.None
 })
 export class GenericArtifactBrowserComponent {
-    @Input()
-    pathsandnames: PathsAndNamesDefinition[];
-    @Input()
-    artifactid: string;
-    @Input()
-    resourceid: string;
-
-    columns: ColumnDefinition[];
-    rows: any[];
-    originRows: any[];
-    selectedRows: any[];
-    isLoading: boolean;
-    ready: boolean;
-    columnsFilters: Map<string, string>;
-
-    constructor(private gabService: GabService) {
-    }
+  @Input()
+  pathsandnames: PathsAndNamesDefinition[];
+  @Input()
+  artifactid: string;
+  @Input()
+  resourceid: string;
+
+  columns: ColumnDefinition[];
+  originColumns: ColumnDefinition[];
+  rows: any[];
+  originRows: any[];
+  isLoading: boolean;
+  ready: boolean;
+  columnsFilters: Map<string, string>;
+  addNewColumn: boolean;
+
+  constructor(private gabService: GabService) {
+  }
 
-    ngOnInit() {
-        this.ready = false;
-        this.isLoading = true;
-        this.columns = [];
-        this.columnsFilters = new Map<string,string>();
-        let paths: string[] = this.pathsandnames.map(item => item.path);
-        this.gabService.getArtifact(this.artifactid, this.resourceid, paths)
-        .subscribe(
-            response => {
-            let typedServerResponse:IServerResponse = <IServerResponse>response.json();
-            this.normalizeDataForNgxDatatable(typedServerResponse.data);
-            },
-            err => console.log(err),
-            () => {
-                this.ready = true;
-                this.isLoading = false;
-            }
-        );
-    }
+  ngOnInit() {
+    this.ready = false;
+    this.isLoading = true;
+    this.columns = [];
+    this.loadArtifacts();
+  }
+
+  loadArtifacts() {
+    this.addNewColumn = false;
+    this.columnsFilters = new Map<string, string>();
+    let paths: string[] = this.pathsandnames.map(item => item.path);
+    this.gabService.getArtifact(this.artifactid, this.resourceid, paths)
+    .subscribe(
+        response => {
+          let typedServerResponse: IServerResponse = response.json() as IServerResponse;
+          this.normalizeDataForNgxDatatable(typedServerResponse.data);
+        },
+        () => {
+            this.ready = false;
+            this.isLoading = false;
+        },
+        () => {
+          this.ready = true;
+          this.isLoading = false;
+        }
+    );
+  }
+
+  refresh() {
+    this.loadArtifacts();
+  }
+
+  canBeDeleted(name: string){
+    return this.originColumns.filter(function(column){
+      return column.name === name;
+    }).length === 0;
+  }
+
+  deleteColumn(col: ColumnDefinition) {
+    this.pathsandnames = this.pathsandnames.filter(function(pathandname){
+      return pathandname.friendlyName != col.name;
+    });
+    this.columns = this.columns.filter(function(column){
+      return column != col;
+    })
+  }
+
+  hideAddNewColumn() {
+    this.addNewColumn = false;
+  }
+
+  showAddNewColumn() {
+    this.addNewColumn = true;
+  }
 
   updateColumnFilter(event, column) {
     const val = event.target.value.toLowerCase();
@@ -83,68 +119,73 @@ export class GenericArtifactBrowserComponent {
   }
 
   private updateSingleColumnFilter(value, column, rows) {
-    return rows.filter(function(obj) {
+    return rows.filter(function (obj) {
       const row = obj[column];
       return row !== undefined && row.toLowerCase().indexOf(value) !== -1 || !value;
     });
   }
 
-    private normalizeDataForNgxDatatable(data: [{ [key: string]: string }]) {
-        let result: NormalizationResult = this.getNormalizationResult(data, this.pathsandnames);
-        this.rows = result.rows;
-        this.originRows = result.rows;
-        this.columns = result.columns;
+  private normalizeDataForNgxDatatable(data: [{ [key: string]: string }]) {
+    let result: NormalizationResult = this.getNormalizationResult(data, this.pathsandnames);
+    this.rows = result.rows;
+    this.originRows = result.rows;
+    this.columns = result.columns;
+    if (!this.originColumns){
+      this.originColumns = [...result.columns];
     }
+  }
 
-    private getNormalizationResult(data: [{ [key: string]: string }],
-                                   pathsAndNames: PathsAndNamesDefinition[]): NormalizationResult {
-        //Prepare column names and column data property names
-        let mappingsPathToProp = new Map<string,string>();
-        let columnsDefinitions = this.normalizeColumns(pathsAndNames, mappingsPathToProp);
+  private getNormalizationResult(data: [{ [key: string]: string }],
+                                 pathsAndNames: PathsAndNamesDefinition[]): NormalizationResult {
+    //Prepare column names and column data property names
+    let mappingsPathToProp = new Map<string, string>();
+    let columnsDefinitions = this.normalizeColumns(pathsAndNames, mappingsPathToProp);
 
-        //Convert rows from { "string": "string" } to { prop : "string" } format
-        //This is required by NgxDatatable component
-        let arrayOfRows = this.normalizeRows(data, mappingsPathToProp);
+    //Convert rows from { "string": "string" } to { prop : "string" } format
+    //This is required by NgxDatatable component
+    let arrayOfRows = this.normalizeRows(data, mappingsPathToProp);
 
-        return new NormalizationResult(arrayOfRows, columnsDefinitions);
-    }
+    return new NormalizationResult(arrayOfRows, columnsDefinitions);
+  }
 
-    private normalizeColumns(pathsAndNames: PathsAndNamesDefinition[], mappingsPathToProp: Map<string,string>) {
-        let columnsDefinitions: ColumnDefinition[] = [];
-        let index: number = 1;
-
-        pathsAndNames.forEach(function (col) {
-            let columnDataPropertyName: string = COLUMN_PREFIX + index;
-            mappingsPathToProp.set(col.path, columnDataPropertyName);
-            let cell: ColumnDefinition = new ColumnDefinition(col.friendlyName, columnDataPropertyName);
-            columnsDefinitions.push(cell);
-            index += 1;
-        });
-        return columnsDefinitions;
-    }
+  private normalizeColumns(pathsAndNames: PathsAndNamesDefinition[], mappingsPathToProp: Map<string, string>) {
+    let columnsDefinitions: ColumnDefinition[] = [];
+    let index: number = 1;
 
-    private normalizeRows(data: [{ [key: string]: string }], mappingsPathToProp: Map<string,string>) {
-        let arrayOfRows = [];
-        data.forEach(function (col) {
-            let row = {};
-            for (let key in col) {
-                if (col.hasOwnProperty(key)) {
-                    let columnNameAsProp = mappingsPathToProp.get(key);
-                    row[columnNameAsProp] = col[key];
-                }
-            }
-            arrayOfRows.push(row);
-        });
-
-        return arrayOfRows;
-    }
+    pathsAndNames.forEach(function (col) {
+      let columnDataPropertyName: string = COLUMN_PREFIX + index;
+      mappingsPathToProp.set(col.path, columnDataPropertyName);
+      let cell: ColumnDefinition = new ColumnDefinition(col.friendlyName, columnDataPropertyName);
+      columnsDefinitions.push(cell);
+      index += 1;
+    });
+    return columnsDefinitions;
+  }
+
+  private normalizeRows(data: [{ [key: string]: string }], mappingsPathToProp: Map<string, string>) {
+    let arrayOfRows = [];
+    data.forEach(function (col) {
+      let row = {};
+      for (let key in col) {
+        if (col.hasOwnProperty(key)) {
+          let columnNameAsProp = mappingsPathToProp.get(key);
+          row[columnNameAsProp] = col[key];
+        }
+      }
+      arrayOfRows.push(row);
+    });
+
+    return arrayOfRows;
+  }
 }
 
 class NormalizationResult {
-    constructor(public rows: any[], public columns: ColumnDefinition[]) {}
+  constructor(public rows: any[], public columns: ColumnDefinition[]) {
+  }
 }
 
 export class ColumnDefinition {
-    constructor(public name: string, public prop: string) {}
+  constructor(public name: string, public prop: string) {
+  }
 }
 
index afb2047..e3ccf30 100644 (file)
@@ -22,17 +22,22 @@ import {GenericArtifactBrowserComponent} from "./generic-artifact-browser.compon
 import {NgxDatatableModule} from "@swimlane/ngx-datatable";
 import {GabService} from "../../../services/gab.service";
 import {BrowserModule} from "@angular/platform-browser";
+import {GenericArtifactBrowserColumnProviderComponent} from "./generic-artifact-browser-column-provider.component";
+import {FormsModule} from "@angular/forms";
 
 @NgModule({
     declarations: [
-        GenericArtifactBrowserComponent
+        GenericArtifactBrowserComponent,
+        GenericArtifactBrowserColumnProviderComponent
     ],
     imports: [
         BrowserModule,
+        FormsModule,
         NgxDatatableModule
     ],
     entryComponents: [ //need to add anything that will be dynamically created
-        GenericArtifactBrowserComponent
+        GenericArtifactBrowserComponent,
+        GenericArtifactBrowserColumnProviderComponent
     ],
     exports: [],
     providers: [GabService]
index 5e78301..5ada3d0 100644 (file)
@@ -289,12 +289,11 @@ export class DeploymentArtifactsViewModel {
                 title: title,
                 type: 'custom',
                 buttons: [{
-                        id: 'okButton',
-                        text: 'OK',
+                        id: 'closeGABButton',
+                        text: 'Close',
                         size: "'x-small'",
                         closeModal: true
-                    },
-                    {text: "Cancel", size: "'x-small'", closeModal: true}]
+                    }]
             };
 
             const uiConfiguration: any = this.cacheService.get('UIConfiguration');