Several fixes after merge with main

This commit is contained in:
Giuseppe Digilio
2020-12-04 14:16:40 +01:00
parent 948e002225
commit 84840678d2
35 changed files with 136 additions and 151 deletions

View File

@@ -133,7 +133,7 @@ export function app() {
windowMs: (environment.ui as UIServerConfig).rateLimiter.windowMs,
max: (environment.ui as UIServerConfig).rateLimiter.max
});
app.use(limiter);
server.use(limiter);
}
/*

View File

@@ -1,7 +1,7 @@
import { CommonModule } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { ActivatedRoute, Router } from '@angular/router';
@@ -52,7 +52,7 @@ describe('GroupFormComponent', () => {
let groupDescription;
let expected;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
groups = [GroupMock, GroupMock2];
groupName = 'testGroupName';
groupDescription = 'testDescription';
@@ -103,7 +103,7 @@ describe('GroupFormComponent', () => {
findByHref(href: string): Observable<RemoteData<DSpaceObject>> {
return null;
}
}
};
builderService = getMockFormBuilderService();
translateService = getMockTranslateService();
router = new RouterMock();
@@ -145,10 +145,6 @@ describe('GroupFormComponent', () => {
fixture.detectChanges();
});
it('should create GroupFormComponent', inject([GroupFormComponent], (comp: GroupFormComponent) => {
expect(comp).toBeDefined();
}));
describe('when submitting the form', () => {
beforeEach(() => {
spyOn(component.submitForm, 'emit');
@@ -161,7 +157,7 @@ describe('GroupFormComponent', () => {
fixture.detectChanges();
});
it('should emit a new group using the correct values', async(() => {
it('should emit a new group using the correct values', waitForAsync(() => {
fixture.whenStable().then(() => {
expect(component.submitForm.emit).toHaveBeenCalledWith(expected);
});
@@ -176,8 +172,9 @@ describe('GroupFormComponent', () => {
fixture.detectChanges();
});
it('should emit the existing group using the correct new values', async(() => {
it('should emit the existing group using the correct new values', waitForAsync(() => {
const expected2 = Object.assign(new Group(), {
id: undefined,
name: 'newGroupName',
metadata: {
'dc.description': [
@@ -186,6 +183,7 @@ describe('GroupFormComponent', () => {
}
],
},
_links: undefined
});
fixture.whenStable().then(() => {
expect(component.submitForm.emit).toHaveBeenCalledWith(expected2);
@@ -193,7 +191,7 @@ describe('GroupFormComponent', () => {
}));
it('should emit success notification', () => {
expect(notificationService.success).toHaveBeenCalled();
})
});
});
});

View File

@@ -136,12 +136,13 @@ export class GroupFormComponent implements OnInit, OnDestroy {
}));
this.canEdit$ = this.groupDataService.getActiveGroup().pipe(
switchMap((group: Group) => {
console.log(group);
return observableCombineLatest(
this.authorizationService.isAuthorized(FeatureID.CanDelete, hasValue(group) ? group.self : undefined),
this.authorizationService.isAuthorized(FeatureID.CanDelete, isNotEmpty(group) ? group.self : undefined),
this.hasLinkedDSO(group),
(isAuthorized: ObservedValueOf<Observable<boolean>>, hasLinkedDSO: ObservedValueOf<Observable<boolean>>) => {
return isAuthorized && !hasLinkedDSO;
})
});
})
);
observableCombineLatest(
@@ -360,11 +361,11 @@ export class GroupFormComponent implements OnInit, OnDestroy {
this.translateService.get(this.messagePrefix + '.notification.deleted.failure.title', { name: group.name }),
this.translateService.get(this.messagePrefix + '.notification.deleted.failure.content', { cause: optionalErrorMessage }));
}
})
});
}
}
});
})
});
}
/**
@@ -397,7 +398,7 @@ export class GroupFormComponent implements OnInit, OnDestroy {
if (hasValue(rd) && hasValue(rd.payload)) {
return true;
} else {
return false
return false;
}
}),
catchError(() => observableOf(false)),
@@ -427,7 +428,7 @@ export class GroupFormComponent implements OnInit, OnDestroy {
return this.getLinkedDSO(group).pipe(
map((rd: RemoteData<DSpaceObject>) => {
if (hasValue(rd) && hasValue(rd.payload)) {
const dso = rd.payload
const dso = rd.payload;
switch ((dso as any).type) {
case Community.type.value:
return getCommunityEditRolesRoute(rd.payload.id);
@@ -436,7 +437,7 @@ export class GroupFormComponent implements OnInit, OnDestroy {
}
}
})
)
);
}
}
}

View File

@@ -87,7 +87,7 @@ describe('GroupRegistryComponent', () => {
findByHref(href: string): Observable<RemoteData<DSpaceObject>> {
return createSuccessfulRemoteDataObject$(undefined);
}
}
};
authorizationService = jasmine.createSpyObj('authorizationService', {
isAuthorized: observableOf(true)
});

View File

@@ -2,9 +2,8 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject, combineLatest as observableCombineLatest, Subscription, Observable, of as observableOf } from 'rxjs';
import { filter } from 'rxjs/internal/operators/filter';
import { ObservedValueOf } from 'rxjs/internal/types';
import { BehaviorSubject, combineLatest as observableCombineLatest, Subscription, Observable, ObservedValueOf, of as observableOf } from 'rxjs';
import { filter } from 'rxjs/operators';
import { catchError, map, switchMap, take } from 'rxjs/operators';
import { DSpaceObjectDataService } from '../../../core/data/dspace-object-data.service';
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
@@ -134,10 +133,10 @@ export class GroupsRegistryComponent implements OnInit, OnDestroy {
groupDtoModel.group = group;
return groupDtoModel;
}
)
);
})).pipe(map((dtos: GroupDtoModel[]) => {
return new PaginatedList(groups.pageInfo, dtos);
}))
}));
})).subscribe((value: PaginatedList<GroupDtoModel>) => {
this.groupsDto$.next(value);
this.pageInfoState$.next(value.pageInfo);
@@ -199,13 +198,7 @@ export class GroupsRegistryComponent implements OnInit, OnDestroy {
*/
hasLinkedDSO(group: Group): Observable<boolean> {
return this.dSpaceObjectDataService.findByHref(group._links.object.href).pipe(
map((rd: RemoteData<DSpaceObject>) => {
if (hasValue(rd) && hasValue(rd.payload)) {
return true;
} else {
return false
}
}),
map((rd: RemoteData<DSpaceObject>) => hasValue(rd) && hasValue(rd.payload)),
catchError(() => observableOf(false)),
);
}

