Autofix lint issues

This commit is contained in:
Yury Bondarenko
2024-03-06 10:30:19 +01:00
parent dbf7fd67fd
commit 2b540cd91c
483 changed files with 9002 additions and 4652 deletions

View File

@@ -1,16 +1,40 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core'; import {
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; DebugElement,
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; NO_ERRORS_SCHEMA,
import { BrowserModule, By } from '@angular/platform-browser'; } from '@angular/core';
import {
ComponentFixture,
fakeAsync,
TestBed,
tick,
waitForAsync,
} from '@angular/core/testing';
import {
FormsModule,
ReactiveFormsModule,
} from '@angular/forms';
import {
BrowserModule,
By,
} from '@angular/platform-browser';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { NgbModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'; import {
NgbModal,
NgbModule,
} from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { Observable, of as observableOf } from 'rxjs'; import {
Observable,
of as observableOf,
} from 'rxjs';
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
import { FindListOptions } from '../../core/data/find-list-options.model'; import { FindListOptions } from '../../core/data/find-list-options.model';
import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model'; import {
buildPaginatedList,
PaginatedList,
} from '../../core/data/paginated-list.model';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { RequestService } from '../../core/data/request.service'; import { RequestService } from '../../core/data/request.service';
import { EPersonDataService } from '../../core/eperson/eperson-data.service'; import { EPersonDataService } from '../../core/eperson/eperson-data.service';
@@ -21,7 +45,10 @@ import { FormBuilderService } from '../../shared/form/builder/form-builder.servi
import { getMockFormBuilderService } from '../../shared/mocks/form-builder-service.mock'; import { getMockFormBuilderService } from '../../shared/mocks/form-builder-service.mock';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import { EPersonMock, EPersonMock2 } from '../../shared/testing/eperson.mock'; import {
EPersonMock,
EPersonMock2,
} from '../../shared/testing/eperson.mock';
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub'; import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
import { RouterStub } from '../../shared/testing/router.stub'; import { RouterStub } from '../../shared/testing/router.stub';

View File

