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/04/14 08:14:18 UTC

[incubator-dlab] 03/05: [DLAB-1551]: Added folders menu

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

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

commit 084a9ecced5d8e3e20428759460cc1dc64467e77
Author: Dmytro Gnatyshyn <di...@ukr.net>
AuthorDate: Fri Apr 10 11:52:29 2020 +0300

    [DLAB-1551]: Added folders menu
---
 .../app/core/services/bucket-browser.service.ts    | 46 ++++++-----
 .../bucket-browser/bucket-browser.component.html   | 38 ++++++----
 .../bucket-browser/bucket-browser.component.scss   | 51 ++++++++++++-
 .../bucket-browser/bucket-browser.component.ts     | 43 ++++++++++-
 .../folder-tree/folder-tree.component.html         | 20 ++---
 .../folder-tree/folder-tree.component.scss         | 22 ++++++
 .../folder-tree/folder-tree.component.ts           | 88 ++++++++++++++++++----
 7 files changed, 242 insertions(+), 66 deletions(-)

diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/bucket-browser.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/bucket-browser.service.ts
index 0c334a1..c98df9b 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/bucket-browser.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/bucket-browser.service.ts
@@ -4,6 +4,7 @@ import {BehaviorSubject} from 'rxjs';
 export class TodoItemNode {
   children: TodoItemNode[];
   item: string;
+  id: string;
 }
 
 /** Flat to-do item node with expandable and level information */
