mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-08 10:34:15 +00:00
71713: Dropzone without uploader to own component
This commit is contained in:
@@ -2,34 +2,11 @@
|
|||||||
<h2 id="header">{{'admin.metadata-import.page.header' | translate}}</h2>
|
<h2 id="header">{{'admin.metadata-import.page.header' | translate}}</h2>
|
||||||
<p>{{'admin.metadata-import.page.help' | translate}}</p>
|
<p>{{'admin.metadata-import.page.help' | translate}}</p>
|
||||||
|
|
||||||
<div ng2FileDrop
|
<ds-file-dropzone-no-uploader
|
||||||
class="ds-document-drop-zone position-fixed h-100 w-100"
|
(onFileAdded)="setFile($event)"
|
||||||
[class.ds-document-drop-zone-active]="(isOverDocumentDropZone | async)"
|
[dropMessageLabel]="'admin.metadata-import.page.dropMsg'"
|
||||||
[uploader]="uploader"
|
[dropMessageLabelReplacement]="'admin.metadata-import.page.dropMsgReplace'">
|
||||||
(onFileDrop)="setFile($event)"
|
</ds-file-dropzone-no-uploader>
|
||||||
(fileOver)="fileOverDocument($event)">
|
|
||||||
</div>
|
|
||||||
<div *ngIf="(isOverDocumentDropZone | async)"
|
|
||||||
class="ds-document-drop-zone-inner position-fixed h-100 w-100 p-2">
|
|
||||||
<div
|
|
||||||
class="ds-document-drop-zone-inner-content position-relative d-flex flex-column justify-content-center text-center h-100 w-100">
|
|
||||||
<p class="text-primary">{{'admin.metadata-import.page.dropMsg' | translate}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="well ds-base-drop-zone mt-1 mb-3 text-muted p-2">
|
|
||||||
<p class="text-center m-0 p-0 d-flex justify-content-center align-items-center"
|
|
||||||
*ngIf="fileObject!=null"> {{ fileObject.name }} </p>
|
|
||||||
<p class="text-center m-0 p-0 d-flex justify-content-center align-items-center">
|
|
||||||
<span><i class="fas fa-cloud-upload"
|
|
||||||
aria-hidden="true"></i> {{ (fileObject == null ? 'admin.metadata-import.page.dropMsg' : 'admin.metadata-import.page.dropMsgReplace') | translate}} {{'uploader.or' | translate}}</span>
|
|
||||||
<label class="btn btn-link m-0 p-0 ml-1">
|
|
||||||
<input class="form-control-file d-none" requireFile #file="ngModel" type="file" name="file-upload"
|
|
||||||
id="file-upload"
|
|
||||||
[ngModel]="fileObject" (ngModelChange)="setFile($event)">
|
|
||||||
{{'uploader.browse' | translate}}
|
|
||||||
</label>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button class="btn btn-secondary" id="backButton"
|
<button class="btn btn-secondary" id="backButton"
|
||||||
(click)="this.onReturn();">{{'admin.metadata-import.page.button.return' | translate}}</button>
|
(click)="this.onReturn();">{{'admin.metadata-import.page.button.return' | translate}}</button>
|
||||||
|
@@ -20,7 +20,7 @@ import { FileValueAccessorDirective } from '../../shared/utils/file-value-access
|
|||||||
import { FileValidator } from '../../shared/utils/require-file.validator';
|
import { FileValidator } from '../../shared/utils/require-file.validator';
|
||||||
import { MetadataImportPageComponent } from './metadata-import-page.component';
|
import { MetadataImportPageComponent } from './metadata-import-page.component';
|
||||||
|
|
||||||
describe('MetadataImportPageComponent', () => {
|
fdescribe('MetadataImportPageComponent', () => {
|
||||||
let comp: MetadataImportPageComponent;
|
let comp: MetadataImportPageComponent;
|
||||||
let fixture: ComponentFixture<MetadataImportPageComponent>;
|
let fixture: ComponentFixture<MetadataImportPageComponent>;
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ describe('MetadataImportPageComponent', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fileMock = new File([''], 'filename.txt', { type: 'text/plain' });
|
fileMock = new File([''], 'filename.txt', { type: 'text/plain' });
|
||||||
comp.setFile([fileMock]);
|
comp.setFile(fileMock);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('if proceed button is pressed', () => {
|
describe('if proceed button is pressed', () => {
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
import { Location } from '@angular/common';
|
import { Location } from '@angular/common';
|
||||||
import { Component, HostListener, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { uniqueId } from 'lodash';
|
|
||||||
import { FileUploader } from 'ng2-file-upload';
|
|
||||||
import { Observable } from 'rxjs/internal/Observable';
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
import { map, switchMap, take } from 'rxjs/operators';
|
import { map, switchMap, take } from 'rxjs/operators';
|
||||||
import { AuthService } from '../../core/auth/auth.service';
|
import { AuthService } from '../../core/auth/auth.service';
|
||||||
@@ -13,13 +11,10 @@ import { EPerson } from '../../core/eperson/models/eperson.model';
|
|||||||
import { ProcessParameter } from '../../process-page/processes/process-parameter.model';
|
import { ProcessParameter } from '../../process-page/processes/process-parameter.model';
|
||||||
import { isNotEmpty } from '../../shared/empty.util';
|
import { isNotEmpty } from '../../shared/empty.util';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { of as observableOf } from 'rxjs';
|
|
||||||
import { UploaderOptions } from '../../shared/uploader/uploader-options.model';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-metadata-import-page',
|
selector: 'ds-metadata-import-page',
|
||||||
templateUrl: './metadata-import-page.component.html',
|
templateUrl: './metadata-import-page.component.html'
|
||||||
styleUrls: ['./metadata-import-page.component.scss']
|
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,19 +22,6 @@ import { UploaderOptions } from '../../shared/uploader/uploader-options.model';
|
|||||||
*/
|
*/
|
||||||
export class MetadataImportPageComponent implements OnInit {
|
export class MetadataImportPageComponent implements OnInit {
|
||||||
|
|
||||||
public isOverDocumentDropZone: Observable<boolean>;
|
|
||||||
public uploader: FileUploader;
|
|
||||||
public uploaderId: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The uploader configuration options
|
|
||||||
* @type {UploaderOptions}
|
|
||||||
*/
|
|
||||||
uploadFilesOptions: UploaderOptions = Object.assign(new UploaderOptions(), {
|
|
||||||
// URL needs to contain something to not produce any errors. We are using onFileDrop; not the uploader
|
|
||||||
url: 'placeholder',
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current value of the file
|
* The current value of the file
|
||||||
*/
|
*/
|
||||||
@@ -58,6 +40,14 @@ export class MetadataImportPageComponent implements OnInit {
|
|||||||
private router: Router) {
|
private router: Router) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set file
|
||||||
|
* @param file
|
||||||
|
*/
|
||||||
|
setFile(file) {
|
||||||
|
this.fileObject = file;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method provided by Angular. Invoked after the constructor.
|
* Method provided by Angular. Invoked after the constructor.
|
||||||
*/
|
*/
|
||||||
@@ -65,41 +55,6 @@ export class MetadataImportPageComponent implements OnInit {
|
|||||||
this.currentUserEmail$ = this.authService.getAuthenticatedUserFromStore().pipe(
|
this.currentUserEmail$ = this.authService.getAuthenticatedUserFromStore().pipe(
|
||||||
map((user: EPerson) => user.email)
|
map((user: EPerson) => user.email)
|
||||||
);
|
);
|
||||||
this.uploaderId = 'ds-drag-and-drop-uploader' + uniqueId();
|
|
||||||
this.isOverDocumentDropZone = observableOf(false);
|
|
||||||
window.addEventListener('drop', (e: DragEvent) => {
|
|
||||||
return e && e.preventDefault();
|
|
||||||
}, false);
|
|
||||||
this.uploader = new FileUploader({
|
|
||||||
// required, but using onFileDrop, not uploader
|
|
||||||
url: 'placeholder',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@HostListener('window:dragover', ['$event'])
|
|
||||||
onDragOver(event: any) {
|
|
||||||
// Show drop area on the page
|
|
||||||
event.preventDefault();
|
|
||||||
if ((event.target as any).tagName !== 'HTML') {
|
|
||||||
this.isOverDocumentDropZone = observableOf(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when files are dragged on the window document drop area.
|
|
||||||
*/
|
|
||||||
public fileOverDocument(isOver: boolean) {
|
|
||||||
if (!isOver) {
|
|
||||||
this.isOverDocumentDropZone = observableOf(isOver);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set (CSV) file
|
|
||||||
* @param files
|
|
||||||
*/
|
|
||||||
setFile(files) {
|
|
||||||
this.fileObject = files.length > 0 ? files[0] : undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -0,0 +1,28 @@
|
|||||||
|
<div ng2FileDrop
|
||||||
|
class="ds-document-drop-zone position-fixed h-100 w-100"
|
||||||
|
[class.ds-document-drop-zone-active]="(isOverDocumentDropZone | async)"
|
||||||
|
[uploader]="uploader"
|
||||||
|
(onFileDrop)="setFile($event)"
|
||||||
|
(fileOver)="fileOverDocument($event)">
|
||||||
|
</div>
|
||||||
|
<div *ngIf="(isOverDocumentDropZone | async)"
|
||||||
|
class="ds-document-drop-zone-inner position-fixed h-100 w-100 p-2">
|
||||||
|
<div
|
||||||
|
class="ds-document-drop-zone-inner-content position-relative d-flex flex-column justify-content-center text-center h-100 w-100">
|
||||||
|
<p class="text-primary">{{ dropMessageLabel | translate}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="well ds-base-drop-zone mt-1 mb-3 text-muted p-2">
|
||||||
|
<p class="text-center m-0 p-0 d-flex justify-content-center align-items-center"
|
||||||
|
*ngIf="fileObject!=null"> {{ fileObject.name }} </p>
|
||||||
|
<p class="text-center m-0 p-0 d-flex justify-content-center align-items-center">
|
||||||
|
<span><i class="fas fa-cloud-upload"
|
||||||
|
aria-hidden="true"></i> {{ (fileObject == null ? dropMessageLabel : dropMessageLabelReplacement) | translate}} {{'uploader.or' | translate}}</span>
|
||||||
|
<label class="btn btn-link m-0 p-0 ml-1">
|
||||||
|
<input class="form-control-file d-none" requireFile #file="ngModel" type="file" name="file-upload"
|
||||||
|
id="file-upload"
|
||||||
|
[ngModel]="fileObject" (ngModelChange)="setFile($event)">
|
||||||
|
{{'uploader.browse' | translate}}
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
</div>
|
@@ -0,0 +1,90 @@
|
|||||||
|
import { Component, EventEmitter, HostListener, Input, OnInit, Output } from '@angular/core';
|
||||||
|
import { uniqueId } from 'lodash';
|
||||||
|
import { FileUploader } from 'ng2-file-upload';
|
||||||
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
|
import { UploaderOptions } from '../uploader/uploader-options.model';
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component to have a file dropzone without that dropping/choosing a file in browse automatically triggers
|
||||||
|
* the uploader, instead an event is emitted with the file that was added.
|
||||||
|
*
|
||||||
|
* Here only one file is allowed to be selected, so if one is selected/dropped the message changes to a
|
||||||
|
* replace message.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-file-dropzone-no-uploader',
|
||||||
|
templateUrl: './file-dropzone-no-uploader.component.html',
|
||||||
|
styleUrls: ['./file-dropzone-no-uploader.scss']
|
||||||
|
})
|
||||||
|
export class FileDropzoneNoUploaderComponent implements OnInit {
|
||||||
|
|
||||||
|
public isOverDocumentDropZone: Observable<boolean>;
|
||||||
|
public uploader: FileUploader;
|
||||||
|
public uploaderId: string;
|
||||||
|
|
||||||
|
@Input() dropMessageLabel: string;
|
||||||
|
@Input() dropMessageLabelReplacement: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The function to call when file is added
|
||||||
|
*/
|
||||||
|
@Output() onFileAdded: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The uploader configuration options
|
||||||
|
* @type {UploaderOptions}
|
||||||
|
*/
|
||||||
|
uploadFilesOptions: UploaderOptions = Object.assign(new UploaderOptions(), {
|
||||||
|
// URL needs to contain something to not produce any errors. We are using onFileDrop; not the uploader
|
||||||
|
url: 'placeholder',
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current value of the file
|
||||||
|
*/
|
||||||
|
fileObject: File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method provided by Angular. Invoked after the constructor.
|
||||||
|
*/
|
||||||
|
ngOnInit() {
|
||||||
|
this.uploaderId = 'ds-drag-and-drop-uploader' + uniqueId();
|
||||||
|
this.isOverDocumentDropZone = observableOf(false);
|
||||||
|
window.addEventListener('drop', (e: DragEvent) => {
|
||||||
|
return e && e.preventDefault();
|
||||||
|
}, false);
|
||||||
|
this.uploader = new FileUploader({
|
||||||
|
// required, but using onFileDrop, not uploader
|
||||||
|
url: 'placeholder',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@HostListener('window:dragover', ['$event'])
|
||||||
|
onDragOver(event: any) {
|
||||||
|
// Show drop area on the page
|
||||||
|
event.preventDefault();
|
||||||
|
if ((event.target as any).tagName !== 'HTML') {
|
||||||
|
this.isOverDocumentDropZone = observableOf(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when files are dragged on the window document drop area.
|
||||||
|
*/
|
||||||
|
public fileOverDocument(isOver: boolean) {
|
||||||
|
if (!isOver) {
|
||||||
|
this.isOverDocumentDropZone = observableOf(isOver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set file
|
||||||
|
* @param files
|
||||||
|
*/
|
||||||
|
setFile(files) {
|
||||||
|
this.fileObject = files.length > 0 ? files[0] : undefined;
|
||||||
|
this.onFileAdded.emit(this.fileObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -11,6 +11,7 @@ import { MissingTranslationHandler, TranslateModule } from '@ngx-translate/core'
|
|||||||
import { NgxPaginationModule } from 'ngx-pagination';
|
import { NgxPaginationModule } from 'ngx-pagination';
|
||||||
import { ComcolRoleComponent } from './comcol-forms/edit-comcol-page/comcol-role/comcol-role.component';
|
import { ComcolRoleComponent } from './comcol-forms/edit-comcol-page/comcol-role/comcol-role.component';
|
||||||
import { ExportMetadataSelectorComponent } from './dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component';
|
import { ExportMetadataSelectorComponent } from './dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component';
|
||||||
|
import { FileDropzoneNoUploaderComponent } from './file-dropzone-no-uploader/file-dropzone-no-uploader.component';
|
||||||
import { PublicationListElementComponent } from './object-list/item-list-element/item-types/publication/publication-list-element.component';
|
import { PublicationListElementComponent } from './object-list/item-list-element/item-types/publication/publication-list-element.component';
|
||||||
|
|
||||||
import { FileUploadModule } from 'ng2-file-upload';
|
import { FileUploadModule } from 'ng2-file-upload';
|
||||||
@@ -308,6 +309,7 @@ const COMPONENTS = [
|
|||||||
ThumbnailComponent,
|
ThumbnailComponent,
|
||||||
GridThumbnailComponent,
|
GridThumbnailComponent,
|
||||||
UploaderComponent,
|
UploaderComponent,
|
||||||
|
FileDropzoneNoUploaderComponent,
|
||||||
ItemListPreviewComponent,
|
ItemListPreviewComponent,
|
||||||
MyDSpaceItemStatusComponent,
|
MyDSpaceItemStatusComponent,
|
||||||
ItemSubmitterComponent,
|
ItemSubmitterComponent,
|
||||||
|
Reference in New Issue
Block a user