Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AAE-3321] Select uploaded local files by default #6079

Merged
merged 8 commits into from
Sep 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 18 additions & 1 deletion demo-shell/src/app/components/files/files.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
[currentFolderId]="'-recent-'"
locationFormat="/files"
[display]="'gallery'"
[preselectNodes]="selectedNodes"
[showHeader]="false"
[maxItems]="5"
(preview)="showFile($event)"
Expand Down Expand Up @@ -221,6 +222,7 @@
[contentActions]="true"
[allowDropFiles]="allowDropFiles"
[selectionMode]="selectionMode"
[preselectNodes]="selectedNodes"
[multiselect]="multiselect"
[display]="displayMode"
[node]="nodeResult"
Expand Down Expand Up @@ -550,7 +552,7 @@ <h1>You don't have permissions</h1>
</section>

<section>
<mat-slide-toggle id="adf-multiple-upload-switch" [color]="'primary'" [(ngModel)]="multipleFileUpload">
<mat-slide-toggle id="adf-multiple-upload-switch" [color]="'primary'" (change)="onMultipleFilesUpload()" [(ngModel)]="multipleFileUpload" >
{{'DOCUMENT_LIST.MULTIPLE_FILE_UPLOAD' | translate}}
</mat-slide-toggle>
</section>
Expand Down Expand Up @@ -643,6 +645,21 @@ <h1>You don't have permissions</h1>
</mat-slide-toggle>
</section>

<section>
<mat-slide-toggle
color="primary" [(ngModel)]="preselectNodes" id="preselectNodes">
Preselect Nodes
</mat-slide-toggle>
</section>

<form class="example-form">
<mat-form-field *ngIf="preselectNodes" class="adf-preselect-nodes-input">
<input matInput
(input)="setPreselectNodes($event.target?.value)"
placeholder="NodeEntry[] => [{ entry: { isFile: true, id: 'node-id' }}, { entry: { isFile: true, id: 'node-id' }} ]">
</mat-form-field>
</form>

<h5>Upload</h5>
<section *ngIf="acceptedFilesTypeShow">
<mat-form-field floatPlaceholder="float">
Expand Down
4 changes: 4 additions & 0 deletions demo-shell/src/app/components/files/files.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,8 @@
justify-content: center;
}
}

.adf-preselect-nodes-input {
width: 100%;
}
}
69 changes: 66 additions & 3 deletions demo-shell/src/app/components/files/files.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ import { Location } from '@angular/common';

import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { MinimalNodeEntity, NodePaging, Pagination, MinimalNodeEntryEntity, SiteEntry, SearchEntry } from '@alfresco/js-api';
import { MinimalNodeEntity, NodePaging, Pagination, MinimalNodeEntryEntity, SiteEntry, SearchEntry, NodeEntry } from '@alfresco/js-api';
import {
AlfrescoApiService, AuthenticationService, AppConfigService, AppConfigValues, ContentService, TranslationService, FolderCreatedEvent, LogService, NotificationService,
UploadService, DataRow, UserPreferencesService,
PaginationComponent, FormValues, DisplayMode, ShowHeaderMode, InfinitePaginationComponent, HighlightDirective,
SharedLinksApiService,
FormRenderingService
FormRenderingService,
FileUploadEvent
} from '@alfresco/adf-core';

import {
Expand All @@ -47,7 +48,7 @@ import { VersionManagerDialogAdapterComponent } from './version-manager-dialog-a
import { MetadataDialogAdapterComponent } from './metadata-dialog-adapter.component';
import { Subject } from 'rxjs';
import { PreviewService } from '../../services/preview.service';
import { takeUntil } from 'rxjs/operators';
import { takeUntil, debounceTime, scan } from 'rxjs/operators';

const DEFAULT_FOLDER_TO_SHOW = '-my-';

Expand Down Expand Up @@ -208,6 +209,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
permissionsStyle: PermissionStyleModel[] = [];
infiniteScrolling: boolean;
stickyHeader: boolean;
preselectNodes: boolean;
warnOnMultipleUploads = false;
thumbnails = false;

Expand All @@ -216,6 +218,8 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
displayEmptyMetadata = false;
hyperlinkNavigation = false;

selectedNodes = [];

constructor(private notificationService: NotificationService,
private uploadService: UploadService,
private contentService: ContentService,
Expand Down Expand Up @@ -277,6 +281,33 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
});
}

