mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-08 02:24:11 +00:00
[CST-3091] add comp collection-selector, fix issue
This commit is contained in:
@@ -0,0 +1,11 @@
|
|||||||
|
<div>
|
||||||
|
<div class="modal-header">{{'dso-selector.'+ action + '.' + objectType.toString().toLowerCase() + '.head' | translate}}
|
||||||
|
<button type="button" class="close" (click)="close()" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<ds-collection-dropdown (selectionChange)="selectObject($event.collection)">
|
||||||
|
</ds-collection-dropdown>
|
||||||
|
</div>
|
||||||
|
</div>
|
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CollectionSelectorComponent } from './collection-selector.component';
|
||||||
|
|
||||||
|
describe('CollectionSelectorComponent', () => {
|
||||||
|
let component: CollectionSelectorComponent;
|
||||||
|
let fixture: ComponentFixture<CollectionSelectorComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ CollectionSelectorComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CollectionSelectorComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,35 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { DSOSelectorModalWrapperComponent, SelectorActionType } from 'src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component';
|
||||||
|
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||||
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { DSpaceObjectType } from 'src/app/core/shared/dspace-object-type.model';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-collection-selector',
|
||||||
|
templateUrl: './collection-selector.component.html',
|
||||||
|
styleUrls: ['./collection-selector.component.scss']
|
||||||
|
})
|
||||||
|
export class CollectionSelectorComponent extends DSOSelectorModalWrapperComponent {
|
||||||
|
objectType = DSpaceObjectType.ITEM;
|
||||||
|
selectorType = DSpaceObjectType.COLLECTION;
|
||||||
|
action = SelectorActionType.CREATE;
|
||||||
|
|
||||||
|
navigate(dso: DSpaceObject) {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router) {
|
||||||
|
super(activeModal, route);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method called when an element has been selected from collection list.
|
||||||
|
* Its close the active modal and send selected value to the component container
|
||||||
|
* @param dso The selected DSpaceObject
|
||||||
|
*/
|
||||||
|
selectObject(dso: DSpaceObject) {
|
||||||
|
this.activeModal.close(dso);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -3,7 +3,8 @@
|
|||||||
<ds-uploader *ngIf="uploadFilesOptions.url !== ''"
|
<ds-uploader *ngIf="uploadFilesOptions.url !== ''"
|
||||||
[uploadFilesOptions]="uploadFilesOptions"
|
[uploadFilesOptions]="uploadFilesOptions"
|
||||||
(onCompleteItem)="onCompleteItem($event)"
|
(onCompleteItem)="onCompleteItem($event)"
|
||||||
(onUploadError)="onUploadError()"></ds-uploader>
|
(onUploadError)="onUploadError($event)"
|
||||||
|
(onFileSelected)="uploadDialogForFileUpload($event)"></ds-uploader>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="add">
|
<div class="add">
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { ChangeDetectorRef, Component, EventEmitter, OnDestroy, OnInit, Output } from '@angular/core';
|
import { ChangeDetectorRef, Component, EventEmitter, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';
|
||||||
|
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { first } from 'rxjs/operators';
|
import { first } from 'rxjs/operators';
|
||||||
@@ -18,6 +18,9 @@ import { SearchResult } from '../../shared/search/search-result.model';
|
|||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { CreateItemParentSelectorComponent } from 'src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component';
|
import { CreateItemParentSelectorComponent } from 'src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component';
|
||||||
|
import { CollectionSelectorComponent } from '../collection-selector/collection-selector.component';
|
||||||
|
import { UploaderComponent } from 'src/app/shared/uploader/uploader.component';
|
||||||
|
import { UploaderError } from 'src/app/shared/uploader/uploader-error.model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This component represents the whole mydspace page header
|
* This component represents the whole mydspace page header
|
||||||
@@ -43,6 +46,11 @@ export class MyDSpaceNewSubmissionComponent implements OnDestroy, OnInit {
|
|||||||
*/
|
*/
|
||||||
private sub: Subscription;
|
private sub: Subscription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to uploaderComponent
|
||||||
|
*/
|
||||||
|
@ViewChild(UploaderComponent, { static: false }) uploaderComponent: UploaderComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize instance variables
|
* Initialize instance variables
|
||||||
*
|
*
|
||||||
@@ -67,6 +75,7 @@ export class MyDSpaceNewSubmissionComponent implements OnDestroy, OnInit {
|
|||||||
* Initialize url and Bearer token
|
* Initialize url and Bearer token
|
||||||
*/
|
*/
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
this.uploadFilesOptions.autoUpload = false;
|
||||||
this.sub = this.halService.getEndpoint('workspaceitems').pipe(first()).subscribe((url) => {
|
this.sub = this.halService.getEndpoint('workspaceitems').pipe(first()).subscribe((url) => {
|
||||||
this.uploadFilesOptions.url = url;
|
this.uploadFilesOptions.url = url;
|
||||||
this.uploadFilesOptions.authToken = this.authService.buildAuthHeader();
|
this.uploadFilesOptions.authToken = this.authService.buildAuthHeader();
|
||||||
@@ -106,8 +115,12 @@ export class MyDSpaceNewSubmissionComponent implements OnDestroy, OnInit {
|
|||||||
/**
|
/**
|
||||||
* Method called on file upload error
|
* Method called on file upload error
|
||||||
*/
|
*/
|
||||||
public onUploadError() {
|
public onUploadError(error: UploaderError) {
|
||||||
this.notificationsService.error(null, this.translate.get('mydspace.upload.upload-failed'));
|
let errorMessageKey = 'mydspace.upload.upload-failed';
|
||||||
|
if (hasValue(error.status) && error.status === 422) {
|
||||||
|
errorMessageKey = 'mydspace.upload.upload-failed-manyentries';
|
||||||
|
}
|
||||||
|
this.notificationsService.error(null, this.translate.get(errorMessageKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,6 +131,28 @@ export class MyDSpaceNewSubmissionComponent implements OnDestroy, OnInit {
|
|||||||
this.modalService.open(CreateItemParentSelectorComponent);
|
this.modalService.open(CreateItemParentSelectorComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method for open dialog after submission file selection
|
||||||
|
*/
|
||||||
|
uploadDialogForFileUpload(items) {
|
||||||
|
const uploader = this.uploaderComponent.uploader;
|
||||||
|
if (hasValue(items) && items.length > 1) {
|
||||||
|
this.notificationsService.error(null, this.translate.get('mydspace.upload.upload-failed-moreonefile'));
|
||||||
|
uploader.clearQueue();
|
||||||
|
this.changeDetectorRef.detectChanges();
|
||||||
|
} else {
|
||||||
|
const modalRef = this.modalService.open(CollectionSelectorComponent);
|
||||||
|
// When the dialog are closes its takes the collection selected and
|
||||||
|
// uploads choosed file after adds owningCollection parameter
|
||||||
|
modalRef.result.then( (result) => {
|
||||||
|
uploader.onBuildItemForm = (fileItem: any, form: any) => {
|
||||||
|
form.append('owningCollection', result.uuid);
|
||||||
|
};
|
||||||
|
uploader.uploadAll();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unsubscribe from the subscription
|
* Unsubscribe from the subscription
|
||||||
*/
|
*/
|
||||||
|
@@ -20,6 +20,7 @@ import { SearchResultListElementComponent } from '../shared/object-list/search-r
|
|||||||
import { ItemSearchResultListElementSubmissionComponent } from '../shared/object-list/my-dspace-result-list-element/item-search-result/item-search-result-list-element-submission.component';
|
import { ItemSearchResultListElementSubmissionComponent } from '../shared/object-list/my-dspace-result-list-element/item-search-result/item-search-result-list-element-submission.component';
|
||||||
import { WorkflowItemSearchResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/workflow-item-search-result/workflow-item-search-result-list-element.component';
|
import { WorkflowItemSearchResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/workflow-item-search-result/workflow-item-search-result-list-element.component';
|
||||||
import { PoolSearchResultDetailElementComponent } from '../shared/object-detail/my-dspace-result-detail-element/pool-search-result/pool-search-result-detail-element.component';
|
import { PoolSearchResultDetailElementComponent } from '../shared/object-detail/my-dspace-result-detail-element/pool-search-result/pool-search-result-detail-element.component';
|
||||||
|
import { CollectionSelectorComponent } from './collection-selector/collection-selector.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -40,7 +41,8 @@ import { PoolSearchResultDetailElementComponent } from '../shared/object-detail/
|
|||||||
ClaimedTaskSearchResultDetailElementComponent,
|
ClaimedTaskSearchResultDetailElementComponent,
|
||||||
PoolSearchResultDetailElementComponent,
|
PoolSearchResultDetailElementComponent,
|
||||||
MyDSpaceNewSubmissionComponent,
|
MyDSpaceNewSubmissionComponent,
|
||||||
ItemSearchResultListElementSubmissionComponent
|
ItemSearchResultListElementSubmissionComponent,
|
||||||
|
CollectionSelectorComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
MyDSpaceGuard,
|
MyDSpaceGuard,
|
||||||
@@ -57,7 +59,8 @@ import { PoolSearchResultDetailElementComponent } from '../shared/object-detail/
|
|||||||
WorkflowItemSearchResultDetailElementComponent,
|
WorkflowItemSearchResultDetailElementComponent,
|
||||||
ClaimedTaskSearchResultDetailElementComponent,
|
ClaimedTaskSearchResultDetailElementComponent,
|
||||||
PoolSearchResultDetailElementComponent,
|
PoolSearchResultDetailElementComponent,
|
||||||
ItemSearchResultListElementSubmissionComponent
|
ItemSearchResultListElementSubmissionComponent,
|
||||||
|
CollectionSelectorComponent
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
9
src/app/shared/uploader/uploader-error.model.ts
Normal file
9
src/app/shared/uploader/uploader-error.model.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* An interface that represents the upload error values
|
||||||
|
*/
|
||||||
|
export interface UploaderError {
|
||||||
|
item?: any;
|
||||||
|
response?: any;
|
||||||
|
status?: any;
|
||||||
|
headers?: any;
|
||||||
|
}
|
@@ -17,6 +17,11 @@ export class UploaderOptions {
|
|||||||
*/
|
*/
|
||||||
autoUpload = true;
|
autoUpload = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the max number of files that can be loaded
|
||||||
|
*/
|
||||||
|
maxFileNumber: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The request method to use for the file upload request
|
* The request method to use for the file upload request
|
||||||
*/
|
*/
|
||||||
|
@@ -69,6 +69,11 @@ export class UploaderComponent {
|
|||||||
*/
|
*/
|
||||||
@Output() onUploadError: EventEmitter<any> = new EventEmitter<any>();
|
@Output() onUploadError: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The function to call when a file is selected
|
||||||
|
*/
|
||||||
|
@Output() onFileSelected: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
public uploader: FileUploader;
|
public uploader: FileUploader;
|
||||||
public uploaderId: string;
|
public uploaderId: string;
|
||||||
public isOverBaseDropZone = observableOf(false);
|
public isOverBaseDropZone = observableOf(false);
|
||||||
@@ -102,7 +107,8 @@ export class UploaderComponent {
|
|||||||
itemAlias: this.uploadFilesOptions.itemAlias,
|
itemAlias: this.uploadFilesOptions.itemAlias,
|
||||||
removeAfterUpload: true,
|
removeAfterUpload: true,
|
||||||
autoUpload: this.uploadFilesOptions.autoUpload,
|
autoUpload: this.uploadFilesOptions.autoUpload,
|
||||||
method: this.uploadFilesOptions.method
|
method: this.uploadFilesOptions.method,
|
||||||
|
queueLimit: this.uploadFilesOptions.maxFileNumber
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isUndefined(this.enableDragOverDocument)) {
|
if (isUndefined(this.enableDragOverDocument)) {
|
||||||
@@ -121,6 +127,9 @@ export class UploaderComponent {
|
|||||||
this.uploader.onAfterAddingFile = ((item) => {
|
this.uploader.onAfterAddingFile = ((item) => {
|
||||||
item.withCredentials = false;
|
item.withCredentials = false;
|
||||||
});
|
});
|
||||||
|
this.uploader.onAfterAddingAll = ((items) => {
|
||||||
|
this.onFileSelected.emit(items);
|
||||||
|
});
|
||||||
if (isUndefined(this.onBeforeUpload)) {
|
if (isUndefined(this.onBeforeUpload)) {
|
||||||
this.onBeforeUpload = () => {return};
|
this.onBeforeUpload = () => {return};
|
||||||
}
|
}
|
||||||
@@ -149,7 +158,7 @@ export class UploaderComponent {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.uploader.onErrorItem = (item: any, response: any, status: any, headers: any) => {
|
this.uploader.onErrorItem = (item: any, response: any, status: any, headers: any) => {
|
||||||
this.onUploadError.emit(null);
|
this.onUploadError.emit({ item: item, response: response, status: status, headers: headers });
|
||||||
this.uploader.cancelAll();
|
this.uploader.cancelAll();
|
||||||
};
|
};
|
||||||
this.uploader.onProgressAll = () => this.onProgress();
|
this.uploader.onProgressAll = () => this.onProgress();
|
||||||
|
@@ -1803,6 +1803,10 @@
|
|||||||
|
|
||||||
"mydspace.upload.upload-failed": "Error creating new workspace. Please verify the content uploaded before retry.",
|
"mydspace.upload.upload-failed": "Error creating new workspace. Please verify the content uploaded before retry.",
|
||||||
|
|
||||||
|
"mydspace.upload.upload-failed-manyentries": "Unprocessable file. Detected too many entries but allowed only one for file.",
|
||||||
|
|
||||||
|
"mydspace.upload.upload-failed-moreonefile": "Unprocessable request. Only one file is allowed.",
|
||||||
|
|
||||||
"mydspace.upload.upload-multiple-successful": "{{qty}} new workspace items created.",
|
"mydspace.upload.upload-multiple-successful": "{{qty}} new workspace items created.",
|
||||||
|
|
||||||
"mydspace.upload.upload-successful": "New workspace item created. Click {{here}} for edit it.",
|
"mydspace.upload.upload-successful": "New workspace item created. Click {{here}} for edit it.",
|
||||||
|
Reference in New Issue
Block a user