From 902d4c2330304ee48597118ea1ea91d50db26fd3 Mon Sep 17 00:00:00 2001 From: Marie Verdonck Date: Mon, 6 Jul 2020 19:18:40 +0200 Subject: [PATCH 01/29] 71712: Export metadata CSV; WIP --- .../admin-sidebar/admin-sidebar.component.ts | 149 +++++++++++------- src/app/app.component.ts | 1 - .../data/processes/script-data.service.ts | 21 +++ .../core/shared/dspace-object-type.model.ts | 1 + .../dso-selector/dso-selector.component.ts | 2 +- .../dso-selector-modal-wrapper.component.ts | 7 +- .../edit-item-selector.component.spec.ts | 2 - .../export-metadata-selector.component.ts | 79 ++++++++++ src/app/shared/shared.module.ts | 5 +- src/assets/i18n/en.json5 | 4 + 10 files changed, 205 insertions(+), 66 deletions(-) create mode 100644 src/app/shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component.ts diff --git a/src/app/+admin/admin-sidebar/admin-sidebar.component.ts b/src/app/+admin/admin-sidebar/admin-sidebar.component.ts index eb86de5f3c..2a911f6097 100644 --- a/src/app/+admin/admin-sidebar/admin-sidebar.component.ts +++ b/src/app/+admin/admin-sidebar/admin-sidebar.component.ts @@ -2,8 +2,13 @@ import { Component, Injector, OnInit } from '@angular/core'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { combineLatest as combineLatestObservable } from 'rxjs'; import { Observable } from 'rxjs/internal/Observable'; -import { first, map } from 'rxjs/operators'; +import { of } from 'rxjs/internal/observable/of'; +import { first, map, take } from 'rxjs/operators'; import { AuthService } from '../../core/auth/auth.service'; +import { ProcessDataService } from '../../core/data/processes/process-data.service'; +import { ScriptDataService } from '../../core/data/processes/script-data.service'; +import { RemoteData } from '../../core/data/remote-data'; +import { Script } from '../../process-page/scripts/script.model'; 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 { CreateCommunityParentSelectorComponent } from '../../shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component'; @@ -11,6 +16,10 @@ import { CreateItemParentSelectorComponent } from '../../shared/dso-selector/mod import { EditCollectionSelectorComponent } from '../../shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-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 { + ExportMetadataSelectorComponent, + METADATA_EXPORT_SCRIPT_NAME +} from '../../shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component'; import { MenuID, MenuItemType } from '../../shared/menu/initial-menus-state'; import { LinkMenuItemModel } from '../../shared/menu/menu-item/models/link.model'; import { OnClickMenuItemModel } from '../../shared/menu/menu-item/models/onclick.model'; @@ -64,7 +73,8 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit { private variableService: CSSVariableService, private authService: AuthService, private modalService: NgbModal, - private authorizationService: AuthorizationDataService + private authorizationService: AuthorizationDataService, + private scriptDataService: ScriptDataService, ) { super(menuService, injector); } @@ -75,6 +85,7 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit { ngOnInit(): void { this.createMenu(); this.createSiteAdministratorMenuSections(); + this.createExportMenuSections(); super.ngOnInit(); this.sidebarWidth = this.variableService.getVariable('sidebarItemsWidth'); this.authService.isAuthenticated() @@ -259,61 +270,6 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit { link: '' } as LinkMenuItemModel, }, - /* Export */ - { - id: 'export', - active: false, - visible: true, - model: { - type: MenuItemType.TEXT, - text: 'menu.section.export' - } as TextMenuItemModel, - icon: 'sign-out-alt', - index: 3 - }, - { - id: 'export_community', - parentID: 'export', - active: false, - visible: true, - model: { - type: MenuItemType.LINK, - text: 'menu.section.export_community', - link: '' - } as LinkMenuItemModel, - }, - { - id: 'export_collection', - parentID: 'export', - active: false, - visible: true, - model: { - type: MenuItemType.LINK, - text: 'menu.section.export_collection', - link: '' - } as LinkMenuItemModel, - }, - { - id: 'export_item', - parentID: 'export', - active: false, - visible: true, - model: { - type: MenuItemType.LINK, - text: 'menu.section.export_item', - link: '' - } as LinkMenuItemModel, - }, { - id: 'export_metadata', - parentID: 'export', - active: false, - visible: true, - model: { - type: MenuItemType.LINK, - text: 'menu.section.export_metadata', - link: '' - } as LinkMenuItemModel, - }, /* Statistics */ { @@ -362,6 +318,85 @@ 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 export scripts exist and the current user is allowed to execute them + */ + createExportMenuSections() { + const isAuthorized$: Observable = this.authorizationService.isAuthorized(FeatureID.AdministratorOf); + isAuthorized$.subscribe((authorized: boolean) => { + if (authorized) { + const metadataExportScriptExists$ = this.scriptDataService.scripWithNameExistsAndCanExecute(METADATA_EXPORT_SCRIPT_NAME); + metadataExportScriptExists$.subscribe((metadataExportScriptExists: boolean) => { + const menuList = [ + /* Export */ + { + id: 'export', + active: false, + visible: true, + model: { + type: MenuItemType.TEXT, + text: 'menu.section.export' + } as TextMenuItemModel, + icon: 'sign-out-alt', + index: 3 + }, + { + id: 'export_community', + parentID: 'export', + active: false, + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.export_community', + link: '' + } as LinkMenuItemModel, + }, + { + id: 'export_collection', + parentID: 'export', + active: false, + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.export_collection', + link: '' + } as LinkMenuItemModel, + }, + { + id: 'export_item', + parentID: 'export', + active: false, + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.export_item', + link: '' + } as LinkMenuItemModel, + }, + { + id: 'export_metadata', + parentID: 'export', + active: true, + visible: authorized && metadataExportScriptExists, + model: { + type: MenuItemType.ONCLICK, + text: 'menu.section.export_metadata', + function: () => { + this.modalService.open(ExportMetadataSelectorComponent); + } + } as OnClickMenuItemModel, + }, + ]; + menuList.forEach((menuSection) => this.menuService.addSection(this.menuID, Object.assign(menuSection, { + shouldPersistOnRouteChange: true + }))); + }); + } + }); + + } + /** * Create menu sections dependent on whether or not the current user is a site administrator */ diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 35ca4db131..10f81a9adc 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -21,7 +21,6 @@ import { HostWindowState } from './shared/search/host-window.reducer'; import { NativeWindowRef, NativeWindowService } from './core/services/window.service'; import { isAuthenticated } from './core/auth/selectors'; import { AuthService } from './core/auth/auth.service'; -import variables from '../styles/_exposed_variables.scss'; import { CSSVariableService } from './shared/sass-helper/sass-helper.service'; import { MenuService } from './shared/menu/menu.service'; import { MenuID } from './shared/menu/initial-menus-state'; diff --git a/src/app/core/data/processes/script-data.service.ts b/src/app/core/data/processes/script-data.service.ts index 6600444ea0..2dcc6e364d 100644 --- a/src/app/core/data/processes/script-data.service.ts +++ b/src/app/core/data/processes/script-data.service.ts @@ -1,4 +1,5 @@ import { Injectable } from '@angular/core'; +import { getRemoteDataPayload, getSucceededRemoteData } from '../../shared/operators'; import { DataService } from '../data.service'; import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; @@ -12,6 +13,7 @@ import { Script } from '../../../process-page/scripts/script.model'; import { ProcessParameter } from '../../../process-page/processes/process-parameter.model'; import { find, map, switchMap } from 'rxjs/operators'; import { URLCombiner } from '../../url-combiner/url-combiner'; +import { PaginatedList } from '../paginated-list'; import { MultipartPostRequest, RestRequest } from '../request.models'; import { RequestService } from '../request.service'; import { Observable } from 'rxjs'; @@ -58,4 +60,23 @@ export class ScriptDataService extends DataService