View File

@@ -21,7 +21,7 @@ export function getCollectionCreateRoute() {
}
export function getCollectionEditRolesRoute(id) {
return new URLCombiner(getCollectionPageRoute(id), COLLECTION_EDIT_PATH, COLLECTION_EDIT_ROLES_PATH).toString()
return new URLCombiner(getCollectionPageRoute(id), COLLECTION_EDIT_PATH, COLLECTION_EDIT_ROLES_PATH).toString();
}
export const COLLECTION_CREATE_PATH = 'create';

View File

@@ -22,7 +22,7 @@ export function getCommunityCreateRoute() {
}
export function getCommunityEditRolesRoute(id) {
return new URLCombiner(getCollectionPageRoute(id), COMMUNITY_EDIT_PATH, COMMUNITY_EDIT_ROLES_PATH).toString()
return new URLCombiner(getCollectionPageRoute(id), COMMUNITY_EDIT_PATH, COMMUNITY_EDIT_ROLES_PATH).toString();
}
export const COMMUNITY_CREATE_PATH = 'create';

View File

@@ -3,11 +3,15 @@ import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { LinkService } from '../../../../core/cache/builders/link.service';
import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions';
import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service';
import { combineLatest as observableCombineLatest, Observable } from 'rxjs';
import { FieldUpdate, FieldUpdates, RelationshipIdentifiable } from '../../../../core/data/object-updates/object-updates.reducer';
import { combineLatest as observableCombineLatest, Observable, of } from 'rxjs';
import {
FieldUpdate,
FieldUpdates,
RelationshipIdentifiable
} from '../../../../core/data/object-updates/object-updates.reducer';
import { RelationshipService } from '../../../../core/data/relationship.service';
import { Item } from '../../../../core/shared/item.model';
import { map, switchMap } from 'rxjs/operators';
import { defaultIfEmpty, filter, map, mergeMap, switchMap, take, tap } from 'rxjs/operators';
import { hasValue } from '../../../../shared/empty.util';
import { Relationship } from '../../../../core/shared/item-relationships/relationship.model';
import { RelationshipType } from '../../../../core/shared/item-relationships/relationship-type.model';
@@ -92,9 +96,9 @@ export class EditRelationshipListComponent implements OnInit {
if (hasValue(label) && label.indexOf('is') > -1 && label.indexOf('Of') > -1) {
const relationshipLabel = `${label.substring(2, label.indexOf('Of'))}`;
if (relationshipLabel !== relatedEntityType.label) {
return `relationships.is${relationshipLabel}Of.${relatedEntityType.label}`
return `relationships.is${relationshipLabel}Of.${relatedEntityType.label}`;
} else {
return `relationships.is${relationshipLabel}Of`
return `relationships.is${relationshipLabel}Of`;
}
} else {
return label;
@@ -140,7 +144,7 @@ export class EditRelationshipListComponent implements OnInit {
modalComp.repeatable = true;
modalComp.listId = this.listId;
modalComp.item = this.item;
modalComp.select = (...selectableObjects: Array<SearchResult<Item>>) => {
modalComp.select = (...selectableObjects: SearchResult<Item>[]) => {
selectableObjects.forEach((searchResult) => {
const relatedItem: Item = searchResult.indexableObject;
this.getFieldUpdatesForRelatedItem(relatedItem)
@@ -158,12 +162,12 @@ export class EditRelationshipListComponent implements OnInit {
relatedItem,
} as RelationshipIdentifiable;
this.objectUpdatesService.saveAddFieldUpdate(this.url, update);
})
});
}
});
})
});
};
modalComp.deselect = (...selectableObjects: Array<SearchResult<Item>>) => {
modalComp.deselect = (...selectableObjects: SearchResult<Item>[]) => {
selectableObjects.forEach((searchResult) => {
const relatedItem: Item = searchResult.indexableObject;
this.objectUpdatesService.removeSingleFieldUpdate(this.url, this.relationshipType.id + '-' + relatedItem.uuid);
@@ -173,7 +177,7 @@ export class EditRelationshipListComponent implements OnInit {
this.objectUpdatesService.saveRemoveFieldUpdate(this.url, identifiable)
)
);
})
});
};
this.relatedEntityType$
.pipe(take(1))
@@ -229,7 +233,7 @@ export class EditRelationshipListComponent implements OnInit {
.map((update) => update.field as RelationshipIdentifiable)
.filter((field) => field.relationship)
),
flatMap((identifiables) =>
mergeMap((identifiables) =>
observableCombineLatest(
identifiables.map((identifiable) => this.getRelatedItem(identifiable.relationship))
).pipe(
@@ -251,7 +255,7 @@ export class EditRelationshipListComponent implements OnInit {
switchMap((isLeftItem) => isLeftItem ? relationship.rightItem : relationship.leftItem),
getSucceededRemoteData(),
getRemoteDataPayload(),
)
);
}
ngOnInit(): void {
@@ -287,7 +291,7 @@ export class EditRelationshipListComponent implements OnInit {
type: this.relationshipType,
relationship,
nameVariant,
} as RelationshipIdentifiable
} as RelationshipIdentifiable;
})),
)),
switchMap((initialFields) => this.objectUpdatesService.getFieldUpdates(this.url, initialFields).pipe(

View File

@@ -6,7 +6,6 @@ import { Item } from '../core/shared/item.model';
import { DsoPageFeatureGuard } from '../core/data/feature-authorization/feature-authorization-guard/dso-page-feature.guard';
import { Observable, of as observableOf } from 'rxjs';
import { FeatureID } from '../core/data/feature-authorization/feature-id';
import { of as observableOf } from 'rxjs';
import { AuthService } from '../core/auth/auth.service';
@Injectable({

View File

@@ -5,16 +5,6 @@ import { AuthBlockingGuard } from './core/auth/auth-blocking.guard';
import { PageNotFoundComponent } from './pagenotfound/pagenotfound.component';
import { AuthenticatedGuard } from './core/auth/authenticated.guard';
import { SiteAdministratorGuard } from './core/data/feature-authorization/feature-authorization-guard/site-administrator.guard';
import {
ADMIN_MODULE_PATH,
BITSTREAM_MODULE_PATH,
FORBIDDEN_PATH
FORGOT_PASSWORD_PATH,
INFO_MODULE_PATH,
PROFILE_MODULE_PATH,
REGISTER_PATH,
WORKFLOW_ITEM_MODULE_PATH
} from './app-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 { ITEM_MODULE_PATH } from './+item-page/item-page-routing-paths';
@@ -22,6 +12,16 @@ import { ReloadGuard } from './core/reload/reload.guard';
import { EndUserAgreementCurrentUserGuard } from './core/end-user-agreement/end-user-agreement-current-user.guard';
import { SiteRegisterGuard } from './core/data/feature-authorization/feature-authorization-guard/site-register.guard';
import { ForbiddenComponent } from './forbidden/forbidden.component';
import {
ADMIN_MODULE_PATH,
BITSTREAM_MODULE_PATH,
FORBIDDEN_PATH,
FORGOT_PASSWORD_PATH,
INFO_MODULE_PATH,
PROFILE_MODULE_PATH,
REGISTER_PATH,
WORKFLOW_ITEM_MODULE_PATH
} from './app-routing-paths';
@NgModule({
imports: [

View File

@@ -1,8 +1,9 @@
import { Injectable } from '@angular/core';
import { createSelector, Store } from '@ngrx/store';
import { combineLatest as observableCombineLatest } from 'rxjs/internal/observable/combineLatest';
import { Observable, of as observableOf } from 'rxjs';
import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { AppState } from '../app.reducer';
import { CommunityDataService } from '../core/data/community-data.service';
import { FindListOptions } from '../core/data/request.models';
@@ -149,7 +150,7 @@ export class CommunityListService {
})
);
return topComs$.pipe(switchMap((topComs: PaginatedList<Community>) => this.transformListOfCommunities(topComs, 0, null, expandedNodes)));
};
}
/**
* Puts the initial top level communities in a list to be called upon
@@ -304,13 +305,7 @@ export class CommunityListService {
let hasChildren$: Observable<boolean>;
hasChildren$ = observableCombineLatest(hasSubcoms$, hasColls$).pipe(
map(([hasSubcoms, hasColls]: [boolean, boolean]) => {
if (hasSubcoms || hasColls) {
return true;
} else {
return false;
}
})
map(([hasSubcoms, hasColls]: [boolean, boolean]) => hasSubcoms || hasColls)
);
return hasChildren$;

View File

@@ -10,14 +10,13 @@ import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
import { Community } from '../shared/community.model';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { Item } from '../shared/item.model';
import { ComColDataService } from './comcol-data.service';
import { CommunityDataService } from './community-data.service';
import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
import { FindByIDRequest, FindListOptions } from './request.models';
import { RequestEntry } from './request.reducer';
import { RequestService } from './request.service';
import {createNoContentRemoteDataObject$, createSuccessfulRemoteDataObject$} from '../../shared/remote-data.utils';
import { createNoContentRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
const LINK_NAME = 'test';
@@ -192,7 +191,7 @@ describe('ComColDataService', () => {
};
service = initTestService();
})
});
describe('cache refreshed top level community', () => {
beforeEach(() => {
spyOn(rdbService, 'buildSingle').and.returnValue(createNoContentRemoteDataObject$());

View File

@@ -1,10 +1,10 @@
import { distinctUntilChanged, filter, map, mergeMap, share, switchMap, take, tap } from 'rxjs/operators';
import {
distinctUntilChanged,
filter, first,map, mergeMap, share, switchMap,
take,
tap
} from 'rxjs/operators';
import { merge as observableMerge, Observable, throwError as observableThrowError, combineLatest as observableCombineLatest } from 'rxjs';
combineLatest as observableCombineLatest,
merge as observableMerge,
Observable,
throwError as observableThrowError
} from 'rxjs';
import { hasValue, isEmpty, isNotEmpty } from '../../shared/empty.util';
import { ObjectCacheService } from '../cache/object-cache.service';
import { Community } from '../shared/community.model';
@@ -13,7 +13,7 @@ import { HALResource } from '../shared/hal-resource.model';
import { CommunityDataService } from './community-data.service';
import { DataService } from './data.service';
import { DeleteRequest, FindListOptions, FindByIDRequest, RestRequest } from './request.models';
import { DeleteRequest, FindByIDRequest, FindListOptions, RestRequest } from './request.models';
import { PaginatedList } from './paginated-list';
import { RemoteData } from './remote-data';
import { HALEndpointService } from '../shared/hal-endpoint.service';
@@ -28,7 +28,7 @@ import { CacheableObject } from '../cache/object-cache.reducer';
import { RestResponse } from '../cache/response.models';
import { Bitstream } from '../shared/bitstream.model';
import { DSpaceObject } from '../shared/dspace-object.model';
import {Collection} from '../shared/collection.model';
import { Collection } from '../shared/collection.model';
export abstract class ComColDataService<T extends CacheableObject> extends DataService<T> {
protected abstract cds: CommunityDataService;
@@ -132,7 +132,7 @@ export abstract class ComColDataService<T extends CacheableObject> extends DataS
take(1),
).subscribe((rd: RemoteData<any>) => {
const href = rd.hasSucceeded && !isEmpty(rd.payload.id) ? rd.payload.id : this.halService.getEndpoint('communities/search/top');
this.requestService.removeByHrefSubstring(href)
this.requestService.removeByHrefSubstring(href);
});
}

View File

@@ -6,7 +6,6 @@ import { createSuccessfulRemoteDataObject$ } from '../../../../shared/remote-dat
import { DSpaceObject } from '../../../shared/dspace-object.model';
import { DsoPageFeatureGuard } from './dso-page-feature.guard';
import { FeatureID } from '../feature-id';
import { Observable } from 'rxjs/internal/Observable';
import { AuthService } from '../../../auth/auth.service';
/**

View File

@@ -77,7 +77,7 @@ export interface VirtualMetadataSource {
}
export interface RelationshipIdentifiable extends Identifiable {
nameVariant?: string,
nameVariant?: string;
relatedItem: Item;
relationship: Relationship;
type: RelationshipType;

View File

@@ -25,7 +25,7 @@ export class ServerResponseService {
}
setForbidden(message = 'Forbidden'): this {
return this.setStatus(403, message)
return this.setStatus(403, message);
}
setNotFound(message = 'Not found'): this {

View File

@@ -8,7 +8,7 @@ describe('Collection', () => {
beforeEach(() => {
metadataValue = {'dc.identifier.uri': [ { value: '123456789/1'}]};
})
});
it('should return the handle value from metadata', () => {
const community = Object.assign(new Collection(), { metadata: metadataValue });

View File

@@ -8,7 +8,7 @@ describe('Community', () => {
beforeEach(() => {
metadataValue = {'dc.identifier.uri': [ { value: '123456789/1'}]};
})
});
it('should return the handle value from metadata', () => {
const community = Object.assign(new Community(), { metadata: metadataValue });

View File

@@ -45,7 +45,7 @@ describe('ProcessDetailComponent', () => {
let processOutput;
function init() {
processOutput = 'Process Started'
processOutput = 'Process Started';
process = Object.assign(new Process(), {
processId: 1,
scriptName: 'script-name',

View File

@@ -81,7 +81,7 @@ export class ProcessDetailComponent implements OnInit {
this.retrievingOutputLogs$ = new BehaviorSubject<boolean>(false);
this.processRD$ = this.route.data.pipe(
map((data) => {
return data.process as RemoteData<Process>
return data.process as RemoteData<Process>;
}),
redirectOn4xx(this.router, this.authService)
);
@@ -128,7 +128,7 @@ export class ProcessDetailComponent implements OnInit {
return hasValue(token) ? new URLCombiner(url, `?authentication-token=${token}`).toString() : url;
}));
})
)
);
});
this.outputLogs$ = this.outputLogFileUrl$.pipe(take(1),
mergeMap((url: string) => {

View File

@@ -2,7 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CommunityDataService } from '../../../core/data/community-data.service';
import { RouteService } from '../../../core/services/route.service';
import { Router } from '@angular/router';
import {TranslateModule, TranslateService} from '@ngx-translate/core';
import { TranslateModule } from '@ngx-translate/core';
import { of as observableOf } from 'rxjs';
import { Community } from '../../../core/shared/community.model';
import { SharedModule } from '../../shared.module';
@@ -11,15 +11,12 @@ import { RouterTestingModule } from '@angular/router/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { CreateComColPageComponent } from './create-comcol-page.component';
import {
createFailedRemoteDataObject$, createNoContentRemoteDataObject$,
createSuccessfulRemoteDataObject$
} from '../../remote-data.utils';
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../remote-data.utils';
import { ComColDataService } from '../../../core/data/comcol-data.service';
import { NotificationsService } from '../../notifications/notifications.service';
import { NotificationsServiceStub } from '../../testing/notifications-service.stub';
import { RequestService } from '../../../core/data/request.service';
import {getTestScheduler} from 'jasmine-marbles';
import { getTestScheduler } from 'jasmine-marbles';
describe('CreateComColPageComponent', () => {
let comp: CreateComColPageComponent<DSpaceObject>;
@@ -80,7 +77,7 @@ describe('CreateComColPageComponent', () => {
create: (com, uuid?) => createSuccessfulRemoteDataObject$(newCommunity),
getLogoEndpoint: () => observableOf(logoEndpoint),
findByHref: () => null,
refreshCache: () => {return}
refreshCache: () => {return;}
};
routeServiceStub = {
@@ -151,7 +148,7 @@ describe('CreateComColPageComponent', () => {
it('should navigate and refresh cache when successful', () => {
spyOn(router, 'navigate');
spyOn((dsoDataService as any), 'refreshCache')
spyOn((dsoDataService as any), 'refreshCache');
scheduler.schedule(() => comp.onSubmit(data));
scheduler.flush();
expect(router.navigate).toHaveBeenCalled();
@@ -161,7 +158,7 @@ describe('CreateComColPageComponent', () => {
it('should neither navigate nor refresh cache on failure', () => {
spyOn(router, 'navigate');
spyOn(dsoDataService, 'create').and.returnValue(createFailedRemoteDataObject$(newCommunity));
spyOn(dsoDataService, 'refreshCache')
spyOn(dsoDataService, 'refreshCache');
scheduler.schedule(() => comp.onSubmit(data));
scheduler.flush();
expect(router.navigate).not.toHaveBeenCalled();

View File

@@ -2,21 +2,19 @@ import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs';
import {flatMap, take} from 'rxjs/operators';
import { mergeMap, take } from 'rxjs/operators';
import { ComColDataService } from '../../../core/data/comcol-data.service';
import { CommunityDataService } from '../../../core/data/community-data.service';
import { RemoteData } from '../../../core/data/remote-data';
import { RouteService } from '../../../core/services/route.service';
import { Community } from '../../../core/shared/community.model';
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import {
getFirstSucceededRemoteDataPayload,
} from '../../../core/shared/operators';
import { getFirstSucceededRemoteDataPayload, } from '../../../core/shared/operators';
import { ResourceType } from '../../../core/shared/resource-type';
import {hasValue, isNotEmpty, isNotUndefined} from '../../empty.util';
import { hasValue, isNotEmpty, isNotUndefined } from '../../empty.util';
import { NotificationsService } from '../../notifications/notifications.service';
import { RequestParam } from '../../../core/cache/models/request-param.model';
import {RequestService} from '../../../core/data/request.service';
import { RequestService } from '../../../core/data/request.service';
/**
* Component representing the create page for communities and collections
@@ -82,11 +80,11 @@ export class CreateComColPageComponent<TDomain extends DSpaceObject> implements
this.parentUUID$.pipe(
take(1),
flatMap((uuid: string) => {
mergeMap((uuid: string) => {
const params = uuid ? [new RequestParam('parent', uuid)] : [];
return this.dsoDataService.create(dso, ...params)
.pipe(getFirstSucceededRemoteDataPayload()
)
);
}))
.subscribe((dsoRD: TDomain) => {
if (isNotUndefined(dsoRD)) {

View File

@@ -1,6 +1,6 @@
<a *ngIf="isAuthorized$ | async"
[routerLink]="['/' + pageRoutePrefix, dso.id, 'edit']"
class="edit-button btn btn-dark text-light btn-sm"
[tooltip]="tooltipMsg | translate">
[ngbTooltip]="tooltipMsg | translate">
<i class="fas fa-pencil-alt fa-fw"></i>
</a>

View File

@@ -8,7 +8,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { RouterTestingModule } from '@angular/router/testing';
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
import { By } from '@angular/platform-browser';
import { TooltipModule } from 'ngx-bootstrap';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
describe('DsoPageEditButtonComponent', () => {
let component: DsoPageEditButtonComponent;
@@ -29,7 +29,7 @@ describe('DsoPageEditButtonComponent', () => {
});
TestBed.configureTestingModule({
declarations: [ DsoPageEditButtonComponent ],
imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), TooltipModule.forRoot()],
imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), NgbModule],
providers: [
{ provide: AuthorizationDataService, useValue: authorizationService }
]

View File

@@ -42,7 +42,7 @@ describe('DSOSelectorComponent', () => {
return createSuccessfulRemoteDataObject$(createPaginatedList(nextPageResults));
}
}
}
};
function createSearchResult(name: string): ItemSearchResult {
return Object.assign(new ItemSearchResult(), {
@@ -56,7 +56,7 @@ describe('DSOSelectorComponent', () => {
]
}
})
})
});
}
beforeEach(async(() => {

View File

@@ -10,7 +10,16 @@ import {
ViewChildren
} from '@angular/core';
import { FormControl } from '@angular/forms';
import {
BehaviorSubject,
combineLatest as observableCombineLatest,
Observable,
of as observableOf,
Subscription
} from 'rxjs';
import { debounceTime, map, startWith, switchMap, tap } from 'rxjs/operators';
import { SearchService } from '../../../core/shared/search/search.service';
import { CollectionElementLinkType } from '../../object-collection/collection-element-link.type';
import { PaginatedSearchOptions } from '../../search/paginated-search-options.model';
@@ -18,12 +27,8 @@ import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model'
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { ViewMode } from '../../../core/shared/view-mode.model';
import { Context } from '../../../core/shared/context.model';
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
import { getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators';
import { Subscription } from 'rxjs/internal/Subscription';
import { hasValue, isEmpty, isNotEmpty } from '../../empty.util';
import { combineLatest as observableCombineLatest, of as observableOf } from 'rxjs';
import { Observable } from 'rxjs/internal/Observable';
import { PaginatedList } from '../../../core/data/paginated-list';
import { SearchResult } from '../../search/search-result.model';
@@ -73,7 +78,7 @@ export class DSOSelectorComponent implements OnInit, OnDestroy {
/**
* List with search results of DSpace objects for the current query
*/
listEntries: Array<SearchResult<DSpaceObject>> = [];
listEntries: SearchResult<DSpaceObject>[] = [];
/**
* The current page to load
@@ -110,7 +115,7 @@ export class DSOSelectorComponent implements OnInit, OnDestroy {
/**
* Track whether the element has the mouse over it
*/
isMouseOver = false
isMouseOver = false;
/**
* Array to track all subscriptions and unsubscribe them onDestroy

View File

@@ -25,6 +25,7 @@ export class CollectionGridElementComponent extends AbstractListableElementCompo
super();
}
// @ts-ignore
@Input() set object(object: Collection) {
this._object = object;
if (hasValue(this._object) && hasNoValue(this._object.logo)) {

View File

@@ -24,10 +24,11 @@ export class CommunityGridElementComponent extends AbstractListableElementCompon
super();
}
// @ts-ignore
@Input() set object(object: Community) {
this._object = object;
if (hasValue(this._object) && hasNoValue(this._object.logo)) {
this.linkService.resolveLink<Community>(this._object, followLink('logo'))
this.linkService.resolveLink<Community>(this._object, followLink('logo'));
}
}

View File

@@ -30,6 +30,7 @@ export class CollectionSearchResultGridElementComponent extends SearchResultGrid
super(truncatableService, bitstreamDataService);
}
// @ts-ignore
@Input() set dso(dso: Collection) {
this._dso = dso;
if (hasValue(this._dso) && hasNoValue(this._dso.logo)) {

View File

@@ -33,6 +33,7 @@ export class CommunitySearchResultGridElementComponent extends SearchResultGridE
super(truncatableService, bitstreamDataService);
}
// @ts-ignore
@Input() set dso(dso: Community) {
this._dso = dso;
if (hasValue(this._dso) && hasNoValue(this._dso.logo)) {

View File

@@ -15,7 +15,6 @@ import { getFirstSucceededRemoteDataPayload } from '../../../core/shared/operato
selector: 'ds-search-result-grid-element',
template: ``
})
export class SearchResultGridElementComponent<T extends SearchResult<K>, K extends DSpaceObject> extends AbstractListableElementComponent<T> implements OnInit {
/**
* The DSpaceObject of the search result

View File

@@ -1,4 +1,4 @@
<ng-container *ngIf="item" @fadeInOut>
<div *ngIf="item" @fadeInOut>
<ng-container *ngIf="status">
<ds-mydspace-item-status [status]="status"></ds-mydspace-item-status>
</ng-container>
@@ -30,4 +30,4 @@
</div>
</ds-truncatable>
<ds-item-submitter *ngIf="showSubmitter" [object]="object.indexableObject"></ds-item-submitter>
</ng-container>
</div>

View File

@@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser';
@@ -9,6 +9,7 @@ import { Item } from '../../../../core/shared/item.model';
import { ItemListPreviewComponent } from './item-list-preview.component';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateLoaderMock } from '../../../mocks/translate-loader.mock';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
let component: ItemListPreviewComponent;
let fixture: ComponentFixture<ItemListPreviewComponent>;
@@ -66,7 +67,7 @@ const mockItemWithEntityType: Item = Object.assign(new Item(), {
});
describe('ItemListPreviewComponent', () => {
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot({
@@ -75,6 +76,7 @@ describe('ItemListPreviewComponent', () => {
useClass: TranslateLoaderMock
}
}),
NoopAnimationsModule
],
declarations: [ItemListPreviewComponent, TruncatePipe],
providers: [
@@ -88,7 +90,7 @@ describe('ItemListPreviewComponent', () => {
}).compileComponents();
}));
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
fixture = TestBed.createComponent(ItemListPreviewComponent);
component = fixture.componentInstance;

View File

@@ -425,22 +425,10 @@ const COMPONENTS = [
BundleListElementComponent,
StartsWithDateComponent,
StartsWithTextComponent,
ItemVersionsNoticeComponent,
ClaimedTaskActionsApproveComponent,
ClaimedTaskActionsRejectComponent,
ClaimedTaskActionsReturnToPoolComponent,
ClaimedTaskActionsEditMetadataComponent,
CollectionDropdownComponent,
FileDownloadLinkComponent,
CurationFormComponent,
ExportMetadataSelectorComponent,
ConfirmationModalComponent,
VocabularyTreeviewComponent,
SidebarSearchListElementComponent,
PublicationSidebarSearchListElementComponent,
CollectionSidebarSearchListElementComponent,
CommunitySidebarSearchListElementComponent,
AuthorizedCollectionSelectorComponent,
];
const SHARED_ITEM_PAGE_COMPONENTS = [
@@ -501,8 +489,7 @@ const DIRECTIVES = [
...COMPONENTS,
...SHARED_ITEM_PAGE_COMPONENTS,
...DIRECTIVES,
TranslateModule,
CurationFormComponent
TranslateModule
]
})

View File

@@ -2919,9 +2919,9 @@ caniuse-api@^3.0.0:
lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000697, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001032, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001164:
version "1.0.30001164"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001164.tgz#5bbfd64ca605d43132f13cc7fdabb17c3036bfdc"
integrity sha512-G+A/tkf4bu0dSp9+duNiXc7bGds35DioCyC6vgK2m/rjA4Krpy5WeZgZyfH2f0wj2kI6yAWWucyap6oOwmY1mg==
version "1.0.30001165"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001165.tgz#32955490d2f60290bb186bb754f2981917fa744f"
integrity sha512-8cEsSMwXfx7lWSUMA2s08z9dIgsnR5NAqjXP23stdsU3AUWkCr/rr4s4OFtHXn5XXr6+7kam3QFVoYyXNPdJPA==
canonical-path@1.0.0:
version "1.0.0"
@@ -4407,9 +4407,9 @@ ejs@^2.6.1:
integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==
electron-to-chromium@^1.3.612:
version "1.3.614"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.614.tgz#ff359e8d2249e2ce859a4c2bc34c22bd2e2eb0a2"
integrity sha512-JMDl46mg4G+n6q/hAJkwy9eMTj5FJjsE+8f/irAGRMLM4yeRVbMuRrdZrbbGGOrGVcZc4vJPjUpEUWNb/fA6hg==
version "1.3.615"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.615.tgz#50f523be4a04449410e9f3a694490814e602cd54"
integrity sha512-fNYTQXoUhNc6RmHDlGN4dgcLURSBIqQCN7ls6MuQ741+NJyLNRz8DxAC+pZpOKfRs6cfY0lv2kWdy8Oxf9j4+A==
elliptic@^6.5.3:
version "6.5.3"
@@ -4835,6 +4835,11 @@ expand-brackets@^2.1.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
express-rate-limit@^5.1.3:
version "5.2.3"
resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-5.2.3.tgz#ae73b3dc723decd697797611bd96e9b34a912f6c"
integrity sha512-cjQH+oDrEPXxc569XvxhHC6QXqJiuBT6BhZ70X3bdAImcnHnTNMVuMAJaT0TXPoRiEErUrVPRcOTpZpM36VbOQ==
express@^4.16.3, express@^4.17.1:
version "4.17.1"
resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"
@@ -5186,9 +5191,9 @@ forever-agent@~0.6.1:
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
fork-ts-checker-webpack-plugin@^6.0.3:
version "6.0.4"
resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.0.4.tgz#6c221e4613946d5458d5735e4eb3c67da7c9f60d"
integrity sha512-8/Q0svTnhyF6msFnW2qOOjn2wVsrMq5C6II6lyN3VkPzqsWS3InHjDr5P8Gk6w7ByhE7U+1CGGAXTVkPf5uHcQ==
version "6.0.5"
resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.0.5.tgz#20d8766b644833cc5c600b9b7c6fbba0c8087419"
integrity sha512-2jIHv2RhXzSxWtvRQX/ZtOxd5joo+FQYzn+sJ/hyLqApKGgvjMEMF951GnvuSNPheGsqiVzIDjvSZo1qRtry1Q==
dependencies:
"@babel/code-frame" "^7.8.3"
"@types/json-schema" "^7.0.5"