[AAE-3110] Move upload button inside the node selector dialog (#5901)

* Open select dialog on all types, fetch destination folder from a relative path

* Dialog UI refactor, multiple upload from local

* Fix document list should automatically reload after upload

* Remove not used ViewChild

* Fix imports, read destination folder from form field

* support different alias

* Remove not needed property, reuse selection mode

* Remove unused methods

* Fix unit tests

* * Added unit tests
* Fixed failing unit tests

* * Added unit for upload button
* Skipped failing e2e

* * Removed process-storage related code

* * Removed unncessory model and code
*

* * Removed contentHost from formCloud model

* * Skiped content-services e2e

* Skip failing process e2e related to attachment

Co-authored-by: sivakumar414ram <siva.kumar@muraai.com>
Co-authored-by: maurizio vitale <maurizio.vitale@alfresco.com>
This commit is contained in:
arditdomi
2020-07-31 07:38:58 +02:00
committed by GitHub
parent 1e692252a5
commit d553c71b1e
31 changed files with 338 additions and 432 deletions

View File

@@ -71,7 +71,7 @@
[allowDropFiles]="false"
[sorting]="'server'"
[where]="where"
(folderChange)="onFolderChange()"
(folderChange)="onFolderChange($event)"
(ready)="onFolderLoaded()"
(nodeSelected)="onCurrentSelection($event)"
data-automation-id="content-node-selector-document-list">

View File

@@ -29,7 +29,7 @@ import { DocumentListService } from '../document-list/services/document-list.ser
import { DocumentListComponent } from '../document-list/components/document-list.component';
import { DropdownSitesComponent } from '../site-dropdown/sites-dropdown.component';
import { CustomResourcesService } from '../document-list/services/custom-resources.service';
import { ShareDataRow } from '../document-list';
import { NodeEntryEvent, ShareDataRow } from '../document-list';
import { TranslateModule } from '@ngx-translate/core';
const ONE_FOLDER_RESULT = {
@@ -59,6 +59,8 @@ describe('ContentNodeSelectorComponent', () => {
let sitesService: SitesService;
let searchSpy: jasmine.Spy;
let cnSearchSpy: jasmine.Spy;
const fakeNodeEntry = new Node({ id: 'fakeId' });
const nodeEntryEvent = new NodeEntryEvent(fakeNodeEntry);
let _observer: Observer<NodePaging>;
@@ -271,7 +273,7 @@ describe('ContentNodeSelectorComponent', () => {
tick(debounceSearch);
component.onFolderChange();
component.onFolderChange(nodeEntryEvent);
fixture.detectChanges();
const breadcrumb = fixture.debugElement.query(By.directive(DropdownBreadcrumbComponent));
expect(breadcrumb).not.toBeNull();
@@ -309,7 +311,7 @@ describe('ContentNodeSelectorComponent', () => {
respondWithSearchResults(ONE_FOLDER_RESULT);
fixture.detectChanges();
component.onFolderChange();
component.onFolderChange(nodeEntryEvent);
fixture.detectChanges();
const chosenNode = <Node> { path: { elements: [] } };
@@ -700,7 +702,7 @@ describe('ContentNodeSelectorComponent', () => {
tick();
fixture.detectChanges();
component.onFolderChange();
component.onFolderChange(nodeEntryEvent);
fixture.detectChanges();
expect(component.clearSearch).toHaveBeenCalled();

View File

@@ -33,7 +33,7 @@ import { ImageResolver } from '../document-list/data/image-resolver.model';
import { ContentNodeSelectorService } from './content-node-selector.service';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { CustomResourcesService } from '../document-list/services/custom-resources.service';
import { ShareDataRow } from '../document-list';
import { NodeEntryEvent, ShareDataRow } from '../document-list';
import { Subject } from 'rxjs';
export type ValidationFunction = (entry: Node) => boolean;
@@ -186,6 +186,10 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
@Output()
select: EventEmitter<Node[]> = new EventEmitter<Node[]>();
/** Emitted when the navigation changes. */
@Output()
navigationChange: EventEmitter<NodeEntryEvent> = new EventEmitter<NodeEntryEvent>();
/** Emitted when the select site changes. */
@Output()
siteChange: EventEmitter<string> = new EventEmitter<string>();
@@ -426,11 +430,12 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
/**
* Sets showingSearchResults state to be able to differentiate between search results or folder results
*/
onFolderChange(): void {
onFolderChange($event: NodeEntryEvent): void {
this.showingSearchResults = false;
this.infiniteScroll = false;
this.breadcrumbFolderTitle = null;
this.clearSearch();
this.navigationChange.emit($event);
}
/**

View File

@@ -36,4 +36,6 @@ export interface ContentNodeSelectorComponentData {
showSearch?: boolean;
showFilesInResult?: boolean;
showDropdownSiteList?: boolean;
showLocalUploadButton?: boolean;
multipleUpload?: boolean;
}

View File

@@ -21,21 +21,33 @@
[showDropdownSiteList]="data?.showDropdownSiteList"
[showFilesInResult]="data?.showFilesInResult"
(select)="onSelect($event)"
(siteChange)="onSiteChange($event)">
(siteChange)="onSiteChange($event)"
(navigationChange)="onNavigationChange($event)">
</adf-content-node-selector-panel>
</mat-dialog-content>
<mat-dialog-actions align="end">
<button
mat-button
(click)="close()"
data-automation-id="content-node-selector-actions-cancel">{{ 'NODE_SELECTOR.CANCEL' | translate }}
</button>
<mat-dialog-actions>
<div>
<adf-upload-button
*ngIf="data?.showLocalUploadButton"
[staticTitle]="'FORM.FIELD.UPLOAD' | translate "
[multipleFiles]="isMultipleSelection()"
[rootFolderId]="currentDirectoryId"
(error)="onError($event)">
</adf-upload-button>
</div>
<div>
<button
mat-button
(click)="close()"
data-automation-id="content-node-selector-actions-cancel">{{ 'NODE_SELECTOR.CANCEL' | translate }}
</button>
<button mat-button
[disabled]="!hasNodeSelected()"
class="adf-choose-action"
(click)="onClick()"
data-automation-id="content-node-selector-actions-choose">{{ buttonActionName | translate }}
</button>
<button mat-button
[disabled]="!chosenNode"
class="adf-choose-action"
(click)="onClick()"
data-automation-id="content-node-selector-actions-choose">{{ buttonActionName | translate }}
</button>
</div>
</mat-dialog-actions>

View File

@@ -36,7 +36,8 @@
padding: 8px;
background-color: mat-color($background, background);
display: flex;
justify-content: flex-end;
flex-direction: row;
justify-content: space-between;
color: mat-color($foreground, text, 0.72);
button {

View File

@@ -40,7 +40,8 @@ describe('ContentNodeSelectorDialogComponent', () => {
select: new EventEmitter<Node>(),
rowFilter: (shareDataRow: ShareDataRow) => shareDataRow.node.entry.name === 'impossible-name',
imageResolver: () => 'piccolo',
currentFolderId: 'cat-girl-nuku-nuku'
currentFolderId: 'cat-girl-nuku-nuku',
showLocalUploadButton: true
};
setupTestBed({
@@ -175,4 +176,22 @@ describe('ContentNodeSelectorDialogComponent', () => {
expect(titleElement.nativeElement.innerText).toBe('NODE_SELECTOR.CHOOSE_ITEM');
});
});
describe('Upload button', () => {
it('should be able to show upload button if showLocalUploadButton set to true', () => {
const adfUploadButton = fixture.debugElement.query(By.css('adf-upload-button'));
expect(adfUploadButton).not.toBeNull();
expect(adfUploadButton.nativeElement.innerText).toEqual('file_uploadFORM.FIELD.UPLOAD');
});
it('should not be able to show upload button if showLocalUploadButton set to false', () => {
component.data.showLocalUploadButton = false;
fixture.detectChanges();
const adfUploadButton = fixture.debugElement.query(By.css('adf-upload-button span'));
expect(adfUploadButton).toBeNull();
});
});
});

View File

@@ -17,9 +17,10 @@
import { Component, Inject, ViewEncapsulation } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { TranslationService } from '@alfresco/adf-core';
import { TranslationService, NotificationService } from '@alfresco/adf-core';
import { Node } from '@alfresco/js-api';
import { ContentNodeSelectorComponentData } from './content-node-selector.component-data.interface';
import { NodeEntryEvent } from '../document-list/components/node.event';
@Component({
selector: 'adf-content-node-selector',
@@ -28,17 +29,19 @@ import { ContentNodeSelectorComponentData } from './content-node-selector.compon
encapsulation: ViewEncapsulation.None
})
export class ContentNodeSelectorComponent {
title: string;
action: string;
buttonActionName: string;
chosenNode: Node[];
currentDirectoryId: string;
constructor(private translation: TranslationService,
private notificationService: NotificationService,
@Inject(MAT_DIALOG_DATA) public data: ContentNodeSelectorComponentData) {
this.action = data.actionName ? data.actionName.toUpperCase() : 'CHOOSE';
this.buttonActionName = `NODE_SELECTOR.${this.action}`;
this.title = data.title;
this.currentDirectoryId = data.currentFolderId;
}
close() {
@@ -49,14 +52,14 @@ export class ContentNodeSelectorComponent {
this.chosenNode = nodeList;
}
hasNodeSelected(): boolean {
return this.chosenNode?.length > 0;
}
onSiteChange(siteTitle: string) {
this.updateTitle(siteTitle);
}
onNavigationChange(pathElement: NodeEntryEvent) {
this.currentDirectoryId = pathElement.value.id;
}
onClick(): void {
this.data.select.next(this.chosenNode);
this.data.select.complete();
@@ -71,4 +74,12 @@ export class ContentNodeSelectorComponent {
getTitleTranslation(action: string, name: string): string {
return this.translation.instant(`NODE_SELECTOR.${action}_ITEM`, { name: this.translation.instant(name) });
}
isMultipleSelection(): boolean {
return this.data.selectionMode === 'multiple';
}
onError(error) {
this.notificationService.showError(error);
}
}

View File

@@ -27,6 +27,7 @@ import { BreadcrumbModule } from '../breadcrumb/breadcrumb.module';
import { CoreModule } from '@alfresco/adf-core';
import { DocumentListModule } from '../document-list/document-list.module';
import { NameLocationCellComponent } from './name-location-cell/name-location-cell.component';
import { UploadModule } from '../upload/upload.module';
@NgModule({
imports: [
@@ -37,7 +38,8 @@ import { NameLocationCellComponent } from './name-location-cell/name-location-ce
MaterialModule,
SitesDropdownModule,
BreadcrumbModule,
DocumentListModule
DocumentListModule,
UploadModule
],
exports: [
ContentNodeSelectorPanelComponent,

View File

@@ -45,7 +45,8 @@ import {
RequestPaginationModel,
AlfrescoApiService,
UserPreferenceValues,
LockService
LockService,
UploadService
} from '@alfresco/adf-core';
import { Node, NodeEntry, NodePaging, Pagination } from '@alfresco/js-api';
@@ -60,7 +61,7 @@ import { NavigableComponentInterface } from '../../breadcrumb/navigable-componen
import { RowFilter } from '../data/row-filter.model';
import { DocumentListService } from '../services/document-list.service';
import { DocumentLoaderNode } from '../models/document-folder.model';
import { takeUntil } from 'rxjs/operators';
import { debounceTime, takeUntil } from 'rxjs/operators';
@Component({
selector: 'adf-document-list',
@@ -337,6 +338,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
private appConfig: AppConfigService,
private userPreferencesService: UserPreferencesService,
private contentService: ContentService,
private uploadService: UploadService,
private thumbnailService: ThumbnailService,
private alfrescoApiService: AlfrescoApiService,
private lockService: LockService) {
@@ -346,6 +348,18 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
.subscribe(pagSize => {
this.maxItems = this._pagination.maxItems = pagSize;
});
this.uploadService.fileUploadComplete
.pipe(
debounceTime(300),
takeUntil(this.onDestroy$))
.subscribe(() => this.reload());
this.uploadService.fileUploadDeleted
.pipe(
debounceTime(300),
takeUntil(this.onDestroy$))
.subscribe(() => this.reload());
}
getContextActions(node: NodeEntry) {

View File

@@ -80,6 +80,7 @@
"NODE_SELECTOR": {
"CANCEL": "Cancel",
"CHOOSE": "Select",
"ATTACH": "Attach",
"CHOOSE_ITEM": "Select content to attach from '{{ name }}'",
"COPY": "Copy",
"COPY_ITEM": "Copy '{{ name }}' to...",

View File

@@ -5,7 +5,7 @@
<!--Single Files Upload-->
<button *ngIf="!multipleFiles"
[disabled]="isButtonDisabled()"
mat-raised-button color="primary"
mat-button
(click)="uploadSingleFile.click()">
<mat-icon>file_upload</mat-icon>
<span id="upload-single-file-label"
@@ -27,7 +27,7 @@
<!--Multiple Files Upload-->
<button *ngIf="multipleFiles"
[disabled]="isButtonDisabled()"
mat-raised-button color="primary"
mat-button
(click)="uploadMultipleFiles.click()">
<mat-icon>file_upload</mat-icon>
@@ -53,7 +53,7 @@
<div *ngIf="uploadFolders">
<button
[disabled]="isButtonDisabled()"
mat-raised-button color="primary"
mat-button
(click)="uploadFolders.click()">
<mat-icon>file_upload</mat-icon>
<span id="uploadFolder-label"