[CST-7216] Angular: Import saf via URL

This commit is contained in:
Sufiyan Shaikh
2022-11-07 20:56:05 +05:30
committed by Francesco Pio Scognamiglio
parent 1ea7c61315
commit e47b42bc89
5 changed files with 130 additions and 8 deletions

View File

@@ -20,12 +20,24 @@
</small> </small>
</div> </div>
<ui-switch [checkedLabel]="'admin.metadata-import.page.toggle.upload' | translate"
[uncheckedLabel]="'admin.metadata-import.page.toggle.url' | translate"
[checked]="isUpload"
(change)="toggleUpload()" ></ui-switch>
<ds-file-dropzone-no-uploader <ds-file-dropzone-no-uploader
*ngIf="isUpload"
data-test="file-dropzone"
(onFileAdded)="setFile($event)" (onFileAdded)="setFile($event)"
[dropMessageLabel]="'admin.batch-import.page.dropMsg'" [dropMessageLabel]="'admin.batch-import.page.dropMsg'"
[dropMessageLabelReplacement]="'admin.batch-import.page.dropMsgReplace'"> [dropMessageLabelReplacement]="'admin.batch-import.page.dropMsgReplace'">
</ds-file-dropzone-no-uploader> </ds-file-dropzone-no-uploader>
<div class="form-group mt-2" *ngIf="!isUpload">
<input class="form-control" type="text" placeholder="{{'admin.metadata-import.page.urlMsg' | translate}}"
data-test="file-url-input" [(ngModel)]="fileURL">
</div>
<div class="space-children-mr"> <div class="space-children-mr">
<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>

View File

@@ -86,10 +86,18 @@ describe('BatchImportPageComponent', () => {
let fileMock: File; let fileMock: File;
beforeEach(() => { beforeEach(() => {
component.isUpload = true;
fileMock = new File([''], 'filename.zip', { type: 'application/zip' }); fileMock = new File([''], 'filename.zip', { type: 'application/zip' });
component.setFile(fileMock); 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', () => { describe('if proceed button is pressed without validate only', () => {
beforeEach(fakeAsync(() => { beforeEach(fakeAsync(() => {
component.validateOnly = false; component.validateOnly = false;
@@ -99,9 +107,9 @@ describe('BatchImportPageComponent', () => {
})); }));
it('metadata-import script is invoked with --zip fileName and the mockFile', () => { it('metadata-import script is invoked with --zip fileName and the mockFile', () => {
const parameterValues: ProcessParameter[] = [ 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]); expect(scriptService.invoke).toHaveBeenCalledWith(BATCH_IMPORT_SCRIPT_NAME, parameterValues, [fileMock]);
}); });
it('success notification is shown', () => { 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', () => { it('metadata-import script is invoked with --zip fileName and the mockFile and -v validate-only', () => {
const parameterValues: ProcessParameter[] = [ const parameterValues: ProcessParameter[] = [
Object.assign(new ProcessParameter(), { name: '--zip', value: 'filename.zip' }),
Object.assign(new ProcessParameter(), { name: '--add' }), Object.assign(new ProcessParameter(), { name: '--add' }),
Object.assign(new ProcessParameter(), { name: '--zip', value: 'filename.zip' }),
Object.assign(new ProcessParameter(), { name: '-v', value: true }), Object.assign(new ProcessParameter(), { name: '-v', value: true }),
]; ];
expect(scriptService.invoke).toHaveBeenCalledWith(BATCH_IMPORT_SCRIPT_NAME, parameterValues, [fileMock]); 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();
});
});
});
}); });

View File

@@ -8,7 +8,7 @@ import { ProcessParameter } from '../../process-page/processes/process-parameter
import { getFirstCompletedRemoteData } from '../../core/shared/operators'; import { getFirstCompletedRemoteData } from '../../core/shared/operators';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { Process } from '../../process-page/processes/process.model'; 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 { getProcessDetailRoute } from '../../process-page/process-page-routing.paths';
import { import {
ImportBatchSelectorComponent ImportBatchSelectorComponent
@@ -32,11 +32,22 @@ export class BatchImportPageComponent {
* The validate only flag * The validate only flag
*/ */
validateOnly = true; validateOnly = true;
/** /**
* dso object for community or collection * dso object for community or collection
*/ */
dso: DSpaceObject = null; 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, public constructor(private location: Location,
protected translate: TranslateService, protected translate: TranslateService,
protected notificationsService: NotificationsService, protected notificationsService: NotificationsService,
@@ -72,13 +83,18 @@ export class BatchImportPageComponent {
* Starts import-metadata script with --zip fileName (and the selected file) * Starts import-metadata script with --zip fileName (and the selected file)
*/ */
public importMetadata() { 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')); this.notificationsService.error(this.translate.get('admin.metadata-import.page.error.addFile'));
} else { } else {
const parameterValues: ProcessParameter[] = [ const parameterValues: ProcessParameter[] = [
Object.assign(new ProcessParameter(), { name: '--zip', value: this.fileObject.name }),
Object.assign(new ProcessParameter(), { name: '--add' }) 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) { if (this.dso) {
parameterValues.push(Object.assign(new ProcessParameter(), { name: '--collection', value: this.dso.uuid })); parameterValues.push(Object.assign(new ProcessParameter(), { name: '--collection', value: this.dso.uuid }));
} }
@@ -121,4 +137,11 @@ export class BatchImportPageComponent {
removeDspaceObject(): void { removeDspaceObject(): void {
this.dso = null; this.dso = null;
} }
/**
* toggle the flag between upload and url
*/
toggleUpload() {
this.isUpload = !this.isUpload;
}
} }

View File

@@ -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 { 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 { 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 { 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 = [ const ENTRY_COMPONENTS = [
// put only entry components that use custom decorator // put only entry components that use custom decorator
@@ -27,7 +27,7 @@ const ENTRY_COMPONENTS = [
AdminSearchModule.withEntryComponents(), AdminSearchModule.withEntryComponents(),
AdminWorkflowModuleModule.withEntryComponents(), AdminWorkflowModuleModule.withEntryComponents(),
SharedModule, SharedModule,
UploadModule, UiSwitchModule
], ],
declarations: [ declarations: [
AdminCurationTasksComponent, AdminCurationTasksComponent,

View File

@@ -586,6 +586,12 @@
"admin.batch-import.page.error.addFile": "Select Zip file first!", "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": "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.", "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.",