diff --git a/src/app/admin/admin-import-batch-page/batch-import-page.component.html b/src/app/admin/admin-import-batch-page/batch-import-page.component.html
index dbc8c74437..190eb0d409 100644
--- a/src/app/admin/admin-import-batch-page/batch-import-page.component.html
+++ b/src/app/admin/admin-import-batch-page/batch-import-page.component.html
@@ -20,12 +20,24 @@
+
+
+
+
+
+
diff --git a/src/app/admin/admin-import-batch-page/batch-import-page.component.spec.ts b/src/app/admin/admin-import-batch-page/batch-import-page.component.spec.ts
index 36ba1137c9..2c465d3f3d 100644
--- a/src/app/admin/admin-import-batch-page/batch-import-page.component.spec.ts
+++ b/src/app/admin/admin-import-batch-page/batch-import-page.component.spec.ts
@@ -86,10 +86,18 @@ describe('BatchImportPageComponent', () => {
let fileMock: File;
beforeEach(() => {
+ component.isUpload = true;
fileMock = new File([''], 'filename.zip', { type: 'application/zip' });
component.setFile(fileMock);
});
+ it('should show the file dropzone', () => {
+ const fileDropzone = fixture.debugElement.query(By.css('[data-test="file-dropzone"]'));
+ const fileUrlInput = fixture.debugElement.query(By.css('[data-test="file-url-input"]'));
+ expect(fileDropzone).toBeTruthy();
+ expect(fileUrlInput).toBeFalsy();
+ });
+
describe('if proceed button is pressed without validate only', () => {
beforeEach(fakeAsync(() => {
component.validateOnly = false;
@@ -99,9 +107,9 @@ describe('BatchImportPageComponent', () => {
}));
it('metadata-import script is invoked with --zip fileName and the mockFile', () => {
const parameterValues: ProcessParameter[] = [
- Object.assign(new ProcessParameter(), { name: '--zip', value: 'filename.zip' }),
+ Object.assign(new ProcessParameter(), { name: '--add' }),
+ Object.assign(new ProcessParameter(), { name: '--zip', value: 'filename.zip' })
];
- parameterValues.push(Object.assign(new ProcessParameter(), { name: '--add' }));
expect(scriptService.invoke).toHaveBeenCalledWith(BATCH_IMPORT_SCRIPT_NAME, parameterValues, [fileMock]);
});
it('success notification is shown', () => {
@@ -121,8 +129,8 @@ describe('BatchImportPageComponent', () => {
}));
it('metadata-import script is invoked with --zip fileName and the mockFile and -v validate-only', () => {
const parameterValues: ProcessParameter[] = [
- Object.assign(new ProcessParameter(), { name: '--zip', value: 'filename.zip' }),
Object.assign(new ProcessParameter(), { name: '--add' }),
+ Object.assign(new ProcessParameter(), { name: '--zip', value: 'filename.zip' }),
Object.assign(new ProcessParameter(), { name: '-v', value: true }),
];
expect(scriptService.invoke).toHaveBeenCalledWith(BATCH_IMPORT_SCRIPT_NAME, parameterValues, [fileMock]);
@@ -148,4 +156,77 @@ describe('BatchImportPageComponent', () => {
});
});
});
+
+ describe('if url is set', () => {
+ beforeEach(fakeAsync(() => {
+ component.isUpload = false;
+ component.fileURL = 'example.fileURL.com';
+ fixture.detectChanges();
+ }));
+
+ it('should show the file url input', () => {
+ const fileDropzone = fixture.debugElement.query(By.css('[data-test="file-dropzone"]'));
+ const fileUrlInput = fixture.debugElement.query(By.css('[data-test="file-url-input"]'));
+ expect(fileDropzone).toBeFalsy();
+ expect(fileUrlInput).toBeTruthy();
+ });
+
+ describe('if proceed button is pressed without validate only', () => {
+ beforeEach(fakeAsync(() => {
+ component.validateOnly = false;
+ const proceed = fixture.debugElement.query(By.css('#proceedButton')).nativeElement;
+ proceed.click();
+ fixture.detectChanges();
+ }));
+ it('metadata-import script is invoked with --u and the file url', () => {
+ const parameterValues: ProcessParameter[] = [
+ Object.assign(new ProcessParameter(), { name: '--add' }),
+ Object.assign(new ProcessParameter(), { name: '--u', value: 'example.fileURL.com' })
+ ];
+ expect(scriptService.invoke).toHaveBeenCalledWith(BATCH_IMPORT_SCRIPT_NAME, parameterValues, [null]);
+ });
+ it('success notification is shown', () => {
+ expect(notificationService.success).toHaveBeenCalled();
+ });
+ it('redirected to process page', () => {
+ expect(router.navigateByUrl).toHaveBeenCalledWith('/processes/46');
+ });
+ });
+
+ describe('if proceed button is pressed with validate only', () => {
+ beforeEach(fakeAsync(() => {
+ component.validateOnly = true;
+ const proceed = fixture.debugElement.query(By.css('#proceedButton')).nativeElement;
+ proceed.click();
+ fixture.detectChanges();
+ }));
+ it('metadata-import script is invoked with --u and the file url and -v validate-only', () => {
+ const parameterValues: ProcessParameter[] = [
+ Object.assign(new ProcessParameter(), { name: '--add' }),
+ Object.assign(new ProcessParameter(), { name: '--u', value: 'example.fileURL.com' }),
+ Object.assign(new ProcessParameter(), { name: '-v', value: true }),
+ ];
+ expect(scriptService.invoke).toHaveBeenCalledWith(BATCH_IMPORT_SCRIPT_NAME, parameterValues, [null]);
+ });
+ it('success notification is shown', () => {
+ expect(notificationService.success).toHaveBeenCalled();
+ });
+ it('redirected to process page', () => {
+ expect(router.navigateByUrl).toHaveBeenCalledWith('/processes/46');
+ });
+ });
+
+ describe('if proceed is pressed; but script invoke fails', () => {
+ beforeEach(fakeAsync(() => {
+ jasmine.getEnv().allowRespy(true);
+ spyOn(scriptService, 'invoke').and.returnValue(createFailedRemoteDataObject$('Error', 500));
+ const proceed = fixture.debugElement.query(By.css('#proceedButton')).nativeElement;
+ proceed.click();
+ fixture.detectChanges();
+ }));
+ it('error notification is shown', () => {
+ expect(notificationService.error).toHaveBeenCalled();
+ });
+ });
+ });
});
diff --git a/src/app/admin/admin-import-batch-page/batch-import-page.component.ts b/src/app/admin/admin-import-batch-page/batch-import-page.component.ts
index 7171c67585..79da641cc6 100644
--- a/src/app/admin/admin-import-batch-page/batch-import-page.component.ts
+++ b/src/app/admin/admin-import-batch-page/batch-import-page.component.ts
@@ -8,7 +8,7 @@ import { ProcessParameter } from '../../process-page/processes/process-parameter
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
import { RemoteData } from '../../core/data/remote-data';
import { Process } from '../../process-page/processes/process.model';
-import { isNotEmpty } from '../../shared/empty.util';
+import { isEmpty, isNotEmpty } from '../../shared/empty.util';
import { getProcessDetailRoute } from '../../process-page/process-page-routing.paths';
import {
ImportBatchSelectorComponent
@@ -32,11 +32,22 @@ export class BatchImportPageComponent {
* The validate only flag
*/
validateOnly = true;
+
/**
* dso object for community or collection
*/
dso: DSpaceObject = null;
+ /**
+ * The flag between upload and url
+ */
+ isUpload = true;
+
+ /**
+ * File URL when flag is for url
+ */
+ fileURL: string;
+
public constructor(private location: Location,
protected translate: TranslateService,
protected notificationsService: NotificationsService,
@@ -72,13 +83,18 @@ export class BatchImportPageComponent {
* Starts import-metadata script with --zip fileName (and the selected file)
*/
public importMetadata() {
- if (this.fileObject == null) {
+ if (this.fileObject == null && isEmpty(this.fileURL)) {
this.notificationsService.error(this.translate.get('admin.metadata-import.page.error.addFile'));
} else {
const parameterValues: ProcessParameter[] = [
- Object.assign(new ProcessParameter(), { name: '--zip', value: this.fileObject.name }),
Object.assign(new ProcessParameter(), { name: '--add' })
];
+ if (this.isUpload) {
+ parameterValues.push(Object.assign(new ProcessParameter(), { name: '--zip', value: this.fileObject.name }));
+ } else {
+ this.fileObject = null;
+ parameterValues.push(Object.assign(new ProcessParameter(), { name: '--u', value: this.fileURL }));
+ }
if (this.dso) {
parameterValues.push(Object.assign(new ProcessParameter(), { name: '--collection', value: this.dso.uuid }));
}
@@ -121,4 +137,11 @@ export class BatchImportPageComponent {
removeDspaceObject(): void {
this.dso = null;
}
+
+ /**
+ * toggle the flag between upload and url
+ */
+ toggleUpload() {
+ this.isUpload = !this.isUpload;
+ }
}
diff --git a/src/app/admin/admin.module.ts b/src/app/admin/admin.module.ts
index dff2e506c3..768e3120df 100644
--- a/src/app/admin/admin.module.ts
+++ b/src/app/admin/admin.module.ts
@@ -10,7 +10,7 @@ import { AdminSearchModule } from './admin-search-page/admin-search.module';
import { AdminSidebarSectionComponent } from './admin-sidebar/admin-sidebar-section/admin-sidebar-section.component';
import { ExpandableAdminSidebarSectionComponent } from './admin-sidebar/expandable-admin-sidebar-section/expandable-admin-sidebar-section.component';
import { BatchImportPageComponent } from './admin-import-batch-page/batch-import-page.component';
-import { UploadModule } from '../shared/upload/upload.module';
+import { UiSwitchModule } from 'ngx-ui-switch';
const ENTRY_COMPONENTS = [
// put only entry components that use custom decorator
@@ -27,7 +27,7 @@ const ENTRY_COMPONENTS = [
AdminSearchModule.withEntryComponents(),
AdminWorkflowModuleModule.withEntryComponents(),
SharedModule,
- UploadModule,
+ UiSwitchModule
],
declarations: [
AdminCurationTasksComponent,
diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5
index fc4c6aa74d..5eb069c804 100644
--- a/src/assets/i18n/en.json5
+++ b/src/assets/i18n/en.json5
@@ -586,6 +586,12 @@
"admin.batch-import.page.error.addFile": "Select Zip file first!",
+ "admin.metadata-import.page.toggle.upload": "Upload",
+
+ "admin.metadata-import.page.toggle.url": "URL",
+
+ "admin.metadata-import.page.urlMsg": "Insert the batch ZIP url to import",
+
"admin.metadata-import.page.validateOnly": "Validate Only",
"admin.metadata-import.page.validateOnly.hint": "When selected, the uploaded CSV will be validated. You will receive a report of detected changes, but no changes will be saved.",