this.uploadService.fileUploadComplete
.pipe(
debounceTime(300),
scan((files, currentFile) => [...files, currentFile], []),
takeUntil(this.onDestroy$)
)
.subscribe((value: any[]) => {
let selectedNodes: NodeEntry[] = [];

if (this.preselectNodes) {
if (value && value.length > 0 ) {
if (this.selectionMode === 'single') {
selectedNodes = [...[value[value.length - 1]].map((uploadedFile) => uploadedFile.data)];
} else {
selectedNodes = [...value.map((uploadedFile) => uploadedFile.data)];
}
this.selectedNodes = [...selectedNodes];
}
}

this.onFileUploadEvent(value[0]);
});

this.uploadService.fileUploadDeleted
.pipe(takeUntil(this.onDestroy$))
.subscribe(value => this.onFileUploadEvent(value));

this.contentService.folderCreated
.pipe(takeUntil(this.onDestroy$))
.subscribe(value => this.onFolderCreated(value));
Expand All @@ -302,6 +333,12 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
});
}

onFileUploadEvent(event: FileUploadEvent) {
if (event && event.file.options.parentId === this.documentList.currentFolderId) {
this.documentList.reload();
}
}

ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
Expand Down Expand Up @@ -669,4 +706,30 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
this.router.navigate([], { relativeTo: this.route, queryParams: objectFromMap });
}

setPreselectNodes(nodes: string) {
this.selectedNodes = this.getArrayFromString(nodes);
this.documentList.reload();
}

isStringArray(str: string): boolean {
try {
const result = JSON.parse(str);
return Array.isArray(result);
} catch (e) {
return false;
}
}

private getArrayFromString<T = any>(value: string): T[] {
if (this.isStringArray(value)) {
return JSON.parse(value);
} else {
return [];
}
}

onMultipleFilesUpload() {
this.selectedNodes = [];
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Displays the documents from a repository.
| navigationMode | `string` | | [User](../../../lib/core/pipes/user-initial.pipe.ts) interaction for folder navigation or file preview. Valid values are "click" and "dblclick". Default value: "dblclick" |
| node | [`NodePaging`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/content-rest-api/docs/NodePaging.md) | null | The Document list will show all the nodes contained in the [NodePaging](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/content-rest-api/docs/NodePaging.md) entity |
| permissionsStyle | [`PermissionStyleModel`](../../../lib/content-services/src/lib/document-list/models/permissions-style.model.ts)`[]` | \[] | Define a set of CSS styles to apply depending on the permission of the user on that node. See the [Permission Style model](../../../lib/content-services/src/lib/document-list/models/permissions-style.model.ts) page for further details and examples. |
| preselectNodes | [`NodeEntry`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/NodeEntry.md) `[]` | \[] | Array of nodes to preselect . |
| rowStyle | `string` | | The inline style to apply to every row. See the Angular NgStyle docs for more details and usage examples. |
| rowStyleClass | `string` | | The CSS class to apply to every row |
| selectionMode | `string` | "single" | Row selection mode. Can be null, `single` or `multiple`. For `multiple` mode, you can use Cmd (macOS) or Ctrl (Win) modifier key to toggle selection for multiple rows. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
adf-highlight-selector=".adf-name-location-cell-name"
[showHeader]="false"
[node]="nodePaging"
[preselectNodes]="preselectNodes"
[maxItems]="pageSize"
[rowFilter]="_rowFilter"
[imageResolver]="imageResolver"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@ import {
UserPreferenceValues,
InfinitePaginationComponent, PaginatedComponent,
NodesApiService,
SitesService
SitesService,
UploadService,
FileUploadCompleteEvent
} from '@alfresco/adf-core';
import { FormControl } from '@angular/forms';
import { Node, NodePaging, Pagination, SiteEntry, SitePaging, NodeEntry } from '@alfresco/js-api';
import { DocumentListComponent } from '../document-list/components/document-list.component';
import { RowFilter } from '../document-list/data/row-filter.model';
import { ImageResolver } from '../document-list/data/image-resolver.model';
import { ContentNodeSelectorService } from './content-node-selector.service';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { debounceTime, takeUntil, scan } from 'rxjs/operators';
import { CustomResourcesService } from '../document-list/services/custom-resources.service';
import { NodeEntryEvent, ShareDataRow } from '../document-list';
import { Subject } from 'rxjs';
Expand Down Expand Up @@ -222,13 +224,15 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
searchInput: FormControl = new FormControl();

target: PaginatedComponent;
preselectNodes: NodeEntry[] = [];

private onDestroy$ = new Subject<boolean>();

constructor(private contentNodeSelectorService: ContentNodeSelectorService,
private customResourcesService: CustomResourcesService,
private userPreferencesService: UserPreferencesService,
private nodesApiService: NodesApiService,
private uploadService: UploadService,
private sitesService: SitesService) {
}

Expand Down Expand Up @@ -267,13 +271,27 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {

this.breadcrumbTransform = this.breadcrumbTransform ? this.breadcrumbTransform : null;
this.isSelectionValid = this.isSelectionValid ? this.isSelectionValid : defaultValidation;
this.onFileUploadEvent();
}

ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}

