You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dlab.apache.org by dg...@apache.org on 2020/05/12 16:57:38 UTC

[incubator-dlab] 01/02: [DLAB-1783]: Added bucket window, changed filter by name, fixed bugs

This is an automated email from the ASF dual-hosted git repository.

dgnatyshyn pushed a commit to branch DLAB-1783
in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git

commit 3ada3f686d7d53f1cc51f7abe11c6c69fbde04f6
Author: Dmytro Gnatyshyn <di...@ukr.net>
AuthorDate: Tue May 12 19:53:33 2020 +0300

    [DLAB-1783]: Added bucket window, changed filter by name, fixed bugs
---
 .../bucket-browser/bucket-browser.component.html   |  64 ++++++------
 .../bucket-browser/bucket-browser.component.scss   | 108 +++++++++++++++++----
 .../bucket-browser/bucket-browser.component.ts     |  20 +++-
 .../bucket-confirmation-dialog.component.html      |   2 +-
 .../bucket-confirmation-dialog.component.scss      |   2 +
 .../bucket-browser/bucket-data.service.ts          |   2 +-
 .../buckets-tree/bucket-tree.component.html        |  15 +++
 .../bucket-tree.component.scss}                    |   0
 .../buckets-tree/bucket-tree.component.ts          |  81 ++++++++++++++++
 .../folder-tree/folder-tree.component.html         |  17 +++-
 .../folder-tree/folder-tree.component.scss         |   1 -
 .../folder-tree/folder-tree.component.ts           |   8 +-
 .../webapp/src/app/resources/resources.module.ts   |   4 +-
 13 files changed, 263 insertions(+), 61 deletions(-)

diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.html
index e38fadd..9041be1 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.html
@@ -27,7 +27,7 @@
   <div class="dialog-content tabs" [hidden]="!path">
     <div class="submit m-bott-10 m-top-10">
       <span [matTooltip]="'You have not permission to upload data'" matTooltipPosition="above" matTooltipDisabled="{{this.bucketStatus.upload}}">
-        <button mat-raised-button type="button" class="butt action first-btn" [disabled]="!this.bucketStatus.upload || allDisable" (click)="handleFileInput($event)">
+        <button mat-raised-button type="button" class="butt action first-btn" [disabled]="!this.bucketStatus.upload || allDisable || isSelectionOpened" (click)="handleFileInput($event)">
           <input [ngClass]="{'not-allowed': !this.bucketStatus.upload}" type="file" (change)="handleFileInput($event)" title="" multiple>
           Upload files
         </button>
@@ -107,35 +107,25 @@
      </span>
     </span></p>
 
-    <div class="navigation-line">
-        <div class="endpoint-select selection">
-          <div class="mat-reset">
-            <div class="control selector-wrapper">
-              <mat-form-field>
-                <mat-label>{{bucketName}}</mat-label>
-                <mat-select [(value)]="bucketName">
-<!--                    <mat-option *ngIf="projects.length > 1" (click)="setActiveProject()">Show all</mat-option>-->
-<!--                    <mat-option *ngFor="let project of projects" [value]="project.name"-->
-<!--                                (click)="setActiveProject(project.name)">-->
-<!--                      {{ project.name }}</mat-option>-->
-                  <mat-option class="multiple-select ml-10" disabled>Bucket list is empty
-                  </mat-option>
-                </mat-select>
-                <button class="caret">
-                  <i class="material-icons">keyboard_arrow_down</i>
-                </button>
-              </mat-form-field>
-            </div>
-          </div>
-        </div>
-        <div class="filter-files">
-          <input _ngcontent-yns-c13="" [(ngModel)]="searchValue" (keyup)=filterObjects($event) class="form-control filter-field" placeholder="Filter by name" type="text">
-        </div>
-
-    </div>
+<!--    <div class="navigation-line">-->
+<!--        <div class="filter-files">-->
+<!--          <input _ngcontent-yns-c13="" [(ngModel)]="searchValue" (keyup)=filterObjects($event) class="form-control filter-field" placeholder="Filter by name" type="text">-->
+<!--        </div>-->
+<!--    </div>-->
 
     <div class="bucket-wrapper" [ngClass]="{'added-upload': addedFiles.length}" id="scrolling">
