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/06 15:54:08 UTC
[incubator-dlab] 01/01: [DLAB-1773]: Fixed bugs,
added possibility save empty folder, multi-file selecting/deleting
This is an automated email from the ASF dual-hosted git repository.
dgnatyshyn pushed a commit to branch DLAB-1773
in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git
commit 64908c130805a66b82282b0140ef8fcd774cdc03
Author: Dmytro Gnatyshyn <di...@ukr.net>
AuthorDate: Wed May 6 18:53:38 2020 +0300
[DLAB-1773]: Fixed bugs, added possibility save empty folder, multi-file selecting/deleting
---
.../app/core/services/bucket-browser.service.ts | 8 +-
.../bucket-browser/bucket-browser.component.html | 9 +--
.../bucket-browser/bucket-browser.component.scss | 9 ++-
.../bucket-browser/bucket-browser.component.ts | 86 ++++++++++------------
.../bucket-confirmation-dialog.component.html | 66 +++++++++++++++++
.../bucket-confirmation-dialog.component.scss | 79 ++++++++++++++++++++
.../bucket-confirmation-dialog.component.ts | 46 ++++++++++++
.../folder-tree/folder-tree.component.html | 16 +++-
.../folder-tree/folder-tree.component.ts | 36 +++++++--
.../webapp/src/app/resources/resources.module.ts | 6 +-
10 files changed, 288 insertions(+), 73 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 c251ed9..54fc3a1 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
@@ -8,7 +8,7 @@ export class TodoItemNode {
children: TodoItemNode[];
item: string;
id: string;
- size: number;
+ object: any;
}
export class TodoItemFlatNode {
@@ -49,13 +49,11 @@ export class BucketBrowserService {
catchError(ErrorUtils.handleServiceError));
}
- public deleteFile(data) {
- const url = JSON.stringify(data);
+ public deleteFile(data, url) {
return this.applicationServiceFacade
- .buildDeleteFileFromBucket(url)
+ .buildDeleteFileFromBucket(data, url)
.pipe(
map(response => response),
catchError(ErrorUtils.handleServiceError));
}
-
}
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 841b7c6..3d034f6 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
@@ -60,14 +60,12 @@
type="button" class="butt"
mat-raised-button
(click)="fileAction('download')"
- [disabled]="!selected?.length || !this.bucketStatus.download || allDisable"
+ [disabled]=" !selected?.length || this.selectedItems?.length > 1 || !this.bucketStatus.download || allDisable"
>
Download
</button>
</span>
-
-<!-- <button type="button" class="butt" mat-raised-button [disabled]="this.addedFiles.length === 0" (click)="uploadNewFile()">Upload</button>-->
</div>
<p class="path"><span>Bucket path:</span><span class="url ellipsis"> {{path}}</span></p>
<div class="backet-wrapper" [ngClass]="{'added-upload': addedFiles.length}" id="scrolling">
@@ -76,6 +74,7 @@
(showFolderContent)=onFolderClick($event)
(disableAll) = dissableAll($event)
[folders] = folders
+ [endpoint] = endpoint
> </dlab-folder-tree>
</div>
<div class="directory">
@@ -108,8 +107,8 @@
</span>
<span class="item-name name-wrap" [ngClass]="{'removed-checkbox': !this.bucketStatus.download && !this.bucketStatus.delete}">{{file.item}}</span>
</div>
- <div class="size">{{file.size?.size}}</div>
- <div class="date" *ngIf="!file.isDownloading">{{file.size?.lastModifiedDate }}</div>
+ <div class="size">{{file.object?.size}}</div>
+ <div class="date" *ngIf="!file.isDownloading">{{file.object?.lastModifiedDate }}</div>
<div class="progress-wrapper" *ngIf="file.isDownloading">
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
</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 bb7029d..ad605bd 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
@@ -82,12 +82,14 @@
border: 2px solid rgba(0,0,0,.12);
border-radius: 5px;
display: flex;
+ width: 100%;
&.added-upload{
height: 37vh;
}
.navigation{
+ width: 33.3%;
flex: 1;
border-right: 2px solid rgba(0,0,0,.12);
height: 100%;
@@ -106,6 +108,7 @@
}
.directory{
+ width: 66.7%;
max-height: 100%;
flex: 2;
font-size: 14px;
@@ -313,7 +316,7 @@ input[type='file'] {
background-color: white;
min-height: 100px;
color: black;
-
+
.upload-header{
padding-left: 8px;
background: #f6fafe;
@@ -331,7 +334,7 @@ input[type='file'] {
font-size: 14px;
background: #f6fafe;
}
-
+
.close{
position: absolute;
top: 0;
@@ -419,8 +422,6 @@ input[type='file'] {
}
}
-
-
@media only screen and (max-height: 840px) {
.backet-wrapper {
height: 45vh;
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 22f70c2..7f1c8d5 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
@@ -27,6 +27,8 @@ import {FolderTreeComponent} from './folder-tree/folder-tree.component';
import {BucketBrowserService, TodoItemNode} from '../../core/services/bucket-browser.service';
import {FileUtils} from '../../core/util';
import {BucketDataService} from './bucket-data.service';
+import {ConfirmationDialogComponent, ConfirmationDialogType} from '../../shared/modal-dialog/confirmation-dialog';
+import {BucketConfirmationDialogComponent} from './bucket-confirmation-dialog/bucket-confirmation-dialog.component';
@Component({
selector: 'dlab-bucket-browser',
@@ -46,10 +48,10 @@ export class BucketBrowserComponent implements OnInit {
public selectedFolder: any;
public selectedFolderForAction: any;
public selected: any[];
- private uploadForm: FormGroup;
public bucketStatus;
public allDisable: boolean;
public folders: any[];
+ private selectedItems;
constructor(
@@ -61,7 +63,6 @@ export class BucketBrowserComponent implements OnInit {
private _fb: FormBuilder,
private bucketBrowserService: BucketBrowserService,
private bucketDataService: BucketDataService,
- private formBuilder: FormBuilder
) {
}
@@ -70,9 +71,6 @@ export class BucketBrowserComponent implements OnInit {
this.bucketDataService.refreshBucketdata(this.data.bucket, this.data.endpoint);
this.endpoint = this.data.endpoint;
this.bucketStatus = this.data.bucketStatus;
- this.uploadForm = this.formBuilder.group({
- file: ['']
- });
}
public showItem(item) {
@@ -82,13 +80,11 @@ export class BucketBrowserComponent implements OnInit {
public handleFileInput(event) {
if (event.target.files.length > 0) {
- const file = event.target.files[0];
- this.uploadForm.get('file').setValue(file);
- const newAddedFiles = Object['values'](event.target.files).map(v => (
- {name: v['name'], file: file, 'size': (v['size'] / 1048576).toFixed(2), path: this.path, isUploading: false, uploaded: false, errorUploading: false}));
+ const newAddedFiles = Object['values'](event.target.files).map(file => (
+ {name: file['name'], file: file, 'size': (file['size'] / 1048576).toFixed(2), path: this.path, isUploading: false, uploaded: false, errorUploading: false}));
this.addedFiles = [...this.addedFiles, ...newAddedFiles];
}
- // event.target.value = null;
+ event.target.value = '';
}
public closeUploadWindow() {
@@ -99,25 +95,10 @@ export class BucketBrowserComponent implements OnInit {
public toggleSelectedFile(file, type) {
- // remove if when will be possible download several files
- if (!file.isSelected || !file.isFolderSelected) {
- this.folderItems.forEach(item => item.isSelected = false);
- this.folderItems.forEach(item => item.isFolderSelected = false);
- }
- if (type === 'file') {
- file.isSelected = !file.isSelected;
- this.selected = this.folderItems.filter(item => item.isSelected);
- this.selectedFolderForAction = this.folderItems.filter(item => item.isFolderSelected);
- }
-
- if (type === 'folder') {
- file.isFolderSelected = !file.isFolderSelected;
- this.selected = this.folderItems.filter(item => item.isSelected);
- this.selectedFolderForAction = this.folderItems.filter(item => item.isFolderSelected);
- }
-
- console.log(this.selectedFolderForAction, this.selected );
-
+ type === 'file' ? file.isSelected = !file.isSelected : file.isFolderSelected = !file.isFolderSelected;
+ this.selected = this.folderItems.filter(item => item.isSelected);
+ this.selectedFolderForAction = this.folderItems.filter(item => item.isFolderSelected);
+ this.selectedItems = [...this.selected, ...this.selectedFolderForAction];
}
filesPicked(files) {
@@ -186,34 +167,47 @@ export class BucketBrowserComponent implements OnInit {
public fileAction(action) {
// this.selected = this.folderItems.filter(item => item.isSelected);
- const selected = this.folderItems.filter(item => item.isSelected)[0];
- const folderSelected = this.folderItems.filter(item => item.isFolderSelected)[0];
- if (!selected) {
- this.toastr.error('Folder deleting not working yet!', 'Oops!');
- return;
- }
- const path = encodeURIComponent(`${this.pathInsideBucket}${this.selected[0].item}`);
+ const selected = this.folderItems.filter(item => item.isSelected);
+ const folderSelected = this.folderItems.filter(item => item.isFolderSelected);
+
if (action === 'download') {
- selected['isDownloading'] = true;
+ const path = encodeURIComponent(`${this.pathInsideBucket}${this.selected[0].item}`);
+ selected[0]['isDownloading'] = true;
this.bucketBrowserService.downloadFile(`/${this.bucketName}/object/${path}/endpoint/${this.endpoint}/download`)
.subscribe(data => {
- FileUtils.downloadBigFiles(data, selected.item);
- selected['isDownloading'] = false;
+ FileUtils.downloadBigFiles(data, selected[0].item);
+ selected[0]['isDownloading'] = false;
this.folderItems.forEach(item => item.isSelected = false);
}, error => {
this.toastr.error(error.message || 'File downloading error!', 'Oops!');
- selected['isDownloading'] = false;
+ selected[0]['isDownloading'] = false;
}
);
}
if (action === 'delete') {
- this.bucketBrowserService.deleteFile(`/${this.bucketName}/object/${path}/endpoint/${this.endpoint}`).subscribe(() => {
- this.bucketDataService.refreshBucketdata(this.data.bucket, this.data.endpoint);
- this.toastr.success('File successfully deleted!', 'Success!');
- this.folderItems.forEach(item => item.isSelected = false);
- }, error => this.toastr.error(error.message || 'File deleting error!', 'Oops!')
- );
+ const itemsForDeleting = [...folderSelected, ...selected];
+ const objects = itemsForDeleting.map(obj => obj.object.object);
+ const dataForServer = [];
+ objects.forEach(object => {
+ dataForServer.push(...this.bucketDataService.serverData.map(v => v.object).filter(v => v.indexOf(object) === 0));
+ });
+ const url = `/${this.bucketName}/endpoint/${this.endpoint}/delete`;
+ console.log(dataForServer);
+ this.dialog.open(BucketConfirmationDialogComponent, {data: {items: itemsForDeleting} , width: '550px'})
+ .afterClosed().subscribe((res) => {
+ !res && this.clearSelection();
+ res && this.bucketBrowserService.deleteFile(dataForServer, url).subscribe(() => {
+ this.bucketDataService.refreshBucketdata(this.data.bucket, this.data.endpoint);
+ this.toastr.success('File successfully deleted!', 'Success!');
+ this.clearSelection();
+ }, error => {
+ this.toastr.error(error.message || 'File deleting error!', 'Oops!');
+ this.clearSelection();
+ });
+ });
+
+
}
}
}
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
new file mode 100644
index 0000000..aaa707e
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-confirmation-dialog/bucket-confirmation-dialog.component.html
@@ -0,0 +1,66 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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 id="dialog-box" class="confirmation-dialog">
+ <header class="dialog-header">
+ <h4 class="modal-title">
+ <span>
+ <span>Delete objects</span>
+ </span>
+ </h4>
+ <button type="button" class="close" (click)="dialogRef.close()">×</button>
+ </header>
+ <div class="dialog-content">
+ <div class="content-box">
+<!-- <p *ngIf="data.type !== 4" class="info text-center">{{ model.title }}</p>-->
+<!-- <div *ngIf="data.type === 4" class="text-center m-bot-20">-->
+<!-- <h3 class="strong">Group data will be updated.</h3>-->
+<!-- </div>-->
+<!-- <p *ngIf="data.type === 4 && data.notebook.length" class="text-center delete-user">User<span *ngIf="data.notebook.length>1">s</span> <span class="strong"> {{data.notebook.join(', ')}} </span>will be deleted from this group.</p>-->
+<!--<!– All <span *ngIf="data.notebook.length===1">his</span><span *ngIf="data.notebook.length>1">their</span> resources authorized within this group will be terminated.–>-->
+ <mat-list class="resources">
+ <mat-list-item class="list-header">
+ <div class="object">Objects</div>
+ <div class="size">Size</div>
+ </mat-list-item>
+ <div class="scrolling-content" id="scrolling">
+ <mat-list-item *ngFor="let object of data.items">
+ <div class="object">
+ <span *ngIf="object['children']"><i class="material-icons folder-icon" >folder</i></span>
+ <div>{{object['item']}}</div>
+ </div>
+ <div class="size">{{object['children'] ? '-' : object['object'].size}}</div>
+ </mat-list-item>
+ </div>
+ </mat-list>
+ <div mat-dialog-content class="bottom-message" >
+ <span class="confirm-message" *ngIf="isFolders">All affected objects will be deleted.</span>
+ <span class="confirm-message" *ngIf="!isFolders">These objects will be deleted.</span>
+ </div>
+
+ <div class="text-center m-top-20">
+ <p class="strong">Do you want to proceed?</p>
+ </div>
+ <div class="text-center m-top-20">
+ <button mat-raised-button type="button" class="butt action" (click)="dialogRef.close()">No</button>
+ <button mat-raised-button type="button" class="butt butt-success action" (click)="dialogRef.close(true)">Yes</button>
+ </div>
+ </div>
+ </div>
+</div>
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
new file mode 100644
index 0000000..75eb0fe
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-confirmation-dialog/bucket-confirmation-dialog.component.scss
@@ -0,0 +1,79 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+.confirmation-dialog {
+
+ .folder-icon{
+ color: rgb(232, 232, 232);
+ margin-right: 5px;
+ }
+ h3{
+ margin-bottom: 20px;
+ }
+ color: #718ba6;
+ p {
+ font-size: 14px;
+ font-weight: 600;
+ margin: 0;
+ margin-bottom: 10px;
+ &.info {
+ font-weight: 500;
+ }
+ }
+ .resources {
+ .object {
+ width: 70%;
+ display: flex;
+ align-items: center;
+ }
+
+ .size {
+ width: 30%;
+ }
+ .scrolling-content {
+ max-height: 200px;
+ overflow-y: auto;
+ }
+ }
+ .empty-list {
+ display: flex;
+ width: 100%;
+ justify-content: center;
+ color: #35afd5;
+ padding: 15px;
+ }
+
+ .list-header {
+ border-top: 1px solid #edf1f5;
+ border-bottom: 1px solid #edf1f5;
+ color: #577289;
+ width: 100%;
+ }
+
+ .bottom-message{
+ padding-top: 15px;
+ text-align: center;
+ .confirm-message{
+ color: #ef5c4b;
+ font-size: 13px;
+ min-height: 18px;
+ text-align: center;
+ padding-top: 20px}
+ }
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-confirmation-dialog/bucket-confirmation-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-confirmation-dialog/bucket-confirmation-dialog.component.ts
new file mode 100644
index 0000000..9d9c80c
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-confirmation-dialog/bucket-confirmation-dialog.component.ts
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import { Component, OnInit, Inject, Input, Output, EventEmitter, ViewEncapsulation } from '@angular/core';
+import { ToastrService } from 'ngx-toastr';
+import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
+
+@Component({
+ selector: 'bucket-confirmation-dialog',
+ templateUrl: 'bucket-confirmation-dialog.component.html',
+ styleUrls: ['./bucket-confirmation-dialog.component.scss'],
+ encapsulation: ViewEncapsulation.None
+})
+
+export class BucketConfirmationDialogComponent implements OnInit {
+ isFolders: boolean = false
+ constructor(
+ @Inject(MAT_DIALOG_DATA) public data: any,
+ public dialogRef: MatDialogRef<BucketConfirmationDialogComponent>,
+ public toastr: ToastrService
+ ) {
+
+ }
+
+ ngOnInit() {
+ this.isFolders = !!this.data.items.filter(v => v.children).length;
+ }
+
+
+}
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 7d79751..5aec2e8 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,5 +1,5 @@
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
- <mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle matTreeNodePadding [ngStyle]="{'display': 'none'}">
+ <mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle matTreeNodePadding matTreeNodePaddingIndent="20" [ngStyle]="{'display': 'none'}">
<button mat-icon-button disabled></button>
<!-- <mat-checkbox class="checklist-leaf-node"-->
<!-- [checked]="checklistSelection.isSelected(node)"-->
@@ -7,7 +7,7 @@
{{node.item}}
</mat-tree-node>
- <mat-tree-node *matTreeNodeDef="let node; when: hasNoContent" matTreeNodePadding class="input-node">
+ <mat-tree-node *matTreeNodeDef="let node; when: hasNoContent" matTreeNodePadding matTreeNodePaddingIndent="20" class="input-node">
<form class="add-folder-form">
<mat-form-field>
<mat-label>New folder</mat-label>
@@ -23,12 +23,20 @@
</mat-error>
</mat-form-field>
- <button (click)="saveNode(node, itemValue.value)" [ngClass]="{'check': folderFormControl.valid && folderFormControl.dirty}" mat-icon-button class="btn action-btn" [disabled]="!folderFormControl.valid || !folderFormControl.dirty"><span><i class="material-icons ">check</i></span></button>
+ <button (click)="saveNode(node, itemValue.value)"
+ [ngClass]="{'check': folderFormControl.valid && folderFormControl.dirty && !folderCreating}"
+ mat-icon-button class="btn action-btn"
+ [disabled]="!folderFormControl.valid || !folderFormControl.dirty"
+ matTooltip="Please wait! Folder is creating."
+ [matTooltipDisabled]="!folderCreating"
+ matTooltipPosition="above"
+ >
+ <span><i class="material-icons ">check</i></span></button>
<button (click)="removeItem(node)" mat-icon-button class="btn close action-btn"><span ><i class="material-icons ">close</i></span></button>
</form>
</mat-tree-node>
- <mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding>
+ <mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding matTreeNodePaddingIndent="20">
<button mat-icon-button matTreeNodeToggle
[attr.aria-label]="'toggle ' + node.filename">
<mat-icon class="mat-icon-rtl-mirror" [ngClass]="{'active-item': selectedFolder === node}">
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 4aeab2b..ff1ae69 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
@@ -8,6 +8,7 @@ import {Subscription} from 'rxjs';
import {FormControl, FormGroupDirective, NgForm, Validators} from '@angular/forms';
import {ErrorStateMatcher} from '@angular/material/core';
import {PATTERNS} from '../../../core/util';
+import {ToastrService} from 'ngx-toastr';
export class MyErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
@@ -27,6 +28,7 @@ export class FolderTreeComponent implements OnInit, OnDestroy {
@Output() showFolderContent: EventEmitter<any> = new EventEmitter();
@Output() disableAll: EventEmitter<any> = new EventEmitter();
@Input() folders;
+ @Input() endpoint;
private folderTreeSubs;
private path = [];
@@ -34,7 +36,7 @@ export class FolderTreeComponent implements OnInit, OnDestroy {
private flatNodeMap = new Map<TodoItemFlatNode, TodoItemNode>();
private nestedNodeMap = new Map<TodoItemNode, TodoItemFlatNode>();
private selectedParent: TodoItemFlatNode | null = null;
- private newItemName = '';
+ private folderCreating = false;
private subscriptions: Subscription = new Subscription();
public treeControl: FlatTreeControl<TodoItemFlatNode>;
private treeFlattener: MatTreeFlattener<TodoItemNode, TodoItemFlatNode>;
@@ -44,6 +46,7 @@ export class FolderTreeComponent implements OnInit, OnDestroy {
private checklistSelection = new SelectionModel<TodoItemFlatNode>(true /* multiple */);
constructor(
+ public toastr: ToastrService,
private bucketBrowserService: BucketBrowserService,
private bucketDataService: BucketDataService,
) {
@@ -226,6 +229,8 @@ 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);
}
@@ -237,14 +242,31 @@ export class FolderTreeComponent implements OnInit, OnDestroy {
}
private saveNode(node: TodoItemFlatNode, itemValue: string) {
- const nestedNode = this.flatNodeMap.get(node);
- this.bucketDataService.updateItem(nestedNode!, itemValue);
- this.resetForm();
- this.folderFormControl.updateValueAndValidity();
- this.folderFormControl.markAsPristine();
+ this.folderCreating = true;
+ const parent = this.getParentNode(node);
+ const flatParent = this.flatNodeMap.get(parent);
+ const path = `${flatParent.object.object}${itemValue}/`;
+ const formData = new FormData();
+ formData.append('file', '');
+ formData.append('object', path);
+ formData.append('bucket', flatParent.object.bucket);
+ formData.append('endpoint', this.endpoint);
+ this.bucketBrowserService.uploadFile(formData)
+ .subscribe(() => {
+ this.bucketDataService.refreshBucketdata(flatParent.object.bucket, this.endpoint);
+ this.toastr.success('Folder successfully created!', 'Success!');
+ this.resetForm();
+ this.folderFormControl.updateValueAndValidity();
+ this.folderFormControl.markAsPristine();
+ this.folderCreating = false;
+ }, error => {
+ this.toastr.error(error.message || 'Folder creation error!', 'Oops!');
+ this.folderCreating = false;
+ }
+ );
}
- private resetForm(){
+ private resetForm() {
this.folderFormControl.setValue('');
this.folderFormControl.updateValueAndValidity();
this.folderFormControl.markAsPristine();
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 c87d12c..0da7bd4 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
@@ -31,6 +31,7 @@ import {BucketBrowserComponent} from './bucket-browser/bucket-browser.component'
import {FolderTreeComponent} from './bucket-browser/folder-tree/folder-tree.component';
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';
@NgModule({
@@ -48,9 +49,10 @@ import {BucketDataService} from './bucket-browser/bucket-data.service';
ManageUngitComponent,
ConfirmDeleteAccountDialog,
BucketBrowserComponent,
- FolderTreeComponent
+ FolderTreeComponent,
+ BucketConfirmationDialogComponent
],
- entryComponents: [ManageUngitComponent, ConfirmDeleteAccountDialog, BucketBrowserComponent, FolderTreeComponent],
+ entryComponents: [ManageUngitComponent, ConfirmDeleteAccountDialog, BucketBrowserComponent, FolderTreeComponent, BucketConfirmationDialogComponent],
providers: [BucketDataService],
exports: [ResourcesComponent]
})
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@dlab.apache.org
For additional commands, e-mail: commits-help@dlab.apache.org