private onFileUploadEvent() {
this.uploadService.fileUploadComplete
.pipe(
debounceTime(300),
scan((files, currentFile) => [...files, currentFile], []),
takeUntil(this.onDestroy$)
)
.subscribe((uploadedFiles: FileUploadCompleteEvent[]) => {
this.preselectNodes = this.getPreselectNodesBasedOnSelectionMode(uploadedFiles);
this.documentList.reload();
});
}

private getStartSite() {
this.nodesApiService.getNode(this.currentFolderId).subscribe((startNodeEntry) => {
this.startSiteGuid = this.sitesService.getSiteNameFromNodePath(startNodeEntry);
Expand Down Expand Up @@ -363,7 +381,7 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
this.searchTerm = '';
this.nodePaging = null;
this.pagination.maxItems = this.pageSize;
this.chosenNode = null;
this.resetChosenNode();
this.showingSearchResults = false;
}

Expand Down Expand Up @@ -434,6 +452,7 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
this.showingSearchResults = false;
this.infiniteScroll = false;
this.breadcrumbFolderTitle = null;
this.preselectNodes = [];
this.clearSearch();
this.navigationChange.emit($event);
}
Expand Down Expand Up @@ -476,8 +495,6 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
private attemptNodeSelection(entry: Node): void {
if (entry && this.isSelectionValid(entry)) {
this.chosenNode = [entry];
} else {
this.resetChosenNode();
}
}

Expand Down Expand Up @@ -510,4 +527,26 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
this.breadcrumbFolderTitle = null;
}
}

hasPreselectNodes(): boolean {
return this.preselectNodes && this.preselectNodes.length > 0;
}

isSingleSelectionMode(): boolean {
return this.selectionMode === 'single';
}

private getPreselectNodesBasedOnSelectionMode(uploadedFiles: FileUploadCompleteEvent[]): NodeEntry[] {
let selectedNodes: NodeEntry[] = [];

if (uploadedFiles && uploadedFiles.length > 0 ) {
if (this.isSingleSelectionMode()) {
selectedNodes = [...[uploadedFiles[uploadedFiles.length - 1]].map((uploadedFile) => uploadedFile.data)];
} else {
selectedNodes = [...uploadedFiles.map((uploadedFile) => uploadedFile.data)];
}
}

return selectedNodes;
}
}