-      <div class="navigation">
+      <div class="backet-selection" [ngClass]="{'opened': isSelectionOpened}">
+        <div class="button-wrapper">
+          <i (click)="toggleBucketSelection()" class="material-icons close">{{isSelectionOpened ? 'chevron_left' : 'chevron_right'}}</i>
+        </div>
+        <dlab-bucket-tree
+          *ngIf="isSelectionOpened"
+          (emitActiveBucket)=onFolderClick($event)
+          [openedBucket] = this.bucketName
+        >
+        </dlab-bucket-tree>
+      </div>
+      <div class="navigation" [ngClass]="{'selection-opened': isSelectionOpened}">
         <dlab-folder-tree
           (showFolderContent)=onFolderClick($event)
           (disableAll) = dissableAll($event)
@@ -143,10 +133,22 @@
           [endpoint] = endpoint
         > </dlab-folder-tree>
       </div>
-      <div class="directory">
-        <div class="folder-item t_header"  *ngIf="folderItems.length">
+      <div class="directory" [ngClass]="{'selection-opened': isSelectionOpened}">
+        <div class="folder-item t_header">
           <div class="folder-item-wrapper header-wrapper folder-tree header-item">
-            <div class="name"><span class="th_name">Name</span></div>
+            <div class="name">
+              <span class="th_name" (click)="isFilterVisible = true" *ngIf="!isFilterVisible">Name</span>
+              <div class="filter-files"  *ngIf="isFilterVisible">
+                <input _ngcontent-yns-c13=""
+                       [(ngModel)]="searchValue"
+                       (keyup)=filterObjects()
+                       class="form-control filter-field filter-name"
+                       placeholder="Filter by name" type="text"
+                >
+                <span><i (click)="closeFilterInput()" class="material-icons close">close</i></span>
+              </div>
+
+            </div>
             <div class="size"><span class="th_size">Size</span></div>
             <div class="date"><span class="th_date">Last modified</span></div>
           </div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.scss
index 564a803..a03428a 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.scss
@@ -86,7 +86,7 @@
   }
 
   .path{
-    margin: 0 4px 10px 0;
+    margin: 0 4px 30px 0;
     padding: 4px 4px 4px 0;
     color: rgba(0,0,0,.87);
     overflow: hidden;
@@ -149,9 +149,7 @@
     opacity: 0;
   }
 
-  .filter-files{
-    flex: 2;
-  }
+
 }
 
 
@@ -165,14 +163,58 @@
   &.added-upload{
     height: 37vh;
   }