@@ -17,23 +18,26 @@ export class TodoItemFlatNode {
  * The Json object for to-do list data.
  */
 const TREE_DATA = {
-  FirsrFolder: {
-    folder: {
-      folder: ['file1', 'file2'],
-      file1: null,
-      file2: null
+  'dlab-local-shared-bucket': {
+    FirsrFolder: {
+      folder: {
+        folder: ['2008.cvs.bz2', 'airports.csv', 'carriers.csv'],
+        folder1: [],
+        folder2: []
+      },
+      'folder1': [],
+      'file2': null,
+      'file3': null,
     },
-    'file': null,
-    'file2': null,
-    'file3': null,
-  },
-  SecondFolder: [
-    'file1',
-    'file2',
-    'file3'
-  ]
+    SecondFolder: [
+      'file1',
+      'file2',
+      'file3'
+    ]
+  }
 };
 
+
 @Injectable({
   providedIn: 'root'
 })
@@ -50,7 +54,7 @@ export class BucketBrowserService {
     // Build the tree nodes from Json object. The result is a list of `TodoItemNode` with nested
     //     file node as children.
     const data = this.buildFileTree(TREE_DATA, 0);
-
+    console.log(data);
     // Notify the change.
     this.dataChange.next(data);
   }
@@ -64,7 +68,6 @@ export class BucketBrowserService {
       const value = obj[key];
       const node = new TodoItemNode();
       node.item = key;
-
       if (value != null) {
         if (typeof value === 'object') {
           node.children = this.buildFileTree(value, level + 1);
@@ -78,9 +81,9 @@ export class BucketBrowserService {
   }
 
   /** Add an item to to-do list */
-  insertItem(parent: TodoItemNode, name: string) {
+  insertItem(parent: TodoItemNode, name: string, isFile) {
     if (parent.children) {
-      parent.children.push({item: name} as TodoItemNode);
+      parent.children.push(isFile ? {item: name} as TodoItemNode : {item: name, children: []} as TodoItemNode);
       this.dataChange.next(this.data);
     }
   }
@@ -89,4 +92,11 @@ export class BucketBrowserService {
     node.item = name;
     this.dataChange.next(this.data);
   }
+
+  uploadFile(parent: TodoItemNode, name: string) {
+    if (parent.children) {
+      parent.children.push({item: name, children: []} as TodoItemNode);
+      this.dataChange.next(this.data);
+    }
+  }
 }
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 307f21b..50c812d 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
@@ -25,38 +25,44 @@
   <div class="dialog-content tabs">
     <div class="submit m-bott-10 m-top-10">
       <button mat-raised-button type="button" class="butt action"><input type="file" (change)="handleFileInput($event.target.files)">Add file</button>
-<!--      <button mat-raised-button type="button" class="butt action"><input type="file" (change)="filesPicked($event.target.files)" webkitdirectory directory multiple/>Upload folder</button>-->
-<!--      <button mat-raised-button type="button" class="butt action">Download files</button>-->
-      <button mat-raised-button type="button" class="butt action">Create folder</button>
+      <button mat-raised-button type="button" class="butt action" (click)="folderTreeComponent.addNewItem(selectedFolder, '', false)">Create folder</button>
     </div>
+    <p class="path"><span class="strong">Bucket path:</span><i> {{path}}</i></p>
     <div class="backet-wrapper" id="scrolling">
       <div class="navigation">
-        <dlab-folder-tree></dlab-folder-tree>
-<!--        <ul class="folder-tree">-->
-<!--          <li class="folder-item">-->
-<!--            <i class="material-icons">folder</i>-->
-<!--            <span class="folder">bucket</span>-->
-<!--          </li>-->
-<!--        </ul>-->
+        <dlab-folder-tree (showFolderContent)=onFolderClick($event)> </dlab-folder-tree>
       </div>
       <div class="directory">
-<!--        <dlab-folder-tree></dlab-folder-tree>-->
+        <ul class="folder-tree" *ngIf="!uploadPaths.length">
+          <li *ngFor="let file of folderItems" class="folder-item" >
+            <div class="folder-item-wrapper" *ngIf="file.children" (click)="showItem(file)">
+              <div class="name name-folder"><i class="material-icons folder-icon" >folder</i><span>{{file.item}}</span></div>
+              <div class="size">2.4kb</div>
+            </div>
+            <div class="folder-item-wrapper" *ngIf="!file.children">
+              <div class="name name-file"> <mat-checkbox ></mat-checkbox><span>{{file.item}}</span></div>
+<!--                [checked]="descendantsAllSelected(node)"-->
+<!--                [indeterminate]="descendantsPartiallySelected(node)"-->
+<!--                (change)="todoItemSelectionToggle(node)"-->
+              <div class="size">2.4kb</div>
+            </div>
+            <!--            <div class="progres"></div>-->
+          </li>
+        </ul>
         <ul class="folder-tree">
           <li *ngFor="let file of uploadPaths" class="folder-item">
             <div class="name">{{file}}</div>
             <div class="size">2.4kb</div>
             <div class="progres"></div>
-          </li>
-          <li class="folder-item">
-
+            <div (click)="deleteAddedFile(file)">X</div>
           </li>
         </ul>
       </div>
     </div>
     <div class="text-center m-top-30 m-bott-30">
       <button type="button" class="butt" mat-raised-button (click)="this.dialogRef.close()">Close</button>
-      <button type="button" class="butt butt-success" mat-raised-button>Download</button>
-      <button type="button" class="butt butt-success" mat-raised-button>Upload</button>
+      <button *ngIf="!this.uploadPaths.length" type="button" class="butt butt-success" mat-raised-button >Download</button>
+      <button *ngIf="this.uploadPaths.length !== 0" type="button" class="butt butt-success" mat-raised-button (click)="uploadItems()">Upload</button>
     </div>
   </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 9d839bb..dba2d31 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
@@ -18,7 +18,13 @@
  */
 
 .bucket-browser {
+  .path{
+    margin-bottom: 8px;
+    padding-left: 20px;
+    .url{
 
+    }
+  }
   bottom: 0;
   .dialog-content{
     padding: 0 35px;
@@ -51,7 +57,6 @@
     left: 0;
     right: 0;
   }
-
 }
 
 .backet-wrapper{
@@ -60,6 +65,8 @@
   border-radius: 5px;
   display: flex;
 
+
+
   .navigation{
     flex: 1;
     border-right: 2px solid rgba(0,0,0,.12);
@@ -79,6 +86,19 @@
     .folder-tree{
       .name{
         flex:2;
+        display: flex;
+        align-items: center;
+        &-folder{
+          span{
+            padding-left: 10px;
+          }
+        }
+        &-file{
+          padding-left: 4px;
+          span{
+            padding-left: 14px;
+          }
+        }
       }
       .size{
         flex:1;
@@ -118,6 +138,33 @@
   .folder-item{
      display: flex;
      align-items: center;
-
+     .folder-item-wrapper{
+       width: 100%;
+       display: flex;
+       justify-content: space-between;
+       align-items: center;
+       cursor: pointer;
+       color: rgba(0,0,0,.87);
+       i{
+         color: rgb(232, 232, 232);
+       }
+       &:hover{
+         color: #00bcd4;
+         transition: .3s ease-in-out;
+         i{
+           color: #00bcd4;
+           transition: .3s ease-in-out;
+         }
+       }
+     }
    }
 }
+
+.folder-item-name{
+  span{
+    color: #000;
+  }
+
+
+
+}
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 447501e..71d9dba 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
@@ -22,9 +22,10 @@ import { FormGroup, FormBuilder, Validators } from '@angular/forms';
 import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
 import { ToastrService } from 'ngx-toastr';
 
-import { AccountCredentials, MangeUngitModel } from './bucket-browser.model';
+// import { AccountCredentials, MangeUngitModel } from './bucket-browser.model';
 import { ManageUngitService } from '../../core/services';
 import {logger} from 'codelyzer/util/logger';
+import {FolderTreeComponent} from './folder-tree/folder-tree.component';
 
 @Component({
   selector: 'dlab-bucket-browser',
@@ -34,7 +35,12 @@ import {logger} from 'codelyzer/util/logger';
 export class BucketBrowserComponent implements OnInit {
   filenames: Array<any> = [];
   uploadPaths = [];
-  @ViewChild('tabGroupGit', { static: false }) tabGroupGit;
+  folderItems = [];
+  path = '';
+  selectedFolderItems = [];
+  // @ViewChild('tabGroupGit', { static: false }) tabGroupGit;
+  @ViewChild(FolderTreeComponent, {static: true}) folderTreeComponent;
+  private selectedFolder: any;
 
   constructor(
     public toastr: ToastrService,
@@ -50,14 +56,22 @@ export class BucketBrowserComponent implements OnInit {
 
   }
 
+  showItem(item) {
+    const flatItem = this.folderTreeComponent.nestedNodeMap.get(item);
+    // this.folderTreeComponent.treeControl.isExpanded(flatItem) = ;
+    this.folderTreeComponent.showItem(flatItem);
+    // console.log(item);
+    // this.onFolderClick(item);
+  }
+
   handleFileInput(files) {
     //   for (let i = 0; i < files.length; i++) {
     //     const file = files[i];
     //     const path = file.webkitRelativePath.split('/');
     //   }
     // }
-    console.log(files)
-    this.filenames = Object['values'](files).map(v => v.name)
+    console.log(files);
+    this.filenames = Object['values'](files).map(v => v.name);
     this.uploadPaths = [...this.uploadPaths, ...this.filenames];
   }
 
@@ -70,6 +84,13 @@ export class BucketBrowserComponent implements OnInit {
     console.log(this.uploadPaths);
   }
 
+  onFolderClick(event) {
+    this.selectedFolder = event.element1;
+    this.folderItems = event.element ? event.element.children : event.children;
+    this.path = event.path;
+
+  }
+
   private upload(tree, path) {
     tree.files.forEach(file => {
       this.uploadPaths.push(path + file.name);
@@ -80,6 +101,20 @@ export class BucketBrowserComponent implements OnInit {
       this.upload(directory, newPath);
     });
   }
+
+  deleteAddedFile(file) {
+    this.uploadPaths.splice(this.uploadPaths.indexOf(file), 1);
+  }
+
+  uploadItems(){
+    // this.folderTreeComponent.addNewItem(this.selectedFolder);
+    this.uploadPaths.forEach(v => {
+      this.folderTreeComponent.addNewItem(this.selectedFolder, v, true);
+    });
+    this.uploadPaths = [];
+    // this.folderTreeComponent.saveNode(this.selectedFolder);
+
+  }
 }
 
 // @Component({
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 2ba6ed8..5b05dea 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
@@ -1,16 +1,16 @@
 <mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
-  <mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle matTreeNodePadding>
-    <button mat-icon-button disabled></button>
-<!--    <mat-checkbox class="checklist-leaf-node"-->
-<!--                  [checked]="checklistSelection.isSelected(node)"-->
-<!--                  (change)="todoLeafItemSelectionToggle(node)"></mat-checkbox>-->
-    {{node.item}}
-  </mat-tree-node>
+  <mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle matTreeNodePadding [ngStyle]="{'display': 'none'}">
+  <button mat-icon-button disabled></button>
+  <!--    <mat-checkbox class="checklist-leaf-node"-->
+  <!--                  [checked]="checklistSelection.isSelected(node)"-->
+  <!--                  (change)="todoLeafItemSelectionToggle(node)"></mat-checkbox>-->
+  {{node.item}}
+</mat-tree-node>
 
   <mat-tree-node *matTreeNodeDef="let node; when: hasNoContent" matTreeNodePadding>
     <button mat-icon-button disabled></button>
     <mat-form-field>
-      <mat-label>New item...</mat-label>
+      <mat-label>New folder</mat-label>
       <input matInput #itemValue placeholder="Ex. Lettuce">
     </mat-form-field>
     <button mat-button (click)="saveNode(node, itemValue.value)">Save</button>
@@ -25,8 +25,8 @@
     </button>
 <!--    <mat-checkbox [checked]="descendantsAllSelected(node)"-->
 <!--                  [indeterminate]="descendantsPartiallySelected(node)"-->
-<!--                  (change)="todoItemSelectionToggle(node)">{{node.item}}</mat-checkbox>-->
-    <i class="material-icons folder-icon">folder</i> <span class="folder">{{node.item}}</span>
+<!--                  (change)="todoItemSelectionToggle(node)"></mat-checkbox>-->
+    <div (click)="showItem(node)" class="folder-item-line" [ngClass]="{'active': selectedFolder === node}"><i class="material-icons folder-icon">folder</i> <span class="folder">{{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 a842b13..8da2b8d 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
@@ -1,3 +1,4 @@
+
 .folder{
   padding-left: 5px;
 }
@@ -5,3 +6,24 @@
 .folder-icon{
   color: rgb(232, 232, 232);
 }
+
+.folder-item-line{
+  display: flex;
+  align-items: center;
+  cursor: pointer;
+  &.active {
+    //border-bottom: 1px solid #00bcd4;
+    color: #00bcd4;
+    i{
+      color: #00bcd4;
+    }
+
+}
+  &:hover{
+    color: #00bcd4;
+    i{
+      color: #00bcd4;
+    }
+  }
+
+}
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 bba1a45..7070c25 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
@@ -1,13 +1,13 @@
-import { Component, OnInit, Injectable } from '@angular/core';
+import {Component, OnInit, AfterViewInit, Output, EventEmitter} from '@angular/core';
 import {SelectionModel} from '@angular/cdk/collections';
 import {FlatTreeControl} from '@angular/cdk/tree';
 import {MatTreeFlatDataSource, MatTreeFlattener} from '@angular/material/tree';
 import {BucketBrowserService, TodoItemFlatNode, TodoItemNode} from '../../../core/services/bucket-browser.service';
+import {Logger} from 'codelyzer/util/logger';
 
 
 class ChecklistDatabase {
 }
-
 /**
  * @title Tree with checkboxes
  */
@@ -17,7 +17,12 @@ class ChecklistDatabase {
   templateUrl: './folder-tree.component.html',
   styleUrls: ['./folder-tree.component.scss']
 })
-export class FolderTreeComponent {
+export class FolderTreeComponent implements AfterViewInit{
+
+  @Output() showFolderContent: EventEmitter<any> = new EventEmitter();
+
+  path = [];
+  selectedFolder: TodoItemFlatNode;
   /** Map from flat node to nested node. This helps us finding the nested node to be modified */
   flatNodeMap = new Map<TodoItemFlatNode, TodoItemNode>();
 
@@ -29,7 +34,9 @@ export class FolderTreeComponent {
 
   /** The new item's name */
   newItemName = '';
+  isOpened = {
 
+  };
   treeControl: FlatTreeControl<TodoItemFlatNode>;
 
   treeFlattener: MatTreeFlattener<TodoItemNode, TodoItemFlatNode>;
@@ -42,14 +49,20 @@ export class FolderTreeComponent {
   constructor(private bucketBrowserService: BucketBrowserService) {
     this.treeFlattener = new MatTreeFlattener(this.transformer, this.getLevel,
       this.isExpandable, this.getChildren);
+
     this.treeControl = new FlatTreeControl<TodoItemFlatNode>(this.getLevel, this.isExpandable);
     this.dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
 
     bucketBrowserService.dataChange.subscribe(data => {
       this.dataSource.data = data;
+      console.log(this.dataSource);
     });
   }
 
+  // ngAfterViewInit(): void {
+  //
+  // }
+
   getLevel = (node: TodoItemFlatNode) => node.level;
 
   isExpandable = (node: TodoItemFlatNode) => node.expandable;
@@ -76,6 +89,46 @@ export class FolderTreeComponent {
     return flatNode;
   }
 
+
+  ngAfterViewInit() {
+    const subject = this.dataSource._flattenedData;
+    let firstSelected;
+    subject.subscribe((data) => {
+      firstSelected = data[0];
+      // this.selectedFolder = ;
+      this.treeControl.expand(data[0]);
+    });
+    this.selectedFolder = firstSelected;
+  }
+
+  showItem(el) {
+    this.treeControl.expand(el);
+    this.selectedFolder = el;
+    const path = this.getpath(el);
+    this.path = [];
+    const data = {
+      flatNode: el,
+      element: this.flatNodeMap.get(el),
+      element1: el,
+      path: path.join('/')
+    };
+    console.log(data);
+    this.showFolderContent.emit(data);
+  }
+
+  getpath(el) {
+    if (this.path.length === 0) {
+      this.path.unshift(el.item);
+    }
+    if (this.getParentNode(el) !== null) {
+      this.path.unshift(this.getParentNode(el).item);
+      this.getpath(this.getParentNode(el));
+    }
+    return this.path;
+  }
+
+
+
   /** Whether all the descendants of the node are selected. */
   descendantsAllSelected(node: TodoItemFlatNode): boolean {
     const descendants = this.treeControl.getDescendants(node);
@@ -95,17 +148,17 @@ export class FolderTreeComponent {
   /** Toggle the to-do item selection. Select/deselect all the descendants node */
   todoItemSelectionToggle(node: TodoItemFlatNode): void {
     this.checklistSelection.toggle(node);
-    const descendants = this.treeControl.getDescendants(node);
-    this.checklistSelection.isSelected(node)
-      ? this.checklistSelection.select(...descendants)
-      : this.checklistSelection.deselect(...descendants);
-
-    // Force update for the parent
-    descendants.every(child =>
-      this.checklistSelection.isSelected(child)
-    );
-    this.checkAllParentsSelection(node);
-  }
+  const descendants = this.treeControl.getDescendants(node);
+  this.checklistSelection.isSelected(node)
+? this.checklistSelection.select(...descendants)
+    : this.checklistSelection.deselect(...descendants);
+
+  // Force update for the parent
+  descendants.every(child =>
+  this.checklistSelection.isSelected(child)
+);
+  this.checkAllParentsSelection(node);
+}
 
   /** Toggle a leaf to-do item selection. Check all the parents to see if they changed */
   todoLeafItemSelectionToggle(node: TodoItemFlatNode): void {
@@ -157,15 +210,18 @@ export class FolderTreeComponent {
   }
 
   /** Select the category so we can insert the new item. */
-  addNewItem(node: TodoItemFlatNode) {
+  addNewItem(node: TodoItemFlatNode, name, isFile) {
+    console.log(node);
     const parentNode = this.flatNodeMap.get(node);
-    this.bucketBrowserService.insertItem(parentNode!, '');
+    this.bucketBrowserService.insertItem(parentNode!, name, isFile);
     this.treeControl.expand(node);
   }
 
   /** Save the node to database */
   saveNode(node: TodoItemFlatNode, itemValue: string) {
     const nestedNode = this.flatNodeMap.get(node);
+    console.log(nestedNode);
+    console.log(itemValue);
     this.bucketBrowserService.updateItem(nestedNode!, itemValue);
   }
 }


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