@@ -1,15 +1,31 @@
import { Component, OnDestroy, OnInit } from '@angular/core'; import {
Component,
OnDestroy,
OnInit,
} from '@angular/core';
import { UntypedFormBuilder } from '@angular/forms'; import { UntypedFormBuilder } from '@angular/forms';
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 { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject, combineLatest, Observable, Subscription } from 'rxjs'; import {
import { map, switchMap, take } from 'rxjs/operators'; BehaviorSubject,
combineLatest,
Observable,
Subscription,
} from 'rxjs';
import {
map,
switchMap,
take,
} from 'rxjs/operators';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
import { FeatureID } from '../../core/data/feature-authorization/feature-id'; import { FeatureID } from '../../core/data/feature-authorization/feature-id';
import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model'; import {
buildPaginatedList,
PaginatedList,
} from '../../core/data/paginated-list.model';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { RequestService } from '../../core/data/request.service'; import { RequestService } from '../../core/data/request.service';
import { EPersonDataService } from '../../core/eperson/eperson-data.service'; import { EPersonDataService } from '../../core/eperson/eperson-data.service';
@@ -17,13 +33,19 @@ import { EPerson } from '../../core/eperson/models/eperson.model';
import { EpersonDtoModel } from '../../core/eperson/models/eperson-dto.model'; import { EpersonDtoModel } from '../../core/eperson/models/eperson-dto.model';
import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationService } from '../../core/pagination/pagination.service';
import { NoContent } from '../../core/shared/NoContent.model'; import { NoContent } from '../../core/shared/NoContent.model';
import { getAllSucceededRemoteData, getFirstCompletedRemoteData } from '../../core/shared/operators'; import {
getAllSucceededRemoteData,
getFirstCompletedRemoteData,
} from '../../core/shared/operators';
import { PageInfo } from '../../core/shared/page-info.model'; import { PageInfo } from '../../core/shared/page-info.model';
import { ConfirmationModalComponent } from '../../shared/confirmation-modal/confirmation-modal.component'; import { ConfirmationModalComponent } from '../../shared/confirmation-modal/confirmation-modal.component';
import { hasValue } from '../../shared/empty.util'; import { hasValue } from '../../shared/empty.util';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { getEPersonEditRoute, getEPersonsRoute } from '../access-control-routing-paths'; import {
getEPersonEditRoute,
getEPersonsRoute,
} from '../access-control-routing-paths';
@Component({ @Component({
selector: 'ds-epeople-registry', selector: 'ds-epeople-registry',

View File

@@ -1,11 +1,37 @@
import { ChangeDetectorRef, Component, EventEmitter, OnDestroy, OnInit, Output } from '@angular/core'; import {
ChangeDetectorRef,
Component,
EventEmitter,
OnDestroy,
OnInit,
Output,
} from '@angular/core';
import { UntypedFormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router'; import {
ActivatedRoute,
Router,
} from '@angular/router';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { DynamicCheckboxModel, DynamicFormControlModel, DynamicFormLayout, DynamicInputModel } from '@ng-dynamic-forms/core'; import {
DynamicCheckboxModel,
DynamicFormControlModel,
DynamicFormLayout,
DynamicInputModel,
} from '@ng-dynamic-forms/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { combineLatest as observableCombineLatest, Observable, of as observableOf, Subscription } from 'rxjs'; import {
import { debounceTime, finalize, map, switchMap, take } from 'rxjs/operators'; combineLatest as observableCombineLatest,
Observable,
of as observableOf,
Subscription,
} from 'rxjs';
import {
debounceTime,
finalize,
map,
switchMap,
take,
} from 'rxjs/operators';
import { AuthService } from '../../../core/auth/auth.service'; import { AuthService } from '../../../core/auth/auth.service';
import { DSONameService } from '../../../core/breadcrumbs/dso-name.service'; import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
@@ -21,7 +47,11 @@ import { EPerson } from '../../../core/eperson/models/eperson.model';
import { Group } from '../../../core/eperson/models/group.model'; import { Group } from '../../../core/eperson/models/group.model';
import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationService } from '../../../core/pagination/pagination.service';
import { NoContent } from '../../../core/shared/NoContent.model'; import { NoContent } from '../../../core/shared/NoContent.model';
import { getFirstCompletedRemoteData, getFirstSucceededRemoteData, getRemoteDataPayload } from '../../../core/shared/operators'; import {
getFirstCompletedRemoteData,
getFirstSucceededRemoteData,
getRemoteDataPayload,
} from '../../../core/shared/operators';
import { PageInfo } from '../../../core/shared/page-info.model'; import { PageInfo } from '../../../core/shared/page-info.model';
import { Registration } from '../../../core/shared/registration.model'; import { Registration } from '../../../core/shared/registration.model';
import { TYPE_REQUEST_FORGOT } from '../../../register-email-form/register-email-form.component'; import { TYPE_REQUEST_FORGOT } from '../../../register-email-form/register-email-form.component';

View File

@@ -1,12 +1,40 @@
import { ChangeDetectorRef, Component, EventEmitter, HostListener, OnDestroy, OnInit, Output } from '@angular/core'; import {
ChangeDetectorRef,
Component,
EventEmitter,
HostListener,
OnDestroy,
OnInit,
Output,
} from '@angular/core';
import { UntypedFormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router'; import {
ActivatedRoute,
Router,
} from '@angular/router';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { DynamicFormControlModel, DynamicFormLayout, DynamicInputModel, DynamicTextAreaModel } from '@ng-dynamic-forms/core'; import {
DynamicFormControlModel,
DynamicFormLayout,
DynamicInputModel,
DynamicTextAreaModel,
} from '@ng-dynamic-forms/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { Operation } from 'fast-json-patch'; import { Operation } from 'fast-json-patch';
import { combineLatest as observableCombineLatest, Observable, of as observableOf, Subscription } from 'rxjs'; import {
import { catchError, debounceTime, filter, map, switchMap, take } from 'rxjs/operators'; combineLatest as observableCombineLatest,
Observable,
of as observableOf,
Subscription,
} from 'rxjs';
import {
catchError,
debounceTime,
filter,
map,
switchMap,
take,
} from 'rxjs/operators';
import { environment } from '../../../../environments/environment'; import { environment } from '../../../../environments/environment';
import { getCollectionEditRolesRoute } from '../../../collection-page/collection-page-routing-paths'; import { getCollectionEditRolesRoute } from '../../../collection-page/collection-page-routing-paths';
@@ -25,14 +53,26 @@ import { Collection } from '../../../core/shared/collection.model';
import { Community } from '../../../core/shared/community.model'; import { Community } from '../../../core/shared/community.model';
import { DSpaceObject } from '../../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { NoContent } from '../../../core/shared/NoContent.model'; import { NoContent } from '../../../core/shared/NoContent.model';
import { getFirstCompletedRemoteData, getFirstSucceededRemoteData, getFirstSucceededRemoteDataPayload, getRemoteDataPayload } from '../../../core/shared/operators'; import {
getFirstCompletedRemoteData,
getFirstSucceededRemoteData,
getFirstSucceededRemoteDataPayload,
getRemoteDataPayload,
} from '../../../core/shared/operators';
import { AlertType } from '../../../shared/alert/alert-type'; import { AlertType } from '../../../shared/alert/alert-type';
import { ConfirmationModalComponent } from '../../../shared/confirmation-modal/confirmation-modal.component'; import { ConfirmationModalComponent } from '../../../shared/confirmation-modal/confirmation-modal.component';
import { hasValue, hasValueOperator, isNotEmpty } from '../../../shared/empty.util'; import {
hasValue,
hasValueOperator,
isNotEmpty,
} from '../../../shared/empty.util';
import { FormBuilderService } from '../../../shared/form/builder/form-builder.service'; import { FormBuilderService } from '../../../shared/form/builder/form-builder.service';
import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { followLink } from '../../../shared/utils/follow-link-config.model'; import { followLink } from '../../../shared/utils/follow-link-config.model';
import { getGroupEditRoute, getGroupsRoute } from '../../access-control-routing-paths'; import {
getGroupEditRoute,
getGroupsRoute,
} from '../../access-control-routing-paths';
import { ValidateGroupExists } from './validators/group-exists.validator'; import { ValidateGroupExists } from './validators/group-exists.validator';
@Component({ @Component({

View File

@@ -1,29 +1,33 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import {
import { LdnServicesOverviewComponent } from './ldn-services-directory/ldn-services-directory.component'; RouterModule,
import { NavigationBreadcrumbResolver } from '../../core/breadcrumbs/navigation-breadcrumb.resolver'; Routes,
} from '@angular/router';
import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver'; import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver';
import { NavigationBreadcrumbResolver } from '../../core/breadcrumbs/navigation-breadcrumb.resolver';
import { LdnServiceFormComponent } from './ldn-service-form/ldn-service-form.component'; import { LdnServiceFormComponent } from './ldn-service-form/ldn-service-form.component';
import { LdnServicesOverviewComponent } from './ldn-services-directory/ldn-services-directory.component';
const moduleRoutes: Routes = [ const moduleRoutes: Routes = [
{ {
path: '', path: '',
pathMatch: 'full', pathMatch: 'full',
component: LdnServicesOverviewComponent, component: LdnServicesOverviewComponent,
resolve: {breadcrumb: I18nBreadcrumbResolver}, resolve: { breadcrumb: I18nBreadcrumbResolver },
data: {title: 'ldn-registered-services.title', breadcrumbKey: 'ldn-registered-services.new'}, data: { title: 'ldn-registered-services.title', breadcrumbKey: 'ldn-registered-services.new' },
}, },
{ {
path: 'new', path: 'new',
resolve: {breadcrumb: NavigationBreadcrumbResolver}, resolve: { breadcrumb: NavigationBreadcrumbResolver },
component: LdnServiceFormComponent, component: LdnServiceFormComponent,
data: {title: 'ldn-register-new-service.title', breadcrumbKey: 'ldn-register-new-service'} data: { title: 'ldn-register-new-service.title', breadcrumbKey: 'ldn-register-new-service' },
}, },
{ {
path: 'edit/:serviceId', path: 'edit/:serviceId',
resolve: {breadcrumb: NavigationBreadcrumbResolver}, resolve: { breadcrumb: NavigationBreadcrumbResolver },
component: LdnServiceFormComponent, component: LdnServiceFormComponent,
data: {title: 'ldn-edit-service.title', breadcrumbKey: 'ldn-edit-service'} data: { title: 'ldn-edit-service.title', breadcrumbKey: 'ldn-edit-service' },
}, },
]; ];
@@ -31,15 +35,15 @@ const moduleRoutes: Routes = [
@NgModule({ @NgModule({
imports: [ imports: [
RouterModule.forChild(moduleRoutes.map(route => { RouterModule.forChild(moduleRoutes.map(route => {
return {...route, data: { return { ...route, data: {
...route.data, ...route.data,
relatedRoutes: moduleRoutes.filter(relatedRoute => relatedRoute.path !== route.path) relatedRoutes: moduleRoutes.filter(relatedRoute => relatedRoute.path !== route.path)
.map((relatedRoute) => { .map((relatedRoute) => {
return {path: relatedRoute.path, data: relatedRoute.data}; return { path: relatedRoute.path, data: relatedRoute.data };
}) }),
}}; } };
})) })),
] ],
}) })
export class AdminLdnServicesRoutingModule { export class AdminLdnServicesRoutingModule {

View File

@@ -1,24 +1,25 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { AdminLdnServicesRoutingModule } from './admin-ldn-services-routing.module'; import { NgModule } from '@angular/core';
import { LdnServicesOverviewComponent } from './ldn-services-directory/ldn-services-directory.component';
import { SharedModule } from '../../shared/shared.module';
import { LdnServiceFormComponent } from './ldn-service-form/ldn-service-form.component';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { SharedModule } from '../../shared/shared.module';
import { AdminLdnServicesRoutingModule } from './admin-ldn-services-routing.module';
import { LdnServiceFormComponent } from './ldn-service-form/ldn-service-form.component';
import { LdnItemfiltersService } from './ldn-services-data/ldn-itemfilters-data.service'; import { LdnItemfiltersService } from './ldn-services-data/ldn-itemfilters-data.service';
import { LdnServicesOverviewComponent } from './ldn-services-directory/ldn-services-directory.component';
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, CommonModule,
SharedModule, SharedModule,
AdminLdnServicesRoutingModule, AdminLdnServicesRoutingModule,
FormsModule FormsModule,
], ],
declarations: [ declarations: [
LdnServicesOverviewComponent, LdnServicesOverviewComponent,
LdnServiceFormComponent, LdnServiceFormComponent,
], ],
providers: [LdnItemfiltersService] providers: [LdnItemfiltersService],
}) })
export class AdminLdnServicesModule { export class AdminLdnServicesModule {
} }

View File

@@ -1,23 +1,49 @@
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import {
ChangeDetectorRef,
import { NgbDropdownModule, NgbModal } from '@ng-bootstrap/ng-bootstrap'; EventEmitter,
import { LdnServiceFormComponent } from './ldn-service-form.component'; } from '@angular/core';
import { ChangeDetectorRef, EventEmitter } from '@angular/core'; import {
import { FormArray, FormBuilder, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; ComponentFixture,
import { ActivatedRoute, Router } from '@angular/router'; fakeAsync,
import { TranslateModule, TranslateService } from '@ngx-translate/core'; TestBed,
tick,
} from '@angular/core/testing';
import {
FormArray,
FormBuilder,
FormControl,
FormGroup,
ReactiveFormsModule,
} from '@angular/forms';
import { By } from '@angular/platform-browser';
import {
ActivatedRoute,
Router,
} from '@angular/router';
import {
NgbDropdownModule,
NgbModal,
} from '@ng-bootstrap/ng-bootstrap';
import { provideMockStore } from '@ngrx/store/testing';
import {
TranslateModule,
TranslateService,
} from '@ngx-translate/core';
import { PaginationService } from 'ngx-pagination'; import { PaginationService } from 'ngx-pagination';
import {
of as observableOf,
of,
} from 'rxjs';
import { RouteService } from '../../../core/services/route.service';
import { MockActivatedRoute } from '../../../shared/mocks/active-router.mock';
import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub';
import { RouterStub } from '../../../shared/testing/router.stub';
import { LdnItemfiltersService } from '../ldn-services-data/ldn-itemfilters-data.service'; import { LdnItemfiltersService } from '../ldn-services-data/ldn-itemfilters-data.service';
import { LdnServicesService } from '../ldn-services-data/ldn-services-data.service'; import { LdnServicesService } from '../ldn-services-data/ldn-services-data.service';
import { RouterStub } from '../../../shared/testing/router.stub'; import { LdnServiceFormComponent } from './ldn-service-form.component';
import { MockActivatedRoute } from '../../../shared/mocks/active-router.mock';
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub';
import { of as observableOf, of } from 'rxjs';
import { RouteService } from '../../../core/services/route.service';
import { provideMockStore } from '@ngrx/store/testing';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
import { By } from '@angular/platform-browser';
describe('LdnServiceFormEditComponent', () => { describe('LdnServiceFormEditComponent', () => {
let component: LdnServiceFormComponent; let component: LdnServiceFormComponent;
@@ -33,7 +59,7 @@ describe('LdnServiceFormEditComponent', () => {
const routeParams = { const routeParams = {
serviceId: testId, serviceId: testId,
}; };
const routeUrlSegments = [{path: 'path'}]; const routeUrlSegments = [{ path: 'path' }];
const formMockValue = { const formMockValue = {
'id': '', 'id': '',
'name': 'name', 'name': 'name',
@@ -52,9 +78,9 @@ describe('LdnServiceFormEditComponent', () => {
'pattern': '', 'pattern': '',
'patternLabel': 'Select a pattern', 'patternLabel': 'Select a pattern',
'constraint': '', 'constraint': '',
'automatic': false 'automatic': false,
} },
] ],
}; };
@@ -63,7 +89,7 @@ describe('LdnServiceFormEditComponent', () => {
instant: () => 'translated-text', instant: () => 'translated-text',
onLangChange: new EventEmitter(), onLangChange: new EventEmitter(),
onTranslationChange: new EventEmitter(), onTranslationChange: new EventEmitter(),
onDefaultLangChange: new EventEmitter() onDefaultLangChange: new EventEmitter(),
}; };
beforeEach(async () => { beforeEach(async () => {
@@ -77,11 +103,11 @@ describe('LdnServiceFormEditComponent', () => {
findAll: () => of(['item1', 'item2']), findAll: () => of(['item1', 'item2']),
}; };
cdRefStub = Object.assign({ cdRefStub = Object.assign({
detectChanges: () => fixture.detectChanges() detectChanges: () => fixture.detectChanges(),
}); });
modalService = { modalService = {
open: () => {/*comment*/ open: () => {/*comment*/
} },
}; };
@@ -91,19 +117,19 @@ describe('LdnServiceFormEditComponent', () => {
imports: [ReactiveFormsModule, TranslateModule.forRoot(), NgbDropdownModule], imports: [ReactiveFormsModule, TranslateModule.forRoot(), NgbDropdownModule],
declarations: [LdnServiceFormComponent], declarations: [LdnServiceFormComponent],
providers: [ providers: [
{provide: LdnServicesService, useValue: ldnServicesService}, { provide: LdnServicesService, useValue: ldnServicesService },
{provide: LdnItemfiltersService, useValue: ldnItemfiltersService}, { provide: LdnItemfiltersService, useValue: ldnItemfiltersService },
{provide: Router, useValue: new RouterStub()}, { provide: Router, useValue: new RouterStub() },
{provide: ActivatedRoute, useValue: activatedRoute}, { provide: ActivatedRoute, useValue: activatedRoute },
{provide: ChangeDetectorRef, useValue: cdRefStub}, { provide: ChangeDetectorRef, useValue: cdRefStub },
{provide: NgbModal, useValue: modalService}, { provide: NgbModal, useValue: modalService },
{provide: NotificationsService, useValue: new NotificationsServiceStub()}, { provide: NotificationsService, useValue: new NotificationsServiceStub() },
{provide: TranslateService, useValue: translateServiceStub}, { provide: TranslateService, useValue: translateServiceStub },
{provide: PaginationService, useValue: {}}, { provide: PaginationService, useValue: {} },
FormBuilder, FormBuilder,
RouteService, RouteService,
provideMockStore({}), provideMockStore({}),
] ],
}) })
.compileComponents(); .compileComponents();
@@ -139,7 +165,7 @@ describe('LdnServiceFormEditComponent', () => {
it('should handle create service with valid form', () => { it('should handle create service with valid form', () => {
spyOn(component, 'fetchServiceData').and.callFake((a) => a); spyOn(component, 'fetchServiceData').and.callFake((a) => a);
component.formModel.addControl('notifyServiceInboundPatterns', (component as any).formBuilder.array([{pattern: 'patternValue'}])); component.formModel.addControl('notifyServiceInboundPatterns', (component as any).formBuilder.array([{ pattern: 'patternValue' }]));
const nameInput = fixture.debugElement.query(By.css('#name')); const nameInput = fixture.debugElement.query(By.css('#name'));
const descriptionInput = fixture.debugElement.query(By.css('#description')); const descriptionInput = fixture.debugElement.query(By.css('#description'));
const urlInput = fixture.debugElement.query(By.css('#url')); const urlInput = fixture.debugElement.query(By.css('#url'));
@@ -184,7 +210,7 @@ describe('LdnServiceFormEditComponent', () => {
spyOn(component.formModel, 'markAllAsTouched'); spyOn(component.formModel, 'markAllAsTouched');
spyOn(component, 'closeModal'); spyOn(component, 'closeModal');
spyOn(component, 'checkPatterns').and.callFake(() => true); spyOn(component, 'checkPatterns').and.callFake(() => true);
component.formModel.addControl('notifyServiceInboundPatterns', (component as any).formBuilder.array([{pattern: 'patternValue'}])); component.formModel.addControl('notifyServiceInboundPatterns', (component as any).formBuilder.array([{ pattern: 'patternValue' }]));
component.formModel.patchValue(formMockValue); component.formModel.patchValue(formMockValue);
component.createService(); component.createService();
@@ -196,13 +222,13 @@ describe('LdnServiceFormEditComponent', () => {
it('should check patterns', () => { it('should check patterns', () => {
const arrValid = new FormArray([ const arrValid = new FormArray([
new FormGroup({ new FormGroup({
pattern: new FormControl('pattern') pattern: new FormControl('pattern'),
}), }),
]); ]);
const arrInvalid = new FormArray([ const arrInvalid = new FormArray([
new FormGroup({ new FormGroup({
pattern: new FormControl('') pattern: new FormControl(''),
}), }),
]); ]);

View File

@@ -1,25 +1,51 @@
import { ChangeDetectorRef, Component, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core'; import {
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; animate,
import { LDN_SERVICE } from '../ldn-services-model/ldn-service.resource-type'; state,
import { ActivatedRoute, Router } from '@angular/router'; style,
import { LdnServicesService } from '../ldn-services-data/ldn-services-data.service'; transition,
import { notifyPatterns } from '../ldn-services-patterns/ldn-service-coar-patterns'; trigger,
import { animate, state, style, transition, trigger } from '@angular/animations'; } from '@angular/animations';
import {
ChangeDetectorRef,
Component,
OnDestroy,
OnInit,
TemplateRef,
ViewChild,
} from '@angular/core';
import {
FormArray,
FormBuilder,
FormGroup,
Validators,
} from '@angular/forms';
import {
ActivatedRoute,
Router,
} from '@angular/router';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { LdnService } from '../ldn-services-model/ldn-services.model';
import { RemoteData } from 'src/app/core/data/remote-data';
import { Operation } from 'fast-json-patch'; import { Operation } from 'fast-json-patch';
import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; import {
import { LdnItemfiltersService } from '../ldn-services-data/ldn-itemfilters-data.service'; combineLatestWith,
import { Itemfilter } from '../ldn-services-model/ldn-service-itemfilters'; Observable,
import { PaginatedList } from '../../../core/data/paginated-list.model'; Subscription,
import { combineLatestWith, Observable, Subscription } from 'rxjs'; } from 'rxjs';
import { PaginationService } from '../../../core/pagination/pagination.service'; import { RemoteData } from 'src/app/core/data/remote-data';
import { FindListOptions } from '../../../core/data/find-list-options.model'; import { FindListOptions } from '../../../core/data/find-list-options.model';
import { NotifyServicePattern } from '../ldn-services-model/ldn-service-patterns.model'; import { PaginatedList } from '../../../core/data/paginated-list.model';
import { PaginationService } from '../../../core/pagination/pagination.service';
import { getFirstCompletedRemoteData } from '../../../core/shared/operators';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { IpV4Validator } from '../../../shared/utils/ipV4.validator'; import { IpV4Validator } from '../../../shared/utils/ipV4.validator';
import { LdnItemfiltersService } from '../ldn-services-data/ldn-itemfilters-data.service';
import { LdnServicesService } from '../ldn-services-data/ldn-services-data.service';
import { LDN_SERVICE } from '../ldn-services-model/ldn-service.resource-type';
import { Itemfilter } from '../ldn-services-model/ldn-service-itemfilters';
import { NotifyServicePattern } from '../ldn-services-model/ldn-service-patterns.model';
import { LdnService } from '../ldn-services-model/ldn-services.model';
import { notifyPatterns } from '../ldn-services-patterns/ldn-service-coar-patterns';
/** /**
* Component for editing LDN service through a form that allows to create or edit the properties of a service * Component for editing LDN service through a form that allows to create or edit the properties of a service
@@ -39,15 +65,15 @@ import { IpV4Validator } from '../../../shared/utils/ipV4.validator';
export class LdnServiceFormComponent implements OnInit, OnDestroy { export class LdnServiceFormComponent implements OnInit, OnDestroy {
formModel: FormGroup; formModel: FormGroup;
@ViewChild('confirmModal', {static: true}) confirmModal: TemplateRef<any>; @ViewChild('confirmModal', { static: true }) confirmModal: TemplateRef<any>;
@ViewChild('resetFormModal', {static: true}) resetFormModal: TemplateRef<any>; @ViewChild('resetFormModal', { static: true }) resetFormModal: TemplateRef<any>;
public inboundPatterns: string[] = notifyPatterns; public inboundPatterns: string[] = notifyPatterns;
public isNewService: boolean; public isNewService: boolean;
public areControlsInitialized: boolean; public areControlsInitialized: boolean;
public itemfiltersRD$: Observable<RemoteData<PaginatedList<Itemfilter>>>; public itemfiltersRD$: Observable<RemoteData<PaginatedList<Itemfilter>>>;
public config: FindListOptions = Object.assign(new FindListOptions(), { public config: FindListOptions = Object.assign(new FindListOptions(), {
elementsPerPage: 20 elementsPerPage: 20,
}); });
public markedForDeletionInboundPattern: number[] = []; public markedForDeletionInboundPattern: number[] = [];
public selectedInboundPatterns: string[]; public selectedInboundPatterns: string[];
@@ -70,7 +96,7 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
protected modalService: NgbModal, protected modalService: NgbModal,
private notificationService: NotificationsService, private notificationService: NotificationsService,
private translateService: TranslateService, private translateService: TranslateService,
protected paginationService: PaginationService protected paginationService: PaginationService,
) { ) {
this.formModel = this.formBuilder.group({ this.formModel = this.formBuilder.group({
@@ -90,7 +116,7 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
ngOnInit(): void { ngOnInit(): void {
this.routeSubscription = this.route.params.pipe( this.routeSubscription = this.route.params.pipe(
combineLatestWith(this.route.url) combineLatestWith(this.route.url),
).subscribe(([params, segment]) => { ).subscribe(([params, segment]) => {
this.serviceId = params.serviceId; this.serviceId = params.serviceId;
this.isNewService = segment[0].path === 'new'; this.isNewService = segment[0].path === 'new';
@@ -141,17 +167,17 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
patternLabel: string, patternLabel: string,
constraintFormatted: string; constraintFormatted: string;
}) => { }) => {
const {patternLabel, ...rest} = pattern; const { patternLabel, ...rest } = pattern;
delete rest.constraintFormatted; delete rest.constraintFormatted;
return rest; return rest;
}); });
const values = {...this.formModel.value, enabled: true}; const values = { ...this.formModel.value, enabled: true };
const ldnServiceData = this.ldnServicesService.create(values); const ldnServiceData = this.ldnServicesService.create(values);
ldnServiceData.pipe( ldnServiceData.pipe(
getFirstCompletedRemoteData() getFirstCompletedRemoteData(),
).subscribe((rd: RemoteData<LdnService>) => { ).subscribe((rd: RemoteData<LdnService>) => {
if (rd.hasSucceeded) { if (rd.hasSucceeded) {
this.notificationService.success(this.translateService.get('ldn-service-notification.created.success.title'), this.notificationService.success(this.translateService.get('ldn-service-notification.created.success.title'),
@@ -191,7 +217,7 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
*/ */
fetchServiceData(serviceId: string): void { fetchServiceData(serviceId: string): void {
this.ldnServicesService.findById(serviceId).pipe( this.ldnServicesService.findById(serviceId).pipe(
getFirstCompletedRemoteData() getFirstCompletedRemoteData(),
).subscribe( ).subscribe(
(data: RemoteData<LdnService>) => { (data: RemoteData<LdnService>) => {
if (data.hasSucceeded) { if (data.hasSucceeded) {
@@ -206,18 +232,18 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
type: this.ldnService.type, type: this.ldnService.type,
enabled: this.ldnService.enabled, enabled: this.ldnService.enabled,
lowerIp: this.ldnService.lowerIp, lowerIp: this.ldnService.lowerIp,
upperIp: this.ldnService.upperIp upperIp: this.ldnService.upperIp,
}); });
this.filterPatternObjectsAndAssignLabel('notifyServiceInboundPatterns'); this.filterPatternObjectsAndAssignLabel('notifyServiceInboundPatterns');
let notifyServiceInboundPatternsFormArray = this.formModel.get('notifyServiceInboundPatterns') as FormArray; const notifyServiceInboundPatternsFormArray = this.formModel.get('notifyServiceInboundPatterns') as FormArray;
notifyServiceInboundPatternsFormArray.controls.forEach( notifyServiceInboundPatternsFormArray.controls.forEach(
control => { control => {
const controlFormGroup = control as FormGroup; const controlFormGroup = control as FormGroup;
const controlConstraint = controlFormGroup.get('constraint').value; const controlConstraint = controlFormGroup.get('constraint').value;
controlFormGroup.patchValue({ controlFormGroup.patchValue({
constraintFormatted: controlConstraint ? this.translateService.instant((controlConstraint as string) + '.label') : '' constraintFormatted: controlConstraint ? this.translateService.instant((controlConstraint as string) + '.label') : '',
}); });
} },
); );
} }
}, },
@@ -232,14 +258,14 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
const PatternsArray = this.formModel.get(formArrayName) as FormArray; const PatternsArray = this.formModel.get(formArrayName) as FormArray;
PatternsArray.clear(); PatternsArray.clear();
let servicesToUse = this.ldnService.notifyServiceInboundPatterns; const servicesToUse = this.ldnService.notifyServiceInboundPatterns;
servicesToUse.forEach((patternObj: NotifyServicePattern) => { servicesToUse.forEach((patternObj: NotifyServicePattern) => {
let patternFormGroup; let patternFormGroup;
patternFormGroup = this.initializeInboundPatternFormGroup(); patternFormGroup = this.initializeInboundPatternFormGroup();
const newPatternObjWithLabel = Object.assign(new NotifyServicePattern(), { const newPatternObjWithLabel = Object.assign(new NotifyServicePattern(), {
...patternObj, ...patternObj,
patternLabel: this.translateService.instant('ldn-service.form.pattern.' + patternObj?.pattern + '.label') patternLabel: this.translateService.instant('ldn-service.form.pattern.' + patternObj?.pattern + '.label'),
}); });
patternFormGroup.patchValue(newPatternObjWithLabel); patternFormGroup.patchValue(newPatternObjWithLabel);
@@ -267,7 +293,7 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
this.deletedInboundPatterns.forEach(index => { this.deletedInboundPatterns.forEach(index => {
const removeOperation: Operation = { const removeOperation: Operation = {
op: 'remove', op: 'remove',
path: `notifyServiceInboundPatterns[${index}]` path: `notifyServiceInboundPatterns[${index}]`,
}; };
patchOperations.push(removeOperation); patchOperations.push(removeOperation);
}); });
@@ -297,8 +323,8 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
*/ */
selectInboundPattern(patternValue: string, index: number): void { selectInboundPattern(patternValue: string, index: number): void {
const patternArray = (this.formModel.get('notifyServiceInboundPatterns') as FormArray); const patternArray = (this.formModel.get('notifyServiceInboundPatterns') as FormArray);
patternArray.controls[index].patchValue({pattern: patternValue}); patternArray.controls[index].patchValue({ pattern: patternValue });
patternArray.controls[index].patchValue({patternLabel: this.translateService.instant('ldn-service.form.pattern.' + patternValue + '.label')}); patternArray.controls[index].patchValue({ patternLabel: this.translateService.instant('ldn-service.form.pattern.' + patternValue + '.label') });
} }
/** /**
@@ -310,7 +336,7 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
const filterArray = (this.formModel.get('notifyServiceInboundPatterns') as FormArray); const filterArray = (this.formModel.get('notifyServiceInboundPatterns') as FormArray);
filterArray.controls[index].patchValue({ filterArray.controls[index].patchValue({
constraint: filterValue, constraint: filterValue,
constraintFormatted: this.translateService.instant((filterValue !== '' ? filterValue : 'ldn.no-filter') + '.label') constraintFormatted: this.translateService.instant((filterValue !== '' ? filterValue : 'ldn.no-filter') + '.label'),
}); });
filterArray.markAllAsTouched(); filterArray.markAllAsTouched();
} }
@@ -340,12 +366,12 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
}; };
this.ldnServicesService.patch(this.ldnService, [patchOperation]).pipe( this.ldnServicesService.patch(this.ldnService, [patchOperation]).pipe(
getFirstCompletedRemoteData() getFirstCompletedRemoteData(),
).subscribe( ).subscribe(
() => { () => {
this.formModel.get('enabled').setValue(newStatus); this.formModel.get('enabled').setValue(newStatus);
this.cdRef.detectChanges(); this.cdRef.detectChanges();
} },
); );
} }
@@ -391,7 +417,7 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
} }
this.ldnServicesService.patch(this.ldnService, patchOperations).pipe( this.ldnServicesService.patch(this.ldnService, patchOperations).pipe(
getFirstCompletedRemoteData() getFirstCompletedRemoteData(),
).subscribe( ).subscribe(
(rd: RemoteData<LdnService>) => { (rd: RemoteData<LdnService>) => {
if (rd.hasSucceeded) { if (rd.hasSucceeded) {
@@ -529,7 +555,7 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
constraint: '', constraint: '',
constraintFormatted: '', constraintFormatted: '',
automatic: false, automatic: false,
isNew: true isNew: true,
}; };
if (this.isNewService) { if (this.isNewService) {
@@ -560,6 +586,6 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
private setLdnUrlError(): void { private setLdnUrlError(): void {
const control = this.formModel.controls.ldnUrl; const control = this.formModel.controls.ldnUrl;
const controlErrors = control.errors || {}; const controlErrors = control.errors || {};
control.setErrors({...controlErrors, ldnUrlAlreadyAssociated: true }); control.setErrors({ ...controlErrors, ldnUrlAlreadyAssociated: true });
} }
} }

View File

@@ -1,9 +1,13 @@
import { LdnService } from '../ldn-services-model/ldn-services.model'; import {
import { LDN_SERVICE } from '../ldn-services-model/ldn-service.resource-type'; Observable,
import { RemoteData } from '../../../core/data/remote-data'; of,
} from 'rxjs';
import { PaginatedList } from '../../../core/data/paginated-list.model'; import { PaginatedList } from '../../../core/data/paginated-list.model';
import { Observable, of } from 'rxjs'; import { RemoteData } from '../../../core/data/remote-data';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
import { LDN_SERVICE } from '../ldn-services-model/ldn-service.resource-type';
import { LdnService } from '../ldn-services-model/ldn-services.model';
export const mockLdnService: LdnService = { export const mockLdnService: LdnService = {
uuid: '1', uuid: '1',
@@ -31,7 +35,7 @@ export const mockLdnService: LdnService = {
type: LDN_SERVICE, type: LDN_SERVICE,
_links: { _links: {
self: { self: {
href: 'http://localhost/api/ldn/ldnservices/1' href: 'http://localhost/api/ldn/ldnservices/1',
}, },
}, },
get self(): string { get self(): string {
@@ -68,7 +72,7 @@ export const mockLdnServices: LdnService[] = [{
type: LDN_SERVICE, type: LDN_SERVICE,
_links: { _links: {
self: { self: {
href: 'http://localhost/api/ldn/ldnservices/1' href: 'http://localhost/api/ldn/ldnservices/1',
}, },
}, },
get self(): string { get self(): string {
@@ -100,12 +104,12 @@ export const mockLdnServices: LdnService[] = [{
type: LDN_SERVICE, type: LDN_SERVICE,
_links: { _links: {
self: { self: {
href: 'http://localhost/api/ldn/ldnservices/1' href: 'http://localhost/api/ldn/ldnservices/1',
}, },
}, },
get self(): string { get self(): string {
return ''; return '';
}, },
} },
]; ];
export const mockLdnServicesRD$: Observable<RemoteData<PaginatedList<LdnService>>> = of((mockLdnServices as unknown) as RemoteData<PaginatedList<LdnService>>); export const mockLdnServicesRD$: Observable<RemoteData<PaginatedList<LdnService>>> = of((mockLdnServices as unknown) as RemoteData<PaginatedList<LdnService>>);

View File

@@ -1,19 +1,23 @@
import {
cold,
getTestScheduler,
} from 'jasmine-marbles';
import { of } from 'rxjs';
import { TestScheduler } from 'rxjs/testing'; import { TestScheduler } from 'rxjs/testing';
import { LdnItemfiltersService } from './ldn-itemfilters-data.service';
import { RequestService } from '../../../core/data/request.service';
import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../core/cache/object-cache.service'; import { ObjectCacheService } from '../../../core/cache/object-cache.service';
import { HALEndpointService } from '../../../core/shared/hal-endpoint.service';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { RequestEntry } from '../../../core/data/request-entry.model';
import { RemoteData } from '../../../core/data/remote-data';
import { RequestEntryState } from '../../../core/data/request-entry-state.model';
import { cold, getTestScheduler } from 'jasmine-marbles';
import { RestResponse } from '../../../core/cache/response.models'; import { RestResponse } from '../../../core/cache/response.models';
import { of } from 'rxjs';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
import { FindAllData } from '../../../core/data/base/find-all-data'; import { FindAllData } from '../../../core/data/base/find-all-data';
import { testFindAllDataImplementation } from '../../../core/data/base/find-all-data.spec'; import { testFindAllDataImplementation } from '../../../core/data/base/find-all-data.spec';
import { RemoteData } from '../../../core/data/remote-data';
import { RequestService } from '../../../core/data/request.service';
import { RequestEntry } from '../../../core/data/request-entry.model';
import { RequestEntryState } from '../../../core/data/request-entry-state.model';
import { HALEndpointService } from '../../../core/shared/hal-endpoint.service';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
import { LdnItemfiltersService } from './ldn-itemfilters-data.service';
describe('LdnItemfiltersService test', () => { describe('LdnItemfiltersService test', () => {
let scheduler: TestScheduler; let scheduler: TestScheduler;
@@ -60,12 +64,12 @@ describe('LdnItemfiltersService test', () => {
}); });
halService = jasmine.createSpyObj('halService', { halService = jasmine.createSpyObj('halService', {
getEndpoint: of(endpointURL) getEndpoint: of(endpointURL),
}); });
rdbService = jasmine.createSpyObj('rdbService', { rdbService = jasmine.createSpyObj('rdbService', {
buildSingle: createSuccessfulRemoteDataObject$({}, 500), buildSingle: createSuccessfulRemoteDataObject$({}, 500),
buildList: cold('a', { a: remoteDataMocks.Success }) buildList: cold('a', { a: remoteDataMocks.Success }),
}); });

View File

@@ -1,20 +1,23 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { dataService } from '../../../core/data/base/data-service.decorator'; import { Observable } from 'rxjs';
import { LDN_SERVICE_CONSTRAINT_FILTERS } from '../ldn-services-model/ldn-service.resource-type';
import { IdentifiableDataService } from '../../../core/data/base/identifiable-data.service';
import { FindAllData, FindAllDataImpl } from '../../../core/data/base/find-all-data';
import { RequestService } from '../../../core/data/request.service';
import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../core/cache/object-cache.service'; import { ObjectCacheService } from '../../../core/cache/object-cache.service';
import { dataService } from '../../../core/data/base/data-service.decorator';
import {
FindAllData,
FindAllDataImpl,
} from '../../../core/data/base/find-all-data';
import { IdentifiableDataService } from '../../../core/data/base/identifiable-data.service';
import { FindListOptions } from '../../../core/data/find-list-options.model';
import { PaginatedList } from '../../../core/data/paginated-list.model';
import { RemoteData } from '../../../core/data/remote-data';
import { RequestService } from '../../../core/data/request.service';
import { HALEndpointService } from '../../../core/shared/hal-endpoint.service'; import { HALEndpointService } from '../../../core/shared/hal-endpoint.service';
import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { FindListOptions } from '../../../core/data/find-list-options.model';
import { FollowLinkConfig } from '../../../shared/utils/follow-link-config.model'; import { FollowLinkConfig } from '../../../shared/utils/follow-link-config.model';
import { Observable } from 'rxjs'; import { LDN_SERVICE_CONSTRAINT_FILTERS } from '../ldn-services-model/ldn-service.resource-type';
import { RemoteData } from '../../../core/data/remote-data';
import { Itemfilter } from '../ldn-services-model/ldn-service-itemfilters'; import { Itemfilter } from '../ldn-services-model/ldn-service-itemfilters';
import { PaginatedList } from '../../../core/data/paginated-list.model';
/** /**
* A service responsible for fetching/sending data from/to the REST API on the itemfilters endpoint * A service responsible for fetching/sending data from/to the REST API on the itemfilters endpoint

View File

@@ -1,31 +1,35 @@
import { TestScheduler } from 'rxjs/testing'; import {
import { RequestService } from '../../../core/data/request.service'; cold,
import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service'; getTestScheduler,
import { ObjectCacheService } from '../../../core/cache/object-cache.service'; } from 'jasmine-marbles';
import { HALEndpointService } from '../../../core/shared/hal-endpoint.service';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { RequestEntry } from '../../../core/data/request-entry.model';
import { RemoteData } from '../../../core/data/remote-data';
import { RequestEntryState } from '../../../core/data/request-entry-state.model';
import { cold, getTestScheduler } from 'jasmine-marbles';
import { RestResponse } from '../../../core/cache/response.models';
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { TestScheduler } from 'rxjs/testing';
import { FindAllData } from '../../../core/data/base/find-all-data';
import { testFindAllDataImplementation } from '../../../core/data/base/find-all-data.spec'; import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service';
import { LdnServicesService } from './ldn-services-data.service'; import { RequestParam } from '../../../core/cache/models/request-param.model';
import { testDeleteDataImplementation } from '../../../core/data/base/delete-data.spec'; import { ObjectCacheService } from '../../../core/cache/object-cache.service';
import { DeleteData } from '../../../core/data/base/delete-data'; import { RestResponse } from '../../../core/cache/response.models';
import { testSearchDataImplementation } from '../../../core/data/base/search-data.spec';
import { SearchData } from '../../../core/data/base/search-data';
import { testPatchDataImplementation } from '../../../core/data/base/patch-data.spec';
import { PatchData } from '../../../core/data/base/patch-data';
import { CreateData } from '../../../core/data/base/create-data'; import { CreateData } from '../../../core/data/base/create-data';
import { testCreateDataImplementation } from '../../../core/data/base/create-data.spec'; import { testCreateDataImplementation } from '../../../core/data/base/create-data.spec';
import { DeleteData } from '../../../core/data/base/delete-data';
import { testDeleteDataImplementation } from '../../../core/data/base/delete-data.spec';
import { FindAllData } from '../../../core/data/base/find-all-data';
import { testFindAllDataImplementation } from '../../../core/data/base/find-all-data.spec';
import { PatchData } from '../../../core/data/base/patch-data';
import { testPatchDataImplementation } from '../../../core/data/base/patch-data.spec';
import { SearchData } from '../../../core/data/base/search-data';
import { testSearchDataImplementation } from '../../../core/data/base/search-data.spec';
import { FindListOptions } from '../../../core/data/find-list-options.model'; import { FindListOptions } from '../../../core/data/find-list-options.model';
import { RequestParam } from '../../../core/cache/models/request-param.model'; import { RemoteData } from '../../../core/data/remote-data';
import { mockLdnService } from '../ldn-service-serviceMock/ldnServicesRD$-mock'; import { RequestService } from '../../../core/data/request.service';
import { RequestEntry } from '../../../core/data/request-entry.model';
import { RequestEntryState } from '../../../core/data/request-entry-state.model';
import { HALEndpointService } from '../../../core/shared/hal-endpoint.service';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
import { createPaginatedList } from '../../../shared/testing/utils.test'; import { createPaginatedList } from '../../../shared/testing/utils.test';
import { mockLdnService } from '../ldn-service-serviceMock/ldnServicesRD$-mock';
import { LdnServicesService } from './ldn-services-data.service';
describe('LdnServicesService test', () => { describe('LdnServicesService test', () => {
let scheduler: TestScheduler; let scheduler: TestScheduler;
@@ -72,13 +76,13 @@ describe('LdnServicesService test', () => {
}); });
halService = jasmine.createSpyObj('halService', { halService = jasmine.createSpyObj('halService', {
getEndpoint: observableOf(endpointURL) getEndpoint: observableOf(endpointURL),
}); });
rdbService = jasmine.createSpyObj('rdbService', { rdbService = jasmine.createSpyObj('rdbService', {
buildSingle: createSuccessfulRemoteDataObject$({}, 500), buildSingle: createSuccessfulRemoteDataObject$({}, 500),
buildFromRequestUUID: createSuccessfulRemoteDataObject$({}, 500), buildFromRequestUUID: createSuccessfulRemoteDataObject$({}, 500),
buildList: cold('a', { a: remoteDataMocks.Success }) buildList: cold('a', { a: remoteDataMocks.Success }),
}); });
@@ -102,7 +106,7 @@ describe('LdnServicesService test', () => {
describe('custom methods', () => { describe('custom methods', () => {
it('should find service by inbound pattern', (done) => { it('should find service by inbound pattern', (done) => {
const params = [new RequestParam('pattern', 'testPattern')]; const params = [new RequestParam('pattern', 'testPattern')];
const findListOptions = Object.assign(new FindListOptions(), {}, {searchParams: params}); const findListOptions = Object.assign(new FindListOptions(), {}, { searchParams: params });
spyOn(service, 'searchBy').and.returnValue(observableOf(null)); spyOn(service, 'searchBy').and.returnValue(observableOf(null));
spyOn((service as any).searchData, 'searchBy').and.returnValue(createSuccessfulRemoteDataObject$(createPaginatedList([mockLdnService]))); spyOn((service as any).searchData, 'searchBy').and.returnValue(createSuccessfulRemoteDataObject$(createPaginatedList([mockLdnService])));
@@ -113,7 +117,7 @@ describe('LdnServicesService test', () => {
}); });
it('should invoke service', (done) => { it('should invoke service', (done) => {
const constraints = [{void: true}]; const constraints = [{ void: true }];
const files = [new File([],'fileName')]; const files = [new File([],'fileName')];
spyOn(service as any, 'getInvocationFormData'); spyOn(service as any, 'getInvocationFormData');
spyOn(service, 'getBrowseEndpoint').and.returnValue(observableOf('testEndpoint')); spyOn(service, 'getBrowseEndpoint').and.returnValue(observableOf('testEndpoint'));

View File

@@ -1,35 +1,49 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { dataService } from '../../../core/data/base/data-service.decorator';
import { LDN_SERVICE } from '../ldn-services-model/ldn-service.resource-type';
import { IdentifiableDataService } from '../../../core/data/base/identifiable-data.service';
import { FindAllData, FindAllDataImpl } from '../../../core/data/base/find-all-data';
import { DeleteData, DeleteDataImpl } from '../../../core/data/base/delete-data';
import { RequestService } from '../../../core/data/request.service';
import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../core/cache/object-cache.service';
import { HALEndpointService } from '../../../core/shared/hal-endpoint.service';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { FindListOptions } from '../../../core/data/find-list-options.model';
import { FollowLinkConfig } from '../../../shared/utils/follow-link-config.model';
import { Observable } from 'rxjs';
import { RemoteData } from '../../../core/data/remote-data';
import { PaginatedList } from '../../../core/data/paginated-list.model';
import { NoContent } from '../../../core/shared/NoContent.model';
import { map, take } from 'rxjs/operators';
import { URLCombiner } from '../../../core/url-combiner/url-combiner';
import { MultipartPostRequest } from '../../../core/data/request.models';
import { RestRequest } from '../../../core/data/rest-request.model';
import { LdnService } from '../ldn-services-model/ldn-services.model';
import { PatchData, PatchDataImpl } from '../../../core/data/base/patch-data';
import { ChangeAnalyzer } from '../../../core/data/change-analyzer';
import { Operation } from 'fast-json-patch'; import { Operation } from 'fast-json-patch';
import { RestRequestMethod } from '../../../core/data/rest-request-method'; import { Observable } from 'rxjs';
import { CreateData, CreateDataImpl } from '../../../core/data/base/create-data'; import {
import { LdnServiceConstrain } from '../ldn-services-model/ldn-service.constrain.model'; map,
import { SearchDataImpl } from '../../../core/data/base/search-data'; take,
} from 'rxjs/operators';
import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service';
import { RequestParam } from '../../../core/cache/models/request-param.model'; import { RequestParam } from '../../../core/cache/models/request-param.model';
import { ObjectCacheService } from '../../../core/cache/object-cache.service';
import {
CreateData,
CreateDataImpl,
} from '../../../core/data/base/create-data';
import { dataService } from '../../../core/data/base/data-service.decorator';
import {
DeleteData,
DeleteDataImpl,
} from '../../../core/data/base/delete-data';
import {
FindAllData,
FindAllDataImpl,
} from '../../../core/data/base/find-all-data';
import { IdentifiableDataService } from '../../../core/data/base/identifiable-data.service';
import {
PatchData,
PatchDataImpl,
} from '../../../core/data/base/patch-data';
import { SearchDataImpl } from '../../../core/data/base/search-data';
import { ChangeAnalyzer } from '../../../core/data/change-analyzer';
import { FindListOptions } from '../../../core/data/find-list-options.model';
import { PaginatedList } from '../../../core/data/paginated-list.model';
import { RemoteData } from '../../../core/data/remote-data';
import { MultipartPostRequest } from '../../../core/data/request.models';
import { RequestService } from '../../../core/data/request.service';
import { RestRequest } from '../../../core/data/rest-request.model';
import { RestRequestMethod } from '../../../core/data/rest-request-method';
import { HALEndpointService } from '../../../core/shared/hal-endpoint.service';
import { NoContent } from '../../../core/shared/NoContent.model';
import { URLCombiner } from '../../../core/url-combiner/url-combiner';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { FollowLinkConfig } from '../../../shared/utils/follow-link-config.model';
import { LdnServiceConstrain } from '../ldn-services-model/ldn-service.constrain.model';
import { LDN_SERVICE } from '../ldn-services-model/ldn-service.resource-type';
import { LdnService } from '../ldn-services-model/ldn-services.model';
/** /**
* Injectable service responsible for fetching/sending data from/to the REST API on the ldnservices endpoint. * Injectable service responsible for fetching/sending data from/to the REST API on the ldnservices endpoint.
@@ -146,7 +160,7 @@ export class LdnServicesService extends IdentifiableDataService<LdnService> impl
*/ */
findByInboundPattern(pattern: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig<LdnService>[]): Observable<RemoteData<PaginatedList<LdnService>>> { findByInboundPattern(pattern: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig<LdnService>[]): Observable<RemoteData<PaginatedList<LdnService>>> {
const params = [new RequestParam('pattern', pattern)]; const params = [new RequestParam('pattern', pattern)];
const findListOptions = Object.assign(new FindListOptions(), options, {searchParams: params}); const findListOptions = Object.assign(new FindListOptions(), options, { searchParams: params });
return this.searchBy(this.findByPatternEndpoint, findListOptions, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); return this.searchBy(this.findByPatternEndpoint, findListOptions, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
} }
@@ -199,7 +213,7 @@ export class LdnServicesService extends IdentifiableDataService<LdnService> impl
map((endpoint: string) => { map((endpoint: string) => {
const body = this.getInvocationFormData(parameters, files); const body = this.getInvocationFormData(parameters, files);
return new MultipartPostRequest(requestId, endpoint, body); return new MultipartPostRequest(requestId, endpoint, body);
}) }),
).subscribe((request: RestRequest) => this.requestService.send(request)); ).subscribe((request: RestRequest) => this.requestService.send(request));
return this.rdbService.buildFromRequestUUID<LdnService>(requestId); return this.rdbService.buildFromRequestUUID<LdnService>(requestId);

View File

@@ -1,19 +1,32 @@
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import {
import { ChangeDetectorRef, EventEmitter, NO_ERRORS_SCHEMA } from '@angular/core'; ChangeDetectorRef,
import { NotificationsService } from '../../../shared/notifications/notifications.service'; EventEmitter,
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub'; NO_ERRORS_SCHEMA,
import { TranslateModule, TranslateService } from '@ngx-translate/core'; } from '@angular/core';
import {
ComponentFixture,
fakeAsync,
TestBed,
tick,
} from '@angular/core/testing';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { LdnServicesService } from '../ldn-services-data/ldn-services-data.service'; import {
import { PaginationService } from '../../../core/pagination/pagination.service'; TranslateModule,
import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; TranslateService,
} from '@ngx-translate/core';
import { of } from 'rxjs'; import { of } from 'rxjs';
import { LdnService } from '../ldn-services-model/ldn-services.model';
import { PaginatedList } from '../../../core/data/paginated-list.model'; import { PaginatedList } from '../../../core/data/paginated-list.model';
import { RemoteData } from '../../../core/data/remote-data'; import { RemoteData } from '../../../core/data/remote-data';
import { LdnServicesOverviewComponent } from './ldn-services-directory.component'; import { PaginationService } from '../../../core/pagination/pagination.service';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub';
import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub';
import { createPaginatedList } from '../../../shared/testing/utils.test'; import { createPaginatedList } from '../../../shared/testing/utils.test';
import { LdnServicesService } from '../ldn-services-data/ldn-services-data.service';
import { LdnService } from '../ldn-services-model/ldn-services.model';
import { LdnServicesOverviewComponent } from './ldn-services-directory.component';
describe('LdnServicesOverviewComponent', () => { describe('LdnServicesOverviewComponent', () => {
let component: LdnServicesOverviewComponent; let component: LdnServicesOverviewComponent;
@@ -26,7 +39,7 @@ describe('LdnServicesOverviewComponent', () => {
get: () => of('translated-text'), get: () => of('translated-text'),
onLangChange: new EventEmitter(), onLangChange: new EventEmitter(),
onTranslationChange: new EventEmitter(), onTranslationChange: new EventEmitter(),
onDefaultLangChange: new EventEmitter() onDefaultLangChange: new EventEmitter(),
}; };
beforeEach(async () => { beforeEach(async () => {
@@ -42,20 +55,20 @@ describe('LdnServicesOverviewComponent', () => {
providers: [ providers: [
{ {
provide: LdnServicesService, provide: LdnServicesService,
useValue: ldnServicesService useValue: ldnServicesService,
}, },
{provide: PaginationService, useValue: paginationService}, { provide: PaginationService, useValue: paginationService },
{ {
provide: NgbModal, useValue: { provide: NgbModal, useValue: {
open: () => { /*comment*/ open: () => { /*comment*/
}
}
}, },
{provide: ChangeDetectorRef, useValue: {}}, },
{provide: NotificationsService, useValue: new NotificationsServiceStub()}, },
{provide: TranslateService, useValue: translateServiceStub}, { provide: ChangeDetectorRef, useValue: {} },
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
{ provide: TranslateService, useValue: translateServiceStub },
], ],
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA],
}).compileComponents(); }).compileComponents();
}); });
@@ -65,8 +78,8 @@ describe('LdnServicesOverviewComponent', () => {
ldnServicesService = TestBed.inject(LdnServicesService); ldnServicesService = TestBed.inject(LdnServicesService);
paginationService = TestBed.inject(PaginationService); paginationService = TestBed.inject(PaginationService);
modalService = TestBed.inject(NgbModal); modalService = TestBed.inject(NgbModal);
component.modalRef = jasmine.createSpyObj({close: null}); component.modalRef = jasmine.createSpyObj({ close: null });
component.isProcessingSub = jasmine.createSpyObj({unsubscribe: null}); component.isProcessingSub = jasmine.createSpyObj({ unsubscribe: null });
component.ldnServicesRD$ = of({} as RemoteData<PaginatedList<LdnService>>); component.ldnServicesRD$ = of({} as RemoteData<PaginatedList<LdnService>>);
fixture.detectChanges(); fixture.detectChanges();
}); });
@@ -86,9 +99,9 @@ describe('LdnServicesOverviewComponent', () => {
it('should set ldnServicesRD$ with mock data', fakeAsync(() => { it('should set ldnServicesRD$ with mock data', fakeAsync(() => {
spyOn(component, 'setLdnServices').and.callThrough(); spyOn(component, 'setLdnServices').and.callThrough();
const testData: LdnService[] = Object.assign([new LdnService()], [ const testData: LdnService[] = Object.assign([new LdnService()], [
{id: 1, name: 'Service 1', description: 'Description 1', enabled: true}, { id: 1, name: 'Service 1', description: 'Description 1', enabled: true },
{id: 2, name: 'Service 2', description: 'Description 2', enabled: false}, { id: 2, name: 'Service 2', description: 'Description 2', enabled: false },
{id: 3, name: 'Service 3', description: 'Description 3', enabled: true}]); { id: 3, name: 'Service 3', description: 'Description 3', enabled: true }]);
const mockLdnServicesRD = createPaginatedList(testData); const mockLdnServicesRD = createPaginatedList(testData);
component.ldnServicesRD$ = createSuccessfulRemoteDataObject$(mockLdnServicesRD); component.ldnServicesRD$ = createSuccessfulRemoteDataObject$(mockLdnServicesRD);
@@ -155,7 +168,7 @@ describe('LdnServicesOverviewComponent', () => {
describe('toggleStatus', () => { describe('toggleStatus', () => {
it('should toggle status', (() => { it('should toggle status', (() => {
component.toggleStatus({enabled: false}, ldnServicesService); component.toggleStatus({ enabled: false }, ldnServicesService);
expect(ldnServicesService.patch).toHaveBeenCalled(); expect(ldnServicesService.patch).toHaveBeenCalled();
})); }));
}); });

View File

@@ -1,19 +1,34 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core'; import {
import { Observable, Subscription } from 'rxjs'; ChangeDetectionStrategy,
import { RemoteData } from '../../../core/data/remote-data'; ChangeDetectorRef,
import { PaginatedList } from '../../../core/data/paginated-list.model'; Component,
import { FindListOptions } from '../../../core/data/find-list-options.model'; OnDestroy,
import { LdnService } from '../ldn-services-model/ldn-services.model'; OnInit,
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; TemplateRef,
import { map, switchMap } from 'rxjs/operators'; ViewChild,
} from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { TranslateService } from '@ngx-translate/core';
import { Operation } from 'fast-json-patch';
import {
Observable,
Subscription,
} from 'rxjs';
import {
map,
switchMap,
} from 'rxjs/operators';
import { LdnServicesService } from 'src/app/admin/admin-ldn-services/ldn-services-data/ldn-services-data.service'; import { LdnServicesService } from 'src/app/admin/admin-ldn-services/ldn-services-data/ldn-services-data.service';
import { PaginationService } from 'src/app/core/pagination/pagination.service'; import { PaginationService } from 'src/app/core/pagination/pagination.service';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { hasValue } from '../../../shared/empty.util'; import { FindListOptions } from '../../../core/data/find-list-options.model';
import { Operation } from 'fast-json-patch'; import { PaginatedList } from '../../../core/data/paginated-list.model';
import { RemoteData } from '../../../core/data/remote-data';
import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; import { getFirstCompletedRemoteData } from '../../../core/shared/operators';
import { hasValue } from '../../../shared/empty.util';
import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { TranslateService } from '@ngx-translate/core'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
import { LdnService } from '../ldn-services-model/ldn-services.model';
/** /**
* The `LdnServicesOverviewComponent` is a component that provides an overview of LDN (Linked Data Notifications) services. * The `LdnServicesOverviewComponent` is a component that provides an overview of LDN (Linked Data Notifications) services.
@@ -24,20 +39,20 @@ import { TranslateService } from '@ngx-translate/core';
selector: 'ds-ldn-services-directory', selector: 'ds-ldn-services-directory',
templateUrl: './ldn-services-directory.component.html', templateUrl: './ldn-services-directory.component.html',
styleUrls: ['./ldn-services-directory.component.scss'], styleUrls: ['./ldn-services-directory.component.scss'],
changeDetection: ChangeDetectionStrategy.Default changeDetection: ChangeDetectionStrategy.Default,
}) })
export class LdnServicesOverviewComponent implements OnInit, OnDestroy { export class LdnServicesOverviewComponent implements OnInit, OnDestroy {
selectedServiceId: string | number | null = null; selectedServiceId: string | number | null = null;
servicesData: any[] = []; servicesData: any[] = [];
@ViewChild('deleteModal', {static: true}) deleteModal: TemplateRef<any>; @ViewChild('deleteModal', { static: true }) deleteModal: TemplateRef<any>;
ldnServicesRD$: Observable<RemoteData<PaginatedList<LdnService>>>; ldnServicesRD$: Observable<RemoteData<PaginatedList<LdnService>>>;
config: FindListOptions = Object.assign(new FindListOptions(), { config: FindListOptions = Object.assign(new FindListOptions(), {
elementsPerPage: 10 elementsPerPage: 10,
}); });
pageConfig: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), { pageConfig: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
id: 'po', id: 'po',
pageSize: 10 pageSize: 10,
}); });
isProcessingSub: Subscription; isProcessingSub: Subscription;
modalRef: any; modalRef: any;
@@ -63,8 +78,8 @@ export class LdnServicesOverviewComponent implements OnInit, OnDestroy {
setLdnServices() { setLdnServices() {
this.ldnServicesRD$ = this.paginationService.getFindListOptions(this.pageConfig.id, this.config).pipe( this.ldnServicesRD$ = this.paginationService.getFindListOptions(this.pageConfig.id, this.config).pipe(
switchMap((config) => this.ldnServicesService.findAll(config, false, false).pipe( switchMap((config) => this.ldnServicesService.findAll(config, false, false).pipe(
getFirstCompletedRemoteData() getFirstCompletedRemoteData(),
)) )),
); );
} }
@@ -119,7 +134,7 @@ export class LdnServicesOverviewComponent implements OnInit, OnDestroy {
remoteData.payload.page = remoteData.payload.page.filter(service => service.id.toString() !== serviceId); remoteData.payload.page = remoteData.payload.page.filter(service => service.id.toString() !== serviceId);
} }
return remoteData; return remoteData;
}) }),
); );
this.cdRef.detectChanges(); this.cdRef.detectChanges();
this.closeModal(); this.closeModal();
@@ -161,7 +176,7 @@ export class LdnServicesOverviewComponent implements OnInit, OnDestroy {
this.notificationService.error(this.translateService.get('ldn-enable-service.notification.error.title'), this.notificationService.error(this.translateService.get('ldn-enable-service.notification.error.title'),
this.translateService.get('ldn-enable-service.notification.error.content')); this.translateService.get('ldn-enable-service.notification.error.content'));
} }
} },
); );
} }
} }

View File

@@ -1,9 +1,14 @@
import { autoserialize, deserialize, inheritSerialization } from 'cerialize'; import {
import { LDN_SERVICE_CONSTRAINT_FILTER } from './ldn-service.resource-type'; autoserialize,
import { CacheableObject } from '../../../core/cache/cacheable-object.model'; deserialize,
inheritSerialization,
} from 'cerialize';
import { typedObject } from '../../../core/cache/builders/build-decorators'; import { typedObject } from '../../../core/cache/builders/build-decorators';
import { excludeFromEquals } from '../../../core/utilities/equals.decorators'; import { CacheableObject } from '../../../core/cache/cacheable-object.model';
import { ResourceType } from '../../../core/shared/resource-type'; import { ResourceType } from '../../../core/shared/resource-type';
import { excludeFromEquals } from '../../../core/utilities/equals.decorators';
import { LDN_SERVICE_CONSTRAINT_FILTER } from './ldn-service.resource-type';
/** A single filter value and its properties. */ /** A single filter value and its properties. */
@typedObject @typedObject

View File

@@ -1,9 +1,15 @@
import { ResourceType } from '../../../core/shared/resource-type'; import {
import { CacheableObject } from '../../../core/cache/cacheable-object.model'; autoserialize,
import { autoserialize, deserialize, deserializeAs, inheritSerialization } from 'cerialize'; deserialize,
import { LDN_SERVICE } from './ldn-service.resource-type'; deserializeAs,
import { excludeFromEquals } from '../../../core/utilities/equals.decorators'; inheritSerialization,
} from 'cerialize';
import { typedObject } from '../../../core/cache/builders/build-decorators'; import { typedObject } from '../../../core/cache/builders/build-decorators';
import { CacheableObject } from '../../../core/cache/cacheable-object.model';
import { ResourceType } from '../../../core/shared/resource-type';
import { excludeFromEquals } from '../../../core/utilities/equals.decorators';
import { LDN_SERVICE } from './ldn-service.resource-type';
import { NotifyServicePattern } from './ldn-service-patterns.model'; import { NotifyServicePattern } from './ldn-service-patterns.model';
/** /**

View File

@@ -1,5 +1,9 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router'; import {
ActivatedRouteSnapshot,
Resolve,
RouterStateSnapshot,
} from '@angular/router';
/** /**
* Interface for the route parameters. * Interface for the route parameters.
@@ -26,7 +30,7 @@ export class NotificationsSuggestionTargetsPageResolver implements Resolve<Notif
return { return {
pageId: route.queryParams.pageId, pageId: route.queryParams.pageId,
pageSize: parseInt(route.queryParams.pageSize, 10), pageSize: parseInt(route.queryParams.pageSize, 10),
currentPage: parseInt(route.queryParams.page, 10) currentPage: parseInt(route.queryParams.page, 10),
}; };
} }
} }

View File

@@ -1,8 +1,12 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import {
async,
ComponentFixture,
TestBed,
} from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { NotificationsSuggestionTargetsPageComponent } from '../../../quality-assurance-notifications-pages/notifications-suggestion-targets-page/notifications-suggestion-targets-page.component'; import { NotificationsSuggestionTargetsPageComponent } from '../../../quality-assurance-notifications-pages/notifications-suggestion-targets-page/notifications-suggestion-targets-page.component';
describe('NotificationsSuggestionTargetsPageComponent', () => { describe('NotificationsSuggestionTargetsPageComponent', () => {
@@ -13,15 +17,15 @@ describe('NotificationsSuggestionTargetsPageComponent', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
CommonModule, CommonModule,
TranslateModule.forRoot() TranslateModule.forRoot(),
], ],
declarations: [ declarations: [
NotificationsSuggestionTargetsPageComponent NotificationsSuggestionTargetsPageComponent,
], ],
providers: [ providers: [
NotificationsSuggestionTargetsPageComponent NotificationsSuggestionTargetsPageComponent,
], ],
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA],
}) })
.compileComponents(); .compileComponents();
})); }));

View File

@@ -3,7 +3,7 @@ import { Component } from '@angular/core';
@Component({ @Component({
selector: 'ds-admin-notifications-publication-claim-page', selector: 'ds-admin-notifications-publication-claim-page',
templateUrl: './admin-notifications-publication-claim-page.component.html', templateUrl: './admin-notifications-publication-claim-page.component.html',
styleUrls: ['./admin-notifications-publication-claim-page.component.scss'] styleUrls: ['./admin-notifications-publication-claim-page.component.scss'],
}) })
export class AdminNotificationsPublicationClaimPageComponent { export class AdminNotificationsPublicationClaimPageComponent {

View File

@@ -4,19 +4,22 @@ import { RouterModule } from '@angular/router';
import { AuthenticatedGuard } from '../../core/auth/authenticated.guard'; import { AuthenticatedGuard } from '../../core/auth/authenticated.guard';
import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver'; import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver';
import { I18nBreadcrumbsService } from '../../core/breadcrumbs/i18n-breadcrumbs.service'; import { I18nBreadcrumbsService } from '../../core/breadcrumbs/i18n-breadcrumbs.service';
import { PUBLICATION_CLAIMS_PATH, QUALITY_ASSURANCE_EDIT_PATH } from './admin-notifications-routing-paths';
import { AdminNotificationsPublicationClaimPageComponent } from './admin-notifications-publication-claim-page/admin-notifications-publication-claim-page.component';
import { SiteAdministratorGuard } from '../../core/data/feature-authorization/feature-authorization-guard/site-administrator.guard';
import { QualityAssuranceBreadcrumbResolver } from '../../core/breadcrumbs/quality-assurance-breadcrumb.resolver'; import { QualityAssuranceBreadcrumbResolver } from '../../core/breadcrumbs/quality-assurance-breadcrumb.resolver';
import { QualityAssuranceBreadcrumbService } from '../../core/breadcrumbs/quality-assurance-breadcrumb.service'; import { QualityAssuranceBreadcrumbService } from '../../core/breadcrumbs/quality-assurance-breadcrumb.service';
import { QualityAssuranceEventsPageResolver } from '../../quality-assurance-notifications-pages/quality-assurance-events-page/quality-assurance-events-page.resolver'; import { SiteAdministratorGuard } from '../../core/data/feature-authorization/feature-authorization-guard/site-administrator.guard';
import { AdminNotificationsPublicationClaimPageResolver } from '../../quality-assurance-notifications-pages/notifications-suggestion-targets-page/notifications-suggestion-targets-page-resolver.service'; import { AdminNotificationsPublicationClaimPageResolver } from '../../quality-assurance-notifications-pages/notifications-suggestion-targets-page/notifications-suggestion-targets-page-resolver.service';
import { QualityAssuranceTopicsPageComponent } from '../../quality-assurance-notifications-pages/quality-assurance-topics-page/quality-assurance-topics-page.component'; import { QualityAssuranceEventsPageComponent } from '../../quality-assurance-notifications-pages/quality-assurance-events-page/quality-assurance-events-page.component';
import { QualityAssuranceTopicsPageResolver } from '../../quality-assurance-notifications-pages/quality-assurance-topics-page/quality-assurance-topics-page-resolver.service'; import { QualityAssuranceEventsPageResolver } from '../../quality-assurance-notifications-pages/quality-assurance-events-page/quality-assurance-events-page.resolver';
import { SourceDataResolver } from '../../quality-assurance-notifications-pages/quality-assurance-source-page-component/quality-assurance-source-data.resolver';
import { QualityAssuranceSourcePageComponent } from '../../quality-assurance-notifications-pages/quality-assurance-source-page-component/quality-assurance-source-page.component'; import { QualityAssuranceSourcePageComponent } from '../../quality-assurance-notifications-pages/quality-assurance-source-page-component/quality-assurance-source-page.component';
import { QualityAssuranceSourcePageResolver } from '../../quality-assurance-notifications-pages/quality-assurance-source-page-component/quality-assurance-source-page-resolver.service'; import { QualityAssuranceSourcePageResolver } from '../../quality-assurance-notifications-pages/quality-assurance-source-page-component/quality-assurance-source-page-resolver.service';
import { SourceDataResolver } from '../../quality-assurance-notifications-pages/quality-assurance-source-page-component/quality-assurance-source-data.resolver'; import { QualityAssuranceTopicsPageComponent } from '../../quality-assurance-notifications-pages/quality-assurance-topics-page/quality-assurance-topics-page.component';
import { QualityAssuranceEventsPageComponent } from '../../quality-assurance-notifications-pages/quality-assurance-events-page/quality-assurance-events-page.component'; import { QualityAssuranceTopicsPageResolver } from '../../quality-assurance-notifications-pages/quality-assurance-topics-page/quality-assurance-topics-page-resolver.service';
import { AdminNotificationsPublicationClaimPageComponent } from './admin-notifications-publication-claim-page/admin-notifications-publication-claim-page.component';
import {
PUBLICATION_CLAIMS_PATH,
QUALITY_ASSURANCE_EDIT_PATH,
} from './admin-notifications-routing-paths';
@NgModule({ @NgModule({
imports: [ imports: [
@@ -28,13 +31,13 @@ import { QualityAssuranceEventsPageComponent } from '../../quality-assurance-not
pathMatch: 'full', pathMatch: 'full',
resolve: { resolve: {
breadcrumb: I18nBreadcrumbResolver, breadcrumb: I18nBreadcrumbResolver,
suggestionTargetParams: AdminNotificationsPublicationClaimPageResolver suggestionTargetParams: AdminNotificationsPublicationClaimPageResolver,
}, },
data: { data: {
title: 'admin.notifications.publicationclaim.page.title', title: 'admin.notifications.publicationclaim.page.title',
breadcrumbKey: 'admin.notifications.publicationclaim', breadcrumbKey: 'admin.notifications.publicationclaim',
showBreadcrumbsFluid: false showBreadcrumbsFluid: false,
} },
}, },
{ {
canActivate: [ AuthenticatedGuard ], canActivate: [ AuthenticatedGuard ],
@@ -43,7 +46,7 @@ import { QualityAssuranceEventsPageComponent } from '../../quality-assurance-not
pathMatch: 'full', pathMatch: 'full',
resolve: { resolve: {
breadcrumb: QualityAssuranceBreadcrumbResolver, breadcrumb: QualityAssuranceBreadcrumbResolver,
openaireQualityAssuranceTopicsParams: QualityAssuranceTopicsPageResolver openaireQualityAssuranceTopicsParams: QualityAssuranceTopicsPageResolver,
}, },
data: { data: {
title: 'admin.quality-assurance.page.title', title: 'admin.quality-assurance.page.title',
@@ -58,13 +61,13 @@ import { QualityAssuranceEventsPageComponent } from '../../quality-assurance-not
pathMatch: 'full', pathMatch: 'full',
resolve: { resolve: {
breadcrumb: I18nBreadcrumbResolver, breadcrumb: I18nBreadcrumbResolver,
openaireQualityAssuranceTopicsParams: QualityAssuranceTopicsPageResolver openaireQualityAssuranceTopicsParams: QualityAssuranceTopicsPageResolver,
}, },
data: { data: {
title: 'admin.quality-assurance.page.title', title: 'admin.quality-assurance.page.title',
breadcrumbKey: 'admin.quality-assurance', breadcrumbKey: 'admin.quality-assurance',
showBreadcrumbsFluid: false showBreadcrumbsFluid: false,
} },
}, },
{ {
canActivate: [ SiteAdministratorGuard ], canActivate: [ SiteAdministratorGuard ],
@@ -74,7 +77,7 @@ import { QualityAssuranceEventsPageComponent } from '../../quality-assurance-not
resolve: { resolve: {
breadcrumb: I18nBreadcrumbResolver, breadcrumb: I18nBreadcrumbResolver,
openaireQualityAssuranceSourceParams: QualityAssuranceSourcePageResolver, openaireQualityAssuranceSourceParams: QualityAssuranceSourcePageResolver,
sourceData: SourceDataResolver sourceData: SourceDataResolver,
}, },
data: { data: {
title: 'admin.notifications.source.breadcrumbs', title: 'admin.notifications.source.breadcrumbs',
@@ -89,7 +92,7 @@ import { QualityAssuranceEventsPageComponent } from '../../quality-assurance-not
pathMatch: 'full', pathMatch: 'full',
resolve: { resolve: {
breadcrumb: QualityAssuranceBreadcrumbResolver, breadcrumb: QualityAssuranceBreadcrumbResolver,
openaireQualityAssuranceEventsParams: QualityAssuranceEventsPageResolver openaireQualityAssuranceEventsParams: QualityAssuranceEventsPageResolver,
}, },
data: { data: {
title: 'admin.notifications.event.page.title', title: 'admin.notifications.event.page.title',

View File

@@ -1,10 +1,11 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { CoreModule } from '../../core/core.module'; import { CoreModule } from '../../core/core.module';
import { SharedModule } from '../../shared/shared.module';
import { AdminNotificationsRoutingModule } from './admin-notifications-routing.module';
import { AdminNotificationsPublicationClaimPageComponent } from './admin-notifications-publication-claim-page/admin-notifications-publication-claim-page.component';
import { NotificationsModule } from '../../notifications/notifications.module'; import { NotificationsModule } from '../../notifications/notifications.module';
import { SharedModule } from '../../shared/shared.module';
import { AdminNotificationsPublicationClaimPageComponent } from './admin-notifications-publication-claim-page/admin-notifications-publication-claim-page.component';
import { AdminNotificationsRoutingModule } from './admin-notifications-routing.module';
@NgModule({ @NgModule({
imports: [ imports: [

View File

@@ -1,11 +1,12 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver'; import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver';
import { AdminNotifyDashboardComponent } from './admin-notify-dashboard.component'; import { NotifyInfoGuard } from '../../core/coar-notify/notify-info/notify-info.guard';
import { SiteAdministratorGuard } from '../../core/data/feature-authorization/feature-authorization-guard/site-administrator.guard'; import { SiteAdministratorGuard } from '../../core/data/feature-authorization/feature-authorization-guard/site-administrator.guard';
import { AdminNotifyDashboardComponent } from './admin-notify-dashboard.component';
import { AdminNotifyIncomingComponent } from './admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component'; import { AdminNotifyIncomingComponent } from './admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component';
import { AdminNotifyOutgoingComponent } from './admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component'; import { AdminNotifyOutgoingComponent } from './admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component';
import { NotifyInfoGuard } from '../../core/coar-notify/notify-info/notify-info.guard';
@NgModule({ @NgModule({
imports: [ imports: [
@@ -46,8 +47,8 @@ import { NotifyInfoGuard } from '../../core/coar-notify/notify-info/notify-info.
title: 'admin.notify.dashboard.page.title', title: 'admin.notify.dashboard.page.title',
breadcrumbKey: 'admin.notify.dashboard', breadcrumbKey: 'admin.notify.dashboard',
}, },
} },
]) ]),
], ],
}) })
/** /**

View File

@@ -1,13 +1,16 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {
ComponentFixture,
import { AdminNotifyDashboardComponent } from './admin-notify-dashboard.component'; TestBed,
import { TranslateModule } from '@ngx-translate/core'; } from '@angular/core/testing';
import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core';
import { buildPaginatedList } from '../../core/data/paginated-list.model';
import { SearchService } from '../../core/shared/search/search.service'; import { SearchService } from '../../core/shared/search/search.service';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import { buildPaginatedList } from '../../core/data/paginated-list.model'; import { AdminNotifyDashboardComponent } from './admin-notify-dashboard.component';
import { AdminNotifySearchResult } from './models/admin-notify-message-search-result.model';
import { AdminNotifyMessage } from './models/admin-notify-message.model'; import { AdminNotifyMessage } from './models/admin-notify-message.model';
import { AdminNotifySearchResult } from './models/admin-notify-message-search-result.model';
describe('AdminNotifyDashboardComponent', () => { describe('AdminNotifyDashboardComponent', () => {
let component: AdminNotifyDashboardComponent; let component: AdminNotifyDashboardComponent;
@@ -23,7 +26,7 @@ describe('AdminNotifyDashboardComponent', () => {
const mockBoxes = [ const mockBoxes = [
{ title: 'admin-notify-dashboard.received-ldn', boxes: [ undefined, undefined, undefined, undefined, undefined ] }, { title: 'admin-notify-dashboard.received-ldn', boxes: [ undefined, undefined, undefined, undefined, undefined ] },
{ title: 'admin-notify-dashboard.generated-ldn', boxes: [ undefined, undefined, undefined, undefined, undefined ] } { title: 'admin-notify-dashboard.generated-ldn', boxes: [ undefined, undefined, undefined, undefined, undefined ] },
]; ];
beforeEach(async () => { beforeEach(async () => {
@@ -38,7 +41,7 @@ describe('AdminNotifyDashboardComponent', () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), NgbNavModule], imports: [TranslateModule.forRoot(), NgbNavModule],
declarations: [ AdminNotifyDashboardComponent ], declarations: [ AdminNotifyDashboardComponent ],
providers: [{ provide: SearchService, useValue: { search: () => createSuccessfulRemoteDataObject$(results)}}] providers: [{ provide: SearchService, useValue: { search: () => createSuccessfulRemoteDataObject$(results) } }],
}) })
.compileComponents(); .compileComponents();

View File

@@ -1,16 +1,26 @@
import { Component, OnInit } from '@angular/core'; import {
import { SearchService } from '../../core/shared/search/search.service'; Component,
import { environment } from '../../../environments/environment'; OnInit,
import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model'; } from '@angular/core';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import {
import { forkJoin, Observable } from 'rxjs'; forkJoin,
import { getFirstCompletedRemoteData } from '../../core/shared/operators'; Observable,
} from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { SearchObjects } from '../../shared/search/models/search-objects.model';
import { AdminNotifyMetricsBox, AdminNotifyMetricsRow } from './admin-notify-metrics/admin-notify-metrics.model'; import { environment } from '../../../environments/environment';
import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../core/shared/dspace-object.model';
import { SEARCH_CONFIG_SERVICE } from '../../my-dspace-page/my-dspace-page.component'; import { getFirstCompletedRemoteData } from '../../core/shared/operators';
import { SearchService } from '../../core/shared/search/search.service';
import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service';
import { SEARCH_CONFIG_SERVICE } from '../../my-dspace-page/my-dspace-page.component';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model';
import { SearchObjects } from '../../shared/search/models/search-objects.model';
import {
AdminNotifyMetricsBox,
AdminNotifyMetricsRow,
} from './admin-notify-metrics/admin-notify-metrics.model';
@Component({ @Component({
selector: 'ds-admin-notify-dashboard', selector: 'ds-admin-notify-dashboard',
@@ -18,9 +28,9 @@ import { SearchConfigurationService } from '../../core/shared/search/search-conf
providers: [ providers: [
{ {
provide: SEARCH_CONFIG_SERVICE, provide: SEARCH_CONFIG_SERVICE,
useClass: SearchConfigurationService useClass: SearchConfigurationService,
} },
] ],
}) })
/** /**
@@ -33,7 +43,7 @@ export class AdminNotifyDashboardComponent implements OnInit{
private metricsConfig = environment.notifyMetrics; private metricsConfig = environment.notifyMetrics;
private singleResultOptions = Object.assign(new PaginationComponentOptions(), { private singleResultOptions = Object.assign(new PaginationComponentOptions(), {
id: 'single-result-options', id: 'single-result-options',
pageSize: 1 pageSize: 1,
}); });
constructor(private searchService: SearchService) { constructor(private searchService: SearchService) {
@@ -46,17 +56,17 @@ export class AdminNotifyDashboardComponent implements OnInit{
const flatConfigurations = [].concat(...mertricsRowsConfigurations.map((config) => config)); const flatConfigurations = [].concat(...mertricsRowsConfigurations.map((config) => config));
const searchConfigurations = flatConfigurations const searchConfigurations = flatConfigurations
.map(config => Object.assign(new PaginatedSearchOptions({}), .map(config => Object.assign(new PaginatedSearchOptions({}),
{ configuration: config, pagination: this.singleResultOptions } { configuration: config, pagination: this.singleResultOptions },
)); ));
this.notifyMetricsRows$ = forkJoin(searchConfigurations.map(config => this.searchService.search(config) this.notifyMetricsRows$ = forkJoin(searchConfigurations.map(config => this.searchService.search(config)
.pipe( .pipe(
getFirstCompletedRemoteData(), getFirstCompletedRemoteData(),
map(response => this.mapSearchObjectsToMetricsBox(response.payload)), map(response => this.mapSearchObjectsToMetricsBox(response.payload)),
) ),
) ),
).pipe( ).pipe(
map(metricBoxes => this.mapUpdatedBoxesToMetricsRows(metricBoxes)) map(metricBoxes => this.mapUpdatedBoxesToMetricsRows(metricBoxes)),
); );
} }
@@ -73,7 +83,7 @@ export class AdminNotifyDashboardComponent implements OnInit{
return { return {
...metricsBoxes.find(box => box.config === objectConfig), ...metricsBoxes.find(box => box.config === objectConfig),
count count,
}; };
} }
@@ -87,7 +97,7 @@ export class AdminNotifyDashboardComponent implements OnInit{
return this.metricsConfig.map(row => { return this.metricsConfig.map(row => {
return { return {
...row, ...row,
boxes: row.boxes.map(rowBox => boxesWithCount.find(boxWithCount => boxWithCount.config === rowBox.config)) boxes: row.boxes.map(rowBox => boxesWithCount.find(boxWithCount => boxWithCount.config === rowBox.config)),
}; };
}); });
} }

View File

@@ -1,21 +1,25 @@
import {
CommonModule,
DatePipe,
} from '@angular/common';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { CommonModule, DatePipe } from '@angular/common';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { SearchPageModule } from '../../search-page/search-page.module';
import { SearchModule } from '../../shared/search/search.module';
import { SharedModule } from '../../shared/shared.module';
import { AdminNotifyDashboardComponent } from './admin-notify-dashboard.component'; import { AdminNotifyDashboardComponent } from './admin-notify-dashboard.component';
import { AdminNotifyDashboardRoutingModule } from './admin-notify-dashboard-routing.module'; import { AdminNotifyDashboardRoutingModule } from './admin-notify-dashboard-routing.module';
import { AdminNotifyMetricsComponent } from './admin-notify-metrics/admin-notify-metrics.component';
import { AdminNotifyIncomingComponent } from './admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component';
import { SharedModule } from '../../shared/shared.module';
import { SearchModule } from '../../shared/search/search.module';
import { SearchPageModule } from '../../search-page/search-page.module';
import { AdminNotifyOutgoingComponent } from './admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component';
import { AdminNotifyDetailModalComponent } from './admin-notify-detail-modal/admin-notify-detail-modal.component'; import { AdminNotifyDetailModalComponent } from './admin-notify-detail-modal/admin-notify-detail-modal.component';
import { AdminNotifyIncomingComponent } from './admin-notify-logs/admin-notify-incoming/admin-notify-incoming.component';
import { AdminNotifyLogsResultComponent } from './admin-notify-logs/admin-notify-logs-result/admin-notify-logs-result.component';
import { AdminNotifyOutgoingComponent } from './admin-notify-logs/admin-notify-outgoing/admin-notify-outgoing.component';
import { AdminNotifyMetricsComponent } from './admin-notify-metrics/admin-notify-metrics.component';
import { AdminNotifySearchResultComponent } from './admin-notify-search-result/admin-notify-search-result.component'; import { AdminNotifySearchResultComponent } from './admin-notify-search-result/admin-notify-search-result.component';
import { AdminNotifyMessagesService } from './services/admin-notify-messages.service'; import { AdminNotifyMessagesService } from './services/admin-notify-messages.service';
import { AdminNotifyLogsResultComponent } from './admin-notify-logs/admin-notify-logs-result/admin-notify-logs-result.component';
const ENTRY_COMPONENTS = [ const ENTRY_COMPONENTS = [
AdminNotifySearchResultComponent AdminNotifySearchResultComponent,
]; ];
@NgModule({ @NgModule({
imports: [ imports: [
@@ -24,11 +28,11 @@ const ENTRY_COMPONENTS = [
SharedModule, SharedModule,
AdminNotifyDashboardRoutingModule, AdminNotifyDashboardRoutingModule,
SearchModule, SearchModule,
SearchPageModule SearchPageModule,
], ],
providers: [ providers: [
AdminNotifyMessagesService, AdminNotifyMessagesService,
DatePipe DatePipe,
], ],
declarations: [ declarations: [
...ENTRY_COMPONENTS, ...ENTRY_COMPONENTS,
@@ -38,14 +42,14 @@ const ENTRY_COMPONENTS = [
AdminNotifyOutgoingComponent, AdminNotifyOutgoingComponent,
AdminNotifyDetailModalComponent, AdminNotifyDetailModalComponent,
AdminNotifySearchResultComponent, AdminNotifySearchResultComponent,
AdminNotifyLogsResultComponent AdminNotifyLogsResultComponent,
] ],
}) })
export class AdminNotifyDashboardModule { export class AdminNotifyDashboardModule {
static withEntryComponents() { static withEntryComponents() {
return { return {
ngModule: AdminNotifyDashboardModule, ngModule: AdminNotifyDashboardModule,
providers: ENTRY_COMPONENTS.map((component) => ({provide: component})) providers: ENTRY_COMPONENTS.map((component) => ({ provide: component })),
}; };
} }
} }

View File

@@ -1,9 +1,12 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {
ComponentFixture,
import { AdminNotifyDetailModalComponent } from './admin-notify-detail-modal.component'; TestBed,
} from '@angular/core/testing';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { AdminNotifyDetailModalComponent } from './admin-notify-detail-modal.component';
describe('AdminNotifyDetailModalComponent', () => { describe('AdminNotifyDetailModalComponent', () => {
let component: AdminNotifyDetailModalComponent; let component: AdminNotifyDetailModalComponent;
let fixture: ComponentFixture<AdminNotifyDetailModalComponent>; let fixture: ComponentFixture<AdminNotifyDetailModalComponent>;
@@ -14,7 +17,7 @@ describe('AdminNotifyDetailModalComponent', () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
imports: [TranslateModule.forRoot()], imports: [TranslateModule.forRoot()],
declarations: [ AdminNotifyDetailModalComponent ], declarations: [ AdminNotifyDetailModalComponent ],
providers: [{ provide: NgbActiveModal, useValue: modalStub }] providers: [{ provide: NgbActiveModal, useValue: modalStub }],
}) })
.compileComponents(); .compileComponents();

View File

@@ -1,16 +1,22 @@
import { Component, EventEmitter, Input, Output } from '@angular/core'; import {
import { AdminNotifyMessage } from '../models/admin-notify-message.model'; Component,
EventEmitter,
Input,
Output,
} from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { MissingTranslationHelper } from '../../../shared/translate/missing-translation.helper';
import { fadeIn } from '../../../shared/animations/fade'; import { fadeIn } from '../../../shared/animations/fade';
import { MissingTranslationHelper } from '../../../shared/translate/missing-translation.helper';
import { AdminNotifyMessage } from '../models/admin-notify-message.model';
@Component({ @Component({
selector: 'ds-admin-notify-detail-modal', selector: 'ds-admin-notify-detail-modal',
templateUrl: './admin-notify-detail-modal.component.html', templateUrl: './admin-notify-detail-modal.component.html',
animations: [ animations: [
fadeIn fadeIn,
] ],
}) })
/** /**
* Component for detailed view of LDN messages displayed in search result in AdminNotifyDashboardComponent * Component for detailed view of LDN messages displayed in search result in AdminNotifyDashboardComponent

View File

@@ -1,18 +1,21 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {
ComponentFixture,
import { AdminNotifyIncomingComponent } from './admin-notify-incoming.component'; TestBed,
import { TranslateModule } from '@ngx-translate/core'; } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { MockActivatedRoute } from '../../../../shared/mocks/active-router.mock';
import { provideMockStore } from '@ngrx/store/testing'; import { provideMockStore } from '@ngrx/store/testing';
import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service'; import { TranslateModule } from '@ngx-translate/core';
import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component';
import { RouteService } from '../../../../core/services/route.service';
import { routeServiceStub } from '../../../../shared/testing/route-service.stub';
import { RequestService } from '../../../../core/data/request.service';
import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service';
import { getMockRemoteDataBuildService } from '../../../../shared/mocks/remote-data-build.service.mock'; import { RequestService } from '../../../../core/data/request.service';
import { RouteService } from '../../../../core/services/route.service';
import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service';
import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service';
import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component';
import { MockActivatedRoute } from '../../../../shared/mocks/active-router.mock';
import { getMockRemoteDataBuildService } from '../../../../shared/mocks/remote-data-build.service.mock';
import { routeServiceStub } from '../../../../shared/testing/route-service.stub';
import { AdminNotifyIncomingComponent } from './admin-notify-incoming.component';
describe('AdminNotifyIncomingComponent', () => { describe('AdminNotifyIncomingComponent', () => {
let component: AdminNotifyIncomingComponent; let component: AdminNotifyIncomingComponent;
@@ -26,7 +29,7 @@ describe('AdminNotifyIncomingComponent', () => {
beforeEach(async () => { beforeEach(async () => {
rdbService = getMockRemoteDataBuildService(); rdbService = getMockRemoteDataBuildService();
halService = jasmine.createSpyObj('halService', { halService = jasmine.createSpyObj('halService', {
'getRootHref': '/api' 'getRootHref': '/api',
}); });
requestService = jasmine.createSpyObj('requestService', { requestService = jasmine.createSpyObj('requestService', {
'generateRequestId': 'client/1234', 'generateRequestId': 'client/1234',
@@ -43,7 +46,7 @@ describe('AdminNotifyIncomingComponent', () => {
{ provide: RequestService, useValue: requestService }, { provide: RequestService, useValue: requestService },
{ provide: RemoteDataBuildService, useValue: rdbService }, { provide: RemoteDataBuildService, useValue: rdbService },
provideMockStore({}), provideMockStore({}),
] ],
}) })
.compileComponents(); .compileComponents();

View File

@@ -1,6 +1,10 @@
import { Component, Inject } from '@angular/core'; import {
import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; Component,
Inject,
} from '@angular/core';
import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service';
import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component';
@Component({ @Component({
selector: 'ds-admin-notify-incoming', selector: 'ds-admin-notify-incoming',
@@ -8,9 +12,9 @@ import { SearchConfigurationService } from '../../../../core/shared/search/searc
providers: [ providers: [
{ {
provide: SEARCH_CONFIG_SERVICE, provide: SEARCH_CONFIG_SERVICE,
useClass: SearchConfigurationService useClass: SearchConfigurationService,
} },
] ],
}) })
export class AdminNotifyIncomingComponent { export class AdminNotifyIncomingComponent {
constructor(@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService) { constructor(@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService) {

View File

@@ -1,17 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {
ComponentFixture,
import { AdminNotifyLogsResultComponent } from './admin-notify-logs-result.component'; TestBed,
import { ActivatedRoute, Router } from '@angular/router'; } from '@angular/core/testing';
import { MockActivatedRoute } from '../../../../shared/mocks/active-router.mock'; import {
ActivatedRoute,
Router,
} from '@angular/router';
import { provideMockStore } from '@ngrx/store/testing'; import { provideMockStore } from '@ngrx/store/testing';
import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service'; import { TranslateModule } from '@ngx-translate/core';
import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../../core/cache/object-cache.service'; import { ObjectCacheService } from '../../../../core/cache/object-cache.service';
import { RequestService } from '../../../../core/data/request.service'; import { RequestService } from '../../../../core/data/request.service';
import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service';
import { TranslateModule } from '@ngx-translate/core';
import { RouterStub } from '../../../../shared/testing/router.stub';
import { RouteService } from '../../../../core/services/route.service'; import { RouteService } from '../../../../core/services/route.service';
import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service';
import { MockActivatedRoute } from '../../../../shared/mocks/active-router.mock';
import { routeServiceStub } from '../../../../shared/testing/route-service.stub'; import { routeServiceStub } from '../../../../shared/testing/route-service.stub';
import { RouterStub } from '../../../../shared/testing/router.stub';
import { AdminNotifyLogsResultComponent } from './admin-notify-logs-result.component';
describe('AdminNotifyLogsResultComponent', () => { describe('AdminNotifyLogsResultComponent', () => {
let component: AdminNotifyLogsResultComponent; let component: AdminNotifyLogsResultComponent;
@@ -34,7 +40,7 @@ describe('AdminNotifyLogsResultComponent', () => {
{ provide: RequestService, useValue: requestService }, { provide: RequestService, useValue: requestService },
{ provide: RemoteDataBuildService, useValue: rdbService }, { provide: RemoteDataBuildService, useValue: rdbService },
provideMockStore({}), provideMockStore({}),
] ],
}) })
.compileComponents(); .compileComponents();

View File

@@ -1,11 +1,22 @@
import { ChangeDetectorRef, Component, Inject, Input, OnInit } from '@angular/core'; import {
import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; ChangeDetectorRef,
Component,
Inject,
Input,
OnInit,
} from '@angular/core';
import {
ActivatedRoute,
ActivatedRouteSnapshot,
Router,
} from '@angular/router';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Context } from '../../../../core/shared/context.model'; import { Context } from '../../../../core/shared/context.model';
import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service';
import { Observable } from 'rxjs';
import { ActivatedRoute, ActivatedRouteSnapshot, Router } from '@angular/router';
import { ViewMode } from '../../../../core/shared/view-mode.model'; import { ViewMode } from '../../../../core/shared/view-mode.model';
import { map } from 'rxjs/operators'; import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component';
@Component({ @Component({
selector: 'ds-admin-notify-logs-result', selector: 'ds-admin-notify-logs-result',
@@ -13,9 +24,9 @@ import { map } from 'rxjs/operators';
providers: [ providers: [
{ {
provide: SEARCH_CONFIG_SERVICE, provide: SEARCH_CONFIG_SERVICE,
useClass: SearchConfigurationService useClass: SearchConfigurationService,
} },
] ],
}) })
/** /**
@@ -42,7 +53,7 @@ export class AdminNotifyLogsResultComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.selectedSearchConfig$ = this.searchConfigService.getCurrentConfiguration(this.defaultConfiguration); this.selectedSearchConfig$ = this.searchConfigService.getCurrentConfiguration(this.defaultConfiguration);
this.isInbound$ = this.selectedSearchConfig$.pipe( this.isInbound$ = this.selectedSearchConfig$.pipe(
map(config => config.startsWith('NOTIFY.incoming')) map(config => config.startsWith('NOTIFY.incoming')),
); );
} }

View File

@@ -1,18 +1,21 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {
ComponentFixture,
import { AdminNotifyOutgoingComponent } from './admin-notify-outgoing.component'; TestBed,
import { TranslateModule } from '@ngx-translate/core'; } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { MockActivatedRoute } from '../../../../shared/mocks/active-router.mock';
import { provideMockStore } from '@ngrx/store/testing'; import { provideMockStore } from '@ngrx/store/testing';
import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service'; import { TranslateModule } from '@ngx-translate/core';
import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component';
import { RouteService } from '../../../../core/services/route.service';
import { routeServiceStub } from '../../../../shared/testing/route-service.stub';
import { RequestService } from '../../../../core/data/request.service';
import { getMockRemoteDataBuildService } from '../../../../shared/mocks/remote-data-build.service.mock';
import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service';
import { RequestService } from '../../../../core/data/request.service';
import { RouteService } from '../../../../core/services/route.service';
import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service';
import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service';
import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component';
import { MockActivatedRoute } from '../../../../shared/mocks/active-router.mock';
import { getMockRemoteDataBuildService } from '../../../../shared/mocks/remote-data-build.service.mock';
import { routeServiceStub } from '../../../../shared/testing/route-service.stub';
import { AdminNotifyOutgoingComponent } from './admin-notify-outgoing.component';
describe('AdminNotifyOutgoingComponent', () => { describe('AdminNotifyOutgoingComponent', () => {
let component: AdminNotifyOutgoingComponent; let component: AdminNotifyOutgoingComponent;
@@ -29,7 +32,7 @@ describe('AdminNotifyOutgoingComponent', () => {
'send': '', 'send': '',
}); });
halService = jasmine.createSpyObj('halService', { halService = jasmine.createSpyObj('halService', {
'getRootHref': '/api' 'getRootHref': '/api',
}); });
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
imports: [TranslateModule.forRoot()], imports: [TranslateModule.forRoot()],
@@ -42,7 +45,7 @@ describe('AdminNotifyOutgoingComponent', () => {
{ provide: RequestService, useValue: requestService }, { provide: RequestService, useValue: requestService },
{ provide: RemoteDataBuildService, useValue: rdbService }, { provide: RemoteDataBuildService, useValue: rdbService },
provideMockStore({}), provideMockStore({}),
] ],
}) })
.compileComponents(); .compileComponents();

View File

@@ -1,6 +1,10 @@
import { Component, Inject } from '@angular/core'; import {
import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; Component,
Inject,
} from '@angular/core';
import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service';
import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component';
@Component({ @Component({
selector: 'ds-admin-notify-outgoing', selector: 'ds-admin-notify-outgoing',
@@ -8,9 +12,9 @@ import { SearchConfigurationService } from '../../../../core/shared/search/searc
providers: [ providers: [
{ {
provide: SEARCH_CONFIG_SERVICE, provide: SEARCH_CONFIG_SERVICE,
useClass: SearchConfigurationService useClass: SearchConfigurationService,
} },
] ],
}) })
export class AdminNotifyOutgoingComponent { export class AdminNotifyOutgoingComponent {
constructor(@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService) { constructor(@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService) {

View File

@@ -1,10 +1,13 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {
ComponentFixture,
import { AdminNotifyMetricsComponent } from './admin-notify-metrics.component'; TestBed,
import { TranslateModule } from '@ngx-translate/core'; } from '@angular/core/testing';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { ViewMode } from '../../../core/shared/view-mode.model'; import { ViewMode } from '../../../core/shared/view-mode.model';
import { RouterStub } from '../../../shared/testing/router.stub'; import { RouterStub } from '../../../shared/testing/router.stub';
import { AdminNotifyMetricsComponent } from './admin-notify-metrics.component';
describe('AdminNotifyMetricsComponent', () => { describe('AdminNotifyMetricsComponent', () => {
let component: AdminNotifyMetricsComponent; let component: AdminNotifyMetricsComponent;
@@ -13,14 +16,14 @@ describe('AdminNotifyMetricsComponent', () => {
beforeEach(async () => { beforeEach(async () => {
router = Object.assign(new RouterStub(), router = Object.assign(new RouterStub(),
{url : '/notify-dashboard'} { url : '/notify-dashboard' },
); );
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
imports: [TranslateModule.forRoot()], imports: [TranslateModule.forRoot()],
declarations: [ AdminNotifyMetricsComponent ], declarations: [ AdminNotifyMetricsComponent ],
providers: [{provide: Router, useValue: router}] providers: [{ provide: Router, useValue: router }],
}) })
.compileComponents(); .compileComponents();
@@ -42,21 +45,21 @@ describe('AdminNotifyMetricsComponent', () => {
const routeExtras = { const routeExtras = {
queryParams: { queryParams: {
configuration: searchConfig, configuration: searchConfig,
view: ViewMode.ListElement view: ViewMode.ListElement,
}, },
}; };
const routeExtrasTable = { const routeExtrasTable = {
queryParams: { queryParams: {
configuration: incomingConfig, configuration: incomingConfig,
view: ViewMode.Table view: ViewMode.Table,
}, },
}; };
const routeExtrasTableOutgoing = { const routeExtrasTableOutgoing = {
queryParams: { queryParams: {
configuration: outgoingConfig, configuration: outgoingConfig,
view: ViewMode.Table view: ViewMode.Table,
}, },
}; };
component.navigateToSelectedSearchConfig(searchConfig); component.navigateToSelectedSearchConfig(searchConfig);

View File

@@ -1,7 +1,11 @@
import { Component, Input } from '@angular/core'; import {
import { AdminNotifyMetricsRow } from './admin-notify-metrics.model'; Component,
Input,
} from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { ViewMode } from '../../../core/shared/view-mode.model'; import { ViewMode } from '../../../core/shared/view-mode.model';
import { AdminNotifyMetricsRow } from './admin-notify-metrics.model';
@Component({ @Component({
selector: 'ds-admin-notify-metrics', selector: 'ds-admin-notify-metrics',
@@ -33,7 +37,7 @@ export class AdminNotifyMetricsComponent {
this.router.navigate([this.adminSearchPath], { this.router.navigate([this.adminSearchPath], {
queryParams: { queryParams: {
configuration: searchConfig, configuration: searchConfig,
view: ViewMode.ListElement view: ViewMode.ListElement,
}, },
}); });
@@ -46,7 +50,7 @@ export class AdminNotifyMetricsComponent {
this.router.navigate([`${this.router.url}${selectedPath}`], { this.router.navigate([`${this.router.url}${selectedPath}`], {
queryParams: { queryParams: {
configuration: searchConfig, configuration: searchConfig,
view: ViewMode.Table view: ViewMode.Table,
}, },
}); });
} }

View File

@@ -1,25 +1,32 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AdminNotifySearchResultComponent } from './admin-notify-search-result.component';
import { AdminNotifyMessagesService } from '../services/admin-notify-messages.service';
import { ObjectCacheService } from '../../../core/cache/object-cache.service';
import { RequestService } from '../../../core/data/request.service';
import { HALEndpointService } from '../../../core/shared/hal-endpoint.service';
import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service';
import { cold } from 'jasmine-marbles';
import { ConfigurationProperty } from '../../../core/shared/configuration-property.model';
import { RouteService } from '../../../core/services/route.service';
import { routeServiceStub } from '../../../shared/testing/route-service.stub';
import { ActivatedRoute } from '@angular/router';
import { RouterStub } from '../../../shared/testing/router.stub';
import { TranslateModule } from '@ngx-translate/core';
import { of as observableOf, of } from 'rxjs';
import { AdminNotifyMessage } from '../models/admin-notify-message.model';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { AdminNotifyDetailModalComponent } from '../admin-notify-detail-modal/admin-notify-detail-modal.component';
import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service';
import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component';
import { DatePipe } from '@angular/common'; import { DatePipe } from '@angular/common';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import {
ComponentFixture,
TestBed,
} from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core';
import { cold } from 'jasmine-marbles';
import {
of as observableOf,
of,
} from 'rxjs';
import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../core/cache/object-cache.service';
import { RequestService } from '../../../core/data/request.service';
import { RouteService } from '../../../core/services/route.service';
import { ConfigurationProperty } from '../../../core/shared/configuration-property.model';
import { HALEndpointService } from '../../../core/shared/hal-endpoint.service';
import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service';
import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component';
import { routeServiceStub } from '../../../shared/testing/route-service.stub';
import { RouterStub } from '../../../shared/testing/router.stub';
import { AdminNotifyDetailModalComponent } from '../admin-notify-detail-modal/admin-notify-detail-modal.component';
import { AdminNotifyMessage } from '../models/admin-notify-message.model';
import { AdminNotifyMessagesService } from '../services/admin-notify-messages.service';
import { AdminNotifySearchResultComponent } from './admin-notify-search-result.component';
export const mockAdminNotifyMessages = [ export const mockAdminNotifyMessages = [
{ {
@@ -39,15 +46,15 @@ export const mockAdminNotifyMessages = [
'queueStatus': 3, 'queueStatus': 3,
'_links': { '_links': {
'self': { 'self': {
'href': 'http://localhost:8080/server/api/ldn/messages/urn:uuid:5fb3af44-d4f8-4226-9475-2d09c2d8d9e0' 'href': 'http://localhost:8080/server/api/ldn/messages/urn:uuid:5fb3af44-d4f8-4226-9475-2d09c2d8d9e0',
} },
}, },
'thumbnail': 'test', 'thumbnail': 'test',
'item': {}, 'item': {},
'accessStatus': {}, 'accessStatus': {},
'ldnService': 'NOTIFY inbox - Automatic service', 'ldnService': 'NOTIFY inbox - Automatic service',
'relatedItem': 'test coar 2 demo', 'relatedItem': 'test coar 2 demo',
'message': '{"@context":["https://www.w3.org/ns/activitystreams","https://purl.org/coar/notify"],"id":"urn:uuid:668f26e0-2e8d-4118-b0d2-ee713523bc45","type":["Reject","coar-notify:IngestAction"],"actor":{"id":"https://generic-service.com","type":["Service"],"name":"Generic Service"},"context":{"id":"https://dspace-coar.4science.cloud/handle/123456789/28","type":["Document"],"ietf:cite-as":"https://doi.org/10.4598/12123488"},"object":{"id":"https://dspace-coar.4science.cloud/handle/123456789/28","type":["Offer"]},"origin":{"id":"https://generic-service.com/system","type":["Service"],"inbox":"https://notify-inbox.info/inbox7"},"target":{"id":"https://some-organisation.org","type":["Organization"],"inbox":"https://dspace-coar.4science.cloud/server/ldn/inbox"},"inReplyTo":"urn:uuid:d9b4010a-f128-4815-abb2-83707a2ee9cf"}' 'message': '{"@context":["https://www.w3.org/ns/activitystreams","https://purl.org/coar/notify"],"id":"urn:uuid:668f26e0-2e8d-4118-b0d2-ee713523bc45","type":["Reject","coar-notify:IngestAction"],"actor":{"id":"https://generic-service.com","type":["Service"],"name":"Generic Service"},"context":{"id":"https://dspace-coar.4science.cloud/handle/123456789/28","type":["Document"],"ietf:cite-as":"https://doi.org/10.4598/12123488"},"object":{"id":"https://dspace-coar.4science.cloud/handle/123456789/28","type":["Offer"]},"origin":{"id":"https://generic-service.com/system","type":["Service"],"inbox":"https://notify-inbox.info/inbox7"},"target":{"id":"https://some-organisation.org","type":["Organization"],"inbox":"https://dspace-coar.4science.cloud/server/ldn/inbox"},"inReplyTo":"urn:uuid:d9b4010a-f128-4815-abb2-83707a2ee9cf"}',
}, },
{ {
'type': 'message', 'type': 'message',
@@ -66,16 +73,16 @@ export const mockAdminNotifyMessages = [
'queueStatus': 6, 'queueStatus': 6,
'_links': { '_links': {
'self': { 'self': {
'href': 'http://localhost:8080/server/api/ldn/messages/urn:uuid:544c8777-e826-4810-a625-3e394cc3660d' 'href': 'http://localhost:8080/server/api/ldn/messages/urn:uuid:544c8777-e826-4810-a625-3e394cc3660d',
} },
}, },
'thumbnail': {}, 'thumbnail': {},
'item': {}, 'item': {},
'accessStatus': {}, 'accessStatus': {},
'ldnService': 'NOTIFY inbox - Automatic service', 'ldnService': 'NOTIFY inbox - Automatic service',
'relatedItem': 'test coar demo', 'relatedItem': 'test coar demo',
'message': '{"@context":["https://www.w3.org/ns/activitystreams","https://purl.org/coar/notify"],"id":"urn:uuid:668f26e0-2e8d-4118-b0d2-ee713523bc45","type":["Reject","coar-notify:IngestAction"],"actor":{"id":"https://generic-service.com","type":["Service"],"name":"Generic Service"},"context":{"id":"https://dspace-coar.4science.cloud/handle/123456789/28","type":["Document"],"ietf:cite-as":"https://doi.org/10.4598/12123488"},"object":{"id":"https://dspace-coar.4science.cloud/handle/123456789/28","type":["Offer"]},"origin":{"id":"https://generic-service.com/system","type":["Service"],"inbox":"https://notify-inbox.info/inbox7"},"target":{"id":"https://some-organisation.org","type":["Organization"],"inbox":"https://dspace-coar.4science.cloud/server/ldn/inbox"},"inReplyTo":"urn:uuid:d9b4010a-f128-4815-abb2-83707a2ee9cf"}' 'message': '{"@context":["https://www.w3.org/ns/activitystreams","https://purl.org/coar/notify"],"id":"urn:uuid:668f26e0-2e8d-4118-b0d2-ee713523bc45","type":["Reject","coar-notify:IngestAction"],"actor":{"id":"https://generic-service.com","type":["Service"],"name":"Generic Service"},"context":{"id":"https://dspace-coar.4science.cloud/handle/123456789/28","type":["Document"],"ietf:cite-as":"https://doi.org/10.4598/12123488"},"object":{"id":"https://dspace-coar.4science.cloud/handle/123456789/28","type":["Offer"]},"origin":{"id":"https://generic-service.com/system","type":["Service"],"inbox":"https://notify-inbox.info/inbox7"},"target":{"id":"https://some-organisation.org","type":["Organization"],"inbox":"https://dspace-coar.4science.cloud/server/ldn/inbox"},"inReplyTo":"urn:uuid:d9b4010a-f128-4815-abb2-83707a2ee9cf"}',
} },
] as unknown as AdminNotifyMessage[]; ] as unknown as AdminNotifyMessage[];
describe('AdminNotifySearchResultComponent', () => { describe('AdminNotifySearchResultComponent', () => {
let component: AdminNotifySearchResultComponent; let component: AdminNotifySearchResultComponent;
@@ -91,12 +98,12 @@ describe('AdminNotifySearchResultComponent', () => {
const testObject = { const testObject = {
uuid: 'test-property', uuid: 'test-property',
name: 'test-property', name: 'test-property',
values: ['value-1', 'value-2'] values: ['value-1', 'value-2'],
} as ConfigurationProperty; } as ConfigurationProperty;
beforeEach(async () => { beforeEach(async () => {
halService = jasmine.createSpyObj('halService', { halService = jasmine.createSpyObj('halService', {
getEndpoint: cold('a', { a: '' }) getEndpoint: cold('a', { a: '' }),
}); });
adminNotifyMessageService = jasmine.createSpyObj('adminNotifyMessageService', { adminNotifyMessageService = jasmine.createSpyObj('adminNotifyMessageService', {
getDetailedMessages: of(mockAdminNotifyMessages), getDetailedMessages: of(mockAdminNotifyMessages),
@@ -104,18 +111,18 @@ describe('AdminNotifySearchResultComponent', () => {
}); });
requestService = jasmine.createSpyObj('requestService', { requestService = jasmine.createSpyObj('requestService', {
generateRequestId: requestUUID, generateRequestId: requestUUID,
send: true send: true,
}); });
rdbService = jasmine.createSpyObj('rdbService', { rdbService = jasmine.createSpyObj('rdbService', {
buildSingle: cold('a', { buildSingle: cold('a', {
a: { a: {
payload: testObject payload: testObject,
} },
}) }),
}); });
searchConfigService = jasmine.createSpyObj('searchConfigService', { searchConfigService = jasmine.createSpyObj('searchConfigService', {
getCurrentConfiguration: of('NOTIFY.outgoing') getCurrentConfiguration: of('NOTIFY.outgoing'),
}); });
objectCache = {} as ObjectCacheService; objectCache = {} as ObjectCacheService;
@@ -132,9 +139,9 @@ describe('AdminNotifySearchResultComponent', () => {
{ provide: RequestService, useValue: requestService }, { provide: RequestService, useValue: requestService },
{ provide: RemoteDataBuildService, useValue: rdbService }, { provide: RemoteDataBuildService, useValue: rdbService },
{ provide: SEARCH_CONFIG_SERVICE, useValue: searchConfigService }, { provide: SEARCH_CONFIG_SERVICE, useValue: searchConfigService },
DatePipe DatePipe,
], ],
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA],
}) })
.compileComponents(); .compileComponents();

View File

@@ -1,18 +1,27 @@
import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; import { DatePipe } from '@angular/common';
import { AdminNotifySearchResult } from '../models/admin-notify-message-search-result.model'; import {
import { ViewMode } from '../../../core/shared/view-mode.model'; Component,
Inject,
OnDestroy,
OnInit,
} from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import {
BehaviorSubject,
Subscription,
} from 'rxjs';
import { PaginatedList } from '../../../core/data/paginated-list.model';
import { Context } from '../../../core/shared/context.model'; import { Context } from '../../../core/shared/context.model';
import { AdminNotifyMessage } from '../models/admin-notify-message.model'; import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service';
import { ViewMode } from '../../../core/shared/view-mode.model';
import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component';
import { tabulatableObjectsComponent } from '../../../shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator'; import { tabulatableObjectsComponent } from '../../../shared/object-collection/shared/tabulatable-objects/tabulatable-objects.decorator';
import { TabulatableResultListElementsComponent } from '../../../shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component'; import { TabulatableResultListElementsComponent } from '../../../shared/object-list/search-result-list-element/tabulatable-search-result/tabulatable-result-list-elements.component';
import { PaginatedList } from '../../../core/data/paginated-list.model';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { AdminNotifyDetailModalComponent } from '../admin-notify-detail-modal/admin-notify-detail-modal.component'; import { AdminNotifyDetailModalComponent } from '../admin-notify-detail-modal/admin-notify-detail-modal.component';
import { BehaviorSubject, Subscription } from 'rxjs'; import { AdminNotifyMessage } from '../models/admin-notify-message.model';
import { AdminNotifySearchResult } from '../models/admin-notify-message-search-result.model';
import { AdminNotifyMessagesService } from '../services/admin-notify-messages.service'; import { AdminNotifyMessagesService } from '../services/admin-notify-messages.service';
import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service';
import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component';
import { DatePipe } from '@angular/common';
@tabulatableObjectsComponent(PaginatedList<AdminNotifySearchResult>, ViewMode.Table, Context.CoarNotify) @tabulatableObjectsComponent(PaginatedList<AdminNotifySearchResult>, ViewMode.Table, Context.CoarNotify)
@Component({ @Component({
@@ -21,9 +30,9 @@ import { DatePipe } from '@angular/common';
providers: [ providers: [
{ {
provide: SEARCH_CONFIG_SERVICE, provide: SEARCH_CONFIG_SERVICE,
useClass: SearchConfigurationService useClass: SearchConfigurationService,
} },
] ],
}) })
/** /**
* Component for visualization in table format of the search results related to the AdminNotifyDashboardComponent * Component for visualization in table format of the search results related to the AdminNotifyDashboardComponent
@@ -43,7 +52,7 @@ export class AdminNotifySearchResultComponent extends TabulatableResultListEleme
'QUEUE_STATUS_UNTRUSTED', 'QUEUE_STATUS_UNTRUSTED',
'QUEUE_STATUS_UNTRUSTED_IP', 'QUEUE_STATUS_UNTRUSTED_IP',
'QUEUE_STATUS_FAILED', 'QUEUE_STATUS_FAILED',
'QUEUE_STATUS_UNMAPPED_ACTION' 'QUEUE_STATUS_UNMAPPED_ACTION',
]; ];
@@ -73,7 +82,7 @@ export class AdminNotifySearchResultComponent extends TabulatableResultListEleme
'queueAttempts', 'queueAttempts',
'queueLastStartTime', 'queueLastStartTime',
'queueStatusLabel', 'queueStatusLabel',
'queueTimeout' 'queueTimeout',
]; ];
/** /**
@@ -97,7 +106,7 @@ export class AdminNotifySearchResultComponent extends TabulatableResultListEleme
this.subs.push(this.searchConfigService.getCurrentConfiguration('') this.subs.push(this.searchConfigService.getCurrentConfiguration('')
.subscribe(configuration => { .subscribe(configuration => {
this.isInbound = configuration.startsWith('NOTIFY.incoming'); this.isInbound = configuration.startsWith('NOTIFY.incoming');
}) }),
); );
} }
@@ -111,7 +120,7 @@ export class AdminNotifySearchResultComponent extends TabulatableResultListEleme
*/ */
openDetailModal(notifyMessage: AdminNotifyMessage) { openDetailModal(notifyMessage: AdminNotifyMessage) {
const modalRef = this.modalService.open(AdminNotifyDetailModalComponent); const modalRef = this.modalService.open(AdminNotifyDetailModalComponent);
const messageToOpen = {...notifyMessage}; const messageToOpen = { ...notifyMessage };
this.messageKeys.forEach(key => { this.messageKeys.forEach(key => {
if (this.dateTypeKeys.includes(key)) { if (this.dateTypeKeys.includes(key)) {
@@ -134,8 +143,8 @@ export class AdminNotifySearchResultComponent extends TabulatableResultListEleme
this.adminNotifyMessagesService.reprocessMessage(message, this.messagesSubject$) this.adminNotifyMessagesService.reprocessMessage(message, this.messagesSubject$)
.subscribe(response => { .subscribe(response => {
this.messagesSubject$.next(response); this.messagesSubject$.next(response);
} },
) ),
); );
} }

View File

@@ -1,6 +1,6 @@
import { AdminNotifyMessage } from './admin-notify-message.model';
import { searchResultFor } from '../../../shared/search/search-result-element-decorator';
import { SearchResult } from '../../../shared/search/models/search-result.model'; import { SearchResult } from '../../../shared/search/models/search-result.model';
import { searchResultFor } from '../../../shared/search/search-result-element-decorator';
import { AdminNotifyMessage } from './admin-notify-message.model';
@searchResultFor(AdminNotifyMessage) @searchResultFor(AdminNotifyMessage)
export class AdminNotifySearchResult extends SearchResult<AdminNotifyMessage> { export class AdminNotifySearchResult extends SearchResult<AdminNotifyMessage> {

View File

@@ -1,11 +1,16 @@
import { autoserialize, deserialize, inheritSerialization } from 'cerialize'; import {
autoserialize,
deserialize,
inheritSerialization,
} from 'cerialize';
import { Observable } from 'rxjs';
import { typedObject } from '../../../core/cache/builders/build-decorators'; import { typedObject } from '../../../core/cache/builders/build-decorators';
import { ADMIN_NOTIFY_MESSAGE } from './admin-notify-message.resource-type';
import { excludeFromEquals } from '../../../core/utilities/equals.decorators';
import { DSpaceObject } from '../../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { GenericConstructor } from '../../../core/shared/generic-constructor'; import { GenericConstructor } from '../../../core/shared/generic-constructor';
import { excludeFromEquals } from '../../../core/utilities/equals.decorators';
import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model'; import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model';
import { Observable } from 'rxjs'; import { ADMIN_NOTIFY_MESSAGE } from './admin-notify-message.resource-type';
/** /**
* A message that includes admin notify info * A message that includes admin notify info

View File

@@ -1,22 +1,26 @@
import { deepClone } from 'fast-json-patch';
import { cold } from 'jasmine-marbles'; import { cold } from 'jasmine-marbles';
import { AdminNotifyMessagesService } from './admin-notify-messages.service'; import {
import { RequestService } from '../../../core/data/request.service'; BehaviorSubject,
of,
} from 'rxjs';
import { take } from 'rxjs/operators';
import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../core/cache/object-cache.service'; import { ObjectCacheService } from '../../../core/cache/object-cache.service';
import { RestResponse } from '../../../core/cache/response.models';
import { ItemDataService } from '../../../core/data/item-data.service';
import { RemoteData } from '../../../core/data/remote-data';
import { RequestService } from '../../../core/data/request.service';
import { RequestEntry } from '../../../core/data/request-entry.model';
import { RequestEntryState } from '../../../core/data/request-entry-state.model';
import { HALEndpointService } from '../../../core/shared/hal-endpoint.service'; import { HALEndpointService } from '../../../core/shared/hal-endpoint.service';
import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { LdnServicesService } from '../../admin-ldn-services/ldn-services-data/ldn-services-data.service';
import { ItemDataService } from '../../../core/data/item-data.service';
import { RequestEntry } from '../../../core/data/request-entry.model';
import { RestResponse } from '../../../core/cache/response.models';
import { BehaviorSubject, of } from 'rxjs';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
import { RemoteData } from '../../../core/data/remote-data'; import { LdnServicesService } from '../../admin-ldn-services/ldn-services-data/ldn-services-data.service';
import { RequestEntryState } from '../../../core/data/request-entry-state.model';
import { mockAdminNotifyMessages } from '../admin-notify-search-result/admin-notify-search-result.component.spec'; import { mockAdminNotifyMessages } from '../admin-notify-search-result/admin-notify-search-result.component.spec';
import { take } from 'rxjs/operators';
import { deepClone } from 'fast-json-patch';
import { AdminNotifyMessage } from '../models/admin-notify-message.model'; import { AdminNotifyMessage } from '../models/admin-notify-message.model';
import { AdminNotifyMessagesService } from './admin-notify-messages.service';
describe('AdminNotifyMessagesService test', () => { describe('AdminNotifyMessagesService test', () => {
let service: AdminNotifyMessagesService; let service: AdminNotifyMessagesService;
@@ -46,7 +50,7 @@ describe('AdminNotifyMessagesService test', () => {
halService, halService,
notificationsService, notificationsService,
ldnServicesService, ldnServicesService,
itemDataService itemDataService,
); );
} }
@@ -68,21 +72,21 @@ describe('AdminNotifyMessagesService test', () => {
}); });
halService = jasmine.createSpyObj('halService', { halService = jasmine.createSpyObj('halService', {
getEndpoint: of(endpointURL) getEndpoint: of(endpointURL),
}); });
rdbService = jasmine.createSpyObj('rdbService', { rdbService = jasmine.createSpyObj('rdbService', {
buildSingle: createSuccessfulRemoteDataObject$({}, 500), buildSingle: createSuccessfulRemoteDataObject$({}, 500),
buildList: cold('a', { a: remoteDataMocks.Success }), buildList: cold('a', { a: remoteDataMocks.Success }),
buildFromRequestUUID: createSuccessfulRemoteDataObject$(mockMessages) buildFromRequestUUID: createSuccessfulRemoteDataObject$(mockMessages),
}); });
ldnServicesService = jasmine.createSpyObj('ldnServicesService', { ldnServicesService = jasmine.createSpyObj('ldnServicesService', {
findById: createSuccessfulRemoteDataObject$({name: testLdnServiceName}), findById: createSuccessfulRemoteDataObject$({ name: testLdnServiceName }),
}); });
itemDataService = jasmine.createSpyObj('itemDataService', { itemDataService = jasmine.createSpyObj('itemDataService', {
findById: createSuccessfulRemoteDataObject$({name: testRelatedItemName}), findById: createSuccessfulRemoteDataObject$({ name: testRelatedItemName }),
}); });
service = initTestService(); service = initTestService();

View File

@@ -1,20 +1,35 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { dataService } from '../../../core/data/base/data-service.decorator'; import {
import { IdentifiableDataService } from '../../../core/data/base/identifiable-data.service'; BehaviorSubject,
import { RequestService } from '../../../core/data/request.service'; from,
Observable,
of,
scan,
} from 'rxjs';
import {
map,
mergeMap,
switchMap,
tap,
} from 'rxjs/operators';
import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../core/cache/object-cache.service'; import { ObjectCacheService } from '../../../core/cache/object-cache.service';
import { HALEndpointService } from '../../../core/shared/hal-endpoint.service'; import { dataService } from '../../../core/data/base/data-service.decorator';
import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { IdentifiableDataService } from '../../../core/data/base/identifiable-data.service';
import { BehaviorSubject, from, Observable, of, scan } from 'rxjs';
import { ADMIN_NOTIFY_MESSAGE } from '../models/admin-notify-message.resource-type';
import { AdminNotifyMessage } from '../models/admin-notify-message.model';
import { map, mergeMap, switchMap, tap } from 'rxjs/operators';
import { getAllSucceededRemoteDataPayload, getFirstCompletedRemoteData } from '../../../core/shared/operators';
import { LdnServicesService } from '../../admin-ldn-services/ldn-services-data/ldn-services-data.service';
import { ItemDataService } from '../../../core/data/item-data.service'; import { ItemDataService } from '../../../core/data/item-data.service';
import { PostRequest } from '../../../core/data/request.models'; import { PostRequest } from '../../../core/data/request.models';
import { RequestService } from '../../../core/data/request.service';
import { RestRequest } from '../../../core/data/rest-request.model'; import { RestRequest } from '../../../core/data/rest-request.model';
import { HALEndpointService } from '../../../core/shared/hal-endpoint.service';
import {
getAllSucceededRemoteDataPayload,
getFirstCompletedRemoteData,
} from '../../../core/shared/operators';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { LdnServicesService } from '../../admin-ldn-services/ldn-services-data/ldn-services-data.service';
import { AdminNotifyMessage } from '../models/admin-notify-message.model';
import { ADMIN_NOTIFY_MESSAGE } from '../models/admin-notify-message.resource-type';
/** /**
* Injectable service responsible for fetching/sending data from/to the REST API on the messages endpoint. * Injectable service responsible for fetching/sending data from/to the REST API on the messages endpoint.
@@ -51,13 +66,13 @@ export class AdminNotifyMessagesService extends IdentifiableDataService<AdminNot
mergeMap(message => mergeMap(message =>
message.target || message.origin ? this.ldnServicesService.findById((message.target || message.origin).toString()).pipe( message.target || message.origin ? this.ldnServicesService.findById((message.target || message.origin).toString()).pipe(
getAllSucceededRemoteDataPayload(), getAllSucceededRemoteDataPayload(),
map(detail => ({...message, ldnService: detail.name})) map(detail => ({ ...message, ldnService: detail.name })),
) : of(message), ) : of(message),
), ),
mergeMap(message => mergeMap(message =>
message.object || message.context ? this.itemDataService.findById(message.object || message.context).pipe( message.object || message.context ? this.itemDataService.findById(message.object || message.context).pipe(
getAllSucceededRemoteDataPayload(), getAllSucceededRemoteDataPayload(),
map(detail => ({...message, relatedItem: detail.name})) map(detail => ({ ...message, relatedItem: detail.name })),
) : of(message), ) : of(message),
), ),
scan((acc: any, value: any) => [...acc, value], []), scan((acc: any, value: any) => [...acc, value], []),
@@ -93,7 +108,7 @@ export class AdminNotifyMessagesService extends IdentifiableDataService<AdminNot
messages[indexOfMessageToUpdate] = detailedReprocessedMessage; messages[indexOfMessageToUpdate] = detailedReprocessedMessage;
return messages; return messages;
}) }),
)), )),
); );
} }

View File

@@ -1,8 +1,9 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver';
import { FilteredCollectionsComponent } from './filtered-collections/filtered-collections.component'; import { FilteredCollectionsComponent } from './filtered-collections/filtered-collections.component';
import { FilteredItemsComponent } from './filtered-items/filtered-items.component'; import { FilteredItemsComponent } from './filtered-items/filtered-items.component';
import { RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver';
@NgModule({ @NgModule({
imports: [ imports: [
@@ -10,27 +11,27 @@ import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.r
{ {
path: 'collections', path: 'collections',
resolve: { breadcrumb: I18nBreadcrumbResolver }, resolve: { breadcrumb: I18nBreadcrumbResolver },
data: {title: 'admin.reports.collections.title', breadcrumbKey: 'admin.reports.collections'}, data: { title: 'admin.reports.collections.title', breadcrumbKey: 'admin.reports.collections' },
children: [ children: [
{ {
path: '', path: '',
component: FilteredCollectionsComponent component: FilteredCollectionsComponent,
} },
] ],
}, },
{ {
path: 'queries', path: 'queries',
resolve: { breadcrumb: I18nBreadcrumbResolver }, resolve: { breadcrumb: I18nBreadcrumbResolver },
data: {title: 'admin.reports.items.title', breadcrumbKey: 'admin.reports.items'}, data: { title: 'admin.reports.items.title', breadcrumbKey: 'admin.reports.items' },
children: [ children: [
{ {
path: '', path: '',
component: FilteredItemsComponent component: FilteredItemsComponent,
} },
] ],
} },
]) ]),
] ],
}) })
export class AdminReportsRoutingModule { export class AdminReportsRoutingModule {

View File

@@ -1,12 +1,13 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { FilteredCollectionsComponent } from './filtered-collections/filtered-collections.component'; import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { SharedModule } from '../../shared/shared.module';
import { FormModule } from '../../shared/form/form.module';
import { FilteredItemsComponent } from './filtered-items/filtered-items.component';
import { AdminReportsRoutingModule } from './admin-reports-routing.module';
import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap'; import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap';
import { FormModule } from '../../shared/form/form.module';
import { SharedModule } from '../../shared/shared.module';
import { AdminReportsRoutingModule } from './admin-reports-routing.module';
import { FilteredCollectionsComponent } from './filtered-collections/filtered-collections.component';
import { FilteredItemsComponent } from './filtered-items/filtered-items.component';
import { FiltersComponent } from './filters-section/filters-section.component'; import { FiltersComponent } from './filters-section/filters-section.component';
@NgModule({ @NgModule({
@@ -16,13 +17,13 @@ import { FiltersComponent } from './filters-section/filters-section.component';
RouterModule, RouterModule,
FormModule, FormModule,
AdminReportsRoutingModule, AdminReportsRoutingModule,
NgbAccordionModule NgbAccordionModule,
], ],
declarations: [ declarations: [
FilteredCollectionsComponent, FilteredCollectionsComponent,
FilteredItemsComponent, FilteredItemsComponent,
FiltersComponent FiltersComponent,
] ],
}) })
export class AdminReportsModule { export class AdminReportsModule {
} }

View File

@@ -25,8 +25,8 @@ export class FilteredCollection {
this.communityLabel = object.community_label; this.communityLabel = object.community_label;
this.communityHandle = object.community_handle; this.communityHandle = object.community_handle;
this.nbTotalItems = object.nb_total_items; this.nbTotalItems = object.nb_total_items;
let valuesPerFilter = object.values; const valuesPerFilter = object.values;
for (let filter in valuesPerFilter) { for (const filter in valuesPerFilter) {
if (valuesPerFilter.hasOwnProperty(filter)) { if (valuesPerFilter.hasOwnProperty(filter)) {
this.values[filter] = valuesPerFilter[filter]; this.values[filter] = valuesPerFilter[filter];
} }

View File

@@ -1,14 +1,25 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateLoaderMock } from 'src/app/shared/mocks/translate-loader.mock';
import { FormBuilder } from '@angular/forms';
import { FilteredCollectionsComponent } from './filtered-collections.component';
import { DspaceRestService } from 'src/app/core/dspace-rest/dspace-rest.service';
import { NgbAccordion, NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap';
import { HttpClientTestingModule } from '@angular/common/http/testing'; import { HttpClientTestingModule } from '@angular/common/http/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import {
ComponentFixture,
TestBed,
waitForAsync,
} from '@angular/core/testing';
import { FormBuilder } from '@angular/forms';
import {
NgbAccordion,
NgbAccordionModule,
} from '@ng-bootstrap/ng-bootstrap';
import {
TranslateLoader,
TranslateModule,
} from '@ngx-translate/core';
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { DspaceRestService } from 'src/app/core/dspace-rest/dspace-rest.service';
import { RawRestResponse } from 'src/app/core/dspace-rest/raw-rest-response.model'; import { RawRestResponse } from 'src/app/core/dspace-rest/raw-rest-response.model';
import { TranslateLoaderMock } from 'src/app/shared/mocks/translate-loader.mock';
import { FilteredCollectionsComponent } from './filtered-collections.component';
describe('FiltersComponent', () => { describe('FiltersComponent', () => {
let component: FilteredCollectionsComponent; let component: FilteredCollectionsComponent;
@@ -19,11 +30,11 @@ describe('FiltersComponent', () => {
payload: { payload: {
collections: [], collections: [],
summary: { summary: {
label: 'Test' label: 'Test',
} },
}, },
statusCode: 200, statusCode: 200,
statusText: 'OK' statusText: 'OK',
} as RawRestResponse; } as RawRestResponse;
beforeEach(waitForAsync(() => { beforeEach(waitForAsync(() => {
@@ -34,16 +45,16 @@ describe('FiltersComponent', () => {
TranslateModule.forRoot({ TranslateModule.forRoot({
loader: { loader: {
provide: TranslateLoader, provide: TranslateLoader,
useClass: TranslateLoaderMock useClass: TranslateLoaderMock,
} },
}), }),
HttpClientTestingModule HttpClientTestingModule,
], ],
providers: [ providers: [
FormBuilder, FormBuilder,
DspaceRestService DspaceRestService,
], ],
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA],
}); });
})); }));

View File

@@ -1,11 +1,18 @@
import { Component, ViewChild } from '@angular/core'; import {
import { FormBuilder, FormGroup } from '@angular/forms'; Component,
ViewChild,
} from '@angular/core';
import {
FormBuilder,
FormGroup,
} from '@angular/forms';
import { NgbAccordion } from '@ng-bootstrap/ng-bootstrap'; import { NgbAccordion } from '@ng-bootstrap/ng-bootstrap';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { RestRequestMethod } from 'src/app/core/data/rest-request-method'; import { RestRequestMethod } from 'src/app/core/data/rest-request-method';
import { DspaceRestService } from 'src/app/core/dspace-rest/dspace-rest.service'; import { DspaceRestService } from 'src/app/core/dspace-rest/dspace-rest.service';
import { RawRestResponse } from 'src/app/core/dspace-rest/raw-rest-response.model'; import { RawRestResponse } from 'src/app/core/dspace-rest/raw-rest-response.model';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
import { FiltersComponent } from '../filters-section/filters-section.component'; import { FiltersComponent } from '../filters-section/filters-section.component';
import { FilteredCollections } from './filtered-collections.model'; import { FilteredCollections } from './filtered-collections.model';
@@ -15,7 +22,7 @@ import { FilteredCollections } from './filtered-collections.model';
@Component({ @Component({
selector: 'ds-report-filtered-collections', selector: 'ds-report-filtered-collections',
templateUrl: './filtered-collections.component.html', templateUrl: './filtered-collections.component.html',
styleUrls: ['./filtered-collections.component.scss'] styleUrls: ['./filtered-collections.component.scss'],
}) })
export class FilteredCollectionsComponent { export class FilteredCollectionsComponent {
@@ -29,7 +36,7 @@ export class FilteredCollectionsComponent {
ngOnInit() { ngOnInit() {
this.queryForm = this.formBuilder.group({ this.queryForm = this.formBuilder.group({
filters: FiltersComponent.formGroup(this.formBuilder) filters: FiltersComponent.formGroup(this.formBuilder),
}); });
} }
@@ -48,7 +55,7 @@ export class FilteredCollectionsComponent {
response => { response => {
this.results.deserialize(response.payload); this.results.deserialize(response.payload);
this.accordionComponent.expand('collections'); this.accordionComponent.expand('collections');
} },
); );
} }
@@ -57,13 +64,13 @@ export class FilteredCollectionsComponent {
if (params.length > 0) { if (params.length > 0) {
params = `?${params}`; params = `?${params}`;
} }
let scheme = environment.rest.ssl ? 'https' : 'http'; const scheme = environment.rest.ssl ? 'https' : 'http';
let urlRestApp = `${scheme}://${environment.rest.host}:${environment.rest.port}${environment.rest.nameSpace}`; const urlRestApp = `${scheme}://${environment.rest.host}:${environment.rest.port}${environment.rest.nameSpace}`;
return this.restService.request(RestRequestMethod.GET, `${urlRestApp}/api/contentreport/filteredcollections${params}`); return this.restService.request(RestRequestMethod.GET, `${urlRestApp}/api/contentreport/filteredcollections${params}`);
} }
private toQueryString(): string { private toQueryString(): string {
let params = FiltersComponent.toQueryString(this.queryForm.value.filters); const params = FiltersComponent.toQueryString(this.queryForm.value.filters);
return params; return params;
} }

View File

@@ -12,12 +12,12 @@ export class FilteredCollections {
public deserialize(object: any) { public deserialize(object: any) {
this.clear(); this.clear();
let summary = object.summary; const summary = object.summary;
this.summary.deserialize(summary); this.summary.deserialize(summary);
let collections = object.collections; const collections = object.collections;
for (let i = 0; i < collections.length; i++) { for (let i = 0; i < collections.length; i++) {
let collection = collections[i]; const collection = collections[i];
let coll = new FilteredCollection(); const coll = new FilteredCollection();
coll.deserialize(collection); coll.deserialize(collection);
this.collections.push(coll); this.collections.push(coll);
} }

View File

@@ -12,9 +12,9 @@ export class FilteredItems {
public deserialize(object: any, offset: number = 0) { public deserialize(object: any, offset: number = 0) {
this.clear(); this.clear();
this.itemCount = object.itemCount; this.itemCount = object.itemCount;
let items = object.items; const items = object.items;
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
let item = items[i]; const item = items[i];
item.index = this.items.length + offset + 1; item.index = this.items.length + offset + 1;
this.items.push(item); this.items.push(item);
} }

View File

@@ -1,8 +1,19 @@
import { Component, ViewChild } from '@angular/core'; import {
import { FormArray, FormBuilder, FormControl, FormGroup } from '@angular/forms'; Component,
ViewChild,
} from '@angular/core';
import {
FormArray,
FormBuilder,
FormControl,
FormGroup,
} from '@angular/forms';
import { NgbAccordion } from '@ng-bootstrap/ng-bootstrap'; import { NgbAccordion } from '@ng-bootstrap/ng-bootstrap';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { map, Observable } from 'rxjs'; import {
map,
Observable,
} from 'rxjs';
import { CollectionDataService } from 'src/app/core/data/collection-data.service'; import { CollectionDataService } from 'src/app/core/data/collection-data.service';
import { CommunityDataService } from 'src/app/core/data/community-data.service'; import { CommunityDataService } from 'src/app/core/data/community-data.service';
import { MetadataFieldDataService } from 'src/app/core/data/metadata-field-data.service'; import { MetadataFieldDataService } from 'src/app/core/data/metadata-field-data.service';
@@ -18,6 +29,7 @@ import { Item } from 'src/app/core/shared/item.model';
import { getFirstSucceededRemoteListPayload } from 'src/app/core/shared/operators'; import { getFirstSucceededRemoteListPayload } from 'src/app/core/shared/operators';
import { isEmpty } from 'src/app/shared/empty.util'; import { isEmpty } from 'src/app/shared/empty.util';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
import { FiltersComponent } from '../filters-section/filters-section.component'; import { FiltersComponent } from '../filters-section/filters-section.component';
import { FilteredItems } from './filtered-items-model'; import { FilteredItems } from './filtered-items-model';
import { OptionVO } from './option-vo.model'; import { OptionVO } from './option-vo.model';
@@ -30,7 +42,7 @@ import { QueryPredicate } from './query-predicate.model';
@Component({ @Component({
selector: 'ds-report-filtered-items', selector: 'ds-report-filtered-items',
templateUrl: './filtered-items.component.html', templateUrl: './filtered-items.component.html',
styleUrls: ['./filtered-items.component.scss'] styleUrls: ['./filtered-items.component.scss'],
}) })
export class FilteredItemsComponent { export class FilteredItemsComponent {
@@ -63,8 +75,8 @@ export class FilteredItemsComponent {
this.loadPredicates(); this.loadPredicates();
this.loadPageLimits(); this.loadPageLimits();
let formQueryPredicates: FormGroup[] = [ const formQueryPredicates: FormGroup[] = [
new QueryPredicate().toFormGroup(this.formBuilder) new QueryPredicate().toFormGroup(this.formBuilder),
]; ];
this.queryForm = this.formBuilder.group({ this.queryForm = this.formBuilder.group({
@@ -73,36 +85,36 @@ export class FilteredItemsComponent {
queryPredicates: this.formBuilder.array(formQueryPredicates), queryPredicates: this.formBuilder.array(formQueryPredicates),
pageLimit: this.formBuilder.control('10', []), pageLimit: this.formBuilder.control('10', []),
filters: FiltersComponent.formGroup(this.formBuilder), filters: FiltersComponent.formGroup(this.formBuilder),
additionalFields: this.formBuilder.control([], []) additionalFields: this.formBuilder.control([], []),
}); });
} }
loadCollections(): void { loadCollections(): void {
this.collections = []; this.collections = [];
let wholeRepo$ = this.translateService.stream('admin.reports.items.wholeRepo'); const wholeRepo$ = this.translateService.stream('admin.reports.items.wholeRepo');
this.collections.push(OptionVO.collectionLoc('', wholeRepo$)); this.collections.push(OptionVO.collectionLoc('', wholeRepo$));
this.communityService.findAll({ elementsPerPage: 10000, currentPage: 1 }).pipe( this.communityService.findAll({ elementsPerPage: 10000, currentPage: 1 }).pipe(
getFirstSucceededRemoteListPayload() getFirstSucceededRemoteListPayload(),
).subscribe( ).subscribe(
(communitiesRest: Community[]) => { (communitiesRest: Community[]) => {
communitiesRest.forEach(community => { communitiesRest.forEach(community => {
let commVO = OptionVO.collection(community.uuid, community.name, true); const commVO = OptionVO.collection(community.uuid, community.name, true);
this.collections.push(commVO); this.collections.push(commVO);
this.collectionService.findByParent(community.uuid, { elementsPerPage: 10000, currentPage: 1 }).pipe( this.collectionService.findByParent(community.uuid, { elementsPerPage: 10000, currentPage: 1 }).pipe(
getFirstSucceededRemoteListPayload() getFirstSucceededRemoteListPayload(),
).subscribe( ).subscribe(
(collectionsRest: Collection[]) => { (collectionsRest: Collection[]) => {
collectionsRest.filter(collection => collection.firstMetadataValue('dspace.entity.type') === 'Publication') collectionsRest.filter(collection => collection.firstMetadataValue('dspace.entity.type') === 'Publication')
.forEach(collection => { .forEach(collection => {
let collVO = OptionVO.collection(collection.uuid, '' + collection.name); const collVO = OptionVO.collection(collection.uuid, '' + collection.name);
this.collections.push(collVO); this.collections.push(collVO);
}); });
} },
); );
}); });
} },
); );
} }
@@ -110,56 +122,56 @@ export class FilteredItemsComponent {
this.presetQueries = [ this.presetQueries = [
PresetQuery.of('new', 'admin.reports.items.preset.new', []), PresetQuery.of('new', 'admin.reports.items.preset.new', []),
PresetQuery.of('q1', 'admin.reports.items.preset.hasNoTitle', [ PresetQuery.of('q1', 'admin.reports.items.preset.hasNoTitle', [
QueryPredicate.of('dc.title', QueryPredicate.DOES_NOT_EXIST) QueryPredicate.of('dc.title', QueryPredicate.DOES_NOT_EXIST),
]), ]),
PresetQuery.of('q2', 'admin.reports.items.preset.hasNoIdentifierUri', [ PresetQuery.of('q2', 'admin.reports.items.preset.hasNoIdentifierUri', [
QueryPredicate.of('dc.identifier.uri', QueryPredicate.DOES_NOT_EXIST) QueryPredicate.of('dc.identifier.uri', QueryPredicate.DOES_NOT_EXIST),
]), ]),
PresetQuery.of('q3', 'admin.reports.items.preset.hasCompoundSubject', [ PresetQuery.of('q3', 'admin.reports.items.preset.hasCompoundSubject', [
QueryPredicate.of('dc.subject.*', QueryPredicate.LIKE, '%;%') QueryPredicate.of('dc.subject.*', QueryPredicate.LIKE, '%;%'),
]), ]),
PresetQuery.of('q4', 'admin.reports.items.preset.hasCompoundAuthor', [ PresetQuery.of('q4', 'admin.reports.items.preset.hasCompoundAuthor', [
QueryPredicate.of('dc.contributor.author', QueryPredicate.LIKE, '% and %') QueryPredicate.of('dc.contributor.author', QueryPredicate.LIKE, '% and %'),
]), ]),
PresetQuery.of('q5', 'admin.reports.items.preset.hasCompoundCreator', [ PresetQuery.of('q5', 'admin.reports.items.preset.hasCompoundCreator', [
QueryPredicate.of('dc.creator', QueryPredicate.LIKE, '% and %') QueryPredicate.of('dc.creator', QueryPredicate.LIKE, '% and %'),
]), ]),
PresetQuery.of('q6', 'admin.reports.items.preset.hasUrlInDescription', [ PresetQuery.of('q6', 'admin.reports.items.preset.hasUrlInDescription', [
QueryPredicate.of('dc.description', QueryPredicate.MATCHES, '^.*(http://|https://|mailto:).*$') QueryPredicate.of('dc.description', QueryPredicate.MATCHES, '^.*(http://|https://|mailto:).*$'),
]), ]),
PresetQuery.of('q7', 'admin.reports.items.preset.hasFullTextInProvenance', [ PresetQuery.of('q7', 'admin.reports.items.preset.hasFullTextInProvenance', [
QueryPredicate.of('dc.description.provenance', QueryPredicate.MATCHES, '^.*No\. of bitstreams(.|\r|\n|\r\n)*\.(PDF|pdf|DOC|doc|PPT|ppt|DOCX|docx|PPTX|pptx).*$') QueryPredicate.of('dc.description.provenance', QueryPredicate.MATCHES, '^.*No\. of bitstreams(.|\r|\n|\r\n)*\.(PDF|pdf|DOC|doc|PPT|ppt|DOCX|docx|PPTX|pptx).*$'),
]), ]),
PresetQuery.of('q8', 'admin.reports.items.preset.hasNonFullTextInProvenance', [ PresetQuery.of('q8', 'admin.reports.items.preset.hasNonFullTextInProvenance', [
QueryPredicate.of('dc.description.provenance', QueryPredicate.DOES_NOT_MATCH, '^.*No\. of bitstreams(.|\r|\n|\r\n)*\.(PDF|pdf|DOC|doc|PPT|ppt|DOCX|docx|PPTX|pptx).*$') QueryPredicate.of('dc.description.provenance', QueryPredicate.DOES_NOT_MATCH, '^.*No\. of bitstreams(.|\r|\n|\r\n)*\.(PDF|pdf|DOC|doc|PPT|ppt|DOCX|docx|PPTX|pptx).*$'),
]), ]),
PresetQuery.of('q9', 'admin.reports.items.preset.hasEmptyMetadata', [ PresetQuery.of('q9', 'admin.reports.items.preset.hasEmptyMetadata', [
QueryPredicate.of('*', QueryPredicate.MATCHES, '^\s*$') QueryPredicate.of('*', QueryPredicate.MATCHES, '^\s*$'),
]), ]),
PresetQuery.of('q10', 'admin.reports.items.preset.hasUnbreakingDataInDescription', [ PresetQuery.of('q10', 'admin.reports.items.preset.hasUnbreakingDataInDescription', [
QueryPredicate.of('dc.description.*', QueryPredicate.MATCHES, '^.*[^\s]{50,}.*$') QueryPredicate.of('dc.description.*', QueryPredicate.MATCHES, '^.*[^\s]{50,}.*$'),
]), ]),
PresetQuery.of('q12', 'admin.reports.items.preset.hasXmlEntityInMetadata', [ PresetQuery.of('q12', 'admin.reports.items.preset.hasXmlEntityInMetadata', [
QueryPredicate.of('*', QueryPredicate.MATCHES, '^.*&#.*$') QueryPredicate.of('*', QueryPredicate.MATCHES, '^.*&#.*$'),
]), ]),
PresetQuery.of('q13', 'admin.reports.items.preset.hasNonAsciiCharInMetadata', [ PresetQuery.of('q13', 'admin.reports.items.preset.hasNonAsciiCharInMetadata', [
QueryPredicate.of('*', QueryPredicate.MATCHES, '^.*[^[:ascii:]].*$') QueryPredicate.of('*', QueryPredicate.MATCHES, '^.*[^[:ascii:]].*$'),
]) ]),
]; ];
} }
loadMetadataFields(): void { loadMetadataFields(): void {
this.metadataFields = []; this.metadataFields = [];
this.metadataFieldsWithAny = []; this.metadataFieldsWithAny = [];
let anyField$ = this.translateService.stream('admin.reports.items.anyField'); const anyField$ = this.translateService.stream('admin.reports.items.anyField');
this.metadataFieldsWithAny.push(OptionVO.itemLoc('*', anyField$)); this.metadataFieldsWithAny.push(OptionVO.itemLoc('*', anyField$));
this.metadataSchemaService.findAll({ elementsPerPage: 10000, currentPage: 1 }).pipe( this.metadataSchemaService.findAll({ elementsPerPage: 10000, currentPage: 1 }).pipe(
getFirstSucceededRemoteListPayload() getFirstSucceededRemoteListPayload(),
).subscribe( ).subscribe(
(schemasRest: MetadataSchema[]) => { (schemasRest: MetadataSchema[]) => {
schemasRest.forEach(schema => { schemasRest.forEach(schema => {
this.metadataFieldService.findBySchema(schema, { elementsPerPage: 10000, currentPage: 1 }).pipe( this.metadataFieldService.findBySchema(schema, { elementsPerPage: 10000, currentPage: 1 }).pipe(
getFirstSucceededRemoteListPayload() getFirstSucceededRemoteListPayload(),
).subscribe( ).subscribe(
(fieldsRest: MetadataField[]) => { (fieldsRest: MetadataField[]) => {
fieldsRest.forEach(field => { fieldsRest.forEach(field => {
@@ -173,10 +185,10 @@ export class FilteredItemsComponent {
this.metadataFieldsWithAny.push(fieldVO); this.metadataFieldsWithAny.push(fieldVO);
} }
}); });
} },
); );
}); });
} },
); );
} }
@@ -191,7 +203,7 @@ export class FilteredItemsComponent {
OptionVO.item(QueryPredicate.CONTAINS, 'admin.reports.items.predicate.contains'), OptionVO.item(QueryPredicate.CONTAINS, 'admin.reports.items.predicate.contains'),
OptionVO.item(QueryPredicate.DOES_NOT_CONTAIN, 'admin.reports.items.predicate.doesNotContain'), OptionVO.item(QueryPredicate.DOES_NOT_CONTAIN, 'admin.reports.items.predicate.doesNotContain'),
OptionVO.item(QueryPredicate.MATCHES, 'admin.reports.items.predicate.matches'), OptionVO.item(QueryPredicate.MATCHES, 'admin.reports.items.predicate.matches'),
OptionVO.item(QueryPredicate.DOES_NOT_MATCH, 'admin.reports.items.predicate.doesNotMatch') OptionVO.item(QueryPredicate.DOES_NOT_MATCH, 'admin.reports.items.predicate.doesNotMatch'),
]; ];
} }
@@ -200,7 +212,7 @@ export class FilteredItemsComponent {
OptionVO.item('10', '10'), OptionVO.item('10', '10'),
OptionVO.item('25', '25'), OptionVO.item('25', '25'),
OptionVO.item('50', '50'), OptionVO.item('50', '50'),
OptionVO.item('100', '100') OptionVO.item('100', '100'),
]; ];
} }
@@ -223,9 +235,9 @@ export class FilteredItemsComponent {
} }
setPresetQuery() { setPresetQuery() {
let queryField = this.queryForm.controls.presetQuery as FormControl; const queryField = this.queryForm.controls.presetQuery as FormControl;
let value = queryField.value; const value = queryField.value;
let query = this.presetQueries.find(q => q.id === value); const query = this.presetQueries.find(q => q.id === value);
if (query !== undefined) { if (query !== undefined) {
this.queryPredicatesArray().clear(); this.queryPredicatesArray().clear();
query.predicates query.predicates
@@ -242,7 +254,7 @@ export class FilteredItemsComponent {
} }
private pageSize() { private pageSize() {
let form = this.queryForm.value; const form = this.queryForm.value;
return form.pageLimit; return form.pageLimit;
} }
@@ -258,7 +270,7 @@ export class FilteredItemsComponent {
} }
pageCount(): number { pageCount(): number {
let total = this.results.itemCount || 0; const total = this.results.itemCount || 0;
return Math.ceil(total / this.pageSize()); return Math.ceil(total / this.pageSize());
} }
@@ -284,10 +296,10 @@ export class FilteredItemsComponent {
.getFilteredItems() .getFilteredItems()
.pipe( .pipe(
map(response => { map(response => {
let offset = this.currentPage * this.pageSize(); const offset = this.currentPage * this.pageSize();
this.results.deserialize(response.payload, offset); this.results.deserialize(response.payload, offset);
return this.results.items; return this.results.items;
}) }),
); );
} }
@@ -296,20 +308,20 @@ export class FilteredItemsComponent {
if (params.length > 0) { if (params.length > 0) {
params = `?${params}`; params = `?${params}`;
} }
let scheme = environment.rest.ssl ? 'https' : 'http'; const scheme = environment.rest.ssl ? 'https' : 'http';
let urlRestApp = `${scheme}://${environment.rest.host}:${environment.rest.port}${environment.rest.nameSpace}`; const urlRestApp = `${scheme}://${environment.rest.host}:${environment.rest.port}${environment.rest.nameSpace}`;
return this.restService.request(RestRequestMethod.GET, `${urlRestApp}/api/contentreport/filtereditems${params}`); return this.restService.request(RestRequestMethod.GET, `${urlRestApp}/api/contentreport/filtereditems${params}`);
} }
private toQueryString(): string { private toQueryString(): string {
let params = `pageNumber=${this.currentPage}&pageLimit=${this.pageSize()}`; let params = `pageNumber=${this.currentPage}&pageLimit=${this.pageSize()}`;
let colls = this.queryForm.value.collections; const colls = this.queryForm.value.collections;
for (let i = 0; i < colls.length; i++) { for (let i = 0; i < colls.length; i++) {
params += `&collections=${colls[i]}`; params += `&collections=${colls[i]}`;
} }
let preds = this.queryForm.value.queryPredicates; const preds = this.queryForm.value.queryPredicates;
for (let i = 0; i < preds.length; i++) { for (let i = 0; i < preds.length; i++) {
const field = preds[i].field; const field = preds[i].field;
const op = preds[i].operator; const op = preds[i].operator;
@@ -320,12 +332,12 @@ export class FilteredItemsComponent {
} }
} }
let filters = FiltersComponent.toQueryString(this.queryForm.value.filters); const filters = FiltersComponent.toQueryString(this.queryForm.value.filters);
if (filters.length > 0) { if (filters.length > 0) {
params += `&${filters}`; params += `&${filters}`;
} }
let addFlds = this.queryForm.value.additionalFields; const addFlds = this.queryForm.value.additionalFields;
for (let i = 0; i < addFlds.length; i++) { for (let i = 0; i < addFlds.length; i++) {
params += `&additionalFields=${addFlds[i]}`; params += `&additionalFields=${addFlds[i]}`;
} }

View File

@@ -11,7 +11,7 @@ export class OptionVO {
disabled = false; disabled = false;
static collection(id: string, name: string, disabled: boolean = false): OptionVO { static collection(id: string, name: string, disabled: boolean = false): OptionVO {
let opt = new OptionVO(); const opt = new OptionVO();
opt.id = id; opt.id = id;
opt.name$ = OptionVO.toObservable(name); opt.name$ = OptionVO.toObservable(name);
opt.disabled = disabled; opt.disabled = disabled;
@@ -19,7 +19,7 @@ export class OptionVO {
} }
static collectionLoc(id: string, name$: Observable<string>, disabled: boolean = false): OptionVO { static collectionLoc(id: string, name$: Observable<string>, disabled: boolean = false): OptionVO {
let opt = new OptionVO(); const opt = new OptionVO();
opt.id = id; opt.id = id;
opt.name$ = name$; opt.name$ = name$;
opt.disabled = disabled; opt.disabled = disabled;
@@ -27,14 +27,14 @@ export class OptionVO {
} }
static item(id: string, name: string): OptionVO { static item(id: string, name: string): OptionVO {
let opt = new OptionVO(); const opt = new OptionVO();
opt.id = id; opt.id = id;
opt.name$ = OptionVO.toObservable(name); opt.name$ = OptionVO.toObservable(name);
return opt; return opt;
} }
static itemLoc(id: string, name$: Observable<string>): OptionVO { static itemLoc(id: string, name$: Observable<string>): OptionVO {
let opt = new OptionVO(); const opt = new OptionVO();
opt.id = id; opt.id = id;
opt.name$ = name$; opt.name$ = name$;
return opt; return opt;

View File

@@ -7,7 +7,7 @@ export class PresetQuery {
predicates: QueryPredicate[]; predicates: QueryPredicate[];
static of(id: string, label: string, predicates: QueryPredicate[]) { static of(id: string, label: string, predicates: QueryPredicate[]) {
let query = new PresetQuery(); const query = new PresetQuery();
query.id = id; query.id = id;
query.label = label; query.label = label;
query.predicates = predicates; query.predicates = predicates;

View File

@@ -1,4 +1,8 @@
import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; import {
FormBuilder,
FormControl,
FormGroup,
} from '@angular/forms';
export class QueryPredicate { export class QueryPredicate {
@@ -18,7 +22,7 @@ export class QueryPredicate {
value: string; value: string;
static of(field: string, operator: string, value: string = '') { static of(field: string, operator: string, value: string = '') {
let pred = new QueryPredicate(); const pred = new QueryPredicate();
pred.field = field; pred.field = field;
pred.operator = operator; pred.operator = operator;
pred.value = value; pred.value = value;
@@ -29,7 +33,7 @@ export class QueryPredicate {
return formBuilder.group({ return formBuilder.group({
field: new FormControl(this.field), field: new FormControl(this.field),
operator: new FormControl(this.operator), operator: new FormControl(this.operator),
value: new FormControl(this.value) value: new FormControl(this.value),
}); });
} }

View File

@@ -1,9 +1,17 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { FiltersComponent } from './filters-section.component'; import {
import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; ComponentFixture,
import { TranslateLoaderMock } from 'src/app/shared/mocks/translate-loader.mock'; TestBed,
waitForAsync,
} from '@angular/core/testing';
import { FormBuilder } from '@angular/forms'; import { FormBuilder } from '@angular/forms';
import {
TranslateLoader,
TranslateModule,
} from '@ngx-translate/core';
import { TranslateLoaderMock } from 'src/app/shared/mocks/translate-loader.mock';
import { FiltersComponent } from './filters-section.component';
describe('FiltersComponent', () => { describe('FiltersComponent', () => {
let component: FiltersComponent; let component: FiltersComponent;
@@ -17,14 +25,14 @@ describe('FiltersComponent', () => {
TranslateModule.forRoot({ TranslateModule.forRoot({
loader: { loader: {
provide: TranslateLoader, provide: TranslateLoader,
useClass: TranslateLoaderMock useClass: TranslateLoaderMock,
} },
}) }),
], ],
providers: [ providers: [
FormBuilder FormBuilder,
], ],
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA],
}); });
})); }));

View File

@@ -1,7 +1,15 @@
import { Component, Input } from '@angular/core'; import {
import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; Component,
import { FilterGroup } from './filter-group.model'; Input,
} from '@angular/core';
import {
FormBuilder,
FormControl,
FormGroup,
} from '@angular/forms';
import { Filter } from './filter.model'; import { Filter } from './filter.model';
import { FilterGroup } from './filter-group.model';
/** /**
* Component representing the Query Filters section used in both * Component representing the Query Filters section used in both
@@ -10,7 +18,7 @@ import { Filter } from './filter.model';
@Component({ @Component({
selector: 'ds-filters', selector: 'ds-filters',
templateUrl: './filters-section.component.html', templateUrl: './filters-section.component.html',
styleUrls: ['./filters-section.component.scss'] styleUrls: ['./filters-section.component.scss'],
}) })
export class FiltersComponent { export class FiltersComponent {
@@ -20,12 +28,12 @@ export class FiltersComponent {
new Filter('is_withdrawn'), new Filter('is_withdrawn'),
new Filter('is_not_withdrawn'), new Filter('is_not_withdrawn'),
new Filter('is_discoverable'), new Filter('is_discoverable'),
new Filter('is_not_discoverable') new Filter('is_not_discoverable'),
]), ]),
new FilterGroup('bitstream', [ new FilterGroup('bitstream', [
new Filter('has_multiple_originals'), new Filter('has_multiple_originals'),
new Filter('has_no_originals'), new Filter('has_no_originals'),
new Filter('has_one_original') new Filter('has_one_original'),
]), ]),
new FilterGroup('bitstream_mime', [ new FilterGroup('bitstream_mime', [
new Filter('has_doc_original'), new Filter('has_doc_original'),
@@ -36,13 +44,13 @@ export class FiltersComponent {
new Filter('has_jpg_original'), new Filter('has_jpg_original'),
new Filter('has_small_pdf'), new Filter('has_small_pdf'),
new Filter('has_large_pdf'), new Filter('has_large_pdf'),
new Filter('has_doc_without_text') new Filter('has_doc_without_text'),
]), ]),
new FilterGroup('mime', [ new FilterGroup('mime', [
new Filter('has_only_supp_image_type'), new Filter('has_only_supp_image_type'),
new Filter('has_unsupp_image_type'), new Filter('has_unsupp_image_type'),
new Filter('has_only_supp_doc_type'), new Filter('has_only_supp_doc_type'),
new Filter('has_unsupp_doc_type') new Filter('has_unsupp_doc_type'),
]), ]),
new FilterGroup('bundle', [ new FilterGroup('bundle', [
new Filter('has_unsupported_bundle'), new Filter('has_unsupported_bundle'),
@@ -51,24 +59,24 @@ export class FiltersComponent {
new Filter('has_invalid_thumbnail_name'), new Filter('has_invalid_thumbnail_name'),
new Filter('has_non_generated_thumb'), new Filter('has_non_generated_thumb'),
new Filter('no_license'), new Filter('no_license'),
new Filter('has_license_documentation') new Filter('has_license_documentation'),
]), ]),
new FilterGroup('permission', [ new FilterGroup('permission', [
new Filter('has_restricted_original', true), new Filter('has_restricted_original', true),
new Filter('has_restricted_thumbnail', true), new Filter('has_restricted_thumbnail', true),
new Filter('has_restricted_metadata', true) new Filter('has_restricted_metadata', true),
]) ]),
]; ];
@Input() filtersForm: FormGroup; @Input() filtersForm: FormGroup;
static formGroup(formBuilder: FormBuilder): FormGroup { static formGroup(formBuilder: FormBuilder): FormGroup {
let fields = {}; const fields = {};
let allFilters = FiltersComponent.FILTERS; const allFilters = FiltersComponent.FILTERS;
for (let i = 0; i < allFilters.length; i++) { for (let i = 0; i < allFilters.length; i++) {
let group = allFilters[i]; const group = allFilters[i];
for (let j = 0; j < group.filters.length; j++) { for (let j = 0; j < group.filters.length; j++) {
let filter = group.filters[j]; const filter = group.filters[j];
fields[filter.id] = new FormControl(false); fields[filter.id] = new FormControl(false);
} }
} }
@@ -76,11 +84,11 @@ export class FiltersComponent {
} }
static getFilter(filterId: string): Filter { static getFilter(filterId: string): Filter {
let allFilters = FiltersComponent.FILTERS; const allFilters = FiltersComponent.FILTERS;
for (let i = 0; i < allFilters.length; i++) { for (let i = 0; i < allFilters.length; i++) {
let group = allFilters[i]; const group = allFilters[i];
for (let j = 0; j < group.filters.length; j++) { for (let j = 0; j < group.filters.length; j++) {
let filter = group.filters[j]; const filter = group.filters[j];
if (filter.id === filterId) { if (filter.id === filterId) {
return filter; return filter;
} }
@@ -90,11 +98,11 @@ export class FiltersComponent {
} }
static getGroup(filterId: string): FilterGroup { static getGroup(filterId: string): FilterGroup {
let allFilters = FiltersComponent.FILTERS; const allFilters = FiltersComponent.FILTERS;
for (let i = 0; i < allFilters.length; i++) { for (let i = 0; i < allFilters.length; i++) {
let group = allFilters[i]; const group = allFilters[i];
for (let j = 0; j < group.filters.length; j++) { for (let j = 0; j < group.filters.length; j++) {
let filter = group.filters[j]; const filter = group.filters[j];
if (filter.id === filterId) { if (filter.id === filterId) {
return group; return group;
} }
@@ -126,12 +134,12 @@ export class FiltersComponent {
private setAllFilters(value: boolean) { private setAllFilters(value: boolean) {
// I don't know why, but patchValue() with individual controls doesn't work. // I don't know why, but patchValue() with individual controls doesn't work.
// I therefore use setValue() with the whole set, which mercifully works... // I therefore use setValue() with the whole set, which mercifully works...
let fields = {}; const fields = {};
let allFilters = FiltersComponent.FILTERS; const allFilters = FiltersComponent.FILTERS;
for (let i = 0; i < allFilters.length; i++) { for (let i = 0; i < allFilters.length; i++) {
let group = allFilters[i]; const group = allFilters[i];
for (let j = 0; j < group.filters.length; j++) { for (let j = 0; j < group.filters.length; j++) {
let filter = group.filters[j]; const filter = group.filters[j];
fields[filter.id] = value; fields[filter.id] = value;
} }
} }

View File

@@ -1,5 +1,5 @@
import { URLCombiner } from '../core/url-combiner/url-combiner';
import { getAdminModuleRoute } from '../app-routing-paths'; import { getAdminModuleRoute } from '../app-routing-paths';
import { URLCombiner } from '../core/url-combiner/url-combiner';
import { getQualityAssuranceEditRoute } from './admin-notifications/admin-notifications-routing-paths'; import { getQualityAssuranceEditRoute } from './admin-notifications/admin-notifications-routing-paths';
export const REGISTRIES_MODULE_PATH = 'registries'; export const REGISTRIES_MODULE_PATH = 'registries';

View File

@@ -3,13 +3,19 @@ import { RouterModule } from '@angular/router';
import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver'; import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver';
import { I18nBreadcrumbsService } from '../core/breadcrumbs/i18n-breadcrumbs.service'; import { I18nBreadcrumbsService } from '../core/breadcrumbs/i18n-breadcrumbs.service';
import { SiteAdministratorGuard } from '../core/data/feature-authorization/feature-authorization-guard/site-administrator.guard';
import { AdminCurationTasksComponent } from './admin-curation-tasks/admin-curation-tasks.component'; import { AdminCurationTasksComponent } from './admin-curation-tasks/admin-curation-tasks.component';
import { BatchImportPageComponent } from './admin-import-batch-page/batch-import-page.component'; import { BatchImportPageComponent } from './admin-import-batch-page/batch-import-page.component';
import { MetadataImportPageComponent } from './admin-import-metadata-page/metadata-import-page.component'; import { MetadataImportPageComponent } from './admin-import-metadata-page/metadata-import-page.component';
import { LDN_PATH, NOTIFICATIONS_MODULE_PATH, NOTIFY_DASHBOARD_MODULE_PATH, REGISTRIES_MODULE_PATH, REPORTS_MODULE_PATH } from './admin-routing-paths'; import {
LDN_PATH,
NOTIFICATIONS_MODULE_PATH,
NOTIFY_DASHBOARD_MODULE_PATH,
REGISTRIES_MODULE_PATH,
REPORTS_MODULE_PATH,
} from './admin-routing-paths';
import { AdminSearchPageComponent } from './admin-search-page/admin-search-page.component'; import { AdminSearchPageComponent } from './admin-search-page/admin-search-page.component';
import { AdminWorkflowPageComponent } from './admin-workflow-page/admin-workflow-page.component'; import { AdminWorkflowPageComponent } from './admin-workflow-page/admin-workflow-page.component';
import { SiteAdministratorGuard } from '../core/data/feature-authorization/feature-authorization-guard/site-administrator.guard';
@NgModule({ @NgModule({
imports: [ imports: [
@@ -23,49 +29,49 @@ import { SiteAdministratorGuard } from '../core/data/feature-authorization/featu
path: REGISTRIES_MODULE_PATH, path: REGISTRIES_MODULE_PATH,
loadChildren: () => import('./admin-registries/admin-registries.module') loadChildren: () => import('./admin-registries/admin-registries.module')
.then((m) => m.AdminRegistriesModule), .then((m) => m.AdminRegistriesModule),
canActivate: [SiteAdministratorGuard] canActivate: [SiteAdministratorGuard],
}, },
{ {
path: 'search', path: 'search',
resolve: { breadcrumb: I18nBreadcrumbResolver }, resolve: { breadcrumb: I18nBreadcrumbResolver },
component: AdminSearchPageComponent, component: AdminSearchPageComponent,
data: { title: 'admin.search.title', breadcrumbKey: 'admin.search' }, data: { title: 'admin.search.title', breadcrumbKey: 'admin.search' },
canActivate: [SiteAdministratorGuard] canActivate: [SiteAdministratorGuard],
}, },
{ {
path: 'workflow', path: 'workflow',
resolve: { breadcrumb: I18nBreadcrumbResolver }, resolve: { breadcrumb: I18nBreadcrumbResolver },
component: AdminWorkflowPageComponent, component: AdminWorkflowPageComponent,
data: { title: 'admin.workflow.title', breadcrumbKey: 'admin.workflow' }, data: { title: 'admin.workflow.title', breadcrumbKey: 'admin.workflow' },
canActivate: [SiteAdministratorGuard] canActivate: [SiteAdministratorGuard],
}, },
{ {
path: 'curation-tasks', path: 'curation-tasks',
resolve: { breadcrumb: I18nBreadcrumbResolver }, resolve: { breadcrumb: I18nBreadcrumbResolver },
component: AdminCurationTasksComponent, component: AdminCurationTasksComponent,
data: { title: 'admin.curation-tasks.title', breadcrumbKey: 'admin.curation-tasks' }, data: { title: 'admin.curation-tasks.title', breadcrumbKey: 'admin.curation-tasks' },
canActivate: [SiteAdministratorGuard] canActivate: [SiteAdministratorGuard],
}, },
{ {
path: 'metadata-import', path: 'metadata-import',
resolve: { breadcrumb: I18nBreadcrumbResolver }, resolve: { breadcrumb: I18nBreadcrumbResolver },
component: MetadataImportPageComponent, component: MetadataImportPageComponent,
data: { title: 'admin.metadata-import.title', breadcrumbKey: 'admin.metadata-import' }, data: { title: 'admin.metadata-import.title', breadcrumbKey: 'admin.metadata-import' },
canActivate: [SiteAdministratorGuard] canActivate: [SiteAdministratorGuard],
}, },
{ {
path: 'batch-import', path: 'batch-import',
resolve: { breadcrumb: I18nBreadcrumbResolver }, resolve: { breadcrumb: I18nBreadcrumbResolver },
component: BatchImportPageComponent, component: BatchImportPageComponent,
data: { title: 'admin.batch-import.title', breadcrumbKey: 'admin.batch-import' }, data: { title: 'admin.batch-import.title', breadcrumbKey: 'admin.batch-import' },
canActivate: [SiteAdministratorGuard] canActivate: [SiteAdministratorGuard],
}, },
{ {
path: 'system-wide-alert', path: 'system-wide-alert',
resolve: { breadcrumb: I18nBreadcrumbResolver }, resolve: { breadcrumb: I18nBreadcrumbResolver },
loadChildren: () => import('../system-wide-alert/system-wide-alert.module').then((m) => m.SystemWideAlertModule), loadChildren: () => import('../system-wide-alert/system-wide-alert.module').then((m) => m.SystemWideAlertModule),
data: {title: 'admin.system-wide-alert.title', breadcrumbKey: 'admin.system-wide-alert'}, data: { title: 'admin.system-wide-alert.title', breadcrumbKey: 'admin.system-wide-alert' },
canActivate: [SiteAdministratorGuard] canActivate: [SiteAdministratorGuard],
}, },
{ {
path: LDN_PATH, path: LDN_PATH,
@@ -75,7 +81,7 @@ import { SiteAdministratorGuard } from '../core/data/feature-authorization/featu
path: 'services', path: 'services',
loadChildren: () => import('./admin-ldn-services/admin-ldn-services.module') loadChildren: () => import('./admin-ldn-services/admin-ldn-services.module')
.then((m) => m.AdminLdnServicesModule), .then((m) => m.AdminLdnServicesModule),
} },
], ],
}, },
{ {

View File

@@ -1,4 +1,11 @@
import { Component, ComponentRef, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core'; import {
Component,
ComponentRef,
ElementRef,
OnDestroy,
OnInit,
ViewChild,
} from '@angular/core';
import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service'; import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service';
import { BitstreamDataService } from '../../../../../core/data/bitstream-data.service'; import { BitstreamDataService } from '../../../../../core/data/bitstream-data.service';
@@ -6,13 +13,16 @@ import { Context } from '../../../../../core/shared/context.model';
import { GenericConstructor } from '../../../../../core/shared/generic-constructor'; import { GenericConstructor } from '../../../../../core/shared/generic-constructor';
import { Item } from '../../../../../core/shared/item.model'; import { Item } from '../../../../../core/shared/item.model';
import { ViewMode } from '../../../../../core/shared/view-mode.model'; import { ViewMode } from '../../../../../core/shared/view-mode.model';
import { DynamicComponentLoaderDirective } from '../../../../../shared/abstract-component-loader/dynamic-component-loader.directive';
import { hasValue } from '../../../../../shared/empty.util';
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model'; import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
import { getListableObjectComponent, listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; import {
getListableObjectComponent,
listableObjectComponent,
} from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { SearchResultGridElementComponent } from '../../../../../shared/object-grid/search-result-grid-element/search-result-grid-element.component'; import { SearchResultGridElementComponent } from '../../../../../shared/object-grid/search-result-grid-element/search-result-grid-element.component';
import { ThemeService } from '../../../../../shared/theme-support/theme.service'; import { ThemeService } from '../../../../../shared/theme-support/theme.service';
import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service'; import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service';
import { DynamicComponentLoaderDirective } from '../../../../../shared/abstract-component-loader/dynamic-component-loader.directive';
import { hasValue } from '../../../../../shared/empty.util';
@listableObjectComponent(ItemSearchResult, ViewMode.GridElement, Context.AdminSearch) @listableObjectComponent(ItemSearchResult, ViewMode.GridElement, Context.AdminSearch)
@Component({ @Component({

View File

@@ -1,5 +1,9 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import {
ComponentFixture,
TestBed,
waitForAsync,
} from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';

View File

@@ -1,4 +1,9 @@
import { Component, Inject, Injector, OnInit } from '@angular/core'; import {
Component,
Inject,
Injector,
OnInit,
} from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { isEmpty } from '../../../shared/empty.util'; import { isEmpty } from '../../../shared/empty.util';

View File

@@ -1,5 +1,15 @@
import { ChangeDetectionStrategy, Injector, NO_ERRORS_SCHEMA } from '@angular/core'; import {
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; ChangeDetectionStrategy,
Injector,
NO_ERRORS_SCHEMA,
} from '@angular/core';
import {
ComponentFixture,
fakeAsync,
TestBed,
tick,
waitForAsync,
} from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';

View File

@@ -1,6 +1,24 @@
import { Component, HostListener, Injector, Input, OnInit } from '@angular/core'; import {
import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; Component,
import { debounceTime, distinctUntilChanged, first, map, withLatestFrom } from 'rxjs/operators'; HostListener,
Injector,
Input,
OnInit,
} from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import {
BehaviorSubject,
combineLatest,
Observable,
} from 'rxjs';
import {
debounceTime,
distinctUntilChanged,
first,
map,
withLatestFrom,
} from 'rxjs/operators';
import { AuthService } from '../../core/auth/auth.service'; import { AuthService } from '../../core/auth/auth.service';
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
import { slideSidebar } from '../../shared/animations/slide'; import { slideSidebar } from '../../shared/animations/slide';
@@ -9,7 +27,6 @@ import { MenuService } from '../../shared/menu/menu.service';
import { MenuID } from '../../shared/menu/menu-id.model'; import { MenuID } from '../../shared/menu/menu-id.model';
import { CSSVariableService } from '../../shared/sass-helper/css-variable.service'; import { CSSVariableService } from '../../shared/sass-helper/css-variable.service';
import { ThemeService } from '../../shared/theme-support/theme.service'; import { ThemeService } from '../../shared/theme-support/theme.service';
import { ActivatedRoute } from '@angular/router';
/** /**
* Component representing the admin sidebar * Component representing the admin sidebar

View File

@@ -1,5 +1,9 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import {
ComponentFixture,
TestBed,
waitForAsync,
} from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { Router } from '@angular/router'; import { Router } from '@angular/router';

View File

@@ -1,6 +1,14 @@
import { Component, Inject, Injector, OnInit } from '@angular/core'; import {
Component,
Inject,
Injector,
OnInit,
} from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { combineLatest as combineLatestObservable, Observable } from 'rxjs'; import {
combineLatest as combineLatestObservable,
Observable,
} from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { bgColor } from '../../../shared/animations/bgColor'; import { bgColor } from '../../../shared/animations/bgColor';
@@ -69,7 +77,7 @@ export class ExpandableAdminSidebarSectionComponent extends AdminSidebarSectionC
this.isSidebarCollapsed$ = this.menuService.isMenuCollapsed(this.menuID); this.isSidebarCollapsed$ = this.menuService.isMenuCollapsed(this.menuID);
this.isSidebarPreviewCollapsed$ = this.menuService.isMenuPreviewCollapsed(this.menuID); this.isSidebarPreviewCollapsed$ = this.menuService.isMenuPreviewCollapsed(this.menuID);
this.isExpanded$ = combineLatestObservable([this.active, this.isSidebarCollapsed$, this.isSidebarPreviewCollapsed$]).pipe( this.isExpanded$ = combineLatestObservable([this.active, this.isSidebarCollapsed$, this.isSidebarPreviewCollapsed$]).pipe(
map(([active, sidebarCollapsed, sidebarPreviewCollapsed]) => (active && (!sidebarCollapsed || !sidebarPreviewCollapsed))) map(([active, sidebarCollapsed, sidebarPreviewCollapsed]) => (active && (!sidebarCollapsed || !sidebarPreviewCollapsed))),
); );
} }

View File

@@ -1,8 +1,11 @@
import { Component, Input } from '@angular/core'; import {
Component,
Input,
} from '@angular/core';
import { Observable } from 'rxjs';
import { ThemedComponent } from '../../shared/theme-support/themed.component'; import { ThemedComponent } from '../../shared/theme-support/themed.component';
import { AdminSidebarComponent } from './admin-sidebar.component'; import { AdminSidebarComponent } from './admin-sidebar.component';
import { Observable } from 'rxjs';
/** /**
* Themed wrapper for AdminSidebarComponent * Themed wrapper for AdminSidebarComponent

View File

@@ -1,8 +1,24 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import {
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; Component,
EventEmitter,
Input,
OnInit,
Output,
} from '@angular/core';
import {
NgbModal,
NgbModalRef,
} from '@ng-bootstrap/ng-bootstrap';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { map, Observable } from 'rxjs'; import {
import { switchMap, take, tap } from 'rxjs/operators'; map,
Observable,
} from 'rxjs';
import {
switchMap,
take,
tap,
} from 'rxjs/operators';
import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service'; import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service';
import { DSpaceObject } from '../../../../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../../../../core/shared/dspace-object.model';

View File

@@ -1,5 +1,9 @@
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import {
ComponentFixture,
TestBed,
waitForAsync,
} from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
@@ -10,16 +14,16 @@ import { BitstreamDataService } from '../../../../../core/data/bitstream-data.se
import { Item } from '../../../../../core/shared/item.model'; import { Item } from '../../../../../core/shared/item.model';
import { ViewMode } from '../../../../../core/shared/view-mode.model'; import { ViewMode } from '../../../../../core/shared/view-mode.model';
import { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model'; import { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model';
import { followLink } from '../../../../../shared/utils/follow-link-config.model';
import { ItemGridElementComponent } from '../../../../../shared/object-grid/item-grid-element/item-types/item/item-grid-element.component';
import { DynamicComponentLoaderDirective } from '../../../../../shared/abstract-component-loader/dynamic-component-loader.directive'; import { DynamicComponentLoaderDirective } from '../../../../../shared/abstract-component-loader/dynamic-component-loader.directive';
import { WorkflowItemSearchResult } from '../../../../../shared/object-collection/shared/workflow-item-search-result.model';
import { createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils';
import { getMockLinkService } from '../../../../../shared/mocks/link-service.mock'; import { getMockLinkService } from '../../../../../shared/mocks/link-service.mock';
import { getMockThemeService } from '../../../../../shared/mocks/theme-service.mock'; import { getMockThemeService } from '../../../../../shared/mocks/theme-service.mock';
import { CollectionElementLinkType } from '../../../../../shared/object-collection/collection-element-link.type'; import { CollectionElementLinkType } from '../../../../../shared/object-collection/collection-element-link.type';
import { WorkflowItemSearchResult } from '../../../../../shared/object-collection/shared/workflow-item-search-result.model';
import { ItemGridElementComponent } from '../../../../../shared/object-grid/item-grid-element/item-types/item/item-grid-element.component';
import { createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils';
import { ThemeService } from '../../../../../shared/theme-support/theme.service'; import { ThemeService } from '../../../../../shared/theme-support/theme.service';
import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service'; import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service';
import { followLink } from '../../../../../shared/utils/follow-link-config.model';
import { WorkflowItemSearchResultAdminWorkflowGridElementComponent } from './workflow-item-search-result-admin-workflow-grid-element.component'; import { WorkflowItemSearchResultAdminWorkflowGridElementComponent } from './workflow-item-search-result-admin-workflow-grid-element.component';
describe('WorkflowItemSearchResultAdminWorkflowGridElementComponent', () => { describe('WorkflowItemSearchResultAdminWorkflowGridElementComponent', () => {

View File

@@ -1,24 +1,37 @@
import { Component, ComponentRef, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core'; import {
import { Item } from '../../../../../core/shared/item.model'; Component,
import { ViewMode } from '../../../../../core/shared/view-mode.model'; ComponentRef,
import { getListableObjectComponent, listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; ElementRef,
import { Context } from '../../../../../core/shared/context.model'; OnDestroy,
import { SearchResultGridElementComponent } from '../../../../../shared/object-grid/search-result-grid-element/search-result-grid-element.component'; OnInit,
import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service'; ViewChild,
import { BitstreamDataService } from '../../../../../core/data/bitstream-data.service'; } from '@angular/core';
import { GenericConstructor } from '../../../../../core/shared/generic-constructor';
import { DynamicComponentLoaderDirective } from '../../../../../shared/abstract-component-loader/dynamic-component-loader.directive';
import { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { take } from 'rxjs/operators'; import { take } from 'rxjs/operators';
import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service'; import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service';
import { LinkService } from '../../../../../core/cache/builders/link.service'; import { LinkService } from '../../../../../core/cache/builders/link.service';
import { BitstreamDataService } from '../../../../../core/data/bitstream-data.service';
import { RemoteData } from '../../../../../core/data/remote-data'; import { RemoteData } from '../../../../../core/data/remote-data';
import { getAllSucceededRemoteData, getRemoteDataPayload } from '../../../../../core/shared/operators'; import { Context } from '../../../../../core/shared/context.model';
import { WorkflowItemSearchResult } from '../../../../../shared/object-collection/shared/workflow-item-search-result.model'; import { GenericConstructor } from '../../../../../core/shared/generic-constructor';
import { ThemeService } from '../../../../../shared/theme-support/theme.service'; import { Item } from '../../../../../core/shared/item.model';
import {
getAllSucceededRemoteData,
getRemoteDataPayload,
} from '../../../../../core/shared/operators';
import { ViewMode } from '../../../../../core/shared/view-mode.model';
import { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model';
import { DynamicComponentLoaderDirective } from '../../../../../shared/abstract-component-loader/dynamic-component-loader.directive';
import { hasValue } from '../../../../../shared/empty.util'; import { hasValue } from '../../../../../shared/empty.util';
import {
getListableObjectComponent,
listableObjectComponent,
} from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { WorkflowItemSearchResult } from '../../../../../shared/object-collection/shared/workflow-item-search-result.model';
import { SearchResultGridElementComponent } from '../../../../../shared/object-grid/search-result-grid-element/search-result-grid-element.component';
import { ThemeService } from '../../../../../shared/theme-support/theme.service';
import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service';
import { followLink } from '../../../../../shared/utils/follow-link-config.model'; import { followLink } from '../../../../../shared/utils/follow-link-config.model';
@listableObjectComponent(WorkflowItemSearchResult, ViewMode.GridElement, Context.AdminWorkflowSearch) @listableObjectComponent(WorkflowItemSearchResult, ViewMode.GridElement, Context.AdminWorkflowSearch)

View File

@@ -1,5 +1,9 @@
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import {
ComponentFixture,
TestBed,
waitForAsync,
} from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
@@ -11,18 +15,21 @@ import { DSpaceObject } from '../../../../../core/shared/dspace-object.model';
import { Item } from '../../../../../core/shared/item.model'; import { Item } from '../../../../../core/shared/item.model';
import { ViewMode } from '../../../../../core/shared/view-mode.model'; import { ViewMode } from '../../../../../core/shared/view-mode.model';
import { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model'; import { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model';
import { followLink } from '../../../../../shared/utils/follow-link-config.model';
import { ItemGridElementComponent } from '../../../../../shared/object-grid/item-grid-element/item-types/item/item-grid-element.component';
import { DynamicComponentLoaderDirective } from '../../../../../shared/abstract-component-loader/dynamic-component-loader.directive';
import { WorkflowItemSearchResult } from '../../../../../shared/object-collection/shared/workflow-item-search-result.model';
import { createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils';
import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service';
import { DynamicComponentLoaderDirective } from '../../../../../shared/abstract-component-loader/dynamic-component-loader.directive';
import { getMockLinkService } from '../../../../../shared/mocks/link-service.mock'; import { getMockLinkService } from '../../../../../shared/mocks/link-service.mock';
import { getMockThemeService } from '../../../../../shared/mocks/theme-service.mock'; import { getMockThemeService } from '../../../../../shared/mocks/theme-service.mock';
import { CollectionElementLinkType } from '../../../../../shared/object-collection/collection-element-link.type'; import { CollectionElementLinkType } from '../../../../../shared/object-collection/collection-element-link.type';
import { supervisionOrderPaginatedListRD, supervisionOrderPaginatedListRD$ } from '../../../../../shared/testing/supervision-order.mock'; import { WorkflowItemSearchResult } from '../../../../../shared/object-collection/shared/workflow-item-search-result.model';
import { ItemGridElementComponent } from '../../../../../shared/object-grid/item-grid-element/item-types/item/item-grid-element.component';
import { createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils';
import {
supervisionOrderPaginatedListRD,
supervisionOrderPaginatedListRD$,
} from '../../../../../shared/testing/supervision-order.mock';
import { ThemeService } from '../../../../../shared/theme-support/theme.service'; import { ThemeService } from '../../../../../shared/theme-support/theme.service';
import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service'; import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service';
import { followLink } from '../../../../../shared/utils/follow-link-config.model';
import { WorkspaceItemSearchResultAdminWorkflowGridElementComponent } from './workspace-item-search-result-admin-workflow-grid-element.component'; import { WorkspaceItemSearchResultAdminWorkflowGridElementComponent } from './workspace-item-search-result-admin-workflow-grid-element.component';
describe('WorkspaceItemSearchResultAdminWorkflowGridElementComponent', () => { describe('WorkspaceItemSearchResultAdminWorkflowGridElementComponent', () => {

View File

@@ -1,30 +1,50 @@
import { Component, ComponentRef, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core'; import {
Component,
import { BehaviorSubject, Observable } from 'rxjs'; ComponentRef,
import { map, mergeMap, take, tap } from 'rxjs/operators'; ElementRef,
OnDestroy,
import { Item } from '../../../../../core/shared/item.model'; OnInit,
import { ViewMode } from '../../../../../core/shared/view-mode.model'; ViewChild,
import { SearchResultGridElementComponent } from '../../../../../shared/object-grid/search-result-grid-element/search-result-grid-element.component'; } from '@angular/core';
import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service'; import {
import { BitstreamDataService } from '../../../../../core/data/bitstream-data.service'; BehaviorSubject,
import { GenericConstructor } from '../../../../../core/shared/generic-constructor'; Observable,
import { DynamicComponentLoaderDirective } from '../../../../../shared/abstract-component-loader/dynamic-component-loader.directive'; } from 'rxjs';
import { WorkspaceItem } from '../../../../../core/submission/models/workspaceitem.model'; import {
map,
mergeMap,
take,
tap,
} from 'rxjs/operators';
import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service'; import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service';
import { LinkService } from '../../../../../core/cache/builders/link.service'; import { LinkService } from '../../../../../core/cache/builders/link.service';
import { BitstreamDataService } from '../../../../../core/data/bitstream-data.service';
import { PaginatedList } from '../../../../../core/data/paginated-list.model'; import { PaginatedList } from '../../../../../core/data/paginated-list.model';
import { RemoteData } from '../../../../../core/data/remote-data'; import { RemoteData } from '../../../../../core/data/remote-data';
import { Context } from '../../../../../core/shared/context.model'; import { Context } from '../../../../../core/shared/context.model';
import { DSpaceObject } from '../../../../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../../../../core/shared/dspace-object.model';
import { getAllSucceededRemoteData, getFirstCompletedRemoteData, getRemoteDataPayload } from '../../../../../core/shared/operators'; import { GenericConstructor } from '../../../../../core/shared/generic-constructor';
import { Item } from '../../../../../core/shared/item.model';
import {
getAllSucceededRemoteData,
getFirstCompletedRemoteData,
getRemoteDataPayload,
} from '../../../../../core/shared/operators';
import { ViewMode } from '../../../../../core/shared/view-mode.model';
import { WorkspaceItem } from '../../../../../core/submission/models/workspaceitem.model';
import { SupervisionOrder } from '../../../../../core/supervision-order/models/supervision-order.model'; import { SupervisionOrder } from '../../../../../core/supervision-order/models/supervision-order.model';
import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service';
import { getListableObjectComponent, listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; import { DynamicComponentLoaderDirective } from '../../../../../shared/abstract-component-loader/dynamic-component-loader.directive';
import { WorkspaceItemSearchResult } from '../../../../../shared/object-collection/shared/workspace-item-search-result.model';
import { ThemeService } from '../../../../../shared/theme-support/theme.service';
import { hasValue } from '../../../../../shared/empty.util'; import { hasValue } from '../../../../../shared/empty.util';
import {
getListableObjectComponent,
listableObjectComponent,
} from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { WorkspaceItemSearchResult } from '../../../../../shared/object-collection/shared/workspace-item-search-result.model';
import { SearchResultGridElementComponent } from '../../../../../shared/object-grid/search-result-grid-element/search-result-grid-element.component';
import { ThemeService } from '../../../../../shared/theme-support/theme.service';
import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service';
import { followLink } from '../../../../../shared/utils/follow-link-config.model'; import { followLink } from '../../../../../shared/utils/follow-link-config.model';
@listableObjectComponent(WorkspaceItemSearchResult, ViewMode.GridElement, Context.AdminWorkflowSearch) @listableObjectComponent(WorkspaceItemSearchResult, ViewMode.GridElement, Context.AdminWorkflowSearch)

View File

@@ -1,18 +1,19 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { SharedModule } from '../shared/shared.module'; import { UiSwitchModule } from 'ngx-ui-switch';
import { AccessControlModule } from '../access-control/access-control.module'; import { AccessControlModule } from '../access-control/access-control.module';
import { SharedModule } from '../shared/shared.module';
import { UploadModule } from '../shared/upload/upload.module';
import { AdminCurationTasksComponent } from './admin-curation-tasks/admin-curation-tasks.component';
import { BatchImportPageComponent } from './admin-import-batch-page/batch-import-page.component';
import { MetadataImportPageComponent } from './admin-import-metadata-page/metadata-import-page.component'; 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 { AdminReportsModule } from './admin-reports/admin-reports.module';
import { AdminRoutingModule } from './admin-routing.module'; import { AdminRoutingModule } from './admin-routing.module';
import { AdminCurationTasksComponent } from './admin-curation-tasks/admin-curation-tasks.component';
import { AdminWorkflowModuleModule } from './admin-workflow-page/admin-workflow.module';
import { AdminSearchModule } from './admin-search-page/admin-search.module'; 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 { AdminWorkflowModuleModule } from './admin-workflow-page/admin-workflow.module';
import { AdminReportsModule } from './admin-reports/admin-reports.module';
import { UiSwitchModule } from 'ngx-ui-switch';
import { UploadModule } from '../shared/upload/upload.module';
const ENTRY_COMPONENTS = [ const ENTRY_COMPONENTS = [
// put only entry components that use custom decorator // put only entry components that use custom decorator

View File

@@ -5,7 +5,10 @@ import { Community } from './core/shared/community.model';
import { DSpaceObject } from './core/shared/dspace-object.model'; import { DSpaceObject } from './core/shared/dspace-object.model';
import { Item } from './core/shared/item.model'; import { Item } from './core/shared/item.model';
import { URLCombiner } from './core/url-combiner/url-combiner'; import { URLCombiner } from './core/url-combiner/url-combiner';
import { getItemModuleRoute, getItemPageRoute } from './item-page/item-page-routing-paths'; import {
getItemModuleRoute,
getItemPageRoute,
} from './item-page/item-page-routing-paths';
import { hasValue } from './shared/empty.util'; import { hasValue } from './shared/empty.util';
export const BITSTREAM_MODULE_PATH = 'bitstreams'; export const BITSTREAM_MODULE_PATH = 'bitstreams';

View File

@@ -1,5 +1,26 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { ACCESS_CONTROL_MODULE_PATH, ADMIN_MODULE_PATH, BITSTREAM_MODULE_PATH, ERROR_PAGE, FORBIDDEN_PATH, FORGOT_PASSWORD_PATH, HEALTH_PAGE_PATH, INFO_MODULE_PATH, INTERNAL_SERVER_ERROR, LEGACY_BITSTREAM_MODULE_PATH, PROFILE_MODULE_PATH, REGISTER_PATH, REQUEST_COPY_MODULE_PATH, WORKFLOW_ITEM_MODULE_PATH } from './app-routing-paths'; import {
NoPreloading,
RouterModule,
} from '@angular/router';
import { NOTIFICATIONS_MODULE_PATH } from './admin/admin-routing-paths';
import {
ACCESS_CONTROL_MODULE_PATH,
ADMIN_MODULE_PATH,
BITSTREAM_MODULE_PATH,
ERROR_PAGE,
FORBIDDEN_PATH,
FORGOT_PASSWORD_PATH,
HEALTH_PAGE_PATH,
INFO_MODULE_PATH,
INTERNAL_SERVER_ERROR,
LEGACY_BITSTREAM_MODULE_PATH,
PROFILE_MODULE_PATH,
REGISTER_PATH,
REQUEST_COPY_MODULE_PATH,
WORKFLOW_ITEM_MODULE_PATH,
} from './app-routing-paths';
import { COLLECTION_MODULE_PATH } from './collection-page/collection-page-routing-paths'; import { COLLECTION_MODULE_PATH } from './collection-page/collection-page-routing-paths';
import { COMMUNITY_MODULE_PATH } from './community-page/community-page-routing-paths'; import { COMMUNITY_MODULE_PATH } from './community-page/community-page-routing-paths';
import { AuthBlockingGuard } from './core/auth/auth-blocking.guard'; import { AuthBlockingGuard } from './core/auth/auth-blocking.guard';
@@ -8,18 +29,16 @@ import { GroupAdministratorGuard } from './core/data/feature-authorization/featu
import { SiteRegisterGuard } from './core/data/feature-authorization/feature-authorization-guard/site-register.guard'; import { SiteRegisterGuard } from './core/data/feature-authorization/feature-authorization-guard/site-register.guard';
import { EndUserAgreementCurrentUserGuard } from './core/end-user-agreement/end-user-agreement-current-user.guard'; import { EndUserAgreementCurrentUserGuard } from './core/end-user-agreement/end-user-agreement-current-user.guard';
import { ReloadGuard } from './core/reload/reload.guard'; import { ReloadGuard } from './core/reload/reload.guard';
import { ForgotPasswordCheckGuard } from './core/rest-property/forgot-password-check-guard.guard';
import { ServerCheckGuard } from './core/server-check/server-check.guard'; import { ServerCheckGuard } from './core/server-check/server-check.guard';
import { ThemedForbiddenComponent } from './forbidden/themed-forbidden.component'; import { ThemedForbiddenComponent } from './forbidden/themed-forbidden.component';
import { ThemedPageInternalServerErrorComponent } from './page-internal-server-error/themed-page-internal-server-error.component'; import { ITEM_MODULE_PATH } from './item-page/item-page-routing-paths';
import { SUGGESTION_MODULE_PATH } from './suggestions-page/suggestions-page-routing-paths';
import { MenuResolver } from './menu.resolver'; import { MenuResolver } from './menu.resolver';
import { ThemedPageErrorComponent } from './page-error/themed-page-error.component'; import { ThemedPageErrorComponent } from './page-error/themed-page-error.component';
import { NOTIFICATIONS_MODULE_PATH } from './admin/admin-routing-paths'; import { ThemedPageInternalServerErrorComponent } from './page-internal-server-error/themed-page-internal-server-error.component';
import { ForgotPasswordCheckGuard } from './core/rest-property/forgot-password-check-guard.guard';
import { ThemedPageNotFoundComponent } from './pagenotfound/themed-pagenotfound.component'; import { ThemedPageNotFoundComponent } from './pagenotfound/themed-pagenotfound.component';
import { NoPreloading, RouterModule } from '@angular/router';
import { ITEM_MODULE_PATH } from './item-page/item-page-routing-paths';
import { PROCESS_MODULE_PATH } from './process-page/process-page-routing.paths'; import { PROCESS_MODULE_PATH } from './process-page/process-page-routing.paths';
import { SUGGESTION_MODULE_PATH } from './suggestions-page/suggestions-page-routing-paths';
@NgModule({ @NgModule({
imports: [ imports: [
@@ -74,7 +93,7 @@ import { PROCESS_MODULE_PATH } from './process-page/process-page-routing.paths';
path: FORGOT_PASSWORD_PATH, path: FORGOT_PASSWORD_PATH,
loadChildren: () => import('./forgot-password/forgot-password.module') loadChildren: () => import('./forgot-password/forgot-password.module')
.then((m) => m.ForgotPasswordModule), .then((m) => m.ForgotPasswordModule),
canActivate: [EndUserAgreementCurrentUserGuard, ForgotPasswordCheckGuard] canActivate: [EndUserAgreementCurrentUserGuard, ForgotPasswordCheckGuard],
}, },
{ {
path: COMMUNITY_MODULE_PATH, path: COMMUNITY_MODULE_PATH,
@@ -134,19 +153,19 @@ import { PROCESS_MODULE_PATH } from './process-page/process-page-routing.paths';
path: ADMIN_MODULE_PATH, path: ADMIN_MODULE_PATH,
loadChildren: () => import('./admin/admin.module') loadChildren: () => import('./admin/admin.module')
.then((m) => m.AdminModule), .then((m) => m.AdminModule),
canActivate: [EndUserAgreementCurrentUserGuard] canActivate: [EndUserAgreementCurrentUserGuard],
}, },
{ {
path: NOTIFICATIONS_MODULE_PATH, path: NOTIFICATIONS_MODULE_PATH,
loadChildren: () => import('./admin/admin-notifications/admin-notifications.module') loadChildren: () => import('./admin/admin-notifications/admin-notifications.module')
.then((m) => m.AdminNotificationsModule), .then((m) => m.AdminNotificationsModule),
canActivate: [AuthenticatedGuard, EndUserAgreementCurrentUserGuard] canActivate: [AuthenticatedGuard, EndUserAgreementCurrentUserGuard],
}, },
{ {
path: NOTIFICATIONS_MODULE_PATH, path: NOTIFICATIONS_MODULE_PATH,
loadChildren: () => import('./quality-assurance-notifications-pages/notifications-pages.module') loadChildren: () => import('./quality-assurance-notifications-pages/notifications-pages.module')
.then((m) => m.NotificationsPageModule), .then((m) => m.NotificationsPageModule),
canActivate: [AuthenticatedGuard, EndUserAgreementCurrentUserGuard] canActivate: [AuthenticatedGuard, EndUserAgreementCurrentUserGuard],
}, },
{ {
path: 'login', path: 'login',
@@ -197,7 +216,7 @@ import { PROCESS_MODULE_PATH } from './process-page/process-page-routing.paths';
{ path: SUGGESTION_MODULE_PATH, { path: SUGGESTION_MODULE_PATH,
loadChildren: () => import('./suggestions-page/suggestions-page.module') loadChildren: () => import('./suggestions-page/suggestions-page.module')
.then((m) => m.SuggestionsPageModule), .then((m) => m.SuggestionsPageModule),
canActivate: [AuthenticatedGuard, EndUserAgreementCurrentUserGuard] canActivate: [AuthenticatedGuard, EndUserAgreementCurrentUserGuard],
}, },
{ {
path: INFO_MODULE_PATH, path: INFO_MODULE_PATH,

View File

@@ -1,31 +1,69 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import {
import { Bitstream } from '../../core/shared/bitstream.model'; ChangeDetectionStrategy,
import { ActivatedRoute, Router } from '@angular/router'; ChangeDetectorRef,
import { filter, map, switchMap, tap } from 'rxjs/operators'; Component,
import { combineLatest, combineLatest as observableCombineLatest, Observable, of as observableOf, Subscription } from 'rxjs'; OnDestroy,
import { DynamicFormControlModel, DynamicFormGroupModel, DynamicFormLayout, DynamicFormService, DynamicInputModel, DynamicSelectModel } from '@ng-dynamic-forms/core'; OnInit,
} from '@angular/core';
import { UntypedFormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import {
ActivatedRoute,
Router,
} from '@angular/router';
import {
DynamicFormControlModel,
DynamicFormGroupModel,
DynamicFormLayout,
DynamicFormService,
DynamicInputModel,
DynamicSelectModel,
} from '@ng-dynamic-forms/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { DynamicCustomSwitchModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/custom-switch/custom-switch.model';
import cloneDeep from 'lodash/cloneDeep'; import cloneDeep from 'lodash/cloneDeep';
import {
combineLatest,
combineLatest as observableCombineLatest,
Observable,
of as observableOf,
Subscription,
} from 'rxjs';
import {
filter,
map,
switchMap,
tap,
} from 'rxjs/operators';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
import { BitstreamDataService } from '../../core/data/bitstream-data.service'; import { BitstreamDataService } from '../../core/data/bitstream-data.service';
import { getAllSucceededRemoteDataPayload, getFirstCompletedRemoteData, getFirstSucceededRemoteData, getFirstSucceededRemoteDataPayload, getRemoteDataPayload } from '../../core/shared/operators';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { BitstreamFormatDataService } from '../../core/data/bitstream-format-data.service'; import { BitstreamFormatDataService } from '../../core/data/bitstream-format-data.service';
import { PaginatedList } from '../../core/data/paginated-list.model'; import { PaginatedList } from '../../core/data/paginated-list.model';
import { PrimaryBitstreamService } from '../../core/data/primary-bitstream.service'; import { PrimaryBitstreamService } from '../../core/data/primary-bitstream.service';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { Bitstream } from '../../core/shared/bitstream.model';
import { BitstreamFormat } from '../../core/shared/bitstream-format.model'; import { BitstreamFormat } from '../../core/shared/bitstream-format.model';
import { BitstreamFormatSupportLevel } from '../../core/shared/bitstream-format-support-level'; import { BitstreamFormatSupportLevel } from '../../core/shared/bitstream-format-support-level';
import { Bundle } from '../../core/shared/bundle.model'; import { Bundle } from '../../core/shared/bundle.model';
import { Item } from '../../core/shared/item.model'; import { Item } from '../../core/shared/item.model';
import { Metadata } from '../../core/shared/metadata.utils'; import { Metadata } from '../../core/shared/metadata.utils';
import {
getAllSucceededRemoteDataPayload,
getFirstCompletedRemoteData,
getFirstSucceededRemoteData,
getFirstSucceededRemoteDataPayload,
getRemoteDataPayload,
} from '../../core/shared/operators';
import { getEntityEditRoute } from '../../item-page/item-page-routing-paths'; import { getEntityEditRoute } from '../../item-page/item-page-routing-paths';
import { hasValue, hasValueOperator, isEmpty, isNotEmpty } from '../../shared/empty.util'; import {
hasValue,
hasValueOperator,
isEmpty,
isNotEmpty,
} from '../../shared/empty.util';
import { DynamicCustomSwitchModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/custom-switch/custom-switch.model';
import { DsDynamicInputModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model'; import { DsDynamicInputModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model';
import { DsDynamicTextAreaModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-textarea.model'; import { DsDynamicTextAreaModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-textarea.model';
import { NotificationsService } from '../../shared/notifications/notifications.service';
@Component({ @Component({
selector: 'ds-edit-bitstream-page', selector: 'ds-edit-bitstream-page',
@@ -258,7 +296,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
group: [ group: [
this.primaryBitstreamModel, this.primaryBitstreamModel,
this.fileNameModel, this.fileNameModel,
] ],
}, { }, {
grid: { grid: {
host: 'form-row', host: 'form-row',
@@ -295,11 +333,11 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
}, },
primaryBitstream: { primaryBitstream: {
grid: { grid: {
container: 'col-12' container: 'col-12',
}, },
element: { element: {
container: 'text-right' container: 'text-right',
} },
}, },
description: { description: {
grid: { grid: {

View File

@@ -1,11 +1,21 @@
import { BrowseByDateComponent } from './browse-by-date.component';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { ChangeDetectorRef, NO_ERRORS_SCHEMA } from '@angular/core'; import {
import { ActivatedRoute, Router } from '@angular/router'; ChangeDetectorRef,
NO_ERRORS_SCHEMA,
} from '@angular/core';
import {
ComponentFixture,
TestBed,
waitForAsync,
} from '@angular/core/testing';
import {
ActivatedRoute,
Router,
} from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { cold } from 'jasmine-marbles';
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { APP_CONFIG } from '../../../config/app-config.interface'; import { APP_CONFIG } from '../../../config/app-config.interface';
@@ -17,14 +27,14 @@ import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.serv
import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationService } from '../../core/pagination/pagination.service';
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';
import { toRemoteData } from '../browse-by-metadata/browse-by-metadata.component.spec'; import { RouterMock } from '../../shared/mocks/router.mock';
import { VarDirective } from '../../shared/utils/var.directive';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import { ActivatedRouteStub } from '../../shared/testing/active-router.stub'; import { ActivatedRouteStub } from '../../shared/testing/active-router.stub';
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
import { cold } from 'jasmine-marbles';
import { EnumKeysPipe } from '../../shared/utils/enum-keys-pipe'; import { EnumKeysPipe } from '../../shared/utils/enum-keys-pipe';
import { RouterMock } from '../../shared/mocks/router.mock'; import { VarDirective } from '../../shared/utils/var.directive';
import { toRemoteData } from '../browse-by-metadata/browse-by-metadata.component.spec';
import { BrowseByDateComponent } from './browse-by-date.component';
describe('BrowseByDateComponent', () => { describe('BrowseByDateComponent', () => {
let comp: BrowseByDateComponent; let comp: BrowseByDateComponent;

View File

@@ -1,22 +1,48 @@
import { ChangeDetectorRef, Component, Inject, OnInit } from '@angular/core'; import {
import { BrowseByMetadataComponent, browseParamsToOptions, getBrowseSearchOptions } from '../browse-by-metadata/browse-by-metadata.component'; ChangeDetectorRef,
import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; Component,
import { hasValue, isNotEmpty } from '../../shared/empty.util'; Inject,
import { ActivatedRoute, Params, Router } from '@angular/router'; OnInit,
} from '@angular/core';
import {
ActivatedRoute,
Params,
Router,
} from '@angular/router';
import {
combineLatest as observableCombineLatest,
Observable,
} from 'rxjs';
import { map } from 'rxjs/operators';
import {
APP_CONFIG,
AppConfig,
} from '../../../config/app-config.interface';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
import { BrowseService } from '../../core/browse/browse.service'; import { BrowseService } from '../../core/browse/browse.service';
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import {
SortDirection,
SortOptions,
} from '../../core/cache/models/sort-options.model';
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service'; import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationService } from '../../core/pagination/pagination.service';
import { Item } from '../../core/shared/item.model'; import { Item } from '../../core/shared/item.model';
import { isValidDate } from '../../shared/date.util'; import { isValidDate } from '../../shared/date.util';
import {
hasValue,
isNotEmpty,
} from '../../shared/empty.util';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { APP_CONFIG, AppConfig } from '../../../config/app-config.interface';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
import { rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator';
import { BrowseByDataType } from '../browse-by-switcher/browse-by-data-type';
import { StartsWithType } from '../../shared/starts-with/starts-with-decorator'; import { StartsWithType } from '../../shared/starts-with/starts-with-decorator';
import { map } from 'rxjs/operators'; import {
BrowseByMetadataComponent,
browseParamsToOptions,
getBrowseSearchOptions,
} from '../browse-by-metadata/browse-by-metadata.component';
import { BrowseByDataType } from '../browse-by-switcher/browse-by-data-type';
import { rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator';
@Component({ @Component({
selector: 'ds-browse-by-date', selector: 'ds-browse-by-date',
@@ -61,7 +87,7 @@ export class BrowseByDateComponent extends BrowseByMetadataComponent implements
this.currentPagination$, this.currentSort$]).pipe( this.currentPagination$, this.currentSort$]).pipe(
map(([routeParams, queryParams, scope, data, currentPage, currentSort]) => { map(([routeParams, queryParams, scope, data, currentPage, currentSort]) => {
return [Object.assign({}, routeParams, queryParams, data), scope, currentPage, currentSort]; return [Object.assign({}, routeParams, queryParams, data), scope, currentPage, currentSort];
}) }),
).subscribe(([params, scope, currentPage, currentSort]: [Params, string, PaginationComponentOptions, SortOptions]) => { ).subscribe(([params, scope, currentPage, currentSort]: [Params, string, PaginationComponentOptions, SortOptions]) => {
const metadataKeys = params.browseDefinition ? params.browseDefinition.metadataKeys : this.defaultMetadataKeys; const metadataKeys = params.browseDefinition ? params.browseDefinition.metadataKeys : this.defaultMetadataKeys;
this.browseId = params.id || this.defaultBrowseId; this.browseId = params.id || this.defaultBrowseId;
@@ -89,7 +115,7 @@ export class BrowseByDateComponent extends BrowseByMetadataComponent implements
firstItemRD$, firstItemRD$,
lastItemRD$, lastItemRD$,
]).pipe( ]).pipe(
map(([firstItemRD, lastItemRD]: [RemoteData<Item>, RemoteData<Item>]) => firstItemRD.isLoading || lastItemRD.isLoading) map(([firstItemRD, lastItemRD]: [RemoteData<Item>, RemoteData<Item>]) => firstItemRD.isLoading || lastItemRD.isLoading),
); );
this.subs.push( this.subs.push(
observableCombineLatest([ observableCombineLatest([
@@ -97,7 +123,7 @@ export class BrowseByDateComponent extends BrowseByMetadataComponent implements
lastItemRD$, lastItemRD$,
]).subscribe(([firstItemRD, lastItemRD]: [RemoteData<Item>, RemoteData<Item>]) => { ]).subscribe(([firstItemRD, lastItemRD]: [RemoteData<Item>, RemoteData<Item>]) => {
let lowerLimit: number = this.getLimit(firstItemRD, metadataKeys, this.appConfig.browseBy.defaultLowerLimit); let lowerLimit: number = this.getLimit(firstItemRD, metadataKeys, this.appConfig.browseBy.defaultLowerLimit);
let upperLimit: number = this.getLimit(lastItemRD, metadataKeys, new Date().getUTCFullYear()); const upperLimit: number = this.getLimit(lastItemRD, metadataKeys, new Date().getUTCFullYear());
const options: number[] = []; const options: number[] = [];
const oneYearBreak: number = Math.floor((upperLimit - this.appConfig.browseBy.oneYearLimit) / 5) * 5; const oneYearBreak: number = Math.floor((upperLimit - this.appConfig.browseBy.oneYearLimit) / 5) * 5;
const fiveYearBreak: number = Math.floor((upperLimit - this.appConfig.browseBy.fiveYearLimit) / 10) * 10; const fiveYearBreak: number = Math.floor((upperLimit - this.appConfig.browseBy.fiveYearLimit) / 10) * 10;

View File

@@ -1,8 +1,12 @@
import { first } from 'rxjs/operators'; import { first } from 'rxjs/operators';
import { BrowseByGuard } from './browse-by-guard';
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils';
import { ValueListBrowseDefinition } from '../core/shared/value-list-browse-definition.model'; import { ValueListBrowseDefinition } from '../core/shared/value-list-browse-definition.model';
import {
createFailedRemoteDataObject$,
createSuccessfulRemoteDataObject$,
} from '../shared/remote-data.utils';
import { RouterStub } from '../shared/testing/router.stub'; import { RouterStub } from '../shared/testing/router.stub';
import { BrowseByGuard } from './browse-by-guard';
import { BrowseByDataType } from './browse-by-switcher/browse-by-data-type'; import { BrowseByDataType } from './browse-by-switcher/browse-by-data-type';
describe('BrowseByGuard', () => { describe('BrowseByGuard', () => {

View File

@@ -1,15 +1,30 @@
import { ActivatedRouteSnapshot, CanActivate, Data, Router, RouterStateSnapshot } from '@angular/router';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { hasNoValue, hasValue } from '../shared/empty.util'; import {
import { map, switchMap } from 'rxjs/operators'; ActivatedRouteSnapshot,
import { getFirstCompletedRemoteData } from '../core/shared/operators'; CanActivate,
Data,
Router,
RouterStateSnapshot,
} from '@angular/router';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { Observable, of as observableOf } from 'rxjs'; import {
Observable,
of as observableOf,
} from 'rxjs';
import {
map,
switchMap,
} from 'rxjs/operators';
import { PAGE_NOT_FOUND_PATH } from '../app-routing-paths'; import { PAGE_NOT_FOUND_PATH } from '../app-routing-paths';
import { BrowseDefinitionDataService } from '../core/browse/browse-definition-data.service'; import { BrowseDefinitionDataService } from '../core/browse/browse-definition-data.service';
import { RemoteData } from '../core/data/remote-data'; import { RemoteData } from '../core/data/remote-data';
import { BrowseDefinition } from '../core/shared/browse-definition.model'; import { BrowseDefinition } from '../core/shared/browse-definition.model';
import { getFirstCompletedRemoteData } from '../core/shared/operators';
import {
hasNoValue,
hasValue,
} from '../shared/empty.util';
@Injectable() @Injectable()
/** /**

View File

@@ -1,19 +1,32 @@
import { BrowseByMetadataComponent, browseParamsToOptions, getBrowseSearchOptions } from './browse-by-metadata.component';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { BrowseService } from '../../core/browse/browse.service';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'; import {
ComponentFixture,
TestBed,
waitForAsync,
} from '@angular/core/testing';
import {
ActivatedRoute,
Router,
} from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { Observable, of as observableOf } from 'rxjs'; import { cold } from 'jasmine-marbles';
import {
Observable,
of as observableOf,
} from 'rxjs';
import { APP_CONFIG } from '../../../config/app-config.interface'; import { APP_CONFIG } from '../../../config/app-config.interface';
import { BrowseService } from '../../core/browse/browse.service';
import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-options.model'; import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-options.model';
import { SortDirection } from '../../core/cache/models/sort-options.model'; import { SortDirection } from '../../core/cache/models/sort-options.model';
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service'; import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model'; import {
buildPaginatedList,
PaginatedList,
} from '../../core/data/paginated-list.model';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationService } from '../../core/pagination/pagination.service';
import { BrowseEntry } from '../../core/shared/browse-entry.model'; import { BrowseEntry } from '../../core/shared/browse-entry.model';
@@ -25,7 +38,11 @@ import { PaginationComponentOptions } from '../../shared/pagination/pagination-c
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import { ActivatedRouteStub } from '../../shared/testing/active-router.stub'; import { ActivatedRouteStub } from '../../shared/testing/active-router.stub';
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
import { cold } from 'jasmine-marbles'; import {
BrowseByMetadataComponent,
browseParamsToOptions,
getBrowseSearchOptions,
} from './browse-by-metadata.component';
describe('BrowseByMetadataComponent', () => { describe('BrowseByMetadataComponent', () => {
let comp: BrowseByMetadataComponent; let comp: BrowseByMetadataComponent;

View File

@@ -1,27 +1,52 @@
import { BehaviorSubject, combineLatest as observableCombineLatest, Observable, of as observableOf, Subscription } from 'rxjs'; import {
import { Component, Inject, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; Component,
import { RemoteData } from '../../core/data/remote-data'; Inject,
import { PaginatedList } from '../../core/data/paginated-list.model'; Input,
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; OnChanges,
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; OnDestroy,
import { ActivatedRoute, Params, Router } from '@angular/router'; OnInit,
import { hasValue, isNotEmpty } from '../../shared/empty.util'; } from '@angular/core';
import {
ActivatedRoute,
Params,
Router,
} from '@angular/router';
import {
BehaviorSubject,
combineLatest as observableCombineLatest,
Observable,
of as observableOf,
Subscription,
} from 'rxjs';
import { map } from 'rxjs/operators';
import {
APP_CONFIG,
AppConfig,
} from '../../../config/app-config.interface';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
import { BrowseService } from '../../core/browse/browse.service'; import { BrowseService } from '../../core/browse/browse.service';
import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-options.model'; import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-options.model';
import {
SortDirection,
SortOptions,
} from '../../core/cache/models/sort-options.model';
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service'; import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
import { StartsWithType } from '../../shared/starts-with/starts-with-decorator'; import { PaginatedList } from '../../core/data/paginated-list.model';
import { RemoteData } from '../../core/data/remote-data';
import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationService } from '../../core/pagination/pagination.service';
import { map } from 'rxjs/operators';
import { APP_CONFIG, AppConfig } from '../../../config/app-config.interface';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
import { rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator';
import { BrowseByDataType } from '../browse-by-switcher/browse-by-data-type';
import { Context } from '../../core/shared/context.model';
import { BrowseEntry } from '../../core/shared/browse-entry.model'; import { BrowseEntry } from '../../core/shared/browse-entry.model';
import { Collection } from '../../core/shared/collection.model'; import { Context } from '../../core/shared/context.model';
import { Community } from '../../core/shared/community.model';
import { Item } from '../../core/shared/item.model'; import { Item } from '../../core/shared/item.model';
import { getFirstSucceededRemoteData } from '../../core/shared/operators'; import { getFirstSucceededRemoteData } from '../../core/shared/operators';
import {
hasValue,
isNotEmpty,
} from '../../shared/empty.util';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { StartsWithType } from '../../shared/starts-with/starts-with-decorator';
import { BrowseByDataType } from '../browse-by-switcher/browse-by-data-type';
import { rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator';
export const BBM_PAGINATION_ID = 'bbm'; export const BBM_PAGINATION_ID = 'bbm';
@@ -167,7 +192,7 @@ export class BrowseByMetadataComponent implements OnInit, OnChanges, OnDestroy {
observableCombineLatest([this.route.params, this.route.queryParams, this.scope$, this.currentPagination$, this.currentSort$]).pipe( observableCombineLatest([this.route.params, this.route.queryParams, this.scope$, this.currentPagination$, this.currentSort$]).pipe(
map(([routeParams, queryParams, scope, currentPage, currentSort]) => { map(([routeParams, queryParams, scope, currentPage, currentSort]) => {
return [Object.assign({}, routeParams, queryParams), scope, currentPage, currentSort]; return [Object.assign({}, routeParams, queryParams), scope, currentPage, currentSort];
}) }),
).subscribe(([params, scope, currentPage, currentSort]: [Params, string, PaginationComponentOptions, SortOptions]) => { ).subscribe(([params, scope, currentPage, currentSort]: [Params, string, PaginationComponentOptions, SortOptions]) => {
this.browseId = params.id || this.defaultBrowseId; this.browseId = params.id || this.defaultBrowseId;
this.authority = params.authority; this.authority = params.authority;

View File

@@ -3,10 +3,10 @@ import { NgModule } from '@angular/core';
import { BrowseService } from '../core/browse/browse.service'; import { BrowseService } from '../core/browse/browse.service';
import { ItemDataService } from '../core/data/item-data.service'; import { ItemDataService } from '../core/data/item-data.service';
import { SharedBrowseByModule } from '../shared/browse-by/shared-browse-by.module'; import { SharedBrowseByModule } from '../shared/browse-by/shared-browse-by.module';
import { BrowseByPageComponent } from './browse-by-page/browse-by-page.component';
import { SharedModule } from '../shared/shared.module'; import { SharedModule } from '../shared/shared.module';
import { BrowseByModule } from './browse-by.module'; import { BrowseByModule } from './browse-by.module';
import { BrowseByGuard } from './browse-by-guard'; import { BrowseByGuard } from './browse-by-guard';
import { BrowseByPageComponent } from './browse-by-page/browse-by-page.component';
import { BrowseByRoutingModule } from './browse-by-routing.module'; import { BrowseByRoutingModule } from './browse-by-routing.module';
const DECLARATIONS = [ const DECLARATIONS = [

View File

@@ -1,17 +1,21 @@
// eslint-disable-next-line max-classes-per-file // eslint-disable-next-line max-classes-per-file
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { BrowseByPageComponent } from './browse-by-page.component';
import { BrowseBySwitcherComponent } from '../browse-by-switcher/browse-by-switcher.component';
import { DynamicComponentLoaderDirective } from '../../shared/abstract-component-loader/dynamic-component-loader.directive';
import { ActivatedRoute } from '@angular/router';
import { ActivatedRouteStub } from '../../shared/testing/active-router.stub';
import { getMockThemeService } from '../../shared/mocks/theme-service.mock';
import { ThemeService } from '../../shared/theme-support/theme.service';
import { rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator';
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { BrowseDefinition } from '../../core/shared/browse-definition.model'; import {
ComponentFixture,
TestBed,
} from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { ActivatedRoute } from '@angular/router';
import { BrowseDefinition } from '../../core/shared/browse-definition.model';
import { DynamicComponentLoaderDirective } from '../../shared/abstract-component-loader/dynamic-component-loader.directive';
import { getMockThemeService } from '../../shared/mocks/theme-service.mock';
import { ActivatedRouteStub } from '../../shared/testing/active-router.stub';
import { ThemeService } from '../../shared/theme-support/theme.service';
import { BrowseByDataType } from '../browse-by-switcher/browse-by-data-type'; import { BrowseByDataType } from '../browse-by-switcher/browse-by-data-type';
import { rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator';
import { BrowseBySwitcherComponent } from '../browse-by-switcher/browse-by-switcher.component';
import { BrowseByPageComponent } from './browse-by-page.component';
@rendersBrowseBy('BrowseByPageComponent' as BrowseByDataType) @rendersBrowseBy('BrowseByPageComponent' as BrowseByDataType)
@Component({ @Component({

View File

@@ -1,8 +1,12 @@
import { Component, OnInit } from '@angular/core'; import {
import { map } from 'rxjs/operators'; Component,
import { BrowseDefinition } from '../../core/shared/browse-definition.model'; OnInit,
} from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { BrowseDefinition } from '../../core/shared/browse-definition.model';
import { BrowseByDataType } from '../browse-by-switcher/browse-by-data-type'; import { BrowseByDataType } from '../browse-by-switcher/browse-by-data-type';
@Component({ @Component({

View File

@@ -1,8 +1,12 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { hasNoValue } from '../../shared/empty.util';
import { DEFAULT_THEME, resolveTheme } from '../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { Context } from '../../core/shared/context.model'; import { Context } from '../../core/shared/context.model';
import { GenericConstructor } from '../../core/shared/generic-constructor'; import { GenericConstructor } from '../../core/shared/generic-constructor';
import { hasNoValue } from '../../shared/empty.util';
import {
DEFAULT_THEME,
resolveTheme,
} from '../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { BrowseByDataType } from './browse-by-data-type'; import { BrowseByDataType } from './browse-by-data-type';
export const DEFAULT_BROWSE_BY_TYPE = BrowseByDataType.Metadata; export const DEFAULT_BROWSE_BY_TYPE = BrowseByDataType.Metadata;

View File

@@ -1,14 +1,22 @@
import { BrowseBySwitcherComponent } from './browse-by-switcher.component'; import {
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; Component,
import { Component, SimpleChange } from '@angular/core'; SimpleChange,
import { rendersBrowseBy } from './browse-by-decorator'; } from '@angular/core';
import { ThemeService } from '../../shared/theme-support/theme.service'; import {
ComponentFixture,
TestBed,
waitForAsync,
} from '@angular/core/testing';
import { FlatBrowseDefinition } from '../../core/shared/flat-browse-definition.model'; import { FlatBrowseDefinition } from '../../core/shared/flat-browse-definition.model';
import { NonHierarchicalBrowseDefinition } from '../../core/shared/non-hierarchical-browse-definition'; import { NonHierarchicalBrowseDefinition } from '../../core/shared/non-hierarchical-browse-definition';
import { getMockThemeService } from '../../shared/mocks/theme-service.mock';
import { DynamicComponentLoaderDirective } from '../../shared/abstract-component-loader/dynamic-component-loader.directive';
import { BrowseByDataType } from './browse-by-data-type';
import { ValueListBrowseDefinition } from '../../core/shared/value-list-browse-definition.model'; import { ValueListBrowseDefinition } from '../../core/shared/value-list-browse-definition.model';
import { DynamicComponentLoaderDirective } from '../../shared/abstract-component-loader/dynamic-component-loader.directive';
import { getMockThemeService } from '../../shared/mocks/theme-service.mock';
import { ThemeService } from '../../shared/theme-support/theme.service';
import { BrowseByDataType } from './browse-by-data-type';
import { rendersBrowseBy } from './browse-by-decorator';
import { BrowseBySwitcherComponent } from './browse-by-switcher.component';
@rendersBrowseBy('BrowseBySwitcherComponent' as BrowseByDataType) @rendersBrowseBy('BrowseBySwitcherComponent' as BrowseByDataType)
@Component({ @Component({

View File

@@ -1,13 +1,17 @@
import { Component, Input } from '@angular/core'; import {
import { getComponentByBrowseByType } from './browse-by-decorator'; Component,
Input,
} from '@angular/core';
import { Context } from '../../core/shared/context.model';
import { GenericConstructor } from '../../core/shared/generic-constructor'; import { GenericConstructor } from '../../core/shared/generic-constructor';
import { AbstractComponentLoaderComponent } from '../../shared/abstract-component-loader/abstract-component-loader.component'; import { AbstractComponentLoaderComponent } from '../../shared/abstract-component-loader/abstract-component-loader.component';
import { BrowseByDataType } from './browse-by-data-type'; import { BrowseByDataType } from './browse-by-data-type';
import { Context } from '../../core/shared/context.model'; import { getComponentByBrowseByType } from './browse-by-decorator';
@Component({ @Component({
selector: 'ds-browse-by-switcher', selector: 'ds-browse-by-switcher',
templateUrl: '../../shared/abstract-component-loader/abstract-component-loader.component.html' templateUrl: '../../shared/abstract-component-loader/abstract-component-loader.component.html',
}) })
export class BrowseBySwitcherComponent extends AbstractComponentLoaderComponent<Component> { export class BrowseBySwitcherComponent extends AbstractComponentLoaderComponent<Component> {

View File

@@ -1,10 +1,13 @@
import { Directive, ViewContainerRef } from '@angular/core'; import {
Directive,
ViewContainerRef,
} from '@angular/core';
/** /**
* Directive used as a hook to know where to inject the dynamic loaded component * Directive used as a hook to know where to inject the dynamic loaded component
*/ */
@Directive({ @Directive({
selector: '[dsDynamicComponentLoader]' selector: '[dsDynamicComponentLoader]',
}) })
export class DynamicComponentLoaderDirective { export class DynamicComponentLoaderDirective {

View File

@@ -1,14 +1,17 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { BrowseByTaxonomyComponent } from './browse-by-taxonomy.component';
import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model';
import { TranslateModule } from '@ngx-translate/core';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import {
ComponentFixture,
TestBed,
} from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { BehaviorSubject } from 'rxjs'; import { BehaviorSubject } from 'rxjs';
import { HierarchicalBrowseDefinition } from '../../core/shared/hierarchical-browse-definition.model'; import { HierarchicalBrowseDefinition } from '../../core/shared/hierarchical-browse-definition.model';
import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model';
import { ThemeService } from '../../shared/theme-support/theme.service'; import { ThemeService } from '../../shared/theme-support/theme.service';
import { createDataWithBrowseDefinition } from '../browse-by-switcher/browse-by-switcher.component.spec'; import { createDataWithBrowseDefinition } from '../browse-by-switcher/browse-by-switcher.component.spec';
import { BrowseByTaxonomyComponent } from './browse-by-taxonomy.component';
describe('BrowseByTaxonomyComponent', () => { describe('BrowseByTaxonomyComponent', () => {
let component: BrowseByTaxonomyComponent; let component: BrowseByTaxonomyComponent;

View File

@@ -1,15 +1,29 @@
import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import {
import { VocabularyOptions } from '../../core/submission/vocabularies/models/vocabulary-options.model'; Component,
import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; Input,
import { ActivatedRoute, Params } from '@angular/router'; OnChanges,
import { BehaviorSubject, Observable, Subscription } from 'rxjs'; OnDestroy,
import { BrowseDefinition } from '../../core/shared/browse-definition.model'; OnInit,
import { rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator'; } from '@angular/core';
import {
ActivatedRoute,
Params,
} from '@angular/router';
import {
BehaviorSubject,
Observable,
Subscription,
} from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { HierarchicalBrowseDefinition } from '../../core/shared/hierarchical-browse-definition.model';
import { BrowseByDataType } from '../browse-by-switcher/browse-by-data-type'; import { BrowseDefinition } from '../../core/shared/browse-definition.model';
import { Context } from '../../core/shared/context.model'; import { Context } from '../../core/shared/context.model';
import { HierarchicalBrowseDefinition } from '../../core/shared/hierarchical-browse-definition.model';
import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model';
import { VocabularyOptions } from '../../core/submission/vocabularies/models/vocabulary-options.model';
import { hasValue } from '../../shared/empty.util'; import { hasValue } from '../../shared/empty.util';
import { BrowseByDataType } from '../browse-by-switcher/browse-by-data-type';
import { rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator';
@Component({ @Component({
selector: 'ds-browse-by-taxonomy', selector: 'ds-browse-by-taxonomy',

View File

@@ -1,7 +1,14 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import {
import { ActivatedRoute, Router } from '@angular/router'; ComponentFixture,
TestBed,
waitForAsync,
} from '@angular/core/testing';
import {
ActivatedRoute,
Router,
} from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
@@ -21,8 +28,8 @@ import { ActivatedRouteStub } from '../../shared/testing/active-router.stub';
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
import { EnumKeysPipe } from '../../shared/utils/enum-keys-pipe'; import { EnumKeysPipe } from '../../shared/utils/enum-keys-pipe';
import { VarDirective } from '../../shared/utils/var.directive'; import { VarDirective } from '../../shared/utils/var.directive';
import { BrowseByTitleComponent } from './browse-by-title.component';
import { toRemoteData } from '../browse-by-metadata/browse-by-metadata.component.spec'; import { toRemoteData } from '../browse-by-metadata/browse-by-metadata.component.spec';
import { BrowseByTitleComponent } from './browse-by-title.component';
describe('BrowseByTitleComponent', () => { describe('BrowseByTitleComponent', () => {
let comp: BrowseByTitleComponent; let comp: BrowseByTitleComponent;

View File

@@ -1,17 +1,28 @@
import { combineLatest as observableCombineLatest } from 'rxjs'; import {
import { Component, OnInit } from '@angular/core'; Component,
OnInit,
} from '@angular/core';
import { Params } from '@angular/router'; import { Params } from '@angular/router';
import { BrowseByMetadataComponent, browseParamsToOptions, getBrowseSearchOptions } from '../browse-by-metadata/browse-by-metadata.component'; import { combineLatest as observableCombineLatest } from 'rxjs';
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import {
SortDirection,
SortOptions,
} from '../../core/cache/models/sort-options.model';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator'; import {
BrowseByMetadataComponent,
browseParamsToOptions,
getBrowseSearchOptions,
} from '../browse-by-metadata/browse-by-metadata.component';
import { BrowseByDataType } from '../browse-by-switcher/browse-by-data-type'; import { BrowseByDataType } from '../browse-by-switcher/browse-by-data-type';
import { rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator';
@Component({ @Component({
selector: 'ds-browse-by-title', selector: 'ds-browse-by-title',
styleUrls: ['../browse-by-metadata/browse-by-metadata.component.scss'], styleUrls: ['../browse-by-metadata/browse-by-metadata.component.scss'],
templateUrl: '../browse-by-metadata/browse-by-metadata.component.html' templateUrl: '../browse-by-metadata/browse-by-metadata.component.html',
}) })
/** /**
* Component for browsing items by title (dc.title) * Component for browsing items by title (dc.title)
@@ -29,7 +40,7 @@ export class BrowseByTitleComponent extends BrowseByMetadataComponent implements
observableCombineLatest([this.route.params, this.route.queryParams, this.scope$, this.currentPagination$, this.currentSort$]).pipe( observableCombineLatest([this.route.params, this.route.queryParams, this.scope$, this.currentPagination$, this.currentSort$]).pipe(
map(([routeParams, queryParams, scope, currentPage, currentSort]) => { map(([routeParams, queryParams, scope, currentPage, currentSort]) => {
return [Object.assign({}, routeParams, queryParams), scope, currentPage, currentSort]; return [Object.assign({}, routeParams, queryParams), scope, currentPage, currentSort];
}) }),
).subscribe(([params, scope, currentPage, currentSort]: [Params, string, PaginationComponentOptions, SortOptions]) => { ).subscribe(([params, scope, currentPage, currentSort]: [Params, string, PaginationComponentOptions, SortOptions]) => {
this.startsWith = +params.startsWith || params.startsWith; this.startsWith = +params.startsWith || params.startsWith;
this.browseId = params.id || this.defaultBrowseId; this.browseId = params.id || this.defaultBrowseId;

View File

@@ -1,14 +1,15 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { BrowseByTitleComponent } from './browse-by-title/browse-by-title.component';
import { BrowseByMetadataComponent } from './browse-by-metadata/browse-by-metadata.component';
import { BrowseByDateComponent } from './browse-by-date/browse-by-date.component';
import { BrowseBySwitcherComponent } from './browse-by-switcher/browse-by-switcher.component';
import { BrowseByTaxonomyComponent } from './browse-by-taxonomy/browse-by-taxonomy.component';
import { SharedBrowseByModule } from '../shared/browse-by/shared-browse-by.module'; import { SharedBrowseByModule } from '../shared/browse-by/shared-browse-by.module';
import { DsoPageModule } from '../shared/dso-page/dso-page.module'; import { DsoPageModule } from '../shared/dso-page/dso-page.module';
import { FormModule } from '../shared/form/form.module'; import { FormModule } from '../shared/form/form.module';
import { SharedModule } from '../shared/shared.module'; import { SharedModule } from '../shared/shared.module';
import { BrowseByDateComponent } from './browse-by-date/browse-by-date.component';
import { BrowseByMetadataComponent } from './browse-by-metadata/browse-by-metadata.component';
import { BrowseBySwitcherComponent } from './browse-by-switcher/browse-by-switcher.component';
import { BrowseByTaxonomyComponent } from './browse-by-taxonomy/browse-by-taxonomy.component';
import { BrowseByTitleComponent } from './browse-by-title/browse-by-title.component';
const DECLARATIONS = [ const DECLARATIONS = [
BrowseBySwitcherComponent, BrowseBySwitcherComponent,
@@ -32,12 +33,12 @@ const ENTRY_COMPONENTS = [
], ],
declarations: [ declarations: [
...DECLARATIONS, ...DECLARATIONS,
...ENTRY_COMPONENTS ...ENTRY_COMPONENTS,
], ],
exports: [ exports: [
...DECLARATIONS, ...DECLARATIONS,
...ENTRY_COMPONENTS, ...ENTRY_COMPONENTS,
] ],
}) })
export class BrowseByModule { export class BrowseByModule {
/** /**

View File

@@ -1,27 +1,31 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { BrowseByGuard } from '../browse-by/browse-by-guard';
import { BrowseByI18nBreadcrumbResolver } from '../browse-by/browse-by-i18n-breadcrumb.resolver';
import { AuthenticatedGuard } from '../core/auth/authenticated.guard'; import { AuthenticatedGuard } from '../core/auth/authenticated.guard';
import { CollectionBreadcrumbResolver } from '../core/breadcrumbs/collection-breadcrumb.resolver'; import { CollectionBreadcrumbResolver } from '../core/breadcrumbs/collection-breadcrumb.resolver';
import { DSOBreadcrumbsService } from '../core/breadcrumbs/dso-breadcrumbs.service'; import { DSOBreadcrumbsService } from '../core/breadcrumbs/dso-breadcrumbs.service';
import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver'; import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver';
import { LinkService } from '../core/cache/builders/link.service'; import { LinkService } from '../core/cache/builders/link.service';
import { ComcolBrowseByComponent } from '../shared/comcol/sections/comcol-browse-by/comcol-browse-by.component';
import { ComcolSearchSectionComponent } from '../shared/comcol/sections/comcol-search-section/comcol-search-section.component';
import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver';
import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model'; import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model';
import { MenuItemType } from '../shared/menu/menu-item-type.model'; import { MenuItemType } from '../shared/menu/menu-item-type.model';
import { CollectionPageResolver } from './collection-page.resolver'; import { CollectionPageResolver } from './collection-page.resolver';
import { CollectionPageAdministratorGuard } from './collection-page-administrator.guard'; import { CollectionPageAdministratorGuard } from './collection-page-administrator.guard';
import { COLLECTION_CREATE_PATH, COLLECTION_EDIT_PATH, ITEMTEMPLATE_PATH } from './collection-page-routing-paths'; import {
COLLECTION_CREATE_PATH,
COLLECTION_EDIT_PATH,
ITEMTEMPLATE_PATH,
} from './collection-page-routing-paths';
import { CreateCollectionPageComponent } from './create-collection-page/create-collection-page.component'; import { CreateCollectionPageComponent } from './create-collection-page/create-collection-page.component';
import { CreateCollectionPageGuard } from './create-collection-page/create-collection-page.guard'; import { CreateCollectionPageGuard } from './create-collection-page/create-collection-page.guard';
import { DeleteCollectionPageComponent } from './delete-collection-page/delete-collection-page.component'; import { DeleteCollectionPageComponent } from './delete-collection-page/delete-collection-page.component';
import { ItemTemplatePageResolver } from './edit-item-template-page/item-template-page.resolver'; import { ItemTemplatePageResolver } from './edit-item-template-page/item-template-page.resolver';
import { ThemedEditItemTemplatePageComponent } from './edit-item-template-page/themed-edit-item-template-page.component'; import { ThemedEditItemTemplatePageComponent } from './edit-item-template-page/themed-edit-item-template-page.component';
import { ThemedCollectionPageComponent } from './themed-collection-page.component'; import { ThemedCollectionPageComponent } from './themed-collection-page.component';
import { ComcolBrowseByComponent } from '../shared/comcol/sections/comcol-browse-by/comcol-browse-by.component';
import { BrowseByGuard } from '../browse-by/browse-by-guard';
import { BrowseByI18nBreadcrumbResolver } from '../browse-by/browse-by-i18n-breadcrumb.resolver';
import { ComcolSearchSectionComponent } from '../shared/comcol/sections/comcol-search-section/comcol-search-section.component';
@NgModule({ @NgModule({
imports: [ imports: [
@@ -82,7 +86,7 @@ import { ComcolSearchSectionComponent } from '../shared/comcol/sections/comcol-s
data: { breadcrumbKey: 'browse.metadata' }, data: { breadcrumbKey: 'browse.metadata' },
}, },
], ],
} },
], ],
data: { data: {
menu: { menu: {

View File

@@ -1,21 +1,40 @@
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import {
import { ActivatedRoute, Router } from '@angular/router'; ChangeDetectionStrategy,
Component,
OnInit,
} from '@angular/core';
import {
ActivatedRoute,
Router,
} from '@angular/router';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { filter, map, mergeMap, take } from 'rxjs/operators'; import {
filter,
map,
mergeMap,
take,
} from 'rxjs/operators';
import { AuthService } from '../core/auth/auth.service';
import { DSONameService } from '../core/breadcrumbs/dso-name.service';
import { SortOptions } from '../core/cache/models/sort-options.model'; import { SortOptions } from '../core/cache/models/sort-options.model';
import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service';
import { FeatureID } from '../core/data/feature-authorization/feature-id';
import { RemoteData } from '../core/data/remote-data'; import { RemoteData } from '../core/data/remote-data';
import { redirectOn4xx } from '../core/shared/authorized.operators'; import { redirectOn4xx } from '../core/shared/authorized.operators';
import { Bitstream } from '../core/shared/bitstream.model'; import { Bitstream } from '../core/shared/bitstream.model';
import { Collection } from '../core/shared/collection.model'; import { Collection } from '../core/shared/collection.model';
import { getAllSucceededRemoteDataPayload } from '../core/shared/operators'; import { getAllSucceededRemoteDataPayload } from '../core/shared/operators';
import { fadeIn, fadeInOut } from '../shared/animations/fade'; import {
import { hasValue, isNotEmpty } from '../shared/empty.util'; fadeIn,
fadeInOut,
} from '../shared/animations/fade';
import {
hasValue,
isNotEmpty,
} from '../shared/empty.util';
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
import { AuthService } from '../core/auth/auth.service';
import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service';
import { FeatureID } from '../core/data/feature-authorization/feature-id';
import { getCollectionPageRoute } from './collection-page-routing-paths'; import { getCollectionPageRoute } from './collection-page-routing-paths';
import { DSONameService } from '../core/breadcrumbs/dso-name.service';
@Component({ @Component({
selector: 'ds-collection-page', selector: 'ds-collection-page',

View File

@@ -1,6 +1,7 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { BrowseByPageModule } from '../browse-by/browse-by-page.module';
import { SearchService } from '../core/shared/search/search.service'; import { SearchService } from '../core/shared/search/search.service';
import { DsoSharedModule } from '../dso-shared/dso-shared.module'; import { DsoSharedModule } from '../dso-shared/dso-shared.module';
import { EditItemPageModule } from '../item-page/edit-item-page/edit-item-page.module'; import { EditItemPageModule } from '../item-page/edit-item-page/edit-item-page.module';
@@ -17,7 +18,6 @@ import { DeleteCollectionPageComponent } from './delete-collection-page/delete-c
import { EditItemTemplatePageComponent } from './edit-item-template-page/edit-item-template-page.component'; import { EditItemTemplatePageComponent } from './edit-item-template-page/edit-item-template-page.component';
import { ThemedEditItemTemplatePageComponent } from './edit-item-template-page/themed-edit-item-template-page.component'; import { ThemedEditItemTemplatePageComponent } from './edit-item-template-page/themed-edit-item-template-page.component';
import { ThemedCollectionPageComponent } from './themed-collection-page.component'; import { ThemedCollectionPageComponent } from './themed-collection-page.component';
import { BrowseByPageModule } from '../browse-by/browse-by-page.module';
const DECLARATIONS = [ const DECLARATIONS = [
CollectionPageComponent, CollectionPageComponent,

View File

@@ -1,10 +1,16 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {
ComponentFixture,
import { CollectionAccessControlComponent } from './collection-access-control.component'; TestBed,
} from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { of, of as observableOf } from 'rxjs'; import {
import { createSuccessfulRemoteDataObject } from '../../../shared/remote-data.utils'; of as observableOf,
of,
} from 'rxjs';
import { Community } from '../../../core/shared/community.model'; import { Community } from '../../../core/shared/community.model';
import { createSuccessfulRemoteDataObject } from '../../../shared/remote-data.utils';
import { CollectionAccessControlComponent } from './collection-access-control.component';
describe('CollectionAccessControlComponent', () => { describe('CollectionAccessControlComponent', () => {
let component: CollectionAccessControlComponent; let component: CollectionAccessControlComponent;
@@ -13,26 +19,26 @@ describe('CollectionAccessControlComponent', () => {
{ {
type: 'community', type: 'community',
metadata: { metadata: {
'dc.title': [{ value: 'community' }] 'dc.title': [{ value: 'community' }],
}, },
uuid: 'communityUUID', uuid: 'communityUUID',
parentCommunity: observableOf(Object.assign(createSuccessfulRemoteDataObject(undefined), { statusCode: 204 })), parentCommunity: observableOf(Object.assign(createSuccessfulRemoteDataObject(undefined), { statusCode: 204 })),
_links: { _links: {
parentCommunity: 'site', parentCommunity: 'site',
self: '/' + 'communityUUID' self: '/' + 'communityUUID',
} },
} },
); );
const routeStub = { const routeStub = {
parent: { parent: {
parent: { parent: {
data: of({ data: of({
dso: createSuccessfulRemoteDataObject(testCommunity) dso: createSuccessfulRemoteDataObject(testCommunity),
}) }),
} },
} },
}; };
beforeEach(async () => { beforeEach(async () => {

View File

@@ -1,6 +1,10 @@
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import {
ComponentFixture,
TestBed,
waitForAsync,
} from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';

View File

@@ -1,22 +1,40 @@
import { Component, Input, OnDestroy, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http';
import {
Component,
Input,
OnDestroy,
OnInit,
} from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import {
BehaviorSubject,
Observable,
Subscription,
} from 'rxjs';
import {
filter,
map,
switchMap,
tap,
} from 'rxjs/operators';
import { BitstreamDataService } from '../../../../core/data/bitstream-data.service';
import { CollectionDataService } from '../../../../core/data/collection-data.service';
import { ProcessDataService } from '../../../../core/data/processes/process-data.service';
import { ScriptDataService } from '../../../../core/data/processes/script-data.service'; import { ScriptDataService } from '../../../../core/data/processes/script-data.service';
import { RequestService } from '../../../../core/data/request.service'; import { RequestService } from '../../../../core/data/request.service';
import { Collection } from '../../../../core/shared/collection.model'; import { Collection } from '../../../../core/shared/collection.model';
import { ContentSource } from '../../../../core/shared/content-source.model'; import { ContentSource } from '../../../../core/shared/content-source.model';
import { ContentSourceSetSerializer } from '../../../../core/shared/content-source-set-serializer'; import { ContentSourceSetSerializer } from '../../../../core/shared/content-source-set-serializer';
import { getAllSucceededRemoteDataPayload, getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../../../core/shared/operators'; import {
import { filter, map, switchMap, tap } from 'rxjs/operators'; getAllSucceededRemoteDataPayload,
import { hasValue } from '../../../../shared/empty.util'; getFirstCompletedRemoteData,
getFirstSucceededRemoteDataPayload,
} from '../../../../core/shared/operators';
import { Process } from '../../../../process-page/processes/process.model'; import { Process } from '../../../../process-page/processes/process.model';
import { ProcessStatus } from '../../../../process-page/processes/process-status.model'; import { ProcessStatus } from '../../../../process-page/processes/process-status.model';
import { hasValue } from '../../../../shared/empty.util';
import { NotificationsService } from '../../../../shared/notifications/notifications.service'; import { NotificationsService } from '../../../../shared/notifications/notifications.service';
import { HttpClient } from '@angular/common/http';
import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
import { BitstreamDataService } from '../../../../core/data/bitstream-data.service';
import { CollectionDataService } from '../../../../core/data/collection-data.service';
import { ProcessDataService } from '../../../../core/data/processes/process-data.service';
/** /**
* Component that contains the controls to run, reset and test the harvest * Component that contains the controls to run, reset and test the harvest
@@ -96,7 +114,7 @@ export class CollectionSourceControlsComponent implements OnInit, OnDestroy {
this.autoRefreshIDs.push(rd.payload.processId); this.autoRefreshIDs.push(rd.payload.processId);
return this.processDataService.autoRefreshUntilCompletion(rd.payload.processId); return this.processDataService.autoRefreshUntilCompletion(rd.payload.processId);
}), }),
map((rd) => rd.payload) map((rd) => rd.payload),
).subscribe((process: Process) => { ).subscribe((process: Process) => {
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) { if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) {
this.notificationsService.error(this.translateService.get('collection.source.controls.test.failed')); this.notificationsService.error(this.translateService.get('collection.source.controls.test.failed'));
@@ -140,7 +158,7 @@ export class CollectionSourceControlsComponent implements OnInit, OnDestroy {
this.autoRefreshIDs.push(rd.payload.processId); this.autoRefreshIDs.push(rd.payload.processId);
return this.processDataService.autoRefreshUntilCompletion(rd.payload.processId); return this.processDataService.autoRefreshUntilCompletion(rd.payload.processId);
}), }),
map((rd) => rd.payload) map((rd) => rd.payload),
).subscribe((process) => { ).subscribe((process) => {
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) { if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) {
this.notificationsService.error(this.translateService.get('collection.source.controls.import.failed')); this.notificationsService.error(this.translateService.get('collection.source.controls.import.failed'));
@@ -178,7 +196,7 @@ export class CollectionSourceControlsComponent implements OnInit, OnDestroy {
this.autoRefreshIDs.push(rd.payload.processId); this.autoRefreshIDs.push(rd.payload.processId);
return this.processDataService.autoRefreshUntilCompletion(rd.payload.processId); return this.processDataService.autoRefreshUntilCompletion(rd.payload.processId);
}), }),
map((rd) => rd.payload) map((rd) => rd.payload),
).subscribe((process) => { ).subscribe((process) => {
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) { if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) {
this.notificationsService.error(this.translateService.get('collection.source.controls.reset.failed')); this.notificationsService.error(this.translateService.get('collection.source.controls.reset.failed'));

View File

@@ -1,8 +1,23 @@
import { CdkTreeModule } from '@angular/cdk/tree'; import { CdkTreeModule } from '@angular/cdk/tree';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import {
import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; CUSTOM_ELEMENTS_SCHEMA,
import { CUSTOM_ELEMENTS_SCHEMA, DebugElement } from '@angular/core'; DebugElement,
} from '@angular/core';
import {
ComponentFixture,
fakeAsync,
inject,
TestBed,
tick,
waitForAsync,
} from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { RouterLinkWithHref } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import {
TranslateLoader,
TranslateModule,
} from '@ngx-translate/core';
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
@@ -10,14 +25,19 @@ import { buildPaginatedList } from '../../core/data/paginated-list.model';
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 { PageInfo } from '../../core/shared/page-info.model'; import { PageInfo } from '../../core/shared/page-info.model';
import { isEmpty, isNotEmpty } from '../../shared/empty.util'; import {
isEmpty,
isNotEmpty,
} from '../../shared/empty.util';
import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import { CommunityListService, showMoreFlatNode, toFlatNode } from '../community-list-service'; import {
CommunityListService,
showMoreFlatNode,
toFlatNode,
} from '../community-list-service';
import { FlatNode } from '../flat-node.model'; import { FlatNode } from '../flat-node.model';
import { CommunityListComponent } from './community-list.component'; import { CommunityListComponent } from './community-list.component';
import { ComponentFixture, fakeAsync, inject, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { RouterLinkWithHref } from '@angular/router';
describe('CommunityListComponent', () => { describe('CommunityListComponent', () => {
let component: CommunityListComponent; let component: CommunityListComponent;

View File

@@ -1,9 +1,16 @@
import { FlatTreeControl } from '@angular/cdk/tree'; import { FlatTreeControl } from '@angular/cdk/tree';
import { Component, OnDestroy, OnInit } from '@angular/core'; import {
Component,
OnDestroy,
OnInit,
} from '@angular/core';
import { take } from 'rxjs/operators'; import { take } from 'rxjs/operators';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import {
SortDirection,
SortOptions,
} from '../../core/cache/models/sort-options.model';
import { FindListOptions } from '../../core/data/find-list-options.model'; import { FindListOptions } from '../../core/data/find-list-options.model';
import { isEmpty } from '../../shared/empty.util'; import { isEmpty } from '../../shared/empty.util';
import { CommunityListDatasource } from '../community-list-datasource'; import { CommunityListDatasource } from '../community-list-datasource';

Some files were not shown because too many files have changed in this diff Show More