forked from hazza/dspace-angular
71713: Import metadata CSV
This commit is contained in:
@@ -0,0 +1,34 @@
|
|||||||
|
<div class="container">
|
||||||
|
<h2 id="header">{{'admin.metadata-import.page.header' | translate}}</h2>
|
||||||
|
<p>{{'admin.metadata-import.page.help' | translate}}</p>
|
||||||
|
|
||||||
|
<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">{{'admin.metadata-import.page.dropMsg' | translate}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="well ds-base-drop-zone mt-1 mb-3 text-muted">
|
||||||
|
<label for="file-upload" class="d-flex align-items-center m-0">
|
||||||
|
<span class="btn btn-light">
|
||||||
|
{{'process.new.parameter.file.upload-button' | translate}}
|
||||||
|
</span>
|
||||||
|
<span class="file-name ml-1">{{fileObject?.name}}</span>
|
||||||
|
</label>
|
||||||
|
<input requireFile #file="ngModel" type="file" name="file-upload" id="file-upload" class="form-control-file d-none"
|
||||||
|
[ngModel]="fileObject" (ngModelChange)="setFile($event)"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="btn btn-secondary"
|
||||||
|
(click)="this.onReturn();">{{'admin.metadata-import.page.button.return' | translate}}</button>
|
||||||
|
<button class="btn btn-primary"
|
||||||
|
(click)="this.importMetadata();">{{'admin.metadata-import.page.button.proceed' | translate}}</button>
|
||||||
|
</div>
|
@@ -0,0 +1,29 @@
|
|||||||
|
.ds-base-drop-zone {
|
||||||
|
border: 2px dashed $gray-600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ds-document-drop-zone {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ds-document-drop-zone-active {
|
||||||
|
z-index: $drop-zone-area-z-index !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ds-document-drop-zone-inner {
|
||||||
|
background-color: rgba($white, 0.7);
|
||||||
|
z-index: $drop-zone-area-inner-z-index;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ds-document-drop-zone-inner-content {
|
||||||
|
border: 4px dashed map-get($theme-colors, primary);
|
||||||
|
z-index: $drop-zone-area-inner-z-index;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ds-document-drop-zone-inner-content p {
|
||||||
|
font-size: ($font-size-lg * 2.5);
|
||||||
|
}
|
@@ -0,0 +1,149 @@
|
|||||||
|
import { Location } from '@angular/common';
|
||||||
|
import { Component, HostListener, OnInit } from '@angular/core';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { uniqueId } from 'lodash';
|
||||||
|
import { FileUploader } from 'ng2-file-upload';
|
||||||
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
|
import { filter, map, take, tap } from 'rxjs/operators';
|
||||||
|
import { AuthService } from '../../core/auth/auth.service';
|
||||||
|
import { METADATA_IMPORT_SCRIPT_NAME, ScriptDataService } from '../../core/data/processes/script-data.service';
|
||||||
|
import { RequestEntry } from '../../core/data/request.reducer';
|
||||||
|
import { EPerson } from '../../core/eperson/models/eperson.model';
|
||||||
|
import { ProcessParameter } from '../../process-page/processes/process-parameter.model';
|
||||||
|
import { hasValue, isNotEmpty } from '../../shared/empty.util';
|
||||||
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
import { UploaderOptions } from '../../shared/uploader/uploader-options.model';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-metadata-import-page',
|
||||||
|
templateUrl: './metadata-import-page.component.html',
|
||||||
|
styleUrls: ['./metadata-import-page.component.scss']
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component that represents a metadata import page for administrators
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
fileObject: File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The authenticated user's email
|
||||||
|
*/
|
||||||
|
private currentUserEmail$: Observable<string>;
|
||||||
|
|
||||||
|
public constructor(protected authService: AuthService,
|
||||||
|
private location: Location,
|
||||||
|
protected translate: TranslateService,
|
||||||
|
protected notificationsService: NotificationsService,
|
||||||
|
private scriptDataService: ScriptDataService,
|
||||||
|
private router: Router) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method provided by Angular. Invoked after the constructor.
|
||||||
|
*/
|
||||||
|
ngOnInit() {
|
||||||
|
this.currentUserEmail$ = this.authService.getAuthenticatedUserFromStore().pipe(
|
||||||
|
map((user: EPerson) => user.email)
|
||||||
|
);
|
||||||
|
this.uploaderId = 'ds-drag-and-drop-uploader' + uniqueId();
|
||||||
|
this.isOverDocumentDropZone = observableOf(false);
|
||||||
|
window.addEventListener('drop', e => {
|
||||||
|
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) {
|
||||||
|
console.log('setfiles', files)
|
||||||
|
this.fileObject = files.length > 0 ? files[0] : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When return button is pressed go to previous location
|
||||||
|
*/
|
||||||
|
public onReturn() {
|
||||||
|
this.location.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts import-metadata script with -e currentUserEmail -f fileName (and the selected file)
|
||||||
|
*/
|
||||||
|
public importMetadata() {
|
||||||
|
if (this.fileObject == null) {
|
||||||
|
this.notificationsService.error(this.translate.get('admin.metadata-import.page.error.addFile'));
|
||||||
|
} else {
|
||||||
|
this.currentUserEmail$.pipe(
|
||||||
|
filter((email: string) => hasValue(email)),
|
||||||
|
take(1)
|
||||||
|
).subscribe((email: string) => {
|
||||||
|
const parameterValues: ProcessParameter[] = [
|
||||||
|
Object.assign(new ProcessParameter(), { name: '-e', value: email }),
|
||||||
|
Object.assign(new ProcessParameter(), { name: '-f', value: this.fileObject.name }),
|
||||||
|
];
|
||||||
|
this.scriptDataService.invoke(METADATA_IMPORT_SCRIPT_NAME, parameterValues, [this.fileObject])
|
||||||
|
.pipe(take(1))
|
||||||
|
.subscribe((requestEntry: RequestEntry) => {
|
||||||
|
if (requestEntry.response.isSuccessful) {
|
||||||
|
const title = this.translate.get('process.new.notification.success.title');
|
||||||
|
const content = this.translate.get('process.new.notification.success.content');
|
||||||
|
this.notificationsService.success(title, content);
|
||||||
|
const response: any = requestEntry.response;
|
||||||
|
if (isNotEmpty(response.resourceSelfLinks)) {
|
||||||
|
const processNumber = response.resourceSelfLinks[0].split('/').pop();
|
||||||
|
this.router.navigateByUrl('/processes/' + processNumber);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const title = this.translate.get('process.new.notification.error.title');
|
||||||
|
const content = this.translate.get('process.new.notification.error.content');
|
||||||
|
this.notificationsService.error(title, content);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,6 +1,7 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { getAdminModulePath } from '../app-routing.module';
|
import { getAdminModulePath } from '../app-routing.module';
|
||||||
|
import { MetadataImportPageComponent } from './admin-import-metadata-page/metadata-import-page.component';
|
||||||
import { AdminSearchPageComponent } from './admin-search-page/admin-search-page.component';
|
import { AdminSearchPageComponent } from './admin-search-page/admin-search-page.component';
|
||||||
import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver';
|
import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver';
|
||||||
import { AdminWorkflowPageComponent } from './admin-workflow-page/admin-workflow-page.component';
|
import { AdminWorkflowPageComponent } from './admin-workflow-page/admin-workflow-page.component';
|
||||||
@@ -48,6 +49,12 @@ export function getAccessControlModulePath() {
|
|||||||
component: AdminCurationTasksComponent,
|
component: AdminCurationTasksComponent,
|
||||||
data: { title: 'admin.curation-tasks.title', breadcrumbKey: 'admin.curation-tasks' }
|
data: { title: 'admin.curation-tasks.title', breadcrumbKey: 'admin.curation-tasks' }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'metadata-import',
|
||||||
|
resolve: { breadcrumb: I18nBreadcrumbResolver },
|
||||||
|
component: MetadataImportPageComponent,
|
||||||
|
data: { title: 'admin.metadata-import.title', breadcrumbKey: 'admin.metadata-import' }
|
||||||
|
},
|
||||||
])
|
])
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
|
@@ -2,13 +2,13 @@ import { Component, Injector, OnInit } from '@angular/core';
|
|||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { combineLatest as observableCombineLatest } from 'rxjs';
|
import { combineLatest as observableCombineLatest } from 'rxjs';
|
||||||
import { Observable } from 'rxjs/internal/Observable';
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
import { of } from 'rxjs/internal/observable/of';
|
import { first, map, take } from 'rxjs/operators';
|
||||||
import { first, map, take, tap, filter } from 'rxjs/operators';
|
|
||||||
import { AuthService } from '../../core/auth/auth.service';
|
import { AuthService } from '../../core/auth/auth.service';
|
||||||
import { ProcessDataService } from '../../core/data/processes/process-data.service';
|
import {
|
||||||
import { ScriptDataService } from '../../core/data/processes/script-data.service';
|
METADATA_EXPORT_SCRIPT_NAME,
|
||||||
import { RemoteData } from '../../core/data/remote-data';
|
METADATA_IMPORT_SCRIPT_NAME,
|
||||||
import { Script } from '../../process-page/scripts/script.model';
|
ScriptDataService
|
||||||
|
} from '../../core/data/processes/script-data.service';
|
||||||
import { slideHorizontal, slideSidebar } from '../../shared/animations/slide';
|
import { slideHorizontal, slideSidebar } from '../../shared/animations/slide';
|
||||||
import { CreateCollectionParentSelectorComponent } from '../../shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component';
|
import { CreateCollectionParentSelectorComponent } from '../../shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component';
|
||||||
import { CreateCommunityParentSelectorComponent } from '../../shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component';
|
import { CreateCommunityParentSelectorComponent } from '../../shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component';
|
||||||
@@ -17,8 +17,7 @@ import { EditCollectionSelectorComponent } from '../../shared/dso-selector/modal
|
|||||||
import { EditCommunitySelectorComponent } from '../../shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component';
|
import { EditCommunitySelectorComponent } from '../../shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component';
|
||||||
import { EditItemSelectorComponent } from '../../shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component';
|
import { EditItemSelectorComponent } from '../../shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component';
|
||||||
import {
|
import {
|
||||||
ExportMetadataSelectorComponent,
|
ExportMetadataSelectorComponent
|
||||||
METADATA_EXPORT_SCRIPT_NAME
|
|
||||||
} from '../../shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component';
|
} from '../../shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component';
|
||||||
import { MenuID, MenuItemType } from '../../shared/menu/initial-menus-state';
|
import { MenuID, MenuItemType } from '../../shared/menu/initial-menus-state';
|
||||||
import { LinkMenuItemModel } from '../../shared/menu/menu-item/models/link.model';
|
import { LinkMenuItemModel } from '../../shared/menu/menu-item/models/link.model';
|
||||||
@@ -86,6 +85,7 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
|
|||||||
this.createMenu();
|
this.createMenu();
|
||||||
this.createSiteAdministratorMenuSections();
|
this.createSiteAdministratorMenuSections();
|
||||||
this.createExportMenuSections();
|
this.createExportMenuSections();
|
||||||
|
this.createImportMenuSections();
|
||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
this.sidebarWidth = this.variableService.getVariable('sidebarItemsWidth');
|
this.sidebarWidth = this.variableService.getVariable('sidebarItemsWidth');
|
||||||
this.authService.isAuthenticated()
|
this.authService.isAuthenticated()
|
||||||
@@ -236,39 +236,18 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
|
|||||||
} as OnClickMenuItemModel,
|
} as OnClickMenuItemModel,
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Import */
|
/* Curation tasks */
|
||||||
{
|
{
|
||||||
id: 'import',
|
id: 'curation_tasks',
|
||||||
active: false,
|
|
||||||
visible: true,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.TEXT,
|
|
||||||
text: 'menu.section.import'
|
|
||||||
} as TextMenuItemModel,
|
|
||||||
icon: 'sign-in-alt',
|
|
||||||
index: 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'import_metadata',
|
|
||||||
parentID: 'import',
|
|
||||||
active: false,
|
active: false,
|
||||||
visible: true,
|
visible: true,
|
||||||
model: {
|
model: {
|
||||||
type: MenuItemType.LINK,
|
type: MenuItemType.LINK,
|
||||||
text: 'menu.section.import_metadata',
|
text: 'menu.section.curation_task',
|
||||||
link: ''
|
|
||||||
} as LinkMenuItemModel,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'import_batch',
|
|
||||||
parentID: 'import',
|
|
||||||
active: false,
|
|
||||||
visible: true,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.LINK,
|
|
||||||
text: 'menu.section.import_batch',
|
|
||||||
link: ''
|
link: ''
|
||||||
} as LinkMenuItemModel,
|
} as LinkMenuItemModel,
|
||||||
|
icon: 'filter',
|
||||||
|
index: 7
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Statistics */
|
/* Statistics */
|
||||||
@@ -401,6 +380,63 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create menu sections dependent on whether or not the current user is a site administrator and on whether or not
|
||||||
|
* the import scripts exist and the current user is allowed to execute them
|
||||||
|
*/
|
||||||
|
createImportMenuSections() {
|
||||||
|
const menuList = [
|
||||||
|
/* Import */
|
||||||
|
{
|
||||||
|
id: 'import',
|
||||||
|
active: false,
|
||||||
|
visible: true,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.TEXT,
|
||||||
|
text: 'menu.section.import'
|
||||||
|
} as TextMenuItemModel,
|
||||||
|
icon: 'sign-in-alt',
|
||||||
|
index: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'import_batch',
|
||||||
|
parentID: 'import',
|
||||||
|
active: false,
|
||||||
|
visible: true,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.LINK,
|
||||||
|
text: 'menu.section.import_batch',
|
||||||
|
link: ''
|
||||||
|
} as LinkMenuItemModel,
|
||||||
|
}
|
||||||
|
];
|
||||||
|
menuList.forEach((menuSection) => this.menuService.addSection(this.menuID, Object.assign(menuSection, {
|
||||||
|
shouldPersistOnRouteChange: true
|
||||||
|
})));
|
||||||
|
|
||||||
|
observableCombineLatest(
|
||||||
|
this.authorizationService.isAuthorized(FeatureID.AdministratorOf),
|
||||||
|
this.scriptDataService.scriptWithNameExistsAndCanExecute(METADATA_IMPORT_SCRIPT_NAME)
|
||||||
|
).pipe(
|
||||||
|
// TODO uncomment when #635 (https://github.com/DSpace/dspace-angular/issues/635) is fixed
|
||||||
|
// filter(([authorized, metadataImportScriptExists]: boolean[]) => authorized && metadataImportScriptExists),
|
||||||
|
take(1)
|
||||||
|
).subscribe(() => {
|
||||||
|
this.menuService.addSection(this.menuID, {
|
||||||
|
id: 'import_metadata',
|
||||||
|
parentID: 'import',
|
||||||
|
active: true,
|
||||||
|
visible: true,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.LINK,
|
||||||
|
text: 'menu.section.import_metadata',
|
||||||
|
link: '/admin/metadata-import'
|
||||||
|
} as LinkMenuItemModel,
|
||||||
|
shouldPersistOnRouteChange: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create menu sections dependent on whether or not the current user is a site administrator
|
* Create menu sections dependent on whether or not the current user is a site administrator
|
||||||
*/
|
*/
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { SharedModule } from '../shared/shared.module';
|
import { SharedModule } from '../shared/shared.module';
|
||||||
import { AdminAccessControlModule } from './admin-access-control/admin-access-control.module';
|
import { AdminAccessControlModule } from './admin-access-control/admin-access-control.module';
|
||||||
|
import { MetadataImportPageComponent } from './admin-import-metadata-page/metadata-import-page.component';
|
||||||
import { AdminRegistriesModule } from './admin-registries/admin-registries.module';
|
import { AdminRegistriesModule } from './admin-registries/admin-registries.module';
|
||||||
import { AdminRoutingModule } from './admin-routing.module';
|
import { AdminRoutingModule } from './admin-routing.module';
|
||||||
import { AdminSearchPageComponent } from './admin-search-page/admin-search-page.component';
|
import { AdminSearchPageComponent } from './admin-search-page/admin-search-page.component';
|
||||||
@@ -40,7 +41,9 @@ import { AdminCurationTasksComponent } from './admin-curation-tasks/admin-curati
|
|||||||
|
|
||||||
WorkflowItemSearchResultAdminWorkflowListElementComponent,
|
WorkflowItemSearchResultAdminWorkflowListElementComponent,
|
||||||
WorkflowItemSearchResultAdminWorkflowGridElementComponent,
|
WorkflowItemSearchResultAdminWorkflowGridElementComponent,
|
||||||
WorkflowItemAdminWorkflowActionsComponent
|
WorkflowItemAdminWorkflowActionsComponent,
|
||||||
|
|
||||||
|
MetadataImportPageComponent
|
||||||
|
|
||||||
],
|
],
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
@@ -54,7 +57,9 @@ import { AdminCurationTasksComponent } from './admin-curation-tasks/admin-curati
|
|||||||
|
|
||||||
WorkflowItemSearchResultAdminWorkflowListElementComponent,
|
WorkflowItemSearchResultAdminWorkflowListElementComponent,
|
||||||
WorkflowItemSearchResultAdminWorkflowGridElementComponent,
|
WorkflowItemSearchResultAdminWorkflowGridElementComponent,
|
||||||
WorkflowItemAdminWorkflowActionsComponent
|
WorkflowItemAdminWorkflowActionsComponent,
|
||||||
|
|
||||||
|
MetadataImportPageComponent
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AdminModule {
|
export class AdminModule {
|
||||||
|
@@ -1,8 +1,4 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import {
|
|
||||||
getSucceededRemoteData,
|
|
||||||
getFirstSucceededRemoteDataPayload
|
|
||||||
} from '../../shared/operators';
|
|
||||||
import { DataService } from '../data.service';
|
import { DataService } from '../data.service';
|
||||||
import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service';
|
import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
@@ -14,7 +10,7 @@ import { HttpClient } from '@angular/common/http';
|
|||||||
import { DefaultChangeAnalyzer } from '../default-change-analyzer.service';
|
import { DefaultChangeAnalyzer } from '../default-change-analyzer.service';
|
||||||
import { Script } from '../../../process-page/scripts/script.model';
|
import { Script } from '../../../process-page/scripts/script.model';
|
||||||
import { ProcessParameter } from '../../../process-page/processes/process-parameter.model';
|
import { ProcessParameter } from '../../../process-page/processes/process-parameter.model';
|
||||||
import { find, map, switchMap, filter } from 'rxjs/operators';
|
import { find, map, switchMap } from 'rxjs/operators';
|
||||||
import { URLCombiner } from '../../url-combiner/url-combiner';
|
import { URLCombiner } from '../../url-combiner/url-combiner';
|
||||||
import { RemoteData } from '../remote-data';
|
import { RemoteData } from '../remote-data';
|
||||||
import { MultipartPostRequest, RestRequest } from '../request.models';
|
import { MultipartPostRequest, RestRequest } from '../request.models';
|
||||||
@@ -25,6 +21,9 @@ import { dataService } from '../../cache/builders/build-decorators';
|
|||||||
import { SCRIPT } from '../../../process-page/scripts/script.resource-type';
|
import { SCRIPT } from '../../../process-page/scripts/script.resource-type';
|
||||||
import { hasValue } from '../../../shared/empty.util';
|
import { hasValue } from '../../../shared/empty.util';
|
||||||
|
|
||||||
|
export const METADATA_IMPORT_SCRIPT_NAME: string = 'metadata-import';
|
||||||
|
export const METADATA_EXPORT_SCRIPT_NAME: string = 'metadata-export';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@dataService(SCRIPT)
|
@dataService(SCRIPT)
|
||||||
export class ScriptDataService extends DataService<Script> {
|
export class ScriptDataService extends DataService<Script> {
|
||||||
|
@@ -5,7 +5,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
|||||||
import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
|
import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { ScriptDataService } from '../../../../core/data/processes/script-data.service';
|
import { METADATA_EXPORT_SCRIPT_NAME, ScriptDataService } from '../../../../core/data/processes/script-data.service';
|
||||||
import { Collection } from '../../../../core/shared/collection.model';
|
import { Collection } from '../../../../core/shared/collection.model';
|
||||||
import { Community } from '../../../../core/shared/community.model';
|
import { Community } from '../../../../core/shared/community.model';
|
||||||
import { Item } from '../../../../core/shared/item.model';
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
@@ -13,7 +13,7 @@ import { ProcessParameter } from '../../../../process-page/processes/process-par
|
|||||||
import { NotificationsService } from '../../../notifications/notifications.service';
|
import { NotificationsService } from '../../../notifications/notifications.service';
|
||||||
import { NotificationsServiceStub } from '../../../testing/notifications-service.stub';
|
import { NotificationsServiceStub } from '../../../testing/notifications-service.stub';
|
||||||
import { createSuccessfulRemoteDataObject } from '../../../remote-data.utils';
|
import { createSuccessfulRemoteDataObject } from '../../../remote-data.utils';
|
||||||
import { ExportMetadataSelectorComponent, METADATA_EXPORT_SCRIPT_NAME } from './export-metadata-selector.component';
|
import { ExportMetadataSelectorComponent } from './export-metadata-selector.component';
|
||||||
|
|
||||||
describe('ExportMetadataSelectorComponent', () => {
|
describe('ExportMetadataSelectorComponent', () => {
|
||||||
let component: ExportMetadataSelectorComponent;
|
let component: ExportMetadataSelectorComponent;
|
||||||
|
@@ -4,7 +4,7 @@ import { TranslateService } from '@ngx-translate/core';
|
|||||||
import { Observable } from 'rxjs/internal/Observable';
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
import { take, map } from 'rxjs/operators';
|
import { take, map } from 'rxjs/operators';
|
||||||
import { of as observableOf } from 'rxjs';
|
import { of as observableOf } from 'rxjs';
|
||||||
import { ScriptDataService } from '../../../../core/data/processes/script-data.service';
|
import { METADATA_EXPORT_SCRIPT_NAME, ScriptDataService } from '../../../../core/data/processes/script-data.service';
|
||||||
import { RequestEntry } from '../../../../core/data/request.reducer';
|
import { RequestEntry } from '../../../../core/data/request.reducer';
|
||||||
import { Collection } from '../../../../core/shared/collection.model';
|
import { Collection } from '../../../../core/shared/collection.model';
|
||||||
import { Community } from '../../../../core/shared/community.model';
|
import { Community } from '../../../../core/shared/community.model';
|
||||||
@@ -16,8 +16,6 @@ import { isNotEmpty } from '../../../empty.util';
|
|||||||
import { NotificationsService } from '../../../notifications/notifications.service';
|
import { NotificationsService } from '../../../notifications/notifications.service';
|
||||||
import { DSOSelectorModalWrapperComponent, SelectorActionType } from '../dso-selector-modal-wrapper.component';
|
import { DSOSelectorModalWrapperComponent, SelectorActionType } from '../dso-selector-modal-wrapper.component';
|
||||||
|
|
||||||
export const METADATA_EXPORT_SCRIPT_NAME: string = 'metadata-export';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to wrap a list of existing dso's inside a modal
|
* Component to wrap a list of existing dso's inside a modal
|
||||||
* Used to choose a dso from to export metadata of
|
* Used to choose a dso from to export metadata of
|
||||||
|
@@ -442,6 +442,24 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"admin.metadata-import.breadcrumbs": "Import Metadata",
|
||||||
|
|
||||||
|
"admin.metadata-import.title": "Import Metadata",
|
||||||
|
|
||||||
|
"admin.metadata-import.page.header": "Import Metadata",
|
||||||
|
|
||||||
|
"admin.metadata-import.page.help": "You can drop or browse CSV files that contain batch metadata operations on files here",
|
||||||
|
|
||||||
|
"admin.metadata-import.page.dropMsg": "Drop a metadata CSV to upload",
|
||||||
|
|
||||||
|
"admin.metadata-import.page.button.return": "Return",
|
||||||
|
|
||||||
|
"admin.metadata-import.page.button.proceed": "Proceed",
|
||||||
|
|
||||||
|
"admin.metadata-import.page.error.addFile": "Select file first!",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"auth.errors.invalid-user": "Invalid email address or password.",
|
"auth.errors.invalid-user": "Invalid email address or password.",
|
||||||
|
|
||||||
@@ -3092,6 +3110,6 @@
|
|||||||
|
|
||||||
"workflow-item.send-back.button.cancel": "Cancel",
|
"workflow-item.send-back.button.cancel": "Cancel",
|
||||||
|
|
||||||
"workflow-item.send-back.button.confirm": "Send back",
|
"workflow-item.send-back.button.confirm": "Send back"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user