+   .backet-selection{
+     position: relative;
+     width: 2%;
+     border-right: 2px solid rgba(0,0,0,.12);
+     padding-top: 6px;
+     transition: .2s;
+     &.opened{
+       width: 33.3%;
+       .button-wrapper {
+         text-align: right;
+         left: auto;
+         i{
+           padding-right: 3px;
+         }
+       }
+     }
+     .button-wrapper {
+       position: absolute;
+       left: 0;
+       right: 0;
+       top: 9px;
+       text-align: center;
+       i{
+         cursor: pointer;
+         font-size: 18px;
+         &:hover{
+           color:  #00bcd4;
+       }
+       }
+     }
 
+     .buckets-list{
+       color: rgba(0, 0, 0, 0.87);
+       padding-left: 20px;
+       line-height: 24px;
+       &-item{
+         &:hover{
+           color:  #00bcd4;
+           cursor: pointer;
+         }
+       }
+     }
+   }
   .navigation{
-    width: 33.3%;
-    flex: 1;
-    border-right: 2px solid rgba(0,0,0,.12);
+    transition: .2s;
+    width: 31.3%;
     height: 100%;
     overflow: auto;
     padding-top: 6px;
+    &.selection-opened{
+      width: 66.7%;
+    }
     .folder-tree{
 
       .folder{
@@ -188,10 +230,13 @@
   .directory{
     width: 66.7%;
     max-height: 100%;
-    flex: 2;
     font-size: 14px;
     font-weight: 400;
     position: relative;
+    border-left: 2px solid rgba(0,0,0,.12);
+    &.selection-opened{
+      display: none;
+    }
     .folder-tree{
       overflow: auto;
       max-height: 100%;
@@ -224,9 +269,6 @@
       }
       .size{
         flex:1;
-        &-folder{
-          padding-left: 7px;
-        }
       }
       .date{
         flex:1;
@@ -291,23 +333,55 @@
      display: flex;
      align-items: center;
     &.t_header{
-      top: -27px;
+      top: -33px;
       position: absolute;
       left: 0;
       right: 0;
 
+      .folder-item-wrapper{
+        height: 52px;
+      }
+
       .th_name{
-        padding-left: 29px;
-        font-size: 11px;
+        padding-left: 25px;
+        font-size: 14px;
+        cursor: pointer;
+        &:hover{
+          color: #00bcd4;
+        }
       }
 
+      .filter-files{
+        width: 100%;
+        padding: 3px 26px;
+        display: flex;
+        align-items: center;
+        .filter-name{
+          font-size: 14px;
+          height: 20px;
+          width: 90%;
+        }
+        span{
+          transform: translateY(2px);
+          &:hover{
+            i{
+              color: #00bcd4;
+            }
+          }
+        }
+      }
+
+
+
       .th_size{
-        font-size: 11px;
+        font-size: 14px;
         padding-left: 3px;
+        cursor: auto;
       }
 
       .th_date{
-        font-size: 11px !important;
+        font-size: 14px !important;
+        cursor: auto;
       }
     }
      .folder-item-wrapper{
@@ -318,7 +392,7 @@
        cursor: pointer;
        color: rgba(0,0,0,.87);
        &.header-item{
-         pointer-events: none;
+         //pointer-events: none;
        }
        i{
          color: rgb(232, 232, 232);
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.ts
index 7570c9d..133d78d 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.ts
@@ -56,6 +56,8 @@ export class BucketBrowserComponent implements OnInit {
   public searchValue: string;
 
   @ViewChild(FolderTreeComponent, {static: true}) folderTreeComponent;
+  private isSelectionOpened: any;
+  isFilterVisible: boolean;
 
 
 
@@ -90,7 +92,7 @@ export class BucketBrowserComponent implements OnInit {
 
       const folderFiles = this.folderItems.filter(v => !v.children).map(v => v.item);
       for (const file of  Object['values'](event.target.files)) {
-      const existFile = folderFiles.includes(v => v === file['name'])[0];
+      const existFile = folderFiles.filter(v => v === file['name'])[0];
         const uploadItem = {
           name: file['name'],
           file: file,
@@ -168,9 +170,8 @@ export class BucketBrowserComponent implements OnInit {
     }
   }
 
-  filterObjects(event) {
-    console.log(event);
-    this.folderItems = this.originFolderItems.filter(v => v.item.indexOf(event.target.value) !== -1);
+  public filterObjects() {
+    this.folderItems = this.originFolderItems.filter(v => v.item.indexOf(this.searchValue) !== -1);
   }
 
   private clearSelection() {
@@ -178,6 +179,7 @@ export class BucketBrowserComponent implements OnInit {
     this.folderItems.forEach(item => item.isFolderSelected = false);
     this.selected = this.folderItems.filter(item => item.isSelected);
     this.selectedFolderForAction = this.folderItems.filter(item => item.isFolderSelected);
+    this.selectedItems = [];
   }
 
   public deleteAddedFile(file) {
@@ -281,6 +283,16 @@ export class BucketBrowserComponent implements OnInit {
     this.isActionsOpen = false;
     this.toastr.success('Object path successfully copied!', 'Success!');
   }
+
+  public toggleBucketSelection(){
+    this.isSelectionOpened = !this.isSelectionOpened
+  }
+
+  public closeFilterInput(){
+    this.isFilterVisible = false;
+    this.searchValue = '';
+    this.filterObjects();
+  }
 }
 
 
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-confirmation-dialog/bucket-confirmation-dialog.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-confirmation-dialog/bucket-confirmation-dialog.component.html
index a512221..de5fef5 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-confirmation-dialog/bucket-confirmation-dialog.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-confirmation-dialog/bucket-confirmation-dialog.component.html
@@ -49,7 +49,7 @@
         </div>
       </mat-list>
       <div mat-dialog-content class="bottom-message" *ngIf="data.type === 'delete'">
-        <span class="confirm-message" *ngIf="isFolders">All affected object <span *ngIf="data.items.length > 1">s</span> will be deleted.</span>
+        <span class="confirm-message" *ngIf="isFolders">All affected objects will be deleted.</span>
         <span class="confirm-message" *ngIf="!isFolders"><span *ngIf="data.items.length > 1">These objects</span><span *ngIf="data.items.length === 1">This object</span> will be deleted.</span>
       </div>
       <div class="text-center m-top-20">
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-confirmation-dialog/bucket-confirmation-dialog.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-confirmation-dialog/bucket-confirmation-dialog.component.scss
index 179fb05..188c4d6 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-confirmation-dialog/bucket-confirmation-dialog.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-confirmation-dialog/bucket-confirmation-dialog.component.scss
@@ -84,6 +84,8 @@
   }
 .upload-item-name{
   max-width: 300px;
+  display: inline-block;
+  margin-bottom: -4px;
 }
 
 .mat-radio-button{
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-data.service.ts b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-data.service.ts
index c3180d7..eb0edb8 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-data.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-data.service.ts
@@ -64,7 +64,7 @@ export class BucketDataService {
           node.children = this.buildFileTree({}, level + 1);
           return accumulator.concat(node);
         }
-        if (Object.keys(value).length && Object.keys(value).length > 1) {
+        if (Object.keys(value).filter(v => v !== 'obj').length > 0) {
           if (typeof value === 'object') {
             node.object = value.obj || {'bucket': node.item, 'object': '', 'size': '', 'lastModifiedDate': ''};
             delete value.obj;
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.html
new file mode 100644
index 0000000..ba3f2a3
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.html
@@ -0,0 +1,15 @@
+<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
+  <mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding matTreeNodePaddingIndent="17" (click)="openBucketData(node)" [ngClass]="{'active-item': activeBucket === node}">
+    <button mat-icon-button disabled></button>
+    {{node.name}}
+  </mat-tree-node>
+  <mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding  matTreeNodePaddingIndent="17">
+    <button mat-icon-button matTreeNodeToggle
+            [attr.aria-label]="'toggle ' + node.name">
+      <mat-icon class="mat-icon-rtl-mirror">
+        {{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
+      </mat-icon>
+    </button>
+    {{node.name}}
+  </mat-tree-node>
+</mat-tree>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.scss
similarity index 100%
copy from services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.scss
copy to services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.scss
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.ts
new file mode 100644
index 0000000..56ef4cc
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.ts
@@ -0,0 +1,81 @@
+import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
+import {FlatTreeControl} from '@angular/cdk/tree';
+import {MatTreeFlatDataSource, MatTreeFlattener} from '@angular/material/tree';
+
+interface FoodNode {
+  name: string;
+  children?: FoodNode[];
+}
+
+const TREE_DATA: FoodNode[] = [
+      {
+        name: 'ProjectA(local)',
+        children: [
+          {name: 'vi-aws-11-05-projectb-local-bucket.'},
+          {name: 'ad-aws-11-05-projectb-local-bucket.'},
+        ]
+      }, {
+        name: 'ProjectA(local1)',
+        children: [
+          {name: 'rt-aws-11-05-projectb-local-bucket.'},
+          {name: 'rt-aws-11-05-projectb-local-bucket.'},
+        ]
+      },
+    ];
+
+/** Flat node with expandable and level information */
+interface ExampleFlatNode {
+  expandable: boolean;
+  name: string;
+  level: number;
+}
+
+
+
+@Component({
+  selector: 'dlab-bucket-tree',
+  templateUrl: './bucket-tree.component.html',
+  styleUrls: ['./bucket-tree.component.scss']
+})
+
+export class BucketTreeComponent implements OnInit {
+  public activeBucket;
+
+  @Output() emitActiveBucket: EventEmitter<{}> = new EventEmitter();
+  @Input() openedBucket: string;
+
+  private _transformer = (node: FoodNode, level: number) => {
+    return {
+      expandable: !!node.children && node.children.length > 0,
+      name: node.name,
+      level: level,
+    };
+  }
+
+  treeControl = new FlatTreeControl<ExampleFlatNode>(
+    node => node.level, node => node.expandable);
+
+  treeFlattener = new MatTreeFlattener(
+    this._transformer, node => node.level, node => node.expandable, node => node.children);
+
+  dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
+  private activeBucketName: string;
+
+  constructor() {
+    this.dataSource.data = TREE_DATA;
+  }
+
+  ngOnInit() {
+    this.activeBucketName = this.openedBucket || '';
+    // console.log(this.activeBucketName);
+    // console.log(...this.dataSource._flattenedData.getValue().filter(v => v.name === this.activeBucketName));
+  }
+
+  public openBucketData(bucket) {
+    this.treeControl.expand(bucket);
+    this.activeBucket = bucket;
+    // console.log(bucket);
+  }
+
+  hasChild = (_: number, node: ExampleFlatNode) => node.expandable;
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.html
index d635c7c..d1de799 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.html
@@ -46,7 +46,22 @@
 <!--    <mat-checkbox [checked]="descendantsAllSelected(node)"-->
 <!--                  [indeterminate]="descendantsPartiallySelected(node)"-->
 <!--                  (change)="todoItemSelectionToggle(node)"></mat-checkbox>-->
-    <div (click)="showItem(node)" class="folder-item-line"  [ngClass]="{'active-item': selectedFolder === node}"><i class="material-icons folder-icon">folder</i> <span class="folder">{{node.item}}</span></div>
+    <div
+      (click)="showItem(node)"
+      class="folder-item-line"
+      [ngClass]="{'active-item': selectedFolder === node}"
+    >
+      <i class="material-icons folder-icon">folder</i>
+      <span
+        class="folder"
+        matTooltip="{{node.item}}"
+        matTooltipPosition="above"
+        matTooltipShowDelay="1000"
+        [matTooltipClass]="'bucket-item-tooltip'"
+      >
+        {{node.item}}
+      </span>
+    </div>
 <!--    <button mat-icon-button (click)="addNewItem(node)"><mat-icon>add</mat-icon></button>-->
   </mat-tree-node>
 </mat-tree>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.scss
index 202d4e0..9fb1e42 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.scss
@@ -5,7 +5,6 @@
   white-space: nowrap;
   text-overflow: ellipsis;
   overflow: hidden;
-
 }
 
 .mat-tree{
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.ts
index ed3ccea..91242eb 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.ts
@@ -231,7 +231,6 @@ export class FolderTreeComponent implements OnInit, OnDestroy {
   private addNewItem(node: TodoItemFlatNode, file, isFile, path) {
     const parentNode = this.flatNodeMap.get(node);
 
-    console.log(parentNode);
     this.bucketDataService.insertItem(parentNode!, file, isFile);
     this.treeControl.expand(node);
   }
@@ -246,15 +245,16 @@ export class FolderTreeComponent implements OnInit, OnDestroy {
     this.folderCreating = true;
     const parent = this.getParentNode(node);
     const flatParent = this.flatNodeMap.get(parent);
-    const path = `${flatParent.object.object}${itemValue}/`;
+    const path = `${ flatParent.object ? flatParent.object.object : ''}${itemValue}/`;
+    const bucket = flatParent.object ? flatParent.object.bucket : flatParent.item;
     const formData = new FormData();
     formData.append('file', '');
     formData.append('object', path);
-    formData.append('bucket', flatParent.object.bucket);
+    formData.append('bucket', bucket);
     formData.append('endpoint', this.endpoint);
     this.bucketBrowserService.uploadFile(formData)
       .subscribe(() => {
-          this.bucketDataService.refreshBucketdata(flatParent.object.bucket, this.endpoint);
+          this.bucketDataService.refreshBucketdata(bucket, this.endpoint);
           this.toastr.success('Folder successfully created!', 'Success!');
           this.resetForm();
           this.folderFormControl.updateValueAndValidity();
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/resources.module.ts b/services/self-service/src/main/resources/webapp/src/app/resources/resources.module.ts
index 15b1d8b..b20ca72 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/resources.module.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/resources.module.ts
@@ -32,6 +32,7 @@ import {FolderTreeComponent} from './bucket-browser/folder-tree/folder-tree.comp
 import {MatTreeModule} from '@angular/material/tree';
 import {BucketDataService} from './bucket-browser/bucket-data.service';
 import {BucketConfirmationDialogComponent} from './bucket-browser/bucket-confirmation-dialog/bucket-confirmation-dialog.component';
+import {BucketTreeComponent} from './bucket-browser/buckets-tree/bucket-tree.component';
 
 @NgModule({
     imports: [
@@ -49,9 +50,10 @@ import {BucketConfirmationDialogComponent} from './bucket-browser/bucket-confirm
     ConfirmDeleteAccountDialog,
     BucketBrowserComponent,
     FolderTreeComponent,
+    BucketTreeComponent,
     BucketConfirmationDialogComponent
   ],
-  entryComponents: [ManageUngitComponent, ConfirmDeleteAccountDialog, BucketBrowserComponent, FolderTreeComponent, BucketConfirmationDialogComponent],
+  entryComponents: [ManageUngitComponent, ConfirmDeleteAccountDialog, BucketBrowserComponent, FolderTreeComponent, BucketTreeComponent, BucketConfirmationDialogComponent],
   providers: [BucketDataService],
   exports: [ResourcesComponent]
 })


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@dlab.apache.org
For additional commands, e-mail: commits-help@dlab.apache.org